Merge changes from topic "morello-dt-fix" into integration
* changes:
fix(morello): dts: remove #a-c and #s-c from memory node
fix(morello): dts: fix GICv3 compatible string
fix(morello): dts: fix DT node naming
fix(morello): dts: fix SCMI shmem/mboxes grouping
fix(morello): dts: use documented DPU compatible string
fix(morello): dts: fix DP SMMU IRQ ordering
fix(morello): dts: fix SMMU IRQ ordering
fix(morello): dts: add model names
fix(morello): dts: fix stdout-path target
diff --git a/.commitlintrc.js b/.commitlintrc.js
index ed971a3..cfafbed 100644
--- a/.commitlintrc.js
+++ b/.commitlintrc.js
@@ -68,7 +68,6 @@
"type-enum": [2, "always", types], /* Error */
"scope-case": [2, "always", "lower-case"], /* Error */
- "scope-empty": [2, "never"], /* Error */
"scope-enum": [1, "always", scopes] /* Warning */
},
};
diff --git a/.gitignore b/.gitignore
index f524658..b005fab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,8 +30,7 @@
tools/stm32image/*.o
tools/stm32image/stm32image
tools/stm32image/stm32image.exe
-tools/sptool/sptool
-tools/sptool/sptool.exe
+tools/sptool/__pycache__/
# GNU GLOBAL files
GPATH
diff --git a/Makefile b/Makefile
index fb50f0c..afa417b 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,8 @@
# Trusted Firmware Version
#
VERSION_MAJOR := 2
-VERSION_MINOR := 6
+VERSION_MINOR := 7
+VERSION := ${VERSION_MAJOR}.${VERSION_MINOR}
# Default goal is build all images
.DEFAULT_GOAL := all
@@ -135,6 +136,10 @@
ifneq (${ENABLE_PIE},0)
$(error ENABLE_RME does not support PIE)
endif
+# RME doesn't support BRBE
+ifneq (${ENABLE_BRBE_FOR_NS},0)
+ $(error ENABLE_RME does not support BRBE.)
+endif
# RME requires AARCH64
ifneq (${ARCH},aarch64)
$(error ENABLE_RME requires AArch64)
@@ -263,42 +268,24 @@
# Determine if FEAT_SB is supported
ENABLE_FEAT_SB = $(if $(findstring sb,${arch-features}),1,0)
-ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_SB = 1
-endif
-
-# Determine and enable FEAT_FGT to access HDFGRTR_EL2 register for v8.6 and higher versions.
-ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_FGT = 1
-endif
-
-# Determine and enable FEAT_ECV to access CNTPOFF_EL2 register for v8.6 and higher versions.
-ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_ECV = 1
-endif
+ifneq ($(findstring clang,$(notdir $(CC))),)
+ ifneq ($(findstring armclang,$(notdir $(CC))),)
+ TF_CFLAGS_aarch32 := -target arm-arm-none-eabi $(march32-directive)
+ TF_CFLAGS_aarch64 := -target aarch64-arm-none-eabi $(march64-directive)
+ LD := $(LINKER)
+ else
+ TF_CFLAGS_aarch32 := $(target32-directive) $(march32-directive)
+ TF_CFLAGS_aarch64 := -target aarch64-elf $(march64-directive)
+ LD := $(shell $(CC) --print-prog-name ld.lld)
-ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_DIT = 1
-endif
+ AR := $(shell $(CC) --print-prog-name llvm-ar)
+ OD := $(shell $(CC) --print-prog-name llvm-objdump)
+ OC := $(shell $(CC) --print-prog-name llvm-objcopy)
+ endif
-ifneq ($(findstring armclang,$(notdir $(CC))),)
-TF_CFLAGS_aarch32 = -target arm-arm-none-eabi $(march32-directive)
-TF_CFLAGS_aarch64 = -target aarch64-arm-none-eabi $(march64-directive)
-LD = $(LINKER)
-AS = $(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
-CPP = $(CC) -E $(TF_CFLAGS_$(ARCH))
-PP = $(CC) -E $(TF_CFLAGS_$(ARCH))
-else ifneq ($(findstring clang,$(notdir $(CC))),)
-CLANG_CCDIR = $(if $(filter-out ./,$(dir $(CC))),$(dir $(CC)),)
-TF_CFLAGS_aarch32 = $(target32-directive) $(march32-directive)
-TF_CFLAGS_aarch64 = -target aarch64-elf $(march64-directive)
-LD = $(CLANG_CCDIR)ld.lld
-ifeq (, $(shell which $(LD)))
-$(error "No $(LD) in PATH, make sure it is installed or set LD to a different linker")
-endif
-AS = $(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
-CPP = $(CC) -E
-PP = $(CC) -E
+ CPP := $(CC) -E $(TF_CFLAGS_$(ARCH))
+ PP := $(CC) -E $(TF_CFLAGS_$(ARCH))
+ AS := $(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
else ifneq ($(findstring gcc,$(notdir $(CC))),)
TF_CFLAGS_aarch32 = $(march32-directive)
TF_CFLAGS_aarch64 = $(march64-directive)
@@ -321,13 +308,8 @@
$(eval $(call add_define,DEBUG))
ifneq (${DEBUG}, 0)
BUILD_TYPE := debug
- TF_CFLAGS += -g
-
- ifneq ($(findstring clang,$(notdir $(CC))),)
- ASFLAGS += -g
- else
- ASFLAGS += -g -Wa,--gdwarf-2
- endif
+ TF_CFLAGS += -g -gdwarf-4
+ ASFLAGS += -g -Wa,-gdwarf-4
# Use LOG_LEVEL_INFO by default for debug builds
LOG_LEVEL := 40
@@ -341,7 +323,7 @@
ifeq (${BUILD_STRING},)
BUILD_STRING := $(shell git describe --always --dirty --tags 2> /dev/null)
endif
-VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}(${BUILD_TYPE}):${BUILD_STRING}
+VERSION_STRING := v${VERSION}(${BUILD_TYPE}):${BUILD_STRING}
ifeq (${AARCH32_INSTRUCTION_SET},A32)
TF_CFLAGS_aarch32 += -marm
@@ -418,6 +400,8 @@
-ffreestanding -fno-builtin -fno-common \
-Os -std=gnu99
+$(eval $(call add_define,SVE_VECTOR_LEN))
+
ifeq (${SANITIZE_UB},on)
TF_CFLAGS += -fsanitize=undefined -fno-sanitize-recover
endif
@@ -467,13 +451,10 @@
DTC_CPPFLAGS += -P -nostdinc -Iinclude -Ifdts -undef \
-x assembler-with-cpp $(DEFINES)
-ifeq ($(MEASURED_BOOT),1)
-DTC_CPPFLAGS += -DMEASURED_BOOT -DBL2_HASH_SIZE=${TCG_DIGEST_SIZE}
-endif
-
################################################################################
# Common sources and include directories
################################################################################
+include ${MAKE_HELPERS_DIRECTORY}arch_features.mk
include lib/compiler-rt/compiler-rt.mk
BL_COMMON_SOURCES += common/bl_common.c \
@@ -544,6 +525,9 @@
ifeq ($(CTX_INCLUDE_EL2_REGS),0)
$(error SPMD with SPM at S-EL2 requires CTX_INCLUDE_EL2_REGS option)
endif
+ ifeq ($(SPMC_AT_EL3),1)
+ $(error SPM cannot be enabled in both S-EL2 and EL3.)
+ endif
endif
ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
@@ -594,6 +578,9 @@
ifneq (${ARCH},aarch64)
$(error ENABLE_RME requires AArch64)
endif
+ifeq ($(SPMC_AT_EL3),1)
+ $(error SPMC_AT_EL3 and ENABLE_RME cannot both be enabled.)
+endif
include services/std_svc/rmmd/rmmd.mk
$(warning "RME is an experimental feature")
endif
@@ -614,6 +601,9 @@
PIE_FOUND := $(findstring --enable-default-pie,${GCC_V_OUTPUT})
ifneq ($(PIE_FOUND),)
TF_CFLAGS += -fno-PIE
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+ TF_LDFLAGS += -no-pie
+endif
endif
ifneq ($(findstring gcc,$(notdir $(LD))),)
@@ -776,6 +766,10 @@
$(info PSA_FWU_SUPPORT is an experimental feature)
endif
+ifeq ($(FEATURE_DETECTION),1)
+ $(info FEATURE_DETECTION is an experimental feature)
+endif
+
ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
$(error "ALLOW_RO_XLAT_TABLES requires translation tables library v2")
@@ -788,8 +782,10 @@
endif
endif
-# SME/SVE only supported on AArch64
+# Ensure that no Aarch64-only features are enabled in Aarch32 build
ifeq (${ARCH},aarch32)
+
+ # SME/SVE only supported on AArch64
ifeq (${ENABLE_SME_FOR_NS},1)
$(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32")
endif
@@ -797,6 +793,16 @@
# Warning instead of error due to CI dependency on this
$(error "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32")
endif
+
+ # BRBE is not supported in AArch32
+ ifeq (${ENABLE_BRBE_FOR_NS},1)
+ $(error "ENABLE_BRBE_FOR_NS cannot be used with ARCH=aarch32")
+ endif
+
+ # FEAT_RNG_TRAP is not supported in AArch32
+ ifeq (${ENABLE_FEAT_RNG_TRAP},1)
+ $(error "ENABLE_FEAT_RNG_TRAP cannot be used with ARCH=aarch32")
+ endif
endif
# Ensure ENABLE_RME is not used with SME
@@ -832,6 +838,10 @@
endif
endif
+ifeq ($(DRTM_SUPPORT),1)
+ $(info DRTM_SUPPORT is an experimental feature)
+endif
+
################################################################################
# Process platform overrideable behaviour
################################################################################
@@ -929,7 +939,7 @@
# Variables for use with sptool
SPTOOLPATH ?= tools/sptool
-SPTOOL ?= ${SPTOOLPATH}/sptool${BIN_EXT}
+SPTOOL ?= ${SPTOOLPATH}/sptool.py
SP_MK_GEN ?= ${SPTOOLPATH}/sp_mk_generator.py
# Variables for use with ROMLIB
@@ -980,10 +990,7 @@
CREATE_KEYS \
CTX_INCLUDE_AARCH32_REGS \
CTX_INCLUDE_FPREGS \
- CTX_INCLUDE_PAUTH_REGS \
- CTX_INCLUDE_MTE_REGS \
CTX_INCLUDE_EL2_REGS \
- CTX_INCLUDE_NEVE_REGS \
DEBUG \
DISABLE_MTPMU \
DYN_DISABLE_AUTH \
@@ -993,11 +1000,9 @@
ENABLE_AMU_FCONF \
AMU_RESTRICT_COUNTERS \
ENABLE_ASSERTIONS \
- ENABLE_MPAM_FOR_LOWER_ELS \
ENABLE_PIE \
ENABLE_PMF \
ENABLE_PSCI_STAT \
- ENABLE_RME \
ENABLE_RUNTIME_INSTRUMENTATION \
ENABLE_SME_FOR_NS \
ENABLE_SME_FOR_SWD \
@@ -1012,18 +1017,22 @@
HW_ASSISTED_COHERENCY \
INVERTED_MEMMAP \
MEASURED_BOOT \
+ DRTM_SUPPORT \
NS_TIMER_SWITCH \
OVERRIDE_LIBC \
PL011_GENERIC_UART \
+ PLAT_RSS_NOT_SUPPORTED \
PROGRAMMABLE_RESET_ADDRESS \
PSCI_EXTENDED_STATE_ID \
- RAS_EXTENSION \
RESET_TO_BL31 \
+ RESET_TO_BL31_WITH_PARAMS \
SAVE_KEYS \
SEPARATE_CODE_AND_RODATA \
+ SEPARATE_BL2_NOLOAD_REGION \
SEPARATE_NOBITS_REGION \
SPIN_ON_BL1_EXIT \
SPM_MM \
+ SPMC_AT_EL3 \
SPMD_SPM_AT_SEL2 \
TRUSTED_BOARD_BOOT \
CRYPTO_SUPPORT \
@@ -1045,20 +1054,12 @@
RAS_TRAP_LOWER_EL_ERR_ACCESS \
COT_DESC_IN_DTB \
USE_SP804_TIMER \
- ENABLE_FEAT_RNG \
- ENABLE_FEAT_SB \
- ENABLE_FEAT_DIT \
PSA_FWU_SUPPORT \
- ENABLE_TRBE_FOR_NS \
ENABLE_SYS_REG_TRACE_FOR_NS \
- ENABLE_TRF_FOR_NS \
- ENABLE_FEAT_HCX \
ENABLE_MPMM \
ENABLE_MPMM_FCONF \
- ENABLE_FEAT_FGT \
- ENABLE_FEAT_AMUv1 \
- ENABLE_FEAT_ECV \
SIMICS_BUILD \
+ FEATURE_DETECTION \
)))
$(eval $(call assert_numerics,\
@@ -1066,9 +1067,36 @@
ARM_ARCH_MAJOR \
ARM_ARCH_MINOR \
BRANCH_PROTECTION \
+ CTX_INCLUDE_PAUTH_REGS \
+ CTX_INCLUDE_MTE_REGS \
+ CTX_INCLUDE_NEVE_REGS \
+ ENABLE_BRBE_FOR_NS \
+ ENABLE_TRBE_FOR_NS \
+ ENABLE_BTI \
+ ENABLE_PAUTH \
+ ENABLE_FEAT_AMUv1 \
+ ENABLE_FEAT_AMUv1p1 \
+ ENABLE_FEAT_CSV2_2 \
+ ENABLE_FEAT_DIT \
+ ENABLE_FEAT_ECV \
+ ENABLE_FEAT_FGT \
+ ENABLE_FEAT_HCX \
+ ENABLE_FEAT_PAN \
+ ENABLE_FEAT_RNG \
+ ENABLE_FEAT_RNG_TRAP \
+ ENABLE_FEAT_SB \
+ ENABLE_FEAT_SEL2 \
+ ENABLE_FEAT_VHE \
+ ENABLE_MPAM_FOR_LOWER_ELS \
+ ENABLE_RME \
+ ENABLE_TRF_FOR_NS \
FW_ENC_STATUS \
NR_OF_FW_BANKS \
NR_OF_IMAGES_IN_FW_BANK \
+ RAS_EXTENSION \
+ TWED_DELAY \
+ ENABLE_FEAT_TWED \
+ SVE_VECTOR_LEN \
)))
ifdef KEY_SIZE
@@ -1128,19 +1156,24 @@
HW_ASSISTED_COHERENCY \
LOG_LEVEL \
MEASURED_BOOT \
+ DRTM_SUPPORT \
NS_TIMER_SWITCH \
PL011_GENERIC_UART \
PLAT_${PLAT} \
+ PLAT_RSS_NOT_SUPPORTED \
PROGRAMMABLE_RESET_ADDRESS \
PSCI_EXTENDED_STATE_ID \
RAS_EXTENSION \
RESET_TO_BL31 \
+ RESET_TO_BL31_WITH_PARAMS \
SEPARATE_CODE_AND_RODATA \
+ SEPARATE_BL2_NOLOAD_REGION \
SEPARATE_NOBITS_REGION \
RECLAIM_INIT_CODE \
SPD_${SPD} \
SPIN_ON_BL1_EXIT \
SPM_MM \
+ SPMC_AT_EL3 \
SPMD_SPM_AT_SEL2 \
TRUSTED_BOARD_BOOT \
CRYPTO_SUPPORT \
@@ -1162,11 +1195,13 @@
COT_DESC_IN_DTB \
USE_SP804_TIMER \
ENABLE_FEAT_RNG \
+ ENABLE_FEAT_RNG_TRAP \
ENABLE_FEAT_SB \
ENABLE_FEAT_DIT \
NR_OF_FW_BANKS \
NR_OF_IMAGES_IN_FW_BANK \
PSA_FWU_SUPPORT \
+ ENABLE_BRBE_FOR_NS \
ENABLE_TRBE_FOR_NS \
ENABLE_SYS_REG_TRACE_FOR_NS \
ENABLE_TRF_FOR_NS \
@@ -1177,6 +1212,14 @@
ENABLE_FEAT_AMUv1 \
ENABLE_FEAT_ECV \
SIMICS_BUILD \
+ ENABLE_FEAT_AMUv1p1 \
+ ENABLE_FEAT_SEL2 \
+ ENABLE_FEAT_VHE \
+ ENABLE_FEAT_CSV2_2 \
+ ENABLE_FEAT_PAN \
+ FEATURE_DETECTION \
+ TWED_DELAY \
+ ENABLE_FEAT_TWED \
)))
ifeq (${SANITIZE_UB},trap)
@@ -1323,8 +1366,7 @@
ifeq (${NEED_SP_PKG},yes)
$(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT}
-sp: $(SPTOOL) $(DTBS) $(BUILD_PLAT)/sp_gen.mk
- ${Q}$(SPTOOL) $(SPTOOL_ARGS)
+sp: $(DTBS) $(BUILD_PLAT)/sp_gen.mk $(SP_PKGS)
@${ECHO_BLANK_LINE}
@echo "Built SP Images successfully"
@${ECHO_BLANK_LINE}
@@ -1364,7 +1406,6 @@
# to pass the gnumake flags to nmake.
${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean
endif
- ${Q}${MAKE} --no-print-directory -C ${SPTOOLPATH} clean
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} realclean
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean
${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
@@ -1458,10 +1499,6 @@
${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
endif
-sptool: ${SPTOOL}
-${SPTOOL}: FORCE
- ${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" SPTOOL=${SPTOOL} --no-print-directory -C ${SPTOOLPATH}
-
romlib.bin: libraries FORCE
${Q}${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all
diff --git a/bl1/aarch32/bl1_exceptions.S b/bl1/aarch32/bl1_exceptions.S
index 493d2ca..4a6815f 100644
--- a/bl1/aarch32/bl1_exceptions.S
+++ b/bl1/aarch32/bl1_exceptions.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -118,6 +118,14 @@
mov r0, #DISABLE_DCACHE
bl enable_mmu_svc_mon
+ /*
+ * Invalidate `smc_ctx_t` in data cache to prevent dirty data being
+ * used.
+ */
+ mov r0, r6
+ mov r1, #SMC_CTX_SIZE
+ bl inv_dcache_range
+
/* Enable the data cache. */
ldcopr r9, SCTLR
orr r9, r9, #SCTLR_C_BIT
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index bc1794c..c95706c 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,6 +18,11 @@
#else
RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
#endif
+#if SEPARATE_BL2_NOLOAD_REGION
+ RAM_NOLOAD (rw!a): ORIGIN = BL2_NOLOAD_START, LENGTH = BL2_NOLOAD_LIMIT - BL2_NOLOAD_START
+#else
+#define RAM_NOLOAD RAM
+#endif
}
#if !BL2_IN_XIP_MEM
@@ -106,9 +111,18 @@
__DATA_RAM_END__ = __DATA_END__;
RELA_SECTION >RAM
- STACK_SECTION >RAM
- BSS_SECTION >RAM
- XLAT_TABLE_SECTION >RAM
+#if SEPARATE_BL2_NOLOAD_REGION
+ SAVED_ADDR = .;
+ . = BL2_NOLOAD_START;
+ __BL2_NOLOAD_START__ = .;
+#endif
+ STACK_SECTION >RAM_NOLOAD
+ BSS_SECTION >RAM_NOLOAD
+ XLAT_TABLE_SECTION >RAM_NOLOAD
+#if SEPARATE_BL2_NOLOAD_REGION
+ __BL2_NOLOAD_END__ = .;
+ . = SAVED_ADDR;
+#endif
#if USE_COHERENT_MEM
/*
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index ed05864..b0c46dc 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -67,6 +67,7 @@
_exception_vectors=runtime_exceptions \
_pie_fixup_size=BL31_LIMIT - BL31_BASE
+#if !RESET_TO_BL31_WITH_PARAMS
/* ---------------------------------------------------------------------
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
* there's no argument to relay from a previous bootloader. Zero the
@@ -77,6 +78,7 @@
mov x21, 0
mov x22, 0
mov x23, 0
+#endif /* RESET_TO_BL31_WITH_PARAMS */
#endif /* RESET_TO_BL31 */
/* --------------------------------------------------------------------
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index fa6ede8..5e53ab4 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -84,10 +85,6 @@
b 2f
1:
- /* Test for EA bit in the instruction syndrome */
- mrs x30, esr_el3
- tbz x30, #ESR_ISS_EABORT_EA_BIT, 3f
-
/*
* Save general purpose and ARMv8.3-PAuth registers (if enabled).
* If Secure Cycle Counter is not disabled in MDCR_EL3 when
@@ -114,7 +111,6 @@
ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
-3:
/* Synchronous exceptions other than the above are assumed to be EA */
ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
no_ret report_unhandled_exception
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 8a1573a..309e752 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -47,6 +47,10 @@
__RODATA_START__ = .;
*(SORT_BY_ALIGNMENT(.rodata*))
+#if PLAT_EXTRA_RODATA_INCLUDES
+#include <plat.ld.rodata.inc>
+#endif
+
RODATA_COMMON
/* Place pubsub sections for events */
@@ -186,10 +190,10 @@
__RW_END__ = .;
__BL31_END__ = .;
+ ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
+#endif
+
/DISCARD/ : {
*(.dynsym .dynstr .hash .gnu.hash)
}
-
- ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
-#endif
}
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index e751824..3964469 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -18,12 +18,21 @@
$(error EL3_EXCEPTION_HANDLING must be 1 for SPM-MM support)
else
$(info Including SPM Management Mode (MM) makefile)
- include services/std_svc/spm_mm/spm_mm.mk
+ include services/std_svc/spm/common/spm.mk
+ include services/std_svc/spm/spm_mm/spm_mm.mk
endif
endif
include lib/extensions/amu/amu.mk
include lib/mpmm/mpmm.mk
+
+ifeq (${SPMC_AT_EL3},1)
+ $(warning "EL3 SPMC is an experimental feature")
+ $(info Including EL3 SPMC makefile)
+ include services/std_svc/spm/common/spm.mk
+ include services/std_svc/spm/el3_spmc/spmc.mk
+endif
+
include lib/psci/psci_lib.mk
BL31_SOURCES += bl31/bl31_main.c \
@@ -40,6 +49,8 @@
services/std_svc/std_svc_setup.c \
${PSCI_LIB_SOURCES} \
${SPMD_SOURCES} \
+ ${SPM_MM_SOURCES} \
+ ${SPMC_SOURCES} \
${SPM_SOURCES}
ifeq (${DISABLE_MTPMU},1)
@@ -104,6 +115,10 @@
BL31_SOURCES += lib/extensions/trbe/trbe.c
endif
+ifeq (${ENABLE_BRBE_FOR_NS},1)
+BL31_SOURCES += lib/extensions/brbe/brbe.c
+endif
+
ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1)
BL31_SOURCES += lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c
endif
@@ -128,6 +143,10 @@
${RMMD_SOURCES}
endif
+ifeq ($(FEATURE_DETECTION),1)
+BL31_SOURCES += common/feat_detect.c
+endif
+
BL31_LINKERFILE := bl31/bl31.ld.S
# Flag used to indicate if Crash reporting via console should be included
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 9ac10e2..2a3d838 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +14,7 @@
#include <bl31/ehf.h>
#include <common/bl_common.h>
#include <common/debug.h>
+#include <common/feat_detect.h>
#include <common/runtime_svc.h>
#include <drivers/console.h>
#include <lib/el3_runtime/context_mgmt.h>
@@ -123,6 +124,11 @@
NOTICE("BL31: %s\n", version_string);
NOTICE("BL31: %s\n", build_message);
+#if FEATURE_DETECTION
+ /* Detect if features enabled during compilation are supported by PE. */
+ detect_arch_features();
+#endif /* FEATURE_DETECTION */
+
#ifdef SUPPORT_UNKNOWN_MPID
if (unsupported_mpid_flag == 0) {
NOTICE("Unsupported MPID detected!\n");
@@ -253,7 +259,16 @@
(image_type == SECURE) ? "secure" : "normal");
print_entry_point_info(next_image_info);
cm_init_my_context(next_image_info);
- cm_prepare_el3_exit(image_type);
+
+ /*
+ * If we are entering the Non-secure world, use
+ * 'cm_prepare_el3_exit_ns' to exit.
+ */
+ if (image_type == NON_SECURE) {
+ cm_prepare_el3_exit_ns();
+ } else {
+ cm_prepare_el3_exit(image_type);
+ }
}
/*******************************************************************************
diff --git a/bl31/ehf.c b/bl31/ehf.c
index 745f165..b328380 100644
--- a/bl31/ehf.c
+++ b/bl31/ehf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -475,9 +475,16 @@
assert((exception_data.pri_bits >= 1U) ||
(exception_data.pri_bits < 8U));
- /* Route EL3 interrupts when in Secure and Non-secure. */
+ /* Route EL3 interrupts when in Non-secure. */
set_interrupt_rm_flag(flags, NON_SECURE);
+
+ /*
+ * Route EL3 interrupts when in secure, only when SPMC is not present
+ * in S-EL2.
+ */
+#if !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1))
set_interrupt_rm_flag(flags, SECURE);
+#endif /* !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)) */
/* Register handler for EL3 interrupts */
ret = register_interrupt_type_handler(INTR_TYPE_EL3,
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 590b032..ab1287d 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -35,6 +35,10 @@
ifeq (${WORKAROUND_CVE_2017_5715},1)
BL32_SOURCES += bl32/sp_min/wa_cve_2017_5715_bpiall.S \
bl32/sp_min/wa_cve_2017_5715_icache_inv.S
+else
+ifeq (${WORKAROUND_CVE_2022_23960},1)
+BL32_SOURCES += bl32/sp_min/wa_cve_2017_5715_icache_inv.S
+endif
endif
ifeq (${TRNG_SUPPORT},1)
diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S
index 7d77f47..e5ea88c 100644
--- a/bl32/tsp/aarch64/tsp_entrypoint.S
+++ b/bl32/tsp/aarch64/tsp_entrypoint.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,12 +10,16 @@
#include <asm_macros.S>
#include <bl32/tsp/tsp.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <smccc_helpers.h>
#include "../tsp_private.h"
.globl tsp_entrypoint
.globl tsp_vector_table
+#if SPMC_AT_EL3
+ .globl tsp_cpu_on_entry
+#endif
@@ -25,10 +29,10 @@
* ---------------------------------------------
*/
.macro restore_args_call_smc
- ldp x6, x7, [x0, #TSP_ARG6]
- ldp x4, x5, [x0, #TSP_ARG4]
- ldp x2, x3, [x0, #TSP_ARG2]
- ldp x0, x1, [x0, #TSP_ARG0]
+ ldp x6, x7, [x0, #SMC_ARG6]
+ ldp x4, x5, [x0, #SMC_ARG4]
+ ldp x2, x3, [x0, #SMC_ARG2]
+ ldp x0, x1, [x0, #SMC_ARG0]
smc #0
.endm
diff --git a/bl32/tsp/ffa_helpers.c b/bl32/tsp/ffa_helpers.c
new file mode 100644
index 0000000..3639c22
--- /dev/null
+++ b/bl32/tsp/ffa_helpers.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include "ffa_helpers.h"
+#include <services/ffa_svc.h>
+#include "tsp_private.h"
+
+/*******************************************************************************
+ * Wrapper function to send a direct request.
+ ******************************************************************************/
+smc_args_t ffa_msg_send_direct_req(ffa_endpoint_id16_t sender,
+ ffa_endpoint_id16_t receiver,
+ uint32_t arg3,
+ uint32_t arg4,
+ uint32_t arg5,
+ uint32_t arg6,
+ uint32_t arg7)
+{
+ uint32_t src_dst_ids = (sender << FFA_DIRECT_MSG_SOURCE_SHIFT) |
+ (receiver << FFA_DIRECT_MSG_DESTINATION_SHIFT);
+
+
+ /* Send Direct Request. */
+ return smc_helper(FFA_MSG_SEND_DIRECT_REQ_SMC64, src_dst_ids,
+ 0, arg3, arg4, arg5, arg6, arg7);
+}
+
+/*******************************************************************************
+ * Wrapper function to send a direct response.
+ ******************************************************************************/
+smc_args_t *ffa_msg_send_direct_resp(ffa_endpoint_id16_t sender,
+ ffa_endpoint_id16_t receiver,
+ uint32_t arg3,
+ uint32_t arg4,
+ uint32_t arg5,
+ uint32_t arg6,
+ uint32_t arg7)
+{
+ uint32_t src_dst_ids = (sender << FFA_DIRECT_MSG_SOURCE_SHIFT) |
+ (receiver << FFA_DIRECT_MSG_DESTINATION_SHIFT);
+
+ return set_smc_args(FFA_MSG_SEND_DIRECT_RESP_SMC64, src_dst_ids,
+ 0, arg3, arg4, arg5, arg6, arg7);
+}
+
+/*******************************************************************************
+ * Memory Management Helpers.
+ ******************************************************************************/
+
+/**
+ * Initialises the header of the given `ffa_mtd`, not including the
+ * composite memory region offset.
+ */
+static void ffa_memory_region_init_header(
+ struct ffa_mtd *memory_region, ffa_endpoint_id16_t sender,
+ ffa_mem_attr16_t attributes, ffa_mtd_flag32_t flags,
+ uint64_t handle, uint64_t tag, ffa_endpoint_id16_t *receivers,
+ uint32_t receiver_count, ffa_mem_perm8_t permissions)
+{
+ struct ffa_emad_v1_0 *emad;
+
+ memory_region->emad_offset = sizeof(struct ffa_mtd);
+ memory_region->emad_size = sizeof(struct ffa_emad_v1_0);
+ emad = (struct ffa_emad_v1_0 *)
+ ((uint8_t *) memory_region +
+ memory_region->emad_offset);
+ memory_region->sender_id = sender;
+ memory_region->memory_region_attributes = attributes;
+ memory_region->reserved_36_39 = 0;
+ memory_region->flags = flags;
+ memory_region->handle = handle;
+ memory_region->tag = tag;
+ memory_region->reserved_40_47 = 0;
+ memory_region->emad_count = receiver_count;
+ for (uint32_t i = 0U; i < receiver_count; i++) {
+ emad[i].mapd.endpoint_id = receivers[i];
+ emad[i].mapd.memory_access_permissions = permissions;
+ emad[i].mapd.flags = 0;
+ emad[i].comp_mrd_offset = 0;
+ emad[i].reserved_8_15 = 0;
+ }
+}
+/**
+ * Initialises the given `ffa_mtd` to be used for an
+ * `FFA_MEM_RETRIEVE_REQ` by the receiver of a memory transaction.
+ * TODO: Support differing attributes per receiver.
+ *
+ * Returns the size of the descriptor written.
+ */
+static uint32_t ffa_memory_retrieve_request_init(
+ struct ffa_mtd *memory_region, uint64_t handle,
+ ffa_endpoint_id16_t sender, ffa_endpoint_id16_t *receivers, uint32_t receiver_count,
+ uint64_t tag, ffa_mtd_flag32_t flags,
+ ffa_mem_perm8_t permissions,
+ ffa_mem_attr16_t attributes)
+{
+ ffa_memory_region_init_header(memory_region, sender, attributes, flags,
+ handle, tag, receivers,
+ receiver_count, permissions);
+
+ return sizeof(struct ffa_mtd) +
+ memory_region->emad_count * sizeof(struct ffa_emad_v1_0);
+}
+
+/* Relinquish access to memory region. */
+bool ffa_mem_relinquish(void)
+{
+ smc_args_t ret;
+
+ ret = smc_helper(FFA_MEM_RELINQUISH, 0, 0, 0, 0, 0, 0, 0);
+ if (ffa_func_id(ret) != FFA_SUCCESS_SMC32) {
+ ERROR("%s failed to relinquish memory! error: (%x) %x\n",
+ __func__, ffa_func_id(ret), ffa_error_code(ret));
+ return false;
+ }
+ return true;
+}
+
+/* Retrieve memory shared by another partition. */
+smc_args_t ffa_mem_retrieve_req(uint32_t descriptor_length,
+ uint32_t fragment_length)
+{
+ return smc_helper(FFA_MEM_RETRIEVE_REQ_SMC32,
+ descriptor_length,
+ fragment_length,
+ 0, 0, 0, 0, 0);
+}
+
+/* Retrieve the next memory descriptor fragment. */
+smc_args_t ffa_mem_frag_rx(uint64_t handle, uint32_t recv_length)
+{
+ return smc_helper(FFA_MEM_FRAG_RX,
+ FFA_MEM_HANDLE_LOW(handle),
+ FFA_MEM_HANDLE_HIGH(handle),
+ recv_length,
+ 0, 0, 0, 0);
+}
+
+bool memory_retrieve(struct mailbox *mb,
+ struct ffa_mtd **retrieved,
+ uint64_t handle, ffa_endpoint_id16_t sender,
+ ffa_endpoint_id16_t *receivers, uint32_t receiver_count,
+ ffa_mtd_flag32_t flags, uint32_t *frag_length,
+ uint32_t *total_length)
+{
+ smc_args_t ret;
+ uint32_t descriptor_size;
+ struct ffa_mtd *memory_region = (struct ffa_mtd *)mb->tx_buffer;
+
+ if (retrieved == NULL || mb == NULL) {
+ ERROR("Invalid parameters!\n");
+ return false;
+ }
+
+ /* Clear TX buffer. */
+ memset(memory_region, 0, PAGE_SIZE);
+
+ /* Clear local buffer. */
+ memset(mem_region_buffer, 0, REGION_BUF_SIZE);
+
+ descriptor_size = ffa_memory_retrieve_request_init(
+ memory_region, handle, sender, receivers, receiver_count, 0, flags,
+ FFA_MEM_PERM_RW | FFA_MEM_PERM_NX,
+ FFA_MEM_ATTR_NORMAL_MEMORY_CACHED_WB |
+ FFA_MEM_ATTR_INNER_SHAREABLE);
+
+ ret = ffa_mem_retrieve_req(descriptor_size, descriptor_size);
+
+ if (ffa_func_id(ret) == FFA_ERROR) {
+ ERROR("Couldn't retrieve the memory page. Error: %x\n",
+ ffa_error_code(ret));
+ return false;
+ }
+
+ /*
+ * Following total_size and fragment_size are useful to keep track
+ * of the state of transaction. When the sum of all fragment_size of all
+ * fragments is equal to total_size, the memory transaction has been
+ * completed.
+ */
+ *total_length = ret._regs[1];
+ *frag_length = ret._regs[2];
+
+ /* Validate frag_length is less than total_length and mailbox size. */
+ if (*frag_length == 0U || *total_length == 0U ||
+ *frag_length > *total_length || *frag_length > (mb->rxtx_page_count * PAGE_SIZE)) {
+ ERROR("Invalid parameters!\n");
+ return false;
+ }
+
+ /* Copy response to local buffer. */
+ memcpy(mem_region_buffer, mb->rx_buffer, *frag_length);
+
+ if (ffa_rx_release()) {
+ ERROR("Failed to release buffer!\n");
+ return false;
+ }
+
+ *retrieved = (struct ffa_mtd *) mem_region_buffer;
+
+ if ((*retrieved)->emad_count > MAX_MEM_SHARE_RECIPIENTS) {
+ VERBOSE("SPMC memory sharing supports max of %u receivers!\n",
+ MAX_MEM_SHARE_RECIPIENTS);
+ return false;
+ }
+
+ /*
+ * We are sharing memory from the normal world therefore validate the NS
+ * bit was set by the SPMC.
+ */
+ if (((*retrieved)->memory_region_attributes & FFA_MEM_ATTR_NS_BIT) == 0U) {
+ ERROR("SPMC has not set the NS bit! 0x%x\n",
+ (*retrieved)->memory_region_attributes);
+ return false;
+ }
+
+ VERBOSE("Memory Descriptor Retrieved!\n");
+
+ return true;
+}
+
+/* Relinquish the memory region. */
+bool memory_relinquish(struct ffa_mem_relinquish_descriptor *m, uint64_t handle,
+ ffa_endpoint_id16_t id)
+{
+ ffa_mem_relinquish_init(m, handle, 0, id);
+ return ffa_mem_relinquish();
+}
+
+/* Query SPMC that the rx buffer of the partition can be released. */
+bool ffa_rx_release(void)
+{
+ smc_args_t ret;
+
+ ret = smc_helper(FFA_RX_RELEASE, 0, 0, 0, 0, 0, 0, 0);
+ return ret._regs[SMC_ARG0] != FFA_SUCCESS_SMC32;
+}
+
+/* Map the provided buffers with the SPMC. */
+bool ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages)
+{
+ smc_args_t ret;
+
+ ret = smc_helper(FFA_RXTX_MAP_SMC64, send, recv, pages, 0, 0, 0, 0);
+ return ret._regs[0] != FFA_SUCCESS_SMC32;
+}
diff --git a/bl32/tsp/ffa_helpers.h b/bl32/tsp/ffa_helpers.h
new file mode 100644
index 0000000..e650a07
--- /dev/null
+++ b/bl32/tsp/ffa_helpers.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FFA_HELPERS_H
+#define FFA_HELPERS_H
+
+#include <stdint.h>
+
+#include "../../services/std_svc/spm/el3_spmc/spmc.h"
+#include "../../services/std_svc/spm/el3_spmc/spmc_shared_mem.h"
+#include <services/el3_spmc_ffa_memory.h>
+#include <services/ffa_svc.h>
+#include "tsp_private.h"
+
+static inline uint32_t ffa_func_id(smc_args_t val)
+{
+ return (uint32_t) val._regs[0];
+}
+
+static inline int32_t ffa_error_code(smc_args_t val)
+{
+ return (uint32_t) val._regs[2];
+}
+
+extern uint8_t mem_region_buffer[4096 * 2] __aligned(PAGE_SIZE);
+#define REGION_BUF_SIZE sizeof(mem_region_buffer)
+
+/** The maximum number of recipients a memory region may be sent to. */
+#define MAX_MEM_SHARE_RECIPIENTS 2U
+
+/* FFA Memory Management mode flags. */
+#define FFA_FLAG_SHARE_MEMORY (1U << 3)
+#define FFA_FLAG_LEND_MEMORY (1U << 4)
+
+#define FFA_FLAG_MEMORY_MASK (3U << 3)
+
+#define FFA_MEM_HANDLE_LOW(x) (x & 0xFFFFFFFF)
+#define FFA_MEM_HANDLE_HIGH(x) (x >> 32)
+
+#define FFA_MEM_PERM_DATA_OFFSET 0
+#define FFA_MEM_PERM_DATA_MASK 0x3
+
+static inline uint32_t ffa_mem_relinquish_init(
+ struct ffa_mem_relinquish_descriptor *relinquish_request,
+ uint64_t handle, ffa_mtd_flag32_t flags,
+ ffa_endpoint_id16_t sender)
+{
+ relinquish_request->handle = handle;
+ relinquish_request->flags = flags;
+ relinquish_request->endpoint_count = 1;
+ relinquish_request->endpoint_array[0] = sender;
+
+ return sizeof(struct ffa_mem_relinquish_descriptor) + sizeof(ffa_endpoint_id16_t);
+}
+
+/**
+ * Gets the `ffa_comp_mrd` for the given receiver from an
+ * `ffa_mtd`, or NULL if it is not valid.
+ */
+static inline struct ffa_comp_mrd *
+ffa_memory_region_get_composite(struct ffa_mtd *memory_region,
+ uint32_t receiver_index)
+{
+ struct ffa_emad_v1_0 *receivers;
+ uint32_t offset;
+
+ receivers = (struct ffa_emad_v1_0 *)
+ ((uint8_t *) memory_region +
+ memory_region->emad_offset +
+ (memory_region->emad_size * receiver_index));
+ offset = receivers->comp_mrd_offset;
+
+ if (offset == 0U) {
+ return NULL;
+ }
+
+ return (struct ffa_comp_mrd *)
+ ((uint8_t *) memory_region + offset);
+}
+
+static inline uint32_t ffa_get_data_access_attr(ffa_mem_perm8_t perm)
+{
+ return ((perm >> FFA_MEM_PERM_DATA_OFFSET) & FFA_MEM_PERM_DATA_MASK);
+}
+
+smc_args_t ffa_mem_frag_rx(uint64_t handle, uint32_t recv_length);
+bool ffa_mem_relinquish(void);
+bool ffa_rx_release(void);
+bool memory_relinquish(struct ffa_mem_relinquish_descriptor *m, uint64_t handle,
+ ffa_endpoint_id16_t id);
+bool ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages);
+bool memory_retrieve(struct mailbox *mb,
+ struct ffa_mtd **retrieved,
+ uint64_t handle, ffa_endpoint_id16_t sender,
+ ffa_endpoint_id16_t *receivers, uint32_t receiver_count,
+ ffa_mtd_flag32_t flags, uint32_t *frag_length,
+ uint32_t *total_length);
+
+smc_args_t ffa_msg_send_direct_req(ffa_endpoint_id16_t sender,
+ ffa_endpoint_id16_t receiver,
+ uint32_t arg3,
+ uint32_t arg4,
+ uint32_t arg5,
+ uint32_t arg6,
+ uint32_t arg7);
+smc_args_t *ffa_msg_send_direct_resp(ffa_endpoint_id16_t sender,
+ ffa_endpoint_id16_t receiver,
+ uint32_t arg3,
+ uint32_t arg4,
+ uint32_t arg5,
+ uint32_t arg6,
+ uint32_t arg7);
+#endif /* FFA_HELPERS_H */
diff --git a/bl32/tsp/tsp.mk b/bl32/tsp/tsp.mk
index 3fd6d99..c31b9b5 100644
--- a/bl32/tsp/tsp.mk
+++ b/bl32/tsp/tsp.mk
@@ -1,17 +1,24 @@
#
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
INCLUDES += -Iinclude/bl32/tsp
-BL32_SOURCES += bl32/tsp/tsp_main.c \
- bl32/tsp/aarch64/tsp_entrypoint.S \
+ifeq (${SPMC_AT_EL3},1)
+ BL32_SOURCES += bl32/tsp/tsp_ffa_main.c \
+ bl32/tsp/ffa_helpers.c
+else
+ BL32_SOURCES += bl32/tsp/tsp_main.c
+endif
+
+BL32_SOURCES += bl32/tsp/aarch64/tsp_entrypoint.S \
bl32/tsp/aarch64/tsp_exceptions.S \
bl32/tsp/aarch64/tsp_request.S \
bl32/tsp/tsp_interrupt.c \
bl32/tsp/tsp_timer.c \
+ bl32/tsp/tsp_common.c \
common/aarch64/early_exceptions.S \
lib/locks/exclusive/aarch64/spinlock.S
diff --git a/bl32/tsp/tsp_common.c b/bl32/tsp/tsp_common.c
new file mode 100644
index 0000000..908b4ff
--- /dev/null
+++ b/bl32/tsp/tsp_common.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
+
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <bl32/tsp/tsp.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+#include <platform_tsp.h>
+#include "tsp_private.h"
+
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Per cpu data structure to populate parameters for an SMC in C code and use
+ * a pointer to this structure in assembler code to populate x0-x7.
+ ******************************************************************************/
+static smc_args_t tsp_smc_args[PLATFORM_CORE_COUNT];
+
+/*******************************************************************************
+ * Per cpu data structure to keep track of TSP activity
+ ******************************************************************************/
+work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
+
+smc_args_t *set_smc_args(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ uint32_t linear_id;
+ smc_args_t *pcpu_smc_args;
+
+ /*
+ * Return to Secure Monitor by raising an SMC. The results of the
+ * service are passed as an arguments to the SMC.
+ */
+ linear_id = plat_my_core_pos();
+ pcpu_smc_args = &tsp_smc_args[linear_id];
+ write_sp_arg(pcpu_smc_args, SMC_ARG0, arg0);
+ write_sp_arg(pcpu_smc_args, SMC_ARG1, arg1);
+ write_sp_arg(pcpu_smc_args, SMC_ARG2, arg2);
+ write_sp_arg(pcpu_smc_args, SMC_ARG3, arg3);
+ write_sp_arg(pcpu_smc_args, SMC_ARG4, arg4);
+ write_sp_arg(pcpu_smc_args, SMC_ARG5, arg5);
+ write_sp_arg(pcpu_smc_args, SMC_ARG6, arg6);
+ write_sp_arg(pcpu_smc_args, SMC_ARG7, arg7);
+
+ return pcpu_smc_args;
+}
+
+/*******************************************************************************
+ * Setup function for TSP.
+ ******************************************************************************/
+void tsp_setup(void)
+{
+ /* Perform early platform-specific setup. */
+ tsp_early_platform_setup();
+
+ /* Perform late platform-specific setup. */
+ tsp_plat_arch_setup();
+
+#if ENABLE_PAUTH
+ /*
+ * Assert that the ARMv8.3-PAuth registers are present or an access
+ * fault will be triggered when they are being saved or restored.
+ */
+ assert(is_armv8_3_pauth_present());
+#endif /* ENABLE_PAUTH */
+}
+
+/*******************************************************************************
+ * This function performs any remaining bookkeeping in the test secure payload
+ * before the system is switched off (in response to a psci SYSTEM_OFF request).
+ ******************************************************************************/
+smc_args_t *tsp_system_off_main(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ uint32_t linear_id = plat_my_core_pos();
+
+ /* Update this cpu's statistics. */
+ tsp_stats[linear_id].smc_count++;
+ tsp_stats[linear_id].eret_count++;
+
+ INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr());
+ INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
+ tsp_stats[linear_id].smc_count,
+ tsp_stats[linear_id].eret_count);
+
+ /* Indicate to the SPD that we have completed this request. */
+ return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
+}
+
+/*******************************************************************************
+ * This function performs any remaining bookkeeping in the test secure payload
+ * before the system is reset (in response to a psci SYSTEM_RESET request).
+ ******************************************************************************/
+smc_args_t *tsp_system_reset_main(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ uint32_t linear_id = plat_my_core_pos();
+
+ /* Update this cpu's statistics. */
+ tsp_stats[linear_id].smc_count++;
+ tsp_stats[linear_id].eret_count++;
+
+ INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr());
+ INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
+ tsp_stats[linear_id].smc_count,
+ tsp_stats[linear_id].eret_count);
+
+ /* Indicate to the SPD that we have completed this request. */
+ return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0);
+}
+
+/*******************************************************************************
+ * TSP smc abort handler. This function is called when aborting a preempted
+ * yielding SMC request. It should cleanup all resources owned by the SMC
+ * handler such as locks or dynamically allocated memory so following SMC
+ * request are executed in a clean environment.
+ ******************************************************************************/
+smc_args_t *tsp_abort_smc_handler(uint64_t func,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0);
+}
diff --git a/bl32/tsp/tsp_ffa_main.c b/bl32/tsp/tsp_ffa_main.c
new file mode 100644
index 0000000..53dbd03
--- /dev/null
+++ b/bl32/tsp/tsp_ffa_main.c
@@ -0,0 +1,655 @@
+/*
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
+
+#include "../../services/std_svc/spm/el3_spmc/spmc.h"
+#include "../../services/std_svc/spm/el3_spmc/spmc_shared_mem.h"
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <bl32/tsp/tsp.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include "ffa_helpers.h"
+#include <lib/psci/psci.h>
+#include <lib/spinlock.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include <platform_tsp.h>
+#include <services/ffa_svc.h>
+#include "tsp_private.h"
+
+#include <platform_def.h>
+
+static ffa_endpoint_id16_t tsp_id, spmc_id;
+uint8_t mem_region_buffer[4096 * 2] __aligned(PAGE_SIZE);
+
+/* Partition Mailbox. */
+static uint8_t send_page[PAGE_SIZE] __aligned(PAGE_SIZE);
+static uint8_t recv_page[PAGE_SIZE] __aligned(PAGE_SIZE);
+
+/*
+ * Declare a global mailbox for use within the TSP.
+ * This will be initialized appropriately when the buffers
+ * are mapped with the SPMC.
+ */
+static struct mailbox mailbox;
+
+/*******************************************************************************
+ * This enum is used to handle test cases driven from the FF-A Test Driver.
+ ******************************************************************************/
+/* Keep in Sync with FF-A Test Driver. */
+enum message_t {
+ /* Partition Only Messages. */
+ FF_A_RELAY_MESSAGE = 0,
+
+ /* Basic Functionality. */
+ FF_A_ECHO_MESSAGE,
+ FF_A_RELAY_MESSAGE_EL3,
+
+ /* Memory Sharing. */
+ FF_A_MEMORY_SHARE,
+ FF_A_MEMORY_SHARE_FRAGMENTED,
+ FF_A_MEMORY_LEND,
+ FF_A_MEMORY_LEND_FRAGMENTED,
+
+ FF_A_MEMORY_SHARE_MULTI_ENDPOINT,
+ FF_A_MEMORY_LEND_MULTI_ENDPOINT,
+
+ LAST,
+ FF_A_RUN_ALL = 255,
+ FF_A_OP_MAX = 256
+};
+
+#if SPMC_AT_EL3
+extern void tsp_cpu_on_entry(void);
+#endif
+
+/*******************************************************************************
+ * Test Functions.
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Enable the TSP to forward the received message to another partition and ask
+ * it to echo the value back in order to validate direct messages functionality.
+ ******************************************************************************/
+static int ffa_test_relay(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ smc_args_t ffa_forward_result;
+ ffa_endpoint_id16_t receiver = arg5;
+
+ ffa_forward_result = ffa_msg_send_direct_req(ffa_endpoint_source(arg1),
+ receiver,
+ FF_A_ECHO_MESSAGE, arg4,
+ 0, 0, 0);
+ return ffa_forward_result._regs[3];
+}
+
+/*******************************************************************************
+ * This function handles memory management tests, currently share and lend.
+ * This test supports the use of FRAG_RX to use memory descriptors that do not
+ * fit in a single 4KB buffer.
+ ******************************************************************************/
+static int test_memory_send(ffa_endpoint_id16_t sender, uint64_t handle,
+ ffa_mtd_flag32_t flags, bool multi_endpoint)
+{
+ struct ffa_mtd *m;
+ struct ffa_emad_v1_0 *receivers;
+ struct ffa_comp_mrd *composite;
+ int ret, status = 0;
+ unsigned int mem_attrs;
+ char *ptr;
+ ffa_endpoint_id16_t source = sender;
+ uint32_t total_length, recv_length = 0;
+
+ /*
+ * In the case that we're testing multiple endpoints choose a partition
+ * ID that resides in the normal world so the SPMC won't detect it as
+ * invalid.
+ * TODO: Should get endpoint receiver id and flag as input from NWd.
+ */
+ uint32_t receiver_count = multi_endpoint ? 2 : 1;
+ ffa_endpoint_id16_t test_receivers[2] = { tsp_id, 0x10 };
+
+ /* Ensure that the sender ID resides in the normal world. */
+ if (ffa_is_secure_world_id(sender)) {
+ ERROR("Invalid sender ID 0x%x.\n", sender);
+ return FFA_ERROR_DENIED;
+ }
+
+ if (!memory_retrieve(&mailbox, &m, handle, source, test_receivers,
+ receiver_count, flags, &recv_length,
+ &total_length)) {
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
+
+ receivers = (struct ffa_emad_v1_0 *)
+ ((uint8_t *) m + m->emad_offset);
+ while (total_length != recv_length) {
+ smc_args_t ffa_return;
+ uint32_t frag_length;
+
+ ffa_return = ffa_mem_frag_rx(handle, recv_length);
+
+ if (ffa_return._regs[0] == FFA_ERROR) {
+ WARN("TSP: failed to resume mem with handle %lx\n",
+ handle);
+ return ffa_return._regs[2];
+ }
+ frag_length = ffa_return._regs[3];
+
+ /* Validate frag_length is less than total_length and mailbox size. */
+ if (frag_length > total_length ||
+ frag_length > (mailbox.rxtx_page_count * PAGE_SIZE)) {
+ ERROR("Invalid parameters!\n");
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
+
+ /* Validate frag_length is less than remaining mem_region_buffer size. */
+ if (frag_length + recv_length >= REGION_BUF_SIZE) {
+ ERROR("Out of memory!\n");
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
+
+ memcpy(&mem_region_buffer[recv_length], mailbox.rx_buffer,
+ frag_length);
+
+ if (ffa_rx_release()) {
+ ERROR("Failed to release buffer!\n");
+ return FFA_ERROR_DENIED;
+ }
+
+ recv_length += frag_length;
+
+ assert(recv_length <= total_length);
+ }
+
+ composite = ffa_memory_region_get_composite(m, 0);
+ if (composite == NULL) {
+ WARN("Failed to get composite descriptor!\n");
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
+
+ VERBOSE("Address: %p; page_count: %x %lx\n",
+ (void *)composite->address_range_array[0].address,
+ composite->address_range_array[0].page_count, PAGE_SIZE);
+
+ /* This test is only concerned with RW permissions. */
+ if (ffa_get_data_access_attr(
+ receivers[0].mapd.memory_access_permissions) != FFA_MEM_PERM_RW) {
+ ERROR("Data permission in retrieve response %x does not match share/lend %x!\n",
+ ffa_get_data_access_attr(receivers[0].mapd.memory_access_permissions),
+ FFA_MEM_PERM_RW);
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
+
+ mem_attrs = MT_RW_DATA | MT_EXECUTE_NEVER;
+
+ /* Only expecting to be sent memory from NWd so map accordingly. */
+ mem_attrs |= MT_NS;
+
+ for (uint32_t i = 0U; i < composite->address_range_count; i++) {
+ size_t size = composite->address_range_array[i].page_count * PAGE_SIZE;
+
+ ptr = (char *) composite->address_range_array[i].address;
+ ret = mmap_add_dynamic_region(
+ (uint64_t)ptr,
+ (uint64_t)ptr,
+ size, mem_attrs);
+
+ if (ret != 0) {
+ ERROR("Failed [%u] mmap_add_dynamic_region %u (%lx) (%lx) (%x)!\n",
+ i, ret,
+ (uint64_t)composite->address_range_array[i].address,
+ size, mem_attrs);
+
+ /* Remove mappings created in this transaction. */
+ for (i--; i >= 0U; i--) {
+ ret = mmap_remove_dynamic_region(
+ (uint64_t)ptr,
+ composite->address_range_array[i].page_count * PAGE_SIZE);
+
+ if (ret != 0) {
+ ERROR("Failed [%d] mmap_remove_dynamic_region!\n", i);
+ panic();
+ }
+ }
+ return FFA_ERROR_NO_MEMORY;
+ }
+
+ /* Increment memory region for validation purposes. */
+ ++(*ptr);
+
+ /*
+ * Read initial magic number from memory region for
+ * validation purposes.
+ */
+ if (!i) {
+ status = *ptr;
+ }
+ }
+
+ for (uint32_t i = 0U; i < composite->address_range_count; i++) {
+ ret = mmap_remove_dynamic_region(
+ (uint64_t)composite->address_range_array[i].address,
+ composite->address_range_array[i].page_count * PAGE_SIZE);
+
+ if (ret != 0) {
+ ERROR("Failed [%d] mmap_remove_dynamic_region!\n", i);
+ return FFA_ERROR_NO_MEMORY;
+ }
+ }
+
+ if (!memory_relinquish((struct ffa_mem_relinquish_descriptor *)mailbox.tx_buffer,
+ m->handle, tsp_id)) {
+ ERROR("Failed to relinquish memory region!\n");
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
+ return status;
+}
+
+static smc_args_t *send_ffa_pm_success(void)
+{
+ return set_smc_args(FFA_MSG_SEND_DIRECT_RESP_SMC32,
+ ((tsp_id & FFA_DIRECT_MSG_ENDPOINT_ID_MASK)
+ << FFA_DIRECT_MSG_SOURCE_SHIFT) | spmc_id,
+ FFA_FWK_MSG_BIT |
+ (FFA_PM_MSG_PM_RESP & FFA_FWK_MSG_MASK),
+ 0, 0, 0, 0, 0);
+}
+
+/*******************************************************************************
+ * This function performs any remaining book keeping in the test secure payload
+ * before this cpu is turned off in response to a psci cpu_off request.
+ ******************************************************************************/
+smc_args_t *tsp_cpu_off_main(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ uint32_t linear_id = plat_my_core_pos();
+
+ /*
+ * This cpu is being turned off, so disable the timer to prevent the
+ * secure timer interrupt from interfering with power down. A pending
+ * interrupt will be lost but we do not care as we are turning off.
+ */
+ tsp_generic_timer_stop();
+
+ /* Update this cpu's statistics. */
+ tsp_stats[linear_id].smc_count++;
+ tsp_stats[linear_id].eret_count++;
+ tsp_stats[linear_id].cpu_off_count++;
+
+ INFO("TSP: cpu 0x%lx off request\n", read_mpidr());
+ INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n",
+ read_mpidr(),
+ tsp_stats[linear_id].smc_count,
+ tsp_stats[linear_id].eret_count,
+ tsp_stats[linear_id].cpu_off_count);
+
+ return send_ffa_pm_success();
+}
+
+/*******************************************************************************
+ * This function performs any book keeping in the test secure payload before
+ * this cpu's architectural state is saved in response to an earlier psci
+ * cpu_suspend request.
+ ******************************************************************************/
+smc_args_t *tsp_cpu_suspend_main(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ uint32_t linear_id = plat_my_core_pos();
+
+ /*
+ * Save the time context and disable it to prevent the secure timer
+ * interrupt from interfering with wakeup from the suspend state.
+ */
+ tsp_generic_timer_save();
+ tsp_generic_timer_stop();
+
+ /* Update this cpu's statistics. */
+ tsp_stats[linear_id].smc_count++;
+ tsp_stats[linear_id].eret_count++;
+ tsp_stats[linear_id].cpu_suspend_count++;
+
+ INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n",
+ read_mpidr(),
+ tsp_stats[linear_id].smc_count,
+ tsp_stats[linear_id].eret_count,
+ tsp_stats[linear_id].cpu_suspend_count);
+
+ return send_ffa_pm_success();
+}
+
+/*******************************************************************************
+ * This function performs any bookkeeping in the test secure payload after this
+ * cpu's architectural state has been restored after wakeup from an earlier psci
+ * cpu_suspend request.
+ ******************************************************************************/
+smc_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ uint32_t linear_id = plat_my_core_pos();
+
+ /* Restore the generic timer context. */
+ tsp_generic_timer_restore();
+
+ /* Update this cpu's statistics. */
+ tsp_stats[linear_id].smc_count++;
+ tsp_stats[linear_id].eret_count++;
+ tsp_stats[linear_id].cpu_resume_count++;
+
+ INFO("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n",
+ read_mpidr(), max_off_pwrlvl);
+ 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_resume_count);
+
+ return send_ffa_pm_success();
+}
+
+/*******************************************************************************
+ * This function handles framework messages. Currently only PM.
+ ******************************************************************************/
+static smc_args_t *handle_framework_message(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ /* Check if it is a power management message from the SPMC. */
+ if (ffa_endpoint_source(arg1) != spmc_id) {
+ goto err;
+ }
+
+ /* Check if it is a PM request message. */
+ if ((arg2 & FFA_FWK_MSG_MASK) == FFA_FWK_MSG_PSCI) {
+ /* Check if it is a PSCI CPU_OFF request. */
+ if (arg3 == PSCI_CPU_OFF) {
+ return tsp_cpu_off_main(arg0, arg1, arg2, arg3,
+ arg4, arg5, arg6, arg7);
+ } else if (arg3 == PSCI_CPU_SUSPEND_AARCH64) {
+ return tsp_cpu_suspend_main(arg0, arg1, arg2, arg3,
+ arg4, arg5, arg6, arg7);
+ }
+ } else if ((arg2 & FFA_FWK_MSG_MASK) == FFA_PM_MSG_WB_REQ) {
+ /* Check it is a PSCI Warm Boot request. */
+ if (arg3 == FFA_WB_TYPE_NOTS2RAM) {
+ return tsp_cpu_resume_main(arg0, arg1, arg2, arg3,
+ arg4, arg5, arg6, arg7);
+ }
+ }
+
+err:
+ ERROR("%s: Unknown framework message!\n", __func__);
+ panic();
+}
+
+/*******************************************************************************
+ * Handles partition messages. Exercised from the FF-A Test Driver.
+ ******************************************************************************/
+static smc_args_t *handle_partition_message(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ uint16_t sender = ffa_endpoint_source(arg1);
+ uint16_t receiver = ffa_endpoint_destination(arg1);
+ int status = -1;
+ const bool multi_endpoint = true;
+
+ switch (arg3) {
+ case FF_A_MEMORY_SHARE:
+ INFO("TSP Tests: Memory Share Request--\n");
+ status = test_memory_send(sender, arg4, FFA_FLAG_SHARE_MEMORY, !multi_endpoint);
+ break;
+
+ case FF_A_MEMORY_LEND:
+ INFO("TSP Tests: Memory Lend Request--\n");
+ status = test_memory_send(sender, arg4, FFA_FLAG_LEND_MEMORY, !multi_endpoint);
+ break;
+
+ case FF_A_MEMORY_SHARE_MULTI_ENDPOINT:
+ INFO("TSP Tests: Multi Endpoint Memory Share Request--\n");
+ status = test_memory_send(sender, arg4, FFA_FLAG_SHARE_MEMORY, multi_endpoint);
+ break;
+
+ case FF_A_MEMORY_LEND_MULTI_ENDPOINT:
+ INFO("TSP Tests: Multi Endpoint Memory Lend Request--\n");
+ status = test_memory_send(sender, arg4, FFA_FLAG_LEND_MEMORY, multi_endpoint);
+ break;
+ case FF_A_RELAY_MESSAGE:
+ INFO("TSP Tests: Relaying message--\n");
+ status = ffa_test_relay(arg0, arg1, arg2, arg3, arg4,
+ arg5, arg6, arg7);
+ break;
+
+ case FF_A_ECHO_MESSAGE:
+ INFO("TSP Tests: echo message--\n");
+ status = arg4;
+ break;
+
+ default:
+ INFO("TSP Tests: Unknown request ID %d--\n", (int) arg3);
+ }
+
+ /* Swap the sender and receiver in the response. */
+ return ffa_msg_send_direct_resp(receiver, sender, status, 0, 0, 0, 0);
+}
+
+/*******************************************************************************
+ * This function implements the event loop for handling FF-A ABI invocations.
+ ******************************************************************************/
+static smc_args_t *tsp_event_loop(uint64_t smc_fid,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ /* Panic if the SPMC did not forward an FF-A call. */
+ if (!is_ffa_fid(smc_fid)) {
+ ERROR("%s: Unknown SMC FID (0x%lx)\n", __func__, smc_fid);
+ panic();
+ }
+
+ switch (smc_fid) {
+ case FFA_INTERRUPT:
+ /*
+ * IRQs were enabled upon re-entry into the TSP. The interrupt
+ * must have been handled by now. Return to the SPMC indicating
+ * the same.
+ */
+ return set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0);
+
+ case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+ case FFA_MSG_SEND_DIRECT_REQ_SMC32:
+ /* Check if a framework message, handle accordingly. */
+ if ((arg2 & FFA_FWK_MSG_BIT)) {
+ return handle_framework_message(smc_fid, arg1, arg2, arg3,
+ arg4, arg5, arg6, arg7);
+ }
+ return handle_partition_message(smc_fid, arg1, arg2, arg3,
+ arg4, arg5, arg6, arg7);
+ }
+
+ ERROR("%s: Unsupported FF-A FID (0x%lx)\n", __func__, smc_fid);
+ panic();
+}
+
+static smc_args_t *tsp_loop(smc_args_t *args)
+{
+ smc_args_t ret;
+
+ do {
+ /* --------------------------------------------
+ * Mask FIQ interrupts to avoid preemption
+ * in case EL3 SPMC delegates an IRQ next or a
+ * managed exit. Lastly, unmask IRQs so that
+ * they can be handled immediately upon re-entry.
+ * ---------------------------------------------
+ */
+ write_daifset(DAIF_FIQ_BIT);
+ write_daifclr(DAIF_IRQ_BIT);
+ ret = smc_helper(args->_regs[0], args->_regs[1], args->_regs[2],
+ args->_regs[3], args->_regs[4], args->_regs[5],
+ args->_regs[6], args->_regs[7]);
+ args = tsp_event_loop(ret._regs[0], ret._regs[1], ret._regs[2],
+ ret._regs[3], ret._regs[4], ret._regs[5],
+ ret._regs[6], ret._regs[7]);
+ } while (1);
+
+ /* Not Reached. */
+ return NULL;
+}
+
+/*******************************************************************************
+ * TSP main entry point where it gets the opportunity to initialize its secure
+ * state/applications. Once the state is initialized, it must return to the
+ * SPD with a pointer to the 'tsp_vector_table' jump table.
+ ******************************************************************************/
+uint64_t tsp_main(void)
+{
+ smc_args_t smc_args = {0};
+
+ NOTICE("TSP: %s\n", version_string);
+ NOTICE("TSP: %s\n", build_message);
+ INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE);
+ INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE);
+ uint32_t linear_id = plat_my_core_pos();
+
+ /* Initialize the platform. */
+ tsp_platform_setup();
+
+ /* Initialize secure/applications state here. */
+ tsp_generic_timer_start();
+
+ /* Register secondary entrypoint with the SPMC. */
+ smc_args = smc_helper(FFA_SECONDARY_EP_REGISTER_SMC64,
+ (uint64_t) tsp_cpu_on_entry,
+ 0, 0, 0, 0, 0, 0);
+ if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) {
+ ERROR("TSP could not register secondary ep (0x%lx)\n",
+ smc_args._regs[2]);
+ panic();
+ }
+ /* Get TSP's endpoint id. */
+ smc_args = smc_helper(FFA_ID_GET, 0, 0, 0, 0, 0, 0, 0);
+ if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) {
+ ERROR("TSP could not get own ID (0x%lx) on core%d\n",
+ smc_args._regs[2], linear_id);
+ panic();
+ }
+
+ tsp_id = smc_args._regs[2];
+ INFO("TSP FF-A endpoint id = 0x%x\n", tsp_id);
+
+ /* Get the SPMC ID. */
+ smc_args = smc_helper(FFA_SPM_ID_GET, 0, 0, 0, 0, 0, 0, 0);
+ if (smc_args._regs[SMC_ARG0] != FFA_SUCCESS_SMC32) {
+ ERROR("TSP could not get SPMC ID (0x%lx) on core%d\n",
+ smc_args._regs[2], linear_id);
+ panic();
+ }
+
+ spmc_id = smc_args._regs[2];
+
+ /* Call RXTX_MAP to map a 4k RX and TX buffer. */
+ if (ffa_rxtx_map((uintptr_t) send_page,
+ (uintptr_t) recv_page, 1)) {
+ ERROR("TSP could not map it's RX/TX Buffers\n");
+ panic();
+ }
+
+ mailbox.tx_buffer = send_page;
+ mailbox.rx_buffer = recv_page;
+ mailbox.rxtx_page_count = 1;
+
+ /* Update this cpu's statistics. */
+ tsp_stats[linear_id].smc_count++;
+ tsp_stats[linear_id].eret_count++;
+ tsp_stats[linear_id].cpu_on_count++;
+
+ INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
+ read_mpidr(),
+ tsp_stats[linear_id].smc_count,
+ tsp_stats[linear_id].eret_count,
+ tsp_stats[linear_id].cpu_on_count);
+
+ /* Tell SPMD that we are done initialising. */
+ tsp_loop(set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0));
+
+ /* Not reached. */
+ return 0;
+}
+
+/*******************************************************************************
+ * This function performs any remaining book keeping in the test secure payload
+ * after this cpu's architectural state has been setup in response to an earlier
+ * psci cpu_on request.
+ ******************************************************************************/
+smc_args_t *tsp_cpu_on_main(void)
+{
+ uint32_t linear_id = plat_my_core_pos();
+
+ /* Initialize secure/applications state here. */
+ tsp_generic_timer_start();
+
+ /* Update this cpu's statistics. */
+ tsp_stats[linear_id].smc_count++;
+ tsp_stats[linear_id].eret_count++;
+ tsp_stats[linear_id].cpu_on_count++;
+ INFO("TSP: cpu 0x%lx turned on\n", read_mpidr());
+ INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
+ read_mpidr(),
+ tsp_stats[linear_id].smc_count,
+ tsp_stats[linear_id].eret_count,
+ tsp_stats[linear_id].cpu_on_count);
+ /* ---------------------------------------------
+ * Jump to the main event loop to return to EL3
+ * and be ready for the next request on this cpu.
+ * ---------------------------------------------
+ */
+ return tsp_loop(set_smc_args(FFA_MSG_WAIT, 0, 0, 0, 0, 0, 0, 0));
+}
diff --git a/bl32/tsp/tsp_interrupt.c b/bl32/tsp/tsp_interrupt.c
index 430b5dd..a847b6c 100644
--- a/bl32/tsp/tsp_interrupt.c
+++ b/bl32/tsp/tsp_interrupt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -35,8 +35,6 @@
if (type == TSP_HANDLE_SEL1_INTR_AND_RETURN)
tsp_stats[linear_id].sync_sel1_intr_ret_count++;
-#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
- spin_lock(&console_lock);
VERBOSE("TSP: cpu 0x%lx sync s-el1 interrupt request from 0x%" PRIx64 "\n",
read_mpidr(), elr_el3);
VERBOSE("TSP: cpu 0x%lx: %d sync s-el1 interrupt requests,"
@@ -44,8 +42,6 @@
read_mpidr(),
tsp_stats[linear_id].sync_sel1_intr_count,
tsp_stats[linear_id].sync_sel1_intr_ret_count);
- spin_unlock(&console_lock);
-#endif
}
/******************************************************************************
@@ -58,12 +54,8 @@
uint32_t linear_id = plat_my_core_pos();
tsp_stats[linear_id].preempt_intr_count++;
-#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
- spin_lock(&console_lock);
VERBOSE("TSP: cpu 0x%lx: %d preempt interrupt requests\n",
read_mpidr(), tsp_stats[linear_id].preempt_intr_count);
- spin_unlock(&console_lock);
-#endif
return TSP_PREEMPTED;
}
@@ -91,8 +83,18 @@
id = plat_ic_get_pending_interrupt_id();
/* TSP can only handle the secure physical timer interrupt */
- if (id != TSP_IRQ_SEC_PHY_TIMER)
+ if (id != TSP_IRQ_SEC_PHY_TIMER) {
+#if SPMC_AT_EL3
+ /*
+ * With the EL3 FF-A SPMC we expect only Timer secure interrupt to fire in
+ * the TSP, so panic if any other interrupt does.
+ */
+ ERROR("Unexpected interrupt id %u\n", id);
+ panic();
+#else
return tsp_handle_preemption();
+#endif
+ }
/*
* Acknowledge and handle the secure timer interrupt. Also sanity check
@@ -105,13 +107,9 @@
/* Update the statistics and print some messages */
tsp_stats[linear_id].sel1_intr_count++;
-#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
- spin_lock(&console_lock);
VERBOSE("TSP: cpu 0x%lx handled S-EL1 interrupt %d\n",
read_mpidr(), id);
VERBOSE("TSP: cpu 0x%lx: %d S-EL1 requests\n",
read_mpidr(), tsp_stats[linear_id].sel1_intr_count);
- spin_unlock(&console_lock);
-#endif
return 0;
}
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index 522c1b4..df9903b 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -15,85 +15,10 @@
#include <common/debug.h>
#include <lib/spinlock.h>
#include <plat/common/platform.h>
-#include <platform_def.h>
#include <platform_tsp.h>
-
#include "tsp_private.h"
-
-/*******************************************************************************
- * Lock to control access to the console
- ******************************************************************************/
-spinlock_t console_lock;
-
-/*******************************************************************************
- * Per cpu data structure to populate parameters for an SMC in C code and use
- * a pointer to this structure in assembler code to populate x0-x7
- ******************************************************************************/
-static tsp_args_t tsp_smc_args[PLATFORM_CORE_COUNT];
-
-/*******************************************************************************
- * Per cpu data structure to keep track of TSP activity
- ******************************************************************************/
-work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
-
-/*******************************************************************************
- * The TSP memory footprint starts at address BL32_BASE and ends with the
- * linker symbol __BL32_END__. Use these addresses to compute the TSP image
- * size.
- ******************************************************************************/
-#define BL32_TOTAL_LIMIT BL32_END
-#define BL32_TOTAL_SIZE (BL32_TOTAL_LIMIT - (unsigned long) BL32_BASE)
-
-static tsp_args_t *set_smc_args(uint64_t arg0,
- uint64_t arg1,
- uint64_t arg2,
- uint64_t arg3,
- uint64_t arg4,
- uint64_t arg5,
- uint64_t arg6,
- uint64_t arg7)
-{
- uint32_t linear_id;
- tsp_args_t *pcpu_smc_args;
-
- /*
- * Return to Secure Monitor by raising an SMC. The results of the
- * service are passed as an arguments to the SMC
- */
- linear_id = plat_my_core_pos();
- pcpu_smc_args = &tsp_smc_args[linear_id];
- write_sp_arg(pcpu_smc_args, TSP_ARG0, arg0);
- write_sp_arg(pcpu_smc_args, TSP_ARG1, arg1);
- write_sp_arg(pcpu_smc_args, TSP_ARG2, arg2);
- write_sp_arg(pcpu_smc_args, TSP_ARG3, arg3);
- write_sp_arg(pcpu_smc_args, TSP_ARG4, arg4);
- write_sp_arg(pcpu_smc_args, TSP_ARG5, arg5);
- write_sp_arg(pcpu_smc_args, TSP_ARG6, arg6);
- write_sp_arg(pcpu_smc_args, TSP_ARG7, arg7);
-
- return pcpu_smc_args;
-}
-
-/*******************************************************************************
- * Setup function for TSP.
- ******************************************************************************/
-void tsp_setup(void)
-{
- /* Perform early platform-specific setup */
- tsp_early_platform_setup();
-
- /* Perform late platform-specific setup */
- tsp_plat_arch_setup();
-
-#if ENABLE_PAUTH
- /*
- * Assert that the ARMv8.3-PAuth registers are present or an access
- * fault will be triggered when they are being saved or restored.
- */
- assert(is_armv8_3_pauth_present());
-#endif /* ENABLE_PAUTH */
-}
+#include <platform_def.h>
/*******************************************************************************
* TSP main entry point where it gets the opportunity to initialize its secure
@@ -120,15 +45,11 @@
tsp_stats[linear_id].eret_count++;
tsp_stats[linear_id].cpu_on_count++;
-#if LOG_LEVEL >= LOG_LEVEL_INFO
- spin_lock(&console_lock);
INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
read_mpidr(),
tsp_stats[linear_id].smc_count,
tsp_stats[linear_id].eret_count,
tsp_stats[linear_id].cpu_on_count);
- spin_unlock(&console_lock);
-#endif
return (uint64_t) &tsp_vector_table;
}
@@ -137,7 +58,7 @@
* after this cpu's architectural state has been setup in response to an earlier
* psci cpu_on request.
******************************************************************************/
-tsp_args_t *tsp_cpu_on_main(void)
+smc_args_t *tsp_cpu_on_main(void)
{
uint32_t linear_id = plat_my_core_pos();
@@ -149,16 +70,12 @@
tsp_stats[linear_id].eret_count++;
tsp_stats[linear_id].cpu_on_count++;
-#if LOG_LEVEL >= LOG_LEVEL_INFO
- spin_lock(&console_lock);
INFO("TSP: cpu 0x%lx turned on\n", read_mpidr());
INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu on requests\n",
read_mpidr(),
tsp_stats[linear_id].smc_count,
tsp_stats[linear_id].eret_count,
tsp_stats[linear_id].cpu_on_count);
- spin_unlock(&console_lock);
-#endif
/* Indicate to the SPD that we have completed turned ourselves on */
return set_smc_args(TSP_ON_DONE, 0, 0, 0, 0, 0, 0, 0);
}
@@ -167,7 +84,7 @@
* This function performs any remaining book keeping in the test secure payload
* before this cpu is turned off in response to a psci cpu_off request.
******************************************************************************/
-tsp_args_t *tsp_cpu_off_main(uint64_t arg0,
+smc_args_t *tsp_cpu_off_main(uint64_t arg0,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
@@ -190,16 +107,12 @@
tsp_stats[linear_id].eret_count++;
tsp_stats[linear_id].cpu_off_count++;
-#if LOG_LEVEL >= LOG_LEVEL_INFO
- spin_lock(&console_lock);
INFO("TSP: cpu 0x%lx off request\n", read_mpidr());
INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu off requests\n",
read_mpidr(),
tsp_stats[linear_id].smc_count,
tsp_stats[linear_id].eret_count,
tsp_stats[linear_id].cpu_off_count);
- spin_unlock(&console_lock);
-#endif
/* Indicate to the SPD that we have completed this request */
return set_smc_args(TSP_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
@@ -210,7 +123,7 @@
* this cpu's architectural state is saved in response to an earlier psci
* cpu_suspend request.
******************************************************************************/
-tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0,
+smc_args_t *tsp_cpu_suspend_main(uint64_t arg0,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
@@ -233,15 +146,11 @@
tsp_stats[linear_id].eret_count++;
tsp_stats[linear_id].cpu_suspend_count++;
-#if LOG_LEVEL >= LOG_LEVEL_INFO
- spin_lock(&console_lock);
INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu suspend requests\n",
read_mpidr(),
tsp_stats[linear_id].smc_count,
tsp_stats[linear_id].eret_count,
tsp_stats[linear_id].cpu_suspend_count);
- spin_unlock(&console_lock);
-#endif
/* Indicate to the SPD that we have completed this request */
return set_smc_args(TSP_SUSPEND_DONE, 0, 0, 0, 0, 0, 0, 0);
@@ -252,7 +161,7 @@
* cpu's architectural state has been restored after wakeup from an earlier psci
* cpu_suspend request.
******************************************************************************/
-tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
+smc_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
@@ -271,8 +180,6 @@
tsp_stats[linear_id].eret_count++;
tsp_stats[linear_id].cpu_resume_count++;
-#if LOG_LEVEL >= LOG_LEVEL_INFO
- spin_lock(&console_lock);
INFO("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n",
read_mpidr(), max_off_pwrlvl);
INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n",
@@ -280,83 +187,17 @@
tsp_stats[linear_id].smc_count,
tsp_stats[linear_id].eret_count,
tsp_stats[linear_id].cpu_resume_count);
- spin_unlock(&console_lock);
-#endif
/* Indicate to the SPD that we have completed this request */
return set_smc_args(TSP_RESUME_DONE, 0, 0, 0, 0, 0, 0, 0);
}
/*******************************************************************************
- * This function performs any remaining bookkeeping in the test secure payload
- * before the system is switched off (in response to a psci SYSTEM_OFF request)
- ******************************************************************************/
-tsp_args_t *tsp_system_off_main(uint64_t arg0,
- uint64_t arg1,
- uint64_t arg2,
- uint64_t arg3,
- uint64_t arg4,
- uint64_t arg5,
- uint64_t arg6,
- uint64_t arg7)
-{
- uint32_t linear_id = plat_my_core_pos();
-
- /* Update this cpu's statistics */
- tsp_stats[linear_id].smc_count++;
- tsp_stats[linear_id].eret_count++;
-
-#if LOG_LEVEL >= LOG_LEVEL_INFO
- spin_lock(&console_lock);
- INFO("TSP: cpu 0x%lx SYSTEM_OFF request\n", read_mpidr());
- INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
- tsp_stats[linear_id].smc_count,
- tsp_stats[linear_id].eret_count);
- spin_unlock(&console_lock);
-#endif
-
- /* Indicate to the SPD that we have completed this request */
- return set_smc_args(TSP_SYSTEM_OFF_DONE, 0, 0, 0, 0, 0, 0, 0);
-}
-
-/*******************************************************************************
- * This function performs any remaining bookkeeping in the test secure payload
- * before the system is reset (in response to a psci SYSTEM_RESET request)
- ******************************************************************************/
-tsp_args_t *tsp_system_reset_main(uint64_t arg0,
- uint64_t arg1,
- uint64_t arg2,
- uint64_t arg3,
- uint64_t arg4,
- uint64_t arg5,
- uint64_t arg6,
- uint64_t arg7)
-{
- uint32_t linear_id = plat_my_core_pos();
-
- /* Update this cpu's statistics */
- tsp_stats[linear_id].smc_count++;
- tsp_stats[linear_id].eret_count++;
-
-#if LOG_LEVEL >= LOG_LEVEL_INFO
- spin_lock(&console_lock);
- INFO("TSP: cpu 0x%lx SYSTEM_RESET request\n", read_mpidr());
- INFO("TSP: cpu 0x%lx: %d smcs, %d erets requests\n", read_mpidr(),
- tsp_stats[linear_id].smc_count,
- tsp_stats[linear_id].eret_count);
- spin_unlock(&console_lock);
-#endif
-
- /* Indicate to the SPD that we have completed this request */
- return set_smc_args(TSP_SYSTEM_RESET_DONE, 0, 0, 0, 0, 0, 0, 0);
-}
-
-/*******************************************************************************
* TSP fast smc handler. The secure monitor jumps to this function by
* doing the ERET after populating X0-X7 registers. The arguments are received
* in the function arguments in order. Once the service is rendered, this
* function returns to Secure Monitor by raising SMC.
******************************************************************************/
-tsp_args_t *tsp_smc_handler(uint64_t func,
+smc_args_t *tsp_smc_handler(uint64_t func,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
@@ -376,16 +217,12 @@
tsp_stats[linear_id].smc_count++;
tsp_stats[linear_id].eret_count++;
-#if LOG_LEVEL >= LOG_LEVEL_INFO
- spin_lock(&console_lock);
INFO("TSP: cpu 0x%lx received %s smc 0x%" PRIx64 "\n", read_mpidr(),
((func >> 31) & 1) == 1 ? "fast" : "yielding",
func);
INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(),
tsp_stats[linear_id].smc_count,
tsp_stats[linear_id].eret_count);
- spin_unlock(&console_lock);
-#endif
/* Render secure services and obtain results here */
results[0] = arg1;
@@ -427,11 +264,7 @@
break;
case TSP_CHECK_DIT:
if (!is_armv8_4_dit_present()) {
-#if LOG_LEVEL >= LOG_LEVEL_ERROR
- spin_lock(&console_lock);
ERROR("DIT not supported\n");
- spin_unlock(&console_lock);
-#endif
results[0] = 0;
results[1] = 0xffff;
break;
@@ -451,21 +284,3 @@
results[1],
0, 0, 0, 0);
}
-
-/*******************************************************************************
- * TSP smc abort handler. This function is called when aborting a preempted
- * yielding SMC request. It should cleanup all resources owned by the SMC
- * handler such as locks or dynamically allocated memory so following SMC
- * request are executed in a clean environment.
- ******************************************************************************/
-tsp_args_t *tsp_abort_smc_handler(uint64_t func,
- uint64_t arg1,
- uint64_t arg2,
- uint64_t arg3,
- uint64_t arg4,
- uint64_t arg5,
- uint64_t arg6,
- uint64_t arg7)
-{
- return set_smc_args(TSP_ABORT_DONE, 0, 0, 0, 0, 0, 0, 0);
-}
diff --git a/bl32/tsp/tsp_private.h b/bl32/tsp/tsp_private.h
index 38d9732..66873e2 100644
--- a/bl32/tsp/tsp_private.h
+++ b/bl32/tsp/tsp_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,28 +7,22 @@
#ifndef TSP_PRIVATE_H
#define TSP_PRIVATE_H
-/* Definitions to help the assembler access the SMC/ERET args structure */
-#define TSP_ARGS_SIZE 0x40
-#define TSP_ARG0 0x0
-#define TSP_ARG1 0x8
-#define TSP_ARG2 0x10
-#define TSP_ARG3 0x18
-#define TSP_ARG4 0x20
-#define TSP_ARG5 0x28
-#define TSP_ARG6 0x30
-#define TSP_ARG7 0x38
-#define TSP_ARGS_END 0x40
-
+/*******************************************************************************
+ * The TSP memory footprint starts at address BL32_BASE and ends with the
+ * linker symbol __BL32_END__. Use these addresses to compute the TSP image
+ * size.
+ ******************************************************************************/
+#define BL32_TOTAL_LIMIT BL32_END
+#define BL32_TOTAL_SIZE (BL32_TOTAL_LIMIT - (unsigned long) BL32_BASE)
#ifndef __ASSEMBLER__
#include <stdint.h>
-#include <platform_def.h> /* For CACHE_WRITEBACK_GRANULE */
-
#include <bl32/tsp/tsp.h>
#include <lib/cassert.h>
#include <lib/spinlock.h>
+#include <smccc_helpers.h>
typedef struct work_statistics {
/* Number of s-el1 interrupts on this cpu */
@@ -47,23 +41,22 @@
uint32_t cpu_resume_count; /* Number of cpu resume requests */
} __aligned(CACHE_WRITEBACK_GRANULE) work_statistics_t;
-typedef struct tsp_args {
- uint64_t _regs[TSP_ARGS_END >> 3];
-} __aligned(CACHE_WRITEBACK_GRANULE) tsp_args_t;
-
/* Macros to access members of the above structure using their offsets */
#define read_sp_arg(args, offset) ((args)->_regs[offset >> 3])
#define write_sp_arg(args, offset, val) (((args)->_regs[offset >> 3]) \
= val)
-/*
- * Ensure that the assembler's view of the size of the tsp_args is the
- * same as the compilers
- */
-CASSERT(TSP_ARGS_SIZE == sizeof(tsp_args_t), assert_sp_args_size_mismatch);
uint128_t tsp_get_magic(void);
-tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
+smc_args_t *set_smc_args(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7);
+smc_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
@@ -71,7 +64,7 @@
uint64_t arg5,
uint64_t arg6,
uint64_t arg7);
-tsp_args_t *tsp_cpu_suspend_main(uint64_t arg0,
+smc_args_t *tsp_cpu_suspend_main(uint64_t arg0,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
@@ -79,8 +72,8 @@
uint64_t arg5,
uint64_t arg6,
uint64_t arg7);
-tsp_args_t *tsp_cpu_on_main(void);
-tsp_args_t *tsp_cpu_off_main(uint64_t arg0,
+smc_args_t *tsp_cpu_on_main(void);
+smc_args_t *tsp_cpu_off_main(uint64_t arg0,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
@@ -101,7 +94,6 @@
/* Data structure to keep track of TSP statistics */
-extern spinlock_t console_lock;
extern work_statistics_t tsp_stats[PLATFORM_CORE_COUNT];
/* Vector table of jumps */
@@ -111,7 +103,7 @@
int32_t tsp_common_int_handler(void);
int32_t tsp_handle_preemption(void);
-tsp_args_t *tsp_abort_smc_handler(uint64_t func,
+smc_args_t *tsp_abort_smc_handler(uint64_t func,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
@@ -120,25 +112,25 @@
uint64_t arg6,
uint64_t arg7);
-tsp_args_t *tsp_smc_handler(uint64_t func,
- uint64_t arg1,
- uint64_t arg2,
- uint64_t arg3,
- uint64_t arg4,
- uint64_t arg5,
- uint64_t arg6,
- uint64_t arg7);
+smc_args_t *tsp_smc_handler(uint64_t func,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7);
-tsp_args_t *tsp_system_reset_main(uint64_t arg0,
- uint64_t arg1,
- uint64_t arg2,
- uint64_t arg3,
- uint64_t arg4,
- uint64_t arg5,
- uint64_t arg6,
- uint64_t arg7);
+smc_args_t *tsp_system_reset_main(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7);
-tsp_args_t *tsp_system_off_main(uint64_t arg0,
+smc_args_t *tsp_system_off_main(uint64_t arg0,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
diff --git a/changelog.yaml b/changelog.yaml
index fa42e96..d3e235d 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -89,6 +89,9 @@
- title: Activity Monitors Extension (FEAT_AMU)
scope: amu
+ - title: Confidential Compute Architecture (CCA)
+ scope: cca
+
- title: Support for the `HCRX_EL2` register (FEAT_HCX)
scope: hcx
@@ -116,6 +119,15 @@
- title: Statistical profiling Extension (FEAT_SPE)
scope: spe
+ - title: Branch Record Buffer Extension (FEAT_BRBE)
+ scope: brbe
+
+ - title: Extended Cache Index (FEAT_CCIDX)
+ scope: ccidx
+
+ - title: Trapping support for RNDR/RNDRRS (FEAT_RNG_TRAP)
+ scope: rng-trap
+
- title: Platforms
subsections:
@@ -158,6 +170,9 @@
- title: Morello
scope: morello
+ - title: N1SDP
+ scope: n1sdp
+
- title: RD
scope: rd
@@ -185,6 +200,12 @@
deprecated:
- plat/tc0
+ - title: Corstone-1000
+ scope: corstone-1000
+
+ - title: Broadcom
+ scope: brcm
+
- title: Intel
scope: intel
@@ -246,6 +267,12 @@
- plat/mediatek/mt8195
- plat/mdeiatek/mt8195
+ - title: MT8186
+ scope: mt8186
+
+ deprecated:
+ - plat/mediatek/mt8186
+
- title: NVIDIA
scope: nvidia
@@ -260,6 +287,9 @@
- title: Tegra 132
scope: tegra132
+ - title: Tegra 194
+ scope: tegra194
+
- title: NXP
scope: nxp
@@ -284,6 +314,12 @@
- plat/imx/imx8m
subsections:
+ - title: i.MX 8M Nano
+ scope: imx8mn
+
+ deprecated:
+ - plat/imx/imx8m/imx8mn
+
- title: i.MX 8M Mini
scope: imx8mm
@@ -296,6 +332,12 @@
deprecated:
- plat/imx/imx8m/imx8mp
+ - title: i.MX 8Q
+ scope: imx8mq
+
+ deprecated:
+ - plat/imx/imx8m/imx8mq
+
- title: Layerscape
scope: layerscape
@@ -316,6 +358,19 @@
deprecated:
- plat/nxp/ls1028ardb
+ - title: LS1043A
+ scope: ls1043a
+
+ deprecated:
+ - plat/nxp/ls1043a
+
+ subsections:
+ - title: LS1043ARDB
+ scope: ls1043ardb
+
+ deprecated:
+ - plat/nxp/ls1043ardb
+
- title: LX2
scope: lx2
@@ -349,6 +404,16 @@
- title: LS1046AQDS
scope: ls1046aqds
+ - title: LS1088A
+ scope: ls1088a
+
+ subsections:
+ - title: LS1088ARDB
+ scope: ls1088ardb
+
+ - title: LS1088AQDS
+ scope: ls1088aqds
+
- title: QEMU
scope: qemu
@@ -426,12 +491,26 @@
- plat/st
subsections:
- - title: ST32MP1
+ - title: STM32MP1
scope: stm32mp1
deprecated:
- plat/st/stm32mp1
+ subsections:
+ - title: STM32MP13
+ scope: stm32mp13
+
+ - title: STM32MP15
+ scope: stm32mp15
+
+ - title: Texas Instruments
+ scope: ti
+
+ subsections:
+ - title: K3
+ scope: k3
+
- title: Xilinx
scope: xilinx
@@ -467,6 +546,16 @@
- title: BL2
scope: bl2
+ - title: BL31
+ scope: bl31
+
+ - title: BL32
+ scope: bl32
+
+ subsections:
+ - title: TSP
+ scope: tsp
+
- title: Services
scope: services
@@ -480,16 +569,25 @@
- title: RME
scope: rme
+ subsections:
+ - title: TRP
+ scope: trp
+
+ - title: RMMD
+ scope: rmmd
+
- title: SPM
scope: spm
- deprecated:
- - spmc
- - spmd
- - SPMD
+ subsections:
+ - title: EL3 SPMC
+ scope: el3-spmc
- - title: SPM MM
- scope: spm-mm
+ - title: SPMD
+ scope: spmd
+
+ - title: SPM MM
+ scope: spm-mm
- title: Libraries
@@ -508,6 +606,10 @@
deprecated:
- el3_runtime
+ subsections:
+ - title: Context Management
+ scope: cm
+
- title: FCONF
scope: fconf
@@ -535,6 +637,18 @@
- title: Translation Tables
scope: xlat
+ - title: C Standard Library
+ scope: libc
+
+ - title: Locks
+ scope: locks
+
+ - title: PSA
+ scope: psa
+
+ - title: Context Management
+ scope: context mgmt
+
- title: Drivers
subsections:
@@ -548,6 +662,9 @@
- title: CryptoCell-713
scope: cc-713
+ - title: Generic Clock
+ scope: clk
+
- title: FWU
scope: fwu
@@ -594,8 +711,8 @@
deprecated:
- spi_nand
- - title: Partition
- scope: partition
+ - title: GUID Partition Tables Support
+ scope: guid-partition
- title: SCMI
scope: scmi
@@ -628,6 +745,21 @@
- title: GIC-600AE
scope: gic600ae
+ - title: SMMU
+ scope: smmu
+
+ - title: MHU
+ scope: mhu
+
+ deprecated:
+ - drivers/arm/mhu
+
+ - title: RSS
+ scope: rss
+
+ deprecated:
+ - drivers/arm/rss
+
- title: TZC
scope: tzc
@@ -638,6 +770,12 @@
deprecated:
- drivers/tzc400
+ - title: TZC-380
+ scope: tzc380
+
+ deprecated:
+ - drivers/tzc380
+
- title: Marvell
scope: marvell-drivers
@@ -748,6 +886,24 @@
- title: NXP Crypto
scope: nxp-crypto
+ - title: DDR
+ scope: nxp-ddr
+
+ - title: GIC
+ scope: nxp-gic
+
+ - title: CSU
+ scope: nxp-csu
+
+ - title: IFC NAND
+ scope: nxp-ifc-nand
+
+ - title: IFC NOR
+ scope: nxp-ifc-nor
+
+ - title: TZC-380
+ scope: nxp-tzc380
+
- title: Renesas
scope: renesas-drivers
@@ -793,9 +949,6 @@
- io-stm32image
- io_stm32image
- - title: fiptool
- scope: fiptool
-
- title: I2C
scope: st-i2c
@@ -908,6 +1061,13 @@
deprecated:
- fdts stm32mp1
+ subsections:
+ - title: STM32MP13
+ scope: stm32mp13-fdts
+
+ - title: STM32MP15
+ scope: stm32mp15-fdts
+
- title: PIE
scope: pie
@@ -961,6 +1121,9 @@
- title: Prerequisites
scope: prerequisites
+ - title: Threat Model
+ scope: threat-model
+
- title: Build System
scope: build
@@ -984,6 +1147,15 @@
- title: NXP Tools
scope: nxp-tools
+ - title: Firmware Image Package Tool
+ scope: fiptool
+
+ - title: Secure Partition Tool
+ scope: sptool
+
+ - title: Certificate Creation Tool
+ scope: cert-create
+
- title: Dependencies
scope: deps
diff --git a/common/bl_common.c b/common/bl_common.c
index 9bfaafd..8fce02f 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -269,3 +269,12 @@
#endif
#undef PRINT_IMAGE_ARG
}
+
+/*
+ * This function is for returning the TF-A version
+ */
+const char *get_version(void)
+{
+ extern const char version[];
+ return version;
+}
diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c
index de02b46..1bad74f 100644
--- a/common/fdt_fixup.c
+++ b/common/fdt_fixup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -394,6 +394,110 @@
return offs;
}
+/*******************************************************************************
+ * fdt_add_cpu_idle_states() - add PSCI CPU idle states to cpu nodes in the DT
+ * @dtb: pointer to the device tree blob in memory
+ * @states: array of idle state descriptions, ending with empty element
+ *
+ * Add information about CPU idle states to the devicetree. This function
+ * assumes that CPU idle states are not already present in the devicetree, and
+ * that all CPU states are equally applicable to all CPUs.
+ *
+ * See arm/idle-states.yaml and arm/psci.yaml in the (Linux kernel) DT binding
+ * documentation for more details.
+ *
+ * Return: 0 on success, a negative error value otherwise.
+ ******************************************************************************/
+int fdt_add_cpu_idle_states(void *dtb, const struct psci_cpu_idle_state *state)
+{
+ int cpu_node, cpus_node, idle_states_node, ret;
+ uint32_t count, phandle;
+
+ ret = fdt_find_max_phandle(dtb, &phandle);
+ phandle++;
+ if (ret < 0) {
+ return ret;
+ }
+
+ cpus_node = fdt_path_offset(dtb, "/cpus");
+ if (cpus_node < 0) {
+ return cpus_node;
+ }
+
+ /* Create the idle-states node and its child nodes. */
+ idle_states_node = fdt_add_subnode(dtb, cpus_node, "idle-states");
+ if (idle_states_node < 0) {
+ return idle_states_node;
+ }
+
+ ret = fdt_setprop_string(dtb, idle_states_node, "entry-method", "psci");
+ if (ret < 0) {
+ return ret;
+ }
+
+ for (count = 0U; state->name != NULL; count++, phandle++, state++) {
+ int idle_state_node;
+
+ idle_state_node = fdt_add_subnode(dtb, idle_states_node,
+ state->name);
+ if (idle_state_node < 0) {
+ return idle_state_node;
+ }
+
+ fdt_setprop_string(dtb, idle_state_node, "compatible",
+ "arm,idle-state");
+ fdt_setprop_u32(dtb, idle_state_node, "arm,psci-suspend-param",
+ state->power_state);
+ if (state->local_timer_stop) {
+ fdt_setprop_empty(dtb, idle_state_node,
+ "local-timer-stop");
+ }
+ fdt_setprop_u32(dtb, idle_state_node, "entry-latency-us",
+ state->entry_latency_us);
+ fdt_setprop_u32(dtb, idle_state_node, "exit-latency-us",
+ state->exit_latency_us);
+ fdt_setprop_u32(dtb, idle_state_node, "min-residency-us",
+ state->min_residency_us);
+ if (state->wakeup_latency_us) {
+ fdt_setprop_u32(dtb, idle_state_node,
+ "wakeup-latency-us",
+ state->wakeup_latency_us);
+ }
+ fdt_setprop_u32(dtb, idle_state_node, "phandle", phandle);
+ }
+
+ if (count == 0U) {
+ return 0;
+ }
+
+ /* Link each cpu node to the idle state nodes. */
+ fdt_for_each_subnode(cpu_node, dtb, cpus_node) {
+ const char *device_type;
+ fdt32_t *value;
+
+ /* Only process child nodes with device_type = "cpu". */
+ device_type = fdt_getprop(dtb, cpu_node, "device_type", NULL);
+ if (device_type == NULL || strcmp(device_type, "cpu") != 0) {
+ continue;
+ }
+
+ /* Allocate space for the list of phandles. */
+ ret = fdt_setprop_placeholder(dtb, cpu_node, "cpu-idle-states",
+ count * sizeof(phandle),
+ (void **)&value);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* Fill in the phandles of the idle state nodes. */
+ for (uint32_t i = 0U; i < count; ++i) {
+ value[i] = cpu_to_fdt32(phandle - count + i);
+ }
+ }
+
+ return 0;
+}
+
/**
* fdt_adjust_gic_redist() - Adjust GICv3 redistributor size
* @dtb: Pointer to the DT blob in memory
@@ -479,3 +583,44 @@
(ac + sc + ac) * 4,
val, sc * 4);
}
+/**
+ * fdt_set_mac_address () - store MAC address in device tree
+ * @dtb: pointer to the device tree blob in memory
+ * @eth_idx: number of Ethernet interface in /aliases node
+ * @mac_addr: pointer to 6 byte MAC address to store
+ *
+ * Use the generic local-mac-address property in a network device DT node
+ * to define the MAC address this device should be using. Many platform
+ * network devices lack device-specific non-volatile storage to hold this
+ * address, and leave it up to firmware to find and store a unique MAC
+ * address in the DT.
+ * The MAC address could be read from some board or firmware defined storage,
+ * or could be derived from some other unique property like a serial number.
+ *
+ * Return: 0 on success, a negative libfdt error value otherwise.
+ */
+int fdt_set_mac_address(void *dtb, unsigned int ethernet_idx,
+ const uint8_t *mac_addr)
+{
+ char eth_alias[12];
+ const char *path;
+ int node;
+
+ if (ethernet_idx > 9U) {
+ return -FDT_ERR_BADVALUE;
+ }
+ snprintf(eth_alias, sizeof(eth_alias), "ethernet%d", ethernet_idx);
+
+ path = fdt_get_alias(dtb, eth_alias);
+ if (path == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ node = fdt_path_offset(dtb, path);
+ if (node < 0) {
+ ERROR("Path \"%s\" not found in DT: %d\n", path, node);
+ return node;
+ }
+
+ return fdt_setprop(dtb, node, "local-mac-address", mac_addr, 6);
+}
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 2a9673f..1b065b1 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -618,3 +618,24 @@
return ret;
}
+
+/*
+ * Find a given node in device tree. If not present, add it.
+ * Returns offset of node found/added on success, and < 0 on error.
+ */
+int fdtw_find_or_add_subnode(void *fdt, int parentoffset, const char *name)
+{
+ int offset;
+
+ offset = fdt_subnode_offset(fdt, parentoffset, name);
+
+ if (offset == -FDT_ERR_NOTFOUND) {
+ offset = fdt_add_subnode(fdt, parentoffset, name);
+ }
+
+ if (offset < 0) {
+ ERROR("%s: %s: %s\n", __func__, name, fdt_strerror(offset));
+ }
+
+ return offset;
+}
diff --git a/common/feat_detect.c b/common/feat_detect.c
new file mode 100644
index 0000000..ee34588
--- /dev/null
+++ b/common/feat_detect.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/feat_detect.h>
+
+/*******************************************************************************
+ * This section lists the wrapper modules for each feature to evaluate the
+ * feature states (FEAT_STATE_1 and FEAT_STATE_2) and perform necessary action
+ * as below:
+ *
+ * It verifies whether the FEAT_XXX (eg: FEAT_SB) is supported by the PE or not.
+ * Without this check an exception would occur during context save/restore
+ * routines, if the feature is enabled but not supported by PE.
+ ******************************************************************************/
+
+/******************************************
+ * Feature : FEAT_SB (Speculation Barrier)
+ *****************************************/
+static void read_feat_sb(void)
+{
+#if (ENABLE_FEAT_SB == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_0_feat_sb_present(), "SB");
+#endif
+}
+
+/******************************************************
+ * Feature : FEAT_CSV2_2 (Cache Speculation Variant 2)
+ *****************************************************/
+static void read_feat_csv2_2(void)
+{
+#if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_0_feat_csv2_2_present(), "CSV2_2");
+#endif
+}
+
+/***********************************************
+ * Feature : FEAT_PAN (Privileged Access Never)
+ **********************************************/
+static void read_feat_pan(void)
+{
+#if (ENABLE_FEAT_PAN == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_1_pan_present(), "PAN");
+#endif
+}
+
+/******************************************************
+ * Feature : FEAT_VHE (Virtualization Host Extensions)
+ *****************************************************/
+static void read_feat_vhe(void)
+{
+#if (ENABLE_FEAT_VHE == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_1_vhe_present(), "VHE");
+#endif
+}
+
+/*******************************************************************************
+ * Feature : FEAT_RAS (Reliability, Availability, and Serviceability Extension)
+ ******************************************************************************/
+static void read_feat_ras(void)
+{
+#if (RAS_EXTENSION == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_2_feat_ras_present(), "RAS");
+#endif
+}
+
+/************************************************
+ * Feature : FEAT_PAUTH (Pointer Authentication)
+ ***********************************************/
+static void read_feat_pauth(void)
+{
+#if (ENABLE_PAUTH == FEAT_STATE_1) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_3_pauth_present(), "PAUTH");
+#endif
+}
+
+/************************************************************
+ * Feature : FEAT_DIT (Data Independent Timing Instructions)
+ ***********************************************************/
+static void read_feat_dit(void)
+{
+#if (ENABLE_FEAT_DIT == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_4_feat_dit_present(), "DIT");
+#endif
+}
+
+/*********************************************************
+ * Feature : FEAT_AMUv1 (Activity Monitors Extensions v1)
+ ********************************************************/
+static void read_feat_amuv1(void)
+{
+#if (ENABLE_FEAT_AMUv1 == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_4_feat_amuv1_present(), "AMUv1");
+#endif
+}
+
+/****************************************************************************
+ * Feature : FEAT_MPAM (Memory Partitioning and Monitoring (MPAM) Extension)
+ ***************************************************************************/
+static void read_feat_mpam(void)
+{
+#if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_1)
+ feat_detect_panic(get_mpam_version() != 0U, "MPAM");
+#endif
+}
+
+/**************************************************************
+ * Feature : FEAT_NV2 (Enhanced Nested Virtualization Support)
+ *************************************************************/
+static void read_feat_nv2(void)
+{
+#if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_1)
+ unsigned int nv = get_armv8_4_feat_nv_support();
+
+ feat_detect_panic((nv == ID_AA64MMFR2_EL1_NV2_SUPPORTED), "NV2");
+#endif
+}
+
+/***********************************
+ * Feature : FEAT_SEL2 (Secure EL2)
+ **********************************/
+static void read_feat_sel2(void)
+{
+#if (ENABLE_FEAT_SEL2 == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_4_sel2_present(), "SEL2");
+#endif
+}
+
+/****************************************************
+ * Feature : FEAT_TRF (Self-hosted Trace Extensions)
+ ***************************************************/
+static void read_feat_trf(void)
+{
+#if (ENABLE_TRF_FOR_NS == FEAT_STATE_1)
+ feat_detect_panic(is_arm8_4_feat_trf_present(), "TRF");
+#endif
+}
+
+/************************************************
+ * Feature : FEAT_MTE (Memory Tagging Extension)
+ ***********************************************/
+static void read_feat_mte(void)
+{
+#if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_1)
+ unsigned int mte = get_armv8_5_mte_support();
+
+ feat_detect_panic((mte != MTE_UNIMPLEMENTED), "MTE");
+#endif
+}
+
+/***********************************************
+ * Feature : FEAT_RNG (Random Number Generator)
+ **********************************************/
+static void read_feat_rng(void)
+{
+#if (ENABLE_FEAT_RNG == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_5_rng_present(), "RNG");
+#endif
+}
+
+/****************************************************
+ * Feature : FEAT_BTI (Branch Target Identification)
+ ***************************************************/
+static void read_feat_bti(void)
+{
+#if (ENABLE_BTI == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_5_bti_present(), "BTI");
+#endif
+}
+
+/****************************************
+ * Feature : FEAT_FGT (Fine Grain Traps)
+ ***************************************/
+static void read_feat_fgt(void)
+{
+#if (ENABLE_FEAT_FGT == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_6_fgt_present(), "FGT");
+#endif
+}
+
+/***********************************************
+ * Feature : FEAT_AMUv1p1 (AMU Extensions v1.1)
+ **********************************************/
+static void read_feat_amuv1p1(void)
+{
+#if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_6_feat_amuv1p1_present(), "AMUv1p1");
+#endif
+}
+
+/*******************************************************
+ * Feature : FEAT_ECV (Enhanced Counter Virtualization)
+ ******************************************************/
+static void read_feat_ecv(void)
+{
+#if (ENABLE_FEAT_ECV == FEAT_STATE_1)
+ unsigned int ecv = get_armv8_6_ecv_support();
+
+ feat_detect_panic(((ecv == ID_AA64MMFR0_EL1_ECV_SUPPORTED) ||
+ (ecv == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH)), "ECV");
+#endif
+}
+
+/***********************************************************
+ * Feature : FEAT_TWED (Delayed Trapping of WFE Instruction)
+ **********************************************************/
+static void read_feat_twed(void)
+{
+#if (ENABLE_FEAT_TWED == FEAT_STATE_1)
+ feat_detect_panic(is_armv8_6_twed_present(), "TWED");
+#endif
+}
+
+/******************************************************************
+ * Feature : FEAT_HCX (Extended Hypervisor Configuration Register)
+ *****************************************************************/
+static void read_feat_hcx(void)
+{
+#if (ENABLE_FEAT_HCX == FEAT_STATE_1)
+ feat_detect_panic(is_feat_hcx_present(), "HCX");
+#endif
+}
+
+/**************************************************
+ * Feature : FEAT_RME (Realm Management Extension)
+ *************************************************/
+static void read_feat_rme(void)
+{
+#if (ENABLE_RME == FEAT_STATE_1)
+ feat_detect_panic((get_armv9_2_feat_rme_support() !=
+ ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED), "RME");
+#endif
+}
+
+/******************************************************
+ * Feature : FEAT_BRBE (Branch Record Buffer Extension)
+ *****************************************************/
+static void read_feat_brbe(void)
+{
+#if (ENABLE_BRBE_FOR_NS == FEAT_STATE_1)
+ feat_detect_panic(is_feat_brbe_present(), "BRBE");
+#endif
+}
+
+/******************************************************
+ * Feature : FEAT_TRBE (Trace Buffer Extension)
+ *****************************************************/
+static void read_feat_trbe(void)
+{
+#if (ENABLE_TRBE_FOR_NS == FEAT_STATE_1)
+ feat_detect_panic(is_feat_trbe_present(), "TRBE");
+#endif
+}
+
+/******************************************************************
+ * Feature : FEAT_RNG_TRAP (Trapping support for RNDR/RNDRRS)
+ *****************************************************************/
+static void read_feat_rng_trap(void)
+{
+#if (ENABLE_FEAT_RNG_TRAP == FEAT_STATE_1)
+ feat_detect_panic(is_feat_rng_trap_present(), "RNG_TRAP");
+#endif
+}
+
+/***********************************************************************************
+ * TF-A supports many Arm architectural features starting from arch version
+ * (8.0 till 8.7+). These features are mostly enabled through build flags. This
+ * mechanism helps in validating these build flags in the early boot phase
+ * either in BL1 or BL31 depending on the platform and assists in identifying
+ * and notifying the features which are enabled but not supported by the PE.
+ *
+ * It reads all the enabled features ID-registers and ensures the features
+ * are supported by the PE.
+ * In case if they aren't it stops booting at an early phase and logs the error
+ * messages, notifying the platforms about the features that are not supported.
+ *
+ * Further the procedure is implemented with a tri-state approach for each feature:
+ * ENABLE_FEAT_xxx = 0 : The feature is disabled statically at compile time
+ * ENABLE_FEAT_xxx = 1 : The feature is enabled and must be present in hardware.
+ * There will be panic if feature is not present at cold boot.
+ * ENABLE_FEAT_xxx = 2 : The feature is enabled but dynamically enabled at runtime
+ * depending on hardware capability.
+ *
+ * For better readability, state values are defined with macros namely:
+ * { FEAT_STATE_0, FEAT_STATE_1, FEAT_STATE_2 } taking values as their naming.
+ **********************************************************************************/
+void detect_arch_features(void)
+{
+ /* v8.0 features */
+ read_feat_sb();
+ read_feat_csv2_2();
+
+ /* v8.1 features */
+ read_feat_pan();
+ read_feat_vhe();
+
+ /* v8.2 features */
+ read_feat_ras();
+
+ /* v8.3 features */
+ read_feat_pauth();
+
+ /* v8.4 features */
+ read_feat_dit();
+ read_feat_amuv1();
+ read_feat_mpam();
+ read_feat_nv2();
+ read_feat_sel2();
+ read_feat_trf();
+
+ /* v8.5 features */
+ read_feat_mte();
+ read_feat_rng();
+ read_feat_bti();
+ read_feat_rng_trap();
+
+ /* v8.6 features */
+ read_feat_amuv1p1();
+ read_feat_fgt();
+ read_feat_ecv();
+ read_feat_twed();
+
+ /* v8.7 features */
+ read_feat_hcx();
+
+ /* v9.0 features */
+ read_feat_brbe();
+ read_feat_trbe();
+
+ /* v9.2 features */
+ read_feat_rme();
+}
diff --git a/common/uuid.c b/common/uuid.c
index ac6db50..3e47eb4 100644
--- a/common/uuid.c
+++ b/common/uuid.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -132,3 +132,27 @@
return 0;
}
+/*
+ * Helper function to check if 2 UUIDs match.
+ */
+bool uuid_match(uint32_t *uuid1, uint32_t *uuid2)
+{
+ return !memcmp(uuid1, uuid2, sizeof(uint32_t) * 4);
+}
+
+/*
+ * Helper function to copy from one UUID struct to another.
+ */
+void copy_uuid(uint32_t *to_uuid, uint32_t *from_uuid)
+{
+ to_uuid[0] = from_uuid[0];
+ to_uuid[1] = from_uuid[1];
+ to_uuid[2] = from_uuid[2];
+ to_uuid[3] = from_uuid[3];
+}
+
+bool is_null_uuid(uint32_t *uuid)
+{
+ return (uuid[0] == 0 && uuid[1] == 0 &&
+ uuid[2] == 0 && uuid[3] == 0);
+}
diff --git a/docs/about/contact.rst b/docs/about/contact.rst
index 4440a37..4f482bd 100644
--- a/docs/about/contact.rst
+++ b/docs/about/contact.rst
@@ -47,10 +47,10 @@
via their partner managers.
.. _`issue tracker`: https://developer.trustedfirmware.org
-.. _`TF-A development`: https://lists.trustedfirmware.org/pipermail/tf-a/
-.. _`TF-A-Tests development`: https://lists.trustedfirmware.org/pipermail/tf-a-tests/
-.. _`summary of all the lists`: https://lists.trustedfirmware.org
+.. _`TF-A development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
+.. _`TF-A-Tests development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a-tests.lists.trustedfirmware.org/
+.. _`summary of all the lists`: https://lists.trustedfirmware.org/mailman3/lists/
--------------
-*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index ad125cf..96a0523 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -48,6 +48,8 @@
:|G|: `madhukar-Arm`_
:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
:|G|: `raghuncstate`_
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
.. _code owners:
@@ -75,8 +77,6 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Mark Dykes <mark.dykes@arm.com>
:|G|: `mardyk01`_
-:|M|: John Powell <john.powell@arm.com>
-:|G|: `john-powell-arm`_
:|F|: services/std_svc/sdei/
Trusted Boot
@@ -89,8 +89,14 @@
:|G|: `ManishVB-Arm`_
:|F|: drivers/auth/
-Secure Partition Manager (SPM)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Secure Partition Manager Core (EL3 FF-A SPMC)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Marc Bonnici <marc.bonnici@arm.com>
+:|G|: `marcbonnici`_
+:|F|: services/std_svc/spm/el3_spmc/\*
+
+Secure Partition Manager Dispatcher (SPMD)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Olivier Deprez <olivier.deprez@arm.com>
:|G|: `odeprez`_
:|M|: Manish Pandey <manish.pandey2@arm.com>
@@ -99,26 +105,30 @@
:|G|: `max-shvetsov`_
:|M|: Joao Alves <Joao.Alves@arm.com>
:|G|: `J-Alves`_
-:|F|: services/std_svc/spm\*
+:|F|: services/std_svc/spmd/\*
Exception Handling Framework (EHF)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
:|G|: `ManishVB-Arm`_
-:|M|: John Powell <john.powell@arm.com>
-:|G|: `john-powell-arm`_
:|F|: bl31/ehf.c
+Realm Management Monitor Dispatcher (RMMD)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
+:|G|: `javieralso-arm`_
+:|F|: services/std_svc/rmmd/\*
+:|F|: include/services/rmmd_svc.h
+:|F|: include/services/rmm_core_manifest.h
+
Realm Management Extension (RME)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Bipin Ravi <bipin.ravi@arm.com>
:|G|: `bipinravi-arm`_
:|M|: Mark Dykes <mark.dykes@arm.com>
:|G|: `mardyk01`_
-:|M|: John Powell <john.powell@arm.com>
-:|G|: `john-powell-arm`_
-:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
-:|G|: `zelalem-aweke`_
+:|M|: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
+:|G|: `javieralso-arm`_
Drivers, Libraries and Framework Code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -154,9 +164,9 @@
JTAG DCC console driver
^^^^^^^^^^^^^^^^^^^^^^^
-:M: Michal Simek <michal.simek@xilinx.com>
+:M: Michal Simek <michal.simek@amd.com>
:G: `michalsimek`_
-:M: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@xilinx.com>
+:M: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>
:G: `venkatesh`_
:F: drivers/arm/dcc/
:F: include/drivers/arm/dcc.h
@@ -193,16 +203,12 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Joao Alves <Joao.Alves@arm.com>
:|G|: `J-Alves`_
-:|M|: Jimmy Brisson <Jimmy.Brisson@arm.com>
-:|G|: `theotherjimmy`_
:|F|: lib/pmf/
Arm CPU libraries
^^^^^^^^^^^^^^^^^
:|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
:|G|: `laurenw-arm`_
-:|M|: John Powell <john.powell@arm.com>
-:|G|: `john-powell-arm`_
:|F|: lib/cpus/
Reliability Availability Serviceabilty (RAS) framework
@@ -225,8 +231,6 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
:|G|: `zelalem-aweke`_
-:|M|: Jimmy Brisson <Jimmy.Brisson@arm.com>
-:|G|: `theotherjimmy`_
:|F|: lib/extensions/mpam/
Pointer Authentication (PAuth) and Branch Target Identification (BTI) extensions
@@ -241,22 +245,12 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
:|G|: `zelalem-aweke`_
-:|M|: Jimmy Brisson <Jimmy.Brisson@arm.com>
-:|G|: `theotherjimmy`_
:|F|: lib/extensions/spe/
-Scalable Vector Extension (SVE)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Jimmy Brisson <Jimmy.Brisson@arm.com>
-:|G|: `theotherjimmy`_
-:|F|: lib/extensions/sve/
-
Standard C library
^^^^^^^^^^^^^^^^^^
:|M|: Alexei Fedorov <Alexei.Fedorov@arm.com>
:|G|: `AlexeiFedorov`_
-:|M|: John Powell <john.powell@arm.com>
-:|G|: `john-powell-arm`_
:|F|: lib/libc/
Library At ROM (ROMlib)
@@ -293,6 +287,20 @@
:|G|: `odeprez`_
:|F|: drivers/arm/gic/
+Message Handling Unit (MHU) driver
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: David Vincze <david.vincze@arm.com>
+:|G|: `davidvincze`_
+:|F|: include/drivers/arm/mhu.h
+:|F|: drivers/arm/mhu
+
+Runtime Security Subsystem (RSS) comms driver
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: David Vincze <david.vincze@arm.com>
+:|G|: `davidvincze`_
+:|F|: include/drivers/arm/rss_comms.h
+:|F|: drivers/arm/rss
+
Libfdt wrappers
^^^^^^^^^^^^^^^
:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
@@ -315,9 +323,28 @@
:|G|: `AlexeiFedorov`_
:|M|: Javier Almansa Sobrino <Javier.AlmansaSobrino@arm.com>
:|G|: `javieralso-arm`_
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
:|F|: drivers/measured_boot
:|F|: include/drivers/measured_boot
-:|F|: plat/arm/board/fvp/fvp_measured_boot.c
+:|F|: docs/components/measured_boot
+:|F|: plat/arm/board/fvp/fvp\*_measured_boot.c
+
+PSA Firmware Update
+^^^^^^^^^^^^^^^^^^^
+:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
+:|G|: `ManishVB-Arm`_
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
+:|F|: drivers/fwu
+:|F|: include/drivers/fwu
+
+Platform Security Architecture (PSA) APIs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
+:|F|: include/lib/psa
+:|F|: lib/psa
System Control and Management Interface (SCMI) Server
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -339,8 +366,6 @@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Mark Dykes <mark.dykes@arm.com>
:|G|: `mardyk01`_
-:|M|: John Powell <john.powell@arm.com>
-:|G|: `john-powell-arm`_
:|F|: lib/gpt_rme
:|F|: include/lib/gpt_rme
@@ -469,17 +494,19 @@
Intel SocFPGA platform ports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Tien Hock Loh <tien.hock.loh@intel.com>
-:|G|: `thloh85-intel`_
-:|M|: Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
-:|G|: mabdulha
-:|F|: plat/intel/soc
+:|M|: Sieu Mun Tang <sieu.mun.tang@intel.com>
+:|G|: `sieumunt`_
+:|M|: Benjamin Jit Loon Lim <jit.loon.lim@intel.com>
+:|G|: `BenjaminLimJL`_
+:|F|: plat/intel/soc/
:|F|: drivers/intel/soc/
MediaTek platform ports
^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Rex-BC Chen <rex-bc.chen@mediatek.com>
:|G|: `mtk-rex-bc-chen`_
+:|M|: Leon Chen <leon.chen@mediatek.com>
+:|G|: `leon-chen-mtk`_
:|F|: docs/plat/mt\*.rst
:|F|: plat/mediatek/
@@ -571,6 +598,14 @@
:|F|: plat/nxp/soc-ls1046a/ls1046afrwy
:|F|: plat/nxp/soc-ls1046a/ls1046aqds
+NXP SoC Part LS1088A and its platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Jiafei Pan <jiafei.pan@nxp.com>
+:|G|: `JiafeiPan`_
+:|F|: plat/nxp/soc-ls1088a
+:|F|: plat/nxp/soc-ls1088a/ls1088ardb
+:|F|: plat/nxp/soc-ls1088a/ls1088aqds
+
QEMU platform port
^^^^^^^^^^^^^^^^^^
:|M|: Jens Wiklander <jens.wiklander@linaro.org>
@@ -692,9 +727,9 @@
Xilinx platform port
^^^^^^^^^^^^^^^^^^^^
-:|M|: Michal Simek <michal.simek@xilinx.com>
+:|M|: Michal Simek <michal.simek@amd.com>
:|G|: `michalsimek`_
-:|M|: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@xilinx.com>
+:|M|: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>
:|G|: `venkatesh`_
:|F|: docs/plat/xilinx-zynqmp.rst
:|F|: plat/xilinx/
@@ -710,16 +745,26 @@
:|F|: docs/components/spd/optee-dispatcher.rst
:|F|: services/spd/opteed/
-TLK/Trusty secure payloads
+TLK
^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Varun Wadekar <vwadekar@nvidia.com>
:|G|: `vwadekar`_
:|F|: docs/components/spd/tlk-dispatcher.rst
-:|F|: docs/components/spd/trusty-dispatcher.rst
:|F|: include/bl32/payloads/tlk.h
:|F|: services/spd/tlkd/
+
+Trusty secure payloads
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Arve Hjønnevåg <arve@android.com>
+:|G|: `arve-android`_
+:|M|: Marco Nelissen <marcone@google.com>
+:|G|: `marcone`_
+:|M|: Varun Wadekar <vwadekar@nvidia.com>
+:|G|: `vwadekar`_
+:|F|: docs/components/spd/trusty-dispatcher.rst
:|F|: services/spd/trusty/
+
Test Secure Payload (TSP)
^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
@@ -752,6 +797,8 @@
^^^^^^
:|M|: Manish Pandey <manish.pandey2@arm.com>
:|G|: `manish-pandey-arm`_
+:|M|: Joao Alves <Joao.Alves@arm.com>
+:|G|: `J-Alves`_
:|F|: tools/sptool/
Build system
@@ -789,6 +836,7 @@
.. _b49020: https://github.com/b49020
.. _carlocaione: https://github.com/carlocaione
.. _danh-arm: https://github.com/danh-arm
+.. _davidvincze: https://github.com/davidvincze
.. _etienne-lms: https://github.com/etienne-lms
.. _glneo: https://github.com/glneo
.. _grandpaul: https://github.com/grandpaul
@@ -805,6 +853,7 @@
.. _mmind: https://github.com/mmind
.. _MrVan: https://github.com/MrVan
.. _mtk-rex-bc-chen: https://github.com/mtk-rex-bc-chen
+.. _leon-chen-mtk: https://github.com/leon-chen-mtk
.. _niej: https://github.com/niej
.. _npoushin: https://github.com/npoushin
.. _prabhakarlad: https://github.com/prabhakarlad
@@ -817,7 +866,8 @@
.. _soby-mathew: https://github.com/soby-mathew
.. _sreekare: https://github.com/sreekare
.. _stephan-gh: https://github.com/stephan-gh
-.. _thloh85-intel: https://github.com/thloh85-intel
+.. _sieumunt: https://github.com/sieumunt
+.. _BenjaminLimJL: https://github.com/BenjaminLimJL
.. _thomas-arm: https://github.com/thomas-arm
.. _TonyXie06: https://github.com/TonyXie06
.. _TravMurav: https://github.com/TravMurav
@@ -834,10 +884,8 @@
.. _javieralso-arm: https://github.com/javieralso-arm
.. _laurenw-arm: https://github.com/laurenw-arm
.. _zelalem-aweke: https://github.com/zelalem-aweke
-.. _theotherjimmy: https://github.com/theotherjimmy
.. _J-Alves: https://github.com/J-Alves
.. _madhukar-Arm: https://github.com/madhukar-Arm
-.. _john-powell-arm: https://github.com/john-powell-arm
.. _raghuncstate: https://github.com/raghuncstate
.. _CJKay: https://github.com/cjkay
.. _nmenon: https://github.com/nmenon
@@ -850,5 +898,8 @@
.. _uarif1: https://github.com/uarif1
.. _pangupta: https://github.com/pangupta
.. _JiafeiPan: https://github.com/JiafeiPan
+.. _arve-android: https://github.com/arve-android
+.. _marcone: https://github.com/marcone
+.. _marcbonnici: https://github.com/marcbonnici
.. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index b3553ae..e9eaa80 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -48,7 +48,9 @@
+-----------------+---------------------------+------------------------------+
| v2.6 | 4th week of Nov '21 | 2nd week of Nov '21 |
+-----------------+---------------------------+------------------------------+
-| v2.7 | 2nd week of May '22 | 4th week of Apr '22 |
+| v2.7 | 5th week of May '22 | 3rd week of May '22 |
++-----------------+---------------------------+------------------------------+
+| v2.8 | 5th week of Nov '22 | 3rd week of Nov '22 |
+-----------------+---------------------------+------------------------------+
Removal of Deprecated Interfaces
diff --git a/docs/change-log.md b/docs/change-log.md
index ab50968..8a555ec 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -3,6 +3,1196 @@
This document contains a summary of the new features, changes, fixes and known
issues in each release of Trusted Firmware-A.
+## [2.7.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.6..refs/tags/v2.7.0) (2022-05-20)
+
+### New Features
+
+- **Architecture**
+
+ - **Statistical profiling Extension (FEAT_SPE)**
+
+ - add support for FEAT_SPEv1p2 ([f20eb89](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f20eb893a072bb9b404eedb886e8c65fe76ffb45))
+
+ - **Branch Record Buffer Extension (FEAT_BRBE)**
+
+ - add BRBE support for NS world ([744ad97](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/744ad97445ce7aa65adaef376d0b5bafc12a90d3))
+
+ - **Extended Cache Index (FEAT_CCIDX)**
+
+ - update the do_dcsw_op function to support FEAT_CCIDX ([d0ec1cc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0ec1cc437c59e64ecba44710dbce82a04ff892d))
+
+- **Platforms**
+
+ - add SZ_* macros ([1af59c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1af59c457010e6e3e6536752736eb02115bca543))
+
+ - **Allwinner**
+
+ - add SMCCC SOCID support ([436cd75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/436cd754f2b0f9c0ce3094961bd1e179eeff2fc1))
+ - allow to skip PMIC regulator setup ([67412e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/67412e4d7ae3defaac78ef5e351c63e06cfd907a))
+ - apx803: add aldo1 regulator ([a29f6e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a29f6e76cbf76d509c00f84f068b59864d210dfd))
+ - choose PSCI states to avoid translation ([159c36f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/159c36fd2fc5afbe979e5028b9e845ed4b7a40f1))
+ - provide CPU idle states to the rich OS ([e2b1877](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e2b18771fc2a0528dda18dbdaac08dd8530df25a))
+ - simplify CPU_SUSPEND power state encoding ([52466ec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52466ec38ef312da62ad062720a03a183329f831))
+
+ - **Arm**
+
+ - **FVP**
+
+ - measure critical data ([cf21064](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cf21064ec8a1889f64de48e30e38285227d27745))
+ - update HW_CONFIG DT loading mechanism ([39f0b86](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/39f0b86a76534d0b7c71dd0c8b34f1a74480386b))
+ - enable RSS backend based measured boot ([c44e50b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c44e50b72567205650c6455f3a258f36af0c84dd))
+
+ - **Morello**
+
+ - add changes to enable TBBR boot ([4af5397](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4af53977533bee7b5763d3efad1448545c2ebef7))
+ - add DTS for Morello SoC platform ([572c8ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/572c8ce255397f7cff9640676e510817a8e4c6a3))
+ - add support for nt_fw_config ([6ad6465](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6ad6465e5ce452688cac079f16d26f64e9f4ce3c))
+ - add TARGET_PLATFORM flag ([8840711](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8840711f33131969ec6b62ca3da079cf0573ac8b))
+ - configure DMC-Bing mode ([9b8c431](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9b8c431e2b2d656da7f8c4158e3d32e104446fec))
+ - expose scmi protocols in fdts ([87639aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/87639aab0b6a30d4f49d069c0ea06900b11072a6))
+ - split platform_info sds struct ([4a7a9da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a7a9dafbc953089957a0cc1a7183731a5b003e1))
+ - zero out the DDR memory space ([2d39b39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d39b39704c1e4f2a189543ac4ff05ae58e5f5c8))
+
+ - **N1SDP**
+
+ - add support for nt_fw_config ([cf85030](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cf85030efe73439e06295f8185b0a6bebf7b5eae))
+ - enable trusted board boot on n1sdp ([fe2b37f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fe2b37f6858168a56c3d393bc72f560468d02165))
+
+ - **RD**
+
+ - **RD-N2**
+
+ - add board support for rdn2cfg2 variant ([efeb438](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/efeb43808d2e3ed23e1d51d5e86460db92971e96))
+ - add support for rdedmunds variant ([ef515f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef515f0d3466a8beded4fd662718abbd97391b13))
+
+ - **SGI**
+
+ - add page table translation entry for secure uart ([33d10ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33d10ac8bf134519f303fd7ce5fb5d583be2f515))
+ - deviate from arm css common uart related definitions ([f2cccca](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f2ccccaa81ec14a80fedb48c37226e5d852ada7a))
+ - enable fpregs context save and restore ([18fa43f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18fa43f753b79cfc3cc5426a3ef50b04efbf6206))
+ - route TF-A logs via secure uart ([987e2b7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/987e2b7c20eb4ab4215ff5289b715300f5cec054))
+
+ - **TC**
+
+ - add reserved memory region for Gralloc ([ad60a42](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ad60a42cd79713984065dca8540c091c49755f32))
+ - enable CI-700 PMU for profiling ([fbfc598](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fbfc59840f9cd0ea53921c7f6fb9f4850a3b42ee))
+ - enable GPU ([82117bb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/82117bb48180175c25936b0ff9e33563e25e18f4))
+ - enable SMMU for DPU ([4a6ebee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a6ebeeca37ece34a58982c8b6ebdc8cfd70814b))
+ - enable tracing ([59da207](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59da207e2f2f028c9051c89bc5a05e95d996c18c))
+
+ - **Corstone-1000**
+
+ - identify bank to load fip ([cf89fd5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cf89fd57ed3286d7842eef41cd72a3977eb6d317))
+ - implement platform specific psci reset ([a599c80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a599c80d063975cbeedbc86cfb619fca8545c487))
+ - made changes to accommodate 3MB for optee ([854d1c1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/854d1c103a9b73bbde7ef1b89b06b29e3cc053bb))
+
+ - **Intel**
+
+ - add macro to switch between different UART PORT ([447e699](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/447e699f70f1a1d1b85a8136b445eba689166c5d))
+ - add RSU 'Max Retry' SiP SMC services ([4c26957](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c26957be253a7ab3acb316f42bf3ee10c409ed2))
+ - add SiP service for DCMF status ([984e236](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/984e236e0dee46708534a23c637271a931ceb67e))
+ - add SMC for enquiring firmware version ([c34b2a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c34b2a7a1a38dba88b6b668a81bd07c757525830))
+ - add SMC support for Get USERCODE ([93a5b97](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/93a5b97ec9e97207769db18ae34886e6b8bf2ea4))
+ - add SMC support for HWMON voltage and temp sensor ([52cf9c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52cf9c2cd4882534d02e8996e4ff1143ee59290e))
+ - add SMC support for ROM Patch SHA384 mailbox ([77902fc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77902fca8fe7449473b09198e1fe197f7b4765d7))
+ - add SMC/PSCI services for DCMF version support ([44eb782](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44eb782e15c9af532f2455b37bd53ca93830f6e2))
+ - add SMPLSEL and DRVSEL setup for Stratix 10 MMC ([bb0fcc7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb0fcc7e011ec4319a79734ba44353015860e39f))
+ - add support for F2S and S2F bridge SMC with mask to enable, disable and reset bridge ([11f4f03](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11f4f03043ef05762f4d6337804c39dc8f9af54f))
+ - allow to access all register addresses if DEBUG=1 ([7e954df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e954dfc2ba83262f7596dd0f17de75163e49e5e))
+ - create source file for firewall configuration ([afa0b1a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/afa0b1a82a404c616da2da8f52cdcd587938955f))
+ - enable firewall for OCRAM in BL31 ([ae19fef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae19fef33707700a91b0b672aa784e084a6ca500))
+ - enable SMC SoC FPGA bridges enable/disable ([b7f3044](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7f3044e8725d9af997999547630892cf9e2f0ad))
+ - extend attestation service to Agilex family ([581182c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/581182c1916df03860744d8e32941c72b2cc3fda))
+ - implement timer init divider via cpu frequency. ([#1](https://review.trustedfirmware.org:29418/TF-A/trusted-firmware-a/issues/1)) ([f65bdf3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f65bdf3a54eed8f7651761c25bf6cc7437f4474b))
+ - initial commit for attestation service ([d174083](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d17408316db10db611e23716e8a5b9b9f53ad509))
+ - single certificate feature enablement ([7facace](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7facacec6328e505b243a4974d045d45fe068afd))
+ - support AES Crypt Service ([6726390](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6726390eb02e9659cfaf2d3598be9bf12fbc5901))
+ - support crypto service key operation ([342a061](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/342a0618c7ff89327ac5b34dc0713509ffae609b))
+ - support crypto service session ([6dc00c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6dc00c24ab0100a2aae0f416c72470f8ed17e149))
+ - support ECDH request ([4944686](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49446866a515c2db855d456f39df3d586b2084b7))
+ - support ECDSA Get Public Key ([d2fee94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2fee94afa6ba7e76508e6bead7eb2936c5eafb8))
+ - support ECDSA HASH Signing ([6925410](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/692541051b8cb0f435ae46c5d7351231ee292319))
+ - support ECDSA HASH Verification ([7e25eb8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e25eb87016ba8355cf0a3a5f71fb8b8785de044))
+ - support ECDSA SHA-2 Data Signature Verification ([5830506](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/583050607e43cef8b544a5700386a019e54c422f))
+ - support ECDSA SHA-2 Data Signing ([07912da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/07912da1b7663451493fb5e40e4c33deeb18a639))
+ - support extended random number generation ([24f9dc8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/24f9dc8a43fea350416ca9312a78ab4e786da8ad))
+ - support HMAC SHA-2 MAC verify request ([c05ea29](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c05ea2969070be90a7dbb2d0344c66d89401edf6))
+ - support session based SDOS encrypt and decrypt ([537ff05](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/537ff052579862a4865d36d06940feaa796d16da))
+ - support SHA-2 hash digest generation on a blob ([7e8249a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e8249a2dbacfa751990c47644f0403311c6e260))
+ - support SiP SVC version ([f0c40b8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f0c40b897f8a25bc50c53239dcf750dd395ebabf))
+ - support version 2 SiP SVC SMC function ID for mailbox commands ([c436707](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c436707bc6eed31ab61408ef40db6063d05f0912))
+ - support version 2 SiP SVC SMC function ID for non-mailbox commands ([ad47f14](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ad47f1422f3f9aa4a622e08b71fc8f5caab98a98))
+ - update to support maximum response data size ([b703fac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b703facaaae1e3fe5afa4742b436bb07e065b5e9))
+
+ - **Marvell**
+
+ - **Armada**
+
+ - **A3K**
+
+ - add north and south bridge reset registers ([a4d35ff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4d35ff381c625d61bcc22f9f9a1a45d8663b19d))
+
+ - **MediaTek**
+
+ - introduce mtk makefile ([500d40d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/500d40d877617653d347fb6308144973d4297ab9))
+
+ - **MT8195**
+
+ - apply erratas of CA78 for MT8195 ([c21a736](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c21a736d6f3fa9fb0647bff404b0174ebf1acd91))
+ - add EMI MPU surppot for SCP and DSP ([690cb12](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/690cb1265ea84851bd6405a0a6a57d2f1c9f03a3))
+ - dump EMI MPU configurations ([20ef588](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/20ef588e86ad8f3cf13382c164463046db261feb))
+ - improve SPM wakeup log ([ab45305](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab45305062f50f81e5c3f800ef4c6cef5097cb04))
+
+ - **MT8186**
+
+ - add DFD control in SiP service ([e46e9df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e46e9df0d0e05f2aaee613fc4f697fcc8d79c0b3))
+ - add SPM suspend driver ([7ac6a76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ac6a76c47d429778723aa804b64c48220a10f11))
+ - add Vcore DVFS driver ([635e6b1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/635e6b108e773daf37c00f46e6fbb1cae4e78f96))
+ - disable 26MHz clock while suspending ([9457cec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9457cec8c02f78ba56fd9298dd795766c89281a2))
+ - initialize platform for MediaTek MT8186 ([27132f1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/27132f13ca871dc3cf1aa6938995284cf5016e00))
+ - add power-off function for PSCI ([a68346a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a68346a772859ee6971ec14c6473d2a853e9c66f))
+ - add CPU hotplug ([1da57e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1da57e54b2270b3b49710afa6fd947b01d61b261))
+ - add DCM driver ([95ea87f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/95ea87ffc2445c77f070e6a2f78ffa424810faed))
+ - add EMI MPU basic driver ([1b17e34](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b17e34c5d7740a357b2027d88aef7760b346616))
+ - add MCDI drivers ([06cb65e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/06cb65ef079941d0525dca75dd0e110e9330906d))
+ - add pinctrl support ([af5a0c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af5a0c40aff21c4b8771365f19dcb01d6086b30d))
+ - add pwrap and pmic driver ([5bc88ec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5bc88ec61c75ed42b41d84817aa4d6ee68a2efc8))
+ - add reboot function for PSCI ([24dd5a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/24dd5a7b71544c503446e58cb23c0cfd09245a3c))
+ - add RTC drivers ([6e5d76b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6e5d76bac8786120d037953f5a6fd67aaff035c1))
+ - add SiP service ([5aab27d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5aab27dc4294110a6c0b69bf5ec5343e7df883a7))
+ - add sys_cirq support ([109b91e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/109b91e38c8d4f73941c8574759560a1f1636d05))
+ - apply erratas for MT8186 ([572f8ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/572f8adbb062c36835fbb82944dd2ed772134bfd))
+ - initialize delay_timer ([d73e15e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d73e15e66a33398c8fc51c83f975a3f35494faf5))
+ - initialize GIC ([206f125](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/206f125cc177bc110eb87d40ffc7fa18b28c01ce))
+ - initialize systimer ([a6a0af5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a6a0af57c3369dfc6fc2f25877d812a24e9be311))
+
+ - **NXP**
+
+ - add SoC erratum a008850 ([3d14a30](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d14a30b88762e901e134acc89c6ac4fa9e3f321))
+ - add ifc nor and nand as io devices ([b759727](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b759727f5936a687314168dd8912d30897a8c6be))
+ - add RCPM2 registers definition ([d374060](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d374060abe9b63296f63f1e3c811aeeddb7a093c))
+ - add CORTEX A53 helper functions ([3ccc8ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3ccc8ac3e5da48819a2fc90ec48a175515de38cb))
+
+ - **i.MX**
+
+ - **i.MX 8M**
+
+ - add a simple csu driver for imx8m family ([71c40d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/71c40d3bb7c90a6c36d5c49d0830ca95aba65a2f))
+ - add imx csu/rdc enum type defines for imx8m ([0c6dfc4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c6dfc47847608b6ade0c00716e93afc6725362c))
+ - enable conditional build for SDEI ([d2a339d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2a339dfa1665edf87a30a4318af954e764c205c))
+ - enable the coram_s tz by default on imx8mn/mp ([d5ede92](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5ede92d78c829d8a3adad0759219b79e0dc0707))
+ - enable the csu init on imx8m ([0a76495](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a76495bc2cb0c5291027020a3cd2d3adf31c8ed))
+ - do not release JR0 to NS if HAB is using it ([77850c9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77850c96f23bcdc76ecb0ecd27a982c00fde5d9d))
+ - switch to xlat_tables_v2 ([4f8d5b0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f8d5b018efc42d1ffa76fca8efb0d16a57f5edd))
+
+ - **i.MX 8M Mini**
+
+ - enable optee fdt overlay support ([9d0eed1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9d0eed111cb1294605b6d82291fef16a51d35e46))
+ - enable Trusty OS on imx8mm ([ff3acfe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff3acfe3cc1658917376152913a9d1b5b9b8de34))
+ - add support for measured boot ([cb2c4f9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cb2c4f93c18b948fbfde9d50ab7d30362be0e00a))
+
+ - **i.MX 8M Plus**
+
+ - add trusty for imx8mp ([8b9c21b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8b9c21b480dd5c3265be1105a9462b3f5657a6b1))
+ - enable BL32 fdt overlay support on imx8mp ([aeff146](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aeff14640a91f6d33bfdbc0dc7b0e920f6d14b91))
+
+ - **i.MX 8M Nano**
+
+ - enable optee fdt overlay support ([2612891](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/26128912884b26fab67bce9d87ba0e1c85a0be1e))
+ - enable Trusty OS for imx8mn ([99349c8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99349c8ecba910dabbaa72b9be91f3ed762036f5))
+
+ - **i.MX 8M Q**
+
+ - enable optee fdt overlay support ([023750c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/023750c6a898e77c185839f5e56f8e23538f718a))
+ - enable trusty for imx8mq ([a18e393](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a18e393339e1d481f4fdf0d621fe4f39ce93a4fe))
+
+ - **Layerscape**
+
+ - add CHASSIS 3 support for tbbr ([9550ce9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9550ce9ddd7729a961f51ed61ea4b2030e284dcb))
+ - add new soc errata a009660 support ([785ee93](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/785ee93cc3bd9b43d88fee5acefbd131bf6f2756))
+ - add new soc errata a010539 support ([85bd092](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/85bd0929433875e0b84fdc2046d9ec2cf0164903))
+ - add soc helper macro definition for chassis 3 ([602cf53](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/602cf53b6f507cea88f4af5c07bed9325bc7a9b8))
+ - define more chassis 3 hardware address ([0d396d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0d396d6455a659c4e679f02fae1f9043713474b0))
+ - print DDR errata information ([3412716](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3412716b30260958b30d1fa2e1c6d8cce195cd7d))
+
+ - **LS1043A**
+
+ - add ls1043a soc support ([3b0de91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b0de9182501fae9de372efd1faaf35a7bf74f68))
+
+ - **LS1043ARDB**
+
+ - add ls1043ardb board support ([e4bd65f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e4bd65fed8a12d06181c1343cf786ac91badb6b0)
+
+ - **LX2**
+
+ - enable DDR erratas for lx2 platforms ([cd960f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd960f5009ee062bba9c479505caee6bbe644649))
+
+ - **LS1046A**
+
+ - add new SoC platform ls1046a ([cc70859](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc708597fa72094c5a01df60e6538e4a7429c2a0))
+
+ - **LS1046ARDB**
+
+ - add ls1046ardb board support ([bb52f75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb52f7560b62043ed08a753f399dc80e8c1582d3))
+
+ - **LS1046AFRWY**
+
+ - add ls1046afrwy board support ([b51dc56](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b51dc56ab9ea79e4709f0d0ce965525d0d3da918))
+
+ - **LS1046AQDS**
+
+ - add board ls1046aqds support ([16662dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/16662dc40dd2578d3000528ece090ed39ed18b9c))
+
+ - **LS1088A**
+
+ - add new SoC platform ls1088a ([9df5ba0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9df5ba05b4fe4cd44157363a897b73553ba6e2f1))
+
+ - **LS1088ARDB**
+
+ - add ls1088ardb board support ([2771dd0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2771dd0293b6cda6811e8bed95f2354a3ee0124e))
+
+ - **LS1088AQDS**
+
+ - add ls1088aqds board support ([0b0e676](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0b0e67669814139c6818e61e03d0d0e3314fdc99))
+
+ - **QEMU**
+
+ - add SPMD support with SPMC at S-EL1 ([f58237c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f58237ccd9fd2350730d60ab7de59b5c376bfb35))
+ - add support for measured boot ([5e69026](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e690269d579d9461be3c5f5e3f59d4c666863a0))
+
+ - **QTI**
+
+ - **MSM8916**
+
+ - allow booting secondary CPU cores ([a758c0b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a758c0b65c6730fb07846899d6436ba257484d34))
+ - initial platform port ([dddba19](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dddba19a6a3cb7a1039beaffc3169c4eb3291afd))
+ - setup hardware for non-secure world ([af64473](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af6447315c8534331513ca6b6556af661e0ba88b))
+
+ - **Renesas**
+
+ - **R-Car**
+
+ - **R-Car 3**
+
+ - modify sequence for update value for WUPMSKCA57/53 ([d9912cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d9912cf3d1022fc6d38a6059290040985de56e63))
+ - modify type for Internal function argument ([ffb725b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ffb725be98ffd010c851629a6da75bf57f770c7f))
+ - update IPL and Secure Monitor Rev.3.0.3 ([14d9727](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/14d9727e334300b3f5f57e76a9f6e21431e6c6b5))
+
+ - **ST**
+
+ - add a function to configure console ([53612f7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/53612f72938f37244a5f10ae7c57abe7358c221f))
+ - add STM32CubeProgrammer support on UART ([fb3e798](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fb3e7985c9b657c535c02b722ecc413f643e671e))
+ - add STM32MP_UART_PROGRAMMER target ([9083fa1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9083fa11ead67272b94329e8f84257de6658620d))
+ - add early console in BL2 ([c768b2b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c768b2b22f4fb16cf8be8b4815a1984b29918c20))
+ - disable authentication based on part_number ([49abdfd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49abdfd8cececb91a4bc7e7b29a30c09dce461c7))
+ - get pin_count from the gpio-ranges property ([d0f2cf3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0f2cf3b148df75d5cbbd42dfa18012043e5d1f4))
+ - map 2MB for ROM code ([1697ad8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1697ad8cc81307972d31cec3b27d58f589eeeb3f))
+ - protect UART during platform init ([acf28c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/acf28c267b3679a0770b2010f2ec3fb3c2d19975))
+ - update stm32image tool for header v2 ([2d8886a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d8886aceed613b9be25f20900914cacc8bb0fb9))
+ - update the security based on new compatible ([812daf9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/812daf916c9c977a4f6d7d745d22b90c8492fc71))
+ - use newly introduced clock framework ([33667d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33667d299bd5398ca549f542345e0f321b483d17))
+
+ - **ST32MP1**
+
+ - adaptations for STM32MP13 image header ([a530874](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5308745ee3ab3b77ca942052e60968bcc01340d))
+ - add "Boot mode" management for STM32MP13 ([296ac80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/296ac8012b77ea84079b38cc60ee786a5f91857f))
+ - add a second fixed regulator ([225ce48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/225ce4822ccf2e7c7c1fca6cf3918d4399158613))
+ - add GUID values for updatable images ([8d6b476](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8d6b4764f3e54431c3d01342d39d1efa70c3dbf9))
+ - add GUID's for identifying firmware images to be booted ([41bd8b9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/41bd8b9e2ad3b755505684601f07d4f7f8ec04c4))
+ - add helper to enable high speed mode in low voltage ([dea02f4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dea02f4eaed855c2f05d8a1d7eefca313e98e5b4))
+ - add logic to pass the boot index to the Update Agent ([ba02add](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba02add9ea8fb9a8b0a533c1065a77c7dda4f2a6))
+ - add logic to select the images to be booted ([8dd7553](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8dd755314fdfa077465bd6cd5e248be392d90378))
+ - add NVMEM layout compatibility definition ([dfbdbd0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dfbdbd0625990267c6742268118ea748e77c6123))
+ - add part numbers for STM32MP13 ([30eea11](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30eea116cdd66b3fa1e1208e185eb7285a83d898))
+ - add regulator framework compilation ([bba9fde](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bba9fdee589fb9a7aca5963f53b7ce67c30520b3))
+ - add sdmmc compatible in platform define ([3331d36](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3331d3637c295993a78f22afe7463cf1c334d329))
+ - add sign-compare warning ([c10f3a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c10f3a4559ebf7a654a9719fec619e81e6ee1d69))
+ - add stm32_get_boot_interface function ([a6bfa75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a6bfa75cf25241a486ab371ae105ea7ebf2d34d8))
+ - add support for building the FWU feature ([ad216c1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ad216c106682f1d2565b2a08e11a601b418dc8a4))
+ - add support for reading the metadata partition ([0ca180f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ca180f6416160a523ff442f1ad0b768a9a3a948))
+ - add timeout in IO compensation ([de02e9b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de02e9b0ec29548b8ce5ef6ee9adcd9c5edb0518))
+ - allow configuration of DDR AXI ports number ([88f4fb8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88f4fb8fa759b1761954067346ee674b454bdfde))
+ - call pmic_voltages_init() in platform init ([ffd1b88](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ffd1b889225a8aec124df9e330f41dc638fd7180))
+ - chip rev. Z is 0x1001 on STM32MP13 ([ef0b8a6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef0b8a6c1b1a0eab3626041f3168f82bdb410836))
+ - enable BL2_IN_XIP_MEM to remove relocation sections ([d958d10](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d958d10eb360024e15f3c921dc3863a0cee98830))
+ - enable format-signedness warning ([cff26c1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cff26c19169dd94857e8180cc46b7aa4ccac574a))
+ - get CPU info from SYSCFG on STM32MP13 ([6512c3a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6512c3a62a4a7baaf32597284b242bc7172b7e26))
+ - introduce new flag for STM32MP13 ([bdec516](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bdec516ee862bfadc25a4d0c02a3b8d859c1fa25))
+ - manage HSLV on STM32MP13 ([fca10a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fca10a8f1b47231ef92634a0adf1a26cbfc97c2a))
+ - manage monotonic counter ([f5a3688](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f5a3688b8608df0f269a0b6df18632ebb9e26a01))
+ - new way to access platform OTP ([ae3ce8b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae3ce8b28eac73e9a41fdb28424d9f0f4b5f200e))
+ - preserve the PLL4 settings for USB boot ([bf1af15](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bf1af154db2c89028a8a551c18885add35d38966))
+ - register fixed regulator ([967a8e6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/967a8e63c33822680e3a4631430dcd9a4a64becd))
+ - remove unsupported features on STM32MP13 ([111a384](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/111a384c90afc629e644e7a8284abbd4311cc6b3))
+ - retry 3 times FWU trial boot ([f87de90](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f87de907c87e5b2091592c131c4d3d2f737bef01))
+ - select platform compilation either by flag or DT ([99a5d8d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99a5d8d01d38474b056766651bd746a4fe93ab20))
+ - skip TOS_FW_CONFIG if not in FIP ([b706608](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7066086424c2f6fd04880db852306d6f487962e))
+ - stm32mp_is_single_core() for STM32MP13 ([7b48a9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7b48a9f3286b8f174acf8821fec48fd2e4771514))
+ - update BACKUP_BOOT_MODE for STM32MP13 ([4b031ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4b031ab4c50d0b9f7127daa7f4eec634f39de970))
+ - update boot API for header v2.0 ([5f52eb1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5f52eb15970e57d2777d114948fc1110e3dd3f6c))
+ - update CFG0 OTP for STM32MP13 ([1c37d0c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1c37d0c1d378769249c797de5b13d73cf6f17a53))
+ - update console management for SP_min ([aafff04](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aafff0435448c8409935132be41758e0031f0822))
+ - update IO compensation on STM32MP13 ([8e07ab5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e07ab5f705b213af28831f7c3e9878154e07df0))
+ - update IP addresses for STM32MP13 ([52ac998](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52ac9983d67522b6b821391941c8b0d01fd68941))
+ - update memory mapping for STM32MP13 ([48ede66](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/48ede6615168118c674288f2e4f8ee1b11d2fa02))
+ - updates for STM32MP13 device tree compilation ([d38eaf9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d38eaf99d327bc1400f51c87b6d8a2f92cd828c6))
+ - usb descriptor update for STM32MP13 ([d59b9d5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d59b9d53b9cfb2443575c62c6716eb5508374a7b))
+ - use clk_enable/disable functions ([c7a66e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c7a66e720ae1a1a5ef98eaf9ff327cd352549010))
+ - use only one filter for TZC400 on STM32MP13 ([b7d0058](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7d0058a3a9153a3863cf76a6763ea751b3ab48d))
+ - warn when debug enabled on secure chip ([ac4b8b0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ac4b8b06eb23134d2a9002834541d33f8d43661b))
+
+ - **Texas Instruments**
+
+ - add enter sleep method ([cf5868b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cf5868b8cd7239dee69bdf6ba3ab87bd06bf15f5))
+ - add gic save and restore calls ([b40a467](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b40a467783e5911f97d6e92ebdeb34ca2f005552))
+ - add PSCI handlers for system suspend ([2393c27](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2393c27680a1ec636e413051e87e986df5a866fe))
+ - allow build config of low power mode support ([a9f46fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a9f46fad82b807a9f0a967245e3ac10ee8dd0ef1))
+ - increase SEC_SRAM_SIZE to 128k ([38164e6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/38164e64bd853a8329475e9168c5fcb94ecc528b))
+
+ - **Xilinx**
+
+ - **Versal**
+
+ - add SPP/EMU platform support for versal ([be73459](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be73459a945d8fa781fcc864943ccd0a8d92421c))
+ - add common interfaces to handle EEMI commands ([1397967](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1397967490c9f0ebff0d20a566260d1475fe065e))
+ - add SMCCC call TF_A_PM_REGISTER_SGI ([fcf6f46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fcf6f469318d693a024d42ae2d0f4afb26c1e85d))
+ - add support to reset SGI ([bf70449](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bf70449ba2d1ffd20b01741c491dc0f565009b3d))
+ - add UART1 as console ([2c79149](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c791499c26b40c31ce7f68c3bf0dca777fc62de))
+ - enhance PM_IOCTL EEMI API to support additional arg ([d34a5db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d34a5db8a76abdfc8fa68f43b24b971699086a06))
+ - get version for ATF related EEMI APIs ([da6e654](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/da6e654bc8b03ee784d0e96a71c4e591e63930f2))
+ - remove the time stamp configuration ([18e2a79](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18e2a79f8a5eaa72a2a7e641c2481beb9f827dce))
+
+ - **ZynqMP**
+
+ - disable the -mbranch-protection flag ([67abd47](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/67abd4762bd563be94e734bb0fe4087e88d5d446))
+ - fix section `coherent_ram' will not fit in region `RAM' ([9b4ed0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9b4ed0af02a8ff1fd9a81af5213fde16d3eb8d92))
+ - add feature check support ([223a628](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/223a6284b8a0a3ead884a7f0cf333a464d32e319))
+ - add support to get info of xilfpga ([cc077c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc077c22273075db328bd30fa12c28abf9eef052))
+ - add uart1 as console ([ea66e4a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ea66e4af0baf5d5b905e72f824a672f16a6e0f98))
+ - increase the max xlat tables when debug build is enabled ([4c4b961](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c4b9615b1d9512a4a89aa08e722547cc491a07b))
+ - pass ioctl calls to firmware ([76ff8c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/76ff8c459e9e6d105e614d68648bd6680806f93e))
+ - pm_api_clock_get_num_clocks cleanup ([e682d38](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e682d38b56854e1586b25d929dbc83543b4c66e4))
+
+- **Bootloader Images**
+
+ - add XLAT tables symbols in linker script ([bb5b942](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb5b942e6f133198daedcca0b74ec598af260a54))
+
+ - **BL2**
+
+ - add support to separate no-loadable sections ([96a8ed1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/96a8ed14b74cca33a8caf567d0f0a2d3b2483a3b))
+
+ - **BL31**
+
+ - aarch64: RESET_TO_BL31_WITH_PARAMS ([25844ff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/25844ff728e4a0e5430ba2032457aba7b780a701))
+
+- **Services**
+
+ - **RME**
+
+ - add dummy platform token to RMMD ([0f9159b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0f9159b7ebb7e784a8ed998869ff21095fa105b1))
+ - add dummy realm attestation key to RMMD ([a043510](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a0435105f229a65c7861b5997793f905cf90b823))
+
+ - **SPM**
+
+ - update ff-a boot protocol documentation ([573ac37](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/573ac37373d3e8b2c31b3aaeed759e4656e060ec))
+
+ - **EL3 SPMC**
+
+ - allow BL32 specific defines to be used by SPMC_AT_EL3 ([2d65ea1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d65ea1930d4ce26cc176a8c60e9401d0b4f862a))
+ - add plat hook for memory transactions ([a8be4cd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8be4cd057bce5f0b4ac6af396c0c870474d1ef4))
+ - add EL3 SPMC #defines ([44639ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44639ab73e43e0b79da834dff8c85266d68e5066))
+ - introduce accessor function to obtain datastore ([6a0788b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a0788bc0e704283e52c80990aa2bb6e047a0cc2))
+ - add FF-A secure partition manager core ([5096aeb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5096aeb2ba646548a7a6ab59e975b996e6c9026a))
+ - add FFA_FEATURES handler ([55a2963](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/55a296387b9720855df429a08c886f47a4a45057))
+ - add FFA_PARTITION_INFO_GET handler ([f74e277](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f74e27723bb54ad1318fa462fbcff70af555b2e6))
+ - add FFA_RUN handler ([aad20c8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aad20c85cb6f4bc91318d3c6488cf72a20fdbe96))
+ - add FFA_RX_RELEASE handler ([f0c25a0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f0c25a082fc8b891d4d21518028118561caa4735))
+ - add function to determine the return path from the SPMC ([20fae0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/20fae0a7ce7fd407cd3efb7745017ee6ab605159))
+ - add helper function to obtain endpoint mailbox ([f16b6ee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f16b6ee3deac93706efe465f399c9542e12d5eeb))
+ - add helper function to obtain hyp structure ([a7c0050](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a7c00505f85684326a223535a319c170d14826f6))
+ - add helper to obtain a partitions FF-A version ([c2b1434](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c2b1434369292081f907c548e496f59e197eb2f1))
+ - add partition mailbox structs ([e1df600](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e1df6008d9b4a00da25ec08fbdcbd3a5967fdb54))
+ - add support for direct req/resp ([9741327](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9741327df577c3f43db42b26bda607429e62af0b))
+ - add support for FF-A power mgmt. messages in the EL3 SPMC ([59bd2ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59bd2ad83c13ed3c84bb9b841032c95927358890))
+ - add support for FFA_MSG_WAIT ([c4db76f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c4db76f066f236fe490ebc7a50833a04e08f5151))
+ - add support for FFA_SPM_ID_GET ([46872e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/46872e01f5efb555fef8367595b59e5d2f75cec0))
+ - add support for forwarding a secure interrupt to the SP ([729d779](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/729d7793f830781ff8ed44d144c3346c6e4251a3))
+ - add support for handling FFA_ERROR ABI ([d663fe7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d663fe7a3002ff028c190eb732278b878e78b7b7))
+ - add support for v1.1 FF-A boot protocol ([2e21921](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2e21921502b1317031cf2a2f69c5d47ac88a505d))
+ - add support for v1.1 FF-A memory data structures ([7e804f9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e804f9695c48681c91e9e6fc6175eb6997df867))
+ - enable building of the SPMC at EL3 ([1d63ae4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1d63ae4d0d8374a732113565be90d58861506e39))
+ - enable checking of execution ctx count ([5b0219d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5b0219ddd5da42413f4c2be9302224b5b71295ff))
+ - enable handling FF-A RX/TX Mapping ABIs ([1a75224](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1a752245ecae6487844c57667e24b704e6df8079))
+ - enable handling FFA_VERSION ABI ([0c7707f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c7707fdf21fc2a8658f5a4bdfd2f8883d02ada5))
+ - enable handling of the NS bit ([0560b53](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0560b53e71ab6daefa8e75665a718605478746a4))
+ - enable parsing of messaging methods from manifest ([3de378f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3de378ff8c9430c964cbe9b0c58fa5afc4d237ce))
+ - enable parsing of UUID from SP Manifest ([857f579](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/857f5790da3770a9ca52416274eec4e545c9be53))
+ - enable the SPMC to pass the linear core ID in a register ([f014300](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f0143004e548582760aacd6f15f5499b18081a69))
+ - prevent read only xlat tables with the EL3 SPMC ([70d986d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70d986ddbbf56a20c7550c079dd4dc9462332594))
+ - support FFA_ID_GET ABI ([d5fe923](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5fe92350cb018ae7083ed26a6a16508ccd82a86))
+ - allow forwarding of FFA_FRAG_RX/TX calls ([642db98](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/642db9840712044b9c496e04a7acd60580e54117))
+ - enable handling of FF-A SMCs with the SPMC at EL3 ([bb01a67](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb01a67306f47271adde051e541c760028c1a0f1))
+ - update SPMC init flow to use EL3 implementation ([6da7607](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6da76075bf4b953d621aa15c379e62a5f785de3f))
+ - add logical partition framework ([7affa25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7affa25cad400101c016082be2d102be0f4fce80))
+ - add FF-A memory management code ([e0b1a6d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0b1a6d59e57c0dbe87f5b8f8166f1123664f058))
+ - prevent duplicated sharing of memory regions ([fef85e1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fef85e1e53fcf44e8d9ed50c89d8a764bf1b7738))
+ - support multiple endpoints in memory transactions ([f0244e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f0244e5dd1b8cbab75ef00c1b9b56eed5b3cad4b))
+
+ - **SPMD**
+
+ - forward FFA_VERSION from SPMD to SPMC ([9944f55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9944f55761c4d5cc1feefaf5e33bf7fb83d8f5f3))
+ - enable SPMD to forward FFA_VERSION to EL3 SPMC ([9576fa9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9576fa93a2effc23a533b80dce41d7104a8d200b))
+ - add FFA_MSG_SEND2 forwarding in SPMD ([c2eba07](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c2eba07c47f8d831629104eeffcec11ed7d3b0a5))
+ - add FFA_RX_ACQUIRE forwarding in SPMD ([d555233](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d555233fe5a04dfd99fd6ac30bacc5284285c131))
+
+ - **SPM MM**
+
+ - add support to save and restore fp regs ([15dd6f1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15dd6f19da8ee4b20ba525e0a742d0df9e46e071))
+
+- **Libraries**
+
+ - **CPU Support**
+
+ - add library support for Poseidon CPU ([1471475](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1471475516cbf1b4a411d5ef853bd92d0edd542e))
+ - add support for Cortex-X1 ([6e8eca7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6e8eca78e5db966e10e2fa2737e9be4d5af51fa9))
+ - add L1PCTL macro definiton for CPUACTLR_EL1 ([8bbb1d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8bbb1d80a58dbdf96fcabbdebbfbd21d2d5344a4))
+
+ - **EL3 Runtime**
+
+ - add arch-features detection mechanism ([6a0da73](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a0da73647546aea1d10b4b2347bac9d532bcb43))
+ - replace ARM_ARCH_AT_LEAST macro with FEAT flags ([0ce220a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ce220afb24f0511332b251952019d7011ccc282))
+
+ - **FCONF**
+
+ - add a helper to get image index ([9e3f409](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9e3f409398af447b1d03001dd981007a9bb1617e))
+ - add NS load address in configuration DTB nodes ([ed4bf52](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ed4bf52c33b6860d58a2ffc946bd293ec76bbdaa))
+
+ - **Standard C Library**
+
+ - add support for length specifiers ([701e94b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/701e94b08f382691b0deabd4df882abd87e17ab5))
+
+ - **PSA**
+
+ - add initial attestation API ([0848565](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/084856513d6730a50a3d65ac9c3bdae465117c40))
+ - add measured boot API ([758c647](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/758c64715b691be92de623f81032494e38a43cc8))
+ - mock PSA APIs ([0ce2072](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ce2072d9b9f419bb19595454395a33a5857ca2f))
+
+- **Drivers**
+
+ - **Generic Clock**
+
+ - add a minimal clock framework ([847c6bc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/847c6bc8e6d55b1c0f31a52407aa61515cd6c612))
+
+ - **FWU**
+
+ - add a function to pass metadata structure to platforms ([9adce87](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9adce87efc8acc947b8b49d700c9773a7f071e02))
+ - add basic definitions for GUID handling ([19d63df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19d63df1af72b312109b827cca793625ba6fcd16))
+ - add platform hook for getting the boot index ([40c175e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40c175e75bc442674a5dc793c601b09681158ab9))
+ - pass a const metadata structure to platform routines ([6aaf257](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6aaf257de4a4070ebc233f35a09bce4c39ea038c))
+ - simplify the assert to check for fwu init ([40b085b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40b085bddf60cf8c533b379ccb41e6668c5080dd))
+
+ - **Measured Boot**
+
+ - add RSS backend ([0442ebd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0442ebd2e9bcf5fa4344d8fa8ef4b69a3b249e33))
+
+ - **GUID Partition Tables Support**
+
+ - add a function to identify a partition by GUID ([3cb1065](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3cb1065581f6d9a8507af8dbca3779d139aa0ca7))
+ - cleanup partition and gpt headers ([2029f93](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2029f930097b0c3b1b1faa660032d16ed01a5c86))
+ - copy the partition GUID into the partition structure ([7585ec4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7585ec4d36ebb7e286cfec959b2de084eded8201))
+ - make provision to store partition GUID value ([938e8a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/938e8a500a25a949cfd25f0cb79f6c1359c9b40c))
+ - verify crc while loading gpt header ([a283d19](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a283d19f82ddb635d9d9fa061e7fd956167ebe60))
+
+ - **Arm**
+
+ - **GIC**
+
+ - allow overriding GICD_PIDR2_GICV2 address ([a7521bd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a7521bd5d887bfd69d99a55a81416e38ba9ebc97))
+
+ - **GIC-600AE**
+
+ - disable SMID for unavailable blocks ([3f0094c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3f0094c15d433cd3de413a4633a4ac2b8e1d1f2e))
+ - enable all GICD, PPI, ITS SMs ([6a1c17c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a1c17c770139c00395783e7568220d61264c247))
+ - introduce support for RAS error handling ([308dce4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/308dce40679f63db504cd3d746a0c37a2a05f473))
+
+ - **SMMU**
+
+ - add SMMU abort transaction function ([6c5c532](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c5c5320511ab8202fb9eccce9e66b4e4e0d9a33))
+ - configure SMMU Root interface ([52a314a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52a314af254966a604e192fcc3326737354f217a))
+
+ - **MHU**
+
+ - add MHU driver ([af26d7d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af26d7d6f01068809f17cc2d49a9b3d573c640a9))
+
+ - **RSS**
+
+ - add RSS communication driver ([ce0c40e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ce0c40edc93aa403cdd2eb6c630ad23e28b01c3e))
+
+ - **TZC**
+
+ - **TZC-380**
+
+ - add sub-region register definition ([fdafe2b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fdafe2b5ead66a1b5175db77bcc7cedafa14a059))
+
+ - **Marvell**
+
+ - **Armada**
+
+ - **A3K**
+
+ - **A3720**
+
+ - preserve x1/x2 regs in console_a3700_core_init() ([7c85a75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c85a7572960efbaabe20c9db037bcec66be3e98))
+
+ - **MediaTek**
+
+ - **APU**
+
+ - add mt8195 APU clock and pll SiP call ([296b590](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/296b590206aa6db51e5c82b1a97a4f9707b49c4d))
+ - add mt8195 APU iommap regions ([339e492](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/339e4924a7a3fd11bc176e0bf3e01d76133d364c))
+ - add mt8195 APU mcu boot and stop SiP call ([88906b4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88906b443734399be5c07a5bd690b63d3d82cefa))
+
+ - **NXP**
+
+ - **DCFG**
+
+ - add Chassis 3 support ([df02aee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/df02aeeec640d2358301e903d9c8c473d455be9e))
+ - add gic address align register definition ([3a8c9d7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3a8c9d78d4c65544d789bd64bd005ac10b5b352d))
+ - add some macro definition ([1b29fe5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b29fe534b8732193850fced2da1dc449450bd3b))
+
+ - **NXP Crypto**
+
+ - add chassis 3 support ([d60364d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d60364d48e31b33b57049d848b7462eb0e0de612))
+
+ - **DDR**
+
+ - add rawcard 1F support ([f2de48c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f2de48cb143c20ccd7a9c141df3d34cae74049de))
+ - add workaround for errata A050958 ([291adf5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/291adf521a54a365e54964bff4dae53d51c65936))
+
+ - **GIC**
+
+ - add some macros definition for gicv3 ([9755fd2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9755fd2ec2894323136715848910b13053cfe0ce))
+
+ - **CSU**
+
+ - add bypass bit mask definition ([ec5fc50](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ec5fc501f15922967bf5d8260072ba1f9aec9640))
+
+ - **IFC NAND**
+
+ - add IFC NAND flash driver ([28279cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/28279cf2c141caf5e4e7156f874cde6f5a0d271b))
+
+ - **IFC NOR**
+
+ - add IFC nor flash driver ([e2fdc77](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e2fdc77ba4eee91f0d1490e34f0fff552fc55dc9))
+
+ - **TZC-380**
+
+ - add tzc380 platform driver support ([de9e57f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de9e57ff1f3769e770eac44b94127eb7239a63f2))
+
+ - **ST**
+
+ - introduce fixed regulator driver ([5d6a264](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5d6a2646f7759a5a2b3daed0d8aef4588c552ba4))
+
+ - **Clock**
+
+ - add clock driver for STM32MP13 ([9be88e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9be88e75c198b08c508d8e470964720a781294b3))
+ - assign clocks to the correct BL ([7418cf3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7418cf397916c97cb4ecf159b1f497a84299b695))
+ - check HSE configuration in serial boot ([31e9750](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/31e9750bc17bd472d4f2a3db297461efc301be51))
+ - define secure and non-secure gate clocks ([aaa09b7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aaa09b713c6f539fb5b2ee7e2dfd75f2d46875f5))
+ - do not refcount on non-secure clocks in bl32 ([3d69149](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d69149a7e9e9a899d57f48bee26f98614f88935))
+ - manage disabled oscillator ([bcccdac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcccdacc7e7b7b985df942b3fae26cb9038a2574))
+
+ - **DDR**
+
+ - add read valid training support ([5def13e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5def13eb01ebac5656031bdc388a215d012fdaf8))
+
+ - **GPIO**
+
+ - allow to set a gpio in output mode ([53584e1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/53584e1d5b2b843ea3bb9e01e3f01ea7c364ee6a))
+ - do not apply secure config in BL2 ([fc0aa10](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fc0aa10a2cd3cab887a8baa602891d1f45db2537))
+ - add a function to reset a pin ([737ad29](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/737ad29bf992a7a79d538d1e0b47c7f38d9a4b9d))
+
+ - **SDMMC2**
+
+ - allow compatible to be defined in platform code ([6481a8f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6481a8f1e045ac80f0325b8bfe7089ba23deaf7b))
+ - manage cards power cycle ([258bef9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/258bef913aa76ead1b10c257d1695d9c0ef1c79d))
+
+ - **ST PMIC**
+
+ - add pmic_voltages_init() function ([5278ec3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5278ec3faf2010fd6aea1d8cd4294dd229c5c21d))
+ - register the PMIC to regulator framework ([85fb175](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/85fb175b5ef854bc4607db98a4cfb5f35d822cee))
+
+ - **STPMIC1**
+
+ - add new services ([ea552bf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ea552bf5a57b573a6b09e396e3466b3c4af727f0))
+ - add USB OTG regulators ([13fbfe0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/13fbfe046e71393961d2c70a4f748a15f9c15f77))
+
+ - **Regulator**
+
+ - add support for regulator-always-on ([9b4ca70](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9b4ca70d97d9a2556752b511ff9fe52012faff02))
+ - add a regulator framework ([d5b4a2c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5b4a2c4e7fd0bcb9f08584b242e69a2e591fb71))
+
+ - **UART**
+
+ - manage oversampling by 8 ([1f60d1b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f60d1bd33d434b0c82a74e276699ee5a2f63833))
+ - add uart driver for STM32MP1 ([165ad55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/165ad5561ef598ea6261ba082610eeff3f208df7))
+
+- **Miscellaneous**
+
+ - **Debug**
+
+ - update print_memory_map.py ([d16bfe0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d16bfe0feffe6a20399fb91d86fd8f7282b941dd))
+
+ - **DT Bindings**
+
+ - add bindings for STM32MP13 ([1b8898e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b8898eb32c3872a34fc59f4216736f23af0c6ea))
+ - add TZC400 bindings for STM32MP13 ([24d3da7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/24d3da76d221390bb47d501c2ed77a1a7d2b42e7))
+
+ - **FDT Wrappers**
+
+ - add function to find or add a sudnode ([dea8ee0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dea8ee0d3f13f8d1638745b76e86bd7617bf92e7))
+
+ - **FDTs**
+
+ - add the ability to supply idle state information ([2b2b565](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2b2b565717cc0299e75e8806004d1a3548e9fbf7))
+
+ - **STM32MP1**
+
+ - add DDR support for STM32MP13 ([e6fddbc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6fddbc995947d4e5a5dc6607c76cd46fdd840e2))
+ - add DT files for STM32MP13 ([3b99ab6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b99ab6e370a01caec14bc5422a86001eaf291b8))
+ - add nvmem_layout node and OTP definitions ([ff8767c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff8767cbfc2bb851a2f6cc32fbe3693ddbfb7d12))
+ - add st-io_policies node for STM32MP13 ([2bea351](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2bea35122d102492f18c427535ce6c9b7016e356))
+ - add support for STM32MP13 DK board ([2b7f7b7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2b7f7b751f4b0f7a8a0f4a35407af22cc269e529))
+ - update NVMEM nodes ([375b79b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/375b79bb4a773fe6a5dd971272c72bf12155050e))
+
+- **Documentation**
+
+ - context management refactor proposal ([3274226](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/327422633bef112a10579d4daeca0f596cd02911))
+
+ - **Threat Model**
+
+ - Threat Model for TF-A v8-R64 Support ([dc66922](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dc669220d5666c2c808bc11ba81c86a9b071271a))
+
+- **Tools**
+
+ - **Secure Partition Tool**
+
+ - add python SpSetupActions framework ([b1e6a41](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b1e6a41572240839e62099aa00298174b18c696a))
+ - delete c version of the sptool ([f4ec476](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4ec47613fef8db8037195147dc2ac6fb6f154ff))
+ - python version of the sptool ([2e82874](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2e82874cc9b7922e000dd4d7718e3153e347b1d7)
+ - use python version of sptool ([822c727](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/822c72791f791d26e233df0c15a655c3dbd8b117))
+
+### Resolved Issues
+
+- **Architecture**
+
+ - **Activity Monitors Extension (FEAT_AMU)**
+
+ - add default value for ENABLE_FEAT_FGT and ENABLE_FEAT_ECV flags ([820371b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/820371b13028a6f620a62cf73a951883d051666b))
+ - fault handling on EL2 context switch ([f74cb0b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f74cb0be8ac80eb3072555cb04eb09375d4cb31f))
+ - limit virtual offset register access to NS world ([a4c3945](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4c394561af31ae0417ed9ff3b3152adb7cd5355))
+
+ - **Scalable Vector Extension (FEAT_SVE)**
+
+ - disable ENABLE_SVE_FOR_NS for AARCH32 ([24ab2c0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/24ab2c0af74be174acf755a36b3ebba867184e60))
+
+- **Platforms**
+
+ - **Allwinner**
+
+ - improve DTB patching error handling ([79808f1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/79808f10c32d441572666551b1545846079af15b))
+
+ - **Arm**
+
+ - fix fvp and juno build with USE_ROMLIB option ([861250c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/861250c3b26d64f859f5f37686e453d5074fa976))
+ - increase ARM_BL_REGIONS count ([dcb1959](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dcb1959161935aa58d2bb852f3cef0b96458a4e1))
+ - remove reclamation of functions starting with "init" ([6c87abd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c87abdda400354ebf4f5351086c32a4620475c9))
+ - use PLAT instead of TARGET_PLATFORM ([c5f3de8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c5f3de8dabc9b955b6051a6c6116d40b10a84f5d))
+ - fix SP count limit without dual root CoT ([9ce15fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9ce15fe8910580efca46b9f102e117402ce769db))
+
+ - **FVP**
+
+ - FCONF Trace Not Shown ([0c55c10](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c55c10305df6217fd978d58ce203dbad3edd4d5))
+ - disable reclaiming init code by default ([fdb9166](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fdb9166b9494402eb2da7e0b004c121b322725e0))
+ - extend memory map to include all DRAM memory regions ([e803542](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e80354212f591c8813dec27353e8241e03155b4c))
+ - fix NULL pointer dereference issue ([a42b426](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a42b426b8548e3304e995f1a49d2470d71072949))
+ - op-tee sp manifest doesn't map gicd ([69cde5c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/69cde5cd9563f0c665862f1e405ae8e8d2818c6e))
+
+ - **Morello**
+
+ - change the AP runtime UART address ([07302a2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/07302a23ec1af856b3d4de0439161a8c23414f84))
+ - fix SoC reference clock frequency ([e8b7a80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8b7a80436c2bc81c61fc4703d6580f2fe9226a9))
+ - include errata workaround for 1868343 ([f94c84b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f94c84baa2a2bad75397b0ec6a0922fe8a475847))
+
+ - **SGI**
+
+ - disable SVE for NS to support SPM_MM builds ([78d7e81](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/78d7e819798ace643b6e22025dc76aedb199bbd5))
+
+ - **TC**
+
+ - remove the bootargs node ([68fe3ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68fe3cec25bc9ea4e1bafdb1d9f5315e245d650b))
+
+ - **Corstone-1000**
+
+ - change base address of FIP in the flash ([1559450](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1559450132c5e712f4d6896e53e4f1cb521fa465))
+
+ - **Broadcom**
+
+ - allow build to specify mbedTLS absolute path ([903d574](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/903d5742953d9d4b224e71d8b1e62635e83f44a9))
+ - fix the build failure with mbedTLS config ([95b5c01](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/95b5c0126b802b894ea0177d973978e06b6a254d))
+
+ - **Intel**
+
+ - add flash dcache after return response for INTEL_SIP_SMC_MBOX_SEND_CMD ([ac097fd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ac097fdf07ad63b567ca751dc518f8445a0baef6))
+ - allow non-secure access to FPGA Crypto Services (FCS) ([4837a64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4837a640934630f8034ceec1bb84cc40673d8a6b))
+ - always set doorbell to SDM after sending command ([e93551b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e93551bb3bd8ac43779fa70c7363ee2568da45ca))
+ - assert if bl_mem_params is NULL pointer ([35fe7f4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/35fe7f400a7f1d65ff2fee5531d20f6c2f3e6f39))
+ - bit-wise configuration flag handling ([276a436](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/276a43663e8e315fa1bf0aa4824051d88705858b))
+ - change SMC return arguments for INTEL_SIP_SMC_MBOX_SEND_CMD ([108514f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/108514ff7160a86efb791449a4635ffe0f9fdf2c))
+ - configuration status based on start request ([e40910e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e40910e2dc3fa59bcce83ec1cf9a33b3e85012c4))
+ - define macros to handle buffer entries ([7db1895](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7db1895f0be2f8c6710bf51d8441d5e53e3ef0fe))
+ - enable HPS QSPI access by default ([000267b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/000267be22d3c0077c0fd0a8377ceeed5aada4c3))
+ - extend SDM command to return the SDM firmware version ([c026dfe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c026dfe38cfae379457a6ef53130bd5ebc9d7808))
+ - extending to support large file size for AES encryption and decryption ([dcb144f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dcb144f1fbcef73ddcc448d5ed6134aa279069b6))
+ - extending to support large file size for SHA-2 ECDSA data signing and signature verifying ([1d97dd7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1d97dd74cd128edd7ad45b725603444333c7b262))
+ - extending to support large file size for SHA2/HMAC get digest and verifying ([70a7e6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70a7e6af958f3541476a8de6baac8e376fcc67f9))
+ - fix bit masking issue in intel_secure_reg_update ([c9c0709](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c9c070994caedf123212aad23b6942122c5dd793))
+ - fix configuration status based on start request ([673afd6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/673afd6f8e7266900b00a7cbeb275fe1a3d69cce))
+ - fix ddr address range checker ([12d71ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12d71ac6627bb6822a0314e737794a8503df79dd))
+ - fix ECC Double Bit Error handling ([c703d75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c703d752cce4fd101599378e72db66ccf53644fa))
+ - fix fpga config write return mechanism ([ef51b09](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef51b097bfa906bf1cee8ee641a1b7bcc8c5f3c0))
+ - flush dcache before sending certificate to mailbox ([49d44ec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49d44ec5f357b1bcf8eae9e91fbd72aef09e00dd))
+ - get config status OK status ([07915a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/07915a4fd5848fbac69dcbf28f00353eed10a942))
+ - introduce a generic response error code ([651841f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/651841f20110ce6fac650e3ac47b0a9cce18e6f3))
+ - make FPGA memory configurations platform specific ([f571183](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f571183b066b1a91b7fb178c3aad9d6360d1918c))
+ - modify how configuration type is handled ([ec4f28e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ec4f28ecec8887a685d6119c096ad346da1ea53e))
+ - null pointer handling for resp_len ([a250c04](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a250c04b0cc807f626df92a7091ff13b3a3aa9ed))
+ - refactor NOC header ([bc1a573](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc1a573d5519f121cb872fce1d88fe2e0db07b2c))
+ - reject non 4-byte align request size for FPGA Crypto Service (FCS) ([52ed157](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52ed157fd66812debb13a792c21f763de01aef70))
+ - remove redundant NOC header declarations ([58690cd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/58690cd629b4ccdefe5313f805219598074a3501))
+ - remove unused printout ([0d19eda](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0d19eda0dd2ffae27d0551b1f0a06a2b8f96c853))
+ - update certificate mask for FPGA Attestation ([fe5637f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fe5637f27aebfdab42915c2ced2c34d8685ee2bb))
+ - update encryption and decryption command logic ([02d3ef3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/02d3ef333d4a0a07a3e40defb12a8cde3a7cba03))
+ - use macro as return value ([e0fc2d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0fc2d1907b1c8a062c44a435be77a12ffeed84b))
+
+ - **Marvell**
+
+ - **Armada**
+
+ - **A3K**
+
+ - change fatal error to warning when CM3 reset is not implemented ([30cdbe7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30cdbe7043832f7bd96b40294ac062a8fc9c540f))
+ - fix comment about BootROM address range ([5a60efa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5a60efa12a57cde98240f861e45609cb9b94d58d))
+
+ - **Mediatek**
+
+ - **MT8186**
+
+ - remove unused files in drivers/mcdi ([bc714ba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc714bafe7ae8ca29075ba9bf3985c0e15ae0f64))
+ - extend MMU region size ([0fe7ae9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0fe7ae9c64aa6f6d5b06a80de9c88081057d5dbe))
+
+ - **NVIDIA**
+
+ - **Tegra**
+
+ - **Tegra 194**
+
+ - remove incorrect erxctlr assert ([e272c61](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e272c61ce8185deb397dcf168ec72bdaa5926a33))
+
+ - **NXP**
+
+ - fix total dram size checking ([0259a3e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0259a3e8282ed17c1d378a27f820f44b3bebab07))
+ - increase soc name maximum length ([3ccd7e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3ccd7e45a2c3ff9fa7794f0284c9d0298e7cb982))
+
+ - **i.MX**
+
+ - **i.MX 8M**
+
+ - check the validation of domain id ([eb7fb93](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eb7fb938c3ce34ccfb143ae8ba695df899098436))
+
+ - **i.MX 8M Plus**
+
+ - change the BL31 physical load address ([32d5042](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32d5042204e8b41caa4c0c1ed5b48bad9f1cb1b5))
+
+ - **Layerscape**
+
+ - fix build issue of mmap_add_ddr_region_dynamically ([e2818d0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e2818d0afc20a60d302f85f4c915e4ae4cc3cb9c))
+ - fix coverity issue ([5161cfd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5161cfde9bfaa3a715d160fcd4870f276adad332))
+ - update WA for Errata A-050426 ([72feaad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/72feaad980cdc472868bc95914202bf57ed51b2d))
+
+ - **LX2**
+
+ - drop erratum A-009810 ([e36b0e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e36b0e4910aea56f90a6ab9b8cf3dc4008220031))
+
+ - **Renesas**
+
+ - **R-Car**
+
+ - **R-Car 3**
+
+ - change stack size of BL31 ([d544dfc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d544dfcc4959d203b06dbfb85fb0ad895178b379))
+ - fix SYSTEM_OFF processing for R-Car D3 ([1b49ba0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b49ba0fde5eb9e47fe50152c192579101feb718))
+ - fix to bit operation for WUPMSKCA57/53 ([82bb6c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/82bb6c2e88314a5b3f2326c95095c3b20a389947))
+
+ - **Socionext**
+
+ - **Synquacer**
+
+ - initialise CNTFRQ in Non Secure CNTBaseN ([4d4911d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4d4911d77d4d59c7dd18d7fc3724ddb1fa3582b7))
+
+ - **ST**
+
+ - add missing header include ([b1391b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b1391b294ca7803f46bc47048b4a02a15dda9a16))
+ - don't try to read boot partition on SD cards ([9492b39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9492b391a35c66e1e7630e95347259191b28314d))
+ - fix NULL pointer dereference issues ([2deff90](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2deff904a953c6a87331ab6830ab80e3889d9e23))
+ - manage UART clock and reset only in BL2 ([9e52d45](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9e52d45fdf619561e0a7a833b77aaacc947a4dfd))
+ - remove extra chars from dtc version ([03d2077](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03d20776efc20a04a5191a4f39965079a4d60b3c))
+
+ - **ST32MP1**
+
+ - add missing debug.h ([356ed96](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/356ed961184847dcd088cfcda44b71eeb0ef2377))
+ - correct dtc version check ([429f10e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/429f10e3367748abd33b4f6f9ee362c0ba74dd95))
+ - correct include order ([ff7675e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff7675ebf94999618dbde14bb59741cefb2b2edd))
+ - correct types in messages ([43bbdca](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/43bbdca04f5a20bb4e648e18fc63061b6a6e4ecf))
+ - deconfigure UART RX pins ([d7176f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d7176f0319cd399aae9a906e5d78e67b32e183f5))
+ - do not reopen debug features ([21cfa45](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21cfa4531a76a7c3cad00e874400b97e2f68723c))
+ - fix enum prints ([ceab2fc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ceab2fc3442dbda1c4beaff3c4fe708a04c02303))
+ - include assert.h to fix build failure ([570c71b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/570c71b20a195ade510f5d584c69325d2634c50b))
+ - remove interrupt_provider warning for dtc ([ca88c76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ca88c761d34854ed3e0b16b9c5f39b0790d320ab))
+ - restrict DEVICE2 mapping in BL2 ([db3e0ec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/db3e0ece7157181a3529d14172368003eb63dc30))
+ - rework switch/case for MISRA ([f7130e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f7130e81cf9c3682232bb9319b1798184b44920f))
+ - set reset pulse duration to 31ms ([9a73a56](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a73a56c353d32742e03b828647562bdbe2ddbb2))
+
+ - **Xilinx**
+
+ - fix coding style violations ([bb1768c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb1768c67ea06ac466e2cdc7e5338c3d23dac79d))
+ - fix mismatching function prototype ([81333ea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/81333eac716b25a9fd112cc4f5990e069f3bdb40))
+
+ - **Versal**
+
+ - resolve misra R10.1 in pm services ([775bf1b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/775bf1bbd32c2df47f4ff597eb8a452d2983e590))
+ - resolve misra R10.3 ([b2bb3ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b2bb3efb8f590f31b1205c51d56be1dd6f473fbb))
+ - resolve misra R10.3 in pm services ([5d1c211](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5d1c211e225d40d2926bf34483c90f907a6c5dc3))
+ - resolve misra R10.6 ([93d4625](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/93d462562727f4f428e6f975a972226dafbfd305))
+ - resolve misra R10.6 in pm services ([fa98d7f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fa98d7f2f8752e37f740b43f533547288552a393))
+ - resolve misra R14.4 ([a62c40d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a62c40d42703d5f60a8d80938d2cff721ee131bd))
+ - resolve misra R15.6 ([b9fa2d9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9fa2d9fc154feffe78e677ace54b0e34f011439))
+ - resolve misra R15.6 in pm services ([4156719](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4156719550ceddf5b1b4a47464fb32f7506e0dca))
+ - resolve misra R15.7 ([bc2637e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc2637e3799dbc9642447ddb719e0262347b1309))
+ - resolve misra R16.3 in pm services ([27ae531](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/27ae5310883b0db7d4e2dd4fbc1fd58e675f75b5))
+ - resolve misra R17.7 ([526a1fd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/526a1fd1472874561988777f8ecd8b87734a0671))
+ - resolve misra R20.7 in pm services ([5dada62](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5dada6227b949ef702bfab7986bc083689afdaf7))
+ - resolve misra R7.2 ([0623dce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0623dcea0f6e7a5c9d65413445df8a96a2b40d42))
+ - fix coverity scan warnings ([0b15187](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0b15187225a9134e3acbc7693646b21d43617b3b))
+ - fix the incorrect log message ([ea04b3f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ea04b3fe183b6661f656b4cc38cb93a73d9bc202))
+
+ - **ZynqMP**
+
+ - define and enable ARM_XLAT_TABLES_LIB_V1 ([c884c9a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c884c9a55b167383ff3d96d2d0a30ac6842bcc86))
+ - query node status to power up APU ([b35b556](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b35b556718b60b78cb5d96b0c137e2fe82eb0086))
+ - resolve misra 7.2 warnings ([5bcbd2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5bcbd2de127292f3ad076217e08468388c6844b0))
+ - resolve misra 8.3 warnings ([944e7ea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/944e7ea94f2594e2b128c671cf7415265302596b))
+ - resolve misra R10.3 ([2b57da6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2b57da6c91ebe14588e63e5a24f31ef32711eca2))
+ - resolve misra R14.4 warnings ([dd1fe71](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dd1fe7178b578916b1e133b7c65c183e1f994371))
+ - resolve misra R15.6 warnings ([eb0d2b1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eb0d2b17722c01a22bf3ec1123f7bed2bf891b09))
+ - resolve misra R15.7 warnings ([16de22d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/16de22d037644359ef2a04058134f9c326b36633))
+ - resolve misra R16.3 warnings ([e7e5d30](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e7e5d30308ccfb931f7b6d0afa6c5c23971e95c0))
+ - resolve misra R8.4 warnings ([610eeac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/610eeac89438d603435bde694eb4ddab07f46e45))
+ - update the log message to verbose ([1277af9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1277af9bacca36b46d7aa341187bb3abef84332f))
+ - use common interface for eemi apis ([a469c1e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a469c1e1f4c1cd69f98ce45d6e0709de091b8cb3))
+
+- **Bootloader Images**
+
+ - **BL1**
+
+ - invalidate SP in data cache during secure SMC ([f1cbbd6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f1cbbd6332bb85672dc72cbcc4ac7023323c6936))
+
+ - **BL2**
+
+ - correct messages with image_id ([e4c77db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e4c77db9c80d87009611a3079454877e6ce45a04))
+ - define RAM_NOLOAD for XIP ([cc562e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc562e74101d800b0b0ee3422fb7f4f8321ae2b7))
+
+- **Services**
+
+ - **RME**
+
+ - enable/disable SVE/FPU for Realms ([a4cc85c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4cc85c129d031d9c887cf59b1baeaef18a43010))
+ - align RMI and GTSI FIDs with SMCCC ([b9fd2d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9fd2d3ce3d4e543a2e04dc237cd4e7ff7765c7a))
+ - preserve x4-x7 as per SMCCCv1.1 ([1157830](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11578303fd04a8da36fddb5e6de44f026bf4d24c))
+
+ - **TRP**
+
+ - Distinguish between cold and warm boot ([00e8113](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/00e8113145aa12d89db72068bdd3157f08575d14))
+
+ - **SPM**
+
+ - **EL3 SPMC**
+
+ - fix incorrect FF-A version usage ([25eb2d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/25eb2d41a6d2ede1e945bbc67ae3f740b92a40bb))
+ - fix FF-A memory transaction validation ([3954bc3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3954bc3c03439dbdc7029cf2418c79a037918ce4))
+
+- **Libraries**
+
+ - **CPU Support**
+
+ - workaround for Cortex-A710 2282622 ([ef934cd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef934cd17c30dcc39cd9022a1c4e9523ec8ba617))
+ - workaround for Cortex-A710 erratum 2267065 ([cfe1a8f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cfe1a8f7123f0dc8376b2075cc6e8e32b13739b2))
+ - workaround for Cortex A78 AE erratum 2376748 ([92e8708](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/92e870843e9bd654fd1041d66f284c19ca9c0d4f))
+ - workaround for Cortex A78 AE erratum 2395408 ([3f4d81d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3f4d81dfd26649fbcbbbe993a9f0236f5bb07c8a))
+ - workaround for Cortex X2 erratum 2002765 ([34ee76d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/34ee76dbdfeee85f123cb903ea95dbee5e9a44a5))
+ - workaround for Cortex X2 erratum 2058056 ([e16045d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e16045de50e8b430e6601ba0e1e47097d8310f3d))
+ - workaround for Cortex X2 erratum 2083908 ([1db6cd6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1db6cd60279e2d082876692a65cf9c532f506a69))
+ - workaround for Cortex-A510 erratum 1922240 ([8343563](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83435637bfafbf1ce642a5fabb52e8d7b2819e36))
+ - workaround for Cortex-A510 erratum 2041909 ([e72bbe4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e72bbe47ba7f2a0087654fd99ae24b5b7b444943))
+ - workaround for Cortex-A510 erratum 2042739 ([d48088a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d48088acbe400133037ae74acf1b722b059119bb))
+ - workaround for Cortex-A510 erratum 2172148 ([c0959d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0959d2c460cbf7c14e7ba2a57d69ecddae80fd8))
+ - workaround for Cortex-A510 erratum 2218950 ([cc79018](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc79018b71e45acb524fc5d429d394497ad53646))
+ - workaround for Cortex-A510 erratum 2250311 ([7f304b0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f304b02a802b7293d7a8b4f4030c5ff00158404))
+ - workaround for Cortex-A510 erratum 2288014 ([d5e2512](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5e2512c6b86409686f5d1282922ebdf72459fc2))
+ - workaround for Cortex-A710 erratum 2008768 ([af220eb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af220ebbe467aa580e6b9ba554676f78ffec930f))
+ - workaround for Cortex-A710 erratum 2136059 ([8a855bd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8a855bd24329e081cf13a257c7d2dc3ab4e5dcca))
+ - workaround for Cortex-A78 erratum 2376745 ([5d796b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5d796b3a25150faff68013880f5a9350cbc53889))
+ - workaround for Cortex-A78 erratum 2395406 ([3b577ed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b577ed53d104cfb324390b7519da5e7744d1001))
+ - workaround for Cortex-X2 errata 2017096 ([e7ca443](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e7ca4433fa591233e7e2912b689ab56e531f9775))
+ - workaround for Cortex-X2 errata 2081180 ([c060b53](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c060b5337a43cd42f55b99d83096bb44b51b5335))
+ - workaround for Cortex-X2 erratum 2147715 ([63446c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/63446c27d11453faacfddecffa44d3880615d412))
+ - workaround for Cortex-X2 erratum 2216384 ([4dff759](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4dff7594f94f1e788aef709cc5b3d079693b6242))
+ - workaround for DSU-110 erratum 2313941 ([7e3273e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e3273e8e4dca44e7cb88a827b94e662fa8f83e9))
+ - workaround for Rainier erratum 1868343 ([a72144f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a72144fb7a30c2782a583a3b0064e741d1fe2c9f))
+ - workarounds for cortex-x1 errata ([7b76c20](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7b76c20d8eb4271b381371ce0d510fbe6ad825bf))
+ - use CPU_NO_EXTRA3_FUNC for all variants ([b2ed998](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b2ed99894d326993961680fb8e786c267a712400))
+
+ - **EL3 Runtime**
+
+ - set unset pstate bits to default ([7d33ffe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d33ffe4c116506ed63e820d5b6edad81680cd11))
+
+ - **Context Management**
+
+ - add barrier before el3 ns exit ([0482503](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04825031b2384a08504821f39e98e23bb6f93f11))
+ - remove registers accessible only from secure state from EL2 context ([7f41bcc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f41bcc76d8857b4678c90796ebd85794ff3ee5f))
+ - refactor the cm_setup_context function ([2bbad1d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2bbad1d126248435e26f9d0d9f5920d8806148d7))
+ - remove initialization of EL2 registers when EL2 is used ([fd5da7a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fd5da7a84731e9687f56c263ff3aa8ebed75075a))
+ - add cm_prepare_el3_exit_ns function ([8b95e84](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8b95e8487006ff77a7d84fba5bd20ba7e68d8330))
+ - refactor initialization of EL1 context registers ([b515f54](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b515f5414b00a8b7ca9b21363886ea976bd19914))
+
+ - **FCONF**
+
+ - correct image_id type in messages ([cec2fb2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cec2fb2b1a8359bf1f349a5b8c8a91a1845f4ca1))
+
+ - **PSCI**
+
+ - correct parent_node type in messages ([b9338ee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9338eee7fbcac7f4b55f27b064572e847810422))
+
+ - **GPT**
+
+ - rework delegating/undelegating sequence ([6a00e9b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a00e9b0c8c37fc446f83ef63e95a75353e31e8b))
+
+ - **Translation Tables**
+
+ - fix bug on VERBOSE trace ([956d76f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/956d76f69d0c96829784c5a6d16aa79e4e0ecab1))
+
+ - **Standard C Library**
+
+ - correct some messages ([a211fde](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a211fde940d4dbd8e95e4f352af2a066a4f89f30))
+ - fix snprintf corner cases ([c1f5a09](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c1f5a0925ddf84981d9e176d146bfddb48eb45d1))
+ - limit snprintf radix value ([b30dd40](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b30dd4030dcef950eac05393013ee019c3cb3205))
+ - snprintf: include stdint.h ([410c925](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/410c925ab31693dc74d654ff9167c8eed3ec5a62))
+
+ - **Locks**
+
+ - add __unused for clang ([5a030ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5a030ce4aed271344087bca723903e10fef59ac9))
+
+- **Drivers**
+
+ - **FWU**
+
+ - rename is_fwu_initialized ([aae7c96](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aae7c96de63914c954f0fc64cd795844832483fc))
+
+ - **I/O**
+
+ - **MTD**
+
+ - correct types in messages ([6e86b46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6e86b462490429fee6db877338a649b0e199b0ec))
+
+ - **Measured Boot**
+
+ - add RMM entry to event_log_metadata ([f4e3e1e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4e3e1e85f64d8930e89c1396bc9785512f656bd))
+
+ - **MTD**
+
+ - correct types in messages ([6e86b46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6e86b462490429fee6db877338a649b0e199b0ec))
+
+ - **SCMI**
+
+ - add missing \n in ERROR message ([0dc9f52](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0dc9f52a2a9f0b9686c65dd60c84e0bcca552144))
+ - make msg_header variable volatile ([99477f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99477f051ef857a1e0600cb98858fc74c007e1ff))
+ - use same type for message_id ([2355ebf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2355ebff6f6312086868f44b8ad7f821f6385208))
+
+ - **UFS**
+
+ - delete call to inv_dcache_range for utrd ([c5ee858](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c5ee8588bf9a36075723e5aacceefa93fd2de8c9))
+ - disables controller if enabled ([b3f03b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b3f03b20135fc5fcd5e6ec7e5ca49f1e59b5602e))
+ - don't zero out buf before ufs read ([2ef6b8d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2ef6b8d378e7f7c1b1eb7abe176989c3f996f2dc))
+ - don't zero out the write buffer ([cd3ea90](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd3ea90b200534b8c9d81619731c9ce198478a3c))
+ - fix cache maintenance issues ([38a5ecb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/38a5ecb756e217a80ed951747797ab150449ee9b))
+ - move nutrs assignment to ufs_init ([0956319](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0956319b580726029ddc4e00cde6c5a348b99052))
+ - read and write attribute based on spec ([a475518](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a475518337e15935469543b1cce353e5b337ef52))
+
+ - **Arm**
+
+ - **GIC**
+
+ - **GICv3**
+
+ - fix iroute value wrong issue ([65bc2d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/65bc2d224b836c230888796c4eda455997dccd8b))
+
+ - **TZC**
+
+ - **TZC-400**
+
+ - correct message with filter ([bdc88d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bdc88d2154448957f452cb472ff95ccec5808ca1))
+
+ - **Marvell**
+
+ - **COMPHY**
+
+ - change reg_set() / reg_set16() to update semantics ([95c26d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/95c26d6489bd8b2fc8b8e14bc2da5d2918055acc))
+
+ - **Armada 3700**
+
+ - drop MODE_REFDIV constant ([9fdecc7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9fdecc72f0fce17ca2cd8e4c3b26c01262166d10))
+ - fix comment about COMPHY status register ([4bcfd8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4bcfd8c02e3e3aa27b55dedeed11fb16bac991a9))
+ - fix comments about selector register values ([71183ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/71183ef6654c2a485458307a84ce7c473524689a))
+ - fix Generation Setting registers names ([e5a2aac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e5a2aac5bbc6dedb20edcc8e7850be2813cb668b))
+ - fix PIN_PU_IVREF register name ([c9f138e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c9f138ebfef90d5b7b5651f06efd81bcbc55366b))
+ - fix reference clock selection value names ([6ba97f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6ba97f83dbb314b076588b97415a4078924e1903))
+ - fix SerDes frequency register value name ([bdcf44f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bdcf44f1af496e06b693b781fe16bbc2a05fa365))
+ - use reg_set() according to update semantics ([4d01bfe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4d01bfe66522b13f0d9042206e986551c94fc01e))
+
+ - **Armada**
+
+ - **A3K**
+
+ - **A3720**
+
+ - configure UART after TX FIFO reset ([15546db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15546dbf40e5ea81a982a1e6d1e5ba729b06ae51))
+ - do external reset during initialization ([0ee80f3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ee80f35a28d651d243a6d56678800f9697d14c0))
+
+ - **NXP**
+
+ - ddr: corrects mapping of HNFs nodes ([e3a2349](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e3a234971abb2402cbf376eca6fcb657a7709fae))
+
+ - **QSPI**
+
+ - fix include path for QSPI driver ([ae95b17](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae95b1782b7a3ab9bbe46ae9ab31f48fb6ebe137))
+
+ - **NXP Crypto**
+
+ - refine code to avoid hang issue for some of toolchain ([fa7fdfa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fa7fdfabf07d91439b0869ffd8e805f0166294bf))
+
+ - **DDR**
+
+ - fix coverity issue ([f713e59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f713e5954e0906443cd20ae97e229ddbb9ab7005))
+
+ - **ST**
+
+ - **Clock**
+
+ - check _clk_stm32_get_parent return ([b8eab51](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b8eab512bf9d253f96b0333ee0f1bffa1afc3170))
+ - correct stm32_clk_parse_fdt_by_name ([7417cda](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7417cda6aeaf6abf48dfbe22dc965b626f61c613))
+ - correct types in error messages ([44fb470](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44fb470b7f298645ac31ada4491553824d77d934))
+ - initialize pllcfg table ([175758b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/175758b2777eb6df3c4aefd79448e97e76a15272))
+ - print enums as unsigned ([9fa9a0c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9fa9a0c55cc830e609415d2cedd2d34fcbec1008))
+
+ - **DDR**
+
+ - add missing debug.h ([15ca2c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15ca2c5e14abe415e70d08fb595973dd3e3b0af9))
+ - correct DDR warnings ([a078134](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a078134e2305ca5695731bc275a5ca892cc38880))
+
+ - **FMC**
+
+ - fix type in message ([afcdc9d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/afcdc9d8d71e2b60071d3d34704f0e598e67a514))
+
+ - **SDMMC2**
+
+ - check regulator enable/disable return ([d50e7a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d50e7a71cb5f8ecfbe2eb69c163d532bab82cbf0))
+ - correct cmd_idx type in messages ([bc1c98a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc1c98a8c79b6f72395123ea8ed857a488746d4b))
+
+ - **ST PMIC**
+
+ - add static const to pmic_ops ([57e6018](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/57e6018305a97f4e3627d16d8b1886419f274b4a))
+ - correct verbose message ([47065ff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47065ffe44c701b231322ec7160c8624d50a9deb))
+
+ - **SPI**
+
+ - always check SR_TCF flags in stm32_qspi_wait_cmd() ([55de583](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/55de58323e458b38b455439a8846cb663deb5508))
+ - remove SR_BUSY bit check before sending command ([5993b91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5993b9157fd049d06194083032771ffcf73da086))
+
+ - **UART**
+
+ - correctly fill BRR register ([af7775a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af7775ab535138ff49643f749110dca143d4122c))
+
+ - **USB**
+
+ - correct type in message ([bd9cd63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bd9cd63ba096cb16161efa4df40f957421660df1))
+
+- **Miscellaneous**
+
+ - **AArch64**
+
+ - fix encodings for MPAMVPM* registers ([e926558](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e92655849d0a9e5893eb2d7e5f42cf8b931d4db6))
+
+ - **FDTs**
+
+ - **STM32MP1**
+
+ - correct memory mapping for STM32MP13 ([99605fb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99605fb1166794db1dedf1b7280cb184945c229c))
+ - remove mmc1 alias if not needed ([a0e9724](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a0e972438b99012da422411c8e504a19bdad44a2))
+
+ - **PIE**
+
+ - align fixup_gdt_reloc() for aarch64 ([5ecde2a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5ecde2a271ac0f3762c16f5a277a70e55e172f0b))
+ - do not skip __RW_END__ address during relocation ([4f1a658](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f1a658f899a169e702b1c7146b59f7c04b0338b))
+
+ - **Security**
+
+ - apply SMCCC_ARCH_WORKAROUND_3 to A73/A75/A72/A57 ([9b2510b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9b2510b69de26cc7f571731b415f6dec82669b6c))
+ - loop workaround for CVE-2022-23960 for Cortex-A76 ([a10a5cb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a10a5cb609045de216c01111ec3fcf09a092da0b))
+ - report CVE 2022 23960 missing for aarch32 A57 and A72 ([2e5d7a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2e5d7a4b6b26d9d8b6c8e580c33d877e591b1fb3))
+ - update Cortex-A15 CPU lib files for CVE-2022-23960 ([187a617](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/187a61761ef5d59bed0c94cca725bd6f116f64d0))
+ - workaround for CVE-2022-23960 ([c2a1521](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c2a15217c3053117f4d39233002cb1830fa96670))
+ - workaround for CVE-2022-23960 ([1fe4a9d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1fe4a9d181ead0dcb2bc494e90552d3e7f0aaf4c))
+ - workaround for CVE-2022-23960 for A76AE, A78AE, A78C ([5f802c8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5f802c8832f3c5824ca6de17593205ebbf8bf585))
+ - workaround for CVE-2022-23960 for Cortex-A57, Cortex-A72 ([be9121f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be9121fd311ff48c94f3d90fe7efcf84586119e4))
+ - workaround for CVE-2022-23960 for Cortex-X1 ([e81e999](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e81e999b9da33ab5d2d3e5185b1ad7c46046329c))
+
+- **Tools**
+
+ - **NXP Tools**
+
+ - fix create_pbl print log ([31af441](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/31af441a0445d4a5e88ddcc371c51b3701c25839))
+ - fix tool location path for byte_swape ([a89412a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a89412a649020367a3ed0f87658ee131cd3dcd18))
+
+ - **Firmware Image Package Tool**
+
+ - avoid packing the zero size images in the FIP ([ab556c9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab556c9c646f1b5f1b500449a5813a4eecdc0302))
+ - respect OPENSSL_DIR ([0a956f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a956f81805b46b1530f30dd79d16950dc491a7b)
+
+ - **Secure Partition Tool**
+
+ - add leading zeroes in UUID conversion ([b06344a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b06344a3f2c5a0fede3646627f37d1fce3d3d585))
+ - update Optee FF-A manifest ([ca0fdbd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ca0fdbd8e0d625ece0f87ca16eacabf13db70921))
+
+ - **Certificate Creation Tool**
+
+ - let distclean Makefile target remove the cert_create tool ([e15591a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e15591aaf47ab45941f0d7a03abf3e4a830ac1d9))
+
+- **Dependencies**
+
+ - **commitlint**
+
+ - change scope-case to lower-case ([804e52e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/804e52e9a770de72913f27b5bc9e7dd965e114c5))
+
## [2.6.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.5..refs/tags/v2.6) (2021-11-22)
### ⚠ BREAKING CHANGES
@@ -4738,7 +5928,7 @@
______________________________________________________________________
-*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.*
[mbed tls releases]: https://tls.mbed.org/tech-updates/releases
[pr#1002]: https://github.com/ARM-software/arm-trusted-firmware/pull/1002#issuecomment-312650193
diff --git a/docs/components/fconf/fconf_properties.rst b/docs/components/fconf/fconf_properties.rst
index 5c28a7a..20cc758 100644
--- a/docs/components/fconf/fconf_properties.rst
+++ b/docs/components/fconf/fconf_properties.rst
@@ -30,3 +30,10 @@
- value type: <u32>
- Image ID of the configuration.
+- ns-load-address [optional]
+ - value type: <u64>
+ - Physical loading base address of the configuration in the non-secure
+ memory.
+ Only needed by those configuration files which require being loaded
+ in secure memory (at load-address) as well as in non-secure memory
+ e.g. HW_CONFIG
diff --git a/docs/components/ffa-manifest-binding.rst b/docs/components/ffa-manifest-binding.rst
index df2985c..6d2f905 100644
--- a/docs/components/ffa-manifest-binding.rst
+++ b/docs/components/ffa-manifest-binding.rst
@@ -4,11 +4,8 @@
This document defines the nodes and properties used to define a partition,
according to the FF-A specification.
-Version 1.0
------------
-
Partition Properties
-^^^^^^^^^^^^^^^^^^^^
+--------------------
- compatible [mandatory]
- value type: <string>
@@ -137,20 +134,30 @@
- gp-register-num
- value type: <u32>
- - Presence of this field indicates that the partition expects the
- ffa_init_info structure to be passed in via the specified general purpose
- register.
- The field specifies the general purpose register number but not its width.
+ - The field specifies the general purpose register number but not its width.
The width is derived from the partition's execution state, as specified in
the partition properties. For example, if the number value is 1 then the
general-purpose register used will be x1 in AArch64 state and w1 in AArch32
state.
+ Presence of this field indicates that the partition expects the address of
+ the FF-A boot information blob to be passed in the specified general purpose
+ register.
- stream-endpoint-ids
- value type: <prop-encoded-array>
- List of <u32> tuples, identifying the IDs this partition is acting as
proxy for.
+- power-management-messages
+ - value type: <u32>
+ - Specifies which power management messages a partition subscribes to.
+ A set bit means the partition should be informed of the power event, clear
+ bit - should not be informed of event:
+
+ - Bit[0]: CPU_OFF
+ - Bit[1]: CPU_SUSPEND
+ - Bit[2]: CPU_SUSPEND_RESUME
+
Memory Regions
--------------
@@ -174,13 +181,14 @@
- 0x1: Read
- 0x2: Write
- 0x4: Execute
+ - 0x8: Security state
- base-address
- value type: <u64>
- Base address of the region. The address must be aligned to the translation
granule size.
The address given may be a Physical Address (PA), Virtual Address (VA), or
- Intermediate Physical Address (IPA). Refer to the FFA specification for
+ Intermediate Physical Address (IPA). Refer to the FF-A specification for
more information on the restrictions around the address type.
If the base address is omitted then the partition manager must map a memory
region of the specified size into the partition's translation regime and
@@ -198,14 +206,10 @@
- value type: <string>
- Name of the device region e.g. for debugging purposes.
-- reg [mandatory]
- - value type: <prop-encoded-array>
- - A (address, num-pages) pair describing the device, where:
-
- - address: The physical base address <u64> value of the device MMIO
- region.
- - num-pages: The <u32> number of pages of the region. The total size of
- the region is this value multiplied by the translation granule size.
+- pages-count [mandatory]
+ - value type: <u32>
+ - Count of pages of memory region as a multiple of the translation granule
+ size
- attributes [mandatory]
- value type: <u32>
@@ -214,6 +218,15 @@
- 0x1: Read
- 0x2: Write
- 0x4: Execute
+ - 0x8: Security state
+
+- base-address [mandatory]
+ - value type: <u64>
+ - Base address of the region. The address must be aligned to the translation
+ granule size.
+ The address given may be a Physical Address (PA), Virtual Address (VA), or
+ Intermediate Physical Address (IPA). Refer to the FF-A specification for
+ more information on the restrictions around the address type.
- smmu-id
- value type: <u32>
@@ -233,14 +246,32 @@
- A list of (id, attributes) pair describing the device interrupts, where:
- id: The <u32> interrupt IDs.
- - attributes: A <u32> value,
- containing the attributes for each interrupt ID:
+ - attributes: A <u32> value, containing attributes for each interrupt ID:
+
+ +----------------------+----------+
+ |Field | Bit(s) |
+ +----------------------+----------+
+ | Priority | 7:0 |
+ +----------------------+----------+
+ | Security state | 8 |
+ +----------------------+----------+
+ | Config(Edge/Level) | 9 |
+ +----------------------+----------+
+ | Type(SPI/PPI/SGI) | 11:10 |
+ +----------------------+----------+
- - Interrupt type: SPI, PPI, SGI
- - Interrupt configuration: Edge triggered, Level triggered
- - Interrupt security state: Secure, Non-secure
- - Interrupt priority value
- - Target execution context/vCPU for each SPI
+ Security state:
+ - Secure: 1
+ - Non-secure: 0
+
+ Configuration:
+ - Edge triggered: 0
+ - Level triggered: 1
+
+ Type:
+ - SPI: 0b10
+ - PPI: 0b01
+ - SGI: 0b00
- exclusive-access
- value type: <empty>
@@ -249,4 +280,4 @@
--------------
-*Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/index.rst b/docs/components/index.rst
index 95fe42c..192773f 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -21,8 +21,8 @@
sdei
secure-partition-manager
secure-partition-manager-mm
- ffa-manifest-binding
xlat-tables-lib-v2-design
cot-binding
realm-management-extension
+ rmm-el3-comms-spec
granule-protection-tables-design
diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst
index 5fa5140..ea921fc 100644
--- a/docs/components/realm-management-extension.rst
+++ b/docs/components/realm-management-extension.rst
@@ -73,6 +73,14 @@
world. It initializes the RMM and handles Realm Management Interface (RMI)
SMC calls from Non-secure and Realm worlds.
+There is a contract between RMM and RMMD that defines the arguments that the
+former needs to take in order to initialize and also the possible return values.
+This contract is defined in the RMM Boot Interface, which can be found at
+:ref:`rmm_el3_boot_interface`.
+
+There is also a specification of the runtime services provided by TF-A
+to RMM. This can be found at :ref:`runtime_services_and_interface`.
+
Test Realm Payload (TRP)
*************************
TRP is a small test payload that runs at R-EL2 and implements a subset of
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
new file mode 100644
index 0000000..b767958
--- /dev/null
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -0,0 +1,537 @@
+RMM-EL3 Communication interface
+*******************************
+
+This document defines the communication interface between RMM and EL3.
+There are two parts in this interface: the boot interface and the runtime
+interface.
+
+The Boot Interface defines the ABI between EL3 and RMM when the CPU enters
+R-EL2 for the first time after boot. The cold boot interface defines the ABI
+for the cold boot path and the warm boot interface defines the same for the
+warm path.
+
+The RMM-EL3 runtime interface defines the ABI for EL3 services which can be
+invoked by RMM as well as the register save-restore convention when handling an
+SMC call from NS.
+
+The below sections discuss these interfaces more in detail.
+
+.. _rmm_el3_ifc_versioning:
+
+RMM-EL3 Interface versioning
+____________________________
+
+The RMM Boot and Runtime Interface uses a version number to check
+compatibility with the register arguments passed as part of Boot Interface and
+RMM-EL3 runtime interface.
+
+The Boot Manifest, discussed later in section :ref:`rmm_el3_boot_manifest`,
+uses a separate version number but with the same scheme.
+
+The version number is a 32-bit type with the following fields:
+
+.. csv-table::
+ :header: "Bits", "Value"
+
+ [0:15],``VERSION_MINOR``
+ [16:30],``VERSION_MAJOR``
+ [31],RES0
+
+The version numbers are sequentially increased and the rules for updating them
+are explained below:
+
+ - ``VERSION_MAJOR``: This value is increased when changes break
+ compatibility with previous versions. If the changes
+ on the ABI are compatible with the previous one, ``VERSION_MAJOR``
+ remains unchanged.
+
+ - ``VERSION_MINOR``: This value is increased on any change that is backwards
+ compatible with the previous version. When ``VERSION_MAJOR`` is increased,
+ ``VERSION_MINOR`` must be set to 0.
+
+ - ``RES0``: Bit 31 of the version number is reserved 0 as to maintain
+ consistency with the versioning schemes used in other parts of RMM.
+
+This document specifies the 0.1 version of Boot Interface ABI and RMM-EL3
+services specification and the 0.1 version of the Boot Manifest.
+
+.. _rmm_el3_boot_interface:
+
+RMM Boot Interface
+__________________
+
+This section deals with the Boot Interface part of the specification.
+
+One of the goals of the Boot Interface is to allow EL3 firmware to pass
+down into RMM certain platform specific information dynamically. This allows
+RMM to be less platform dependent and be more generic across platform
+variations. It also allows RMM to be decoupled from the other boot loader
+images in the boot sequence and remain agnostic of any particular format used
+for configuration files.
+
+The Boot Interface ABI defines a set of register conventions and
+also a memory based manifest file to pass information from EL3 to RMM. The
+boot manifest and the associated platform data in it can be dynamically created
+by EL3 and there is no restriction on how the data can be obtained (e.g by DTB,
+hoblist or other).
+
+The register convention and the manifest are versioned separately to manage
+future enhancements and compatibility.
+
+RMM completes the boot by issuing the ``RMM_BOOT_COMPLETE`` SMC (0xC40001CF)
+back to EL3. After the RMM has finished the boot process, it can only be
+entered from EL3 as part of RMI handling.
+
+If RMM returns an error during boot (in any CPU), then RMM must not be entered
+from any CPU.
+
+.. _rmm_cold_boot_interface:
+
+Cold Boot Interface
+~~~~~~~~~~~~~~~~~~~
+
+During cold boot RMM expects the following register values:
+
+.. csv-table::
+ :header: "Register", "Value"
+ :widths: 1, 5
+
+ x0,Linear index of this PE. This index starts from 0 and must be less than the maximum number of CPUs to be supported at runtime (see x2).
+ x1,Version for this Boot Interface as defined in :ref:`rmm_el3_ifc_versioning`.
+ x2,Maximum number of CPUs to be supported at runtime. RMM should ensure that it can support this maximum number.
+ x3,Base address for the shared buffer used for communication between EL3 firmware and RMM. This buffer must be of 4KB size (1 page). The boot manifest must be present at the base of this shared buffer during cold boot.
+
+During cold boot, EL3 firmware needs to allocate a 4K page that will be
+passed to RMM in x3. This memory will be used as shared buffer for communication
+between EL3 and RMM. It must be assigned to Realm world and must be mapped with
+Normal memory attributes (IWB-OWB-ISH) at EL3. At boot, this memory will be
+used to populate the Boot Manifest. Since the Boot Manifest can be accessed by
+RMM prior to enabling its MMU, EL3 must ensure that proper cache maintenance
+operations are performed after the Boot Manifest is populated.
+
+EL3 should also ensure that this shared buffer is always available for use by RMM
+during the lifetime of the system and that it can be used for runtime
+communication between RMM and EL3. For example, when RMM invokes attestation
+service commands in EL3, this buffer can be used to exchange data between RMM
+and EL3. It is also allowed for RMM to invoke runtime services provided by EL3
+utilizing this buffer during the boot phase, prior to return back to EL3 via
+RMM_BOOT_COMPLETE SMC.
+
+RMM should map this memory page into its Stage 1 page-tables using Normal
+memory attributes.
+
+During runtime, it is the RMM which initiates any communication with EL3. If that
+communication requires the use of the shared area, it is expected that RMM needs
+to do the necessary concurrency protection to prevent the use of the same buffer
+by other PEs.
+
+The following sequence diagram shows how a generic EL3 Firmware would boot RMM.
+
+.. image:: ../resources/diagrams/rmm_cold_boot_generic.png
+
+Warm Boot Interface
+~~~~~~~~~~~~~~~~~~~
+
+At warm boot, RMM is already initialized and only some per-CPU initialization
+is still pending. The only argument that is required by RMM at this stage is
+the CPU Id, which will be passed through register x0 whilst x1 to x3 are RES0.
+This is summarized in the following table:
+
+.. csv-table::
+ :header: "Register", "Value"
+ :widths: 1, 5
+
+ x0,Linear index of this PE. This index starts from 0 and must be less than the maximum number of CPUs to be supported at runtime (see x2).
+ x1 - x3,RES0
+
+Boot error handling and return values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After boot up and initialization, RMM returns control back to EL3 through a
+``RMM_BOOT_COMPLETE`` SMC call. The only argument of this SMC call will
+be returned in x1 and it will encode a signed integer with the error reason
+as per the following table:
+
+.. csv-table::
+ :header: "Error code", "Description", "ID"
+ :widths: 2 4 1
+
+ ``E_RMM_BOOT_SUCCESS``,Boot successful,0
+ ``E_RMM_BOOT_ERR_UNKNOWN``,Unknown error,-1
+ ``E_RMM_BOOT_VERSION_NOT_VALID``,Boot Interface version reported by EL3 is not supported by RMM,-2
+ ``E_RMM_BOOT_CPUS_OUT_OF_RAGE``,Number of CPUs reported by EL3 larger than maximum supported by RMM,-3
+ ``E_RMM_BOOT_CPU_ID_OUT_OF_RAGE``,Current CPU Id is higher or equal than the number of CPUs supported by RMM,-4
+ ``E_RMM_BOOT_INVALID_SHARED_BUFFER``,Invalid pointer to shared memory area,-5
+ ``E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED``,Version reported by the boot manifest not supported by RMM,-6
+ ``E_RMM_BOOT_MANIFEST_DATA_ERROR``,Error parsing core boot manifest,-7
+
+For any error detected in RMM during cold or warm boot, RMM will return back to
+EL3 using ``RMM_BOOT_COMPLETE`` SMC with an appropriate error code. It is
+expected that EL3 will take necessary action to disable Realm world for further
+entry from NS Host on receiving an error. This will be done across all the PEs
+in the system so as to present a symmetric view to the NS Host. Any further
+warm boot by any PE should not enter RMM using the warm boot interface.
+
+.. _rmm_el3_boot_manifest:
+
+Boot Manifest
+~~~~~~~~~~~~~
+
+During cold boot, EL3 Firmware passes a memory boot manifest to RMM containing
+platform information.
+
+This boot manifest is versioned independently of the boot interface, to help
+evolve the boot manifest independent of the rest of Boot Manifest.
+The current version for the boot manifest is ``v0.1`` and the rules explained
+in :ref:`rmm_el3_ifc_versioning` apply on this version as well.
+
+The boot manifest is divided into two different components:
+
+ - Core Manifest: This is the generic parameters passed to RMM by EL3 common to all platforms.
+ - Platform data: This is defined by the platform owner and contains information specific to that platform.
+
+For the current version of the manifest, the core manifest contains a pointer
+to the platform data. EL3 must ensure that the whole boot manifest,
+including the platform data, if available, fits inside the RMM EL3 shared
+buffer.
+
+For the type specification of the RMM Boot Manifest v0.1, refer to
+:ref:`rmm_el3_manifest_struct`
+
+.. _runtime_services_and_interface:
+
+RMM-EL3 Runtime Interface
+__________________________
+
+This section defines the RMM-EL3 runtime interface which specifies the ABI for
+EL3 services expected by RMM at runtime as well as the register save and
+restore convention between EL3 and RMM as part of RMI call handling. It is
+important to note that RMM is allowed to invoke EL3-RMM runtime interface
+services during the boot phase as well. The EL3 runtime service handling must
+not result in a world switch to another world unless specified. Both the RMM
+and EL3 are allowed to make suitable optimizations based on this assumption.
+
+If the interface requires the use of memory, then the memory references should
+be within the shared buffer communicated as part of the boot interface. See
+:ref:`rmm_cold_boot_interface` for properties of this shared buffer which both
+EL3 and RMM must adhere to.
+
+RMM-EL3 runtime service return codes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The return codes from EL3 to RMM is a 32 bit signed integer which encapsulates
+error condition as described in the following table:
+
+.. csv-table::
+ :header: "Error code", "Description", "ID"
+ :widths: 2 4 1
+
+ ``E_RMM_OK``,No errors detected,0
+ ``E_RMM_UNK``,Unknown/Generic error,-1
+ ``E_RMM_BAD_ADDR``,The value of an address used as argument was invalid,-2
+ ``E_RMM_BAD_PAS``,Incorrect PAS,-3
+ ``E_RMM_NOMEM``,Not enough memory to perform an operation,-4
+ ``E_RMM_INVAL``,The value of an argument was invalid,-5
+
+If multiple failure conditions are detected in an RMM to EL3 command, then EL3
+is allowed to return an error code corresponding to any of the failure
+conditions.
+
+RMM-EL3 runtime services
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following table summarizes the RMM runtime services that need to be
+implemented by EL3 Firmware.
+
+.. csv-table::
+ :header: "FID", "Command"
+ :widths: 2 5
+
+ 0xC400018F,``RMM_RMI_REQ_COMPLETE``
+ 0xC40001B0,``RMM_GTSI_DELEGATE``
+ 0xC40001B1,``RMM_GTSI_UNDELEGATE``
+ 0xC40001B2,``RMM_ATTEST_GET_REALM_KEY``
+ 0xC40001B3,``RMM_ATTEST_GET_PLAT_TOKEN``
+
+RMM_RMI_REQ_COMPLETE command
+============================
+
+Notifies the completion of an RMI call to the Non-Secure world.
+
+This call is the only function currently in RMM-EL3 runtime interface which
+results in a world switch to NS. This call is the reply to the original RMI
+call and it is forwarded by EL3 to the NS world.
+
+FID
+---
+
+``0xC400018F``
+
+Input values
+------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ fid,x0,[63:0],UInt64,Command FID
+ err_code,x1,[63:0],RmiCommandReturnCode,Error code returned by the RMI service invoked by NS World. See Realm Management Monitor specification for more info
+
+Output values
+-------------
+
+This call does not return.
+
+Failure conditions
+------------------
+
+Since this call does not return to RMM, there is no failure condition which
+can be notified back to RMM.
+
+RMM_GTSI_DELEGATE command
+=========================
+
+Delegate a memory granule by changing its PAS from Non-Secure to Realm.
+
+FID
+---
+
+``0xC40001B0``
+
+Input values
+------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ fid,x0,[63:0],UInt64,Command FID
+ base_pa,x1,[63:0],Address,PA of the start of the granule to be delegated
+
+Output values
+-------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 2 4
+
+ Result,x0,[63:0],Error Code,Command return status
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table::
+ :header: "ID", "Condition"
+ :widths: 1 5
+
+ ``E_RMM_BAD_ADDR``,``PA`` does not correspond to a valid granule address
+ ``E_RMM_BAD_PAS``,The granule pointed by ``PA`` does not belong to Non-Secure PAS
+ ``E_RMM_OK``,No errors detected
+
+RMM_GTSI_UNDELEGATE command
+===========================
+
+Undelegate a memory granule by changing its PAS from Realm to Non-Secure.
+
+FID
+---
+
+``0xC40001B1``
+
+Input values
+------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ fid,x0,[63:0],UInt64,Command FID
+ base_pa,x1,[63:0],Address,PA of the start of the granule to be undelegated
+
+Output values
+-------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 2 4
+
+ Result,x0,[63:0],Error Code,Command return status
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table::
+ :header: "ID", "Condition"
+ :widths: 1 5
+
+ ``E_RMM_BAD_ADDR``,``PA`` does not correspond to a valid granule address
+ ``E_RMM_BAD_PAS``,The granule pointed by ``PA`` does not belong to Realm PAS
+ ``E_RMM_OK``,No errors detected
+
+RMM_ATTEST_GET_REALM_KEY command
+================================
+
+Retrieve the Realm Attestation Token Signing key from EL3.
+
+FID
+---
+
+``0xC40001B2``
+
+Input values
+------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ fid,x0,[63:0],UInt64,Command FID
+ buf_pa,x1,[63:0],Address,PA where the Realm Attestation Key must be stored by EL3. The PA must belong to the shared buffer
+ buf_size,x2,[63:0],Size,Size in bytes of the Realm Attestation Key buffer. ``bufPa + bufSize`` must lie within the shared buffer
+ ecc_curve,x3,[63:0],Enum,Type of the elliptic curve to which the requested attestation key belongs to. See :ref:`ecc_curves`
+
+Output values
+-------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ Result,x0,[63:0],Error Code,Command return status
+ keySize,x1,[63:0],Size,Size of the Realm Attestation Key
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table::
+ :header: "ID", "Condition"
+ :widths: 1 5
+
+ ``E_RMM_BAD_ADDR``,``PA`` is outside the shared buffer
+ ``E_RMM_INVAL``,``PA + BSize`` is outside the shared buffer
+ ``E_RMM_INVAL``,``Curve`` is not one of the listed in :ref:`ecc_curves`
+ ``E_RMM_UNK``,An unknown error occurred whilst processing the command
+ ``E_RMM_OK``,No errors detected
+
+.. _ecc_curves:
+
+Supported ECC Curves
+--------------------
+
+.. csv-table::
+ :header: "ID", "Curve"
+ :widths: 1 5
+
+ 0,ECC SECP384R1
+
+RMM_ATTEST_GET_PLAT_TOKEN command
+=================================
+
+Retrieve the Platform Token from EL3.
+
+FID
+---
+
+``0xC40001B3``
+
+Input values
+------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ fid,x0,[63:0],UInt64,Command FID
+ buf_pa,x1,[63:0],Address,PA of the platform attestation token. The challenge object is passed in this buffer. The PA must belong to the shared buffer
+ buf_size,x2,[63:0],Size,Size in bytes of the platform attestation token buffer. ``bufPa + bufSize`` must lie within the shared buffer
+ c_size,x3,[63:0],Size,Size in bytes of the challenge object. It corresponds to the size of one of the defined SHA algorithms
+
+Output values
+-------------
+
+.. csv-table::
+ :header: "Name", "Register", "Field", "Type", "Description"
+ :widths: 1 1 1 1 5
+
+ Result,x0,[63:0],Error Code,Command return status
+ tokenSize,x1,[63:0],Size,Size of the platform token
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table::
+ :header: "ID", "Condition"
+ :widths: 1 5
+
+ ``E_RMM_BAD_ADDR``,``PA`` is outside the shared buffer
+ ``E_RMM_INVAL``,``PA + BSize`` is outside the shared buffer
+ ``E_RMM_INVAL``,``CSize`` does not represent the size of a supported SHA algorithm
+ ``E_RMM_UNK``,An unknown error occurred whilst processing the command
+ ``E_RMM_OK``,No errors detected
+
+RMM-EL3 world switch register save restore convention
+_____________________________________________________
+
+As part of NS world switch, EL3 is expected to maintain a register context
+specific to each world and will save and restore the registers
+appropriately. This section captures the contract between EL3 and RMM on the
+register set to be saved and restored.
+
+EL3 must maintain a separate register context for the following:
+
+ #. General purpose registers (x0-x30) and ``sp_el0``, ``sp_el2`` stack pointers
+ #. EL2 system register context for all enabled features by EL3. These include system registers with the ``_EL2`` prefix. The EL2 physical and virtual timer registers must not be included in this.
+
+It is the responsibility of EL3 that the above registers will not be leaked to
+the NS Host and to maintain the confidentiality of the Realm World.
+
+EL3 will not save some registers as mentioned in the below list. It is the
+responsibility of RMM to ensure that these are appropriately saved if the
+Realm World makes use of them:
+
+ #. FP/SIMD registers
+ #. SVE registers
+ #. SME registers
+ #. EL1/0 registers
+
+SMCCC v1.3 allows NS world to specify whether SVE context is in use. In this
+case, RMM could choose to not save the incoming SVE context but must ensure
+to clear SVE registers if they have been used in Realm World. The same applies
+to SME registers.
+
+Types
+_____
+
+.. _rmm_el3_manifest_struct:
+
+RMM-EL3 Boot Manifest Version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The RMM-EL3 Boot Manifest structure contains platform boot information passed
+from EL3 to RMM. The width of the Boot Manifest is 128 bits
+
+.. image:: ../resources/diagrams/rmm_el3_manifest_struct.png
+
+The members of the RMM-EL3 Boot Manifest structure are shown in the following
+table:
+
+.. csv-table::
+ :header: "Name", "Range", "Type", Description
+ :widths: 2 1 1 4
+
+ ``Version Minor``,15:0,uint16_t,Version Minor part of the Boot Manifest Version.
+ ``Version Major``,30:16,uint16_t,Version Major part of the Boot Manifest Version.
+ ``RES0``,31,bit,Reserved. Set to 0.
+ ``Platform Data``,127:64,Address,Pointer to the Platform Data section of the Boot Manifest.
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index a598e5f..18d870b 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -3,6 +3,9 @@
.. contents::
+.. toctree::
+ ffa-manifest-binding
+
Acronyms
========
@@ -23,6 +26,8 @@
+--------+--------------------------------------+
| IPA | Intermediate Physical Address |
+--------+--------------------------------------+
+| JOP | Jump-Oriented Programming |
++--------+--------------------------------------+
| NWd | Normal World |
+--------+--------------------------------------+
| ODM | Original Design Manufacturer |
@@ -37,6 +42,8 @@
+--------+--------------------------------------+
| PVM | Primary VM |
+--------+--------------------------------------+
+| ROP | Return-Oriented Programming |
++--------+--------------------------------------+
| SMMU | System Memory Management Unit |
+--------+--------------------------------------+
| SP | Secure Partition |
@@ -63,24 +70,25 @@
Foreword
========
-Two implementations of a Secure Partition Manager co-exist in the TF-A codebase:
+Three implementations of a Secure Partition Manager co-exist in the TF-A
+codebase:
-- SPM based on the FF-A specification `[1]`_.
-- SPM based on the MM interface to communicate with an S-EL0 partition `[2]`_.
+#. S-EL2 SPMC based on the FF-A specification `[1]`_, enabling virtualization in
+ the secure world, managing multiple S-EL1 or S-EL0 partitions.
+#. EL3 SPMC based on the FF-A specification, managing a single S-EL1 partition
+ without virtualization in the secure world.
+#. EL3 SPM based on the MM specification, legacy implementation managing a
+ single S-EL0 partition `[2]`_.
-Both implementations differ in their architectures and only one can be selected
-at build time.
+These implementations differ in their respective SW architecture and only one
+can be selected at build time. This document:
-This document:
-
-- describes the FF-A implementation where the Secure Partition Manager
- resides at EL3 and S-EL2 (or EL3 and S-EL1).
+- describes the implementation from bullet 1. when the SPMC resides at S-EL2.
- is not an architecture specification and it might provide assumptions
on sections mandated as implementation-defined in the specification.
-- covers the implications to TF-A used as a bootloader, and Hafnium
- used as a reference code base for an S-EL2 secure firmware on
- platforms implementing the FEAT_SEL2 (formerly Armv8.4 Secure EL2)
- architecture extension.
+- covers the implications to TF-A used as a bootloader, and Hafnium used as a
+ reference code base for an S-EL2/SPMC secure firmware on platforms
+ implementing the FEAT_SEL2 architecture extension.
Terminology
-----------
@@ -98,20 +106,23 @@
Support for legacy platforms
----------------------------
-In the implementation, the SPM is split into SPMD and SPMC components.
-The SPMD is located at EL3 and mainly relays FF-A messages from
-NWd (Hypervisor or OS kernel) to SPMC located either at S-EL1 or S-EL2.
+The SPM is split into a dispatcher and a core component (respectively SPMD and
+SPMC) residing at different exception levels. To permit the FF-A specification
+adoption and a smooth migration, the SPMD supports an SPMC residing either at
+S-EL1 or S-EL2:
-Hence TF-A supports both cases where the SPMC is located either at:
+- The SPMD is located at EL3 and mainly relays the FF-A protocol from NWd
+ (Hypervisor or OS kernel) to the SPMC.
+- The same SPMD component is used for both S-EL1 and S-EL2 SPMC configurations.
+- The SPMC exception level is a build time choice.
-- S-EL1 supporting platforms not implementing the FEAT_SEL2 architecture
+TF-A supports both cases:
+
+- S-EL1 SPMC for platforms not supporting the FEAT_SEL2 architecture
extension. The SPMD relays the FF-A protocol from EL3 to S-EL1.
-- or S-EL2 supporting platforms implementing the FEAT_SEL2 architecture
+- S-EL2 SPMC for platforms implementing the FEAT_SEL2 architecture
extension. The SPMD relays the FF-A protocol from EL3 to S-EL2.
-The same TF-A SPMD component is used to support both configurations.
-The SPMC exception level is a build time choice.
-
Sample reference stack
======================
@@ -127,14 +138,18 @@
This section explains the TF-A build options involved in building with
support for an FF-A based SPM where the SPMD is located at EL3 and the
-SPMC located at S-EL1 or S-EL2:
+SPMC located at S-EL1, S-EL2 or EL3:
- **SPD=spmd**: this option selects the SPMD component to relay the FF-A
protocol from NWd to SWd back and forth. It is not possible to
enable another Secure Payload Dispatcher when this option is chosen.
- **SPMD_SPM_AT_SEL2**: this option adjusts the SPMC exception
- level to being S-EL1 or S-EL2. It defaults to enabled (value 1) when
+ level to being at S-EL2. It defaults to enabled (value 1) when
SPD=spmd is chosen.
+- **SPMC_AT_EL3**: this option adjusts the SPMC exception level to being
+ at EL3.
+- If neither ``SPMD_SPM_AT_SEL2`` or ``SPMC_AT_EL3`` are enabled the SPMC
+ exception level is set to S-EL1.
- **CTX_INCLUDE_EL2_REGS**: this option permits saving (resp.
restoring) the EL2 system register context before entering (resp.
after leaving) the SPMC. It is mandatorily enabled when
@@ -144,16 +159,18 @@
providing paths to SP binary images and manifests in DTS format
(see `Describing secure partitions`_). It
is required when ``SPMD_SPM_AT_SEL2`` is enabled hence when multiple
- secure partitions are to be loaded on behalf of the SPMC.
+ secure partitions are to be loaded by BL2 on behalf of the SPMC.
-+---------------+----------------------+------------------+
-| | CTX_INCLUDE_EL2_REGS | SPMD_SPM_AT_SEL2 |
-+---------------+----------------------+------------------+
-| SPMC at S-EL1 | 0 | 0 |
-+---------------+----------------------+------------------+
-| SPMC at S-EL2 | 1 | 1 (default when |
-| | | SPD=spmd) |
-+---------------+----------------------+------------------+
++---------------+----------------------+------------------+-------------+
+| | CTX_INCLUDE_EL2_REGS | SPMD_SPM_AT_SEL2 | SPMC_AT_EL3 |
++---------------+----------------------+------------------+-------------+
+| SPMC at S-EL1 | 0 | 0 | 0 |
++---------------+----------------------+------------------+-------------+
+| SPMC at S-EL2 | 1 | 1 (default when | 0 |
+| | | SPD=spmd) | |
++---------------+----------------------+------------------+-------------+
+| SPMC at EL3 | 0 | 0 | 1 |
++---------------+----------------------+------------------+-------------+
Other combinations of such build options either break the build or are not
supported.
@@ -162,9 +179,8 @@
- Only Arm's FVP platform is supported to use with the TF-A reference software
stack.
-- The reference software stack uses FEAT_PAuth (formerly Armv8.3-PAuth) and
- FEAT_BTI (formerly Armv8.5-BTI) architecture extensions by default at EL3
- and S-EL2.
+- When ``SPMD_SPM_AT_SEL2=1``, the reference software stack assumes enablement
+ of FEAT_PAuth, FEAT_BTI and FEAT_MTE architecture extensions.
- The ``CTX_INCLUDE_EL2_REGS`` option provides the generic support for
barely saving/restoring EL2 registers from an Arm arch perspective. As such
it is decoupled from the ``SPD=spmd`` option.
@@ -172,10 +188,10 @@
the Hafnium binary path (built for the secure world) or the path to a TEE
binary implementing FF-A interfaces.
- BL33 option can specify the TFTF binary or a normal world loader
- such as U-Boot or the UEFI framework.
+ such as U-Boot or the UEFI framework payload.
-Sample TF-A build command line when SPMC is located at S-EL1
-(e.g. when the FEAT_EL2 architecture extension is not implemented):
+Sample TF-A build command line when the SPMC is located at S-EL1
+(e.g. when the FEAT_SEL2 architecture extension is not implemented):
.. code:: shell
@@ -188,9 +204,8 @@
PLAT=fvp \
all fip
-Sample TF-A build command line for a FEAT_SEL2 enabled system where the SPMC is
-located at S-EL2:
-
+Sample TF-A build command line when FEAT_SEL2 architecture extension is
+implemented and the SPMC is located at S-EL2:
.. code:: shell
make \
@@ -201,13 +216,14 @@
ARM_ARCH_MINOR=5 \
BRANCH_PROTECTION=1 \
CTX_INCLUDE_PAUTH_REGS=1 \
+ CTX_INCLUDE_MTE_REGS=1 \
BL32=<path-to-hafnium-binary> \
BL33=<path-to-bl33-binary> \
SP_LAYOUT_FILE=sp_layout.json \
all fip
-Same as above with enabling secure boot in addition:
-
+Sample TF-A build command line when FEAT_SEL2 architecture extension is
+implemented, the SPMC is located at S-EL2, and enabling secure boot:
.. code:: shell
make \
@@ -218,6 +234,7 @@
ARM_ARCH_MINOR=5 \
BRANCH_PROTECTION=1 \
CTX_INCLUDE_PAUTH_REGS=1 \
+ CTX_INCLUDE_MTE_REGS=1 \
BL32=<path-to-hafnium-binary> \
BL33=<path-to-bl33-binary> \
SP_LAYOUT_FILE=sp_layout.json \
@@ -229,6 +246,20 @@
GENERATE_COT=1 \
all fip
+Sample TF-A build command line when the SPMC is located at EL3:
+
+.. code:: shell
+
+ make \
+ CROSS_COMPILE=aarch64-none-elf- \
+ SPD=spmd \
+ SPMD_SPM_AT_SEL2=0 \
+ SPMC_AT_EL3=1 \
+ BL32=<path-to-tee-binary> \
+ BL33=<path-to-bl33-binary> \
+ PLAT=fvp \
+ all fip
+
FVP model invocation
====================
@@ -250,29 +281,33 @@
| - cluster0.has_branch_target_exception=1 | Implements FEAT_BTI. |
| - cluster1.has_branch_target_exception=1 | |
+---------------------------------------------------+------------------------------------+
-| - cluster0.restriction_on_speculative_execution=2 | Required by the EL2 context |
-| - cluster1.restriction_on_speculative_execution=2 | save/restore routine. |
+| - cluster0.has_pointer_authentication=2 | Implements FEAT_PAuth |
+| - cluster1.has_pointer_authentication=2 | |
++---------------------------------------------------+------------------------------------+
+| - cluster0.memory_tagging_support_level=2 | Implements FEAT_MTE2 |
+| - cluster1.memory_tagging_support_level=2 | |
+| - bp.dram_metadata.is_enabled=1 | |
+---------------------------------------------------+------------------------------------+
Sample FVP command line invocation:
.. code:: shell
- <path-to-fvp-model>/FVP_Base_RevC-2xAEMv8A -C pctl.startup=0.0.0.0
+ <path-to-fvp-model>/FVP_Base_RevC-2xAEMvA -C pctl.startup=0.0.0.0 \
-C cluster0.NUM_CORES=4 -C cluster1.NUM_CORES=4 -C bp.secure_memory=1 \
-C bp.secureflashloader.fname=trusted-firmware-a/build/fvp/debug/bl1.bin \
-C bp.flashloader0.fname=trusted-firmware-a/build/fvp/debug/fip.bin \
-C bp.pl011_uart0.out_file=fvp-uart0.log -C bp.pl011_uart1.out_file=fvp-uart1.log \
-C bp.pl011_uart2.out_file=fvp-uart2.log \
- -C cluster0.has_arm_v8-5=1 -C cluster1.has_arm_v8-5=1 -C pci.pci_smmuv3.mmu.SMMU_AIDR=2 \
- -C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B -C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002 \
- -C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714 -C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0472 \
- -C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002 -C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0 \
- -C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0 \
- -C cluster0.has_branch_target_exception=1 \
- -C cluster1.has_branch_target_exception=1 \
- -C cluster0.restriction_on_speculative_execution=2 \
- -C cluster1.restriction_on_speculative_execution=2
+ -C cluster0.has_arm_v8-5=1 -C cluster1.has_arm_v8-5=1 \
+ -C cluster0.has_pointer_authentication=2 -C cluster1.has_pointer_authentication=2 \
+ -C cluster0.has_branch_target_exception=1 -C cluster1.has_branch_target_exception=1 \
+ -C cluster0.memory_tagging_support_level=2 -C cluster1.memory_tagging_support_level=2 \
+ -C bp.dram_metadata.is_enabled=1 \
+ -C pci.pci_smmuv3.mmu.SMMU_AIDR=2 -C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B \
+ -C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002 -C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714 \
+ -C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0472 -C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002 \
+ -C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0 -C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0
Boot process
============
@@ -338,11 +373,23 @@
A json-formatted description file is passed to the build flow specifying paths
to the SP binary image and associated DTS partition manifest file. The latter
is processed by the dtc compiler to generate a DTB fed into the SP package.
+Optionally, the partition's json description can contain offsets for both
+the image and partition manifest within the SP package. Both offsets need to be
+4KB aligned, because it is the translation granule supported by Hafnium SPMC.
+These fields can be leveraged to support SPs with S1 translation granules that
+differ from 4KB, and to configure the regions allocated within the SP package,
+as well as to comply with the requirements for the implementation of the boot
+information protocol (see `Passing boot data to the SP`_ for more details). In
+case the offsets are absent in their json node, they default to 0x1000 and
+0x4000 for the manifest offset and image offset respectively.
This file also specifies the SP owner (as an optional field) identifying the
signing domain in case of dual root CoT.
The SP owner can either be the silicon or the platform provider. The
corresponding "owner" field value can either take the value of "SiP" or "Plat".
In absence of "owner" field, it defaults to "SiP" owner.
+The UUID of the partition can be specified as a field in the description file or
+if it does not exist there the UUID is extracted from the DTS partition
+manifest.
.. code:: shell
@@ -350,14 +397,27 @@
"tee1" : {
"image": "tee1.bin",
"pm": "tee1.dts",
- "owner": "SiP"
+ "owner": "SiP",
+ "uuid": "1b1820fe-48f7-4175-8999-d51da00b7c9f"
},
"tee2" : {
"image": "tee2.bin",
"pm": "tee2.dts",
"owner": "Plat"
+ },
+
+ "tee3" : {
+ "image": {
+ "file": "tee3.bin",
+ "offset":"0x2000"
+ },
+ "pm": {
+ "file": "tee3.dts",
+ "offset":"0x6000"
+ },
+ "owner": "Plat"
- }
+ },
}
SPMC manifest
@@ -379,7 +439,7 @@
attribute {
spmc_id = <0x8000>;
maj_ver = <0x1>;
- min_ver = <0x0>;
+ min_ver = <0x1>;
exec_state = <0x0>;
load_address = <0x0 0x6000000>;
entrypoint = <0x0 0x6000000>;
@@ -398,13 +458,13 @@
SPMD (currently matches ``BL32_BASE``) to enter the SPMC.
Other nodes in the manifest are consumed by Hafnium in the secure world.
-A sample can be found at [7]:
+A sample can be found at `[7]`_:
- The *hypervisor* node describes SPs. *is_ffa_partition* boolean attribute
indicates a FF-A compliant SP. The *load_address* field specifies the load
- address at which TF-A loaded the SP package.
+ address at which BL2 loaded the SP package.
- *cpus* node provide the platform topology and allows MPIDR to VMPIDR mapping.
- Note the primary core is declared first, then secondary core are declared
+ Note the primary core is declared first, then secondary cores are declared
in reverse order.
- The *memory* node provides platform information on the ranges of memory
available to the SPMC.
@@ -436,7 +496,7 @@
Note this boot flow is an implementation sample on Arm's FVP platform.
Platforms not using TF-A's *Firmware CONFiguration* framework would adjust to a
-different implementation.
+different boot flow. The flow restricts to a maximum of 8 secure partitions.
Secure boot
~~~~~~~~~~~
@@ -451,6 +511,8 @@
- SPMC (BL32) and SPMC manifest are signed by the SiP using the S-ROTPK.
- BL33 may be signed by the OEM using NS-ROTPK.
- An SP may be signed either by SiP (using S-ROTPK) or by OEM (using NS-ROTPK).
+- A maximum of 4 partitions can be signed with the S-ROTPK key and 4 partitions
+ signed with the NS-ROTPK key.
Also refer to `Describing secure partitions`_ and `TF-A build options`_ sections.
@@ -467,20 +529,23 @@
the secure world. Such portions are isolated in architecture specific files
and/or enclosed by a ``SECURE_WORLD`` macro.
-Secure partitions CPU scheduling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Secure partitions scheduling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The FF-A v1.0 specification `[1]`_ provides two ways to relinquinsh CPU time to
+The FF-A specification `[1]`_ provides two ways to relinquinsh CPU time to
secure partitions. For this a VM (Hypervisor or OS kernel), or SP invokes one of:
- the FFA_MSG_SEND_DIRECT_REQ interface.
- the FFA_RUN interface.
+Additionally a secure interrupt can pre-empt the normal world execution and give
+CPU cycles by transitioning to EL3 and S-EL2.
+
Platform topology
~~~~~~~~~~~~~~~~~
The *execution-ctx-count* SP manifest field can take the value of one or the
-total number of PEs. The FF-A v1.0 specification `[1]`_ recommends the
+total number of PEs. The FF-A specification `[1]`_ recommends the
following SP types:
- Pinned MP SPs: an execution context matches a physical PE. MP SPs must
@@ -520,13 +585,46 @@
Passing boot data to the SP
---------------------------
+In `[1]`_ , the section "Boot information protocol" defines a method for passing
+data to the SPs at boot time. It specifies the format for the boot information
+descriptor and boot information header structures, which describe the data to be
+exchanged between SPMC and SP.
+The specification also defines the types of data that can be passed.
+The aggregate of both the boot info structures and the data itself is designated
+the boot information blob, and is passed to a Partition as a contiguous memory
+region.
+
+Currently, the SPM implementation supports the FDT type which is used to pass the
+partition's DTB manifest.
+
-In `[1]`_ , the "Protocol for passing data" section defines a method for passing
-boot data to SPs (not currently implemented).
+The region for the boot information blob is allocated through the SP package.
-Provided that the whole secure partition package image (see
-`Secure Partition packages`_) is mapped to the SP secure EL1&0 Stage-2
-translation regime, an SP can access its own manifest DTB blob and extract its
-partition manifest properties.
+.. image:: ../resources/diagrams/partition-package.png
+
+To adjust the space allocated for the boot information blob, the json description
+of the SP (see section `Describing secure partitions`_) shall be updated to contain
+the manifest offset. If no offset is provided the manifest offset defaults to 0x1000,
+which is the page size in the Hafnium SPMC.
+
+The configuration of the boot protocol is done in the SPs manifest. As defined by
+the specification, the manifest field 'gp-register-num' configures the GP register
+which shall be used to pass the address to the partitions boot information blob when
+booting the partition.
+In addition, the Hafnium SPMC implementation requires the boot information arguments
+to be listed in a designated DT node:
+
+.. code:: shell
+
+ boot-info {
+ compatible = "arm,ffa-manifest-boot-info";
+ ffa_manifest;
+ };
+
+The whole secure partition package image (see `Secure Partition packages`_) is
+mapped to the SP secure EL1&0 Stage-2 translation regime. As such, the SP can
+retrieve the address for the boot information blob in the designated GP register,
+process the boot information header and descriptors, access its own manifest
+DTB blob and extract its partition manifest properties.
SP Boot order
-------------
@@ -633,28 +731,29 @@
receiver.
There are two types of notifications supported:
+
- Global, which are targeted to a FF-A endpoint and can be handled within any of
-its execution contexts, as determined by the scheduler of the system.
+ its execution contexts, as determined by the scheduler of the system.
- Per-vCPU, which are targeted to a FF-A endpoint and to be handled within a
-a specific execution context, as determined by the sender.
+ a specific execution context, as determined by the sender.
The type of a notification is set when invoking FFA_NOTIFICATION_BIND to give
permissions to the sender.
Notification signaling resorts to two interrupts:
-- Schedule Receiver Interrupt: Non-secure physical interrupt to be handled by
-the FF-A 'transport' driver within the receiver scheduler. At initialization
-the SPMC (as suggested by the spec) configures a secure SGI, as non-secure, and
-triggers it when there are pending notifications, and the respective receivers
-need CPU cycles to handle them.
-- Notifications Pending Interrupt: Virtual Interrupt to be handled by the
-receiver of the notification. Set when there are pending notifications. For
-per-vCPU the NPI is pended at the handling of FFA_NOTIFICATION_SET interface.
-The notifications receipt support is enabled in the partition FF-A manifest.
+- Schedule Receiver Interrupt: non-secure physical interrupt to be handled by
+ the FF-A driver within the receiver scheduler. At initialization the SPMC
+ donates a SGI ID chosen from the secure SGI IDs range and configures it as
+ non-secure. The SPMC triggers this SGI on the currently running core when
+ there are pending notifications, and the respective receivers need CPU cycles
+ to handle them.
+- Notifications Pending Interrupt: virtual interrupt to be handled by the
+ receiver of the notification. Set when there are pending notifications for the
+ given secure partition. The NPI is pended when the NWd relinquishes CPU cycles
+ to an SP.
-The subsequent section provides more details about the each one of the
-FF-A interfaces for notifications support.
+The notifications receipt support is enabled in the partition FF-A manifest.
Mandatory interfaces
--------------------
@@ -677,9 +776,12 @@
- ``FFA_MEM_RETRIEVE_REQ``
- ``FFA_MEM_RETRIEVE_RESP``
- ``FFA_MEM_RELINQUISH``
+- ``FFA_MEM_FRAG_RX``
+- ``FFA_MEM_FRAG_TX``
- ``FFA_MEM_RECLAIM``
+- ``FFA_RUN``
-As part of the support of FF-A v1.1, the following interfaces were added:
+As part of the FF-A v1.1 support, the following interfaces were added:
- ``FFA_NOTIFICATION_BITMAP_CREATE``
- ``FFA_NOTIFICATION_BITMAP_DESTROY``
@@ -690,6 +792,8 @@
- ``FFA_NOTIFICATION_INFO_GET``
- ``FFA_SPM_ID_GET``
- ``FFA_SECONDARY_EP_REGISTER``
+ - ``FFA_MEM_PERM_GET``
+ - ``FFA_MEM_PERM_SET``
FFA_VERSION
~~~~~~~~~~~
@@ -817,24 +921,21 @@
FFA_NOTIFICATION_SET/FFA_NOTIFICATION_GET
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If the notifications set are per-vCPU, the NPI interrupt is set as pending
-for a given receiver partition.
+FFA_NOTIFICATION_GET retrieves all pending global notifications and
+per-vCPU notifications targeted to the current vCPU.
-The FFA_NOTIFICATION_GET will retrieve all pending global notifications and all
-pending per-vCPU notifications targeted to the current vCPU.
-
-Hafnium keeps the global counting of the pending notifications, which is
-incremented and decremented at the handling of FFA_NOTIFICATION_SET and
-FFA_NOTIFICATION_GET, respectively. If the counter reaches zero, prior to SPMC
-triggering the SRI, it won't be triggered.
+Hafnium maintains a global count of pending notifications which gets incremented
+and decremented when handling FFA_NOTIFICATION_SET and FFA_NOTIFICATION_GET
+respectively. A delayed SRI is triggered if the counter is non-zero when the
+SPMC returns to normal world.
FFA_NOTIFICATION_INFO_GET
~~~~~~~~~~~~~~~~~~~~~~~~~
-Hafnium keeps the global counting of pending notifications whose info has been
-retrieved by this interface. The counting is incremented and decremented at the
-handling of FFA_NOTIFICATION_INFO_GET and FFA_NOTIFICATION_GET, respectively.
-It also tracks the notifications whose info has been retrieved individually,
+Hafnium maintains a global count of pending notifications whose information
+has been retrieved by this interface. The count is incremented and decremented
+when handling FFA_NOTIFICATION_INFO_GET and FFA_NOTIFICATION_GET respectively.
+It also tracks notifications whose information has been retrieved individually,
such that it avoids duplicating returned information for subsequent calls to
FFA_NOTIFICATION_INFO_GET. For each notification, this state information is
reset when receiver called FFA_NOTIFICATION_GET to retrieve them.
@@ -842,18 +943,18 @@
FFA_SPM_ID_GET
~~~~~~~~~~~~~~
-Returns the FF-A ID allocated to the SPM component (which includes SPMC + SPMD).
-At initialization, the SPMC queries the SPMD for the SPM ID, using this
-same interface, and saves it.
+Returns the FF-A ID allocated to an SPM component which can be one of SPMD
+or SPMC.
-The call emitted at NS and secure physical FF-A instances returns the SPM ID
-specified in the SPMC manifest.
+At initialization, the SPMC queries the SPMD for the SPMC ID, using the
+FFA_ID_GET interface, and records it. The SPMC can also query the SPMD ID using
+the FFA_SPM_ID_GET interface at the secure physical FF-A instance.
-Secure partitions call this interface at the virtual instance, to which the SPMC
-shall return the priorly retrieved SPM ID.
+Secure partitions call this interface at the virtual FF-A instance, to which
+the SPMC returns the priorly retrieved SPMC ID.
-The Hypervisor or OS kernel can issue an FFA_SPM_ID_GET call handled by the
-SPMD, which returns the SPM ID.
+The Hypervisor or OS kernel can issue the FFA_SPM_ID_GET call handled by the
+SPMD, which returns the SPMC ID.
FFA_SECONDARY_EP_REGISTER
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -861,7 +962,7 @@
When the SPMC boots, all secure partitions are initialized on their primary
Execution Context.
-The interface FFA_SECONDARY_EP_REGISTER is to be used by a secure partitions
+The FFA_SECONDARY_EP_REGISTER interface is to be used by a secure partition
from its first execution context, to provide the entry point address for
secondary execution contexts.
@@ -878,26 +979,35 @@
- SPMC to SPMD direct request/response uses SMC conduit.
- SPMD to SPMC direct request/response uses ERET conduit.
+This is used in particular to convey power management messages.
+
PE MMU configuration
--------------------
-With secure virtualization enabled, two IPA spaces are output from the secure
-EL1&0 Stage-1 translation (secure and non-secure). The EL1&0 Stage-2 translation
-hardware is fed by:
+With secure virtualization enabled (``HCR_EL2.VM = 1``) and for S-EL1
+partitions, two IPA spaces (secure and non-secure) are output from the
+secure EL1&0 Stage-1 translation.
+The EL1&0 Stage-2 translation hardware is fed by:
-- A single secure IPA space when the SP EL1&0 Stage-1 MMU is disabled.
-- Two IPA spaces (secure and non-secure) when the SP EL1&0 Stage-1 MMU is
- enabled.
+- A secure IPA when the SP EL1&0 Stage-1 MMU is disabled.
+- One of secure or non-secure IPA when the secure EL1&0 Stage-1 MMU is enabled.
``VTCR_EL2`` and ``VSTCR_EL2`` provide configuration bits for controlling the
-NS/S IPA translations.
-``VSTCR_EL2.SW`` = 0, ``VSTCR_EL2.SA`` = 0,``VTCR_EL2.NSW`` = 0, ``VTCR_EL2.NSA`` = 1:
+NS/S IPA translations. The following controls are set up:
+``VSTCR_EL2.SW = 0`` , ``VSTCR_EL2.SA = 0``, ``VTCR_EL2.NSW = 0``,
+``VTCR_EL2.NSA = 1``:
- Stage-2 translations for the NS IPA space access the NS PA space.
- Stage-2 translation table walks for the NS IPA space are to the secure PA space.
-Secure and non-secure IPA regions use the same set of Stage-2 page tables within
-a SP.
+Secure and non-secure IPA regions (rooted to by ``VTTBR_EL2`` and ``VSTTBR_EL2``)
+use the same set of Stage-2 page tables within a SP.
+
+The ``VTCR_EL2/VSTCR_EL2/VTTBR_EL2/VSTTBR_EL2`` virtual address space
+configuration is made part of a vCPU context.
+
+For S-EL0 partitions with VHE enabled, a single secure EL2&0 Stage-1 translation
+regime is used for both Hafnium and the partition.
Interrupt management
--------------------
@@ -1094,16 +1204,46 @@
(svc_off) hooks are registered.
- The behavior for the cpu on event is described in `Secondary cores boot-up`_.
The SPMC is entered through its secondary physical core entry point.
-- The cpu off event occurs when the NWd calls PSCI_CPU_OFF. The method by which
- the PM event is conveyed to the SPMC is implementation-defined in context of
- FF-A v1.0 (`SPMC-SPMD direct requests/responses`_). It consists in a SPMD-to-SPMC
- direct request/response conveying the PM event details and SPMC response.
+- The cpu off event occurs when the NWd calls PSCI_CPU_OFF. The PM event is
+ signaled to the SPMC through a power management framework message.
+ It consists in a SPMD-to-SPMC direct request/response (`SPMC-SPMD direct
+ requests/responses`_) conveying the event details and SPMC response.
The SPMD performs a synchronous entry into the SPMC. The SPMC is entered and
updates its internal state to reflect the physical core is being turned off.
In the current implementation no SP is resumed as a consequence. This behavior
ensures a minimal support for CPU hotplug e.g. when initiated by the NWd linux
userspace.
+Arm architecture extensions for security hardening
+==================================================
+
+Hafnium supports the following architecture extensions for security hardening:
+
+- Pointer authentication (FEAT_PAuth): the extension permits detection of forged
+ pointers used by ROP type of attacks through the signing of the pointer
+ value. Hafnium is built with the compiler branch protection option to permit
+ generation of a pointer authentication code for return addresses (pointer
+ authentication for instructions). The APIA key is used while Hafnium runs.
+ A random key is generated at boot time and restored upon entry into Hafnium
+ at run-time. APIA and other keys (APIB, APDA, APDB, APGA) are saved/restored
+ in vCPU contexts permitting to enable pointer authentication in VMs/SPs.
+- Branch Target Identification (FEAT_BTI): the extension permits detection of
+ unexpected indirect branches used by JOP type of attacks. Hafnium is built
+ with the compiler branch protection option, inserting land pads at function
+ prologues that are reached by indirect branch instructions (BR/BLR).
+ Hafnium code pages are marked as guarded in the EL2 Stage-1 MMU descriptors
+ such that an indirect branch must always target a landpad. A fault is
+ triggered otherwise. VMs/SPs can (independently) mark their code pages as
+ guarded in the EL1&0 Stage-1 translation regime.
+- Memory Tagging Extension (FEAT_MTE): the option permits detection of out of
+ bound memory array accesses or re-use of an already freed memory region.
+ Hafnium enables the compiler option permitting to leverage MTE stack tagging
+ applied to core stacks. Core stacks are marked as normal tagged memory in the
+ EL2 Stage-1 translation regime. A synchronous data abort is generated upon tag
+ check failure on load/stores. A random seed is generated at boot time and
+ restored upon entry into Hafnium. MTE system registers are saved/restored in
+ vCPU contexts permitting MTE usage from VMs/SPs.
+
SMMUv3 support in Hafnium
=========================
@@ -1213,7 +1353,7 @@
- No support for independent peripheral devices.
S-EL0 Partition support
-=========================
+=======================
The SPMC (Hafnium) has limited capability to run S-EL0 FF-A partitions using
FEAT_VHE (mandatory with ARMv8.1 in non-secure state, and in secure world
with ARMv8.4 and FEAT_SEL2).
@@ -1276,7 +1416,7 @@
.. _[8]:
-[8] https://lists.trustedfirmware.org/pipermail/tf-a/2020-February/000296.html
+[8] https://lists.trustedfirmware.org/archives/list/tf-a@lists.trustedfirmware.org/thread/CFQFGU6H2D5GZYMUYGTGUSXIU3OYZP6U/
.. _[9]:
@@ -1284,4 +1424,4 @@
--------------
-*Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index b7d1168..3477a04 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -270,6 +270,9 @@
- ``ERRATA_A77_1791578``: This applies errata 1791578 workaround to Cortex-A77
CPU. This needs to be enabled for r0p0, r1p0, and r1p1, it is still open.
+- ``ERRATA_A77_2356587``: This applies errata 2356587 workaround to Cortex-A77
+ CPU. This needs to be enabled for r0p0, r1p0, and r1p1, it is still open.
+
For Cortex-A78, the following errata build flags are defined :
- ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78
@@ -296,15 +299,60 @@
CPU. This needs to be enabled for revisions r1p0, r1p1, and r1p2. The issue
is present in r0p0 but there is no workaround. It is still open.
+- ``ERRATA_A78_2376745``: This applies errata 2376745 workaround to Cortex-A78
+ CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
+ it is still open.
+
+- ``ERRATA_A78_2395406``: This applies errata 2395406 workaround to Cortex-A78
+ CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
+ it is still open.
+
For Cortex-A78 AE, the following errata build flags are defined :
+- ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to
+ Cortex-A78 AE CPU. This needs to be enabled for revisions r0p0 and r0p1.
+ This erratum is still open.
+
+- ``ERRATA_A78_AE_1951502`` : This applies errata 1951502 workaround to
+ Cortex-A78 AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This
+ erratum is still open.
+
+- ``ERRATA_A78_AE_2376748`` : This applies errata 2376748 workaround to
+ Cortex-A78 AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This
+ erratum is still open.
+
+- ``ERRATA_A78_AE_2395408`` : This applies errata 2395408 workaround to
+ Cortex-A78 AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This
+ erratum is still open.
+
+For Cortex-A78C, the following errata build flags are defined :
+
-- ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to Cortex-A78
- AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This erratum is
- still open.
+- ``ERRATA_A78C_2132064`` : This applies errata 2132064 workaround to
+ Cortex-A78C CPU. This needs to be enabled for revisions r0p1, r0p2 and
+ it is still open.
-- ``ERRATA_A78_AE_1951502`` : This applies errata 1951502 workaround to Cortex-A78
- AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This erratum is
- still open.
+- ``ERRATA_A78C_2242638`` : This applies errata 2242638 workaround to
+ Cortex-A78C CPU. This needs to be enabled for revisions r0p1, r0p2 and
+ it is still open.
+
+- ``ERRATA_A78C_2376749`` : This applies errata 2376749 workaround to
+ Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
+ erratum is still open.
+
+- ``ERRATA_A78C_2395411`` : This applies errata 2395411 workaround to
+ Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
+ erratum is still open.
+
+For Cortex-X1 CPU, the following errata build flags are defined:
+
+- ``ERRATA_X1_1821534`` : This applies errata 1821534 workaround to Cortex-X1
+ CPU. This needs to be enabled only for revision <= r1p0 of the CPU.
+
+- ``ERRATA_X1_1688305`` : This applies errata 1688305 workaround to Cortex-X1
+ CPU. This needs to be enabled only for revision <= r1p0 of the CPU.
+
+- ``ERRATA_X1_1827429`` : This applies errata 1827429 workaround to Cortex-X1
+ CPU. This needs to be enabled only for revision <= r1p0 of the CPU.
For Neoverse N1, the following errata build flags are defined :
@@ -350,6 +398,10 @@
For Neoverse V1, the following errata build flags are defined :
+- ``ERRATA_V1_1618635``: This applies errata 1618635 workaround to Neoverse-V1
+ CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
+ r1p0.
+
- ``ERRATA_V1_1774420``: This applies errata 1774420 workaround to Neoverse-V1
CPU. This needs to be enabled only for revisions r0p0 and r1p0, it is fixed
in r1p1.
@@ -387,6 +439,13 @@
issue is present in r0p0 as well but there is no workaround for that
revision. It is still open.
+- ``ERRATA_V1_2294912``: This applies errata 2294912 workaround to Neoverse-V1
+ CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU.
+
+- ``ERRATA_V1_2372203``: This applies errata 2372203 workaround to Neoverse-V1
+ CPU. This needs to be enabled for revisions r0p0, r1p0 and r1p1 of the CPU.
+ It is still open.
+
For Cortex-A710, the following errata build flags are defined :
- ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -421,10 +480,26 @@
Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
of the CPU and is fixed in r2p1.
+- ``ERRATA_A710_2147715``: This applies errata 2147715 workaround to
+ Cortex-A710 CPU. This needs to be enabled for revision r2p0 of the CPU
+ and is fixed in r2p1.
+
+- ``ERRATA_A710_2216384``: This applies errata 2216384 workaround to
+ Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
+ of the CPU and is fixed in r2p1.
+
- ``ERRATA_A710_2282622``: This applies errata 2282622 workaround to
Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
of the CPU and is fixed in r2p1.
+- ``ERRATA_A710_2008768``: This applies errata 2008768 workaround to
+ Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
+ of the CPU and is fixed in r2p1.
+
+- ``ERRATA_A710_2371105``: This applies errata 2371105 workaround to
+ Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
+ of the CPU and is fixed in r2p1.
+
For Neoverse N2, the following errata build flags are defined :
- ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
@@ -457,6 +532,14 @@
- ``ERRATA_N2_2280757``: This applies errata 2280757 workaround to Neoverse-N2
CPU. This needs to be enabled for revision r0p0 of the CPU and is still open.
+- ``ERRATA_N2_2376738``: This applies errata 2376738 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
+ r0p1.
+
+- ``ERRATA_N2_2388450``: This applies errata 2388450 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
+ r0p1.
+
For Cortex-X2, the following errata build flags are defined :
- ``ERRATA_X2_2002765``: This applies errata 2002765 workaround to Cortex-X2
@@ -482,6 +565,14 @@
Cortex-X2 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
r2p0 of the CPU, it is fixed in r2p1.
+- ``ERRATA_X2_2147715``: This applies errata 2147715 workaround to
+ Cortex-X2 CPU. This needs to be enabled only for revision r2p0 of the CPU,
+ it is fixed in r2p1.
+
+- ``ERRATA_X2_2371105``: This applies errata 2371105 workaround to
+ Cortex-X2 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
+ of the CPU and is fixed in r2p1.
+
For Cortex-A510, the following errata build flags are defined :
- ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
@@ -514,6 +605,14 @@
Cortex-A510 CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2,
r0p3 and r1p0, it is fixed in r1p1.
+- ``ERRATA_A510_2347730``: This applies errata 2347730 workaround to
+ Cortex-A510 CPU. This needs to be enabled for revisions r0p0, r0p1, r0p2,
+ r0p3, r1p0 and r1p1. It is fixed in r1p2.
+
+- ``ERRATA_A510_2371937``: This applies errata 2371937 workaround to
+ Cortex-A510 CPU. This needs to applied for revisions r0p0, r0p1, r0p2,
+ r0p3, r1p0, r1p1, and is fixed in r1p2.
+
DSU Errata Workarounds
----------------------
@@ -541,6 +640,12 @@
r2p0 it is fixed). However, please note that this workaround results in
increased DSU power consumption on idle.
+- ``ERRATA_DSU_2313941``: This applies errata 2313941 workaround for the
+ affected DSU configurations. This errata applies for those DSUs with
+ revisions r0p0, r1p0, r2p0, r2p1, r3p0, r3p1 and is still open. However,
+ please note that this workaround results in increased DSU power consumption
+ on idle.
+
CPU Specific optimizations
--------------------------
@@ -583,9 +688,17 @@
This is used to control how the LL_CACHE* PMU events count.
Default value is 0 (Disabled).
+GIC Errata Workarounds
+----------------------
+- ``GIC600_ERRATA_WA_2384374``: This flag applies part 2 of errata 2384374
+ workaround for the affected GIC600 and GIC600-AE implementations. It applies
+ to implementations of GIC600 and GIC600-AE with revisions less than or equal
+ to r1p6 and r0p2 respectively. If the platform sets GICV3_SUPPORT_GIC600,
+ then this flag is enabled; otherwise, it is 0 (Disabled).
+
--------------
-*Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.*
.. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
.. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 0831dc0..71fdfcb 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -131,6 +131,9 @@
- For other BL3x images, if the firmware configuration file is loaded by
BL2, then its address is passed in ``arg0`` and if HW_CONFIG is loaded
then its address is passed in ``arg1``.
+ - In case of the Arm FVP platform, FW_CONFIG address passed in ``arg1`` to
+ BL31/SP_MIN, and the SOC_FW_CONFIG and HW_CONFIG details are retrieved
+ from FW_CONFIG device tree.
BL1
~~~
@@ -1757,12 +1760,20 @@
DRAM
0xffffffff +----------+
: :
- |----------|
+ 0x82100000 |----------|
|HW_CONFIG |
- 0x83000000 |----------| (non-secure)
+ 0x82000000 |----------| (non-secure)
| |
0x80000000 +----------+
+ Trusted DRAM
+ 0x08000000 +----------+
+ |HW_CONFIG |
+ 0x07f00000 |----------|
+ : :
+ | |
+ 0x06000000 +----------+
+
Trusted SRAM
0x04040000 +----------+ loaded by BL2 +----------------+
| BL1 (rw) | <<<<<<<<<<<<< | |
@@ -1790,15 +1801,18 @@
DRAM
0xffffffff +--------------+
: :
- |--------------|
+ 0x82100000 |--------------|
| HW_CONFIG |
- 0x83000000 |--------------| (non-secure)
+ 0x82000000 |--------------| (non-secure)
| |
0x80000000 +--------------+
- Trusted DRAM
+ Trusted DRAM
0x08000000 +--------------+
- | BL32 |
+ | HW_CONFIG |
+ 0x07f00000 |--------------|
+ : :
+ | BL32 |
0x06000000 +--------------+
Trusted SRAM
@@ -1829,12 +1843,20 @@
| BL32 | (secure)
0xff000000 +----------+
| |
- |----------|
+ 0x82100000 |----------|
|HW_CONFIG |
- 0x83000000 |----------| (non-secure)
+ 0x82000000 |----------| (non-secure)
| |
0x80000000 +----------+
+ Trusted DRAM
+ 0x08000000 +----------+
+ |HW_CONFIG |
+ 0x7f000000 |----------|
+ : :
+ | |
+ 0x06000000 +----------+
+
Trusted SRAM
0x04040000 +----------+ loaded by BL2 +----------------+
| BL1 (rw) | <<<<<<<<<<<<< | |
@@ -2729,7 +2751,7 @@
--------------
-*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.*
.. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
.. _SMCCC: https://developer.arm.com/docs/den0028/latest
diff --git a/docs/design/reset-design.rst b/docs/design/reset-design.rst
index 7b10c95..666ee4f 100644
--- a/docs/design/reset-design.rst
+++ b/docs/design/reset-design.rst
@@ -141,19 +141,26 @@
Platform initialization
~~~~~~~~~~~~~~~~~~~~~~~
-In this configuration, when the CPU resets to BL31 there are no parameters that
-can be passed in registers by previous boot stages. Instead, the platform code
-in BL31 needs to know, or be able to determine, the location of the BL32 (if
-required) and BL33 images and provide this information in response to the
+In this configuration, when the CPU resets to BL31 there should be no parameters
+that can be passed in registers by previous boot stages. Instead, the platform
+code in BL31 needs to know, or be able to determine, the location of the BL32
+(if required) and BL33 images and provide this information in response to the
``bl31_plat_get_next_image_ep_info()`` function.
+.. note::
+ Some platforms that configure ``RESET_TO_BL31`` might still be able to
+ receive parameters in registers depending on their actual boot sequence. On
+ those occasions, and in addition to ``RESET_TO_BL31``, these platforms should
+ set ``RESET_TO_BL31_WITH_PARAMS`` to avoid the input registers from being
+ zeroed before entering BL31.
+
Additionally, platform software is responsible for carrying out any security
initialisation, for example programming a TrustZone address space controller.
This might be done by the Trusted Boot Firmware or by platform code in BL31.
--------------
-*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.*
.. |Default reset code flow| image:: ../resources/diagrams/default_reset_code.png
.. |Reset code flow with programmable reset address| image:: ../resources/diagrams/reset_code_no_boot_type_check.png
diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst
index dd61b61..c3f3a2f 100644
--- a/docs/design/trusted-board-boot-build.rst
+++ b/docs/design/trusted-board-boot-build.rst
@@ -35,6 +35,13 @@
By default, this will use the Chain of Trust described in the TBBR-client
document. To select a different one, use the ``COT`` build option.
+ If using a custom build of OpenSSL, set the ``OPENSSL_DIR`` variable
+ accordingly so it points at the OpenSSL installation path, as explained in
+ :ref:`Build Options`. In addition, set the ``LD_LIBRARY_PATH`` variable
+ when running to point at the custom OpenSSL path, so the OpenSSL libraries
+ are loaded from that path instead of the default OS path. Export this
+ variable if necessary.
+
In the case of Arm platforms, the location of the ROTPK hash must also be
specified at build time. The following locations are currently supported (see
``ARM_ROTPK_LOCATION`` build option):
@@ -63,7 +70,7 @@
make PLAT=<platform> TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 \
ARM_ROTPK_LOCATION=devel_rsa \
ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
- BL33=<path-to>/<bl33_image> \
+ BL33=<path-to>/<bl33_image> OPENSSL_DIR=<path-to>/<openssl> \
all fip
The result of this build will be the bl1.bin and the fip.bin binaries. This
@@ -87,7 +94,7 @@
make PLAT=juno TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 \
ARM_ROTPK_LOCATION=devel_rsa \
ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
- BL33=<path-to>/<bl33_image> \
+ BL33=<path-to>/<bl33_image> OPENSSL_DIR=<path-to>/<openssl> \
SCP_BL2=<path-to>/<scp_bl2_image> \
SCP_BL2U=<path-to>/<scp_bl2u_image> \
NS_BL2U=<path-to>/<ns_bl2u_image> \
@@ -109,7 +116,7 @@
--------------
-*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
.. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git
.. _mbed TLS Security Center: https://tls.mbed.org/security
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index a34bb3c..cca76c6 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -174,14 +174,23 @@
registers to be included when saving and restoring the CPU context. Default
is 0.
-- ``CTX_INCLUDE_NEVE_REGS``: Boolean option that, when set to 1, will cause the
- Armv8.4-NV registers to be saved/restored when entering/exiting an EL2
- execution context. Default value is 0.
+- ``CTX_INCLUDE_MTE_REGS``: Numeric value to include Memory Tagging Extension
+ registers in cpu context. This must be enabled, if the platform wants to use
+ this feature in the Secure world and MTE is enabled at ELX. This flag can
+ take values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
+ Default value is 0.
-- ``CTX_INCLUDE_PAUTH_REGS``: Boolean option that, when set to 1, enables
- Pointer Authentication for Secure world. This will cause the ARMv8.3-PAuth
- registers to be included when saving and restoring the CPU context as
- part of world switch. Default value is 0.
+- ``CTX_INCLUDE_NEVE_REGS``: Numeric value, when set will cause the Armv8.4-NV
+ registers to be saved/restored when entering/exiting an EL2 execution
+ context. This flag can take values 0 to 2, to align with the
+ ``FEATURE_DETECTION`` mechanism. Default value is 0.
+
+- ``CTX_INCLUDE_PAUTH_REGS``: Numeric value to enable the Pointer
+ Authentication for Secure world. This will cause the ARMv8.3-PAuth registers
+ to be included when saving and restoring the CPU context as part of world
+ switch. This flag can take values 0 to 2, to align with ``FEATURE_DETECTION``
+ mechanism. Default value is 0.
+
Note that Pointer Authentication is enabled for Non-secure world irrespective
of the value of this flag if the CPU supports it.
@@ -246,42 +255,115 @@
builds, but this behaviour can be overridden in each platform's Makefile or
in the build command line.
-- ``ENABLE_FEAT_AMUv1``: Boolean option to enable access to the HAFGRTR_EL2
+- ``ENABLE_FEAT_AMUv1``: Numeric value to enable access to the HAFGRTR_EL2
(Hypervisor Activity Monitors Fine-Grained Read Trap Register) during EL2
- to EL3 context save/restore operations. It is an optional feature available
- on v8.4 and onwards and must be set to 1 alongside ``ENABLE_FEAT_FGT``, to
- access the HAFGRTR_EL2 register. Defaults to ``0``.
+ to EL3 context save/restore operations. This flag can take the values 0 to 2,
+ to align with the ``FEATURE_DETECTION`` mechanism. It is an optional feature
+ available on v8.4 and onwards and must be set to either 1 or 2 alongside
+ ``ENABLE_FEAT_FGT``, to access the HAFGRTR_EL2 register.
+ Default value is ``0``.
+
+- ``ENABLE_FEAT_AMUv1p1``: Numeric value to enable the ``FEAT_AMUv1p1``
+ extension. ``FEAT_AMUv1p1`` is an optional feature available on Arm v8.6
+ onwards. This flag can take the values 0 to 2, to align with the
+ ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
-- ``ENABLE_FEAT_ECV``: Boolean option to enable support for the Enhanced Counter
+- ``ENABLE_FEAT_CSV2_2``: Numeric value to enable the ``FEAT_CSV2_2``
+ extension. It allows access to the SCXTNUM_EL2 (Software Context Number)
+ register during EL2 context save/restore operations. ``FEAT_CSV2_2`` is an
+ optional feature available on Arm v8.0 onwards. This flag can take values
+ 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
+ Default value is ``0``.
+
+- ``ENABLE_FEAT_DIT``: Numeric value to enable ``FEAT_DIT`` (Data Independent
+ Timing) extension. It allows setting the ``DIT`` bit of PSTATE in EL3.
+ ``FEAT_DIT`` is a mandatory architectural feature and is enabled from v8.4
+ and upwards. This flag can take the values 0 to 2, to align with the
+ ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
+
+- ``ENABLE_FEAT_ECV``: Numeric value to enable support for the Enhanced Counter
Virtualization feature, allowing for access to the CNTPOFF_EL2 (Counter-timer
Physical Offset register) during EL2 to EL3 context save/restore operations.
- Its a mandatory architectural feature in Armv8.6 and defaults to ``1`` for
- v8.6 or later CPUs.
+ Its a mandatory architectural feature and is enabled from v8.6 and upwards.
+ This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+ mechanism. Default value is ``0``.
-- ``ENABLE_FEAT_FGT``: Boolean option to enable support for FGT (Fine Grain Traps)
+- ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps)
feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained
- Read Trap Register) during EL2 to EL3 context save/restore operations.
- Its a mandatory architectural feature in Armv8.6 and defaults to ``1`` for
- v8.6 or later CPUs.
+ Read Trap Register) during EL2 to EL3 context save/restore operations.
+ Its a mandatory architectural feature and is enabled from v8.6 and upwards.
+ This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+ mechanism. Default value is ``0``.
+
+- ``ENABLE_FEAT_HCX``: Numeric value to set the bit SCR_EL3.HXEn in EL3 to
+ allow access to HCRX_EL2 (extended hypervisor control register) from EL2 as
+ well as adding HCRX_EL2 to the EL2 context save/restore operations. Its a
+ mandatory architectural feature and is enabled from v8.7 and upwards. This
+ flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+ mechanism. Default value is ``0``.
+
+- ``ENABLE_FEAT_PAN``: Numeric value to enable the ``FEAT_PAN`` (Privileged
+ Access Never) extension. ``FEAT_PAN`` adds a bit to PSTATE, generating a
+ permission fault for any privileged data access from EL1/EL2 to virtual
+ memory address, accessible at EL0, provided (HCR_EL2.E2H=1). It is a
+ mandatory architectural feature and is enabled from v8.1 and upwards. This
+ flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
+ mechanism. Default value is ``0``.
+
+- ``ENABLE_FEAT_RNG``: Numeric value to enable the ``FEAT_RNG`` extension.
+ ``FEAT_RNG`` is an optional feature available on Arm v8.5 onwards. This
+ flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+ mechanism. Default value is ``0``.
+
+- ``ENABLE_FEAT_RNG_TRAP``: Numeric value to enable the ``FEAT_RNG_TRAP``
+ extension. This feature is only supported in AArch64 state. This flag can
+ take values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
+ Default value is ``0``. ``FEAT_RNG_TRAP`` is an optional feature from
+ Armv8.5 onwards.
-- ``ENABLE_FEAT_HCX``: This option sets the bit SCR_EL3.HXEn in EL3 to allow
- access to HCRX_EL2 (extended hypervisor control register) from EL2 as well as
- adding HCRX_EL2 to the EL2 context save/restore operations.
+- ``ENABLE_FEAT_SB``: Numeric value to enable the ``FEAT_SB`` (Speculation
+ Barrier) extension allowing access to ``sb`` instruction. ``FEAT_SB`` is an
+ optional feature and defaults to ``0`` for pre-Armv8.5 CPUs but are mandatory
+ for Armv8.5 or later CPUs. This flag can take values 0 to 2, to align with
+ ``FEATURE_DETECTION`` mechanism. It is enabled from v8.5 and upwards and if
+ needed could be overidden from platforms explicitly. Default value is ``0``.
+
+- ``ENABLE_FEAT_SEL2``: Numeric value to enable the ``FEAT_SEL2`` (Secure EL2)
+ extension. ``FEAT_SEL2`` is a mandatory feature available on Arm v8.4.
+ This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
+ mechanism. Default is ``0``.
+
+- ``ENABLE_FEAT_TWED``: Numeric value to enable the ``FEAT_TWED`` (Delayed
+ trapping of WFE Instruction) extension. ``FEAT_TWED`` is a optional feature
+ available on Arm v8.6. This flag can take values 0 to 2, to align with the
+ ``FEATURE_DETECTION`` mechanism. Default is ``0``.
+
+ When ``ENABLE_FEAT_TWED`` is set to ``1``, WFE instruction trapping gets
+ delayed by the amount of value in ``TWED_DELAY``.
+
+- ``ENABLE_FEAT_VHE``: Numeric value to enable the ``FEAT_VHE`` (Virtualization
+ Host Extensions) extension. It allows access to CONTEXTIDR_EL2 register
+ during EL2 context save/restore operations.``FEAT_VHE`` is a mandatory
+ architectural feature and is enabled from v8.1 and upwards. It can take
+ values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
+ Default value is ``0``.
- ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
support in GCC for TF-A. This option is currently only supported for
AArch64. Default is 0.
-- ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM
+- ``ENABLE_MPAM_FOR_LOWER_ELS``: Numeric value to enable lower ELs to use MPAM
feature. MPAM is an optional Armv8.4 extension that enables various memory
system components and resources to define partitions; software running at
various ELs can assign themselves to desired partition to control their
performance aspects.
- When this option is set to ``1``, EL3 allows lower ELs to access their own
- MPAM registers without trapping into EL3. This option doesn't make use of
- partitioning in EL3, however. Platform initialisation code should configure
- and use partitions in EL3 as required. This option defaults to ``0``.
+ This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
+ mechanism. When this option is set to ``1`` or ``2``, EL3 allows lower ELs to
+ access their own MPAM registers without trapping into EL3. This option
+ doesn't make use of partitioning in EL3, however. Platform initialisation
+ code should configure and use partitions in EL3 as required. This option
+ defaults to ``0``.
- ``ENABLE_MPMM``: Boolean option to enable support for the Maximum Power
Mitigation Mechanism supported by certain Arm cores, which allows the SoC
@@ -307,9 +389,10 @@
be enabled. If ``ENABLE_PMF`` is set, the residency statistics are tracked in
software.
-- ``ENABLE_RME``: Boolean option to enable support for the ARMv9 Realm
- Management Extension. Default value is 0. This is currently an experimental
- feature.
+- ``ENABLE_RME``: Numeric value to enable support for the ARMv9 Realm
+ Management Extension. This flag can take the values 0 to 2, to align with
+ the ``FEATURE_DETECTION`` mechanism. Default value is 0. This is currently
+ an experimental feature.
- ``ENABLE_RUNTIME_INSTRUMENTATION``: Boolean option to enable runtime
instrumentation which injects timestamp collection points into TF-A to
@@ -352,8 +435,8 @@
- ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world.
SVE is an optional architectural feature for AArch64. Note that this option
- requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it is
- automatically disabled when the target architecture is AArch32.
+ requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it
+ is automatically disabled when the target architecture is AArch32.
- ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
checks in GCC. Allowed values are "all", "strong", "default" and "none". The
@@ -384,8 +467,11 @@
- ``EL3_EXCEPTION_HANDLING``: When set to ``1``, enable handling of exceptions
targeted at EL3. When set ``0`` (default), no exceptions are expected or
- handled at EL3, and a panic will result. This is supported only for AArch64
- builds.
+ handled at EL3, and a panic will result. The exception to this rule is when
+ ``SPMD_SPM_AT_SEL2`` is set to ``1``, in which case, only exceptions
+ occuring during normal world execution, are trapped to EL3. Any exception
+ trapped during secure world execution are trapped to the SPMC. This is
+ supported only for AArch64 builds.
- ``EVENT_LOG_LEVEL``: Chooses the log level to use for Measured Boot when
``MEASURED_BOOT`` is enabled. For a list of valid values, see ``LOG_LEVEL``.
@@ -399,6 +485,43 @@
This feature is intended for testing purposes only, and is advisable to keep
disabled for production images.
+- ``FEATURE_DETECTION``: Boolean option to enable the architectural features
+ detection mechanism. It detects whether the Architectural features enabled
+ through feature specific build flags are supported by the PE or not by
+ validating them either at boot phase or at runtime based on the value
+ possessed by the feature flag (0 to 2) and report error messages at an early
+ stage.
+
+ This prevents and benefits us from EL3 runtime exceptions during context save
+ and restore routines guarded by these build flags. Henceforth validating them
+ before their usage provides more control on the actions taken under them.
+
+ The mechanism permits the build flags to take values 0, 1 or 2 and
+ evaluates them accordingly.
+
+ Lets consider ``ENABLE_FEAT_HCX``, build flag for ``FEAT_HCX`` as an example:
+
+ ::
+
+ ENABLE_FEAT_HCX = 0: Feature disabled statically at compile time.
+ ENABLE_FEAT_HCX = 1: Feature Enabled and the flag is validated at boottime.
+ ENABLE_FEAT_HCX = 2: Feature Enabled and the flag is validated at runtime.
+
+ In the above example, if the feature build flag, ``ENABLE_FEAT_HCX`` set to
+ 0, feature is disabled statically during compilation. If it is defined as 1,
+ feature is validated, wherein FEAT_HCX is detected at boot time. In case not
+ implemented by the PE, a hard panic is generated. Finally, if the flag is set
+ to 2, feature is validated at runtime.
+
+ Note that the entire implementation is divided into two phases, wherein as
+ as part of phase-1 we are supporting the values 0,1. Value 2 is currently not
+ supported and is planned to be handled explicilty in phase-2 implementation.
+
+ FEATURE_DETECTION macro is disabled by default, and is currently an
+ experimental procedure. Platforms can explicitly make use of this by
+ mechanism, by enabling it to validate whether they have set their build flags
+ properly at an early phase.
+
- ``FIP_NAME``: This is an optional build option which specifies the FIP
filename for the ``fip`` target. Default is ``fip.bin``.
@@ -535,6 +658,15 @@
This option defaults to 0.
+- ``DRTM_SUPPORT``: Boolean flag to enable support for Dynamic Root of Trust
+ for Measurement (DRTM). This feature has trust dependency on BL31 for taking
+ the measurements and recording them as per `PSA DRTM specification`_. For
+ platforms which use BL2 to load/authenticate BL31 ``TRUSTED_BOARD_BOOT`` can
+ be used and for the platforms which use ``RESET_TO_BL31`` platform owners
+ should have mechanism to authenticate BL31.
+
+ This option defaults to 0.
+
- ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
specifies the file that contains the Non-Trusted World private key in PEM
format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
@@ -588,9 +720,10 @@
enabled on Arm platforms, the option ``ARM_RECOM_STATE_ID_ENC`` needs to be
set to 1 as well.
-- ``RAS_EXTENSION``: When set to ``1``, enable Armv8.2 RAS features. RAS features
+- ``RAS_EXTENSION``: Numeric value to enable Armv8.2 RAS features. RAS features
are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
- or later CPUs.
+ or later CPUs. This flag can take the values 0 to 2, to align with the
+ ``FEATURE_DETECTION`` mechanism.
When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST`` must also be
set to ``1``.
@@ -602,6 +735,11 @@
entrypoint) or 1 (CPU reset to BL31 entrypoint).
The default value is 0.
+- ``RESET_TO_BL31_WITH_PARAMS``: If ``RESET_TO_BL31`` has been enabled, setting
+ this additional option guarantees that the input registers are not cleared
+ therefore allowing parameters to be passed to the BL31 entrypoint.
+ The default value is 0.
+
- ``RESET_TO_SP_MIN``: SP_MIN is the minimal AArch32 Secure Payload provided
in TF-A. This flag configures SP_MIN entrypoint as the CPU reset vector
instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
@@ -647,6 +785,13 @@
``BL31_NOBITS_LIMIT``. When the option is ``0`` (the default), NOBITS
sections are placed in RAM immediately following the loaded firmware image.
+- ``SEPARATE_BL2_NOLOAD_REGION``: Setting this option to ``1`` allows the
+ NOLOAD sections of BL2 (.bss, stacks, page tables) to be allocated in RAM
+ discontiguous from loaded firmware images. When set, the platform need to
+ provide definitions of ``BL2_NOLOAD_START`` and ``BL2_NOLOAD_LIMIT``. This
+ flag is disabled by default and NOLOAD sections are placed in RAM immediately
+ following the loaded firmware image.
+
- ``SMC_PCI_SUPPORT``: This option allows platforms to handle PCI configuration
access requests via a standard SMCCC defined in `DEN0115`_. When combined with
UEFI+ACPI this can provide a certain amount of OS forward compatibility
@@ -666,13 +811,20 @@
firmware images have been loaded in memory, and the MMU and caches are
turned off. Refer to the "Debugging options" section for more details.
+- ``SPMC_AT_EL3`` : This boolean option is used jointly with the SPM
+ Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC
+ component runs at the EL3 exception level. The default value is ``0`` (
+ disabled). This configuration supports pre-Armv8.4 platforms (aka not
+ implementing the ``FEAT_SEL2`` extension). This is an experimental feature.
+
-- ``SPMD_SPM_AT_SEL2`` : this boolean option is used jointly with the SPM
+- ``SPMD_SPM_AT_SEL2`` : This boolean option is used jointly with the SPM
Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC
- component runs at the S-EL2 execution state provided by the Armv8.4-SecEL2
+ component runs at the S-EL2 exception level provided by the ``FEAT_SEL2``
extension. This is the default when enabling the SPM Dispatcher. When
disabled (0) it indicates the SPMC component runs at the S-EL1 execution
- state. This latter configuration supports pre-Armv8.4 platforms (aka not
- implementing the Armv8.4-SecEL2 extension).
+ state or at EL3 if ``SPMC_AT_EL3`` is enabled. The latter configurations
+ support pre-Armv8.4 platforms (aka not implementing the ``FEAT_SEL2``
+ extension).
- ``SPM_MM`` : Boolean option to enable the Management Mode (MM)-based Secure
Partition Manager (SPM) implementation. The default value is ``0``
@@ -691,6 +843,14 @@
to mask these events. Platforms that enable FIQ handling in SP_MIN shall
implement the api ``sp_min_plat_fiq_handler()``. The default value is 0.
+- ``SVE_VECTOR_LEN``: SVE vector length to configure in ZCR_EL3.
+ Platforms can configure this if they need to lower the hardware
+ limit, for example due to asymmetric configuration or limitations of
+ software run at lower ELs. The default is the architectural maximum
+ of 2048 which should be suitable for most configurations, the
+ hardware will limit the effective VL to the maximum physically supported
+ VL.
+
- ``TRUSTED_BOARD_BOOT``: Boolean flag to include support for the Trusted Board
Boot feature. When set to '1', BL1 and BL2 images include support to load
and verify the certificates and images in a FIP, and BL1 includes support
@@ -724,6 +884,12 @@
When ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT``
must also be set to ``1``.
+- ``TWED_DELAY``: Numeric value to be set in order to delay the trapping of
+ WFE instruction. ``ENABLE_FEAT_TWED`` build option must be enabled to set
+ this delay. It can take values in the range (0-15). Default value is ``0``
+ and based on this value, 2^(TWED_DELAY + 8) cycles will be delayed.
+ Platforms need to explicitly update this value based on their requirements.
+
- ``USE_ARM_LINK``: This flag determines whether to enable support for ARM
linker. When the ``LINKER`` build variable points to the armlink linker,
this flag is enabled automatically. To enable support for armlink, platforms
@@ -825,28 +991,42 @@
bit, to trap access to the RAS ERR and RAS ERX registers from lower ELs.
This flag is disabled by default.
-- ``OPENSSL_DIR``: This flag is used to provide the installed openssl directory
- path on the host machine which is used to build certificate generation and
- firmware encryption tool.
+- ``OPENSSL_DIR``: This option is used to provide the path to a directory on the
+ host machine where a custom installation of OpenSSL is located, which is used
+ to build the certificate generation, firmware encryption and FIP tools. If
+ this option is not set, the default OS installation will be used.
- ``USE_SP804_TIMER``: Use the SP804 timer instead of the Generic Timer for
functions that wait for an arbitrary time length (udelay and mdelay). The
default value is 0.
-- ``ENABLE_TRBE_FOR_NS``: This flag is used to enable access of trace buffer
+- ``ENABLE_BRBE_FOR_NS``: Numeric value to enable access to the branch record
+ buffer registers from NS ELs when FEAT_BRBE is implemented. BRBE is an
+ optional architectural feature for AArch64. This flag can take the values
+ 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. The default is 0
+ and it is automatically disabled when the target architecture is AArch32.
+
+- ``ENABLE_TRBE_FOR_NS``: Numeric value to enable access of trace buffer
control registers from NS ELs, NS-EL2 or NS-EL1(when NS-EL2 is implemented
but unused) when FEAT_TRBE is implemented. TRBE is an optional architectural
- feature for AArch64. The default is 0 and it is automatically disabled when
- the target architecture is AArch32.
+ feature for AArch64. This flag can take the values 0 to 2, to align with the
+ ``FEATURE_DETECTION`` mechanism. The default is 0 and it is automatically
+ disabled when the target architecture is AArch32.
- ``ENABLE_SYS_REG_TRACE_FOR_NS``: Boolean option to enable trace system
registers access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented
but unused). This feature is available if trace unit such as ETMv4.x, and
ETE(extending ETM feature) is implemented. This flag is disabled by default.
-- ``ENABLE_TRF_FOR_NS``: Boolean option to enable trace filter control registers
+- ``ENABLE_TRF_FOR_NS``: Numeric value to enable trace filter control registers
access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented but unused),
- if FEAT_TRF is implemented. This flag is disabled by default.
+ if FEAT_TRF is implemented. This flag can take the values 0 to 2, to align
+ with the ``FEATURE_DETECTION`` mechanism. This flag is disabled by default.
+
+- ``PLAT_RSS_NOT_SUPPORTED``: Boolean option to enable the usage of the PSA
+ APIs on platforms that doesn't support RSS (providing Arm CCA HES
+ functionalities). When enabled (``1``), a mocked version of the APIs are used.
+ The default value is 0.
GICv3 driver options
--------------------
@@ -891,11 +1071,11 @@
make PLAT=<platform> DEBUG=1 V=1 all
-AArch64 GCC uses DWARF version 4 debugging symbols by default. Some tools (for
-example DS-5) might not support this and may need an older version of DWARF
-symbols to be emitted by GCC. This can be achieved by using the
-``-gdwarf-<version>`` flag, with the version being set to 2 or 3. Setting the
-version to 2 is recommended for DS-5 versions older than 5.16.
+AArch64 GCC 11 uses DWARF version 5 debugging symbols by default. Some tools
+(for example Arm-DS) might not support this and may need an older version of
+DWARF symbols to be emitted by GCC. This can be achieved by using the
+``-gdwarf-<version>`` flag, with the version being set to 2, 3, 4 or 5. Setting
+the version to 4 is recommended for Arm-DS.
When debugging logic problems it might also be useful to disable all compiler
optimizations by using ``-O0``.
@@ -920,7 +1100,7 @@
post-BL2 phase of TF-A. This can be done by rebuilding BL1 with the
``SPIN_ON_BL1_EXIT=1`` build flag. Refer to the :ref:`build_options_common`
section. In this case, the developer may take control of the target using a
-debugger when indicated by the console output. When using DS-5, the following
+debugger when indicated by the console output. When using Arm-DS, the following
commands can be used:
::
@@ -961,7 +1141,8 @@
--------------
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
.. _DEN0115: https://developer.arm.com/docs/den0115/latest
.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
+.. _PSA DRTM specification: https://developer.arm.com/documentation/den0113/a
diff --git a/docs/getting_started/initial-build.rst b/docs/getting_started/initial-build.rst
index d4a8f01..62f1941 100644
--- a/docs/getting_started/initial-build.rst
+++ b/docs/getting_started/initial-build.rst
@@ -18,16 +18,12 @@
It is possible to build TF-A using Clang or Arm Compiler 6. To do so
``CC`` needs to point to the clang or armclang binary, which will
- also select the clang or armclang assembler. Be aware that for Arm Compiler,
- the GNU linker is used by default. However for Clang LLVM linker (LLD)
- is used by default. In case of being needed the linker can be overridden
- using the ``LD`` variable. LLVM linker (LLD) version 9 is
- known to work with TF-A.
-
- In both cases ``CROSS_COMPILE`` should be set as described above.
-
- Arm Compiler 6 will be selected when the base name of the path assigned
- to ``CC`` matches the string 'armclang'.
+ also select the clang or armclang assembler. Arm Compiler 6 will be selected
+ when the base name of the path assigned to ``CC`` matches the string
+ 'armclang'. GNU binutils are required since the TF-A build system doesn't
+ currently support Arm Scatter files. Meaning the GNU linker is used by
+ default for Arm Compiler 6. Because of this dependency, ``CROSS_COMPILE``
+ should be set as described above.
For AArch64 using Arm Compiler 6:
@@ -36,6 +32,11 @@
export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all
+ On the other hand, Clang uses LLVM linker (LLD) and other LLVM binutils by
+ default instead of GNU utilities (LLVM linker (LLD) 14.0.0 is known to
+ work with TF-A). ``CROSS_COMPILE`` need not be set for Clang. Please note,
+ that the default linker may be manually overridden using the ``LD`` variable.
+
Clang will be selected when the base name of the path assigned to ``CC``
contains the string 'clang'. This is to allow both clang and clang-X.Y
to work.
@@ -44,7 +45,6 @@
.. code:: shell
- export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
make CC=<path-to-clang>/bin/clang PLAT=<platform> all
- Change to the root directory of the TF-A source tree and build.
@@ -115,4 +115,4 @@
--------------
-*Copyright (c) 2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2022, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 7f10ca6..992aca1 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -89,6 +89,8 @@
The following variables, functions and constants must be defined by the platform
for the firmware to work correctly.
+.. _platform_def_mandatory:
+
File : platform_def.h [mandatory]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -118,7 +120,7 @@
- **#define : CACHE_WRITEBACK_GRANULE**
- Defines the size in bits of the largest cache line across all the cache
+ Defines the size in bytes of the largest cache line across all the cache
levels in the platform.
- **#define : FIRMWARE_WELCOME_STR**
@@ -1663,6 +1665,42 @@
must return 0, otherwise it must return 1. The default implementation
of this always returns 0.
+Function : bl2_plat_mboot_init() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+When the MEASURED_BOOT flag is enabled:
+
+- This function is used to initialize the backend driver(s) of measured boot.
+- On the Arm FVP port, this function is used to initialize the Event Log
+ backend driver with the Event Log buffer information (base address and
+ size) received from BL1. It results in panic on error.
+
+When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
+
+Function : bl2_plat_mboot_finish() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+When the MEASURED_BOOT flag is enabled:
+
+- This function is used to finalize the measured boot backend driver(s),
+ and also, set the information for the next bootloader component to extend
+ the measurement if needed.
+- On the Arm FVP port, this function is used to pass the Event Log buffer
+ information (base address and size) to non-secure(BL33) and trusted OS(BL32)
+ via nt_fw and tos_fw config respectively. It results in panic on error.
+
+When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
+
Boot Loader Stage 2 (BL2) at EL3
--------------------------------
@@ -1820,42 +1858,6 @@
This function returns 0 on success, a negative error code otherwise.
This function is included if SCP_BL2U_BASE is defined.
-Function : bl2_plat_mboot_init() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-When the MEASURED_BOOT flag is enabled:
-
-- This function is used to initialize the backend driver(s) of measured boot.
-- On the Arm FVP port, this function is used to initialize the Event Log
- backend driver with the Event Log buffer information (base address and
- size) received from BL1. It results in panic on error.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
-Function : bl2_plat_mboot_finish() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-When the MEASURED_BOOT flag is enabled:
-
-- This function is used to finalize the measured boot backend driver(s),
- and also, set the information for the next bootloader component to extend
- the measurement if needed.
-- On the Arm FVP port, this function is used to pass the Event Log buffer
- information (base address and size) to non-secure(BL33) and trusted OS(BL32)
- via nt_fw and tos_fw config respectively. It results in panic on error.
-
-When the MEASURED_BOOT flag is disabled, this function doesn't do anything.
-
Boot Loader Stage 3-1 (BL31)
----------------------------
@@ -2017,6 +2019,83 @@
(that was copied during ``bl31_early_platform_setup()``) if the image exists. It
should return NULL otherwise.
+Function : plat_rmmd_get_cca_attest_token() [mandatory when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uintptr_t, size_t *, uintptr_t, size_t
+ Return : int
+
+This function returns the Platform attestation token.
+
+The parameters of the function are:
+
+ arg0 - A pointer to the buffer where the Platform token should be copied by
+ this function. The buffer must be big enough to hold the Platform
+ token.
+
+ arg1 - Contains the size (in bytes) of the buffer passed in arg0. The
+ function returns the platform token length in this parameter.
+
+ arg2 - A pointer to the buffer where the challenge object is stored.
+
+ arg3 - The length of the challenge object in bytes. Possible values are 32,
+ 48 and 64.
+
+The function returns 0 on success, -EINVAL on failure.
+
+Function : plat_rmmd_get_cca_realm_attest_key() [mandatory when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uintptr_t, size_t *, unsigned int
+ Return : int
+
+This function returns the delegated realm attestation key which will be used to
+sign Realm attestation token. The API currently only supports P-384 ECC curve
+key.
+
+The parameters of the function are:
+
+ arg0 - A pointer to the buffer where the attestation key should be copied
+ by this function. The buffer must be big enough to hold the
+ attestation key.
+
+ arg1 - Contains the size (in bytes) of the buffer passed in arg0. The
+ function returns the attestation key length in this parameter.
+
+ arg2 - The type of the elliptic curve to which the requested attestation key
+ belongs.
+
+The function returns 0 on success, -EINVAL on failure.
+
+Function : plat_rmmd_get_el3_rmm_shared_mem() [when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uintptr_t *
+ Return : size_t
+
+This function returns the size of the shared area between EL3 and RMM (or 0 on
+failure). A pointer to the shared area (or a NULL pointer on failure) is stored
+in the pointer passed as argument.
+
+Function : plat_rmmd_load_manifest() [when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments : rmm_manifest_t *manifest
+ Return : int
+
+When ENABLE_RME is enabled, this function populates a boot manifest for the
+RMM image and stores it in the area specified by manifest.
+
+When ENABLE_RME is disabled, this function is not used.
+
Function : bl31_plat_enable_mmu [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2066,21 +2145,6 @@
of the system counter, which is retrieved from the first entry in the frequency
modes table.
-Function : plat_arm_set_twedel_scr_el3() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : uint32_t
-
-This function is used in v8.6+ systems to set the WFE trap delay value in
-SCR_EL3. If this function returns TWED_DISABLED or is left unimplemented, this
-feature is not enabled. The only hook provided is to set the TWED fields in
-SCR_EL3, there are similar fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 to adjust
-the WFE trap delays in lower ELs and these fields should be set by the
-appropriate EL2 or EL1 code depending on the platform configuration.
-
#define : PLAT_PERCPU_BAKERY_LOCK_SIZE [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -3154,7 +3218,7 @@
--------------
-*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.*
.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
.. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index ee30128..81c55a5 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -26,9 +26,9 @@
|TF-A| can be built with any of the following *cross-compiler* toolchains that
target the Armv7-A or Armv8-A architectures:
-- GCC >= 10.3-2021.07 (from the `Arm Developer website`_)
-- Clang >= 4.0
-- Arm Compiler >= 6.0
+- GCC >= 11.2-2022.02 (from the `Arm Developer website`_)
+- Clang >= 14.0.0
+- Arm Compiler >= 6.18
In addition, a native compiler is required to build the supporting tools.
@@ -54,13 +54,20 @@
The following libraries must be available to build one or more components or
supporting tools:
-- OpenSSL >= 1.0.1
+- OpenSSL >= 3.0
Required to build the cert_create tool.
-The following libraries are required for Trusted Board Boot support:
+ .. note::
-- mbed TLS == 2.26.0 (tag: ``mbedtls-2.26.0``)
+ OpenSSL 3.0 has to be built from source code, as it's not available in
+ the default package repositories in recent Ubuntu versions. Please refer
+ to the OpenSSL project documentation for more information.
+
+The following libraries are required for Trusted Board Boot and Measured Boot
+support:
+
+- mbed TLS == 2.28.0 (tag: ``mbedtls-2.28.0``)
These tools are optional:
@@ -70,7 +77,7 @@
source files (``.dts`` files). DTC is available for Linux through the package
repositories of most distributions.
-- Arm `Development Studio 5 (DS-5)`_
+- Arm `Development Studio (Arm-DS)`_
The standard software package used for debugging software on Arm development
platforms and |FVP| models.
@@ -89,7 +96,7 @@
.. code:: shell
- sudo apt install build-essential git libssl-dev
+ sudo apt install build-essential git
The optional packages can be installed using:
@@ -159,11 +166,11 @@
--------------
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
-.. _Arm Developer website: https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads
+.. _Arm Developer website: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
.. _Gerrit Code Review: https://www.gerritcodereview.com/
.. _Linaro Release Notes: https://community.arm.com/dev-platforms/w/docs/226/old-release-notes
.. _Linaro instructions: https://community.arm.com/dev-platforms/w/docs/304/arm-reference-platforms-deliverables
-.. _Development Studio 5 (DS-5): https://developer.arm.com/products/software-development-tools/ds-5-development-studio
+.. _Development Studio (Arm-DS): https://developer.arm.com/Tools%20and%20Software/Arm%20Development%20Studio
.. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
diff --git a/docs/getting_started/tools-build.rst b/docs/getting_started/tools-build.rst
index c050f58..daf7e06 100644
--- a/docs/getting_started/tools-build.rst
+++ b/docs/getting_started/tools-build.rst
@@ -1,6 +1,16 @@
Building Supporting Tools
=========================
+.. note::
+
+ OpenSSL 3.0 is needed in order to build the tools. A custom installation
+ can be used if not updating the OpenSSL version on the OS. In order to do
+ this, use the ``OPENSSL_DIR`` variable after the ``make`` command to
+ indicate the location of the custom OpenSSL build. Then, to run the tools,
+ use the ``LD_LIBRARY_PATH`` to indicate the location of the built
+ libraries. More info about ``OPENSSL_DIR`` can be found at
+ :ref:`Build Options`.
+
Building and using the FIP tool
-------------------------------
@@ -164,4 +174,4 @@
--------------
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 2aaf195..3d10e45 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -12,7 +12,7 @@
(64-bit host machine only).
.. note::
- The FVP models used are Version 11.16 Build 16, unless otherwise stated.
+ The FVP models used are Version 11.17 Build 21, unless otherwise stated.
- ``Foundation_Platform``
- ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502``
@@ -48,12 +48,12 @@
- ``FVP_Base_Neoverse-N2x4`` (Version 11.12 build 38)
- ``FVP_Base_Neoverse-V1x4``
- ``FVP_Base_RevC-2xAEMvA`` (For certain configurations also uses 0.0/6557)
-- ``FVP_CSS_SGI-575`` (Version 11.15/26)
-- ``FVP_Morello`` (Version 0.11/19)
-- ``FVP_RD_E1_edge`` (Version 11.15/26)
-- ``FVP_RD_N1_edge_dual`` (Version 11.15/26)
-- ``FVP_RD_N1_edge`` (Version 11.15/26)
-- ``FVP_RD_V1`` (Version 11.15/26)
+- ``FVP_CSS_SGI-575`` (Version 11.17/33)
+- ``FVP_Morello`` (Version 0.11/33)
+- ``FVP_RD_E1_edge`` (Version 11.17/33)
+- ``FVP_RD_N1_edge_dual`` (Version 11.17/33)
+- ``FVP_RD_N1_edge`` (Version 11.17/33)
+- ``FVP_RD_V1`` (Version 11.17/33)
- ``FVP_TC0``
- ``FVP_TC1``
@@ -392,7 +392,8 @@
- BL1 is loaded at the start of the Trusted ROM.
- The Firmware Image Package is loaded at the start of NOR FLASH0.
- The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
- is specified via the ``hw_config_addr`` property in `TB_FW_CONFIG for FVP`_.
+ is specified via the ``load-address`` property in the ``hw-config`` node of
+ `FW_CONFIG for FVP`_.
- The default use-case for the Foundation FVP is to use the ``--gicv3`` option
and enable the GICv3 device in the model. Note that without this option,
the Foundation FVP defaults to legacy (Versatile Express) memory map which
@@ -643,9 +644,9 @@
--------------
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
-.. _TB_FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+.. _FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_fw_config.dts
.. _Arm's website: `FVP models`_
.. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
.. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index 8b9d453..91e681f 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -241,13 +241,13 @@
--------------
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
.. _Linaro release software stack: http://releases.linaro.org/members/arm/platforms/
.. _Juno platform software user guide: https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/juno/user-guide.rst
.. _TF-A downloads page: https://downloads.trustedfirmware.org/tf-a/css_scp_2.8.0/juno/
.. _build the binaries from source: https://github.com/ARM-software/SCP-firmware/blob/master/user_guide.md#scp-firmware-user-guide
.. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
-.. _Juno Getting Started Guide: http://infocenter.arm.com/help/topic/com.arm.doc.dui0928e/DUI0928E_juno_arm_development_platform_gsg.pdf
+.. _Juno Getting Started Guide: https://developer.arm.com/documentation/den0928/f/?lang=en
.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
.. _Juno Arm Development Platform: http://www.arm.com/products/tools/development-boards/versatile-express/juno-arm-development-platform.php
diff --git a/docs/plat/arm/tc/index.rst b/docs/plat/arm/tc/index.rst
index 20d3e56..ae2b836 100644
--- a/docs/plat/arm/tc/index.rst
+++ b/docs/plat/arm/tc/index.rst
@@ -13,11 +13,14 @@
- SCMI
- MHUv2
-Currently, the main difference between TC0 (TARGET_PLATFORM=0) and TC1
-(TARGET_PLATFORM=1) platforms w.r.t to TF-A is the CPUs supported. TC0 has
-support for Cortex A510, Cortex A710 and Cortex X2, while TC1 has support for
-Cortex A510, Cortex Makalu and Cortex Makalu ELP Arm CPUs.
+Currently, the main difference between TC0 (TARGET_PLATFORM=0), TC1
+(TARGET_PLATFORM=1), TC2 (TARGET_PLATFORM=2) platforms w.r.t to TF-A
+is the CPUs supported as below:
+- TC0 has support for Cortex A510, Cortex A710 and Cortex X2.
+- TC1 has support for Cortex A510, Cortex Makalu and Cortex Makalu ELP.
+- TC2 has support for Hayes and Hunter Arm CPUs.
+
Boot Sequence
-------------
@@ -33,15 +36,15 @@
Build Procedure (TF-A only)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- Obtain arm `toolchain <https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads>`_.
- Set the CROSS_COMPILE environment variable to point to the toolchain folder.
+- Obtain `Arm toolchain`_ and set the CROSS_COMPILE environment variable to
+ point to the toolchain folder.
- Build TF-A:
.. code:: shell
make PLAT=tc BL33=<path_to_uboot.bin> \
- SCP_BL2=<path_to_scp_ramfw.bin> TARGET_PLATFORM={0,1} all fip
+ SCP_BL2=<path_to_scp_ramfw.bin> TARGET_PLATFORM={0,1,2} all fip
Enable TBBR by adding the following options to the make command:
@@ -53,4 +56,8 @@
ARM_ROTPK_LOCATION=devel_rsa \
ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem
+--------------
+
+*Copyright (c) 2020-2022, Arm Limited. All rights reserved.*
+
-*Copyright (c) 2020-2021, Arm Limited. All rights reserved.*
+.. _Arm Toolchain: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 0cef16a..1f497e0 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -21,6 +21,7 @@
marvell/index
mt8183
mt8186
+ mt8188
mt8192
mt8195
nvidia-tegra
diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst
index 5147cf2..adb9603 100644
--- a/docs/plat/marvell/armada/build.rst
+++ b/docs/plat/marvell/armada/build.rst
@@ -68,8 +68,9 @@
- DEBUG
Default is without debug information (=0). in order to enable it use ``DEBUG=1``.
- Must be disabled when building UART recovery images due to current console driver
- implementation that is not compatible with Xmodem protocol used for boot image download.
+ Can be enabled also when building UART recovery images, there is no issue with it.
+
+ Production TF-A images should be built without this debug option!
- LOG_LEVEL
diff --git a/docs/plat/marvell/armada/uart-booting.rst b/docs/plat/marvell/armada/uart-booting.rst
new file mode 100644
index 0000000..06601d1
--- /dev/null
+++ b/docs/plat/marvell/armada/uart-booting.rst
@@ -0,0 +1,103 @@
+TF-A UART Booting Instructions for Marvell Platforms
+====================================================
+
+This section describes how to temporary boot the Trusted Firmware-A (TF-A) project over UART
+without flashing it to non-volatile storage for Marvell's platforms.
+
+See :ref:`TF-A Build Instructions for Marvell Platforms` how to build ``mrvl_uart`` and
+``mrvl_flash`` targets used in this section.
+
+Armada37x0 UART image downloading
+---------------------------------
+
+There are two options how to download UART image into any Armada37x0 board.
+
+Marvell Wtpdownloader
+~~~~~~~~~~~~~~~~~~~~~
+
+Marvell Wtpdownloader works only with UART images stored in separate files and supports only upload
+speed with 115200 bauds. Target ``mrvl_uart`` produces GZIPed TAR archive ``uart-images.tgz.bin``
+with either three files ``TIM_ATF.bin``, ``wtmi_h.bin`` and ``boot-image_h.bin`` for non-secure
+boot or with four files ``TIM_ATF_TRUSTED.bin``, ``TIMN_ATF_TRUSTED.bin``, ``wtmi_h.bin`` and
+``boot-image_h.bin`` when secure boot is enabled.
+
+Compilation:
+
+.. code:: shell
+
+ > git clone https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git
+ > make -C A3700-utils-marvell/wtptp/src/Wtpdownloader_Linux -f makefile.mk
+
+It produces executable binary ``A3700-utils-marvell/wtptp/src/Wtpdownloader_Linux/WtpDownload_linux``
+
+To download images from ``uart-images.tgz.bin`` archive unpack it and for non-secure boot variant run:
+
+.. code:: shell
+
+ > stty -F /dev/ttyUSB<port#> clocal
+ > WtpDownload_linux -P UART -C <port#> -E -B TIM_ATF.bin -I wtmi_h.bin -I boot-image_h.bin
+
+After that immediately start terminal on ``/dev/ttyUSB<port#>`` to see boot output.
+
+CZ.NIC mox-imager
+~~~~~~~~~~~~~~~~~
+
+CZ.NIC mox-imager supports all Armada37x0 boards (not only Turris MOX as name suggests). It works
+with either with separate files from ``uart-images.tgz.bin`` archive (like Marvell Wtpdownloader)
+produced by ``mrvl_uart`` target or also with ``flash-image.bin`` file produced by ``mrvl_flash``
+target, which is the exactly same file as used for flashing. So when using CZ.NIC mox-imager there
+is no need to build separate files for UART flashing like in case with Marvell Wtpdownloader.
+
+CZ.NIC mox-imager moreover supports higher upload speeds up to the 6000000 bauds (which seems to
+be limit of Armada37x0 SoC) which is much higher and faster than Marvell Wtpdownloader.
+
+Compilation:
+
+.. code:: shell
+
+ > git clone https://gitlab.nic.cz/turris/mox-imager.git
+ > make -C mox-imager
+
+It produces executable binary ``mox-imager/mox-imager``
+
+To download single file image built by ``mrvl_flash`` target at the highest speed, run:
+
+.. code:: shell
+
+ > mox-imager -D /dev/ttyUSB<port#> -E -b 6000000 -t flash-image.bin
+
+To download images from ``uart-images.tgz.bin`` archive built by ``mrvl_uart`` target for
+non-secure boot variant (like Wtpdownloader) but at the highest speed, first unpack
+``uart-images.tgz.bin`` archive and then run:
+
+.. code:: shell
+
+ > mox-imager -D /dev/ttyUSB<port#> -E -b 6000000 -t TIM_ATF.bin wtmi_h.bin boot-image_h.bin
+
+CZ.NIC mox-imager after successful download will start its own mini terminal (option ``-t``) to
+not loose any boot output. It also prints boot output which is sent either by image files or by
+bootrom during transferring of image files. This mini terminal can be quit by CTRL-\\ + C keypress.
+
+
+A7K/8K/CN913x UART image downloading
+------------------------------------
+
+A7K/8K/CN913x uses same image ``flash-image.bin`` for both flashing and booting over UART.
+For downloading image over UART it is possible to use mvebu64boot tool.
+
+Compilation:
+
+.. code:: shell
+
+ > git clone https://github.com/pali/mvebu64boot.git
+ > make -C mvebu64boot
+
+It produces executable binary ``mvebu64boot/mvebu64boot``
+
+To download ``flash-image.bin`` image run:
+
+.. code:: shell
+
+ > mvebu64boot -t -b flash-image.bin /dev/ttyUSB0
+
+After successful download it will start own mini terminal (option ``-t``) like CZ.NIC mox-imager.
diff --git a/docs/plat/marvell/index.rst b/docs/plat/marvell/index.rst
index 0d33432..2d5cdeb 100644
--- a/docs/plat/marvell/index.rst
+++ b/docs/plat/marvell/index.rst
@@ -6,6 +6,7 @@
:caption: Contents
armada/build
+ armada/uart-booting
armada/porting
armada/misc/mvebu-a8k-addr-map
armada/misc/mvebu-amb
diff --git a/docs/plat/mt8188.rst b/docs/plat/mt8188.rst
new file mode 100644
index 0000000..93abaa5
--- /dev/null
+++ b/docs/plat/mt8188.rst
@@ -0,0 +1,21 @@
+MediaTek 8188
+=============
+
+MediaTek 8188 (MT8188) is a 64-bit ARM SoC introduced by MediaTek in 2022.
+The chip incorporates eight cores - six Cortex-A55 little cores and two Cortex-A78.
+Cortex-A78 can operate at up to 2.6 GHz.
+Cortex-A55 can operate at up to 2.0 GHz.
+
+Boot Sequence
+-------------
+
+::
+
+ Boot Rom --> Coreboot --> TF-A BL31 --> Depthcharge --> Linux Kernel
+
+ How to Build
+ ------------
+
+ .. code:: shell
+
+ make CROSS_COMPILE=aarch64-linux-gnu- LD=aarch64-linux-gnu-gcc PLAT=mt8188 DEBUG=1 COREBOOT=1
diff --git a/docs/plat/nxp/nxp-layerscape.rst b/docs/plat/nxp/nxp-layerscape.rst
index 6cbd7f9..cd5874b 100644
--- a/docs/plat/nxp/nxp-layerscape.rst
+++ b/docs/plat/nxp/nxp-layerscape.rst
@@ -103,7 +103,7 @@
Arm Cortex-A72 cores with ECC-protected L1 and L2 cache memories for high
reliability, running up to 1.8 GHz.
-Details about LS1043A can be found at `ls1046a`_.
+Details about LS1046A can be found at `ls1046a`_.
- LS1046ARDB Board:
@@ -113,7 +113,7 @@
processor and is optimized to support the DDR4 memory and a full complement
of high-speed SerDes ports.
-Details about LS1043A RDB board can be found at `ls1046ardb`_.
+Details about LS1046A RDB board can be found at `ls1046ardb`_.
- LS1046AFRWY Board:
@@ -124,7 +124,28 @@
Ethernet, USB3.0 and M2_Type_E interfaces for Wi-Fi, FRWY-LS1046A-AC includes
the Wi-Fi card.
-Details about LS1043A RDB board can be found at `ls1046afrwy`_.
+Details about LS1046A FRWY board can be found at `ls1046afrwy`_.
+
+5. LS1088A
+
+- SoC Overview:
+
+The LS1088A family of multicore communications processors combines up to and eight
+Arm Cortex-A53 cores with the advanced, high-performance data path and network
+peripheral interfaces required for wireless access points, networking infrastructure,
+intelligent edge access, including virtual customer premise equipment (vCPE) and
+high-performance industrial applications.
+
+Details about LS1088A can be found at `ls1088a`_.
+
+- LS1088ARDB Board:
+
+The LS1088A reference design board provides a comprehensive platform that
+enables design and evaluation of the product (LS1088A processor). This RDB
+comes pre-loaded with a board support package (BSP) based on a standard
+Linux kernel.
+
+Details about LS1088A RDB board can be found at `ls1088ardb`_.
Table of supported boot-modes by each platform & platform that needs FIP-DDR:
-----------------------------------------------------------------------------
@@ -144,6 +165,8 @@
+---------------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
| ls1046afrwy | yes | yes | | | | | | no |
+---------------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
+| ls1088ardb | yes | yes | | | | | | no |
++---------------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
Boot Sequence
@@ -336,7 +359,7 @@
-- Then reset to alternate bank to boot up ATF.
- Command for lx2160a and ls1028a platforms:
+ Command for lx2160a, ls1088a and ls1028a platforms:
.. code:: shell
@@ -370,7 +393,7 @@
-- Then reset to sd/emmc to boot up ATF from sd/emmc as boot-source.
- Command for lx2160A and ls1028a platforms:
+ Command for lx2160A, ls1088a and ls1028a platforms:
.. code:: shell
@@ -445,4 +468,6 @@
.. _ls1046a: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-processors/layerscape-1046a-and-1026a-processors:LS1046A
.. _ls1046ardb: https://www.nxp.com/design/qoriq-developer-resources/layerscape-ls1046a-reference-design-board:LS1046A-RDB
.. _ls1046afrwy: https://www.nxp.com/design/qoriq-developer-resources/ls1046a-freeway-board:FRWY-LS1046A
+.. _ls1088a: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-processors/layerscape-1088a-and-1048a-processor:LS1088A
+.. _ls1088ardb: https://www.nxp.com/design/qoriq-developer-resources/layerscape-ls1088a-reference-design-board:LS1088A-RDB
.. _nxp-ls-tbbr.rst: ./nxp-ls-tbbr.rst
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index cefc21f..7ae98b1 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -2,15 +2,34 @@
===========================
STM32MP1 is a microprocessor designed by STMicroelectronics
-based on a dual Arm Cortex-A7.
+based on Arm Cortex-A7.
It is an Armv7-A platform, using dedicated code from TF-A.
-The STM32MP1 chip also embeds a Cortex-M4.
More information can be found on `STM32MP1 Series`_ page.
STM32MP1 Versions
-----------------
-The STM32MP1 series is available in 3 different lines which are pin-to-pin compatible:
+
+There are 2 variants for STM32MP1: STM32MP13 and STM32MP15
+
+STM32MP13 Versions
+~~~~~~~~~~~~~~~~~~
+The STM32MP13 series is available in 3 different lines which are pin-to-pin compatible:
+
+- STM32MP131: Single Cortex-A7 core
+- STM32MP133: STM32MP131 + 2*CAN, ETH2(GMAC), ADC1
+- STM32MP135: STM32MP133 + DCMIPP, LTDC
+
+Each line comes with a security option (cryptography & secure boot) and a Cortex-A frequency option:
+
+- A Cortex-A7 @ 650 MHz
+- C Secure Boot + HW Crypto + Cortex-A7 @ 650 MHz
+- D Cortex-A7 @ 900 MHz
+- F Secure Boot + HW Crypto + Cortex-A7 @ 900 MHz
+
+STM32MP15 Versions
+~~~~~~~~~~~~~~~~~~
+The STM32MP15 series is available in 3 different lines which are pin-to-pin compatible:
- STM32MP157: Dual Cortex-A7 cores, Cortex-M4 core @ 209 MHz, 3D GPU, DSI display interface and CAN FD
- STM32MP153: Dual Cortex-A7 cores, Cortex-M4 core @ 209 MHz and CAN FD
@@ -131,6 +150,10 @@
| Default: 115200
- | ``STM32_TF_VERSION``: to manage BL2 monotonic counter.
| Default: 0
+- | ``STM32MP13``: to select STM32MP13 variant configuration.
+ | Default: 0
+- | ``STM32MP15``: to select STM32MP15 variant configuration.
+ | Default: 1
Boot with FIP
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index d65b048..09a6ee2 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -43,6 +43,8 @@
* `VERSAL_PLATFORM`: Select the platform. Options:
- `versal_virt` : Versal Virtual platform
+ - `spp_itr6` : SPP ITR6
+ - `emu_itr6` : EMU ITR6
# PLM->TF-A Parameter Passing
------------------------------
diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst
index 79c2535..af1cb22 100644
--- a/docs/plat/xilinx-zynqmp.rst
+++ b/docs/plat/xilinx-zynqmp.rst
@@ -14,13 +14,13 @@
.. code:: bash
- make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp bl31
+ make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1 bl31
To build bl32 TSP you have to rebuild bl31 too:
.. code:: bash
- make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp SPD=tspd bl31 bl32
+ make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp SPD=tspd RESET_TO_BL31=1 bl31 bl32
To build TF-A for JTAG DCC console:
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index f80389d..ef9ebd3 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -299,6 +299,6 @@
.. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io
.. _Trusted Firmware binary repository: https://review.trustedfirmware.org/admin/repos/tf-binaries
.. _tf-binaries-readme: https://git.trustedfirmware.org/tf-binaries.git/tree/readme.rst
-.. _TF-A mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _TF-A mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
.. _tf-a-ci-scripts repository: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/
.. _tf-cov-make: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/tree/script/tf-coverity/tf-cov-make
diff --git a/docs/process/platform-compatibility-policy.rst b/docs/process/platform-compatibility-policy.rst
index be1f9ba..a10236c 100644
--- a/docs/process/platform-compatibility-policy.rst
+++ b/docs/process/platform-compatibility-policy.rst
@@ -31,6 +31,6 @@
--------------
-*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.*
-.. _TF-A public mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _TF-A public mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
diff --git a/docs/process/security.rst b/docs/process/security.rst
index a3b9971..e15783b 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -71,7 +71,7 @@
+-----------+------------------------------------------------------------------+
.. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
-.. _mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
.. |TFV-1| replace:: :ref:`Advisory TFV-1 (CVE-2016-10319)`
.. |TFV-2| replace:: :ref:`Advisory TFV-2 (CVE-2017-7564)`
@@ -86,4 +86,4 @@
--------------
-*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
diff --git a/docs/resources/diagrams/Makefile b/docs/resources/diagrams/Makefile
index 7f583b5..4e65569 100644
--- a/docs/resources/diagrams/Makefile
+++ b/docs/resources/diagrams/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -61,7 +61,19 @@
xlat_align_layers = "bg,translations"
xlat_align_opts =
-all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG)
+RMM_DIA = rmm_cold_boot_generic.dia
+RMM_PNG = rmm_cold_boot_generic.png
+
+rmm_cold_boot_generic_layers = "background"
+rmm_cold_boot_generic_opts =
+
+RMM_EL3_MANIFEST_DIA = rmm_el3_manifest_struct.dia
+RMM_EL3_MANIFEST_PNG = rmm_el3_manifest_struct.png
+
+rmm_el3_manifest_struct_layers = "Background"
+rmm_el3_manifest_struct_opts =
+
+all:$(RESET_PNGS) $(INT_PNGS) $(XLAT_PNG) $(RMM_PNG) $(RMM_EL3_MANIFEST_PNG)
$(RESET_PNGS):$(RESET_DIA)
$(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
@@ -72,3 +84,9 @@
$(XLAT_PNG):$(XLAT_DIA)
$(call generate_image,$($(patsubst %.png,%_layers,$@)),$(patsubst %.png,%.svg,$@),svg,$($(patsubst %.png,%_opts,$@)),$<)
inkscape -z $(patsubst %.png,%.svg,$@) -e $@ -d 45
+
+$(RMM_PNG):$(RMM_DIA)
+ $(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
+
+$(RMM_EL3_MANIFEST_PNG):$(RMM_EL3_MANIFEST_DIA)
+ $(call generate_image,$($(patsubst %.png,%_layers,$@)),$@,png,$($(patsubst %.png,%_opts,$@)),$<)
diff --git a/docs/resources/diagrams/partition-package.png b/docs/resources/diagrams/partition-package.png
new file mode 100644
index 0000000..3367422
--- /dev/null
+++ b/docs/resources/diagrams/partition-package.png
Binary files differ
diff --git a/docs/resources/diagrams/rmm_cold_boot_generic.dia b/docs/resources/diagrams/rmm_cold_boot_generic.dia
new file mode 100644
index 0000000..739a1df
--- /dev/null
+++ b/docs/resources/diagrams/rmm_cold_boot_generic.dia
Binary files differ
diff --git a/docs/resources/diagrams/rmm_cold_boot_generic.png b/docs/resources/diagrams/rmm_cold_boot_generic.png
new file mode 100644
index 0000000..df4c1ba
--- /dev/null
+++ b/docs/resources/diagrams/rmm_cold_boot_generic.png
Binary files differ
diff --git a/docs/resources/diagrams/rmm_el3_manifest_struct.dia b/docs/resources/diagrams/rmm_el3_manifest_struct.dia
new file mode 100644
index 0000000..7b7a9c2
--- /dev/null
+++ b/docs/resources/diagrams/rmm_el3_manifest_struct.dia
Binary files differ
diff --git a/docs/resources/diagrams/rmm_el3_manifest_struct.png b/docs/resources/diagrams/rmm_el3_manifest_struct.png
new file mode 100644
index 0000000..8b5776c
--- /dev/null
+++ b/docs/resources/diagrams/rmm_el3_manifest_struct.png
Binary files differ
diff --git a/docs/security_advisories/security-advisory-tfv-9.rst b/docs/security_advisories/security-advisory-tfv-9.rst
index 74b85dc..a7b5984 100644
--- a/docs/security_advisories/security-advisory-tfv-9.rst
+++ b/docs/security_advisories/security-advisory-tfv-9.rst
@@ -57,20 +57,38 @@
+----------------------+
| Cortex-A76 |
+----------------------+
+| Cortex-A76AE |
++----------------------+
| Cortex-A77 |
+----------------------+
| Cortex-A78 |
+----------------------+
+| Cortex-A78AE |
++----------------------+
+| Cortex-A78C |
++----------------------+
+| Cortex-X1 |
++----------------------+
| Cortex-X2 |
+----------------------+
| Cortex-A710 |
+----------------------+
+| Cortex-Makalu |
++----------------------+
+| Cortex-Makalu-ELP |
++----------------------+
+| Cortex-Hunter |
++----------------------+
| Neoverse-N1 |
+----------------------+
| Neoverse-N2 |
+----------------------+
| Neoverse-V1 |
+----------------------+
+| Neoverse-Demeter |
++----------------------+
+| Neoverse-Poseidon |
++----------------------+
For all other cores impacted by Spectre-BHB, some of which that do not implement
FEAT_CSV2 and some that do e.g. Cortex-A73, the recommended mitigation is to
@@ -90,7 +108,7 @@
implementation also enables the normal world to discover the presence of this
firmware service. This patch also implements ``SMCCC_ARCH_WORKAROUND_3`` for
Cortex-A57, Coxtex-A72, Cortex-A73 and Cortex-A75 using the existing workaround.
-for CVE-2017-5715.
+for CVE-2017-5715. Cortex-A15 patch extends Spectre V2 mitigation to Spectre-BHB.
The above workaround is enabled by default (on vulnerable CPUs only). Platforms
can choose to disable them at compile time if they do not require them.
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst
index 072babc..38e5c87 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/threat_model.rst
@@ -1,9 +1,10 @@
Generic Threat Model
********************
-************************
+************
Introduction
-************************
+************
+
This document provides a generic threat model for TF-A firmware.
.. note::
@@ -11,9 +12,10 @@
This threat model doesn't consider Root and Realm worlds introduced by
:ref:`Realm Management Extension (RME)`.
-************************
+********************
Target of Evaluation
-************************
+********************
+
In this threat model, the target of evaluation is the Trusted
Firmware for A-class Processors (TF-A). This includes the boot ROM (BL1),
the trusted boot firmware (BL2) and the runtime EL3 firmware (BL31) as
@@ -34,8 +36,15 @@
- There is no Secure-EL2. We don't consider threats that may come with
Secure-EL2 software.
+- Measured boot is disabled. We do not consider the threats nor the mitigations
+ that may come with it.
+
+- No experimental features are enabled. We do not consider threats that may come
+ from them.
+
Data Flow Diagram
-======================
+=================
+
Figure 1 shows a high-level data flow diagram for TF-A. The diagram
shows a model of the different components of a TF-A-based system and
their interactions with TF-A. A description of each diagram element
@@ -51,26 +60,26 @@
+-----------------+--------------------------------------------------------+
| Diagram Element | Description |
+=================+========================================================+
- | ``DF1`` | | At boot time, images are loaded from non-volatile |
+ | DF1 | | At boot time, images are loaded from non-volatile |
| | memory and verified by TF-A boot firmware. These |
| | images include TF-A BL2 and BL31 images, as well as |
| | other secure and non-secure images. |
+-----------------+--------------------------------------------------------+
- | ``DF2`` | | TF-A log system framework outputs debug messages |
+ | DF2 | | TF-A log system framework outputs debug messages |
| | over a UART interface. |
+-----------------+--------------------------------------------------------+
- | ``DF3`` | | Debug and trace IP on a platform can allow access |
+ | DF3 | | Debug and trace IP on a platform can allow access |
| | to registers and memory of TF-A. |
+-----------------+--------------------------------------------------------+
- | ``DF4`` | | Secure world software (e.g. trusted OS) interact |
+ | DF4 | | Secure world software (e.g. trusted OS) interact |
| | with TF-A through SMC call interface and/or shared |
| | memory. |
+-----------------+--------------------------------------------------------+
- | ``DF5`` | | Non-secure world software (e.g. rich OS) interact |
+ | DF5 | | Non-secure world software (e.g. rich OS) interact |
| | with TF-A through SMC call interface and/or shared |
| | memory. |
+-----------------+--------------------------------------------------------+
- | ``DF6`` | | This path represents the interaction between TF-A and|
+ | DF6 | | This path represents the interaction between TF-A and|
| | various hardware IPs such as TrustZone controller |
| | and GIC. At boot time TF-A configures/initializes the|
| | IPs and interacts with them at runtime through |
@@ -78,9 +87,10 @@
+-----------------+--------------------------------------------------------+
-*********************
+***************
Threat Analysis
-*********************
+***************
+
In this section we identify and provide assessment of potential threats to TF-A
firmware. The threats are identified for each diagram element on the
data flow diagram above.
@@ -91,7 +101,8 @@
potential mitigations.
Assets
-==================
+======
+
We have identified the following assets for TF-A:
.. table:: Table 2: TF-A Assets
@@ -99,21 +110,22 @@
+--------------------+---------------------------------------------------+
| Asset | Description |
+====================+===================================================+
- | ``Sensitive Data`` | | These include sensitive data that an attacker |
+ | Sensitive Data | | These include sensitive data that an attacker |
| | must not be able to tamper with (e.g. the Root |
| | of Trust Public Key) or see (e.g. secure logs, |
| | debugging information such as crash reports). |
+--------------------+---------------------------------------------------+
- | ``Code Execution`` | | This represents the requirement that the |
+ | Code Execution | | This represents the requirement that the |
| | platform should run only TF-A code approved by |
| | the platform provider. |
+--------------------+---------------------------------------------------+
- | ``Availability`` | | This represents the requirement that TF-A |
+ | Availability | | This represents the requirement that TF-A |
| | services should always be available for use. |
+--------------------+---------------------------------------------------+
Threat Agents
-=====================
+=============
+
To understand the attack surface, it is important to identify potential
attackers, i.e. attack entry points. The following threat agents are
in scope of this threat model.
@@ -123,16 +135,16 @@
+-------------------+-------------------------------------------------------+
| Threat Agent | Description |
+===================+=======================================================+
- | ``NSCode`` | | Malicious or faulty code running in the Non-secure |
+ | NSCode | | Malicious or faulty code running in the Non-secure |
| | world, including NS-EL0 NS-EL1 and NS-EL2 levels |
+-------------------+-------------------------------------------------------+
- | ``SecCode`` | | Malicious or faulty code running in the secure |
+ | SecCode | | Malicious or faulty code running in the secure |
| | world, including S-EL0 and S-EL1 levels |
+-------------------+-------------------------------------------------------+
- | ``AppDebug`` | | Physical attacker using debug signals to access |
+ | AppDebug | | Physical attacker using debug signals to access |
| | TF-A resources |
+-------------------+-------------------------------------------------------+
- | ``PhysicalAccess``| | Physical attacker having access to external device |
+ | PhysicalAccess | | Physical attacker having access to external device |
| | communication bus and to external flash |
| | communication bus using common hardware |
+-------------------+-------------------------------------------------------+
@@ -145,7 +157,8 @@
considered out-of-scope.
Threat Types
-========================
+============
+
In this threat model we categorize threats using the `STRIDE threat
analysis technique`_. In this technique a threat is categorized as one
or more of these types: ``Spoofing``, ``Tampering``, ``Repudiation``,
@@ -153,7 +166,8 @@
``Elevation of privilege``.
Threat Risk Ratings
-========================
+===================
+
For each threat identified, a risk rating that ranges
from *informational* to *critical* is given based on the likelihood of the
threat occuring if a mitigation is not in place, and the impact of the
@@ -165,7 +179,7 @@
+-----------------------+-------------------------+---------------------------+
| **Rating (Score)** | **Impact** | **Likelihood** |
+=======================+=========================+===========================+
- | ``Critical (5)`` | | Extreme impact to | | Threat is almost |
+ | Critical (5) | | Extreme impact to | | Threat is almost |
| | entire organization | certain to be exploited.|
| | if exploited. | |
| | | | Knowledge of the threat |
@@ -173,17 +187,17 @@
| | | are in the public |
| | | domain. |
+-----------------------+-------------------------+---------------------------+
- | ``High (4)`` | | Major impact to entire| | Threat is relatively |
+ | High (4) | | Major impact to entire| | Threat is relatively |
| | organization or single| easy to detect and |
| | line of business if | exploit by an attacker |
| | exploited | with little skill. |
+-----------------------+-------------------------+---------------------------+
- | ``Medium (3)`` | | Noticeable impact to | | A knowledgeable insider |
+ | Medium (3) | | Noticeable impact to | | A knowledgeable insider |
| | line of business if | or expert attacker could|
| | exploited. | exploit the threat |
| | | without much difficulty.|
+-----------------------+-------------------------+---------------------------+
- | ``Low (2)`` | | Minor damage if | | Exploiting the threat |
+ | Low (2) | | Minor damage if | | Exploiting the threat |
| | exploited or could | would require |
| | be used in conjunction| considerable expertise |
| | with other | and resources |
@@ -191,7 +205,7 @@
| | perform a more serious| |
| | attack | |
+-----------------------+-------------------------+---------------------------+
- | ``Informational (1)`` | | Poor programming | | Threat is not likely |
+ | Informational (1) | | Poor programming | | Threat is not likely |
| | practice or poor | to be exploited on its |
| | design decision that | own, but may be used to |
| | may not represent an | gain information for |
@@ -235,14 +249,27 @@
``Internet of Things(IoT)``, ``Mobile`` and ``Server``.
Threat Assessment
-============================
+=================
+
The following threats were identified by applying STRIDE analysis on
each diagram element of the data flow diagram.
+For each threat, we strive to indicate whether the mitigations are currently
+implemented or not. However, the answer to this question is not always straight
+forward. Some mitigations are partially implemented in the generic code but also
+rely on the platform code to implement some bits of it. This threat model aims
+to be platform-independent and it is important to keep in mind that such threats
+only get mitigated if the platform code properly fulfills its responsibilities.
+
+Also, some mitigations require enabling specific features, which must be
+explicitly turned on via a build flag.
+
+These are highlighted in the ``Mitigations implemented?`` box.
+
+------------------------+----------------------------------------------------+
| ID | 01 |
+========================+====================================================+
-| ``Threat`` | | **An attacker can mangle firmware images to |
+| Threat | | **An attacker can mangle firmware images to |
| | execute arbitrary code** |
| | |
| | | Some TF-A images are loaded from external |
@@ -252,79 +279,89 @@
| | updating mechanism to modify the non-volatile |
| | images to execute arbitrary code. |
+------------------------+----------------------------------------------------+
-| ``Diagram Elements`` | DF1, DF4, DF5 |
+| Diagram Elements | DF1, DF4, DF5 |
+------------------------+----------------------------------------------------+
-| ``Affected TF-A | BL2, BL31 |
-| Components`` | |
+| Affected TF-A | BL2, BL31 |
+| Components | |
+------------------------+----------------------------------------------------+
-| ``Assets`` | Code Execution |
+| Assets | Code Execution |
+------------------------+----------------------------------------------------+
-| ``Threat Agent`` | PhysicalAccess, NSCode, SecCode |
+| Threat Agent | PhysicalAccess, NSCode, SecCode |
+------------------------+----------------------------------------------------+
-| ``Threat Type`` | Tampering, Elevation of Privilege |
+| Threat Type | Tampering, Elevation of Privilege |
+------------------------+------------------+-----------------+---------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+------------------+-----------------+---------------+
-| ``Impact`` | Critical (5) | Critical (5) | Critical (5) |
+| Impact | Critical (5) | Critical (5) | Critical (5) |
+------------------------+------------------+-----------------+---------------+
-| ``Likelihood`` | Critical (5) | Critical (5) | Critical (5) |
+| Likelihood | Critical (5) | Critical (5) | Critical (5) |
+------------------------+------------------+-----------------+---------------+
-| ``Total Risk Rating`` | Critical (25) | Critical (25) | Critical (25) |
+| Total Risk Rating | Critical (25) | Critical (25) | Critical (25) |
+------------------------+------------------+-----------------+---------------+
-| ``Mitigations`` | | TF-A implements the `Trusted Board Boot (TBB)`_ |
+| Mitigations | | 1) Implement the `Trusted Board Boot (TBB)`_ |
| | feature which prevents malicious firmware from |
| | running on the platform by authenticating all |
-| | firmware images. In addition to this, the TF-A |
-| | boot firmware performs extra checks on |
-| | unauthenticated data, such as FIP metadata, prior|
-| | to use. |
+| | firmware images. |
+| | |
+| | | 2) Perform extra checks on unauthenticated data, |
+| | such as FIP metadata, prior to use. |
++------------------------+----------------------------------------------------+
+| Mitigations | | 1) Yes, provided that the ``TRUSTED_BOARD_BOOT`` |
+| implemented? | build option is set to 1. |
+| | |
+| | | 2) Yes. |
+------------------------+----------------------------------------------------+
+------------------------+----------------------------------------------------+
| ID | 02 |
+========================+====================================================+
-| ``Threat`` | | **An attacker may attempt to boot outdated, |
+| Threat | | **An attacker may attempt to boot outdated, |
| | potentially vulnerable firmware image** |
| | |
| | | When updating firmware, an attacker may attempt |
| | to rollback to an older version that has unfixed |
| | vulnerabilities. |
+------------------------+----------------------------------------------------+
-| ``Diagram Elements`` | DF1, DF4, DF5 |
+| Diagram Elements | DF1, DF4, DF5 |
+------------------------+----------------------------------------------------+
-| ``Affected TF-A | BL2, BL31 |
-| Components`` | |
+| Affected TF-A | BL2, BL31 |
+| Components | |
+------------------------+----------------------------------------------------+
-| ``Assets`` | Code Execution |
+| Assets | Code Execution |
+------------------------+----------------------------------------------------+
-| ``Threat Agent`` | PhysicalAccess, NSCode, SecCode |
+| Threat Agent | PhysicalAccess, NSCode, SecCode |
+------------------------+----------------------------------------------------+
-| ``Threat Type`` | Tampering |
+| Threat Type | Tampering |
+------------------------+------------------+-----------------+---------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+------------------+-----------------+---------------+
-| ``Impact`` | Critical (5) | Critical (5) | Critical (5) |
+| Impact | Critical (5) | Critical (5) | Critical (5) |
+------------------------+------------------+-----------------+---------------+
-| ``Likelihood`` | Critical (5) | Critical (5) | Critical (5) |
+| Likelihood | Critical (5) | Critical (5) | Critical (5) |
+------------------------+------------------+-----------------+---------------+
-| ``Total Risk Rating`` | Critical (25) | Critical (25) | Critical (25) |
+| Total Risk Rating | Critical (25) | Critical (25) | Critical (25) |
+------------------------+------------------+-----------------+---------------+
-| ``Mitigations`` | | TF-A supports anti-rollback protection using |
-| | non-volatile counters (NV counters) as required |
-| | by `TBBR-Client specification`_. After a firmware|
-| | image is validated, the image revision number |
-| | taken from a certificate extension field is |
-| | compared with the corresponding NV counter stored|
-| | in hardware to make sure the new counter value is|
-| | larger or equal to the current counter value. |
-| | Platforms must implement this protection using |
-| | platform specific hardware NV counters. |
+| Mitigations | Implement anti-rollback protection using |
+| | non-volatile counters (NV counters) as required |
+| | by `TBBR-Client specification`_. |
++------------------------+----------------------------------------------------+
+| Mitigations | | Yes / Platform specific. |
+| implemented? | |
+| | | After a firmware image is validated, the image |
+| | revision number taken from a certificate |
+| | extension field is compared with the |
+| | corresponding NV counter stored in hardware to |
+| | make sure the new counter value is larger than |
+| | the current counter value. |
+| | |
+| | | **Platforms must implement this protection using |
+| | platform specific hardware NV counters.** |
+------------------------+----------------------------------------------------+
+------------------------+-------------------------------------------------------+
| ID | 03 |
+========================+=======================================================+
-| ``Threat`` | | **An attacker can use Time-of-Check-Time-of-Use |
+| Threat | | **An attacker can use Time-of-Check-Time-of-Use |
| | (TOCTOU) attack to bypass image authentication |
| | during the boot process** |
| | |
@@ -336,33 +373,39 @@
| | after the integrity and authentication check has |
| | been performed. |
+------------------------+-------------------------------------------------------+
-| ``Diagram Elements`` | DF1 |
+| Diagram Elements | DF1 |
+------------------------+-------------------------------------------------------+
-| ``Affected TF-A | BL1, BL2 |
-| Components`` | |
+| Affected TF-A | BL1, BL2 |
+| Components | |
+------------------------+-------------------------------------------------------+
-| ``Assets`` | Code Execution, Sensitive Data |
+| Assets | Code Execution, Sensitive Data |
+------------------------+-------------------------------------------------------+
-| ``Threat Agent`` | PhysicalAccess |
+| Threat Agent | PhysicalAccess |
+------------------------+-------------------------------------------------------+
-| ``Threat Type`` | Elevation of Privilege |
+| Threat Type | Elevation of Privilege |
+------------------------+---------------------+-----------------+---------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+---------------------+-----------------+---------------+
-| ``Impact`` | N/A | Critical (5) | Critical (5) |
+| Impact | N/A | Critical (5) | Critical (5) |
+------------------------+---------------------+-----------------+---------------+
-| ``Likelihood`` | N/A | Medium (3) | Medium (3) |
+| Likelihood | N/A | Medium (3) | Medium (3) |
+------------------------+---------------------+-----------------+---------------+
-| ``Total Risk Rating`` | N/A | High (15) | High (15) |
+| Total Risk Rating | N/A | High (15) | High (15) |
+------------------------+---------------------+-----------------+---------------+
-| ``Mitigations`` | | TF-A boot firmware copies image to on-chip |
-| | memory before authenticating an image. |
+| Mitigations | Copy image to on-chip memory before authenticating |
+| | it. |
++------------------------+-------------------------------------------------------+
+| Mitigations | | Platform specific. |
+| implemented? | |
+| | | The list of images to load and their location is |
+| | platform specific. Platforms are responsible for |
+| | arranging images to be loaded in on-chip memory. |
+------------------------+-------------------------------------------------------+
+------------------------+-------------------------------------------------------+
| ID | 04 |
+========================+=======================================================+
-| ``Threat`` | | **An attacker with physical access can execute |
+| Threat | | **An attacker with physical access can execute |
| | arbitrary image by bypassing the signature |
| | verification stage using glitching techniques** |
| | |
@@ -381,31 +424,38 @@
| | points where the image is validated against the |
| | signature. |
+------------------------+-------------------------------------------------------+
-| ``Diagram Elements`` | DF1 |
+| Diagram Elements | DF1 |
+------------------------+-------------------------------------------------------+
-| ``Affected TF-A | BL1, BL2 |
-| Components`` | |
+| Affected TF-A | BL1, BL2 |
+| Components | |
+------------------------+-------------------------------------------------------+
-| ``Assets`` | Code Execution |
+| Assets | Code Execution |
+------------------------+-------------------------------------------------------+
-| ``Threat Agent`` | PhysicalAccess |
+| Threat Agent | PhysicalAccess |
+------------------------+-------------------------------------------------------+
-| ``Threat Type`` | Tampering, Elevation of Privilege |
+| Threat Type | Tampering, Elevation of Privilege |
+------------------------+---------------------+-----------------+---------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+---------------------+-----------------+---------------+
-| ``Impact`` | N/A | Critical (5) | Critical (5) |
+| Impact | N/A | Critical (5) | Critical (5) |
+------------------------+---------------------+-----------------+---------------+
-| ``Likelihood`` | N/A | Medium (3) | Medium (3) |
+| Likelihood | N/A | Medium (3) | Medium (3) |
+------------------------+---------------------+-----------------+---------------+
-| ``Total Risk Rating`` | N/A | High (15) | High (15) |
+| Total Risk Rating | N/A | High (15) | High (15) |
+------------------------+---------------------+-----------------+---------------+
-| ``Mitigations`` | | The most effective mitigation is adding glitching |
+| Mitigations | Mechanisms to detect clock glitch and power |
+| | variations. |
++------------------------+-------------------------------------------------------+
+| Mitigations | | No. |
+| implemented? | |
+| | | The most effective mitigation is adding glitching |
| | detection and mitigation circuit at the hardware |
-| | level. However, software techniques, |
-| | such as adding redundant checks when performing |
-| | conditional branches that are security sensitive, |
-| | can be used to harden TF-A against such attacks. |
+| | level. |
+| | |
+| | | However, software techniques, such as adding |
+| | redundant checks when performing conditional |
+| | branches that are security sensitive, can be used |
+| | to harden TF-A against such attacks. |
| | **At the moment TF-A doesn't implement such |
| | mitigations.** |
+------------------------+-------------------------------------------------------+
@@ -413,49 +463,76 @@
+------------------------+---------------------------------------------------+
| ID | 05 |
+========================+===================================================+
-| ``Threat`` | | **Information leak via UART logs such as |
-| | crashes** |
+| Threat | | **Information leak via UART logs** |
| | |
| | | During the development stages of software it is |
-| | common to include crash reports with detailed |
-| | information of the CPU state including current |
-| | values of the registers, privilege level and |
-| | stack dumps. This information is useful when |
-| | debugging problems before releasing the |
-| | production version, but it could be used by an |
-| | attacker to develop a working exploit if left |
-| | in the production version. |
+| | common to print all sorts of information on the |
+| | console, including sensitive or confidential |
+| | information such as crash reports with detailed |
+| | information of the CPU state, current registers |
+| | values, privilege level or stack dumps. |
+| | |
+| | | This information is useful when debugging |
+| | problems before releasing the production |
+| | version but it could be used by an attacker |
+| | to develop a working exploit if left enabled in |
+| | the production version. |
+| | |
+| | | This happens when directly logging sensitive |
+| | information and more subtly when logging |
+| | side-channel information that can be used by an |
+| | attacker to learn about sensitive information. |
+------------------------+---------------------------------------------------+
-| ``Diagram Elements`` | DF2 |
+| Diagram Elements | DF2 |
+------------------------+---------------------------------------------------+
-| ``Affected TF-A | BL1, BL2, BL31 |
-| Components`` | |
+| Affected TF-A | BL1, BL2, BL31 |
+| Components | |
+------------------------+---------------------------------------------------+
-| ``Assets`` | Sensitive Data |
+| Assets | Sensitive Data |
+------------------------+---------------------------------------------------+
-| ``Threat Agent`` | AppDebug |
+| Threat Agent | AppDebug |
+------------------------+---------------------------------------------------+
-| ``Threat Type`` | Information Disclosure |
+| Threat Type | Information Disclosure |
+------------------------+------------------+----------------+---------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+------------------+----------------+---------------+
-| ``Impact`` | N/A | Low (2) | Low (2) |
+| Impact | N/A | Low (2) | Low (2) |
+------------------------+------------------+----------------+---------------+
-| ``Likelihood`` | N/A | High (4) | High (4) |
+| Likelihood | N/A | High (4) | High (4) |
+------------------------+------------------+----------------+---------------+
-| ``Total Risk Rating`` | N/A | Medium (8) | Medium (8) |
+| Total Risk Rating | N/A | Medium (8) | Medium (8) |
+------------------------+------------------+----------------+---------------+
-| ``Mitigations`` | | In TF-A, crash reporting is only enabled for |
-| | debug builds by default. Alternatively, the log |
-| | level can be tuned at build time (from verbose |
-| | to no output at all), independently of the |
-| | build type. |
+| Mitigations | | Remove sensitive information logging in |
+| | production releases. |
+| | |
+| | | Do not conditionally log information depending |
+| | on potentially sensitive data. |
+| | |
+| | | Do not log high precision timing information. |
++------------------------+---------------------------------------------------+
+| Mitigations | | Yes / Platform Specific. |
+| implemented? | Requires the right build options to be used. |
+| | |
+| | | Crash reporting is only enabled for debug |
+| | builds by default, see ``CRASH_REPORTING`` |
+| | build option. |
+| | |
+| | | The log level can be tuned at build time, from |
+| | very verbose to no output at all. See |
+| | ``LOG_LEVEL`` build option. By default, release |
+| | builds are a lot less verbose than debug ones |
+| | but still produce some output. |
+| | |
+| | | Messages produced by the platform code should |
+| | use the appropriate level of verbosity so as |
+| | not to leak sensitive information in production |
+| | builds. |
+------------------------+---------------------------------------------------+
+------------------------+----------------------------------------------------+
| ID | 06 |
+========================+====================================================+
-| ``Threat`` | | **An attacker can read sensitive data and |
+| Threat | | **An attacker can read sensitive data and |
| | execute arbitrary code through the external |
| | debug and trace interface** |
| | |
@@ -468,37 +545,40 @@
| | attacker to read sensitive data and execute |
| | arbitrary code. |
+------------------------+----------------------------------------------------+
-| ``Diagram Elements`` | DF3 |
+| Diagram Elements | DF3 |
+------------------------+----------------------------------------------------+
-| ``Affected TF-A | BL1, BL2, BL31 |
-| Components`` | |
+| Affected TF-A | BL1, BL2, BL31 |
+| Components | |
+------------------------+----------------------------------------------------+
-| ``Assets`` | Code Execution, Sensitive Data |
+| Assets | Code Execution, Sensitive Data |
+------------------------+----------------------------------------------------+
-| ``Threat Agent`` | AppDebug |
+| Threat Agent | AppDebug |
+------------------------+----------------------------------------------------+
-| ``Threat Type`` | Tampering, Information Disclosure, |
+| Threat Type | Tampering, Information Disclosure, |
| | Elevation of privilege |
+------------------------+------------------+---------------+-----------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+------------------+---------------+-----------------+
-| ``Impact`` | N/A | High (4) | High (4) |
+| Impact | N/A | High (4) | High (4) |
+------------------------+------------------+---------------+-----------------+
-| ``Likelihood`` | N/A | Critical (5) | Critical (5) |
+| Likelihood | N/A | Critical (5) | Critical (5) |
+------------------------+------------------+---------------+-----------------+
-| ``Total Risk Rating`` | N/A | Critical (20) | Critical (20) |
+| Total Risk Rating | N/A | Critical (20) | Critical (20) |
+------------------------+------------------+---------------+-----------------+
-| ``Mitigations`` | | Configuration of debug and trace capabilities is |
-| | platform specific. Therefore, platforms must |
-| | disable the debug and trace capability for |
-| | production releases or enable proper debug |
-| | authentication as recommended by [`DEN0034`_]. |
+| Mitigations | Disable the debug and trace capability for |
+| | production releases or enable proper debug |
+| | authentication as recommended by [`DEN0034`_]. |
++------------------------+----------------------------------------------------+
+| Mitigations | | Platform specific. |
+| implemented? | |
+| | | Configuration of debug and trace capabilities is |
+| | entirely platform specific. |
+------------------------+----------------------------------------------------+
+------------------------+------------------------------------------------------+
| ID | 07 |
+========================+======================================================+
-| ``Threat`` | | **An attacker can perform a denial-of-service |
+| Threat | | **An attacker can perform a denial-of-service |
| | attack by using a broken SMC call that causes the |
| | system to reboot or enter into unknown state.** |
| | |
@@ -508,48 +588,48 @@
| | by calling unimplemented SMC call or by passing |
| | invalid arguments. |
+------------------------+------------------------------------------------------+
-| ``Diagram Elements`` | DF4, DF5 |
+| Diagram Elements | DF4, DF5 |
+------------------------+------------------------------------------------------+
-| ``Affected TF-A | BL31 |
-| Components`` | |
+| Affected TF-A | BL31 |
+| Components | |
+------------------------+------------------------------------------------------+
-| ``Assets`` | Availability |
+| Assets | Availability |
+------------------------+------------------------------------------------------+
-| ``Threat Agent`` | NSCode, SecCode |
+| Threat Agent | NSCode, SecCode |
+------------------------+------------------------------------------------------+
-| ``Threat Type`` | Denial of Service |
+| Threat Type | Denial of Service |
+------------------------+-------------------+----------------+-----------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+-------------------+----------------+-----------------+
-| ``Impact`` | Medium (3) | Medium (3) | Medium (3) |
+| Impact | Medium (3) | Medium (3) | Medium (3) |
+------------------------+-------------------+----------------+-----------------+
-| ``Likelihood`` | High (4) | High (4) | High (4) |
+| Likelihood | High (4) | High (4) | High (4) |
+------------------------+-------------------+----------------+-----------------+
-| ``Total Risk Rating`` | High (12) | High (12) | High (12) |
+| Total Risk Rating | High (12) | High (12) | High (12) |
+------------------------+-------------------+----------------+-----------------+
-| ``Mitigations`` | | The generic TF-A code validates SMC function ids |
-| | and arguments before using them. |
-| | Platforms that implement SiP services must also |
+| Mitigations | Validate SMC function ids and arguments before using |
+| | them. |
++------------------------+------------------------------------------------------+
+| Mitigations | | Yes / Platform specific. |
+| implemented? | |
+| | | For standard services, all input is validated. |
+| | |
+| | | Platforms that implement SiP services must also |
| | validate SMC call arguments. |
+------------------------+------------------------------------------------------+
+------------------------+------------------------------------------------------+
| ID | 08 |
+========================+======================================================+
-| ``Threat`` | | **Memory corruption due to memory overflows and |
+| Threat | | **Memory corruption due to memory overflows and |
| | lack of boundary checking when accessing resources |
| | could allow an attacker to execute arbitrary code, |
| | modify some state variable to change the normal |
| | flow of the program, or leak sensitive |
| | information** |
| | |
-| | | Like in other software, the Trusted Firmware has |
-| | multiple points where memory corruption security |
-| | errors can arise. Memory corruption is a dangerous |
-| | security issue since it could allow an attacker |
-| | to execute arbitrary code, modify some state |
-| | variable to change the normal flow of the program, |
-| | or leak sensitive information. |
+| | | Like in other software, TF-A has multiple points |
+| | where memory corruption security errors can arise. |
| | |
| | | Some of the errors include integer overflow, |
| | buffer overflow, incorrect array boundary checks, |
@@ -558,37 +638,32 @@
| | validations might also result in these kinds of |
| | errors in release builds. |
+------------------------+------------------------------------------------------+
-| ``Diagram Elements`` | DF4, DF5 |
+| Diagram Elements | DF4, DF5 |
+------------------------+------------------------------------------------------+
-| ``Affected TF-A | BL1, BL2, BL31 |
-| Components`` | |
+| Affected TF-A | BL1, BL2, BL31 |
+| Components | |
+------------------------+------------------------------------------------------+
-| ``Assets`` | Code Execution, Sensitive Data |
+| Assets | Code Execution, Sensitive Data |
+------------------------+------------------------------------------------------+
-| ``Threat Agent`` | NSCode, SecCode |
+| Threat Agent | NSCode, SecCode |
+------------------------+------------------------------------------------------+
-| ``Threat Type`` | Tampering, Information Disclosure, |
+| Threat Type | Tampering, Information Disclosure, |
| | Elevation of Privilege |
+------------------------+-------------------+-----------------+----------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+-------------------+-----------------+----------------+
-| ``Impact`` | Critical (5) | Critical (5) | Critical (5) |
+| Impact | Critical (5) | Critical (5) | Critical (5) |
+------------------------+-------------------+-----------------+----------------+
-| ``Likelihood`` | Medium (3 | Medium (3) | Medium (3) |
+| Likelihood | Medium (3 | Medium (3) | Medium (3) |
+------------------------+-------------------+-----------------+----------------+
-| ``Total Risk Rating`` | High (15) | High (15) | High (15) |
+| Total Risk Rating | High (15) | High (15) | High (15) |
+------------------------+-------------------+-----------------+----------------+
-| ``Mitigations`` | | TF-A uses a combination of manual code reviews and |
-| | automated program analysis and testing to detect |
-| | and fix memory corruption bugs. All TF-A code |
-| | including platform code go through manual code |
-| | reviews. Additionally, static code analysis is |
-| | performed using Coverity Scan on all TF-A code. |
-| | The code is also tested with |
-| | `Trusted Firmware-A Tests`_ on Juno and FVP |
-| | platforms. |
+| Mitigations | | 1) Use proper input validation. |
| | |
-| | | Data received from normal world, such as addresses |
+| | | 2) Code reviews, testing. |
++------------------------+------------------------------------------------------+
+| Mitigations | | 1) Yes. |
+| implemented? | Data received from normal world, such as addresses |
| | and sizes identifying memory regions, are |
| | sanitized before being used. These security checks |
| | make sure that the normal world software does not |
@@ -602,48 +677,62 @@
| | option to use *asserts* in release builds, however |
| | we recommend using proper runtime checks instead |
| | of relying on asserts in release builds. |
+| | |
+| | | 2) Yes. |
+| | TF-A uses a combination of manual code reviews |
+| | and automated program analysis and testing to |
+| | detect and fix memory corruption bugs. All TF-A |
+| | code including platform code go through manual |
+| | code reviews. Additionally, static code analysis |
+| | is performed using Coverity Scan on all TF-A code. |
+| | The code is also tested with |
+| | `Trusted Firmware-A Tests`_ on Juno and FVP |
+| | platforms. |
+------------------------+------------------------------------------------------+
+------------------------+------------------------------------------------------+
| ID | 09 |
+========================+======================================================+
-| ``Threat`` | | **Improperly handled SMC calls can leak register |
+| Threat | | **Improperly handled SMC calls can leak register |
| | contents** |
| | |
-| | | When switching between secure and non-secure |
-| | states, register contents of Secure world or |
-| | register contents of other normal world clients |
-| | can be leaked. |
+| | | When switching between worlds, TF-A register state |
+| | can leak to software in different security |
+| | contexts. |
+------------------------+------------------------------------------------------+
-| ``Diagram Elements`` | DF5 |
+| Diagram Elements | DF4, DF5 |
+------------------------+------------------------------------------------------+
-| ``Affected TF-A | BL31 |
-| Components`` | |
+| Affected TF-A | BL31 |
+| Components | |
+------------------------+------------------------------------------------------+
-| ``Assets`` | Sensitive Data |
+| Assets | Sensitive Data |
+------------------------+------------------------------------------------------+
-| ``Threat Agent`` | NSCode |
+| Threat Agent | NSCode, SecCode |
+------------------------+------------------------------------------------------+
-| ``Threat Type`` | Information Disclosure |
+| Threat Type | Information Disclosure |
+------------------------+-------------------+----------------+-----------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+-------------------+----------------+-----------------+
-| ``Impact`` | Medium (3) | Medium (3) | Medium (3) |
+| Impact | Medium (3) | Medium (3) | Medium (3) |
+------------------------+-------------------+----------------+-----------------+
-| ``Likelihood`` | High (4) | High (4) | High (4) |
+| Likelihood | High (4) | High (4) | High (4) |
+------------------------+-------------------+----------------+-----------------+
-| ``Total Risk Rating`` | High (12) | High (12) | High (12) |
+| Total Risk Rating | High (12) | High (12) | High (12) |
+------------------------+-------------------+----------------+-----------------+
-| ``Mitigations`` | | TF-A saves and restores registers |
-| | by default when switching contexts. Build options |
-| | are also provided to save/restore additional |
-| | registers such as floating-point registers. |
+| Mitigations | Save and restore registers when switching contexts. |
++------------------------+------------------------------------------------------+
+| Mitigations | | Yes. |
+| implemented? | |
+| | | This is the default behaviour in TF-A. |
+| | Build options are also provided to save/restore |
+| | additional registers such as floating-point |
+| | registers. These should be enabled if required. |
+------------------------+------------------------------------------------------+
+------------------------+-----------------------------------------------------+
| ID | 10 |
+========================+=====================================================+
-| ``Threat`` | | **SMC calls can leak sensitive information from |
+| Threat | | **SMC calls can leak sensitive information from |
| | TF-A memory via microarchitectural side channels**|
| | |
| | | Microarchitectural side-channel attacks such as |
@@ -652,36 +741,42 @@
| | use this kind of attack to leak sensitive |
| | data from TF-A memory. |
+------------------------+-----------------------------------------------------+
-| ``Diagram Elements`` | DF4, DF5 |
+| Diagram Elements | DF4, DF5 |
+------------------------+-----------------------------------------------------+
-| ``Affected TF-A | BL31 |
-| Components`` | |
+| Affected TF-A | BL31 |
+| Components | |
+------------------------+-----------------------------------------------------+
-| ``Assets`` | Sensitive Data |
+| Assets | Sensitive Data |
+------------------------+-----------------------------------------------------+
-| ``Threat Agent`` | SecCode, NSCode |
+| Threat Agent | SecCode, NSCode |
+------------------------+-----------------------------------------------------+
-| ``Threat Type`` | Information Disclosure |
+| Threat Type | Information Disclosure |
+------------------------+-------------------+----------------+----------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+-------------------+----------------+----------------+
-| ``Impact`` | Medium (3) | Medium (3) | Medium (3) |
+| Impact | Medium (3) | Medium (3) | Medium (3) |
+------------------------+-------------------+----------------+----------------+
-| ``Likelihood`` | Medium (3) | Medium (3) | Medium (3) |
+| Likelihood | Medium (3) | Medium (3) | Medium (3) |
+------------------------+-------------------+----------------+----------------+
-| ``Total Risk Rating`` | Medium (9) | Medium (9) | Medium (9) |
+| Total Risk Rating | Medium (9) | Medium (9) | Medium (9) |
+------------------------+-------------------+----------------+----------------+
-| ``Mitigations`` | | TF-A implements software mitigations for Spectre |
+| Mitigations | Enable appropriate side-channel protections. |
++------------------------+-----------------------------------------------------+
+| Mitigations | | Yes / Platform specific. |
+| implemented? | |
+| | | TF-A implements software mitigations for Spectre |
| | type attacks as recommended by `Cache Speculation |
-| | Side-channels`_ for the generic code. SiPs should |
-| | implement similar mitigations for code that is |
-| | deemed to be vulnerable to such attacks. |
+| | Side-channels`_ for the generic code. |
+| | |
+| | | SiPs should implement similar mitigations for |
+| | code that is deemed to be vulnerable to such |
+| | attacks. |
+------------------------+-----------------------------------------------------+
+------------------------+----------------------------------------------------+
| ID | 11 |
+========================+====================================================+
-| ``Threat`` | | **Misconfiguration of the Memory Management Unit |
+| Threat | | **Misconfiguration of the Memory Management Unit |
| | (MMU) may allow a normal world software to |
| | access sensitive data or execute arbitrary |
| | code** |
@@ -692,44 +787,50 @@
| | execute code if the proper security mechanisms |
| | are not in place. |
+------------------------+----------------------------------------------------+
-| ``Diagram Elements`` | DF5, DF6 |
+| Diagram Elements | DF5, DF6 |
+------------------------+----------------------------------------------------+
-| ``Affected TF-A | BL1, BL2, BL31 |
-| Components`` | |
+| Affected TF-A | BL1, BL2, BL31 |
+| Components | |
+------------------------+----------------------------------------------------+
-| ``Assets`` | Sensitive Data, Code execution |
+| Assets | Sensitive Data, Code execution |
+------------------------+----------------------------------------------------+
-| ``Threat Agent`` | NSCode |
+| Threat Agent | NSCode |
+------------------------+----------------------------------------------------+
-| ``Threat Type`` | Information Disclosure, Elevation of Privilege |
+| Threat Type | Information Disclosure, Elevation of Privilege |
+------------------------+-----------------+-----------------+----------------+
-| ``Application`` | ``Server`` | ``IoT`` | ``Mobile`` |
+| Application | Server | IoT | Mobile |
+------------------------+-----------------+-----------------+----------------+
-| ``Impact`` | Critical (5) | Critical (5) | Critical (5) |
+| Impact | Critical (5) | Critical (5) | Critical (5) |
+------------------------+-----------------+-----------------+----------------+
-| ``Likelihood`` | High (4) | High (4) | High (4) |
+| Likelihood | High (4) | High (4) | High (4) |
+------------------------+-----------------+-----------------+----------------+
-| ``Total Risk Rating`` | Critical (20) | Critical (20) | Critical (20) |
+| Total Risk Rating | Critical (20) | Critical (20) | Critical (20) |
+------------------------+-----------------+-----------------+----------------+
-| ``Mitigations`` | | In TF-A, configuration of the MMU is done |
-| | through a translation tables library. The |
-| | library provides APIs to define memory regions |
-| | and assign attributes including memory types and |
-| | access permissions. Memory configurations are |
-| | platform specific, therefore platforms need make |
-| | sure the correct attributes are assigned to |
-| | memory regions. When assigning access |
-| | permissions, principle of least privilege ought |
-| | to be enforced, i.e. we should not grant more |
-| | privileges than strictly needed, e.g. code |
-| | should be read-only executable, RO data should |
-| | be read-only XN, and so on. |
+| Mitigations | When configuring access permissions, the |
+| | principle of least privilege ought to be |
+| | enforced. This means we should not grant more |
+| | privileges than strictly needed, e.g. code |
+| | should be read-only executable, read-only data |
+| | should be read-only execute-never, and so on. |
++------------------------+----------------------------------------------------+
+| Mitigations | | Platform specific. |
+| implemented? | |
+| | | MMU configuration is platform specific, |
+| | therefore platforms need to make sure that the |
+| | correct attributes are assigned to memory |
+| | regions. |
+| | |
+| | | TF-A provides a library which abstracts the |
+| | low-level details of MMU configuration. It |
+| | provides well-defined and tested APIs. |
+| | Platforms are encouraged to use it to limit the |
+| | risk of misconfiguration. |
+------------------------+----------------------------------------------------+
+------------------------+-----------------------------------------------------+
| ID | 12 |
+========================+=====================================================+
-| ``Threat`` | | **Incorrect configuration of Performance Monitor |
+| Threat | | **Incorrect configuration of Performance Monitor |
| | Unit (PMU) counters can allow an attacker to |
| | mount side-channel attacks using information |
| | exposed by the counters** |
@@ -738,43 +839,50 @@
| | to count events at any exception level and in |
| | both Secure and Non-secure states. This allows |
| | a Non-secure software (or a lower-level Secure |
-| | software) to potentially carry out |
+| | software) to potentially carry out |
| | side-channel timing attacks against TF-A. |
+------------------------+-----------------------------------------------------+
-| ``Diagram Elements`` | DF5, DF6 |
+| Diagram Elements | DF5, DF6 |
+------------------------+-----------------------------------------------------+
-| ``Affected TF-A | BL31 |
-| Components`` | |
+| Affected TF-A | BL31 |
+| Components | |
+------------------------+-----------------------------------------------------+
-| ``Assets`` | Sensitive Data |
+| Assets | Sensitive Data |
+------------------------+-----------------------------------------------------+
-| ``Threat Agent`` | NSCode |
+| Threat Agent | NSCode |
+------------------------+-----------------------------------------------------+
-| ``Threat Type`` | Information Disclosure |
+| Threat Type | Information Disclosure |
+------------------------+-------------------+----------------+----------------+
-| ``Impact`` | Medium (3) | Medium (3) | Medium (3) |
+| Impact | Medium (3) | Medium (3) | Medium (3) |
+------------------------+-------------------+----------------+----------------+
-| ``Likelihood`` | Low (2) | Low (2) | Low (2) |
+| Likelihood | Low (2) | Low (2) | Low (2) |
+------------------------+-------------------+----------------+----------------+
-| ``Total Risk Rating`` | Medium (6) | Medium (6) | Medium (6) |
+| Total Risk Rating | Medium (6) | Medium (6) | Medium (6) |
+------------------------+-------------------+----------------+----------------+
-| ``Mitigations`` | | TF-A follows mitigation strategies as described |
-| | in `Secure Development Guidelines`_. General |
-| | events and cycle counting in the Secure world is |
-| | prohibited by default when applicable. However, |
-| | on some implementations (e.g. PMUv3) Secure world |
-| | event counting depends on external debug interface|
-| | signals, i.e. Secure world event counting is |
-| | enabled if external debug is enabled. |
-| | Configuration of debug signals is platform |
+| Mitigations | Follow mitigation strategies as described in |
+| | `Secure Development Guidelines`_. |
++------------------------+-----------------------------------------------------+
+| Mitigations | | Yes / platform specific. |
+| implemented? | |
+| | | General events and cycle counting in the Secure |
+| | world is prohibited by default when applicable. |
+| | |
+| | | However, on some implementations (e.g. PMUv3) |
+| | Secure world event counting depends on external |
+| | debug interface signals, i.e. Secure world event |
+| | counting is enabled if external debug is enabled. |
+| | |
+| | | Configuration of debug signals is platform |
| | specific, therefore platforms need to make sure |
| | that external debug is disabled in production or |
-| | proper debug authentication is in place. |
+| | proper debug authentication is in place. This |
+| | should be the case if threat #06 is properly |
+| | mitigated. |
+------------------------+-----------------------------------------------------+
--------------
-*Copyright (c) 2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2022, Arm Limited. All rights reserved.*
.. _STRIDE threat analysis technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c
index aaef485..75eb69a 100644
--- a/drivers/arm/gic/v3/gic-x00.c
+++ b/drivers/arm/gic/v3/gic-x00.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -42,6 +42,8 @@
#define PWRR_ON (0U << PWRR_RDPD_SHIFT)
#define PWRR_OFF (1U << PWRR_RDPD_SHIFT)
+static bool gic600_errata_wa_2384374 __unused;
+
#if GICV3_SUPPORT_GIC600
/* GIC-600/700 specific accessor functions */
@@ -170,3 +172,60 @@
}
#endif
}
+
+#if GIC600_ERRATA_WA_2384374
+/*******************************************************************************
+ * Apply part 2 of workaround for errata-2384374 as per SDEN:
+ * https://developer.arm.com/documentation/sden892601/latest/
+ ******************************************************************************/
+void gicv3_apply_errata_wa_2384374(uintptr_t gicr_base)
+{
+ if (gic600_errata_wa_2384374) {
+ uint32_t gicr_ctlr_val = gicr_read_ctlr(gicr_base);
+
+ gicr_write_ctlr(gicr_base, gicr_ctlr_val |
+ (GICR_CTLR_DPG0_BIT | GICR_CTLR_DPG1NS_BIT |
+ GICR_CTLR_DPG1S_BIT));
+ gicr_write_ctlr(gicr_base, gicr_ctlr_val &
+ ~(GICR_CTLR_DPG0_BIT | GICR_CTLR_DPG1NS_BIT |
+ GICR_CTLR_DPG1S_BIT));
+ }
+}
+#endif /* GIC600_ERRATA_WA_2384374 */
+
+void gicv3_check_erratas_applies(uintptr_t gicd_base)
+{
+ unsigned int gic_prod_id;
+ uint8_t gic_rev;
+
+ assert(gicd_base != 0UL);
+
+ gicv3_get_component_prodid_rev(gicd_base, &gic_prod_id, &gic_rev);
+
+ /*
+ * This workaround applicable only to GIC600 and GIC600AE products with
+ * revision less than r1p6 and r0p2 respectively.
+ * As per GIC600/GIC600AE specification -
+ * r1p6 = 0x17 => GICD_IIDR[19:12]
+ * r0p2 = 0x04 => GICD_IIDR[19:12]
+ */
+ if ((gic_prod_id == GIC_PRODUCT_ID_GIC600) ||
+ (gic_prod_id == GIC_PRODUCT_ID_GIC600AE)) {
+ if (((gic_prod_id == GIC_PRODUCT_ID_GIC600) &&
+ (gic_rev <= GIC_REV(GIC_VARIANT_R1, GIC_REV_P6))) ||
+ ((gic_prod_id == GIC_PRODUCT_ID_GIC600AE) &&
+ (gic_rev <= GIC_REV(GIC_VARIANT_R0, GIC_REV_P2)))) {
+#if GIC600_ERRATA_WA_2384374
+ gic600_errata_wa_2384374 = true;
+ VERBOSE("%s applies\n",
+ "GIC600/GIC600AE errata workaround 2384374");
+#else
+ WARN("%s missing\n",
+ "GIC600/GIC600AE errata workaround 2384374");
+#endif /* GIC600_ERRATA_WA_2384374 */
+ } else {
+ VERBOSE("%s not applies\n",
+ "GIC600/GIC600AE errata workaround 2384374");
+ }
+ }
+}
diff --git a/drivers/arm/gic/v3/gic600ae_fmu.c b/drivers/arm/gic/v3/gic600ae_fmu.c
index 13979fa..0262f48 100644
--- a/drivers/arm/gic/v3/gic600ae_fmu.c
+++ b/drivers/arm/gic/v3/gic600ae_fmu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
*/
#include <assert.h>
+#include <inttypes.h>
#include <arch_helpers.h>
#include <common/debug.h>
@@ -112,6 +113,135 @@
"Wake-GICD AXI4-Stream interface error"
};
+/* Helper function to find detailed information for a specific IERR */
+static char __unused *ras_ierr_to_str(unsigned int blkid, unsigned int ierr)
+{
+ char *str = NULL;
+
+ /* Find the correct record */
+ switch (blkid) {
+ case FMU_BLK_GICD:
+ assert(ierr < ARRAY_SIZE(gicd_sm_info));
+ str = gicd_sm_info[ierr];
+ break;
+
+ case FMU_BLK_SPICOL:
+ assert(ierr < ARRAY_SIZE(spicol_sm_info));
+ str = spicol_sm_info[ierr];
+ break;
+
+ case FMU_BLK_WAKERQ:
+ assert(ierr < ARRAY_SIZE(wkrqst_sm_info));
+ str = wkrqst_sm_info[ierr];
+ break;
+
+ case FMU_BLK_ITS0...FMU_BLK_ITS7:
+ assert(ierr < ARRAY_SIZE(its_sm_info));
+ str = its_sm_info[ierr];
+ break;
+
+ case FMU_BLK_PPI0...FMU_BLK_PPI31:
+ assert(ierr < ARRAY_SIZE(ppi_sm_info));
+ str = ppi_sm_info[ierr];
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+
+ return str;
+}
+
+/*
+ * Probe for error in memory-mapped registers containing error records.
+ * Upon detecting an error, set probe data to the index of the record
+ * in error, and return 1; otherwise, return 0.
+ */
+int gic600_fmu_probe(uint64_t base, int *probe_data)
+{
+ uint64_t gsr;
+
+ assert(base != 0UL);
+
+ /*
+ * Read ERR_GSR to find the error record 'M'
+ */
+ gsr = gic_fmu_read_errgsr(base);
+ if (gsr == U(0)) {
+ return 0;
+ }
+
+ /* Return the index of the record in error */
+ if (probe_data != NULL) {
+ *probe_data = (int)__builtin_ctzll(gsr);
+ }
+
+ return 1;
+}
+
+/*
+ * The handler function to read RAS records and find the safety
+ * mechanism with the error.
+ */
+int gic600_fmu_ras_handler(uint64_t base, int probe_data)
+{
+ uint64_t errstatus;
+ unsigned int blkid = (unsigned int)probe_data, ierr, serr;
+
+ assert(base != 0UL);
+
+ /*
+ * FMU_ERRGSR indicates the ID of the GIC
+ * block that faulted.
+ */
+ assert(blkid <= FMU_BLK_PPI31);
+
+ /*
+ * Find more information by reading FMU_ERR<M>STATUS
+ * register
+ */
+ errstatus = gic_fmu_read_errstatus(base, blkid);
+
+ /*
+ * If FMU_ERR<M>STATUS.V is set to 0, no RAS records
+ * need to be scanned.
+ */
+ if ((errstatus & FMU_ERRSTATUS_V_BIT) == U(0)) {
+ return 0;
+ }
+
+ /*
+ * FMU_ERR<M>STATUS.IERR indicates which Safety Mechanism
+ * reported the error.
+ */
+ ierr = (errstatus >> FMU_ERRSTATUS_IERR_SHIFT) &
+ FMU_ERRSTATUS_IERR_MASK;
+
+ /*
+ * FMU_ERR<M>STATUS.SERR indicates architecturally
+ * defined primary error code.
+ */
+ serr = errstatus & FMU_ERRSTATUS_SERR_MASK;
+
+ ERROR("**************************************\n");
+ ERROR("RAS %s Error detected by GIC600 AE FMU\n",
+ ((errstatus & FMU_ERRSTATUS_UE_BIT) != 0U) ?
+ "Uncorrectable" : "Corrected");
+ ERROR("\tStatus = 0x%lx \n", errstatus);
+ ERROR("\tBlock ID = 0x%x\n", blkid);
+ ERROR("\tSafety Mechanism ID = 0x%x (%s)\n", ierr,
+ ras_ierr_to_str(blkid, ierr));
+ ERROR("\tArchitecturally defined primary error code = 0x%x\n",
+ serr);
+ ERROR("**************************************\n");
+
+ /* Clear FMU_ERR<M>STATUS */
+ gic_fmu_write_errstatus(base, probe_data, errstatus);
+
+ return 0;
+}
+
/*
* Initialization sequence for the FMU
*
@@ -138,8 +268,12 @@
/* Enable error detection for all error records */
for (unsigned int i = 0U; i < num_blk; i++) {
- /* Skip next steps if the block is not present */
+ /*
+ * Disable all safety mechanisms for blocks that are not
+ * present and skip the next steps.
+ */
if ((blk_present_mask & BIT(i)) == 0U) {
+ gic_fmu_disable_all_sm_blkid(base, i);
continue;
}
@@ -168,22 +302,26 @@
*/
if ((blk_present_mask & BIT(FMU_BLK_GICD)) != 0U) {
smen = (GICD_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
- (FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT);
+ (FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT) |
+ FMU_SMEN_EN_BIT;
gic_fmu_write_smen(base, smen);
smen = (GICD_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
- (FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT);
+ (FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT) |
+ FMU_SMEN_EN_BIT;
gic_fmu_write_smen(base, smen);
}
for (unsigned int i = FMU_BLK_PPI0; i < FMU_BLK_PPI31; i++) {
if ((blk_present_mask & BIT(i)) != 0U) {
smen = (PPI_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
- (i << FMU_SMEN_BLK_SHIFT);
+ (i << FMU_SMEN_BLK_SHIFT) |
+ FMU_SMEN_EN_BIT;
gic_fmu_write_smen(base, smen);
smen = (PPI_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
- (i << FMU_SMEN_BLK_SHIFT);
+ (i << FMU_SMEN_BLK_SHIFT) |
+ FMU_SMEN_EN_BIT;
gic_fmu_write_smen(base, smen);
}
}
@@ -191,11 +329,13 @@
for (unsigned int i = FMU_BLK_ITS0; i < FMU_BLK_ITS7; i++) {
if ((blk_present_mask & BIT(i)) != 0U) {
smen = (ITS_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) |
- (i << FMU_SMEN_BLK_SHIFT);
+ (i << FMU_SMEN_BLK_SHIFT) |
+ FMU_SMEN_EN_BIT;
gic_fmu_write_smen(base, smen);
smen = (ITS_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) |
- (i << FMU_SMEN_BLK_SHIFT);
+ (i << FMU_SMEN_BLK_SHIFT) |
+ FMU_SMEN_EN_BIT;
gic_fmu_write_smen(base, smen);
}
}
diff --git a/drivers/arm/gic/v3/gic600ae_fmu_helpers.c b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c
index 4aa0efb..09806dc 100644
--- a/drivers/arm/gic/v3/gic600ae_fmu_helpers.c
+++ b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -258,3 +258,47 @@
{
GIC_FMU_WRITE_64(base, GICFMU_PINGMASK, 0, val);
}
+
+/*
+ * Helper function to disable all safety mechanisms for a given block
+ */
+void gic_fmu_disable_all_sm_blkid(uintptr_t base, unsigned int blkid)
+{
+ uint32_t smen, max_smid = U(0);
+
+ /* Sanity check block ID */
+ assert((blkid >= FMU_BLK_GICD) && (blkid <= FMU_BLK_PPI31));
+
+ /* Find the max safety mechanism ID for the block */
+ switch (blkid) {
+ case FMU_BLK_GICD:
+ max_smid = FMU_SMID_GICD_MAX;
+ break;
+
+ case FMU_BLK_SPICOL:
+ max_smid = FMU_SMID_SPICOL_MAX;
+ break;
+
+ case FMU_BLK_WAKERQ:
+ max_smid = FMU_SMID_WAKERQ_MAX;
+ break;
+
+ case FMU_BLK_ITS0...FMU_BLK_ITS7:
+ max_smid = FMU_SMID_ITS_MAX;
+ break;
+
+ case FMU_BLK_PPI0...FMU_BLK_PPI31:
+ max_smid = FMU_SMID_PPI_MAX;
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+
+ /* Disable all Safety Mechanisms for a given block id */
+ for (unsigned int i = 0U; i < max_smid; i++) {
+ smen = (blkid << FMU_SMEN_BLK_SHIFT) | (i << FMU_SMEN_SMID_SHIFT);
+ gic_fmu_write_smen(base, smen);
+ }
+}
diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk
index d7e3536..1d20ff3 100644
--- a/drivers/arm/gic/v3/gicv3.mk
+++ b/drivers/arm/gic/v3/gicv3.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
# Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
@@ -12,6 +12,7 @@
GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0
GIC_ENABLE_V4_EXTN ?= 0
GIC_EXT_INTID ?= 0
+GIC600_ERRATA_WA_2384374 ?= ${GICV3_SUPPORT_GIC600}
GICV3_SOURCES += drivers/arm/gic/v3/gicv3_main.c \
drivers/arm/gic/v3/gicv3_helpers.c \
@@ -47,3 +48,7 @@
# Set support for extended PPI and SPI range
$(eval $(call assert_boolean,GIC_EXT_INTID))
$(eval $(call add_define,GIC_EXT_INTID))
+
+# Set errata workaround for GIC600/GIC600AE
+$(eval $(call assert_boolean,GIC600_ERRATA_WA_2384374))
+$(eval $(call add_define,GIC600_ERRATA_WA_2384374))
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index 753d995..f3852d2 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -408,3 +408,34 @@
return part_id;
}
+
+/*******************************************************************************
+ * Helper function to return product ID and revision of GIC
+ * @gicd_base: base address of the GIC distributor
+ * @gic_prod_id: retrieved product id of GIC
+ * @gic_rev: retrieved revision of GIC
+ ******************************************************************************/
+void gicv3_get_component_prodid_rev(const uintptr_t gicd_base,
+ unsigned int *gic_prod_id,
+ uint8_t *gic_rev)
+{
+ unsigned int gicd_iidr;
+ uint8_t gic_variant;
+
+ gicd_iidr = gicd_read_iidr(gicd_base);
+ *gic_prod_id = gicd_iidr >> IIDR_PRODUCT_ID_SHIFT;
+ *gic_prod_id &= IIDR_PRODUCT_ID_MASK;
+
+ gic_variant = gicd_iidr >> IIDR_VARIANT_SHIFT;
+ gic_variant &= IIDR_VARIANT_MASK;
+
+ *gic_rev = gicd_iidr >> IIDR_REV_SHIFT;
+ *gic_rev &= IIDR_REV_MASK;
+
+ /*
+ * pack gic variant and gic_rev in 1 byte
+ * gic_rev = gic_variant[7:4] and gic_rev[0:3]
+ */
+ *gic_rev = *gic_rev | gic_variant << 0x4;
+
+}
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 53a8fae..8ead43b 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -169,6 +169,8 @@
flush_dcache_range((uintptr_t)gicv3_driver_data,
sizeof(*gicv3_driver_data));
#endif
+ gicv3_check_erratas_applies(plat_driver_data->gicd_base);
+
INFO("GICv%u with%s legacy support detected.\n", gic_version,
(gicv2_compat == 0U) ? "" : "out");
INFO("ARM GICv%u driver initialized in EL3\n", gic_version);
@@ -362,9 +364,17 @@
/* Add DSB to ensure visibility of System register writes */
dsb();
- /* Mark the connected core as asleep */
gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
- assert(gicr_base != 0U);
+ assert(gicr_base != 0UL);
+
+ /*
+ * dsb() already issued previously after clearing the CPU group
+ * enabled, apply below workaround to toggle the "DPG*"
+ * bits of GICR_CTLR register for unblocking event.
+ */
+ gicv3_apply_errata_wa_2384374(gicr_base);
+
+ /* Mark the connected core as asleep */
gicv3_rdistif_mark_core_asleep(gicr_base);
}
diff --git a/drivers/arm/mhu/mhu_v2_x.c b/drivers/arm/mhu/mhu_v2_x.c
new file mode 100644
index 0000000..3103b92
--- /dev/null
+++ b/drivers/arm/mhu/mhu_v2_x.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "mhu_v2_x.h"
+
+#define MHU_V2_X_MAX_CHANNELS 124
+#define MHU_V2_1_MAX_CHCOMB_INT 4
+#define ENABLE 0x1
+#define DISABLE 0x0
+#define CLEAR_INTR 0x1
+#define CH_PER_CH_COMB 0x20
+#define SEND_FRAME(p_mhu) ((struct mhu_v2_x_send_frame_t *)p_mhu)
+#define RECV_FRAME(p_mhu) ((struct mhu_v2_x_recv_frame_t *)p_mhu)
+
+#define MHU_MAJOR_REV_V2 0x1u
+#define MHU_MINOR_REV_2_0 0x0u
+#define MHU_MINOR_REV_2_1 0x1u
+
+struct mhu_v2_x_send_ch_window_t {
+ /* Offset: 0x00 (R/ ) Channel Status */
+ volatile uint32_t ch_st;
+ /* Offset: 0x04 (R/ ) Reserved */
+ volatile uint32_t reserved_0;
+ /* Offset: 0x08 (R/ ) Reserved */
+ volatile uint32_t reserved_1;
+ /* Offset: 0x0C ( /W) Channel Set */
+ volatile uint32_t ch_set;
+ /* Offset: 0x10 (R/ ) Channel Interrupt Status (Reserved in 2.0) */
+ volatile uint32_t ch_int_st;
+ /* Offset: 0x14 ( /W) Channel Interrupt Clear (Reserved in 2.0) */
+ volatile uint32_t ch_int_clr;
+ /* Offset: 0x18 (R/W) Channel Interrupt Enable (Reserved in 2.0) */
+ volatile uint32_t ch_int_en;
+ /* Offset: 0x1C (R/ ) Reserved */
+ volatile uint32_t reserved_2;
+};
+
+struct mhu_v2_x_send_frame_t {
+ /* Offset: 0x000 ( / ) Sender Channel Window 0 -123 */
+ struct mhu_v2_x_send_ch_window_t send_ch_window[MHU_V2_X_MAX_CHANNELS];
+ /* Offset: 0xF80 (R/ ) Message Handling Unit Configuration */
+ volatile uint32_t mhu_cfg;
+ /* Offset: 0xF84 (R/W) Response Configuration */
+ volatile uint32_t resp_cfg;
+ /* Offset: 0xF88 (R/W) Access Request */
+ volatile uint32_t access_request;
+ /* Offset: 0xF8C (R/ ) Access Ready */
+ volatile uint32_t access_ready;
+ /* Offset: 0xF90 (R/ ) Interrupt Status */
+ volatile uint32_t int_st;
+ /* Offset: 0xF94 ( /W) Interrupt Clear */
+ volatile uint32_t int_clr;
+ /* Offset: 0xF98 (R/W) Interrupt Enable */
+ volatile uint32_t int_en;
+ /* Offset: 0xF9C (R/ ) Reserved */
+ volatile uint32_t reserved_0;
+ /* Offset: 0xFA0 (R/W) Channel Combined IRQ Stat (Reserved in 2.0) */
+ volatile uint32_t ch_comb_int_st[MHU_V2_1_MAX_CHCOMB_INT];
+ /* Offset: 0xFC4 (R/ ) Reserved */
+ volatile uint32_t reserved_1[6];
+ /* Offset: 0xFC8 (R/ ) Implementer Identification Register */
+ volatile uint32_t iidr;
+ /* Offset: 0xFCC (R/ ) Architecture Identification Register */
+ volatile uint32_t aidr;
+ /* Offset: 0xFD0 (R/ ) */
+ volatile uint32_t pid_1[4];
+ /* Offset: 0xFE0 (R/ ) */
+ volatile uint32_t pid_0[4];
+ /* Offset: 0xFF0 (R/ ) */
+ volatile uint32_t cid[4];
+};
+
+struct mhu_v2_x_rec_ch_window_t {
+ /* Offset: 0x00 (R/ ) Channel Status */
+ volatile uint32_t ch_st;
+ /* Offset: 0x04 (R/ ) Channel Status Masked */
+ volatile uint32_t ch_st_msk;
+ /* Offset: 0x08 ( /W) Channel Clear */
+ volatile uint32_t ch_clr;
+ /* Offset: 0x0C (R/ ) Reserved */
+ volatile uint32_t reserved_0;
+ /* Offset: 0x10 (R/ ) Channel Mask Status */
+ volatile uint32_t ch_msk_st;
+ /* Offset: 0x14 ( /W) Channel Mask Set */
+ volatile uint32_t ch_msk_set;
+ /* Offset: 0x18 ( /W) Channel Mask Clear */
+ volatile uint32_t ch_msk_clr;
+ /* Offset: 0x1C (R/ ) Reserved */
+ volatile uint32_t reserved_1;
+};
+
+struct mhu_v2_x_recv_frame_t {
+ /* Offset: 0x000 ( / ) Receiver Channel Window 0 -123 */
+ struct mhu_v2_x_rec_ch_window_t rec_ch_window[MHU_V2_X_MAX_CHANNELS];
+ /* Offset: 0xF80 (R/ ) Message Handling Unit Configuration */
+ volatile uint32_t mhu_cfg;
+ /* Offset: 0xF84 (R/ ) Reserved */
+ volatile uint32_t reserved_0[3];
+ /* Offset: 0xF90 (R/ ) Interrupt Status (Reserved in 2.0) */
+ volatile uint32_t int_st;
+ /* Offset: 0xF94 (R/ ) Interrupt Clear (Reserved in 2.0) */
+ volatile uint32_t int_clr;
+ /* Offset: 0xF98 (R/W) Interrupt Enable (Reserved in 2.0) */
+ volatile uint32_t int_en;
+ /* Offset: 0xF9C (R/ ) Reserved */
+ volatile uint32_t reserved_1;
+ /* Offset: 0xFA0 (R/ ) Channel Combined IRQ Stat (Reserved in 2.0) */
+ volatile uint32_t ch_comb_int_st[MHU_V2_1_MAX_CHCOMB_INT];
+ /* Offset: 0xFB0 (R/ ) Reserved */
+ volatile uint32_t reserved_2[6];
+ /* Offset: 0xFC8 (R/ ) Implementer Identification Register */
+ volatile uint32_t iidr;
+ /* Offset: 0xFCC (R/ ) Architecture Identification Register */
+ volatile uint32_t aidr;
+ /* Offset: 0xFD0 (R/ ) */
+ volatile uint32_t pid_1[4];
+ /* Offset: 0xFE0 (R/ ) */
+ volatile uint32_t pid_0[4];
+ /* Offset: 0xFF0 (R/ ) */
+ volatile uint32_t cid[4];
+};
+
+union mhu_v2_x_frame {
+ struct mhu_v2_x_send_frame_t send_frame;
+ struct mhu_v2_x_recv_frame_t recv_frame;
+};
+
+enum mhu_v2_x_error_t mhu_v2_x_driver_init(struct mhu_v2_x_dev_t *dev,
+ enum mhu_v2_x_supported_revisions rev)
+{
+ uint32_t AIDR = 0;
+ union mhu_v2_x_frame *p_mhu;
+
+ assert(dev != NULL);
+
+ p_mhu = (union mhu_v2_x_frame *)dev->base;
+
+ if (dev->is_initialized) {
+ return MHU_V_2_X_ERR_ALREADY_INIT;
+ }
+
+ if (rev == MHU_REV_READ_FROM_HW) {
+ /* Read revision from HW */
+ if (dev->frame == MHU_V2_X_RECEIVER_FRAME) {
+ AIDR = p_mhu->recv_frame.aidr;
+ } else {
+ AIDR = p_mhu->send_frame.aidr;
+ }
+
+ /* Get bits 7:4 to read major revision */
+ if (((AIDR >> 4) & 0b1111) != MHU_MAJOR_REV_V2) {
+ /* Unsupported MHU version */
+ return MHU_V_2_X_ERR_UNSUPPORTED_VERSION;
+ } /* No need to save major version, driver only supports MHUv2 */
+
+ /* Get bits 3:0 to read minor revision */
+ dev->subversion = AIDR & 0b1111;
+
+ if (dev->subversion != MHU_MINOR_REV_2_0 &&
+ dev->subversion != MHU_MINOR_REV_2_1) {
+ /* Unsupported subversion */
+ return MHU_V_2_X_ERR_UNSUPPORTED_VERSION;
+ }
+ } else {
+ /* Revisions were provided by caller */
+ if (rev == MHU_REV_2_0) {
+ dev->subversion = MHU_MINOR_REV_2_0;
+ } else if (rev == MHU_REV_2_1) {
+ dev->subversion = MHU_MINOR_REV_2_1;
+ } else {
+ /* Unsupported subversion */
+ return MHU_V_2_X_ERR_UNSUPPORTED_VERSION;
+ } /* No need to save major version, driver only supports MHUv2 */
+ }
+
+ dev->is_initialized = true;
+
+ return MHU_V_2_X_ERR_NONE;
+}
+
+uint32_t mhu_v2_x_get_num_channel_implemented(const struct mhu_v2_x_dev_t *dev)
+{
+ union mhu_v2_x_frame *p_mhu;
+
+ assert(dev != NULL);
+
+ p_mhu = (union mhu_v2_x_frame *)dev->base;
+
+ if (!(dev->is_initialized)) {
+ return MHU_V_2_X_ERR_NOT_INIT;
+ }
+
+ if (dev->frame == MHU_V2_X_SENDER_FRAME) {
+ return (SEND_FRAME(p_mhu))->mhu_cfg;
+ } else {
+ assert(dev->frame == MHU_V2_X_RECEIVER_FRAME);
+ return (RECV_FRAME(p_mhu))->mhu_cfg;
+ }
+}
+
+enum mhu_v2_x_error_t mhu_v2_x_channel_send(const struct mhu_v2_x_dev_t *dev,
+ uint32_t channel, uint32_t val)
+{
+ union mhu_v2_x_frame *p_mhu;
+
+ assert(dev != NULL);
+
+ p_mhu = (union mhu_v2_x_frame *)dev->base;
+
+ if (!(dev->is_initialized)) {
+ return MHU_V_2_X_ERR_NOT_INIT;
+ }
+
+ if (dev->frame == MHU_V2_X_SENDER_FRAME) {
+ (SEND_FRAME(p_mhu))->send_ch_window[channel].ch_set = val;
+ return MHU_V_2_X_ERR_NONE;
+ } else {
+ return MHU_V_2_X_ERR_INVALID_ARG;
+ }
+}
+
+enum mhu_v2_x_error_t mhu_v2_x_channel_poll(const struct mhu_v2_x_dev_t *dev,
+ uint32_t channel, uint32_t *value)
+{
+ union mhu_v2_x_frame *p_mhu;
+
+ assert(dev != NULL);
+
+ p_mhu = (union mhu_v2_x_frame *)dev->base;
+
+ if (!(dev->is_initialized)) {
+ return MHU_V_2_X_ERR_NOT_INIT;
+ }
+
+ if (dev->frame == MHU_V2_X_SENDER_FRAME) {
+ *value = (SEND_FRAME(p_mhu))->send_ch_window[channel].ch_st;
+ return MHU_V_2_X_ERR_NONE;
+ } else {
+ return MHU_V_2_X_ERR_INVALID_ARG;
+ }
+}
+
+enum mhu_v2_x_error_t mhu_v2_x_channel_clear(const struct mhu_v2_x_dev_t *dev,
+ uint32_t channel)
+{
+ union mhu_v2_x_frame *p_mhu;
+
+ assert(dev != NULL);
+
+ p_mhu = (union mhu_v2_x_frame *)dev->base;
+
+ if (!(dev->is_initialized)) {
+ return MHU_V_2_X_ERR_NOT_INIT;
+ }
+
+ if (dev->frame == MHU_V2_X_RECEIVER_FRAME) {
+ (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_clr = UINT32_MAX;
+ return MHU_V_2_X_ERR_NONE;
+ } else {
+ return MHU_V_2_X_ERR_INVALID_ARG;
+ }
+}
+
+enum mhu_v2_x_error_t mhu_v2_x_channel_receive(
+ const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t *value)
+{
+ union mhu_v2_x_frame *p_mhu;
+
+ assert(dev != NULL);
+
+ p_mhu = (union mhu_v2_x_frame *)dev->base;
+
+ if (!(dev->is_initialized)) {
+ return MHU_V_2_X_ERR_NOT_INIT;
+ }
+
+ if (dev->frame == MHU_V2_X_RECEIVER_FRAME) {
+ *value = (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_st;
+ return MHU_V_2_X_ERR_NONE;
+ } else {
+ return MHU_V_2_X_ERR_INVALID_ARG;
+ }
+}
+
+enum mhu_v2_x_error_t mhu_v2_x_channel_mask_set(
+ const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask)
+{
+ union mhu_v2_x_frame *p_mhu;
+
+ assert(dev != NULL);
+
+ p_mhu = (union mhu_v2_x_frame *)dev->base;
+
+ if (!(dev->is_initialized)) {
+ return MHU_V_2_X_ERR_NOT_INIT;
+ }
+
+ if (dev->frame == MHU_V2_X_RECEIVER_FRAME) {
+ (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_msk_set = mask;
+ return MHU_V_2_X_ERR_NONE;
+ } else {
+ return MHU_V_2_X_ERR_INVALID_ARG;
+ }
+}
+
+enum mhu_v2_x_error_t mhu_v2_x_channel_mask_clear(
+ const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask)
+{
+ union mhu_v2_x_frame *p_mhu;
+
+ assert(dev != NULL);
+
+ p_mhu = (union mhu_v2_x_frame *)dev->base;
+
+ if (!(dev->is_initialized)) {
+ return MHU_V_2_X_ERR_NOT_INIT;
+ }
+
+ if (dev->frame == MHU_V2_X_RECEIVER_FRAME) {
+ (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_msk_clr = mask;
+ return MHU_V_2_X_ERR_NONE;
+ } else {
+ return MHU_V_2_X_ERR_INVALID_ARG;
+ }
+}
+enum mhu_v2_x_error_t mhu_v2_x_initiate_transfer(
+ const struct mhu_v2_x_dev_t *dev)
+{
+ union mhu_v2_x_frame *p_mhu;
+
+ assert(dev != NULL);
+
+ p_mhu = (union mhu_v2_x_frame *)dev->base;
+
+ if (!(dev->is_initialized)) {
+ return MHU_V_2_X_ERR_NOT_INIT;
+ }
+
+ if (dev->frame != MHU_V2_X_SENDER_FRAME) {
+ return MHU_V_2_X_ERR_INVALID_ARG;
+ }
+
+ (SEND_FRAME(p_mhu))->access_request = ENABLE;
+
+ while (!((SEND_FRAME(p_mhu))->access_ready)) {
+ /* Wait in a loop for access ready signal to be high */
+ ;
+ }
+
+ return MHU_V_2_X_ERR_NONE;
+}
+
+enum mhu_v2_x_error_t mhu_v2_x_close_transfer(const struct mhu_v2_x_dev_t *dev)
+{
+ union mhu_v2_x_frame *p_mhu;
+
+ assert(dev != NULL);
+
+ p_mhu = (union mhu_v2_x_frame *)dev->base;
+
+ if (!(dev->is_initialized)) {
+ return MHU_V_2_X_ERR_NOT_INIT;
+ }
+
+ if (dev->frame != MHU_V2_X_SENDER_FRAME) {
+ return MHU_V_2_X_ERR_INVALID_ARG;
+ }
+
+ (SEND_FRAME(p_mhu))->access_request = DISABLE;
+
+ return MHU_V_2_X_ERR_NONE;
+}
diff --git a/drivers/arm/mhu/mhu_v2_x.h b/drivers/arm/mhu/mhu_v2_x.h
new file mode 100644
index 0000000..10247d2
--- /dev/null
+++ b/drivers/arm/mhu/mhu_v2_x.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MHU_V2_X_H
+#define MHU_V2_X_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define MHU_2_X_INTR_NR2R_OFF (0x0u)
+#define MHU_2_X_INTR_R2NR_OFF (0x1u)
+#define MHU_2_1_INTR_CHCOMB_OFF (0x2u)
+
+#define MHU_2_X_INTR_NR2R_MASK (0x1u << MHU_2_X_INTR_NR2R_OFF)
+#define MHU_2_X_INTR_R2NR_MASK (0x1u << MHU_2_X_INTR_R2NR_OFF)
+#define MHU_2_1_INTR_CHCOMB_MASK (0x1u << MHU_2_1_INTR_CHCOMB_OFF)
+
+enum mhu_v2_x_frame_t {
+ MHU_V2_X_SENDER_FRAME = 0x0u,
+ MHU_V2_X_RECEIVER_FRAME = 0x1u,
+};
+
+enum mhu_v2_x_supported_revisions {
+ MHU_REV_READ_FROM_HW = 0,
+ MHU_REV_2_0,
+ MHU_REV_2_1,
+};
+
+struct mhu_v2_x_dev_t {
+ uintptr_t base;
+ enum mhu_v2_x_frame_t frame;
+ uint32_t subversion; /*!< Hardware subversion: v2.X */
+ bool is_initialized; /*!< Indicates if the MHU driver
+ * is initialized and enabled
+ */
+};
+
+/**
+ * MHU v2 error enumeration types.
+ */
+enum mhu_v2_x_error_t {
+ MHU_V_2_X_ERR_NONE = 0,
+ MHU_V_2_X_ERR_NOT_INIT = -1,
+ MHU_V_2_X_ERR_ALREADY_INIT = -2,
+ MHU_V_2_X_ERR_UNSUPPORTED_VERSION = -3,
+ MHU_V_2_X_ERR_INVALID_ARG = -4,
+ MHU_V_2_X_ERR_GENERAL = -5
+};
+
+/**
+ * Initializes the driver.
+ *
+ * dev MHU device struct mhu_v2_x_dev_t.
+ * rev MHU revision (if can't be identified from HW).
+ *
+ * Reads the MHU hardware version.
+ *
+ * Returns mhu_v2_x_error_t error code.
+ *
+ * MHU revision only has to be specified when versions can't be read
+ * from HW (ARCH_MAJOR_REV reg reads as 0x0).
+ *
+ * This function doesn't check if dev is NULL.
+ */
+enum mhu_v2_x_error_t mhu_v2_x_driver_init(struct mhu_v2_x_dev_t *dev,
+ enum mhu_v2_x_supported_revisions rev);
+
+/**
+ * Returns the number of channels implemented.
+ *
+ * dev MHU device struct mhu_v2_x_dev_t.
+ *
+ * This function doesn't check if dev is NULL.
+ */
+uint32_t mhu_v2_x_get_num_channel_implemented(
+ const struct mhu_v2_x_dev_t *dev);
+
+/**
+ * Sends the value over a channel.
+ *
+ * dev MHU device struct mhu_v2_x_dev_t.
+ * channel Channel to send the value over.
+ * val Value to send.
+ *
+ * Sends the value over a channel.
+ *
+ * Returns mhu_v2_x_error_t error code.
+ *
+ * This function doesn't check if dev is NULL.
+ * This function doesn't check if channel is implemented.
+ */
+enum mhu_v2_x_error_t mhu_v2_x_channel_send(const struct mhu_v2_x_dev_t *dev,
+ uint32_t channel, uint32_t val);
+
+/**
+ * Polls sender channel status.
+ *
+ * dev MHU device struct mhu_v2_x_dev_t.
+ * channel Channel to poll the status of.
+ * value Pointer to variable that will store the value.
+ *
+ * Polls sender channel status.
+ *
+ * Returns mhu_v2_x_error_t error code.
+ *
+ * This function doesn't check if dev is NULL.
+ * This function doesn't check if channel is implemented.
+ */
+enum mhu_v2_x_error_t mhu_v2_x_channel_poll(const struct mhu_v2_x_dev_t *dev,
+ uint32_t channel, uint32_t *value);
+
+/**
+ * Clears the channel after the value is send over it.
+ *
+ * dev MHU device struct mhu_v2_x_dev_t.
+ * channel Channel to clear.
+ *
+ * Clears the channel after the value is send over it.
+ *
+ * Returns mhu_v2_x_error_t error code..
+ *
+ * This function doesn't check if dev is NULL.
+ * This function doesn't check if channel is implemented.
+ */
+enum mhu_v2_x_error_t mhu_v2_x_channel_clear(const struct mhu_v2_x_dev_t *dev,
+ uint32_t channel);
+
+/**
+ * Receives the value over a channel.
+ *
+ * dev MHU device struct mhu_v2_x_dev_t.
+ * channel Channel to receive the value from.
+ * value Pointer to variable that will store the value.
+ *
+ * Receives the value over a channel.
+ *
+ * Returns mhu_v2_x_error_t error code.
+ *
+ * This function doesn't check if dev is NULL.
+ * This function doesn't check if channel is implemented.
+ */
+enum mhu_v2_x_error_t mhu_v2_x_channel_receive(
+ const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t *value);
+
+/**
+ * Sets bits in the Channel Mask.
+ *
+ * dev MHU device struct mhu_v2_x_dev_t.
+ * channel Which channel's mask to set.
+ * mask Mask to be set over a receiver frame.
+ *
+ * Sets bits in the Channel Mask.
+ *
+ * Returns mhu_v2_x_error_t error code..
+ *
+ * This function doesn't check if dev is NULL.
+ * This function doesn't check if channel is implemented.
+ */
+enum mhu_v2_x_error_t mhu_v2_x_channel_mask_set(
+ const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask);
+
+/**
+ * Clears bits in the Channel Mask.
+ *
+ * dev MHU device struct mhu_v2_x_dev_t.
+ * channel Which channel's mask to clear.
+ * mask Mask to be clear over a receiver frame.
+ *
+ * Clears bits in the Channel Mask.
+ *
+ * Returns mhu_v2_x_error_t error code.
+ *
+ * This function doesn't check if dev is NULL.
+ * This function doesn't check if channel is implemented.
+ */
+enum mhu_v2_x_error_t mhu_v2_x_channel_mask_clear(
+ const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask);
+
+/**
+ * Initiates a MHU transfer with the handshake signals.
+ *
+ * dev MHU device struct mhu_v2_x_dev_t.
+ *
+ * Initiates a MHU transfer with the handshake signals in a blocking mode.
+ *
+ * Returns mhu_v2_x_error_t error code.
+ *
+ * This function doesn't check if dev is NULL.
+ */
+enum mhu_v2_x_error_t mhu_v2_x_initiate_transfer(
+ const struct mhu_v2_x_dev_t *dev);
+
+/**
+ * Closes a MHU transfer with the handshake signals.
+ *
+ * dev MHU device struct mhu_v2_x_dev_t.
+ *
+ * Closes a MHU transfer with the handshake signals in a blocking mode.
+ *
+ * Returns mhu_v2_x_error_t error code.
+ *
+ * This function doesn't check if dev is NULL.
+ */
+enum mhu_v2_x_error_t mhu_v2_x_close_transfer(
+ const struct mhu_v2_x_dev_t *dev);
+
+#endif /* MHU_V2_X_H */
diff --git a/drivers/arm/mhu/mhu_wrapper_v2_x.c b/drivers/arm/mhu/mhu_wrapper_v2_x.c
new file mode 100644
index 0000000..d8b7cfd
--- /dev/null
+++ b/drivers/arm/mhu/mhu_wrapper_v2_x.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <drivers/arm/mhu.h>
+
+#include "mhu_v2_x.h"
+
+#define MHU_NOTIFY_VALUE (1234u)
+
+/*
+ * MHU devices for host:
+ * HSE: Host to Secure Enclave (sender device)
+ * SEH: Secure Enclave to Host (receiver device)
+ */
+struct mhu_v2_x_dev_t MHU1_HSE_DEV = {0, MHU_V2_X_SENDER_FRAME};
+struct mhu_v2_x_dev_t MHU1_SEH_DEV = {0, MHU_V2_X_RECEIVER_FRAME};
+
+static enum mhu_error_t error_mapping_to_mhu_error_t(enum mhu_v2_x_error_t err)
+{
+ switch (err) {
+ case MHU_V_2_X_ERR_NONE:
+ return MHU_ERR_NONE;
+ case MHU_V_2_X_ERR_NOT_INIT:
+ return MHU_ERR_NOT_INIT;
+ case MHU_V_2_X_ERR_ALREADY_INIT:
+ return MHU_ERR_ALREADY_INIT;
+ case MHU_V_2_X_ERR_UNSUPPORTED_VERSION:
+ return MHU_ERR_UNSUPPORTED_VERSION;
+ case MHU_V_2_X_ERR_INVALID_ARG:
+ return MHU_ERR_INVALID_ARG;
+ case MHU_V_2_X_ERR_GENERAL:
+ return MHU_ERR_GENERAL;
+ default:
+ return MHU_ERR_GENERAL;
+ }
+}
+
+static enum mhu_v2_x_error_t signal_and_wait_for_clear(void)
+{
+ enum mhu_v2_x_error_t err;
+ struct mhu_v2_x_dev_t *dev = &MHU1_HSE_DEV;
+ uint32_t val = MHU_NOTIFY_VALUE;
+ /* Using the last channel for notifications */
+ uint32_t channel_notify = mhu_v2_x_get_num_channel_implemented(dev) - 1;
+
+ err = mhu_v2_x_channel_send(dev, channel_notify, val);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return err;
+ }
+
+ do {
+ err = mhu_v2_x_channel_poll(dev, channel_notify, &val);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ break;
+ }
+ } while (val != 0);
+
+ return err;
+}
+
+static enum mhu_v2_x_error_t wait_for_signal(void)
+{
+ enum mhu_v2_x_error_t err;
+ struct mhu_v2_x_dev_t *dev = &MHU1_SEH_DEV;
+ uint32_t val = 0;
+ /* Using the last channel for notifications */
+ uint32_t channel_notify = mhu_v2_x_get_num_channel_implemented(dev) - 1;
+
+ do {
+ err = mhu_v2_x_channel_receive(dev, channel_notify, &val);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ break;
+ }
+ } while (val != MHU_NOTIFY_VALUE);
+
+ return err;
+}
+
+static enum mhu_v2_x_error_t clear_and_wait_for_next_signal(void)
+{
+ enum mhu_v2_x_error_t err;
+ struct mhu_v2_x_dev_t *dev = &MHU1_SEH_DEV;
+ uint32_t num_channels = mhu_v2_x_get_num_channel_implemented(dev);
+ uint32_t i;
+
+ /* Clear all channels */
+ for (i = 0; i < num_channels; ++i) {
+ err = mhu_v2_x_channel_clear(dev, i);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return err;
+ }
+ }
+
+ return wait_for_signal();
+}
+
+enum mhu_error_t mhu_init_sender(uintptr_t mhu_sender_base)
+{
+ enum mhu_v2_x_error_t err;
+
+ assert(mhu_sender_base != (uintptr_t)NULL);
+
+ MHU1_HSE_DEV.base = mhu_sender_base;
+
+ err = mhu_v2_x_driver_init(&MHU1_HSE_DEV, MHU_REV_READ_FROM_HW);
+ return error_mapping_to_mhu_error_t(err);
+}
+
+enum mhu_error_t mhu_init_receiver(uintptr_t mhu_receiver_base)
+{
+ enum mhu_v2_x_error_t err;
+ uint32_t num_channels, i;
+
+ assert(mhu_receiver_base != (uintptr_t)NULL);
+
+ MHU1_SEH_DEV.base = mhu_receiver_base;
+
+ err = mhu_v2_x_driver_init(&MHU1_SEH_DEV, MHU_REV_READ_FROM_HW);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+
+ num_channels = mhu_v2_x_get_num_channel_implemented(&MHU1_SEH_DEV);
+
+ /* Mask all channels except the notifying channel */
+ for (i = 0; i < (num_channels - 1); ++i) {
+ err = mhu_v2_x_channel_mask_set(&MHU1_SEH_DEV, i, UINT32_MAX);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+ }
+
+ /* The last channel is used for notifications */
+ err = mhu_v2_x_channel_mask_clear(
+ &MHU1_SEH_DEV, (num_channels - 1), UINT32_MAX);
+ return error_mapping_to_mhu_error_t(err);
+}
+
+/*
+ * Public function. See mhu.h
+ *
+ * The basic steps of transferring a message:
+ * 1. Initiate MHU transfer.
+ * 2. Send over the size of the payload on Channel 1. It is the very first
+ * 4 Bytes of the transfer. Continue with Channel 2.
+ * 3. Send over the payload, writing the channels one after the other
+ * (4 Bytes each). The last available channel is reserved for controlling
+ * the transfer.
+ * When the last channel is reached or no more data is left, STOP.
+ * 4. Notify the receiver using the last channel and wait for acknowledge.
+ * If there is still data to transfer, jump to step 3. Otherwise, proceed.
+ * 5. Close MHU transfer.
+ *
+ */
+enum mhu_error_t mhu_send_data(const uint8_t *send_buffer, size_t size)
+{
+ enum mhu_v2_x_error_t err;
+ struct mhu_v2_x_dev_t *dev = &MHU1_HSE_DEV;
+ uint32_t num_channels = mhu_v2_x_get_num_channel_implemented(dev);
+ uint32_t chan = 0;
+ uint32_t i;
+ uint32_t *p;
+
+ /* For simplicity, require the send_buffer to be 4-byte aligned */
+ if ((uintptr_t)send_buffer & 0x3U) {
+ return MHU_ERR_INVALID_ARG;
+ }
+
+ err = mhu_v2_x_initiate_transfer(dev);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+
+ /* First send over the size of the actual message */
+ err = mhu_v2_x_channel_send(dev, chan, (uint32_t)size);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+ chan++;
+
+ p = (uint32_t *)send_buffer;
+ for (i = 0; i < size; i += 4) {
+ err = mhu_v2_x_channel_send(dev, chan, *p++);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+ if (++chan == (num_channels - 1)) {
+ err = signal_and_wait_for_clear();
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+ chan = 0;
+ }
+ }
+
+ /* Signal the end of transfer.
+ * It's not required to send a signal when the message was
+ * perfectly-aligned (num_channels - 1 channels were used in the last
+ * round) preventing it from signaling twice at the end of transfer.
+ */
+ if (chan != 0) {
+ err = signal_and_wait_for_clear();
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+ }
+
+ err = mhu_v2_x_close_transfer(dev);
+ return error_mapping_to_mhu_error_t(err);
+}
+
+/*
+ * Public function. See mhu.h
+ *
+ * The basic steps of receiving a message:
+ * 1. Read the size of the payload from Channel 1. It is the very first
+ * 4 Bytes of the transfer. Continue with Channel 2.
+ * 2. Receive the payload, read the channels one after the other
+ * (4 Bytes each). The last available channel is reserved for controlling
+ * the transfer.
+ * When the last channel is reached clear all the channels
+ * (also sending an acknowledge on the last channel).
+ * 3. If there is still data to receive wait for a notification on the last
+ * channel and jump to step 2 as soon as it arrived. Otherwise, proceed.
+ * 4. End of transfer.
+ *
+ */
+enum mhu_error_t mhu_receive_data(uint8_t *receive_buffer, size_t *size)
+{
+ enum mhu_v2_x_error_t err;
+ struct mhu_v2_x_dev_t *dev = &MHU1_SEH_DEV;
+ uint32_t num_channels = mhu_v2_x_get_num_channel_implemented(dev);
+ uint32_t chan = 0;
+ uint32_t message_len;
+ uint32_t i;
+ uint32_t *p;
+
+ /* For simplicity, require:
+ * - the receive_buffer to be 4-byte aligned,
+ * - the buffer size to be a multiple of 4.
+ */
+ if (((uintptr_t)receive_buffer & 0x3U) || (*size & 0x3U)) {
+ return MHU_ERR_INVALID_ARG;
+ }
+
+ /* Busy wait for incoming reply */
+ err = wait_for_signal();
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+
+ /* The first word is the length of the actual message */
+ err = mhu_v2_x_channel_receive(dev, chan, &message_len);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+ chan++;
+
+ if (message_len > *size) {
+ /* Message buffer too small */
+ *size = message_len;
+ return MHU_ERR_BUFFER_TOO_SMALL;
+ }
+
+ p = (uint32_t *)receive_buffer;
+ for (i = 0; i < message_len; i += 4) {
+ err = mhu_v2_x_channel_receive(dev, chan, p++);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+
+ /* Only wait for next transfer if there is still missing data */
+ if (++chan == (num_channels - 1) && (message_len - i) > 4) {
+ /* Busy wait for next transfer */
+ err = clear_and_wait_for_next_signal();
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+ chan = 0;
+ }
+ }
+
+ /* Clear all channels */
+ for (i = 0; i < num_channels; ++i) {
+ err = mhu_v2_x_channel_clear(dev, i);
+ if (err != MHU_V_2_X_ERR_NONE) {
+ return error_mapping_to_mhu_error_t(err);
+ }
+ }
+
+ *size = message_len;
+
+ return MHU_ERR_NONE;
+}
diff --git a/drivers/arm/rss/rss_comms.c b/drivers/arm/rss/rss_comms.c
new file mode 100644
index 0000000..28a4925
--- /dev/null
+++ b/drivers/arm/rss/rss_comms.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/arm/mhu.h>
+#include <drivers/arm/rss_comms.h>
+#include <initial_attestation.h>
+#include <psa/client.h>
+
+#include <platform_def.h>
+
+#define TYPE_OFFSET U(16)
+#define TYPE_MASK (0xFFFFUL << TYPE_OFFSET)
+#define IN_LEN_OFFSET U(8)
+#define IN_LEN_MASK (0xFFUL << IN_LEN_OFFSET)
+#define OUT_LEN_OFFSET U(0)
+#define OUT_LEN_MASK (0xFFUL << OUT_LEN_OFFSET)
+
+#define PARAM_PACK(type, in_len, out_len) \
+ (((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK) | \
+ ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK) | \
+ ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
+
+#define PARAM_UNPACK_IN_LEN(ctrl_param) \
+ ((size_t)(((ctrl_param) & IN_LEN_MASK) >> IN_LEN_OFFSET))
+
+/* Message types */
+struct __packed packed_psa_call_t {
+ uint8_t protocol_ver;
+ uint8_t seq_num;
+ uint16_t client_id;
+ psa_handle_t handle;
+ uint32_t ctrl_param; /* type, in_len, out_len */
+ uint16_t io_size[4];
+};
+
+struct __packed packed_psa_reply_t {
+ uint8_t protocol_ver;
+ uint8_t seq_num;
+ uint16_t client_id;
+ int32_t return_val;
+ uint16_t out_size[4];
+};
+
+/*
+ * In the current implementation the RoT Service request that requires the
+ * biggest message buffer is the RSS_ATTEST_GET_TOKEN. The maximum required
+ * buffer size is calculated based on the platform-specific needs of
+ * this request.
+ */
+#define MAX_REQUEST_PAYLOAD_SIZE (PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 \
+ + PLAT_ATTEST_TOKEN_MAX_SIZE)
+
+/* Buffer to store the messages to be sent/received. */
+static uint8_t message_buf[MAX_REQUEST_PAYLOAD_SIZE] __aligned(4);
+
+static int32_t pack_params(const psa_invec *invecs,
+ size_t in_len,
+ uint8_t *buf,
+ size_t *buf_len)
+{
+ uint32_t i;
+ size_t payload_size = 0U;
+
+ for (i = 0U; i < in_len; ++i) {
+ if (invecs[i].len > *buf_len - payload_size) {
+ return -1;
+ }
+ memcpy(buf + payload_size, invecs[i].base, invecs[i].len);
+ payload_size += invecs[i].len;
+ }
+
+ *buf_len = payload_size;
+ return 0;
+}
+
+static int serialise_message(const struct packed_psa_call_t *msg,
+ const psa_invec *invecs,
+ uint8_t *payload_buf,
+ size_t *payload_len)
+{
+ size_t message_len = 0U;
+ size_t len;
+
+ /* Copy the message header into the payload buffer. */
+ len = sizeof(*msg);
+ if (len > *payload_len) {
+ ERROR("[RSS-COMMS] Message buffer too small.\n");
+ return -1;
+ }
+ memcpy(payload_buf, (const void *)msg, len);
+ message_len += len;
+
+ /* The input data will follow the message header in the payload buffer. */
+ len = *payload_len - message_len;
+ if (pack_params(invecs, PARAM_UNPACK_IN_LEN(msg->ctrl_param),
+ payload_buf + message_len, &len) != 0) {
+ ERROR("[RSS-COMMS] Message buffer too small.\n");
+ return -1;
+ }
+ message_len += len;
+
+ *payload_len = message_len;
+ return 0;
+}
+
+static void unpack_params(const uint8_t *buf,
+ psa_outvec *outvecs,
+ size_t out_len)
+{
+ size_t i;
+
+ for (i = 0U; i < out_len; ++i) {
+ memcpy(outvecs[i].base, buf, outvecs[i].len);
+ buf += outvecs[i].len;
+ }
+}
+
+static void deserialise_reply(struct packed_psa_reply_t *reply,
+ psa_outvec *outvecs,
+ size_t outlen,
+ const uint8_t *message,
+ size_t message_len)
+{
+ uint32_t i;
+
+ memcpy(reply, message, sizeof(*reply));
+
+ /* Outvecs */
+ for (i = 0U; i < outlen; ++i) {
+ outvecs[i].len = reply->out_size[i];
+ }
+
+ unpack_params(message + sizeof(*reply), outvecs, outlen);
+}
+
+psa_status_t psa_call(psa_handle_t handle, int32_t type,
+ const psa_invec *in_vec, size_t in_len,
+ psa_outvec *out_vec, size_t out_len)
+{
+ enum mhu_error_t err;
+ static uint32_t seq_num = 1U;
+ struct packed_psa_call_t msg = {
+ .protocol_ver = 0U,
+ .seq_num = seq_num,
+ /* No need to distinguish callers (currently concurrent calls are not supported). */
+ .client_id = 1U,
+ .handle = handle,
+ .ctrl_param = PARAM_PACK(type, in_len, out_len),
+ };
+
+ struct packed_psa_reply_t reply = {0};
+ size_t message_size;
+ uint32_t i;
+
+ /* Fill msg iovec lengths */
+ for (i = 0U; i < in_len; ++i) {
+ msg.io_size[i] = in_vec[i].len;
+ }
+ for (i = 0U; i < out_len; ++i) {
+ msg.io_size[in_len + i] = out_vec[i].len;
+ }
+
+ message_size = sizeof(message_buf);
+ if (serialise_message(&msg, in_vec, message_buf, &message_size)) {
+ /* Local buffer is probably too small. */
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ err = mhu_send_data(message_buf, message_size);
+ if (err != MHU_ERR_NONE) {
+ return PSA_ERROR_COMMUNICATION_FAILURE;
+ }
+
+ message_size = sizeof(message_buf);
+#if DEBUG
+ /*
+ * Poisoning the message buffer (with a known pattern).
+ * Helps in detecting hypothetical RSS communication bugs.
+ */
+ memset(message_buf, 0xA5, message_size);
+#endif
+ err = mhu_receive_data(message_buf, &message_size);
+ if (err != MHU_ERR_NONE) {
+ return PSA_ERROR_COMMUNICATION_FAILURE;
+ }
+
+ deserialise_reply(&reply, out_vec, out_len, message_buf, message_size);
+
+ seq_num++;
+
+ VERBOSE("[RSS-COMMS] Received reply\n");
+ VERBOSE("protocol_ver=%d\n", reply.protocol_ver);
+ VERBOSE("seq_num=%d\n", reply.seq_num);
+ VERBOSE("client_id=%d\n", reply.client_id);
+ VERBOSE("return_val=%d\n", reply.return_val);
+ VERBOSE("out_size[0]=%d\n", reply.out_size[0]);
+
+ return reply.return_val;
+}
+
+int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base)
+{
+ enum mhu_error_t err;
+
+ err = mhu_init_sender(mhu_sender_base);
+ if (err != MHU_ERR_NONE) {
+ ERROR("[RSS-COMMS] Host to RSS MHU driver initialization failed: %d\n", err);
+ return -1;
+ }
+
+ err = mhu_init_receiver(mhu_receiver_base);
+ if (err != MHU_ERR_NONE) {
+ ERROR("[RSS-COMMS] RSS to Host MHU driver initialization failed: %d\n", err);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index a082a81..6c6f978 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,11 +9,12 @@
#include <drivers/arm/smmu_v3.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
+#include <arch_features.h>
/* SMMU poll number of retries */
#define SMMU_POLL_TIMEOUT_US U(1000)
-static int __init smmuv3_poll(uintptr_t smmu_reg, uint32_t mask,
+static int smmuv3_poll(uintptr_t smmu_reg, uint32_t mask,
uint32_t value)
{
uint32_t reg_val;
@@ -79,14 +80,74 @@
if (smmuv3_security_init(smmu_base) != 0)
return -1;
- /* Check if the SMMU supports secure state */
- if ((mmio_read_32(smmu_base + SMMU_S_IDR1) &
- SMMU_S_IDR1_SECURE_IMPL) == 0U)
- return 0;
+#if ENABLE_RME
+
+ if (get_armv9_2_feat_rme_support() != 0U) {
+ if ((mmio_read_32(smmu_base + SMMU_ROOT_IDR0) &
+ SMMU_ROOT_IDR0_ROOT_IMPL) == 0U) {
+ WARN("Skip SMMU GPC configuration.\n");
+ } else {
+ uint64_t gpccr_el3 = read_gpccr_el3();
+ uint64_t gptbr_el3 = read_gptbr_el3();
+
+ /* SMMU_ROOT_GPT_BASE_CFG[16] is RES0. */
+ gpccr_el3 &= ~(1UL << 16);
+
+ /*
+ * TODO: SMMU_ROOT_GPT_BASE_CFG is 64b in the spec,
+ * but SMMU model only accepts 32b access.
+ */
+ mmio_write_32(smmu_base + SMMU_ROOT_GPT_BASE_CFG,
+ gpccr_el3);
+
+ /*
+ * pa_gpt_table_base[51:12] maps to GPTBR_EL3[39:0]
+ * whereas it maps to SMMU_ROOT_GPT_BASE[51:12]
+ * hence needs a 12 bit left shit.
+ */
+ mmio_write_64(smmu_base + SMMU_ROOT_GPT_BASE,
+ gptbr_el3 << 12);
+
+ /*
+ * ACCESSEN=1: SMMU- and client-originated accesses are
+ * not terminated by this mechanism.
+ * GPCEN=1: All clients and SMMU-originated accesses,
+ * except GPT-walks, are subject to GPC.
+ */
+ mmio_setbits_32(smmu_base + SMMU_ROOT_CR0,
+ SMMU_ROOT_CR0_GPCEN |
+ SMMU_ROOT_CR0_ACCESSEN);
+
+ /* Poll for ACCESSEN and GPCEN ack bits. */
+ if (smmuv3_poll(smmu_base + SMMU_ROOT_CR0ACK,
+ SMMU_ROOT_CR0_GPCEN |
+ SMMU_ROOT_CR0_ACCESSEN,
+ SMMU_ROOT_CR0_GPCEN |
+ SMMU_ROOT_CR0_ACCESSEN) != 0) {
+ WARN("Failed enabling SMMU GPC.\n");
+
+ /*
+ * Do not return in error, but fall back to
+ * invalidating all entries through the secure
+ * register file.
+ */
+ }
+ }
+ }
+
+#endif /* ENABLE_RME */
+
/*
* Initiate invalidation of secure caches and TLBs if the SMMU
* supports secure state. If not, it's implementation defined
* as to how SMMU_S_INIT register is accessed.
+ * Arm SMMU Arch RME supplement, section 3.4: all SMMU registers
+ * specified to be accessible only in secure physical address space are
+ * additionally accessible in root physical address space in an SMMU
+ * with RME.
+ * Section 3.3: as GPT information is permitted to be cached in a TLB,
+ * the SMMU_S_INIT.INV_ALL mechanism also invalidates GPT information
+ * cached in TLBs.
*/
mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
@@ -94,3 +155,28 @@
return smmuv3_poll(smmu_base + SMMU_S_INIT,
SMMU_S_INIT_INV_ALL, 0U);
}
+
+int smmuv3_ns_set_abort_all(uintptr_t smmu_base)
+{
+ /* Attribute update has completed when SMMU_GBPA.Update bit is 0 */
+ if (smmuv3_poll(smmu_base + SMMU_GBPA, SMMU_GBPA_UPDATE, 0U) != 0U) {
+ return -1;
+ }
+
+ /*
+ * Set GBPA's ABORT bit. Other GBPA fields are presumably ignored then,
+ * so simply preserve their value.
+ */
+ mmio_setbits_32(smmu_base + SMMU_GBPA, SMMU_GBPA_UPDATE | SMMU_GBPA_ABORT);
+ if (smmuv3_poll(smmu_base + SMMU_GBPA, SMMU_GBPA_UPDATE, 0U) != 0U) {
+ return -1;
+ }
+
+ /* Disable the SMMU to engage the GBPA fields previously configured. */
+ mmio_clrbits_32(smmu_base + SMMU_CR0, SMMU_CR0_SMMUEN);
+ if (smmuv3_poll(smmu_base + SMMU_CR0ACK, SMMU_CR0_SMMUEN, 0U) != 0U) {
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/drivers/auth/cca/cot.c b/drivers/auth/cca/cot.c
new file mode 100644
index 0000000..d3f3087
--- /dev/null
+++ b/drivers/auth/cca/cot.c
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <drivers/auth/auth_mod.h>
+#include MBEDTLS_CONFIG_FILE
+#include <tools_share/cca_oid.h>
+
+#include <platform_def.h>
+
+/*
+ * Allocate static buffers to store the authentication parameters extracted from
+ * the certificates.
+ */
+static unsigned char fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char hw_config_hash_buf[HASH_DER_LEN];
+static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
+static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char rmm_hash_buf[HASH_DER_LEN];
+
+#ifdef IMAGE_BL2
+static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
+static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
+static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
+#if defined(SPD_spmd)
+static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
+#endif /* SPD_spmd */
+
+static unsigned char core_swd_pk_buf[PK_DER_LEN];
+static unsigned char plat_pk_buf[PK_DER_LEN];
+#endif /* IMAGE_BL2 */
+
+/*
+ * Parameter type descriptors.
+ */
+static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, 0);
+static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_SIG, 0);
+static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_SIG_ALG, 0);
+static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_RAW_DATA, 0);
+
+static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
+static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
+static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID);
+static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t rmm_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, RMM_HASH_OID);
+
+#ifdef IMAGE_BL2
+static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
+
+static auth_param_type_desc_t prot_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, PROT_PK_OID);
+static auth_param_type_desc_t swd_rot_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, SWD_ROT_PK_OID);
+static auth_param_type_desc_t core_swd_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, CORE_SWD_PK_OID);
+static auth_param_type_desc_t plat_pk = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_PUB_KEY, PLAT_PK_OID);
+
+static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID);
+static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
+static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
+#if defined(SPD_spmd)
+static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
+static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
+static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
+static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
+static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
+static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
+static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
+static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
+ AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
+#endif /* SPD_spmd */
+#endif /* IMAGE_BL2 */
+
+/* CCA Content Certificate */
+static const auth_img_desc_t cca_content_cert = {
+ .img_id = CCA_CONTENT_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = NULL,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &subject_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &tb_fw_hash,
+ .data = {
+ .ptr = (void *)tb_fw_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &tb_fw_config_hash,
+ .data = {
+ .ptr = (void *)tb_fw_config_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [2] = {
+ .type_desc = &fw_config_hash,
+ .data = {
+ .ptr = (void *)fw_config_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [3] = {
+ .type_desc = &hw_config_hash,
+ .data = {
+ .ptr = (void *)hw_config_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [4] = {
+ .type_desc = &soc_fw_hash,
+ .data = {
+ .ptr = (void *)soc_fw_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [5] = {
+ .type_desc = &soc_fw_config_hash,
+ .data = {
+ .ptr = (void *)soc_fw_config_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [6] = {
+ .type_desc = &rmm_hash,
+ .data = {
+ .ptr = (void *)rmm_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ }
+ }
+};
+
+#ifdef IMAGE_BL1
+static const auth_img_desc_t bl2_image = {
+ .img_id = BL2_IMAGE_ID,
+ .img_type = IMG_RAW,
+ .parent = &cca_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &tb_fw_hash
+ }
+ }
+ }
+};
+
+static const auth_img_desc_t tb_fw_config = {
+ .img_id = TB_FW_CONFIG_ID,
+ .img_type = IMG_RAW,
+ .parent = &cca_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &tb_fw_config_hash
+ }
+ }
+ }
+};
+
+static const auth_img_desc_t fw_config = {
+ .img_id = FW_CONFIG_ID,
+ .img_type = IMG_RAW,
+ .parent = &cca_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &fw_config_hash
+ }
+ }
+ }
+};
+#endif /* IMAGE_BL1 */
+
+#ifdef IMAGE_BL2
+/* HW Config */
+static const auth_img_desc_t hw_config = {
+ .img_id = HW_CONFIG_ID,
+ .img_type = IMG_RAW,
+ .parent = &cca_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &hw_config_hash
+ }
+ }
+ }
+};
+
+/* BL31 */
+static const auth_img_desc_t bl31_image = {
+ .img_id = BL31_IMAGE_ID,
+ .img_type = IMG_RAW,
+ .parent = &cca_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &soc_fw_hash
+ }
+ }
+ }
+};
+
+/* BL31 Config */
+static const auth_img_desc_t soc_fw_config = {
+ .img_id = SOC_FW_CONFIG_ID,
+ .img_type = IMG_RAW,
+ .parent = &cca_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &soc_fw_config_hash
+ }
+ }
+ }
+};
+
+/* RMM */
+static const auth_img_desc_t rmm_image = {
+ .img_id = RMM_IMAGE_ID,
+ .img_type = IMG_RAW,
+ .parent = &cca_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &rmm_hash
+ }
+ }
+ }
+};
+
+/* Core SWD Key Certificate */
+static const auth_img_desc_t core_swd_key_cert = {
+ .img_id = CORE_SWD_KEY_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = NULL, /* SWD ROOT CERT */
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &swd_rot_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &core_swd_pk,
+ .data = {
+ .ptr = (void *)core_swd_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ }
+ }
+};
+
+/* SPMC Content Certificate */
+static const auth_img_desc_t trusted_os_fw_content_cert = {
+ .img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = &core_swd_key_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &core_swd_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &tos_fw_hash,
+ .data = {
+ .ptr = (void *)tos_fw_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &tos_fw_config_hash,
+ .data = {
+ .ptr = (void *)tos_fw_config_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ }
+ }
+};
+
+/* SPMC */
+static const auth_img_desc_t bl32_image = {
+ .img_id = BL32_IMAGE_ID,
+ .img_type = IMG_RAW,
+ .parent = &trusted_os_fw_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &tos_fw_hash
+ }
+ }
+ }
+};
+
+/* SPM Config */
+static const auth_img_desc_t tos_fw_config = {
+ .img_id = TOS_FW_CONFIG_ID,
+ .img_type = IMG_RAW,
+ .parent = &trusted_os_fw_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &tos_fw_config_hash
+ }
+ }
+ }
+};
+
+/* Platform Key Certificate */
+static const auth_img_desc_t plat_key_cert = {
+ .img_id = PLAT_KEY_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = NULL, /* PLATFORM ROOT CERT */
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &prot_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &non_trusted_nv_ctr,
+ .plat_nv_ctr = &non_trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &plat_pk,
+ .data = {
+ .ptr = (void *)plat_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ }
+ }
+};
+
+/* Non-Trusted Firmware */
+static const auth_img_desc_t non_trusted_fw_content_cert = {
+ .img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = &plat_key_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &plat_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &non_trusted_nv_ctr,
+ .plat_nv_ctr = &non_trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &nt_world_bl_hash,
+ .data = {
+ .ptr = (void *)nt_world_bl_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &nt_fw_config_hash,
+ .data = {
+ .ptr = (void *)nt_fw_config_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ }
+ }
+};
+
+static const auth_img_desc_t bl33_image = {
+ .img_id = BL33_IMAGE_ID,
+ .img_type = IMG_RAW,
+ .parent = &non_trusted_fw_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &nt_world_bl_hash
+ }
+ }
+ }
+};
+
+/* NT FW Config */
+static const auth_img_desc_t nt_fw_config = {
+ .img_id = NT_FW_CONFIG_ID,
+ .img_type = IMG_RAW,
+ .parent = &non_trusted_fw_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &nt_fw_config_hash
+ }
+ }
+ }
+};
+
+/*
+ * Secure Partitions
+ */
+#if defined(SPD_spmd)
+static const auth_img_desc_t sip_sp_content_cert = {
+ .img_id = SIP_SP_CONTENT_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = &core_swd_key_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &core_swd_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &sp_pkg1_hash,
+ .data = {
+ .ptr = (void *)sp_pkg_hash_buf[0],
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &sp_pkg2_hash,
+ .data = {
+ .ptr = (void *)sp_pkg_hash_buf[1],
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [2] = {
+ .type_desc = &sp_pkg3_hash,
+ .data = {
+ .ptr = (void *)sp_pkg_hash_buf[2],
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [3] = {
+ .type_desc = &sp_pkg4_hash,
+ .data = {
+ .ptr = (void *)sp_pkg_hash_buf[3],
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ }
+ }
+};
+
+DEFINE_SIP_SP_PKG(1);
+DEFINE_SIP_SP_PKG(2);
+DEFINE_SIP_SP_PKG(3);
+DEFINE_SIP_SP_PKG(4);
+
+static const auth_img_desc_t plat_sp_content_cert = {
+ .img_id = PLAT_SP_CONTENT_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = &plat_key_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &plat_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &non_trusted_nv_ctr,
+ .plat_nv_ctr = &non_trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &sp_pkg5_hash,
+ .data = {
+ .ptr = (void *)sp_pkg_hash_buf[4],
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &sp_pkg6_hash,
+ .data = {
+ .ptr = (void *)sp_pkg_hash_buf[5],
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [2] = {
+ .type_desc = &sp_pkg7_hash,
+ .data = {
+ .ptr = (void *)sp_pkg_hash_buf[6],
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [3] = {
+ .type_desc = &sp_pkg8_hash,
+ .data = {
+ .ptr = (void *)sp_pkg_hash_buf[7],
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ }
+ }
+};
+
+DEFINE_PLAT_SP_PKG(5);
+DEFINE_PLAT_SP_PKG(6);
+DEFINE_PLAT_SP_PKG(7);
+DEFINE_PLAT_SP_PKG(8);
+#endif /* SPD_spmd */
+#endif /* IMAGE_BL2 */
+/*
+ * Chain of trust definition
+ */
+#ifdef IMAGE_BL1
+static const auth_img_desc_t * const cot_desc[] = {
+ [CCA_CONTENT_CERT_ID] = &cca_content_cert,
+ [BL2_IMAGE_ID] = &bl2_image,
+ [TB_FW_CONFIG_ID] = &tb_fw_config,
+ [FW_CONFIG_ID] = &fw_config,
+};
+#else /* IMAGE_BL2 */
+static const auth_img_desc_t * const cot_desc[] = {
+ [CCA_CONTENT_CERT_ID] = &cca_content_cert,
+ [HW_CONFIG_ID] = &hw_config,
+ [BL31_IMAGE_ID] = &bl31_image,
+ [SOC_FW_CONFIG_ID] = &soc_fw_config,
+ [RMM_IMAGE_ID] = &rmm_image,
+ [CORE_SWD_KEY_CERT_ID] = &core_swd_key_cert,
+ [TRUSTED_OS_FW_CONTENT_CERT_ID] = &trusted_os_fw_content_cert,
+ [BL32_IMAGE_ID] = &bl32_image,
+ [TOS_FW_CONFIG_ID] = &tos_fw_config,
+ [PLAT_KEY_CERT_ID] = &plat_key_cert,
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert,
+ [BL33_IMAGE_ID] = &bl33_image,
+ [NT_FW_CONFIG_ID] = &nt_fw_config,
+#if defined(SPD_spmd)
+ [SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert,
+ [PLAT_SP_CONTENT_CERT_ID] = &plat_sp_content_cert,
+ [SP_PKG1_ID] = &sp_pkg1,
+ [SP_PKG2_ID] = &sp_pkg2,
+ [SP_PKG3_ID] = &sp_pkg3,
+ [SP_PKG4_ID] = &sp_pkg4,
+ [SP_PKG5_ID] = &sp_pkg5,
+ [SP_PKG6_ID] = &sp_pkg6,
+ [SP_PKG7_ID] = &sp_pkg7,
+ [SP_PKG8_ID] = &sp_pkg8,
+#endif
+};
+#endif /* IMAGE_BL1 */
+
+/* Register the CoT in the authentication module */
+REGISTER_COT(cot_desc);
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 0a4775d..16ce65f 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -48,6 +48,7 @@
rsa_internal.c \
x509.c \
x509_crt.c \
+ constant_time.c \
)
# The platform may define the variable 'TF_MBEDTLS_KEY_ALG' to select the key
@@ -96,18 +97,6 @@
TF_MBEDTLS_USE_AES_GCM := 0
endif
-ifeq ($(MEASURED_BOOT),1)
- ifeq (${TPM_HASH_ALG}, sha256)
- TF_MBEDTLS_TPM_HASH_ALG_ID := TF_MBEDTLS_SHA256
- else ifeq (${TPM_HASH_ALG}, sha384)
- TF_MBEDTLS_TPM_HASH_ALG_ID := TF_MBEDTLS_SHA384
- else ifeq (${TPM_HASH_ALG}, sha512)
- TF_MBEDTLS_TPM_HASH_ALG_ID := TF_MBEDTLS_SHA512
- else
- $(error "TPM_HASH_ALG not defined.")
- endif
-endif
-
# Needs to be set to drive mbed TLS configuration correctly
$(eval $(call add_defines,\
$(sort \
@@ -117,10 +106,6 @@
TF_MBEDTLS_USE_AES_GCM \
)))
-ifeq ($(MEASURED_BOOT),1)
- $(eval $(call add_define,TF_MBEDTLS_TPM_HASH_ALG_ID))
-endif
-
$(eval $(call MAKE_LIB,mbedtls))
endif
diff --git a/drivers/fwu/fwu.c b/drivers/fwu/fwu.c
index 80f870b..ff432be 100644
--- a/drivers/fwu/fwu.c
+++ b/drivers/fwu/fwu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,7 +25,7 @@
crc_32_must_be_first_member_of_structure);
static struct fwu_metadata metadata;
-static bool is_fwu_initialized;
+static bool is_metadata_initialized __unused;
/*******************************************************************************
* Compute CRC32 of the FWU metadata, and check it against the CRC32 value
@@ -142,7 +142,7 @@
{
bool trial_run = false;
- assert(is_fwu_initialized);
+ assert(is_metadata_initialized);
for (unsigned int i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
struct fwu_image_entry *entry = &metadata.img_entry[i];
@@ -159,7 +159,7 @@
const struct fwu_metadata *fwu_get_metadata(void)
{
- assert(is_fwu_initialized);
+ assert(is_metadata_initialized);
return &metadata;
}
@@ -188,7 +188,7 @@
}
}
- plat_fwu_set_images_source(&metadata);
+ is_metadata_initialized = true;
- is_fwu_initialized = true;
+ plat_fwu_set_images_source(&metadata);
}
diff --git a/drivers/measured_boot/event_log/event_log.c b/drivers/measured_boot/event_log/event_log.c
index 792f235..abe469b 100644
--- a/drivers/measured_boot/event_log/event_log.c
+++ b/drivers/measured_boot/event_log/event_log.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -180,6 +180,8 @@
/* event_log_init() must have been called prior to this. */
assert(log_ptr != NULL);
+ assert(((uintptr_t)log_ptr + ID_EVENT_SIZE + LOC_EVENT_SIZE) <
+ log_end);
/*
* Add Specification ID Event first
@@ -219,7 +221,7 @@
((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID;
/* TCG_PCR_EVENT2.Digests[].Digest[] */
- (void)memset(&((tpmt_ha *)ptr)->digest, 0, TPM_ALG_ID);
+ (void)memset(&((tpmt_ha *)ptr)->digest, 0, TCG_DIGEST_SIZE);
ptr = (uint8_t *)((uintptr_t)ptr +
offsetof(tpmt_ha, digest) + TCG_DIGEST_SIZE);
diff --git a/drivers/measured_boot/event_log/event_log.mk b/drivers/measured_boot/event_log/event_log.mk
index 1ff4aa8..5ea4c55 100644
--- a/drivers/measured_boot/event_log/event_log.mk
+++ b/drivers/measured_boot/event_log/event_log.mk
@@ -7,20 +7,25 @@
# Default log level to dump the event log (LOG_LEVEL_INFO)
EVENT_LOG_LEVEL ?= 40
-# TPM hash algorithm.
+# Measured Boot hash algorithm.
# SHA-256 (or stronger) is required for all devices that are TPM 2.0 compliant.
-TPM_HASH_ALG := sha256
+ifdef TPM_HASH_ALG
+ $(warning "TPM_HASH_ALG is deprecated. Please use MBOOT_EL_HASH_ALG instead.")
+ MBOOT_EL_HASH_ALG := ${TPM_HASH_ALG}
+else
+ MBOOT_EL_HASH_ALG := sha256
+endif
-ifeq (${TPM_HASH_ALG}, sha512)
+ifeq (${MBOOT_EL_HASH_ALG}, sha512)
TPM_ALG_ID := TPM_ALG_SHA512
TCG_DIGEST_SIZE := 64U
-else ifeq (${TPM_HASH_ALG}, sha384)
+else ifeq (${MBOOT_EL_HASH_ALG}, sha384)
TPM_ALG_ID := TPM_ALG_SHA384
TCG_DIGEST_SIZE := 48U
else
TPM_ALG_ID := TPM_ALG_SHA256
TCG_DIGEST_SIZE := 32U
-endif #TPM_HASH_ALG
+endif #MBOOT_EL_HASH_ALG
# Set definitions for Measured Boot driver.
$(eval $(call add_defines,\
diff --git a/drivers/measured_boot/rss/rss_measured_boot.c b/drivers/measured_boot/rss/rss_measured_boot.c
new file mode 100644
index 0000000..fe2baf0
--- /dev/null
+++ b/drivers/measured_boot/rss/rss_measured_boot.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+#include <psa/crypto_types.h>
+#include <psa/crypto_values.h>
+#include <psa/error.h>
+
+#define MBOOT_ALG_SHA512 0
+#define MBOOT_ALG_SHA384 1
+#define MBOOT_ALG_SHA256 2
+
+#if MBOOT_ALG_ID == MBOOT_ALG_SHA512
+#define CRYPTO_MD_ID CRYPTO_MD_SHA512
+#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_512
+#elif MBOOT_ALG_ID == MBOOT_ALG_SHA384
+#define CRYPTO_MD_ID CRYPTO_MD_SHA384
+#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_384
+#elif MBOOT_ALG_ID == MBOOT_ALG_SHA256
+#define CRYPTO_MD_ID CRYPTO_MD_SHA256
+#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_256
+#else
+# error Invalid Measured Boot algorithm.
+#endif /* MBOOT_ALG_ID */
+
+/* Pointer to struct rss_mboot_metadata */
+static struct rss_mboot_metadata *plat_metadata_ptr;
+
+/* Functions' declarations */
+void rss_measured_boot_init(void)
+{
+ /* At this point it is expected that communication channel over MHU
+ * is already initialised by platform init.
+ */
+
+ /* Get pointer to platform's struct rss_mboot_metadata structure */
+ plat_metadata_ptr = plat_rss_mboot_get_metadata();
+ assert(plat_metadata_ptr != NULL);
+}
+
+int rss_mboot_measure_and_record(uintptr_t data_base, uint32_t data_size,
+ uint32_t data_id)
+{
+ unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
+ int rc;
+ psa_status_t ret;
+ const struct rss_mboot_metadata *metadata_ptr = plat_metadata_ptr;
+
+ /* Get the metadata associated with this image. */
+ while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) &&
+ (metadata_ptr->id != data_id)) {
+ metadata_ptr++;
+ }
+
+ /* If image is not present in metadata array then skip */
+ if (metadata_ptr->id == RSS_MBOOT_INVALID_ID) {
+ return 0;
+ }
+
+ /* Calculate hash */
+ rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
+ (void *)data_base, data_size, hash_data);
+ if (rc != 0) {
+ return rc;
+ }
+
+ ret = rss_measured_boot_extend_measurement(
+ metadata_ptr->slot,
+ metadata_ptr->signer_id,
+ metadata_ptr->signer_id_size,
+ metadata_ptr->version,
+ metadata_ptr->version_size,
+ PSA_CRYPTO_MD_ID,
+ metadata_ptr->sw_type,
+ metadata_ptr->sw_type_size,
+ hash_data,
+ MBOOT_DIGEST_SIZE,
+ metadata_ptr->lock_measurement);
+ if (ret != PSA_SUCCESS) {
+ return ret;
+ }
+
+ return 0;
+}
+
+int rss_mboot_set_signer_id(unsigned int img_id,
+ const void *pk_ptr,
+ size_t pk_len)
+{
+ unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
+ struct rss_mboot_metadata *metadata_ptr = plat_metadata_ptr;
+ int rc;
+
+ /* Get the metadata associated with this image. */
+ while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) &&
+ (metadata_ptr->id != img_id)) {
+ metadata_ptr++;
+ }
+
+ /* If image is not present in metadata array then skip */
+ if (metadata_ptr->id == RSS_MBOOT_INVALID_ID) {
+ return 0;
+ }
+
+ /* Calculate public key hash */
+ rc = crypto_mod_calc_hash(CRYPTO_MD_ID, (void *)pk_ptr,
+ pk_len, hash_data);
+ if (rc != 0) {
+ return rc;
+ }
+
+ /* Update metadata struct with the received signer_id */
+ (void)memcpy(metadata_ptr->signer_id, hash_data, MBOOT_DIGEST_SIZE);
+ metadata_ptr->signer_id_size = MBOOT_DIGEST_SIZE;
+
+ return 0;
+}
diff --git a/drivers/measured_boot/rss/rss_measured_boot.mk b/drivers/measured_boot/rss/rss_measured_boot.mk
new file mode 100644
index 0000000..18ee836
--- /dev/null
+++ b/drivers/measured_boot/rss/rss_measured_boot.mk
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Hash algorithm for measured boot
+# SHA-256 (or stronger) is required.
+MBOOT_RSS_HASH_ALG := sha256
+
+ifeq (${MBOOT_RSS_HASH_ALG}, sha512)
+ MBOOT_ALG_ID := MBOOT_ALG_SHA512
+ MBOOT_DIGEST_SIZE := 64U
+else ifeq (${MBOOT_RSS_HASH_ALG}, sha384)
+ MBOOT_ALG_ID := MBOOT_ALG_SHA384
+ MBOOT_DIGEST_SIZE := 48U
+else
+ MBOOT_ALG_ID := MBOOT_ALG_SHA256
+ MBOOT_DIGEST_SIZE := 32U
+endif #MBOOT_RSS_HASH_ALG
+
+# Set definitions for Measured Boot driver.
+$(eval $(call add_defines,\
+ $(sort \
+ MBOOT_ALG_ID \
+ MBOOT_DIGEST_SIZE \
+ MBOOT_RSS_BACKEND \
+)))
+
+MEASURED_BOOT_SRC_DIR := drivers/measured_boot/rss/
+
+MEASURED_BOOT_SOURCES += ${MEASURED_BOOT_SRC_DIR}rss_measured_boot.c
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index c327e71..8e83464 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,7 @@
#include <drivers/delay_timer.h>
#include <drivers/mmc.h>
#include <lib/utils.h>
+#include <plat/common/common_def.h>
#define MMC_DEFAULT_MAX_RETRIES 5
#define SEND_OP_COND_MAX_RETRIES 100
@@ -25,6 +26,7 @@
static const struct mmc_ops *ops;
static unsigned int mmc_ocr_value;
static struct mmc_csd_emmc mmc_csd;
+static struct sd_switch_status sd_switch_func_status;
static unsigned char mmc_ext_csd[512] __aligned(16);
static unsigned int mmc_flags;
static struct mmc_device_info *mmc_dev_info;
@@ -44,6 +46,11 @@
return ((mmc_flags & MMC_FLAG_CMD23) != 0U);
}
+static bool is_sd_cmd6_enabled(void)
+{
+ return ((mmc_flags & MMC_FLAG_SD_CMD6) != 0U);
+}
+
static int mmc_send_cmd(unsigned int idx, unsigned int arg,
unsigned int r_type, unsigned int *r_data)
{
@@ -357,6 +364,33 @@
return 0;
}
+static int sd_switch(unsigned int mode, unsigned char group,
+ unsigned char func)
+{
+ unsigned int group_shift = (group - 1U) * 4U;
+ unsigned int group_mask = GENMASK(group_shift + 3U, group_shift);
+ unsigned int arg;
+ int ret;
+
+ ret = ops->prepare(0, (uintptr_t)&sd_switch_func_status,
+ sizeof(sd_switch_func_status));
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* MMC CMD6: SWITCH_FUNC */
+ arg = mode | SD_SWITCH_ALL_GROUPS_MASK;
+ arg &= ~group_mask;
+ arg |= func << group_shift;
+ ret = mmc_send_cmd(MMC_CMD(6), arg, MMC_RESPONSE_R1, NULL);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return ops->read(0, (uintptr_t)&sd_switch_func_status,
+ sizeof(sd_switch_func_status));
+}
+
static int sd_send_op_cond(void)
{
int n;
@@ -524,7 +558,39 @@
return ret;
}
- return mmc_fill_device_info();
+ ret = mmc_fill_device_info();
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (is_sd_cmd6_enabled() &&
+ (mmc_dev_info->mmc_dev_type == MMC_IS_SD_HC)) {
+ /* Try to switch to High Speed Mode */
+ ret = sd_switch(SD_SWITCH_FUNC_CHECK, 1U, 1U);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if ((sd_switch_func_status.support_g1 & BIT(9)) == 0U) {
+ /* High speed not supported, keep default speed */
+ return 0;
+ }
+
+ ret = sd_switch(SD_SWITCH_FUNC_SWITCH, 1U, 1U);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if ((sd_switch_func_status.sel_g2_g1 & 0x1U) == 0U) {
+ /* Cannot switch to high speed, keep default speed */
+ return 0;
+ }
+
+ mmc_dev_info->max_bus_freq = 50000000U;
+ ret = ops->set_ios(clk, bus_width);
+ }
+
+ return ret;
}
size_t mmc_read_blocks(int lba, uintptr_t buf, size_t size)
@@ -694,90 +760,71 @@
return size;
}
-static inline void mmc_rpmb_enable(void)
-{
- mmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
- PART_CFG_BOOT_PARTITION1_ENABLE |
- PART_CFG_BOOT_PARTITION1_ACCESS);
-}
-
-static inline void mmc_rpmb_disable(void)
-{
- mmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
- PART_CFG_BOOT_PARTITION1_ENABLE);
-}
-
-size_t mmc_rpmb_read_blocks(int lba, uintptr_t buf, size_t size)
+static int mmc_part_switch(unsigned int part_type)
{
- size_t size_read;
+ uint8_t part_config = mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG];
- mmc_rpmb_enable();
- size_read = mmc_read_blocks(lba, buf, size);
- mmc_rpmb_disable();
+ part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
+ part_config |= part_type;
- return size_read;
+ return mmc_send_part_switch_cmd(part_config);
}
-size_t mmc_rpmb_write_blocks(int lba, const uintptr_t buf, size_t size)
+static unsigned char mmc_current_boot_part(void)
{
- size_t size_written;
-
- mmc_rpmb_enable();
- size_written = mmc_write_blocks(lba, buf, size);
- mmc_rpmb_disable();
-
- return size_written;
+ return PART_CFG_CURRENT_BOOT_PARTITION(mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG]);
}
-size_t mmc_rpmb_erase_blocks(int lba, size_t size)
+int mmc_part_switch_current_boot(void)
{
- size_t size_erased;
+ unsigned char current_boot_part = mmc_current_boot_part();
+ int ret;
- mmc_rpmb_enable();
- size_erased = mmc_erase_blocks(lba, size);
- mmc_rpmb_disable();
+ if (current_boot_part != 1U &&
+ current_boot_part != 2U) {
+ ERROR("Got unexpected value for active boot partition, %u\n", current_boot_part);
+ return -EIO;
+ }
- return size_erased;
+ ret = mmc_part_switch(current_boot_part);
+ if (ret < 0) {
+ ERROR("Failed to switch to boot partition, %d\n", ret);
+ }
+
+ return ret;
}
-static int mmc_part_switch(unsigned int part_type)
+int mmc_part_switch_user(void)
{
- uint8_t part_config = mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG];
+ int ret;
- part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
- part_config |= part_type;
+ ret = mmc_part_switch(PART_CFG_BOOT_PARTITION_NO_ACCESS);
+ if (ret < 0) {
+ ERROR("Failed to switch to user partition, %d\n", ret);
+ }
- return mmc_send_part_switch_cmd(part_config);
+ return ret;
}
-static unsigned char mmc_current_boot_part(void)
+size_t mmc_boot_part_size(void)
{
- return PART_CFG_CURRENT_BOOT_PARTITION(mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG]);
+ return mmc_ext_csd[CMD_EXTCSD_BOOT_SIZE_MULT] * SZ_128K;
}
size_t mmc_boot_part_read_blocks(int lba, uintptr_t buf, size_t size)
{
size_t size_read;
int ret;
- unsigned char current_boot_part = mmc_current_boot_part();
-
- if (current_boot_part != 1U &&
- current_boot_part != 2U) {
- ERROR("Got unexpected value for active boot partition, %u\n", current_boot_part);
- return 0;
- }
- ret = mmc_part_switch(current_boot_part);
+ ret = mmc_part_switch_current_boot();
if (ret < 0) {
- ERROR("Failed to switch to boot partition, %d\n", ret);
return 0;
}
size_read = mmc_read_blocks(lba, buf, size);
- ret = mmc_part_switch(0);
+ ret = mmc_part_switch_user();
if (ret < 0) {
- ERROR("Failed to switch back to user partition, %d\n", ret);
return 0;
}
diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
index 9f0331a..6ef2256 100644
--- a/drivers/mtd/nand/core.c
+++ b/drivers/mtd/nand/core.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,18 +8,29 @@
#include <errno.h>
#include <stddef.h>
-#include <platform_def.h>
-
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <drivers/nand.h>
#include <lib/utils.h>
+#include <platform_def.h>
+
/*
* Define a single nand_device used by specific NAND frameworks.
*/
static struct nand_device nand_dev;
-static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+
+#pragma weak plat_get_scratch_buffer
+void plat_get_scratch_buffer(void **buffer_addr, size_t *buf_size)
+{
+ static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+
+ assert(buffer_addr != NULL);
+ assert(buf_size != NULL);
+
+ *buffer_addr = (void *)scratch_buff;
+ *buf_size = sizeof(scratch_buff);
+}
int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
size_t *length_read)
@@ -34,6 +45,12 @@
unsigned int bytes_read;
int is_bad;
int ret;
+ uint8_t *scratch_buff;
+ size_t scratch_buff_size;
+
+ plat_get_scratch_buffer((void **)&scratch_buff, &scratch_buff_size);
+
+ assert(scratch_buff != NULL);
VERBOSE("Block %u - %u, page_start %u, nb %u, length %zu, offset %u\n",
block, end_block, page_start, nb_pages, length, offset);
@@ -41,7 +58,7 @@
*length_read = 0UL;
if (((start_offset != 0U) || (length % nand_dev.page_size) != 0U) &&
- (sizeof(scratch_buff) < nand_dev.page_size)) {
+ (scratch_buff_size < nand_dev.page_size)) {
return -EINVAL;
}
diff --git a/drivers/nxp/dcfg/dcfg.c b/drivers/nxp/dcfg/dcfg.c
index a988c5d..e5c4db4 100644
--- a/drivers/nxp/dcfg/dcfg.c
+++ b/drivers/nxp/dcfg/dcfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2021 NXP
+ * Copyright 2020-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -74,14 +74,11 @@
reg = gur_in32(dcfg_init_info->g_nxp_dcfg_addr + DCFG_DEVDISR5_OFFSET);
-#if defined(CONFIG_CHASSIS_3_2)
devdisr5_info.ddrc1_present = (reg & DISR5_DDRC1_MASK) ? 0 : 1;
+#if defined(CONFIG_CHASSIS_3_2)
devdisr5_info.ddrc2_present = (reg & DISR5_DDRC2_MASK) ? 0 : 1;
- devdisr5_info.ocram_present = (reg & DISR5_OCRAM_MASK) ? 0 : 1;
-#elif defined(CONFIG_CHASSIS_2)
- devdisr5_info.ddrc1_present = (reg & DISR5_DDRC1_MASK) ? 0 : 1;
- devdisr5_info.ocram_present = (reg & DISR5_OCRAM_MASK) ? 0 : 1;
#endif
+ devdisr5_info.ocram_present = (reg & DISR5_OCRAM_MASK) ? 0 : 1;
devdisr5_info.is_populated = true;
return (const devdisr5_info_t *) &devdisr5_info;
diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.mk b/drivers/nxp/ddr/nxp-ddr/ddr.mk
index 6bdd947..f827a1b 100644
--- a/drivers/nxp/ddr/nxp-ddr/ddr.mk
+++ b/drivers/nxp/ddr/nxp-ddr/ddr.mk
@@ -1,5 +1,5 @@
#
-# Copyright 2021 NXP
+# Copyright 2021-2022 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -19,6 +19,10 @@
$(eval $(call add_define,ERRATA_DDR_A050450))
endif
+ifeq (${ERRATA_DDR_A050958}, 1)
+$(eval $(call add_define,ERRATA_DDR_A050958))
+endif
+
endif
ifeq ($(PLAT_DDR_PHY), PHY_GEN1)
diff --git a/drivers/nxp/ddr/nxp-ddr/dimm.c b/drivers/nxp/ddr/nxp-ddr/dimm.c
index 16efcba..a82db6c 100644
--- a/drivers/nxp/ddr/nxp-ddr/dimm.c
+++ b/drivers/nxp/ddr/nxp-ddr/dimm.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -194,7 +194,7 @@
case DDR4_SPD_MINI_RDIMM:
case DDR4_SPD_72B_SO_RDIMM:
pdimm->rdimm = 1;
- pdimm->rc = spd->mod_section.registered.ref_raw_card & 0x8f;
+ pdimm->rc = spd->mod_section.registered.ref_raw_card & 0x9f;
if ((spd->mod_section.registered.reg_map & 0x1) != 0) {
pdimm->mirrored_dimm = 1;
}
@@ -223,7 +223,7 @@
case DDR4_SPD_72B_SO_UDIMM:
case DDR4_SPD_16B_SO_DIMM:
case DDR4_SPD_32B_SO_DIMM:
- pdimm->rc = spd->mod_section.unbuffered.ref_raw_card & 0x8f;
+ pdimm->rc = spd->mod_section.unbuffered.ref_raw_card & 0x9f;
if ((spd->mod_section.unbuffered.addr_mapping & 0x1) != 0) {
pdimm->mirrored_dimm = 1;
}
diff --git a/drivers/nxp/ddr/phy-gen2/phy.c b/drivers/nxp/ddr/phy-gen2/phy.c
index 9c84b00..9e52145 100644
--- a/drivers/nxp/ddr/phy-gen2/phy.c
+++ b/drivers/nxp/ddr/phy-gen2/phy.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
* SPDX-License-Identifier: BSD-3-Clause
*
*/
@@ -1673,6 +1673,10 @@
int sel_analog_vref = 1;
uint32_t addr;
+#ifdef ERRATA_DDR_A050958
+ gain_curr_adj_defval = 0x1f;
+#endif
+
dq_dqs_rcv_cntrl = gain_curr_adj_defval << csr_gain_curr_adj_lsb |
major_mode_dbyte << csr_major_mode_dbyte_lsb |
dfe_ctrl_defval << csr_dfe_ctrl_lsb |
@@ -2212,10 +2216,6 @@
size = PHY_GEN2_MAX_IMAGE_SIZE;
image_buf = (uintptr_t)phy_gen2_fw_img_buf;
- mmap_add_dynamic_region(phy_gen2_fw_img_buf,
- phy_gen2_fw_img_buf,
- PHY_GEN2_MAX_IMAGE_SIZE,
- MT_MEMORY | MT_RW | MT_SECURE);
ret = img_loadr(imem_id, &image_buf, &size);
if (ret != 0) {
ERROR("Failed to load %d firmware.\n", imem_id);
@@ -2584,6 +2584,15 @@
}
} else {
#endif
+ /* Mapping IMG buffer firstly */
+ ret = mmap_add_dynamic_region(priv->phy_gen2_fw_img_buf,
+ priv->phy_gen2_fw_img_buf,
+ PHY_GEN2_MAX_IMAGE_SIZE,
+ MT_MEMORY | MT_RW | MT_SECURE);
+ if (ret != 0) {
+ ERROR("Failed to add dynamic memory region.\n");
+ return ret;
+ }
debug("Load 1D firmware\n");
ret = load_fw(priv->phy, &input, 0, &msg_1d,
diff --git a/drivers/partition/gpt.c b/drivers/partition/gpt.c
index ee0bddf..4fe8322 100644
--- a/drivers/partition/gpt.c
+++ b/drivers/partition/gpt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -59,6 +59,7 @@
gpt_entry->first_lba + 1) *
PLAT_PARTITION_BLOCK_SIZE;
guidcpy(&entry->part_guid, &gpt_entry->unique_uuid);
+ guidcpy(&entry->type_guid, &gpt_entry->type_uuid);
return 0;
}
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 7706f88..1881c91 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,7 @@
#include <string.h>
#include <common/debug.h>
+#include <common/tf_crc32.h>
#include <drivers/io/io_storage.h>
#include <drivers/partition/efi.h>
#include <drivers/partition/partition.h>
@@ -76,7 +77,7 @@
}
/*
- * Load GPT header and check the GPT signature.
+ * Load GPT header and check the GPT signature and header CRC.
* If partition numbers could be found, check & update it.
*/
static int load_gpt_header(uintptr_t image_handle)
@@ -84,6 +85,7 @@
gpt_header_t header;
size_t bytes_read;
int result;
+ uint32_t header_crc, calc_crc;
result = io_seek(image_handle, IO_SEEK_SET, GPT_HEADER_OFFSET);
if (result != 0) {
@@ -99,6 +101,23 @@
return -EINVAL;
}
+ /*
+ * UEFI Spec 2.8 March 2019 Page 119: HeaderCRC32 value is
+ * computed by setting this field to 0, and computing the
+ * 32-bit CRC for HeaderSize bytes.
+ */
+ header_crc = header.header_crc;
+ header.header_crc = 0U;
+
+ calc_crc = tf_crc32(0U, (uint8_t *)&header, DEFAULT_GPT_HEADER_SIZE);
+ if (header_crc != calc_crc) {
+ ERROR("Invalid GPT Header CRC: Expected 0x%x but got 0x%x.\n",
+ header_crc, calc_crc);
+ return -EINVAL;
+ }
+
+ header.header_crc = header_crc;
+
/* partition numbers can't exceed PLAT_PARTITION_MAX_ENTRIES */
list.entry_count = header.list_num;
if (list.entry_count > PLAT_PARTITION_MAX_ENTRIES) {
@@ -247,6 +266,19 @@
return NULL;
}
+const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_uuid)
+{
+ int i;
+
+ for (i = 0; i < list.entry_count; i++) {
+ if (guidcmp(type_uuid, &list.list[i].type_guid) == 0) {
+ return &list.list[i];
+ }
+ }
+
+ return NULL;
+}
+
const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid)
{
int i;
diff --git a/drivers/scmi-msg/base.c b/drivers/scmi-msg/base.c
index 2d72034..2db4d7e 100644
--- a/drivers/scmi-msg/base.c
+++ b/drivers/scmi-msg/base.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
* Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2020, Linaro Limited
+ * Copyright (c) 2019-2022, Linaro Limited
*/
#include <assert.h>
#include <string.h>
@@ -131,15 +131,12 @@
return count;
}
-#define MAX_PROTOCOL_IN_LIST 8U
-
static void discover_list_protocols(struct scmi_msg *msg)
{
const struct scmi_base_discover_list_protocols_a2p *a2p = NULL;
struct scmi_base_discover_list_protocols_p2a p2a = {
.status = SCMI_SUCCESS,
};
- uint8_t outargs[sizeof(p2a) + MAX_PROTOCOL_IN_LIST] = { 0U };
const uint8_t *list = NULL;
unsigned int count = 0U;
@@ -148,24 +145,22 @@
return;
}
- assert(msg->out_size > sizeof(outargs));
-
a2p = (void *)msg->in;
list = plat_scmi_protocol_list(msg->agent_id);
count = count_protocols_in_list(list);
+
if (count > a2p->skip) {
- count = MIN(count - a2p->skip, MAX_PROTOCOL_IN_LIST);
+ count = MIN(count - a2p->skip, msg->out_size - sizeof(p2a));
} else {
count = 0U;
}
p2a.num_protocols = count;
- memcpy(outargs, &p2a, sizeof(p2a));
- memcpy(outargs + sizeof(p2a), list + a2p->skip, count);
-
- scmi_write_response(msg, outargs, sizeof(outargs));
+ memcpy(msg->out, &p2a, sizeof(p2a));
+ memcpy(msg->out + sizeof(p2a), list + a2p->skip, count);
+ msg->out_size_out = sizeof(p2a) + round_up(count, sizeof(uint32_t));
}
static const scmi_msg_handler_t scmi_base_handler_table[] = {
diff --git a/drivers/scmi-msg/clock.c b/drivers/scmi-msg/clock.c
index e96cede..85bf7d2 100644
--- a/drivers/scmi-msg/clock.c
+++ b/drivers/scmi-msg/clock.c
@@ -361,7 +361,7 @@
[SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set,
};
-static bool message_id_is_supported(size_t message_id)
+static bool message_id_is_supported(unsigned int message_id)
{
return (message_id < ARRAY_SIZE(scmi_clock_handler_table)) &&
(scmi_clock_handler_table[message_id] != NULL);
diff --git a/drivers/scmi-msg/power_domain.c b/drivers/scmi-msg/power_domain.c
index c4e1289..87c41dd 100644
--- a/drivers/scmi-msg/power_domain.c
+++ b/drivers/scmi-msg/power_domain.c
@@ -19,7 +19,7 @@
#pragma weak plat_scmi_pd_statistics
#pragma weak plat_scmi_pd_get_attributes
-static bool message_id_is_supported(size_t message_id);
+static bool message_id_is_supported(unsigned int message_id);
size_t plat_scmi_pd_count(unsigned int agent_id __unused)
{
@@ -219,7 +219,7 @@
[SCMI_PD_STATE_GET] = scmi_pd_state_get,
};
-static bool message_id_is_supported(size_t message_id)
+static bool message_id_is_supported(unsigned int message_id)
{
return (message_id < ARRAY_SIZE(scmi_pd_handler_table)) &&
(scmi_pd_handler_table[message_id] != NULL);
diff --git a/drivers/st/clk/clk-stm32-core.c b/drivers/st/clk/clk-stm32-core.c
new file mode 100644
index 0000000..bb03125
--- /dev/null
+++ b/drivers/st/clk/clk-stm32-core.c
@@ -0,0 +1,1096 @@
+/*
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include "clk-stm32-core.h"
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/clk.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp_clkfunc.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+
+static struct spinlock reg_lock;
+static struct spinlock refcount_lock;
+
+static struct stm32_clk_priv *stm32_clock_data;
+
+const struct stm32_clk_ops clk_mux_ops;
+
+struct stm32_clk_priv *clk_stm32_get_priv(void)
+{
+ return stm32_clock_data;
+}
+
+static void stm32mp1_clk_lock(struct spinlock *lock)
+{
+ if (stm32mp_lock_available()) {
+ /* Assume interrupts are masked */
+ spin_lock(lock);
+ }
+}
+
+static void stm32mp1_clk_unlock(struct spinlock *lock)
+{
+ if (stm32mp_lock_available()) {
+ spin_unlock(lock);
+ }
+}
+
+void stm32mp1_clk_rcc_regs_lock(void)
+{
+ stm32mp1_clk_lock(®_lock);
+}
+
+void stm32mp1_clk_rcc_regs_unlock(void)
+{
+ stm32mp1_clk_unlock(®_lock);
+}
+
+#define TIMEOUT_US_1S U(1000000)
+#define OSCRDY_TIMEOUT TIMEOUT_US_1S
+
+struct clk_oscillator_data *clk_oscillator_get_data(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct stm32_osc_cfg *osc_cfg = clk->clock_cfg;
+ int osc_id = osc_cfg->osc_id;
+
+ return &priv->osci_data[osc_id];
+}
+
+void clk_oscillator_set_bypass(struct stm32_clk_priv *priv, int id, bool digbyp, bool bypass)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
+
+ struct stm32_clk_bypass *bypass_data = osc_data->bypass;
+ uintptr_t address;
+
+ if (bypass_data == NULL) {
+ return;
+ }
+
+ address = priv->base + bypass_data->offset;
+
+ if (digbyp) {
+ mmio_setbits_32(address, BIT(bypass_data->bit_digbyp));
+ }
+
+ if (bypass || digbyp) {
+ mmio_setbits_32(address, BIT(bypass_data->bit_byp));
+ }
+}
+
+void clk_oscillator_set_css(struct stm32_clk_priv *priv, int id, bool css)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
+
+ struct stm32_clk_css *css_data = osc_data->css;
+ uintptr_t address;
+
+ if (css_data == NULL) {
+ return;
+ }
+
+ address = priv->base + css_data->offset;
+
+ if (css) {
+ mmio_setbits_32(address, BIT(css_data->bit_css));
+ }
+}
+
+void clk_oscillator_set_drive(struct stm32_clk_priv *priv, int id, uint8_t lsedrv)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
+
+ struct stm32_clk_drive *drive_data = osc_data->drive;
+ uintptr_t address;
+ uint32_t mask;
+ uint32_t value;
+
+ if (drive_data == NULL) {
+ return;
+ }
+
+ address = priv->base + drive_data->offset;
+
+ mask = (BIT(drive_data->drv_width) - 1U) << drive_data->drv_shift;
+
+ /*
+ * Warning: not recommended to switch directly from "high drive"
+ * to "medium low drive", and vice-versa.
+ */
+ value = (mmio_read_32(address) & mask) >> drive_data->drv_shift;
+
+ while (value != lsedrv) {
+ if (value > lsedrv) {
+ value--;
+ } else {
+ value++;
+ }
+
+ mmio_clrsetbits_32(address, mask, value << drive_data->drv_shift);
+ }
+}
+
+int clk_oscillator_wait_ready(struct stm32_clk_priv *priv, int id, bool ready_on)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
+
+ return _clk_stm32_gate_wait_ready(priv, osc_data->gate_rdy_id, ready_on);
+}
+
+int clk_oscillator_wait_ready_on(struct stm32_clk_priv *priv, int id)
+{
+ return clk_oscillator_wait_ready(priv, id, true);
+}
+
+int clk_oscillator_wait_ready_off(struct stm32_clk_priv *priv, int id)
+{
+ return clk_oscillator_wait_ready(priv, id, false);
+}
+
+static int clk_gate_enable(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct clk_gate_cfg *cfg = clk->clock_cfg;
+
+ mmio_setbits_32(priv->base + cfg->offset, BIT(cfg->bit_idx));
+
+ return 0;
+}
+
+static void clk_gate_disable(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct clk_gate_cfg *cfg = clk->clock_cfg;
+
+ mmio_clrbits_32(priv->base + cfg->offset, BIT(cfg->bit_idx));
+}
+
+static bool clk_gate_is_enabled(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct clk_gate_cfg *cfg = clk->clock_cfg;
+
+ return ((mmio_read_32(priv->base + cfg->offset) & BIT(cfg->bit_idx)) != 0U);
+}
+
+const struct stm32_clk_ops clk_gate_ops = {
+ .enable = clk_gate_enable,
+ .disable = clk_gate_disable,
+ .is_enabled = clk_gate_is_enabled,
+};
+
+void _clk_stm32_gate_disable(struct stm32_clk_priv *priv, uint16_t gate_id)
+{
+ const struct gate_cfg *gate = &priv->gates[gate_id];
+ uintptr_t addr = priv->base + gate->offset;
+
+ if (gate->set_clr != 0U) {
+ mmio_write_32(addr + RCC_MP_ENCLRR_OFFSET, BIT(gate->bit_idx));
+ } else {
+ mmio_clrbits_32(addr, BIT(gate->bit_idx));
+ }
+}
+
+int _clk_stm32_gate_enable(struct stm32_clk_priv *priv, uint16_t gate_id)
+{
+ const struct gate_cfg *gate = &priv->gates[gate_id];
+ uintptr_t addr = priv->base + gate->offset;
+
+ if (gate->set_clr != 0U) {
+ mmio_write_32(addr, BIT(gate->bit_idx));
+
+ } else {
+ mmio_setbits_32(addr, BIT(gate->bit_idx));
+ }
+
+ return 0;
+}
+
+const struct clk_stm32 *_clk_get(struct stm32_clk_priv *priv, int id)
+{
+ if ((unsigned int)id < priv->num) {
+ return &priv->clks[id];
+ }
+
+ return NULL;
+}
+
+#define clk_div_mask(_width) GENMASK(((_width) - 1U), 0U)
+
+static unsigned int _get_table_div(const struct clk_div_table *table,
+ unsigned int val)
+{
+ const struct clk_div_table *clkt;
+
+ for (clkt = table; clkt->div; clkt++) {
+ if (clkt->val == val) {
+ return clkt->div;
+ }
+ }
+
+ return 0;
+}
+
+static unsigned int _get_div(const struct clk_div_table *table,
+ unsigned int val, unsigned long flags,
+ uint8_t width)
+{
+ if ((flags & CLK_DIVIDER_ONE_BASED) != 0UL) {
+ return val;
+ }
+
+ if ((flags & CLK_DIVIDER_POWER_OF_TWO) != 0UL) {
+ return BIT(val);
+ }
+
+ if ((flags & CLK_DIVIDER_MAX_AT_ZERO) != 0UL) {
+ return (val != 0U) ? val : BIT(width);
+ }
+
+ if (table != NULL) {
+ return _get_table_div(table, val);
+ }
+
+ return val + 1U;
+}
+
+#define TIMEOUT_US_200MS U(200000)
+#define CLKSRC_TIMEOUT TIMEOUT_US_200MS
+
+int clk_mux_set_parent(struct stm32_clk_priv *priv, uint16_t pid, uint8_t sel)
+{
+ const struct parent_cfg *parents = &priv->parents[pid & MUX_PARENT_MASK];
+ const struct mux_cfg *mux = parents->mux;
+ uintptr_t address = priv->base + mux->offset;
+ uint32_t mask;
+ uint64_t timeout;
+
+ mask = MASK_WIDTH_SHIFT(mux->width, mux->shift);
+
+ mmio_clrsetbits_32(address, mask, (sel << mux->shift) & mask);
+
+ if (mux->bitrdy == MUX_NO_BIT_RDY) {
+ return 0;
+ }
+
+ timeout = timeout_init_us(CLKSRC_TIMEOUT);
+
+ mask = BIT(mux->bitrdy);
+
+ while ((mmio_read_32(address) & mask) == 0U) {
+ if (timeout_elapsed(timeout)) {
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+int _clk_stm32_set_parent(struct stm32_clk_priv *priv, int clk, int clkp)
+{
+ const struct parent_cfg *parents;
+ uint16_t pid;
+ uint8_t sel;
+ int old_parent;
+
+ pid = priv->clks[clk].parent;
+
+ if ((pid == CLK_IS_ROOT) || (pid < MUX_MAX_PARENTS)) {
+ return -EINVAL;
+ }
+
+ old_parent = _clk_stm32_get_parent(priv, clk);
+ if (old_parent < 0) {
+ return old_parent;
+ }
+ if (old_parent == clkp) {
+ return 0;
+ }
+
+ parents = &priv->parents[pid & MUX_PARENT_MASK];
+
+ for (sel = 0; sel < parents->num_parents; sel++) {
+ if (parents->id_parents[sel] == (uint16_t)clkp) {
+ bool clk_was_enabled = _clk_stm32_is_enabled(priv, clk);
+ int err = 0;
+
+ /* Enable the parents (for glitch free mux) */
+ _clk_stm32_enable(priv, clkp);
+ _clk_stm32_enable(priv, old_parent);
+
+ err = clk_mux_set_parent(priv, pid, sel);
+
+ _clk_stm32_disable(priv, old_parent);
+
+ if (clk_was_enabled) {
+ _clk_stm32_disable(priv, old_parent);
+ } else {
+ _clk_stm32_disable(priv, clkp);
+ }
+
+ return err;
+ }
+ }
+
+ return -EINVAL;
+}
+
+int clk_mux_get_parent(struct stm32_clk_priv *priv, uint32_t mux_id)
+{
+ const struct parent_cfg *parent;
+ const struct mux_cfg *mux;
+ uint32_t mask;
+
+ if (mux_id >= priv->nb_parents) {
+ panic();
+ }
+
+ parent = &priv->parents[mux_id];
+ mux = parent->mux;
+
+ mask = MASK_WIDTH_SHIFT(mux->width, mux->shift);
+
+ return (mmio_read_32(priv->base + mux->offset) & mask) >> mux->shift;
+}
+
+int _clk_stm32_set_parent_by_index(struct stm32_clk_priv *priv, int clk, int sel)
+{
+ uint16_t pid;
+
+ pid = priv->clks[clk].parent;
+
+ if ((pid == CLK_IS_ROOT) || (pid < MUX_MAX_PARENTS)) {
+ return -EINVAL;
+ }
+
+ return clk_mux_set_parent(priv, pid, sel);
+}
+
+int _clk_stm32_get_parent(struct stm32_clk_priv *priv, int clk_id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, clk_id);
+ const struct parent_cfg *parent;
+ uint16_t mux_id;
+ int sel;
+
+ mux_id = priv->clks[clk_id].parent;
+ if (mux_id == CLK_IS_ROOT) {
+ return CLK_IS_ROOT;
+ }
+
+ if (mux_id < MUX_MAX_PARENTS) {
+ return mux_id & MUX_PARENT_MASK;
+ }
+
+ mux_id &= MUX_PARENT_MASK;
+ parent = &priv->parents[mux_id];
+
+ if (clk->ops->get_parent != NULL) {
+ sel = clk->ops->get_parent(priv, clk_id);
+ } else {
+ sel = clk_mux_get_parent(priv, mux_id);
+ }
+
+ if ((sel >= 0) && (sel < parent->num_parents)) {
+ return parent->id_parents[sel];
+ }
+
+ return -EINVAL;
+}
+
+int _clk_stm32_get_parent_index(struct stm32_clk_priv *priv, int clk_id)
+{
+ uint16_t mux_id;
+
+ mux_id = priv->clks[clk_id].parent;
+ if (mux_id == CLK_IS_ROOT) {
+ return CLK_IS_ROOT;
+ }
+
+ if (mux_id < MUX_MAX_PARENTS) {
+ return mux_id & MUX_PARENT_MASK;
+ }
+
+ mux_id &= MUX_PARENT_MASK;
+
+ return clk_mux_get_parent(priv, mux_id);
+}
+
+int _clk_stm32_get_parent_by_index(struct stm32_clk_priv *priv, int clk_id, int idx)
+{
+ const struct parent_cfg *parent;
+ uint16_t mux_id;
+
+ mux_id = priv->clks[clk_id].parent;
+ if (mux_id == CLK_IS_ROOT) {
+ return CLK_IS_ROOT;
+ }
+
+ if (mux_id < MUX_MAX_PARENTS) {
+ return mux_id & MUX_PARENT_MASK;
+ }
+
+ mux_id &= MUX_PARENT_MASK;
+ parent = &priv->parents[mux_id];
+
+ if (idx < parent->num_parents) {
+ return parent->id_parents[idx];
+ }
+
+ return -EINVAL;
+}
+
+int clk_get_index(struct stm32_clk_priv *priv, unsigned long binding_id)
+{
+ unsigned int i;
+
+ for (i = 0U; i < priv->num; i++) {
+ if (binding_id == priv->clks[i].binding) {
+ return (int)i;
+ }
+ }
+
+ return -EINVAL;
+}
+
+unsigned long _clk_stm32_get_rate(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ int parent;
+ unsigned long rate = 0UL;
+
+ if ((unsigned int)id >= priv->num) {
+ return rate;
+ }
+
+ parent = _clk_stm32_get_parent(priv, id);
+ if (parent < 0) {
+ return 0UL;
+ }
+
+ if (clk->ops->recalc_rate != NULL) {
+ unsigned long prate = 0UL;
+
+ if (parent != CLK_IS_ROOT) {
+ prate = _clk_stm32_get_rate(priv, parent);
+ }
+
+ rate = clk->ops->recalc_rate(priv, id, prate);
+
+ return rate;
+ }
+
+ switch (parent) {
+ case CLK_IS_ROOT:
+ panic();
+
+ default:
+ rate = _clk_stm32_get_rate(priv, parent);
+ break;
+ }
+ return rate;
+
+}
+
+unsigned long _clk_stm32_get_parent_rate(struct stm32_clk_priv *priv, int id)
+{
+ int parent_id = _clk_stm32_get_parent(priv, id);
+
+ if (parent_id < 0) {
+ return 0UL;
+ }
+
+ return _clk_stm32_get_rate(priv, parent_id);
+}
+
+static uint8_t _stm32_clk_get_flags(struct stm32_clk_priv *priv, int id)
+{
+ return priv->clks[id].flags;
+}
+
+bool _stm32_clk_is_flags(struct stm32_clk_priv *priv, int id, uint8_t flag)
+{
+ if (_stm32_clk_get_flags(priv, id) & flag) {
+ return true;
+ }
+
+ return false;
+}
+
+int clk_stm32_enable_call_ops(struct stm32_clk_priv *priv, uint16_t id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+
+ if (clk->ops->enable != NULL) {
+ clk->ops->enable(priv, id);
+ }
+
+ return 0;
+}
+
+static int _clk_stm32_enable_core(struct stm32_clk_priv *priv, int id)
+{
+ int parent;
+ int ret = 0;
+
+ if (priv->gate_refcounts[id] == 0U) {
+ parent = _clk_stm32_get_parent(priv, id);
+ if (parent < 0) {
+ return parent;
+ }
+ if (parent != CLK_IS_ROOT) {
+ ret = _clk_stm32_enable_core(priv, parent);
+ if (ret) {
+ return ret;
+ }
+ }
+ clk_stm32_enable_call_ops(priv, id);
+ }
+
+ priv->gate_refcounts[id]++;
+
+ if (priv->gate_refcounts[id] == UINT_MAX) {
+ ERROR("%s: %d max enable count !", __func__, id);
+ panic();
+ }
+
+ return 0;
+}
+
+int _clk_stm32_enable(struct stm32_clk_priv *priv, int id)
+{
+ int ret;
+
+ stm32mp1_clk_lock(&refcount_lock);
+ ret = _clk_stm32_enable_core(priv, id);
+ stm32mp1_clk_unlock(&refcount_lock);
+
+ return ret;
+}
+
+void clk_stm32_disable_call_ops(struct stm32_clk_priv *priv, uint16_t id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+
+ if (clk->ops->disable != NULL) {
+ clk->ops->disable(priv, id);
+ }
+}
+
+static void _clk_stm32_disable_core(struct stm32_clk_priv *priv, int id)
+{
+ int parent;
+
+ if ((priv->gate_refcounts[id] == 1U) && _stm32_clk_is_flags(priv, id, CLK_IS_CRITICAL)) {
+ return;
+ }
+
+ if (priv->gate_refcounts[id] == 0U) {
+ /* case of clock ignore unused */
+ if (_clk_stm32_is_enabled(priv, id)) {
+ clk_stm32_disable_call_ops(priv, id);
+ return;
+ }
+ VERBOSE("%s: %d already disabled !\n\n", __func__, id);
+ return;
+ }
+
+ if (--priv->gate_refcounts[id] > 0U) {
+ return;
+ }
+
+ clk_stm32_disable_call_ops(priv, id);
+
+ parent = _clk_stm32_get_parent(priv, id);
+ if ((parent >= 0) && (parent != CLK_IS_ROOT)) {
+ _clk_stm32_disable_core(priv, parent);
+ }
+}
+
+void _clk_stm32_disable(struct stm32_clk_priv *priv, int id)
+{
+ stm32mp1_clk_lock(&refcount_lock);
+
+ _clk_stm32_disable_core(priv, id);
+
+ stm32mp1_clk_unlock(&refcount_lock);
+}
+
+bool _clk_stm32_is_enabled(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+
+ if (clk->ops->is_enabled != NULL) {
+ return clk->ops->is_enabled(priv, id);
+ }
+
+ return priv->gate_refcounts[id];
+}
+
+static int clk_stm32_enable(unsigned long binding_id)
+{
+ struct stm32_clk_priv *priv = clk_stm32_get_priv();
+ int id;
+
+ id = clk_get_index(priv, binding_id);
+ if (id == -EINVAL) {
+ return id;
+ }
+
+ return _clk_stm32_enable(priv, id);
+}
+
+static void clk_stm32_disable(unsigned long binding_id)
+{
+ struct stm32_clk_priv *priv = clk_stm32_get_priv();
+ int id;
+
+ id = clk_get_index(priv, binding_id);
+ if (id != -EINVAL) {
+ _clk_stm32_disable(priv, id);
+ }
+}
+
+static bool clk_stm32_is_enabled(unsigned long binding_id)
+{
+ struct stm32_clk_priv *priv = clk_stm32_get_priv();
+ int id;
+
+ id = clk_get_index(priv, binding_id);
+ if (id == -EINVAL) {
+ return false;
+ }
+
+ return _clk_stm32_is_enabled(priv, id);
+}
+
+static unsigned long clk_stm32_get_rate(unsigned long binding_id)
+{
+ struct stm32_clk_priv *priv = clk_stm32_get_priv();
+ int id;
+
+ id = clk_get_index(priv, binding_id);
+ if (id == -EINVAL) {
+ return 0UL;
+ }
+
+ return _clk_stm32_get_rate(priv, id);
+}
+
+static int clk_stm32_get_parent(unsigned long binding_id)
+{
+ struct stm32_clk_priv *priv = clk_stm32_get_priv();
+ int id;
+
+ id = clk_get_index(priv, binding_id);
+ if (id == -EINVAL) {
+ return id;
+ }
+
+ return _clk_stm32_get_parent(priv, id);
+}
+
+static const struct clk_ops stm32mp_clk_ops = {
+ .enable = clk_stm32_enable,
+ .disable = clk_stm32_disable,
+ .is_enabled = clk_stm32_is_enabled,
+ .get_rate = clk_stm32_get_rate,
+ .get_parent = clk_stm32_get_parent,
+};
+
+void clk_stm32_enable_critical_clocks(void)
+{
+ struct stm32_clk_priv *priv = clk_stm32_get_priv();
+ unsigned int i;
+
+ for (i = 0U; i < priv->num; i++) {
+ if (_stm32_clk_is_flags(priv, i, CLK_IS_CRITICAL)) {
+ _clk_stm32_enable(priv, i);
+ }
+ }
+}
+
+static void stm32_clk_register(void)
+{
+ clk_register(&stm32mp_clk_ops);
+}
+
+uint32_t clk_stm32_div_get_value(struct stm32_clk_priv *priv, int div_id)
+{
+ const struct div_cfg *divider = &priv->div[div_id];
+ uint32_t val = 0;
+
+ val = mmio_read_32(priv->base + divider->offset) >> divider->shift;
+ val &= clk_div_mask(divider->width);
+
+ return val;
+}
+
+unsigned long _clk_stm32_divider_recalc(struct stm32_clk_priv *priv,
+ int div_id,
+ unsigned long prate)
+{
+ const struct div_cfg *divider = &priv->div[div_id];
+ uint32_t val = clk_stm32_div_get_value(priv, div_id);
+ unsigned int div = 0U;
+
+ div = _get_div(divider->table, val, divider->flags, divider->width);
+ if (div == 0U) {
+ return prate;
+ }
+
+ return div_round_up((uint64_t)prate, div);
+}
+
+unsigned long clk_stm32_divider_recalc(struct stm32_clk_priv *priv, int id,
+ unsigned long prate)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct clk_stm32_div_cfg *div_cfg = clk->clock_cfg;
+
+ return _clk_stm32_divider_recalc(priv, div_cfg->id, prate);
+}
+
+const struct stm32_clk_ops clk_stm32_divider_ops = {
+ .recalc_rate = clk_stm32_divider_recalc,
+};
+
+int clk_stm32_set_div(struct stm32_clk_priv *priv, uint32_t div_id, uint32_t value)
+{
+ const struct div_cfg *divider;
+ uintptr_t address;
+ uint64_t timeout;
+ uint32_t mask;
+
+ if (div_id >= priv->nb_div) {
+ panic();
+ }
+
+ divider = &priv->div[div_id];
+ address = priv->base + divider->offset;
+
+ mask = MASK_WIDTH_SHIFT(divider->width, divider->shift);
+ mmio_clrsetbits_32(address, mask, (value << divider->shift) & mask);
+
+ if (divider->bitrdy == DIV_NO_BIT_RDY) {
+ return 0;
+ }
+
+ timeout = timeout_init_us(CLKSRC_TIMEOUT);
+ mask = BIT(divider->bitrdy);
+
+ while ((mmio_read_32(address) & mask) == 0U) {
+ if (timeout_elapsed(timeout)) {
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+int _clk_stm32_gate_wait_ready(struct stm32_clk_priv *priv, uint16_t gate_id,
+ bool ready_on)
+{
+ const struct gate_cfg *gate = &priv->gates[gate_id];
+ uintptr_t address = priv->base + gate->offset;
+ uint32_t mask_rdy = BIT(gate->bit_idx);
+ uint64_t timeout;
+ uint32_t mask_test;
+
+ if (ready_on) {
+ mask_test = BIT(gate->bit_idx);
+ } else {
+ mask_test = 0U;
+ }
+
+ timeout = timeout_init_us(OSCRDY_TIMEOUT);
+
+ while ((mmio_read_32(address) & mask_rdy) != mask_test) {
+ if (timeout_elapsed(timeout)) {
+ break;
+ }
+ }
+
+ if ((mmio_read_32(address) & mask_rdy) != mask_test) {
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+int clk_stm32_gate_enable(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct clk_stm32_gate_cfg *cfg = clk->clock_cfg;
+ const struct gate_cfg *gate = &priv->gates[cfg->id];
+ uintptr_t addr = priv->base + gate->offset;
+
+ if (gate->set_clr != 0U) {
+ mmio_write_32(addr, BIT(gate->bit_idx));
+
+ } else {
+ mmio_setbits_32(addr, BIT(gate->bit_idx));
+ }
+
+ return 0;
+}
+
+void clk_stm32_gate_disable(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct clk_stm32_gate_cfg *cfg = clk->clock_cfg;
+ const struct gate_cfg *gate = &priv->gates[cfg->id];
+ uintptr_t addr = priv->base + gate->offset;
+
+ if (gate->set_clr != 0U) {
+ mmio_write_32(addr + RCC_MP_ENCLRR_OFFSET, BIT(gate->bit_idx));
+ } else {
+ mmio_clrbits_32(addr, BIT(gate->bit_idx));
+ }
+}
+
+bool _clk_stm32_gate_is_enabled(struct stm32_clk_priv *priv, int gate_id)
+{
+ const struct gate_cfg *gate;
+ uint32_t addr;
+
+ gate = &priv->gates[gate_id];
+ addr = priv->base + gate->offset;
+
+ return ((mmio_read_32(addr) & BIT(gate->bit_idx)) != 0U);
+}
+
+bool clk_stm32_gate_is_enabled(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct clk_stm32_gate_cfg *cfg = clk->clock_cfg;
+
+ return _clk_stm32_gate_is_enabled(priv, cfg->id);
+}
+
+const struct stm32_clk_ops clk_stm32_gate_ops = {
+ .enable = clk_stm32_gate_enable,
+ .disable = clk_stm32_gate_disable,
+ .is_enabled = clk_stm32_gate_is_enabled,
+};
+
+const struct stm32_clk_ops clk_fixed_factor_ops = {
+ .recalc_rate = fixed_factor_recalc_rate,
+};
+
+unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
+ int id, unsigned long prate)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ const struct fixed_factor_cfg *cfg = clk->clock_cfg;
+ unsigned long long rate;
+
+ rate = (unsigned long long)prate * cfg->mult;
+
+ if (cfg->div == 0U) {
+ ERROR("division by zero\n");
+ panic();
+ }
+
+ return (unsigned long)(rate / cfg->div);
+};
+
+#define APB_DIV_MASK GENMASK(2, 0)
+#define TIM_PRE_MASK BIT(0)
+
+static unsigned long timer_recalc_rate(struct stm32_clk_priv *priv,
+ int id, unsigned long prate)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ const struct clk_timer_cfg *cfg = clk->clock_cfg;
+ uint32_t prescaler, timpre;
+ uintptr_t rcc_base = priv->base;
+
+ prescaler = mmio_read_32(rcc_base + cfg->apbdiv) &
+ APB_DIV_MASK;
+
+ timpre = mmio_read_32(rcc_base + cfg->timpre) &
+ TIM_PRE_MASK;
+
+ if (prescaler == 0U) {
+ return prate;
+ }
+
+ return prate * (timpre + 1U) * 2U;
+};
+
+const struct stm32_clk_ops clk_timer_ops = {
+ .recalc_rate = timer_recalc_rate,
+};
+
+static unsigned long clk_fixed_rate_recalc(struct stm32_clk_priv *priv, int id,
+ unsigned long prate)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct clk_stm32_fixed_rate_cfg *cfg = clk->clock_cfg;
+
+ return cfg->rate;
+}
+
+const struct stm32_clk_ops clk_stm32_fixed_rate_ops = {
+ .recalc_rate = clk_fixed_rate_recalc,
+};
+
+static unsigned long clk_stm32_osc_recalc_rate(struct stm32_clk_priv *priv,
+ int id, unsigned long prate)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
+
+ return osc_data->frequency;
+};
+
+bool clk_stm32_osc_gate_is_enabled(struct stm32_clk_priv *priv, int id)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
+
+ return _clk_stm32_gate_is_enabled(priv, osc_data->gate_id);
+
+}
+
+int clk_stm32_osc_gate_enable(struct stm32_clk_priv *priv, int id)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
+
+ _clk_stm32_gate_enable(priv, osc_data->gate_id);
+
+ if (_clk_stm32_gate_wait_ready(priv, osc_data->gate_rdy_id, true) != 0U) {
+ ERROR("%s: %s (%d)\n", __func__, osc_data->name, __LINE__);
+ panic();
+ }
+
+ return 0;
+}
+
+void clk_stm32_osc_gate_disable(struct stm32_clk_priv *priv, int id)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
+
+ _clk_stm32_gate_disable(priv, osc_data->gate_id);
+
+ if (_clk_stm32_gate_wait_ready(priv, osc_data->gate_rdy_id, false) != 0U) {
+ ERROR("%s: %s (%d)\n", __func__, osc_data->name, __LINE__);
+ panic();
+ }
+}
+
+static unsigned long clk_stm32_get_dt_oscillator_frequency(const char *name)
+{
+ void *fdt = NULL;
+ int node = 0;
+ int subnode = 0;
+
+ if (fdt_get_address(&fdt) == 0) {
+ panic();
+ }
+
+ node = fdt_path_offset(fdt, "/clocks");
+ if (node < 0) {
+ return 0UL;
+ }
+
+ fdt_for_each_subnode(subnode, fdt, node) {
+ const char *cchar = NULL;
+ const fdt32_t *cuint = NULL;
+ int ret = 0;
+
+ cchar = fdt_get_name(fdt, subnode, &ret);
+ if (cchar == NULL) {
+ continue;
+ }
+
+ if (strncmp(cchar, name, (size_t)ret) ||
+ fdt_get_status(subnode) == DT_DISABLED) {
+ continue;
+ }
+
+ cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret);
+ if (cuint == NULL) {
+ return 0UL;
+ }
+
+ return fdt32_to_cpu(*cuint);
+ }
+
+ return 0UL;
+}
+
+void clk_stm32_osc_init(struct stm32_clk_priv *priv, int id)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
+ const char *name = osc_data->name;
+
+ osc_data->frequency = clk_stm32_get_dt_oscillator_frequency(name);
+}
+
+const struct stm32_clk_ops clk_stm32_osc_ops = {
+ .recalc_rate = clk_stm32_osc_recalc_rate,
+ .is_enabled = clk_stm32_osc_gate_is_enabled,
+ .enable = clk_stm32_osc_gate_enable,
+ .disable = clk_stm32_osc_gate_disable,
+ .init = clk_stm32_osc_init,
+};
+
+const struct stm32_clk_ops clk_stm32_osc_nogate_ops = {
+ .recalc_rate = clk_stm32_osc_recalc_rate,
+ .init = clk_stm32_osc_init,
+};
+
+int stm32_clk_parse_fdt_by_name(void *fdt, int node, const char *name, uint32_t *tab, uint32_t *nb)
+{
+ const fdt32_t *cell;
+ int len = 0;
+ uint32_t i;
+
+ cell = fdt_getprop(fdt, node, name, &len);
+ if (cell == NULL) {
+ *nb = 0U;
+ return 0;
+ }
+
+ for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+ uint32_t val = fdt32_to_cpu(cell[i]);
+
+ tab[i] = val;
+ }
+
+ *nb = (uint32_t)len / sizeof(uint32_t);
+
+ return 0;
+}
+
+int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base)
+{
+ unsigned int i;
+
+ stm32_clock_data = priv;
+
+ priv->base = base;
+
+ for (i = 0U; i < priv->num; i++) {
+ const struct clk_stm32 *clk = _clk_get(priv, i);
+
+ assert(clk->ops != NULL);
+
+ if (clk->ops->init != NULL) {
+ clk->ops->init(priv, i);
+ }
+ }
+
+ stm32_clk_register();
+
+ return 0;
+}
diff --git a/drivers/st/clk/clk-stm32-core.h b/drivers/st/clk/clk-stm32-core.h
new file mode 100644
index 0000000..8bfb513
--- /dev/null
+++ b/drivers/st/clk/clk-stm32-core.h
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef CLK_STM32_CORE_H
+#define CLK_STM32_CORE_H
+
+struct mux_cfg {
+ uint16_t offset;
+ uint8_t shift;
+ uint8_t width;
+ uint8_t bitrdy;
+};
+
+struct gate_cfg {
+ uint16_t offset;
+ uint8_t bit_idx;
+ uint8_t set_clr;
+};
+
+struct clk_div_table {
+ unsigned int val;
+ unsigned int div;
+};
+
+struct div_cfg {
+ uint16_t offset;
+ uint8_t shift;
+ uint8_t width;
+ uint8_t flags;
+ uint8_t bitrdy;
+ const struct clk_div_table *table;
+};
+
+struct parent_cfg {
+ uint8_t num_parents;
+ const uint16_t *id_parents;
+ struct mux_cfg *mux;
+};
+
+struct stm32_clk_priv;
+
+struct stm32_clk_ops {
+ unsigned long (*recalc_rate)(struct stm32_clk_priv *priv, int id, unsigned long rate);
+ int (*get_parent)(struct stm32_clk_priv *priv, int id);
+ int (*set_rate)(struct stm32_clk_priv *priv, int id, unsigned long rate,
+ unsigned long prate);
+ int (*enable)(struct stm32_clk_priv *priv, int id);
+ void (*disable)(struct stm32_clk_priv *priv, int id);
+ bool (*is_enabled)(struct stm32_clk_priv *priv, int id);
+ void (*init)(struct stm32_clk_priv *priv, int id);
+};
+
+struct clk_stm32 {
+ uint16_t binding;
+ uint16_t parent;
+ uint8_t flags;
+ void *clock_cfg;
+ const struct stm32_clk_ops *ops;
+};
+
+struct stm32_clk_priv {
+ uintptr_t base;
+ const uint32_t num;
+ const struct clk_stm32 *clks;
+ const struct parent_cfg *parents;
+ const uint32_t nb_parents;
+ const struct gate_cfg *gates;
+ const uint32_t nb_gates;
+ const struct div_cfg *div;
+ const uint32_t nb_div;
+ struct clk_oscillator_data *osci_data;
+ const uint32_t nb_osci_data;
+ uint32_t *gate_refcounts;
+ void *pdata;
+};
+
+struct stm32_clk_bypass {
+ uint16_t offset;
+ uint8_t bit_byp;
+ uint8_t bit_digbyp;
+};
+
+struct stm32_clk_css {
+ uint16_t offset;
+ uint8_t bit_css;
+};
+
+struct stm32_clk_drive {
+ uint16_t offset;
+ uint8_t drv_shift;
+ uint8_t drv_width;
+ uint8_t drv_default;
+};
+
+struct clk_oscillator_data {
+ const char *name;
+ uint16_t id_clk;
+ unsigned long frequency;
+ uint16_t gate_id;
+ uint16_t gate_rdy_id;
+ struct stm32_clk_bypass *bypass;
+ struct stm32_clk_css *css;
+ struct stm32_clk_drive *drive;
+};
+
+struct clk_fixed_rate {
+ const char *name;
+ unsigned long fixed_rate;
+};
+
+struct clk_gate_cfg {
+ uint32_t offset;
+ uint8_t bit_idx;
+};
+
+/* CLOCK FLAGS */
+#define CLK_IS_CRITICAL BIT(0)
+#define CLK_IGNORE_UNUSED BIT(1)
+#define CLK_SET_RATE_PARENT BIT(2)
+
+#define CLK_DIVIDER_ONE_BASED BIT(0)
+#define CLK_DIVIDER_POWER_OF_TWO BIT(1)
+#define CLK_DIVIDER_ALLOW_ZERO BIT(2)
+#define CLK_DIVIDER_HIWORD_MASK BIT(3)
+#define CLK_DIVIDER_ROUND_CLOSEST BIT(4)
+#define CLK_DIVIDER_READ_ONLY BIT(5)
+#define CLK_DIVIDER_MAX_AT_ZERO BIT(6)
+#define CLK_DIVIDER_BIG_ENDIAN BIT(7)
+
+#define MUX_MAX_PARENTS U(0x8000)
+#define MUX_PARENT_MASK GENMASK(14, 0)
+#define MUX_FLAG U(0x8000)
+#define MUX(mux) ((mux) | MUX_FLAG)
+
+#define NO_GATE 0
+#define _NO_ID UINT16_MAX
+#define CLK_IS_ROOT UINT16_MAX
+#define MUX_NO_BIT_RDY UINT8_MAX
+#define DIV_NO_BIT_RDY UINT8_MAX
+
+#define MASK_WIDTH_SHIFT(_width, _shift) \
+ GENMASK(((_width) + (_shift) - 1U), (_shift))
+
+int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base);
+void clk_stm32_enable_critical_clocks(void);
+
+struct stm32_clk_priv *clk_stm32_get_priv(void);
+
+int clk_get_index(struct stm32_clk_priv *priv, unsigned long binding_id);
+const struct clk_stm32 *_clk_get(struct stm32_clk_priv *priv, int id);
+
+void clk_oscillator_set_bypass(struct stm32_clk_priv *priv, int id, bool digbyp, bool bypass);
+void clk_oscillator_set_drive(struct stm32_clk_priv *priv, int id, uint8_t lsedrv);
+void clk_oscillator_set_css(struct stm32_clk_priv *priv, int id, bool css);
+
+int _clk_stm32_gate_wait_ready(struct stm32_clk_priv *priv, uint16_t gate_id, bool ready_on);
+
+int clk_oscillator_wait_ready(struct stm32_clk_priv *priv, int id, bool ready_on);
+int clk_oscillator_wait_ready_on(struct stm32_clk_priv *priv, int id);
+int clk_oscillator_wait_ready_off(struct stm32_clk_priv *priv, int id);
+
+int clk_stm32_get_counter(unsigned long binding_id);
+
+void _clk_stm32_gate_disable(struct stm32_clk_priv *priv, uint16_t gate_id);
+int _clk_stm32_gate_enable(struct stm32_clk_priv *priv, uint16_t gate_id);
+
+int _clk_stm32_set_parent(struct stm32_clk_priv *priv, int id, int src_id);
+int _clk_stm32_set_parent_by_index(struct stm32_clk_priv *priv, int clk, int sel);
+
+int _clk_stm32_get_parent(struct stm32_clk_priv *priv, int id);
+int _clk_stm32_get_parent_by_index(struct stm32_clk_priv *priv, int clk_id, int idx);
+int _clk_stm32_get_parent_index(struct stm32_clk_priv *priv, int clk_id);
+
+unsigned long _clk_stm32_get_rate(struct stm32_clk_priv *priv, int id);
+unsigned long _clk_stm32_get_parent_rate(struct stm32_clk_priv *priv, int id);
+
+bool _stm32_clk_is_flags(struct stm32_clk_priv *priv, int id, uint8_t flag);
+
+int _clk_stm32_enable(struct stm32_clk_priv *priv, int id);
+void _clk_stm32_disable(struct stm32_clk_priv *priv, int id);
+
+int clk_stm32_enable_call_ops(struct stm32_clk_priv *priv, uint16_t id);
+void clk_stm32_disable_call_ops(struct stm32_clk_priv *priv, uint16_t id);
+
+bool _clk_stm32_is_enabled(struct stm32_clk_priv *priv, int id);
+
+int _clk_stm32_divider_set_rate(struct stm32_clk_priv *priv, int div_id,
+ unsigned long rate, unsigned long parent_rate);
+
+int clk_stm32_divider_set_rate(struct stm32_clk_priv *priv, int id, unsigned long rate,
+ unsigned long prate);
+
+unsigned long _clk_stm32_divider_recalc(struct stm32_clk_priv *priv,
+ int div_id,
+ unsigned long prate);
+
+unsigned long clk_stm32_divider_recalc(struct stm32_clk_priv *priv, int idx,
+ unsigned long prate);
+
+int clk_stm32_gate_enable(struct stm32_clk_priv *priv, int idx);
+void clk_stm32_gate_disable(struct stm32_clk_priv *priv, int idx);
+
+bool _clk_stm32_gate_is_enabled(struct stm32_clk_priv *priv, int gate_id);
+bool clk_stm32_gate_is_enabled(struct stm32_clk_priv *priv, int idx);
+
+uint32_t clk_stm32_div_get_value(struct stm32_clk_priv *priv, int div_id);
+int clk_stm32_set_div(struct stm32_clk_priv *priv, uint32_t div_id, uint32_t value);
+int clk_mux_set_parent(struct stm32_clk_priv *priv, uint16_t pid, uint8_t sel);
+int clk_mux_get_parent(struct stm32_clk_priv *priv, uint32_t mux_id);
+
+int stm32_clk_parse_fdt_by_name(void *fdt, int node, const char *name, uint32_t *tab, uint32_t *nb);
+
+#ifdef CFG_STM32_CLK_DEBUG
+void clk_stm32_display_clock_info(void);
+#endif
+
+struct clk_stm32_div_cfg {
+ int id;
+};
+
+#define STM32_DIV(idx, _binding, _parent, _flags, _div_id) \
+ [(idx)] = (struct clk_stm32){ \
+ .binding = (_binding),\
+ .parent = (_parent),\
+ .flags = (_flags),\
+ .clock_cfg = &(struct clk_stm32_div_cfg){\
+ .id = (_div_id),\
+ },\
+ .ops = &clk_stm32_divider_ops,\
+ }
+
+struct clk_stm32_gate_cfg {
+ int id;
+};
+
+#define STM32_GATE(idx, _binding, _parent, _flags, _gate_id) \
+ [(idx)] = (struct clk_stm32){ \
+ .binding = (_binding),\
+ .parent = (_parent),\
+ .flags = (_flags),\
+ .clock_cfg = &(struct clk_stm32_gate_cfg){\
+ .id = (_gate_id),\
+ },\
+ .ops = &clk_stm32_gate_ops,\
+ }
+
+struct fixed_factor_cfg {
+ unsigned int mult;
+ unsigned int div;
+};
+
+unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
+ int _idx, unsigned long prate);
+
+#define FIXED_FACTOR(idx, _idx, _parent, _mult, _div) \
+ [(idx)] = (struct clk_stm32){ \
+ .binding = (_idx),\
+ .parent = (_parent),\
+ .clock_cfg = &(struct fixed_factor_cfg){\
+ .mult = (_mult),\
+ .div = (_div),\
+ },\
+ .ops = &clk_fixed_factor_ops,\
+ }
+
+#define GATE(idx, _binding, _parent, _flags, _offset, _bit_idx) \
+ [(idx)] = (struct clk_stm32){ \
+ .binding = (_binding),\
+ .parent = (_parent),\
+ .flags = (_flags),\
+ .clock_cfg = &(struct clk_gate_cfg){\
+ .offset = (_offset),\
+ .bit_idx = (_bit_idx),\
+ },\
+ .ops = &clk_gate_ops,\
+ }
+
+#define STM32_MUX(idx, _binding, _mux_id, _flags) \
+ [(idx)] = (struct clk_stm32){ \
+ .binding = (_binding),\
+ .parent = (MUX(_mux_id)),\
+ .flags = (_flags),\
+ .clock_cfg = NULL,\
+ .ops = (&clk_mux_ops),\
+ }
+
+struct clk_timer_cfg {
+ uint32_t apbdiv;
+ uint32_t timpre;
+};
+
+#define CK_TIMER(idx, _idx, _parent, _flags, _apbdiv, _timpre) \
+ [(idx)] = (struct clk_stm32){ \
+ .binding = (_idx),\
+ .parent = (_parent),\
+ .flags = (CLK_SET_RATE_PARENT | (_flags)),\
+ .clock_cfg = &(struct clk_timer_cfg){\
+ .apbdiv = (_apbdiv),\
+ .timpre = (_timpre),\
+ },\
+ .ops = &clk_timer_ops,\
+ }
+
+struct clk_stm32_fixed_rate_cfg {
+ unsigned long rate;
+};
+
+#define CLK_FIXED_RATE(idx, _binding, _rate) \
+ [(idx)] = (struct clk_stm32){ \
+ .binding = (_binding),\
+ .parent = (CLK_IS_ROOT),\
+ .clock_cfg = &(struct clk_stm32_fixed_rate_cfg){\
+ .rate = (_rate),\
+ },\
+ .ops = &clk_stm32_fixed_rate_ops,\
+ }
+
+#define BYPASS(_offset, _bit_byp, _bit_digbyp) &(struct stm32_clk_bypass){\
+ .offset = (_offset),\
+ .bit_byp = (_bit_byp),\
+ .bit_digbyp = (_bit_digbyp),\
+}
+
+#define CSS(_offset, _bit_css) &(struct stm32_clk_css){\
+ .offset = (_offset),\
+ .bit_css = (_bit_css),\
+}
+
+#define DRIVE(_offset, _shift, _width, _default) &(struct stm32_clk_drive){\
+ .offset = (_offset),\
+ .drv_shift = (_shift),\
+ .drv_width = (_width),\
+ .drv_default = (_default),\
+}
+
+#define OSCILLATOR(idx_osc, _id, _name, _gate_id, _gate_rdy_id, _bypass, _css, _drive) \
+ [(idx_osc)] = (struct clk_oscillator_data){\
+ .name = (_name),\
+ .id_clk = (_id),\
+ .gate_id = (_gate_id),\
+ .gate_rdy_id = (_gate_rdy_id),\
+ .bypass = (_bypass),\
+ .css = (_css),\
+ .drive = (_drive),\
+ }
+
+struct clk_oscillator_data *clk_oscillator_get_data(struct stm32_clk_priv *priv, int id);
+
+void clk_stm32_osc_init(struct stm32_clk_priv *priv, int id);
+bool clk_stm32_osc_gate_is_enabled(struct stm32_clk_priv *priv, int id);
+int clk_stm32_osc_gate_enable(struct stm32_clk_priv *priv, int id);
+void clk_stm32_osc_gate_disable(struct stm32_clk_priv *priv, int id);
+
+struct stm32_osc_cfg {
+ int osc_id;
+};
+
+#define CLK_OSC(idx, _idx, _parent, _osc_id) \
+ [(idx)] = (struct clk_stm32){ \
+ .binding = (_idx),\
+ .parent = (_parent),\
+ .flags = CLK_IS_CRITICAL,\
+ .clock_cfg = &(struct stm32_osc_cfg){\
+ .osc_id = (_osc_id),\
+ },\
+ .ops = &clk_stm32_osc_ops,\
+ }
+
+#define CLK_OSC_FIXED(idx, _idx, _parent, _osc_id) \
+ [(idx)] = (struct clk_stm32){ \
+ .binding = (_idx),\
+ .parent = (_parent),\
+ .flags = CLK_IS_CRITICAL,\
+ .clock_cfg = &(struct stm32_osc_cfg){\
+ .osc_id = (_osc_id),\
+ },\
+ .ops = &clk_stm32_osc_nogate_ops,\
+ }
+
+extern const struct stm32_clk_ops clk_mux_ops;
+extern const struct stm32_clk_ops clk_stm32_divider_ops;
+extern const struct stm32_clk_ops clk_stm32_gate_ops;
+extern const struct stm32_clk_ops clk_fixed_factor_ops;
+extern const struct stm32_clk_ops clk_gate_ops;
+extern const struct stm32_clk_ops clk_timer_ops;
+extern const struct stm32_clk_ops clk_stm32_fixed_rate_ops;
+extern const struct stm32_clk_ops clk_stm32_osc_ops;
+extern const struct stm32_clk_ops clk_stm32_osc_nogate_ops;
+
+#endif /* CLK_STM32_CORE_H */
diff --git a/drivers/st/clk/clk-stm32mp13.c b/drivers/st/clk/clk-stm32mp13.c
new file mode 100644
index 0000000..c960928
--- /dev/null
+++ b/drivers/st/clk/clk-stm32mp13.c
@@ -0,0 +1,2332 @@
+/*
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include "clk-stm32-core.h"
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/clk.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp13_rcc.h>
+#include <drivers/st/stm32mp1_clk.h>
+#include <drivers/st/stm32mp_clkfunc.h>
+#include <dt-bindings/clock/stm32mp13-clksrc.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <lib/utils_def.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+struct stm32_osci_dt_cfg {
+ unsigned long freq;
+ bool bypass;
+ bool digbyp;
+ bool css;
+ uint32_t drive;
+};
+
+enum pll_mn {
+ PLL_CFG_M,
+ PLL_CFG_N,
+ PLL_DIV_MN_NB
+};
+
+enum pll_pqr {
+ PLL_CFG_P,
+ PLL_CFG_Q,
+ PLL_CFG_R,
+ PLL_DIV_PQR_NB
+};
+
+enum pll_csg {
+ PLL_CSG_MOD_PER,
+ PLL_CSG_INC_STEP,
+ PLL_CSG_SSCG_MODE,
+ PLL_CSG_NB
+};
+
+struct stm32_pll_vco {
+ uint32_t status;
+ uint32_t src;
+ uint32_t div_mn[PLL_DIV_MN_NB];
+ uint32_t frac;
+ bool csg_enabled;
+ uint32_t csg[PLL_CSG_NB];
+};
+
+struct stm32_pll_output {
+ uint32_t output[PLL_DIV_PQR_NB];
+};
+
+struct stm32_pll_dt_cfg {
+ struct stm32_pll_vco vco;
+ struct stm32_pll_output output;
+};
+
+struct stm32_clk_platdata {
+ uint32_t nosci;
+ struct stm32_osci_dt_cfg *osci;
+ uint32_t npll;
+ struct stm32_pll_dt_cfg *pll;
+ uint32_t nclksrc;
+ uint32_t *clksrc;
+ uint32_t nclkdiv;
+ uint32_t *clkdiv;
+};
+
+enum stm32_clock {
+ /* ROOT CLOCKS */
+ _CK_OFF,
+ _CK_HSI,
+ _CK_HSE,
+ _CK_CSI,
+ _CK_LSI,
+ _CK_LSE,
+ _I2SCKIN,
+ _CSI_DIV122,
+ _HSE_DIV,
+ _HSE_DIV2,
+ _CK_PLL1,
+ _CK_PLL2,
+ _CK_PLL3,
+ _CK_PLL4,
+ _PLL1P,
+ _PLL1P_DIV,
+ _PLL2P,
+ _PLL2Q,
+ _PLL2R,
+ _PLL3P,
+ _PLL3Q,
+ _PLL3R,
+ _PLL4P,
+ _PLL4Q,
+ _PLL4R,
+ _PCLK1,
+ _PCLK2,
+ _PCLK3,
+ _PCLK4,
+ _PCLK5,
+ _PCLK6,
+ _CKMPU,
+ _CKAXI,
+ _CKMLAHB,
+ _CKPER,
+ _CKTIMG1,
+ _CKTIMG2,
+ _CKTIMG3,
+ _USB_PHY_48,
+ _MCO1_K,
+ _MCO2_K,
+ _TRACECK,
+ /* BUS and KERNEL CLOCKS */
+ _DDRC1,
+ _DDRC1LP,
+ _DDRPHYC,
+ _DDRPHYCLP,
+ _DDRCAPB,
+ _DDRCAPBLP,
+ _AXIDCG,
+ _DDRPHYCAPB,
+ _DDRPHYCAPBLP,
+ _SYSCFG,
+ _DDRPERFM,
+ _IWDG2APB,
+ _USBPHY_K,
+ _USBO_K,
+ _RTCAPB,
+ _TZC,
+ _ETZPC,
+ _IWDG1APB,
+ _BSEC,
+ _STGENC,
+ _USART1_K,
+ _USART2_K,
+ _I2C3_K,
+ _I2C4_K,
+ _I2C5_K,
+ _TIM12,
+ _TIM15,
+ _RTCCK,
+ _GPIOA,
+ _GPIOB,
+ _GPIOC,
+ _GPIOD,
+ _GPIOE,
+ _GPIOF,
+ _GPIOG,
+ _GPIOH,
+ _GPIOI,
+ _PKA,
+ _SAES_K,
+ _CRYP1,
+ _HASH1,
+ _RNG1_K,
+ _BKPSRAM,
+ _SDMMC1_K,
+ _SDMMC2_K,
+ _DBGCK,
+ _USART3_K,
+ _UART4_K,
+ _UART5_K,
+ _UART7_K,
+ _UART8_K,
+ _USART6_K,
+ _MCE,
+ _FMC_K,
+ _QSPI_K,
+#if defined(IMAGE_BL32)
+ _LTDC,
+ _DMA1,
+ _DMA2,
+ _MDMA,
+ _ETH1MAC,
+ _USBH,
+ _TIM2,
+ _TIM3,
+ _TIM4,
+ _TIM5,
+ _TIM6,
+ _TIM7,
+ _LPTIM1_K,
+ _SPI2_K,
+ _SPI3_K,
+ _SPDIF_K,
+ _TIM1,
+ _TIM8,
+ _SPI1_K,
+ _SAI1_K,
+ _SAI2_K,
+ _DFSDM,
+ _FDCAN_K,
+ _TIM13,
+ _TIM14,
+ _TIM16,
+ _TIM17,
+ _SPI4_K,
+ _SPI5_K,
+ _I2C1_K,
+ _I2C2_K,
+ _ADFSDM,
+ _LPTIM2_K,
+ _LPTIM3_K,
+ _LPTIM4_K,
+ _LPTIM5_K,
+ _VREF,
+ _DTS,
+ _PMBCTRL,
+ _HDP,
+ _STGENRO,
+ _DCMIPP_K,
+ _DMAMUX1,
+ _DMAMUX2,
+ _DMA3,
+ _ADC1_K,
+ _ADC2_K,
+ _TSC,
+ _AXIMC,
+ _ETH1CK,
+ _ETH1TX,
+ _ETH1RX,
+ _CRC1,
+ _ETH2CK,
+ _ETH2TX,
+ _ETH2RX,
+ _ETH2MAC,
+#endif
+ CK_LAST
+};
+
+/* PARENT CONFIG */
+static const uint16_t RTC_src[] = {
+ _CK_OFF, _CK_LSE, _CK_LSI, _CK_HSE
+};
+
+static const uint16_t MCO1_src[] = {
+ _CK_HSI, _CK_HSE, _CK_CSI, _CK_LSI, _CK_LSE
+};
+
+static const uint16_t MCO2_src[] = {
+ _CKMPU, _CKAXI, _CKMLAHB, _PLL4P, _CK_HSE, _CK_HSI
+};
+
+static const uint16_t PLL12_src[] = {
+ _CK_HSI, _CK_HSE
+};
+
+static const uint16_t PLL3_src[] = {
+ _CK_HSI, _CK_HSE, _CK_CSI
+};
+
+static const uint16_t PLL4_src[] = {
+ _CK_HSI, _CK_HSE, _CK_CSI, _I2SCKIN
+};
+
+static const uint16_t MPU_src[] = {
+ _CK_HSI, _CK_HSE, _PLL1P, _PLL1P_DIV
+};
+
+static const uint16_t AXI_src[] = {
+ _CK_HSI, _CK_HSE, _PLL2P
+};
+
+static const uint16_t MLAHBS_src[] = {
+ _CK_HSI, _CK_HSE, _CK_CSI, _PLL3P
+};
+
+static const uint16_t CKPER_src[] = {
+ _CK_HSI, _CK_CSI, _CK_HSE, _CK_OFF
+};
+
+static const uint16_t I2C12_src[] = {
+ _PCLK1, _PLL4R, _CK_HSI, _CK_CSI
+};
+
+static const uint16_t I2C3_src[] = {
+ _PCLK6, _PLL4R, _CK_HSI, _CK_CSI
+};
+
+static const uint16_t I2C4_src[] = {
+ _PCLK6, _PLL4R, _CK_HSI, _CK_CSI
+};
+
+static const uint16_t I2C5_src[] = {
+ _PCLK6, _PLL4R, _CK_HSI, _CK_CSI
+};
+
+static const uint16_t SPI1_src[] = {
+ _PLL4P, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R
+};
+
+static const uint16_t SPI23_src[] = {
+ _PLL4P, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R
+};
+
+static const uint16_t SPI4_src[] = {
+ _PCLK6, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE, _I2SCKIN
+};
+
+static const uint16_t SPI5_src[] = {
+ _PCLK6, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
+};
+
+static const uint16_t UART1_src[] = {
+ _PCLK6, _PLL3Q, _CK_HSI, _CK_CSI, _PLL4Q, _CK_HSE
+};
+
+static const uint16_t UART2_src[] = {
+ _PCLK6, _PLL3Q, _CK_HSI, _CK_CSI, _PLL4Q, _CK_HSE
+};
+
+static const uint16_t UART35_src[] = {
+ _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
+};
+
+static const uint16_t UART4_src[] = {
+ _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
+};
+
+static const uint16_t UART6_src[] = {
+ _PCLK2, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
+};
+
+static const uint16_t UART78_src[] = {
+ _PCLK1, _PLL4Q, _CK_HSI, _CK_CSI, _CK_HSE
+};
+
+static const uint16_t LPTIM1_src[] = {
+ _PCLK1, _PLL4P, _PLL3Q, _CK_LSE, _CK_LSI, _CKPER
+};
+
+static const uint16_t LPTIM2_src[] = {
+ _PCLK3, _PLL4Q, _CKPER, _CK_LSE, _CK_LSI
+};
+
+static const uint16_t LPTIM3_src[] = {
+ _PCLK3, _PLL4Q, _CKPER, _CK_LSE, _CK_LSI
+};
+
+static const uint16_t LPTIM45_src[] = {
+ _PCLK3, _PLL4P, _PLL3Q, _CK_LSE, _CK_LSI, _CKPER
+};
+
+static const uint16_t SAI1_src[] = {
+ _PLL4Q, _PLL3Q, _I2SCKIN, _CKPER, _PLL3R
+};
+
+static const uint16_t SAI2_src[] = {
+ _PLL4Q, _PLL3Q, _I2SCKIN, _CKPER, _NO_ID, _PLL3R
+};
+
+static const uint16_t FDCAN_src[] = {
+ _CK_HSE, _PLL3Q, _PLL4Q, _PLL4R
+};
+
+static const uint16_t SPDIF_src[] = {
+ _PLL4P, _PLL3Q, _CK_HSI
+};
+
+static const uint16_t ADC1_src[] = {
+ _PLL4R, _CKPER, _PLL3Q
+};
+
+static const uint16_t ADC2_src[] = {
+ _PLL4R, _CKPER, _PLL3Q
+};
+
+static const uint16_t SDMMC1_src[] = {
+ _CKAXI, _PLL3R, _PLL4P, _CK_HSI
+};
+
+static const uint16_t SDMMC2_src[] = {
+ _CKAXI, _PLL3R, _PLL4P, _CK_HSI
+};
+
+static const uint16_t ETH1_src[] = {
+ _PLL4P, _PLL3Q
+};
+
+static const uint16_t ETH2_src[] = {
+ _PLL4P, _PLL3Q
+};
+
+static const uint16_t USBPHY_src[] = {
+ _CK_HSE, _PLL4R, _HSE_DIV2
+};
+
+static const uint16_t USBO_src[] = {
+ _PLL4R, _USB_PHY_48
+};
+
+static const uint16_t QSPI_src[] = {
+ _CKAXI, _PLL3R, _PLL4P, _CKPER
+};
+
+static const uint16_t FMC_src[] = {
+ _CKAXI, _PLL3R, _PLL4P, _CKPER
+};
+
+/* Position 2 of RNG1 mux is reserved */
+static const uint16_t RNG1_src[] = {
+ _CK_CSI, _PLL4R, _CK_OFF, _CK_LSI
+};
+
+static const uint16_t STGEN_src[] = {
+ _CK_HSI, _CK_HSE
+};
+
+static const uint16_t DCMIPP_src[] = {
+ _CKAXI, _PLL2Q, _PLL4P, _CKPER
+};
+
+static const uint16_t SAES_src[] = {
+ _CKAXI, _CKPER, _PLL4R, _CK_LSI
+};
+
+#define MUX_CFG(id, src, _offset, _shift, _witdh)[id] = {\
+ .id_parents = src,\
+ .num_parents = ARRAY_SIZE(src),\
+ .mux = &(struct mux_cfg) {\
+ .offset = (_offset),\
+ .shift = (_shift),\
+ .width = (_witdh),\
+ .bitrdy = MUX_NO_BIT_RDY,\
+ },\
+}
+
+#define MUX_RDY_CFG(id, src, _offset, _shift, _witdh)[id] = {\
+ .id_parents = src,\
+ .num_parents = ARRAY_SIZE(src),\
+ .mux = &(struct mux_cfg) {\
+ .offset = (_offset),\
+ .shift = (_shift),\
+ .width = (_witdh),\
+ .bitrdy = 31,\
+ },\
+}
+
+static const struct parent_cfg parent_mp13[] = {
+ MUX_CFG(MUX_ADC1, ADC1_src, RCC_ADC12CKSELR, 0, 2),
+ MUX_CFG(MUX_ADC2, ADC2_src, RCC_ADC12CKSELR, 2, 2),
+ MUX_RDY_CFG(MUX_AXI, AXI_src, RCC_ASSCKSELR, 0, 3),
+ MUX_CFG(MUX_CKPER, CKPER_src, RCC_CPERCKSELR, 0, 2),
+ MUX_CFG(MUX_DCMIPP, DCMIPP_src, RCC_DCMIPPCKSELR, 0, 2),
+ MUX_CFG(MUX_ETH1, ETH1_src, RCC_ETH12CKSELR, 0, 2),
+ MUX_CFG(MUX_ETH2, ETH2_src, RCC_ETH12CKSELR, 8, 2),
+ MUX_CFG(MUX_FDCAN, FDCAN_src, RCC_FDCANCKSELR, 0, 2),
+ MUX_CFG(MUX_FMC, FMC_src, RCC_FMCCKSELR, 0, 2),
+ MUX_CFG(MUX_I2C12, I2C12_src, RCC_I2C12CKSELR, 0, 3),
+ MUX_CFG(MUX_I2C3, I2C3_src, RCC_I2C345CKSELR, 0, 3),
+ MUX_CFG(MUX_I2C4, I2C4_src, RCC_I2C345CKSELR, 3, 3),
+ MUX_CFG(MUX_I2C5, I2C5_src, RCC_I2C345CKSELR, 6, 3),
+ MUX_CFG(MUX_LPTIM1, LPTIM1_src, RCC_LPTIM1CKSELR, 0, 3),
+ MUX_CFG(MUX_LPTIM2, LPTIM2_src, RCC_LPTIM23CKSELR, 0, 3),
+ MUX_CFG(MUX_LPTIM3, LPTIM3_src, RCC_LPTIM23CKSELR, 3, 3),
+ MUX_CFG(MUX_LPTIM45, LPTIM45_src, RCC_LPTIM45CKSELR, 0, 3),
+ MUX_CFG(MUX_MCO1, MCO1_src, RCC_MCO1CFGR, 0, 3),
+ MUX_CFG(MUX_MCO2, MCO2_src, RCC_MCO2CFGR, 0, 3),
+ MUX_RDY_CFG(MUX_MLAHB, MLAHBS_src, RCC_MSSCKSELR, 0, 2),
+ MUX_RDY_CFG(MUX_MPU, MPU_src, RCC_MPCKSELR, 0, 2),
+ MUX_RDY_CFG(MUX_PLL12, PLL12_src, RCC_RCK12SELR, 0, 2),
+ MUX_RDY_CFG(MUX_PLL3, PLL3_src, RCC_RCK3SELR, 0, 2),
+ MUX_RDY_CFG(MUX_PLL4, PLL4_src, RCC_RCK4SELR, 0, 2),
+ MUX_CFG(MUX_QSPI, QSPI_src, RCC_QSPICKSELR, 0, 2),
+ MUX_CFG(MUX_RNG1, RNG1_src, RCC_RNG1CKSELR, 0, 2),
+ MUX_CFG(MUX_RTC, RTC_src, RCC_BDCR, 16, 2),
+ MUX_CFG(MUX_SAES, SAES_src, RCC_SAESCKSELR, 0, 2),
+ MUX_CFG(MUX_SAI1, SAI1_src, RCC_SAI1CKSELR, 0, 3),
+ MUX_CFG(MUX_SAI2, SAI2_src, RCC_SAI2CKSELR, 0, 3),
+ MUX_CFG(MUX_SDMMC1, SDMMC1_src, RCC_SDMMC12CKSELR, 0, 3),
+ MUX_CFG(MUX_SDMMC2, SDMMC2_src, RCC_SDMMC12CKSELR, 3, 3),
+ MUX_CFG(MUX_SPDIF, SPDIF_src, RCC_SPDIFCKSELR, 0, 2),
+ MUX_CFG(MUX_SPI1, SPI1_src, RCC_SPI2S1CKSELR, 0, 3),
+ MUX_CFG(MUX_SPI23, SPI23_src, RCC_SPI2S23CKSELR, 0, 3),
+ MUX_CFG(MUX_SPI4, SPI4_src, RCC_SPI45CKSELR, 0, 3),
+ MUX_CFG(MUX_SPI5, SPI5_src, RCC_SPI45CKSELR, 3, 3),
+ MUX_CFG(MUX_STGEN, STGEN_src, RCC_STGENCKSELR, 0, 2),
+ MUX_CFG(MUX_UART1, UART1_src, RCC_UART12CKSELR, 0, 3),
+ MUX_CFG(MUX_UART2, UART2_src, RCC_UART12CKSELR, 3, 3),
+ MUX_CFG(MUX_UART35, UART35_src, RCC_UART35CKSELR, 0, 3),
+ MUX_CFG(MUX_UART4, UART4_src, RCC_UART4CKSELR, 0, 3),
+ MUX_CFG(MUX_UART6, UART6_src, RCC_UART6CKSELR, 0, 3),
+ MUX_CFG(MUX_UART78, UART78_src, RCC_UART78CKSELR, 0, 3),
+ MUX_CFG(MUX_USBO, USBO_src, RCC_USBCKSELR, 4, 1),
+ MUX_CFG(MUX_USBPHY, USBPHY_src, RCC_USBCKSELR, 0, 2),
+};
+
+/*
+ * GATE CONFIG
+ */
+
+enum enum_gate_cfg {
+ GATE_ZERO, /* reserved for no gate */
+ GATE_LSE,
+ GATE_RTCCK,
+ GATE_LSI,
+ GATE_HSI,
+ GATE_CSI,
+ GATE_HSE,
+ GATE_LSI_RDY,
+ GATE_CSI_RDY,
+ GATE_LSE_RDY,
+ GATE_HSE_RDY,
+ GATE_HSI_RDY,
+ GATE_MCO1,
+ GATE_MCO2,
+ GATE_DBGCK,
+ GATE_TRACECK,
+ GATE_PLL1,
+ GATE_PLL1_DIVP,
+ GATE_PLL1_DIVQ,
+ GATE_PLL1_DIVR,
+ GATE_PLL2,
+ GATE_PLL2_DIVP,
+ GATE_PLL2_DIVQ,
+ GATE_PLL2_DIVR,
+ GATE_PLL3,
+ GATE_PLL3_DIVP,
+ GATE_PLL3_DIVQ,
+ GATE_PLL3_DIVR,
+ GATE_PLL4,
+ GATE_PLL4_DIVP,
+ GATE_PLL4_DIVQ,
+ GATE_PLL4_DIVR,
+ GATE_DDRC1,
+ GATE_DDRC1LP,
+ GATE_DDRPHYC,
+ GATE_DDRPHYCLP,
+ GATE_DDRCAPB,
+ GATE_DDRCAPBLP,
+ GATE_AXIDCG,
+ GATE_DDRPHYCAPB,
+ GATE_DDRPHYCAPBLP,
+ GATE_TIM2,
+ GATE_TIM3,
+ GATE_TIM4,
+ GATE_TIM5,
+ GATE_TIM6,
+ GATE_TIM7,
+ GATE_LPTIM1,
+ GATE_SPI2,
+ GATE_SPI3,
+ GATE_USART3,
+ GATE_UART4,
+ GATE_UART5,
+ GATE_UART7,
+ GATE_UART8,
+ GATE_I2C1,
+ GATE_I2C2,
+ GATE_SPDIF,
+ GATE_TIM1,
+ GATE_TIM8,
+ GATE_SPI1,
+ GATE_USART6,
+ GATE_SAI1,
+ GATE_SAI2,
+ GATE_DFSDM,
+ GATE_ADFSDM,
+ GATE_FDCAN,
+ GATE_LPTIM2,
+ GATE_LPTIM3,
+ GATE_LPTIM4,
+ GATE_LPTIM5,
+ GATE_VREF,
+ GATE_DTS,
+ GATE_PMBCTRL,
+ GATE_HDP,
+ GATE_SYSCFG,
+ GATE_DCMIPP,
+ GATE_DDRPERFM,
+ GATE_IWDG2APB,
+ GATE_USBPHY,
+ GATE_STGENRO,
+ GATE_LTDC,
+ GATE_RTCAPB,
+ GATE_TZC,
+ GATE_ETZPC,
+ GATE_IWDG1APB,
+ GATE_BSEC,
+ GATE_STGENC,
+ GATE_USART1,
+ GATE_USART2,
+ GATE_SPI4,
+ GATE_SPI5,
+ GATE_I2C3,
+ GATE_I2C4,
+ GATE_I2C5,
+ GATE_TIM12,
+ GATE_TIM13,
+ GATE_TIM14,
+ GATE_TIM15,
+ GATE_TIM16,
+ GATE_TIM17,
+ GATE_DMA1,
+ GATE_DMA2,
+ GATE_DMAMUX1,
+ GATE_DMA3,
+ GATE_DMAMUX2,
+ GATE_ADC1,
+ GATE_ADC2,
+ GATE_USBO,
+ GATE_TSC,
+ GATE_GPIOA,
+ GATE_GPIOB,
+ GATE_GPIOC,
+ GATE_GPIOD,
+ GATE_GPIOE,
+ GATE_GPIOF,
+ GATE_GPIOG,
+ GATE_GPIOH,
+ GATE_GPIOI,
+ GATE_PKA,
+ GATE_SAES,
+ GATE_CRYP1,
+ GATE_HASH1,
+ GATE_RNG1,
+ GATE_BKPSRAM,
+ GATE_AXIMC,
+ GATE_MCE,
+ GATE_ETH1CK,
+ GATE_ETH1TX,
+ GATE_ETH1RX,
+ GATE_ETH1MAC,
+ GATE_FMC,
+ GATE_QSPI,
+ GATE_SDMMC1,
+ GATE_SDMMC2,
+ GATE_CRC1,
+ GATE_USBH,
+ GATE_ETH2CK,
+ GATE_ETH2TX,
+ GATE_ETH2RX,
+ GATE_ETH2MAC,
+ GATE_MDMA,
+
+ LAST_GATE
+};
+
+#define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\
+ .offset = (_offset),\
+ .bit_idx = (_bit_idx),\
+ .set_clr = (_offset_clr),\
+}
+
+static const struct gate_cfg gates_mp13[LAST_GATE] = {
+ GATE_CFG(GATE_LSE, RCC_BDCR, 0, 0),
+ GATE_CFG(GATE_RTCCK, RCC_BDCR, 20, 0),
+ GATE_CFG(GATE_LSI, RCC_RDLSICR, 0, 0),
+ GATE_CFG(GATE_HSI, RCC_OCENSETR, 0, 1),
+ GATE_CFG(GATE_CSI, RCC_OCENSETR, 4, 1),
+ GATE_CFG(GATE_HSE, RCC_OCENSETR, 8, 1),
+ GATE_CFG(GATE_LSI_RDY, RCC_RDLSICR, 1, 0),
+ GATE_CFG(GATE_CSI_RDY, RCC_OCRDYR, 4, 0),
+ GATE_CFG(GATE_LSE_RDY, RCC_BDCR, 2, 0),
+ GATE_CFG(GATE_HSE_RDY, RCC_OCRDYR, 8, 0),
+ GATE_CFG(GATE_HSI_RDY, RCC_OCRDYR, 0, 0),
+ GATE_CFG(GATE_MCO1, RCC_MCO1CFGR, 12, 0),
+ GATE_CFG(GATE_MCO2, RCC_MCO2CFGR, 12, 0),
+ GATE_CFG(GATE_DBGCK, RCC_DBGCFGR, 8, 0),
+ GATE_CFG(GATE_TRACECK, RCC_DBGCFGR, 9, 0),
+ GATE_CFG(GATE_PLL1, RCC_PLL1CR, 0, 0),
+ GATE_CFG(GATE_PLL1_DIVP, RCC_PLL1CR, 4, 0),
+ GATE_CFG(GATE_PLL1_DIVQ, RCC_PLL1CR, 5, 0),
+ GATE_CFG(GATE_PLL1_DIVR, RCC_PLL1CR, 6, 0),
+ GATE_CFG(GATE_PLL2, RCC_PLL2CR, 0, 0),
+ GATE_CFG(GATE_PLL2_DIVP, RCC_PLL2CR, 4, 0),
+ GATE_CFG(GATE_PLL2_DIVQ, RCC_PLL2CR, 5, 0),
+ GATE_CFG(GATE_PLL2_DIVR, RCC_PLL2CR, 6, 0),
+ GATE_CFG(GATE_PLL3, RCC_PLL3CR, 0, 0),
+ GATE_CFG(GATE_PLL3_DIVP, RCC_PLL3CR, 4, 0),
+ GATE_CFG(GATE_PLL3_DIVQ, RCC_PLL3CR, 5, 0),
+ GATE_CFG(GATE_PLL3_DIVR, RCC_PLL3CR, 6, 0),
+ GATE_CFG(GATE_PLL4, RCC_PLL4CR, 0, 0),
+ GATE_CFG(GATE_PLL4_DIVP, RCC_PLL4CR, 4, 0),
+ GATE_CFG(GATE_PLL4_DIVQ, RCC_PLL4CR, 5, 0),
+ GATE_CFG(GATE_PLL4_DIVR, RCC_PLL4CR, 6, 0),
+ GATE_CFG(GATE_DDRC1, RCC_DDRITFCR, 0, 0),
+ GATE_CFG(GATE_DDRC1LP, RCC_DDRITFCR, 1, 0),
+ GATE_CFG(GATE_DDRPHYC, RCC_DDRITFCR, 4, 0),
+ GATE_CFG(GATE_DDRPHYCLP, RCC_DDRITFCR, 5, 0),
+ GATE_CFG(GATE_DDRCAPB, RCC_DDRITFCR, 6, 0),
+ GATE_CFG(GATE_DDRCAPBLP, RCC_DDRITFCR, 7, 0),
+ GATE_CFG(GATE_AXIDCG, RCC_DDRITFCR, 8, 0),
+ GATE_CFG(GATE_DDRPHYCAPB, RCC_DDRITFCR, 9, 0),
+ GATE_CFG(GATE_DDRPHYCAPBLP, RCC_DDRITFCR, 10, 0),
+ GATE_CFG(GATE_TIM2, RCC_MP_APB1ENSETR, 0, 1),
+ GATE_CFG(GATE_TIM3, RCC_MP_APB1ENSETR, 1, 1),
+ GATE_CFG(GATE_TIM4, RCC_MP_APB1ENSETR, 2, 1),
+ GATE_CFG(GATE_TIM5, RCC_MP_APB1ENSETR, 3, 1),
+ GATE_CFG(GATE_TIM6, RCC_MP_APB1ENSETR, 4, 1),
+ GATE_CFG(GATE_TIM7, RCC_MP_APB1ENSETR, 5, 1),
+ GATE_CFG(GATE_LPTIM1, RCC_MP_APB1ENSETR, 9, 1),
+ GATE_CFG(GATE_SPI2, RCC_MP_APB1ENSETR, 11, 1),
+ GATE_CFG(GATE_SPI3, RCC_MP_APB1ENSETR, 12, 1),
+ GATE_CFG(GATE_USART3, RCC_MP_APB1ENSETR, 15, 1),
+ GATE_CFG(GATE_UART4, RCC_MP_APB1ENSETR, 16, 1),
+ GATE_CFG(GATE_UART5, RCC_MP_APB1ENSETR, 17, 1),
+ GATE_CFG(GATE_UART7, RCC_MP_APB1ENSETR, 18, 1),
+ GATE_CFG(GATE_UART8, RCC_MP_APB1ENSETR, 19, 1),
+ GATE_CFG(GATE_I2C1, RCC_MP_APB1ENSETR, 21, 1),
+ GATE_CFG(GATE_I2C2, RCC_MP_APB1ENSETR, 22, 1),
+ GATE_CFG(GATE_SPDIF, RCC_MP_APB1ENSETR, 26, 1),
+ GATE_CFG(GATE_TIM1, RCC_MP_APB2ENSETR, 0, 1),
+ GATE_CFG(GATE_TIM8, RCC_MP_APB2ENSETR, 1, 1),
+ GATE_CFG(GATE_SPI1, RCC_MP_APB2ENSETR, 8, 1),
+ GATE_CFG(GATE_USART6, RCC_MP_APB2ENSETR, 13, 1),
+ GATE_CFG(GATE_SAI1, RCC_MP_APB2ENSETR, 16, 1),
+ GATE_CFG(GATE_SAI2, RCC_MP_APB2ENSETR, 17, 1),
+ GATE_CFG(GATE_DFSDM, RCC_MP_APB2ENSETR, 20, 1),
+ GATE_CFG(GATE_ADFSDM, RCC_MP_APB2ENSETR, 21, 1),
+ GATE_CFG(GATE_FDCAN, RCC_MP_APB2ENSETR, 24, 1),
+ GATE_CFG(GATE_LPTIM2, RCC_MP_APB3ENSETR, 0, 1),
+ GATE_CFG(GATE_LPTIM3, RCC_MP_APB3ENSETR, 1, 1),
+ GATE_CFG(GATE_LPTIM4, RCC_MP_APB3ENSETR, 2, 1),
+ GATE_CFG(GATE_LPTIM5, RCC_MP_APB3ENSETR, 3, 1),
+ GATE_CFG(GATE_VREF, RCC_MP_APB3ENSETR, 13, 1),
+ GATE_CFG(GATE_DTS, RCC_MP_APB3ENSETR, 16, 1),
+ GATE_CFG(GATE_PMBCTRL, RCC_MP_APB3ENSETR, 17, 1),
+ GATE_CFG(GATE_HDP, RCC_MP_APB3ENSETR, 20, 1),
+ GATE_CFG(GATE_SYSCFG, RCC_MP_S_APB3ENSETR, 0, 1),
+ GATE_CFG(GATE_DCMIPP, RCC_MP_APB4ENSETR, 1, 1),
+ GATE_CFG(GATE_DDRPERFM, RCC_MP_APB4ENSETR, 8, 1),
+ GATE_CFG(GATE_IWDG2APB, RCC_MP_APB4ENSETR, 15, 1),
+ GATE_CFG(GATE_USBPHY, RCC_MP_APB4ENSETR, 16, 1),
+ GATE_CFG(GATE_STGENRO, RCC_MP_APB4ENSETR, 20, 1),
+ GATE_CFG(GATE_LTDC, RCC_MP_S_APB4ENSETR, 0, 1),
+ GATE_CFG(GATE_RTCAPB, RCC_MP_APB5ENSETR, 8, 1),
+ GATE_CFG(GATE_TZC, RCC_MP_APB5ENSETR, 11, 1),
+ GATE_CFG(GATE_ETZPC, RCC_MP_APB5ENSETR, 13, 1),
+ GATE_CFG(GATE_IWDG1APB, RCC_MP_APB5ENSETR, 15, 1),
+ GATE_CFG(GATE_BSEC, RCC_MP_APB5ENSETR, 16, 1),
+ GATE_CFG(GATE_STGENC, RCC_MP_APB5ENSETR, 20, 1),
+ GATE_CFG(GATE_USART1, RCC_MP_APB6ENSETR, 0, 1),
+ GATE_CFG(GATE_USART2, RCC_MP_APB6ENSETR, 1, 1),
+ GATE_CFG(GATE_SPI4, RCC_MP_APB6ENSETR, 2, 1),
+ GATE_CFG(GATE_SPI5, RCC_MP_APB6ENSETR, 3, 1),
+ GATE_CFG(GATE_I2C3, RCC_MP_APB6ENSETR, 4, 1),
+ GATE_CFG(GATE_I2C4, RCC_MP_APB6ENSETR, 5, 1),
+ GATE_CFG(GATE_I2C5, RCC_MP_APB6ENSETR, 6, 1),
+ GATE_CFG(GATE_TIM12, RCC_MP_APB6ENSETR, 7, 1),
+ GATE_CFG(GATE_TIM13, RCC_MP_APB6ENSETR, 8, 1),
+ GATE_CFG(GATE_TIM14, RCC_MP_APB6ENSETR, 9, 1),
+ GATE_CFG(GATE_TIM15, RCC_MP_APB6ENSETR, 10, 1),
+ GATE_CFG(GATE_TIM16, RCC_MP_APB6ENSETR, 11, 1),
+ GATE_CFG(GATE_TIM17, RCC_MP_APB6ENSETR, 12, 1),
+ GATE_CFG(GATE_DMA1, RCC_MP_AHB2ENSETR, 0, 1),
+ GATE_CFG(GATE_DMA2, RCC_MP_AHB2ENSETR, 1, 1),
+ GATE_CFG(GATE_DMAMUX1, RCC_MP_AHB2ENSETR, 2, 1),
+ GATE_CFG(GATE_DMA3, RCC_MP_AHB2ENSETR, 3, 1),
+ GATE_CFG(GATE_DMAMUX2, RCC_MP_AHB2ENSETR, 4, 1),
+ GATE_CFG(GATE_ADC1, RCC_MP_AHB2ENSETR, 5, 1),
+ GATE_CFG(GATE_ADC2, RCC_MP_AHB2ENSETR, 6, 1),
+ GATE_CFG(GATE_USBO, RCC_MP_AHB2ENSETR, 8, 1),
+ GATE_CFG(GATE_TSC, RCC_MP_AHB4ENSETR, 15, 1),
+
+ GATE_CFG(GATE_GPIOA, RCC_MP_S_AHB4ENSETR, 0, 1),
+ GATE_CFG(GATE_GPIOB, RCC_MP_S_AHB4ENSETR, 1, 1),
+ GATE_CFG(GATE_GPIOC, RCC_MP_S_AHB4ENSETR, 2, 1),
+ GATE_CFG(GATE_GPIOD, RCC_MP_S_AHB4ENSETR, 3, 1),
+ GATE_CFG(GATE_GPIOE, RCC_MP_S_AHB4ENSETR, 4, 1),
+ GATE_CFG(GATE_GPIOF, RCC_MP_S_AHB4ENSETR, 5, 1),
+ GATE_CFG(GATE_GPIOG, RCC_MP_S_AHB4ENSETR, 6, 1),
+ GATE_CFG(GATE_GPIOH, RCC_MP_S_AHB4ENSETR, 7, 1),
+ GATE_CFG(GATE_GPIOI, RCC_MP_S_AHB4ENSETR, 8, 1),
+
+ GATE_CFG(GATE_PKA, RCC_MP_AHB5ENSETR, 2, 1),
+ GATE_CFG(GATE_SAES, RCC_MP_AHB5ENSETR, 3, 1),
+ GATE_CFG(GATE_CRYP1, RCC_MP_AHB5ENSETR, 4, 1),
+ GATE_CFG(GATE_HASH1, RCC_MP_AHB5ENSETR, 5, 1),
+ GATE_CFG(GATE_RNG1, RCC_MP_AHB5ENSETR, 6, 1),
+ GATE_CFG(GATE_BKPSRAM, RCC_MP_AHB5ENSETR, 8, 1),
+ GATE_CFG(GATE_AXIMC, RCC_MP_AHB5ENSETR, 16, 1),
+ GATE_CFG(GATE_MCE, RCC_MP_AHB6ENSETR, 1, 1),
+ GATE_CFG(GATE_ETH1CK, RCC_MP_AHB6ENSETR, 7, 1),
+ GATE_CFG(GATE_ETH1TX, RCC_MP_AHB6ENSETR, 8, 1),
+ GATE_CFG(GATE_ETH1RX, RCC_MP_AHB6ENSETR, 9, 1),
+ GATE_CFG(GATE_ETH1MAC, RCC_MP_AHB6ENSETR, 10, 1),
+ GATE_CFG(GATE_FMC, RCC_MP_AHB6ENSETR, 12, 1),
+ GATE_CFG(GATE_QSPI, RCC_MP_AHB6ENSETR, 14, 1),
+ GATE_CFG(GATE_SDMMC1, RCC_MP_AHB6ENSETR, 16, 1),
+ GATE_CFG(GATE_SDMMC2, RCC_MP_AHB6ENSETR, 17, 1),
+ GATE_CFG(GATE_CRC1, RCC_MP_AHB6ENSETR, 20, 1),
+ GATE_CFG(GATE_USBH, RCC_MP_AHB6ENSETR, 24, 1),
+ GATE_CFG(GATE_ETH2CK, RCC_MP_AHB6ENSETR, 27, 1),
+ GATE_CFG(GATE_ETH2TX, RCC_MP_AHB6ENSETR, 28, 1),
+ GATE_CFG(GATE_ETH2RX, RCC_MP_AHB6ENSETR, 29, 1),
+ GATE_CFG(GATE_ETH2MAC, RCC_MP_AHB6ENSETR, 30, 1),
+ GATE_CFG(GATE_MDMA, RCC_MP_S_AHB6ENSETR, 0, 1),
+};
+
+/*
+ * DIV CONFIG
+ */
+
+static const struct clk_div_table axi_div_table[] = {
+ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
+ { 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 },
+ { 0 },
+};
+
+static const struct clk_div_table mlahb_div_table[] = {
+ { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+ { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
+ { 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 },
+ { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
+ { 0 },
+};
+
+static const struct clk_div_table apb_div_table[] = {
+ { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+ { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
+ { 0 },
+};
+
+#define DIV_CFG(id, _offset, _shift, _width, _flags, _table, _bitrdy)[id] = {\
+ .offset = _offset,\
+ .shift = _shift,\
+ .width = _width,\
+ .flags = _flags,\
+ .table = _table,\
+ .bitrdy = _bitrdy,\
+}
+
+static const struct div_cfg dividers_mp13[] = {
+ DIV_CFG(DIV_PLL1DIVP, RCC_PLL1CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_PLL2DIVP, RCC_PLL2CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_PLL2DIVQ, RCC_PLL2CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_PLL2DIVR, RCC_PLL2CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_PLL3DIVP, RCC_PLL3CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_PLL3DIVQ, RCC_PLL3CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_PLL3DIVR, RCC_PLL3CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_PLL4DIVP, RCC_PLL4CFGR2, 0, 7, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_PLL4DIVQ, RCC_PLL4CFGR2, 8, 7, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_PLL4DIVR, RCC_PLL4CFGR2, 16, 7, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_MPU, RCC_MPCKDIVR, 0, 4, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_AXI, RCC_AXIDIVR, 0, 3, 0, axi_div_table, 31),
+ DIV_CFG(DIV_MLAHB, RCC_MLAHBDIVR, 0, 4, 0, mlahb_div_table, 31),
+ DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, 31),
+ DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, 31),
+ DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, 31),
+ DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, 31),
+ DIV_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table, 31),
+ DIV_CFG(DIV_APB6, RCC_APB6DIVR, 0, 3, 0, apb_div_table, 31),
+ DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_MCO2, RCC_MCO2CFGR, 4, 4, 0, NULL, DIV_NO_BIT_RDY),
+
+ DIV_CFG(DIV_HSI, RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_TRACE, RCC_DBGCFGR, 0, 3, CLK_DIVIDER_POWER_OF_TWO, NULL, DIV_NO_BIT_RDY),
+
+ DIV_CFG(DIV_ETH1PTP, RCC_ETH12CKSELR, 4, 4, 0, NULL, DIV_NO_BIT_RDY),
+ DIV_CFG(DIV_ETH2PTP, RCC_ETH12CKSELR, 12, 4, 0, NULL, DIV_NO_BIT_RDY),
+};
+
+#define MAX_HSI_HZ 64000000
+#define USB_PHY_48_MHZ 48000000
+
+#define TIMEOUT_US_200MS U(200000)
+#define TIMEOUT_US_1S U(1000000)
+
+#define PLLRDY_TIMEOUT TIMEOUT_US_200MS
+#define CLKSRC_TIMEOUT TIMEOUT_US_200MS
+#define CLKDIV_TIMEOUT TIMEOUT_US_200MS
+#define HSIDIV_TIMEOUT TIMEOUT_US_200MS
+#define OSCRDY_TIMEOUT TIMEOUT_US_1S
+
+enum stm32_osc {
+ OSC_HSI,
+ OSC_HSE,
+ OSC_CSI,
+ OSC_LSI,
+ OSC_LSE,
+ OSC_I2SCKIN,
+ NB_OSCILLATOR
+};
+
+enum stm32mp1_pll_id {
+ _PLL1,
+ _PLL2,
+ _PLL3,
+ _PLL4,
+ _PLL_NB
+};
+
+enum stm32mp1_plltype {
+ PLL_800,
+ PLL_1600,
+ PLL_2000,
+ PLL_TYPE_NB
+};
+
+#define RCC_OFFSET_PLLXCR 0
+#define RCC_OFFSET_PLLXCFGR1 4
+#define RCC_OFFSET_PLLXCFGR2 8
+#define RCC_OFFSET_PLLXFRACR 12
+#define RCC_OFFSET_PLLXCSGR 16
+
+struct stm32_clk_pll {
+ enum stm32mp1_plltype plltype;
+ uint16_t clk_id;
+ uint16_t reg_pllxcr;
+};
+
+struct stm32mp1_pll {
+ uint8_t refclk_min;
+ uint8_t refclk_max;
+};
+
+/* Define characteristic of PLL according type */
+static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
+ [PLL_800] = {
+ .refclk_min = 4,
+ .refclk_max = 16,
+ },
+ [PLL_1600] = {
+ .refclk_min = 8,
+ .refclk_max = 16,
+ },
+ [PLL_2000] = {
+ .refclk_min = 8,
+ .refclk_max = 16,
+ },
+};
+
+#if STM32MP_USB_PROGRAMMER
+static bool pll4_bootrom;
+#endif
+
+/* RCC clock device driver private */
+static unsigned int refcounts_mp13[CK_LAST];
+
+static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx);
+
+#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
+static void clk_oscillator_check_bypass(struct stm32_clk_priv *priv, int idx,
+ bool digbyp, bool bypass)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, idx);
+ struct stm32_clk_bypass *bypass_data = osc_data->bypass;
+ uintptr_t address;
+
+ if (bypass_data == NULL) {
+ return;
+ }
+
+ address = priv->base + bypass_data->offset;
+ if ((mmio_read_32(address) & RCC_OCENR_HSEBYP) &&
+ (!(digbyp || bypass))) {
+ panic();
+ }
+}
+#endif
+
+static void stm32_enable_oscillator_hse(struct stm32_clk_priv *priv)
+{
+ struct stm32_clk_platdata *pdata = priv->pdata;
+ struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE];
+ bool digbyp = osci->digbyp;
+ bool bypass = osci->bypass;
+ bool css = osci->css;
+
+ if (_clk_stm32_get_rate(priv, _CK_HSE) == 0U) {
+ return;
+ }
+
+ clk_oscillator_set_bypass(priv, _CK_HSE, digbyp, bypass);
+
+ _clk_stm32_enable(priv, _CK_HSE);
+
+#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
+ clk_oscillator_check_bypass(priv, _CK_HSE, digbyp, bypass);
+#endif
+
+ clk_oscillator_set_css(priv, _CK_HSE, css);
+}
+
+static void stm32_enable_oscillator_lse(struct stm32_clk_priv *priv)
+{
+ struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, _CK_LSE);
+ struct stm32_clk_platdata *pdata = priv->pdata;
+ struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
+ bool digbyp = osci->digbyp;
+ bool bypass = osci->bypass;
+ uint8_t drive = osci->drive;
+
+ if (_clk_stm32_get_rate(priv, _CK_LSE) == 0U) {
+ return;
+ }
+
+ clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass);
+
+ clk_oscillator_set_drive(priv, _CK_LSE, drive);
+
+ _clk_stm32_gate_enable(priv, osc_data->gate_id);
+}
+
+static int stm32mp1_set_hsidiv(uint8_t hsidiv)
+{
+ uint64_t timeout;
+ uintptr_t rcc_base = stm32mp_rcc_base();
+ uintptr_t address = rcc_base + RCC_OCRDYR;
+
+ mmio_clrsetbits_32(rcc_base + RCC_HSICFGR,
+ RCC_HSICFGR_HSIDIV_MASK,
+ RCC_HSICFGR_HSIDIV_MASK & (uint32_t)hsidiv);
+
+ timeout = timeout_init_us(HSIDIV_TIMEOUT);
+ while ((mmio_read_32(address) & RCC_OCRDYR_HSIDIVRDY) == 0U) {
+ if (timeout_elapsed(timeout)) {
+ ERROR("HSIDIV failed @ 0x%lx: 0x%x\n",
+ address, mmio_read_32(address));
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static int stm32mp1_hsidiv(unsigned long hsifreq)
+{
+ uint8_t hsidiv;
+ uint32_t hsidivfreq = MAX_HSI_HZ;
+
+ for (hsidiv = 0; hsidiv < 4U; hsidiv++) {
+ if (hsidivfreq == hsifreq) {
+ break;
+ }
+
+ hsidivfreq /= 2U;
+ }
+
+ if (hsidiv == 4U) {
+ ERROR("Invalid clk-hsi frequency\n");
+ return -EINVAL;
+ }
+
+ if (hsidiv != 0U) {
+ return stm32mp1_set_hsidiv(hsidiv);
+ }
+
+ return 0;
+}
+
+static int stm32_clk_oscillators_lse_set_css(struct stm32_clk_priv *priv)
+{
+ struct stm32_clk_platdata *pdata = priv->pdata;
+ struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
+
+ clk_oscillator_set_css(priv, _CK_LSE, osci->css);
+
+ return 0;
+}
+
+static int stm32mp1_come_back_to_hsi(void)
+{
+ int ret;
+ struct stm32_clk_priv *priv = clk_stm32_get_priv();
+
+ /* Come back to HSI */
+ ret = _clk_stm32_set_parent(priv, _CKMPU, _CK_HSI);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = _clk_stm32_set_parent(priv, _CKAXI, _CK_HSI);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = _clk_stm32_set_parent(priv, _CKMLAHB, _CK_HSI);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static int stm32_clk_configure_clk_get_binding_id(struct stm32_clk_priv *priv, uint32_t data)
+{
+ unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT;
+
+ return clk_get_index(priv, binding_id);
+}
+
+static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data)
+{
+ int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT;
+ int enable = (data & CLK_ON_MASK) >> CLK_ON_SHIFT;
+ int clk_id;
+ int ret;
+
+ clk_id = stm32_clk_configure_clk_get_binding_id(priv, data);
+ if (clk_id < 0) {
+ return clk_id;
+ }
+
+ ret = _clk_stm32_set_parent_by_index(priv, clk_id, sel);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (enable) {
+ clk_stm32_enable_call_ops(priv, clk_id);
+ } else {
+ clk_stm32_disable_call_ops(priv, clk_id);
+ }
+
+ return 0;
+}
+
+static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data)
+{
+ int mux = (data & MUX_ID_MASK) >> MUX_ID_SHIFT;
+ int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
+
+ return clk_mux_set_parent(priv, mux, sel);
+}
+
+static int stm32_clk_dividers_configure(struct stm32_clk_priv *priv)
+{
+ struct stm32_clk_platdata *pdata = priv->pdata;
+ uint32_t i;
+
+ for (i = 0; i < pdata->nclkdiv; i++) {
+ int div_id, div_n;
+ int val;
+ int ret;
+
+ val = pdata->clkdiv[i] & CMD_DATA_MASK;
+ div_id = (val & DIV_ID_MASK) >> DIV_ID_SHIFT;
+ div_n = (val & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT;
+
+ ret = clk_stm32_set_div(priv, div_id, div_n);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int stm32_clk_source_configure(struct stm32_clk_priv *priv)
+{
+ struct stm32_clk_platdata *pdata = priv->pdata;
+ bool ckper_disabled = false;
+ int clk_id;
+ int ret;
+ uint32_t i;
+
+ for (i = 0; i < pdata->nclksrc; i++) {
+ uint32_t val = pdata->clksrc[i];
+ uint32_t cmd, cmd_data;
+
+ if (val == (uint32_t)CLK_CKPER_DISABLED) {
+ ckper_disabled = true;
+ continue;
+ }
+
+ if (val == (uint32_t)CLK_RTC_DISABLED) {
+ continue;
+ }
+
+ cmd = (val & CMD_MASK) >> CMD_SHIFT;
+ cmd_data = val & ~CMD_MASK;
+
+ switch (cmd) {
+ case CMD_MUX:
+ ret = stm32_clk_configure_mux(priv, cmd_data);
+ break;
+
+ case CMD_CLK:
+ clk_id = stm32_clk_configure_clk_get_binding_id(priv, cmd_data);
+
+ if (clk_id == _RTCCK) {
+ if ((_clk_stm32_is_enabled(priv, _RTCCK) == true)) {
+ continue;
+ }
+ }
+
+ ret = stm32_clk_configure_clk(priv, cmd_data);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ /*
+ * CKPER is source for some peripheral clocks
+ * (FMC-NAND / QPSI-NOR) and switching source is allowed
+ * only if previous clock is still ON
+ * => deactivate CKPER only after switching clock
+ */
+ if (ckper_disabled) {
+ ret = stm32_clk_configure_mux(priv, CLK_CKPER_DISABLED & CMD_MASK);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int stm32_clk_stgen_configure(struct stm32_clk_priv *priv, int id)
+{
+ unsigned long stgen_freq;
+
+ stgen_freq = _clk_stm32_get_rate(priv, id);
+
+ stm32mp_stgen_config(stgen_freq);
+
+ return 0;
+}
+
+#define CLK_PLL_CFG(_idx, _clk_id, _type, _reg)\
+ [(_idx)] = {\
+ .clk_id = (_clk_id),\
+ .plltype = (_type),\
+ .reg_pllxcr = (_reg),\
+ }
+
+static int clk_stm32_pll_compute_cfgr1(struct stm32_clk_priv *priv,
+ const struct stm32_clk_pll *pll,
+ struct stm32_pll_vco *vco,
+ uint32_t *value)
+{
+ uint32_t divm = vco->div_mn[PLL_CFG_M];
+ uint32_t divn = vco->div_mn[PLL_CFG_N];
+ unsigned long prate = 0UL;
+ unsigned long refclk = 0UL;
+
+ prate = _clk_stm32_get_parent_rate(priv, pll->clk_id);
+ refclk = prate / (divm + 1U);
+
+ if ((refclk < (stm32mp1_pll[pll->plltype].refclk_min * 1000000U)) ||
+ (refclk > (stm32mp1_pll[pll->plltype].refclk_max * 1000000U))) {
+ return -EINVAL;
+ }
+
+ *value = 0;
+
+ if ((pll->plltype == PLL_800) && (refclk >= 8000000U)) {
+ *value = 1U << RCC_PLLNCFGR1_IFRGE_SHIFT;
+ }
+
+ *value |= (divn << RCC_PLLNCFGR1_DIVN_SHIFT) & RCC_PLLNCFGR1_DIVN_MASK;
+ *value |= (divm << RCC_PLLNCFGR1_DIVM_SHIFT) & RCC_PLLNCFGR1_DIVM_MASK;
+
+ return 0;
+}
+
+static uint32_t clk_stm32_pll_compute_cfgr2(struct stm32_pll_output *out)
+{
+ uint32_t value = 0;
+
+ value |= (out->output[PLL_CFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) & RCC_PLLNCFGR2_DIVP_MASK;
+ value |= (out->output[PLL_CFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) & RCC_PLLNCFGR2_DIVQ_MASK;
+ value |= (out->output[PLL_CFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) & RCC_PLLNCFGR2_DIVR_MASK;
+
+ return value;
+}
+
+static void clk_stm32_pll_config_vco(struct stm32_clk_priv *priv,
+ const struct stm32_clk_pll *pll,
+ struct stm32_pll_vco *vco)
+{
+ uintptr_t pll_base = priv->base + pll->reg_pllxcr;
+ uint32_t value = 0;
+
+ if (clk_stm32_pll_compute_cfgr1(priv, pll, vco, &value) != 0) {
+ ERROR("Invalid Vref clock !\n");
+ panic();
+ }
+
+ /* Write N / M / IFREGE fields */
+ mmio_write_32(pll_base + RCC_OFFSET_PLLXCFGR1, value);
+
+ /* Fractional configuration */
+ mmio_write_32(pll_base + RCC_OFFSET_PLLXFRACR, 0);
+
+ /* Frac must be enabled only once its configuration is loaded */
+ mmio_write_32(pll_base + RCC_OFFSET_PLLXFRACR, vco->frac << RCC_PLLNFRACR_FRACV_SHIFT);
+ mmio_setbits_32(pll_base + RCC_OFFSET_PLLXFRACR, RCC_PLLNFRACR_FRACLE);
+}
+
+static void clk_stm32_pll_config_csg(struct stm32_clk_priv *priv,
+ const struct stm32_clk_pll *pll,
+ struct stm32_pll_vco *vco)
+{
+ uintptr_t pll_base = priv->base + pll->reg_pllxcr;
+ uint32_t mod_per = 0;
+ uint32_t inc_step = 0;
+ uint32_t sscg_mode = 0;
+ uint32_t value = 0;
+
+ if (!vco->csg_enabled) {
+ return;
+ }
+
+ mod_per = vco->csg[PLL_CSG_MOD_PER];
+ inc_step = vco->csg[PLL_CSG_INC_STEP];
+ sscg_mode = vco->csg[PLL_CSG_SSCG_MODE];
+
+ value |= (mod_per << RCC_PLLNCSGR_MOD_PER_SHIFT) & RCC_PLLNCSGR_MOD_PER_MASK;
+ value |= (inc_step << RCC_PLLNCSGR_INC_STEP_SHIFT) & RCC_PLLNCSGR_INC_STEP_MASK;
+ value |= (sscg_mode << RCC_PLLNCSGR_SSCG_MODE_SHIFT) & RCC_PLLNCSGR_SSCG_MODE_MASK;
+
+ mmio_write_32(pll_base + RCC_OFFSET_PLLXCSGR, value);
+ mmio_setbits_32(pll_base + RCC_OFFSET_PLLXCR, RCC_PLLNCR_SSCG_CTRL);
+}
+
+static void clk_stm32_pll_config_out(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll,
+ struct stm32_pll_output *out)
+{
+ uintptr_t pll_base = priv->base + pll->reg_pllxcr;
+ uint32_t value = 0;
+
+ value = clk_stm32_pll_compute_cfgr2(out);
+
+ mmio_write_32(pll_base + RCC_OFFSET_PLLXCFGR2, value);
+}
+
+static inline struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx)
+{
+ struct stm32_clk_priv *priv = clk_stm32_get_priv();
+ struct stm32_clk_platdata *pdata = priv->pdata;
+
+ return &pdata->pll[pll_idx];
+}
+
+static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+ uintptr_t pll_base = priv->base + pll->reg_pllxcr;
+
+ return ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLON) != 0U);
+}
+
+static void _clk_stm32_pll_set_on(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+ uintptr_t pll_base = priv->base + pll->reg_pllxcr;
+
+ /* Preserve RCC_PLLNCR_SSCG_CTRL value */
+ mmio_clrsetbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN,
+ RCC_PLLNCR_PLLON);
+}
+
+static void _clk_stm32_pll_set_off(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+ uintptr_t pll_base = priv->base + pll->reg_pllxcr;
+
+ /* Stop all output */
+ mmio_clrbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN);
+
+ /* Stop PLL */
+ mmio_clrbits_32(pll_base, RCC_PLLNCR_PLLON);
+}
+
+static int _clk_stm32_pll_wait_ready_on(struct stm32_clk_priv *priv,
+ const struct stm32_clk_pll *pll)
+{
+ uintptr_t pll_base = priv->base + pll->reg_pllxcr;
+ uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
+
+ /* Wait PLL lock */
+ while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) == 0U) {
+ if (timeout_elapsed(timeout)) {
+ ERROR("%d clock start failed @ 0x%x: 0x%x\n",
+ pll->clk_id, pll->reg_pllxcr, mmio_read_32(pll_base));
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int _clk_stm32_pll_wait_ready_off(struct stm32_clk_priv *priv,
+ const struct stm32_clk_pll *pll)
+{
+ uintptr_t pll_base = priv->base + pll->reg_pllxcr;
+ uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
+
+ /* Wait PLL lock */
+ while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) != 0U) {
+ if (timeout_elapsed(timeout)) {
+ ERROR("%d clock stop failed @ 0x%x: 0x%x\n",
+ pll->clk_id, pll->reg_pllxcr, mmio_read_32(pll_base));
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int _clk_stm32_pll_enable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+ if (_clk_stm32_pll_is_enabled(priv, pll)) {
+ return 0;
+ }
+
+ /* Preserve RCC_PLLNCR_SSCG_CTRL value */
+ _clk_stm32_pll_set_on(priv, pll);
+
+ /* Wait PLL lock */
+ return _clk_stm32_pll_wait_ready_on(priv, pll);
+}
+
+static void _clk_stm32_pll_disable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+ if (!_clk_stm32_pll_is_enabled(priv, pll)) {
+ return;
+ }
+
+ /* Stop all outputs and the PLL */
+ _clk_stm32_pll_set_off(priv, pll);
+
+ /* Wait PLL stopped */
+ _clk_stm32_pll_wait_ready_off(priv, pll);
+}
+
+static int _clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx,
+ struct stm32_pll_dt_cfg *pll_conf)
+{
+ const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_idx);
+ uintptr_t pll_base = priv->base + pll->reg_pllxcr;
+ int ret = 0;
+
+ /* Configure PLLs source */
+ ret = stm32_clk_configure_mux(priv, pll_conf->vco.src);
+ if (ret) {
+ return ret;
+ }
+
+#if STM32MP_USB_PROGRAMMER
+ if ((pll_idx == _PLL4) && pll4_bootrom) {
+ clk_stm32_pll_config_out(priv, pll, &pll_conf->output);
+
+ mmio_setbits_32(pll_base,
+ RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN);
+
+ return 0;
+ }
+#endif
+ /* Stop the PLL before */
+ _clk_stm32_pll_disable(priv, pll);
+
+ clk_stm32_pll_config_vco(priv, pll, &pll_conf->vco);
+ clk_stm32_pll_config_out(priv, pll, &pll_conf->output);
+ clk_stm32_pll_config_csg(priv, pll, &pll_conf->vco);
+
+ ret = _clk_stm32_pll_enable(priv, pll);
+ if (ret != 0) {
+ return ret;
+ }
+
+ mmio_setbits_32(pll_base, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN);
+
+ return 0;
+}
+
+static int clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx)
+{
+ struct stm32_pll_dt_cfg *pll_conf = clk_stm32_pll_get_pdata(pll_idx);
+
+ if (pll_conf->vco.status) {
+ return _clk_stm32_pll_init(priv, pll_idx, pll_conf);
+ }
+
+ return 0;
+}
+
+static int stm32_clk_pll_configure(struct stm32_clk_priv *priv)
+{
+ int err = 0;
+
+ err = clk_stm32_pll_init(priv, _PLL1);
+ if (err) {
+ return err;
+ }
+
+ err = clk_stm32_pll_init(priv, _PLL2);
+ if (err) {
+ return err;
+ }
+
+ err = clk_stm32_pll_init(priv, _PLL3);
+ if (err) {
+ return err;
+ }
+
+ err = clk_stm32_pll_init(priv, _PLL4);
+ if (err) {
+ return err;
+ }
+
+ return 0;
+}
+
+static int stm32_clk_oscillators_wait_lse_ready(struct stm32_clk_priv *priv)
+{
+ int ret = 0;
+
+ if (_clk_stm32_get_rate(priv, _CK_LSE) != 0U) {
+ ret = clk_oscillator_wait_ready_on(priv, _CK_LSE);
+ }
+
+ return ret;
+}
+
+static void stm32_clk_oscillators_enable(struct stm32_clk_priv *priv)
+{
+ stm32_enable_oscillator_hse(priv);
+ stm32_enable_oscillator_lse(priv);
+ _clk_stm32_enable(priv, _CK_LSI);
+ _clk_stm32_enable(priv, _CK_CSI);
+}
+
+static int stm32_clk_hsidiv_configure(struct stm32_clk_priv *priv)
+{
+ return stm32mp1_hsidiv(_clk_stm32_get_rate(priv, _CK_HSI));
+}
+
+#if STM32MP_USB_PROGRAMMER
+static bool stm32mp1_clk_is_pll4_used_by_bootrom(struct stm32_clk_priv *priv, int usbphy_p)
+{
+ /* Don't initialize PLL4, when used by BOOTROM */
+ if ((stm32mp_get_boot_itf_selected() ==
+ BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB) &&
+ (usbphy_p == _PLL4R)) {
+ return true;
+ }
+
+ return false;
+}
+
+static int stm32mp1_clk_check_usb_conflict(struct stm32_clk_priv *priv, int usbphy_p, int usbo_p)
+{
+ int _usbo_p;
+ int _usbphy_p;
+
+ if (!pll4_bootrom) {
+ return 0;
+ }
+
+ _usbo_p = _clk_stm32_get_parent(priv, _USBO_K);
+ _usbphy_p = _clk_stm32_get_parent(priv, _USBPHY_K);
+
+ if ((_usbo_p != usbo_p) || (_usbphy_p != usbphy_p)) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ return 0;
+}
+#endif
+
+static struct clk_oscillator_data stm32mp13_osc_data[NB_OSCILLATOR] = {
+ OSCILLATOR(OSC_HSI, _CK_HSI, "clk-hsi", GATE_HSI, GATE_HSI_RDY,
+ NULL, NULL, NULL),
+
+ OSCILLATOR(OSC_LSI, _CK_LSI, "clk-lsi", GATE_LSI, GATE_LSI_RDY,
+ NULL, NULL, NULL),
+
+ OSCILLATOR(OSC_CSI, _CK_CSI, "clk-csi", GATE_CSI, GATE_CSI_RDY,
+ NULL, NULL, NULL),
+
+ OSCILLATOR(OSC_LSE, _CK_LSE, "clk-lse", GATE_LSE, GATE_LSE_RDY,
+ BYPASS(RCC_BDCR, 1, 3),
+ CSS(RCC_BDCR, 8),
+ DRIVE(RCC_BDCR, 4, 2, 2)),
+
+ OSCILLATOR(OSC_HSE, _CK_HSE, "clk-hse", GATE_HSE, GATE_HSE_RDY,
+ BYPASS(RCC_OCENSETR, 10, 7),
+ CSS(RCC_OCENSETR, 11),
+ NULL),
+
+ OSCILLATOR(OSC_I2SCKIN, _I2SCKIN, "i2s_ckin", NO_GATE, NO_GATE,
+ NULL, NULL, NULL),
+};
+
+static const char *clk_stm32_get_oscillator_name(enum stm32_osc id)
+{
+ if (id < NB_OSCILLATOR) {
+ return stm32mp13_osc_data[id].name;
+ }
+
+ return NULL;
+}
+
+#define CLK_PLL_CFG(_idx, _clk_id, _type, _reg)\
+ [(_idx)] = {\
+ .clk_id = (_clk_id),\
+ .plltype = (_type),\
+ .reg_pllxcr = (_reg),\
+ }
+
+static const struct stm32_clk_pll stm32_mp13_clk_pll[_PLL_NB] = {
+ CLK_PLL_CFG(_PLL1, _CK_PLL1, PLL_2000, RCC_PLL1CR),
+ CLK_PLL_CFG(_PLL2, _CK_PLL2, PLL_1600, RCC_PLL2CR),
+ CLK_PLL_CFG(_PLL3, _CK_PLL3, PLL_800, RCC_PLL3CR),
+ CLK_PLL_CFG(_PLL4, _CK_PLL4, PLL_800, RCC_PLL4CR),
+};
+
+static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx)
+{
+ return &stm32_mp13_clk_pll[idx];
+}
+
+struct stm32_pll_cfg {
+ int pll_id;
+};
+
+static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv, int id,
+ unsigned long prate)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+ const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
+ uintptr_t pll_base = priv->base + pll->reg_pllxcr;
+ uint32_t cfgr1, fracr, divm, divn;
+ unsigned long fvco;
+
+ cfgr1 = mmio_read_32(pll_base + RCC_OFFSET_PLLXCFGR1);
+ fracr = mmio_read_32(pll_base + RCC_OFFSET_PLLXFRACR);
+
+ divm = (cfgr1 & (RCC_PLLNCFGR1_DIVM_MASK)) >> RCC_PLLNCFGR1_DIVM_SHIFT;
+ divn = cfgr1 & RCC_PLLNCFGR1_DIVN_MASK;
+
+ /*
+ * With FRACV :
+ * Fvco = Fck_ref * ((DIVN + 1) + FRACV / 2^13) / (DIVM + 1)
+ * Without FRACV
+ * Fvco = Fck_ref * ((DIVN + 1) / (DIVM + 1)
+ */
+ if ((fracr & RCC_PLLNFRACR_FRACLE) != 0U) {
+ uint32_t fracv = (fracr & RCC_PLLNFRACR_FRACV_MASK) >>
+ RCC_PLLNFRACR_FRACV_SHIFT;
+ unsigned long long numerator, denominator;
+
+ numerator = (((unsigned long long)divn + 1U) << 13) + fracv;
+ numerator = prate * numerator;
+ denominator = ((unsigned long long)divm + 1U) << 13;
+ fvco = (unsigned long)(numerator / denominator);
+ } else {
+ fvco = (unsigned long)(prate * (divn + 1U) / (divm + 1U));
+ }
+
+ return fvco;
+};
+
+static bool clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+ const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
+
+ return _clk_stm32_pll_is_enabled(priv, pll);
+}
+
+static int clk_stm32_pll_enable(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+ const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
+
+ return _clk_stm32_pll_enable(priv, pll);
+}
+
+static void clk_stm32_pll_disable(struct stm32_clk_priv *priv, int id)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, id);
+ struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+ const struct stm32_clk_pll *pll = clk_st32_pll_data(pll_cfg->pll_id);
+
+ _clk_stm32_pll_disable(priv, pll);
+}
+
+static const struct stm32_clk_ops clk_stm32_pll_ops = {
+ .recalc_rate = clk_stm32_pll_recalc_rate,
+ .enable = clk_stm32_pll_enable,
+ .disable = clk_stm32_pll_disable,
+ .is_enabled = clk_stm32_pll_is_enabled,
+};
+
+#define CLK_PLL(idx, _idx, _parent, _gate, _pll_id, _flags)[idx] = {\
+ .binding = _idx,\
+ .parent = _parent,\
+ .flags = (_flags),\
+ .clock_cfg = &(struct stm32_pll_cfg) {\
+ .pll_id = _pll_id,\
+ },\
+ .ops = &clk_stm32_pll_ops,\
+}
+
+struct clk_stm32_composite_cfg {
+ int gate_id;
+ int div_id;
+};
+
+static unsigned long clk_stm32_composite_recalc_rate(struct stm32_clk_priv *priv,
+ int idx, unsigned long prate)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, idx);
+ struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
+
+ return _clk_stm32_divider_recalc(priv, composite_cfg->div_id, prate);
+};
+
+static bool clk_stm32_composite_gate_is_enabled(struct stm32_clk_priv *priv, int idx)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, idx);
+ struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
+
+ return _clk_stm32_gate_is_enabled(priv, composite_cfg->gate_id);
+}
+
+static int clk_stm32_composite_gate_enable(struct stm32_clk_priv *priv, int idx)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, idx);
+ struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
+
+ return _clk_stm32_gate_enable(priv, composite_cfg->gate_id);
+}
+
+static void clk_stm32_composite_gate_disable(struct stm32_clk_priv *priv, int idx)
+{
+ const struct clk_stm32 *clk = _clk_get(priv, idx);
+ struct clk_stm32_composite_cfg *composite_cfg = clk->clock_cfg;
+
+ _clk_stm32_gate_disable(priv, composite_cfg->gate_id);
+}
+
+static const struct stm32_clk_ops clk_stm32_composite_ops = {
+ .recalc_rate = clk_stm32_composite_recalc_rate,
+ .is_enabled = clk_stm32_composite_gate_is_enabled,
+ .enable = clk_stm32_composite_gate_enable,
+ .disable = clk_stm32_composite_gate_disable,
+};
+
+#define STM32_COMPOSITE(idx, _binding, _parent, _flags, _gate_id,\
+ _div_id)[idx] = {\
+ .binding = (_binding),\
+ .parent = (_parent),\
+ .flags = (_flags),\
+ .clock_cfg = &(struct clk_stm32_composite_cfg) {\
+ .gate_id = (_gate_id),\
+ .div_id = (_div_id),\
+ },\
+ .ops = &clk_stm32_composite_ops,\
+}
+
+static const struct clk_stm32 stm32mp13_clk[CK_LAST] = {
+ /* ROOT CLOCKS */
+ CLK_FIXED_RATE(_CK_OFF, _NO_ID, 0),
+ CLK_OSC(_CK_HSE, CK_HSE, CLK_IS_ROOT, OSC_HSE),
+ CLK_OSC(_CK_HSI, CK_HSI, CLK_IS_ROOT, OSC_HSI),
+ CLK_OSC(_CK_CSI, CK_CSI, CLK_IS_ROOT, OSC_CSI),
+ CLK_OSC(_CK_LSI, CK_LSI, CLK_IS_ROOT, OSC_LSI),
+ CLK_OSC(_CK_LSE, CK_LSE, CLK_IS_ROOT, OSC_LSE),
+
+ CLK_OSC_FIXED(_I2SCKIN, _NO_ID, CLK_IS_ROOT, OSC_I2SCKIN),
+
+ CLK_FIXED_RATE(_USB_PHY_48, _NO_ID, USB_PHY_48_MHZ),
+
+ STM32_DIV(_HSE_DIV, _NO_ID, _CK_HSE, 0, DIV_RTC),
+
+ FIXED_FACTOR(_HSE_DIV2, CK_HSE_DIV2, _CK_HSE, 1, 2),
+ FIXED_FACTOR(_CSI_DIV122, _NO_ID, _CK_CSI, 1, 122),
+
+ CLK_PLL(_CK_PLL1, PLL1, MUX(MUX_PLL12), GATE_PLL1, _PLL1, 0),
+ CLK_PLL(_CK_PLL2, PLL2, MUX(MUX_PLL12), GATE_PLL2, _PLL2, 0),
+ CLK_PLL(_CK_PLL3, PLL3, MUX(MUX_PLL3), GATE_PLL3, _PLL3, 0),
+ CLK_PLL(_CK_PLL4, PLL4, MUX(MUX_PLL4), GATE_PLL4, _PLL4, 0),
+
+ STM32_COMPOSITE(_PLL1P, PLL1_P, _CK_PLL1, CLK_IS_CRITICAL, GATE_PLL1_DIVP, DIV_PLL1DIVP),
+ STM32_DIV(_PLL1P_DIV, _NO_ID, _CK_PLL1, 0, DIV_MPU),
+
+ STM32_COMPOSITE(_PLL2P, PLL2_P, _CK_PLL2, CLK_IS_CRITICAL, GATE_PLL2_DIVP, DIV_PLL2DIVP),
+ STM32_COMPOSITE(_PLL2Q, PLL2_Q, _CK_PLL2, 0, GATE_PLL2_DIVQ, DIV_PLL2DIVQ),
+ STM32_COMPOSITE(_PLL2R, PLL2_R, _CK_PLL2, CLK_IS_CRITICAL, GATE_PLL2_DIVR, DIV_PLL2DIVR),
+
+ STM32_COMPOSITE(_PLL3P, PLL3_P, _CK_PLL3, 0, GATE_PLL3_DIVP, DIV_PLL3DIVP),
+ STM32_COMPOSITE(_PLL3Q, PLL3_Q, _CK_PLL3, 0, GATE_PLL3_DIVQ, DIV_PLL3DIVQ),
+ STM32_COMPOSITE(_PLL3R, PLL3_R, _CK_PLL3, 0, GATE_PLL3_DIVR, DIV_PLL3DIVR),
+
+ STM32_COMPOSITE(_PLL4P, PLL4_P, _CK_PLL4, 0, GATE_PLL4_DIVP, DIV_PLL4DIVP),
+ STM32_COMPOSITE(_PLL4Q, PLL4_Q, _CK_PLL4, 0, GATE_PLL4_DIVQ, DIV_PLL4DIVQ),
+ STM32_COMPOSITE(_PLL4R, PLL4_R, _CK_PLL4, 0, GATE_PLL4_DIVR, DIV_PLL4DIVR),
+
+ STM32_MUX(_CKMPU, CK_MPU, MUX_MPU, 0),
+ STM32_DIV(_CKAXI, CK_AXI, MUX(MUX_AXI), 0, DIV_AXI),
+ STM32_DIV(_CKMLAHB, CK_MLAHB, MUX(MUX_MLAHB), CLK_IS_CRITICAL, DIV_MLAHB),
+ STM32_MUX(_CKPER, CK_PER, MUX(MUX_CKPER), 0),
+
+ STM32_DIV(_PCLK1, PCLK1, _CKMLAHB, 0, DIV_APB1),
+ STM32_DIV(_PCLK2, PCLK2, _CKMLAHB, 0, DIV_APB2),
+ STM32_DIV(_PCLK3, PCLK3, _CKMLAHB, 0, DIV_APB3),
+ STM32_DIV(_PCLK4, PCLK4, _CKAXI, 0, DIV_APB4),
+ STM32_DIV(_PCLK5, PCLK5, _CKAXI, 0, DIV_APB5),
+ STM32_DIV(_PCLK6, PCLK6, _CKMLAHB, 0, DIV_APB6),
+
+ CK_TIMER(_CKTIMG1, CK_TIMG1, _PCLK1, 0, RCC_APB1DIVR, RCC_TIMG1PRER),
+ CK_TIMER(_CKTIMG2, CK_TIMG2, _PCLK2, 0, RCC_APB2DIVR, RCC_TIMG2PRER),
+ CK_TIMER(_CKTIMG3, CK_TIMG3, _PCLK6, 0, RCC_APB6DIVR, RCC_TIMG3PRER),
+
+ /* END ROOT CLOCKS */
+
+ STM32_GATE(_DDRC1, DDRC1, _CKAXI, CLK_IS_CRITICAL, GATE_DDRC1),
+ STM32_GATE(_DDRC1LP, DDRC1LP, _CKAXI, CLK_IS_CRITICAL, GATE_DDRC1LP),
+ STM32_GATE(_DDRPHYC, DDRPHYC, _PLL2R, CLK_IS_CRITICAL, GATE_DDRPHYC),
+ STM32_GATE(_DDRPHYCLP, DDRPHYCLP, _PLL2R, CLK_IS_CRITICAL, GATE_DDRPHYCLP),
+ STM32_GATE(_DDRCAPB, DDRCAPB, _PCLK4, CLK_IS_CRITICAL, GATE_DDRCAPB),
+ STM32_GATE(_DDRCAPBLP, DDRCAPBLP, _PCLK4, CLK_IS_CRITICAL, GATE_DDRCAPBLP),
+ STM32_GATE(_AXIDCG, AXIDCG, _CKAXI, CLK_IS_CRITICAL, GATE_AXIDCG),
+ STM32_GATE(_DDRPHYCAPB, DDRPHYCAPB, _PCLK4, CLK_IS_CRITICAL, GATE_DDRPHYCAPB),
+ STM32_GATE(_DDRPHYCAPBLP, DDRPHYCAPBLP, _PCLK4, CLK_IS_CRITICAL, GATE_DDRPHYCAPBLP),
+
+ STM32_GATE(_SYSCFG, SYSCFG, _PCLK3, 0, GATE_SYSCFG),
+ STM32_GATE(_DDRPERFM, DDRPERFM, _PCLK4, 0, GATE_DDRPERFM),
+ STM32_GATE(_IWDG2APB, IWDG2, _PCLK4, 0, GATE_IWDG2APB),
+ STM32_GATE(_USBPHY_K, USBPHY_K, MUX(MUX_USBPHY), 0, GATE_USBPHY),
+ STM32_GATE(_USBO_K, USBO_K, MUX(MUX_USBO), 0, GATE_USBO),
+
+ STM32_GATE(_RTCAPB, RTCAPB, _PCLK5, CLK_IS_CRITICAL, GATE_RTCAPB),
+ STM32_GATE(_TZC, TZC, _PCLK5, CLK_IS_CRITICAL, GATE_TZC),
+ STM32_GATE(_ETZPC, TZPC, _PCLK5, CLK_IS_CRITICAL, GATE_ETZPC),
+ STM32_GATE(_IWDG1APB, IWDG1, _PCLK5, 0, GATE_IWDG1APB),
+ STM32_GATE(_BSEC, BSEC, _PCLK5, CLK_IS_CRITICAL, GATE_BSEC),
+ STM32_GATE(_STGENC, STGEN_K, MUX(MUX_STGEN), CLK_IS_CRITICAL, GATE_STGENC),
+
+ STM32_GATE(_USART1_K, USART1_K, MUX(MUX_UART1), 0, GATE_USART1),
+ STM32_GATE(_USART2_K, USART2_K, MUX(MUX_UART2), 0, GATE_USART2),
+ STM32_GATE(_I2C3_K, I2C3_K, MUX(MUX_I2C3), 0, GATE_I2C3),
+ STM32_GATE(_I2C4_K, I2C4_K, MUX(MUX_I2C4), 0, GATE_I2C4),
+ STM32_GATE(_I2C5_K, I2C5_K, MUX(MUX_I2C5), 0, GATE_I2C5),
+ STM32_GATE(_TIM12, TIM12_K, _CKTIMG3, 0, GATE_TIM12),
+ STM32_GATE(_TIM15, TIM15_K, _CKTIMG3, 0, GATE_TIM15),
+
+ STM32_GATE(_RTCCK, RTC, MUX(MUX_RTC), 0, GATE_RTCCK),
+
+ STM32_GATE(_GPIOA, GPIOA, _CKMLAHB, 0, GATE_GPIOA),
+ STM32_GATE(_GPIOB, GPIOB, _CKMLAHB, 0, GATE_GPIOB),
+ STM32_GATE(_GPIOC, GPIOC, _CKMLAHB, 0, GATE_GPIOC),
+ STM32_GATE(_GPIOD, GPIOD, _CKMLAHB, 0, GATE_GPIOD),
+ STM32_GATE(_GPIOE, GPIOE, _CKMLAHB, 0, GATE_GPIOE),
+ STM32_GATE(_GPIOF, GPIOF, _CKMLAHB, 0, GATE_GPIOF),
+ STM32_GATE(_GPIOG, GPIOG, _CKMLAHB, 0, GATE_GPIOG),
+ STM32_GATE(_GPIOH, GPIOH, _CKMLAHB, 0, GATE_GPIOH),
+ STM32_GATE(_GPIOI, GPIOI, _CKMLAHB, 0, GATE_GPIOI),
+
+ STM32_GATE(_PKA, PKA, _CKAXI, 0, GATE_PKA),
+ STM32_GATE(_SAES_K, SAES_K, MUX(MUX_SAES), 0, GATE_SAES),
+ STM32_GATE(_CRYP1, CRYP1, _PCLK5, 0, GATE_CRYP1),
+ STM32_GATE(_HASH1, HASH1, _PCLK5, 0, GATE_HASH1),
+
+ STM32_GATE(_RNG1_K, RNG1_K, MUX(MUX_RNG1), 0, GATE_RNG1),
+ STM32_GATE(_BKPSRAM, BKPSRAM, _PCLK5, CLK_IS_CRITICAL, GATE_BKPSRAM),
+
+ STM32_GATE(_SDMMC1_K, SDMMC1_K, MUX(MUX_SDMMC1), 0, GATE_SDMMC1),
+ STM32_GATE(_SDMMC2_K, SDMMC2_K, MUX(MUX_SDMMC2), 0, GATE_SDMMC2),
+ STM32_GATE(_DBGCK, CK_DBG, _CKAXI, 0, GATE_DBGCK),
+
+/* TODO: CHECK CLOCK FOR BL2/BL32 AND IF ONLY FOR TEST OR NOT */
+ STM32_GATE(_USART3_K, USART3_K, MUX(MUX_UART35), 0, GATE_USART3),
+ STM32_GATE(_UART4_K, UART4_K, MUX(MUX_UART4), 0, GATE_UART4),
+ STM32_GATE(_UART5_K, UART5_K, MUX(MUX_UART35), 0, GATE_UART5),
+ STM32_GATE(_UART7_K, UART7_K, MUX(MUX_UART78), 0, GATE_UART7),
+ STM32_GATE(_UART8_K, UART8_K, MUX(MUX_UART78), 0, GATE_UART8),
+ STM32_GATE(_USART6_K, USART6_K, MUX(MUX_UART6), 0, GATE_USART6),
+ STM32_GATE(_MCE, MCE, _CKAXI, CLK_IS_CRITICAL, GATE_MCE),
+ STM32_GATE(_FMC_K, FMC_K, MUX(MUX_FMC), 0, GATE_FMC),
+ STM32_GATE(_QSPI_K, QSPI_K, MUX(MUX_QSPI), 0, GATE_QSPI),
+
+ STM32_COMPOSITE(_MCO1_K, CK_MCO1, MUX(MUX_MCO1), 0, GATE_MCO1, DIV_MCO1),
+ STM32_COMPOSITE(_MCO2_K, CK_MCO2, MUX(MUX_MCO2), 0, GATE_MCO2, DIV_MCO2),
+ STM32_COMPOSITE(_TRACECK, CK_TRACE, _CKAXI, 0, GATE_TRACECK, DIV_TRACE),
+
+#if defined(IMAGE_BL32)
+ STM32_GATE(_TIM2, TIM2_K, _CKTIMG1, 0, GATE_TIM2),
+ STM32_GATE(_TIM3, TIM3_K, _CKTIMG1, 0, GATE_TIM3),
+ STM32_GATE(_TIM4, TIM4_K, _CKTIMG1, 0, GATE_TIM4),
+ STM32_GATE(_TIM5, TIM5_K, _CKTIMG1, 0, GATE_TIM5),
+ STM32_GATE(_TIM6, TIM6_K, _CKTIMG1, 0, GATE_TIM6),
+ STM32_GATE(_TIM7, TIM7_K, _CKTIMG1, 0, GATE_TIM7),
+ STM32_GATE(_TIM13, TIM13_K, _CKTIMG3, 0, GATE_TIM13),
+ STM32_GATE(_TIM14, TIM14_K, _CKTIMG3, 0, GATE_TIM14),
+ STM32_GATE(_LPTIM1_K, LPTIM1_K, MUX(MUX_LPTIM1), 0, GATE_LPTIM1),
+ STM32_GATE(_SPI2_K, SPI2_K, MUX(MUX_SPI23), 0, GATE_SPI2),
+ STM32_GATE(_SPI3_K, SPI3_K, MUX(MUX_SPI23), 0, GATE_SPI3),
+ STM32_GATE(_SPDIF_K, SPDIF_K, MUX(MUX_SPDIF), 0, GATE_SPDIF),
+ STM32_GATE(_TIM1, TIM1_K, _CKTIMG2, 0, GATE_TIM1),
+ STM32_GATE(_TIM8, TIM8_K, _CKTIMG2, 0, GATE_TIM8),
+ STM32_GATE(_TIM16, TIM16_K, _CKTIMG3, 0, GATE_TIM16),
+ STM32_GATE(_TIM17, TIM17_K, _CKTIMG3, 0, GATE_TIM17),
+ STM32_GATE(_SPI1_K, SPI1_K, MUX(MUX_SPI1), 0, GATE_SPI1),
+ STM32_GATE(_SPI4_K, SPI4_K, MUX(MUX_SPI4), 0, GATE_SPI4),
+ STM32_GATE(_SPI5_K, SPI5_K, MUX(MUX_SPI5), 0, GATE_SPI5),
+ STM32_GATE(_SAI1_K, SAI1_K, MUX(MUX_SAI1), 0, GATE_SAI1),
+ STM32_GATE(_SAI2_K, SAI2_K, MUX(MUX_SAI2), 0, GATE_SAI2),
+ STM32_GATE(_DFSDM, DFSDM_K, MUX(MUX_SAI1), 0, GATE_DFSDM),
+ STM32_GATE(_FDCAN_K, FDCAN_K, MUX(MUX_FDCAN), 0, GATE_FDCAN),
+ STM32_GATE(_USBH, USBH, _CKAXI, 0, GATE_USBH),
+ STM32_GATE(_I2C1_K, I2C1_K, MUX(MUX_I2C12), 0, GATE_I2C1),
+ STM32_GATE(_I2C2_K, I2C2_K, MUX(MUX_I2C12), 0, GATE_I2C2),
+ STM32_GATE(_ADFSDM, ADFSDM_K, MUX(MUX_SAI1), 0, GATE_ADFSDM),
+ STM32_GATE(_LPTIM2_K, LPTIM2_K, MUX(MUX_LPTIM2), 0, GATE_LPTIM2),
+ STM32_GATE(_LPTIM3_K, LPTIM3_K, MUX(MUX_LPTIM3), 0, GATE_LPTIM3),
+ STM32_GATE(_LPTIM4_K, LPTIM4_K, MUX(MUX_LPTIM45), 0, GATE_LPTIM4),
+ STM32_GATE(_LPTIM5_K, LPTIM5_K, MUX(MUX_LPTIM45), 0, GATE_LPTIM5),
+ STM32_GATE(_VREF, VREF, _PCLK3, 0, GATE_VREF),
+ STM32_GATE(_DTS, TMPSENS, _PCLK3, 0, GATE_DTS),
+ STM32_GATE(_PMBCTRL, PMBCTRL, _PCLK3, 0, GATE_HDP),
+ STM32_GATE(_HDP, HDP, _PCLK3, 0, GATE_PMBCTRL),
+ STM32_GATE(_STGENRO, STGENRO, _PCLK4, 0, GATE_DCMIPP),
+ STM32_GATE(_DCMIPP_K, DCMIPP_K, MUX(MUX_DCMIPP), 0, GATE_DCMIPP),
+ STM32_GATE(_DMAMUX1, DMAMUX1, _CKAXI, 0, GATE_DMAMUX1),
+ STM32_GATE(_DMAMUX2, DMAMUX2, _CKAXI, 0, GATE_DMAMUX2),
+ STM32_GATE(_DMA3, DMA3, _CKAXI, 0, GATE_DMAMUX2),
+ STM32_GATE(_ADC1_K, ADC1_K, MUX(MUX_ADC1), 0, GATE_ADC1),
+ STM32_GATE(_ADC2_K, ADC2_K, MUX(MUX_ADC2), 0, GATE_ADC2),
+ STM32_GATE(_TSC, TSC, _CKAXI, 0, GATE_TSC),
+ STM32_GATE(_AXIMC, AXIMC, _CKAXI, 0, GATE_AXIMC),
+ STM32_GATE(_CRC1, CRC1, _CKAXI, 0, GATE_ETH1TX),
+ STM32_GATE(_ETH1CK, ETH1CK_K, MUX(MUX_ETH1), 0, GATE_ETH1CK),
+ STM32_GATE(_ETH1TX, ETH1TX, _CKAXI, 0, GATE_ETH1TX),
+ STM32_GATE(_ETH1RX, ETH1RX, _CKAXI, 0, GATE_ETH1RX),
+ STM32_GATE(_ETH2CK, ETH2CK_K, MUX(MUX_ETH2), 0, GATE_ETH2CK),
+ STM32_GATE(_ETH2TX, ETH2TX, _CKAXI, 0, GATE_ETH2TX),
+ STM32_GATE(_ETH2RX, ETH2RX, _CKAXI, 0, GATE_ETH2RX),
+ STM32_GATE(_ETH2MAC, ETH2MAC, _CKAXI, 0, GATE_ETH2MAC),
+#endif
+};
+
+static struct stm32_pll_dt_cfg mp13_pll[_PLL_NB];
+
+static struct stm32_osci_dt_cfg mp13_osci[NB_OSCILLATOR];
+
+static uint32_t mp13_clksrc[MUX_MAX];
+
+static uint32_t mp13_clkdiv[DIV_MAX];
+
+static struct stm32_clk_platdata stm32mp13_clock_pdata = {
+ .osci = mp13_osci,
+ .nosci = NB_OSCILLATOR,
+ .pll = mp13_pll,
+ .npll = _PLL_NB,
+ .clksrc = mp13_clksrc,
+ .nclksrc = MUX_MAX,
+ .clkdiv = mp13_clkdiv,
+ .nclkdiv = DIV_MAX,
+};
+
+static struct stm32_clk_priv stm32mp13_clock_data = {
+ .base = RCC_BASE,
+ .num = ARRAY_SIZE(stm32mp13_clk),
+ .clks = stm32mp13_clk,
+ .parents = parent_mp13,
+ .nb_parents = ARRAY_SIZE(parent_mp13),
+ .gates = gates_mp13,
+ .nb_gates = ARRAY_SIZE(gates_mp13),
+ .div = dividers_mp13,
+ .nb_div = ARRAY_SIZE(dividers_mp13),
+ .osci_data = stm32mp13_osc_data,
+ .nb_osci_data = ARRAY_SIZE(stm32mp13_osc_data),
+ .gate_refcounts = refcounts_mp13,
+ .pdata = &stm32mp13_clock_pdata,
+};
+
+static int stm32mp1_init_clock_tree(void)
+{
+ struct stm32_clk_priv *priv = clk_stm32_get_priv();
+ int ret;
+
+#if STM32MP_USB_PROGRAMMER
+ int usbphy_p = _clk_stm32_get_parent(priv, _USBPHY_K);
+ int usbo_p = _clk_stm32_get_parent(priv, _USBO_K);
+
+ /* Don't initialize PLL4, when used by BOOTROM */
+ pll4_bootrom = stm32mp1_clk_is_pll4_used_by_bootrom(priv, usbphy_p);
+#endif
+
+ /*
+ * Switch ON oscillators found in device-tree.
+ * Note: HSI already ON after BootROM stage.
+ */
+ stm32_clk_oscillators_enable(priv);
+
+ /* Come back to HSI */
+ ret = stm32mp1_come_back_to_hsi();
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = stm32_clk_hsidiv_configure(priv);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = stm32_clk_stgen_configure(priv, _STGENC);
+ if (ret != 0) {
+ panic();
+ }
+
+ ret = stm32_clk_dividers_configure(priv);
+ if (ret != 0) {
+ panic();
+ }
+
+ ret = stm32_clk_pll_configure(priv);
+ if (ret != 0) {
+ panic();
+ }
+
+ /* Wait LSE ready before to use it */
+ ret = stm32_clk_oscillators_wait_lse_ready(priv);
+ if (ret != 0) {
+ panic();
+ }
+
+ /* Configure with expected clock source */
+ ret = stm32_clk_source_configure(priv);
+ if (ret != 0) {
+ panic();
+ }
+
+ /* Configure LSE css after RTC source configuration */
+ ret = stm32_clk_oscillators_lse_set_css(priv);
+ if (ret != 0) {
+ panic();
+ }
+
+#if STM32MP_USB_PROGRAMMER
+ ret = stm32mp1_clk_check_usb_conflict(priv, usbphy_p, usbo_p);
+ if (ret != 0) {
+ return ret;
+ }
+#endif
+ /* reconfigure STGEN with DT config */
+ ret = stm32_clk_stgen_configure(priv, _STGENC);
+ if (ret != 0) {
+ panic();
+ }
+
+ /* Software Self-Refresh mode (SSR) during DDR initilialization */
+ mmio_clrsetbits_32(priv->base + RCC_DDRITFCR,
+ RCC_DDRITFCR_DDRCKMOD_MASK,
+ RCC_DDRITFCR_DDRCKMOD_SSR <<
+ RCC_DDRITFCR_DDRCKMOD_SHIFT);
+
+ return 0;
+}
+
+#define LSEDRV_MEDIUM_HIGH 2
+
+static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name,
+ struct stm32_osci_dt_cfg *osci)
+{
+ int subnode = 0;
+
+ /* default value oscillator not found, freq=0 */
+ osci->freq = 0;
+
+ fdt_for_each_subnode(subnode, fdt, node) {
+ const char *cchar = NULL;
+ const fdt32_t *cuint = NULL;
+ int ret = 0;
+
+ cchar = fdt_get_name(fdt, subnode, &ret);
+ if (cchar == NULL) {
+ return ret;
+ }
+
+ if (strncmp(cchar, name, (size_t)ret) ||
+ fdt_get_status(subnode) == DT_DISABLED) {
+ continue;
+ }
+
+ cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret);
+ if (cuint == NULL) {
+ return ret;
+ }
+
+ osci->freq = fdt32_to_cpu(*cuint);
+
+ if (fdt_getprop(fdt, subnode, "st,bypass", NULL) != NULL) {
+ osci->bypass = true;
+ }
+
+ if (fdt_getprop(fdt, subnode, "st,digbypass", NULL) != NULL) {
+ osci->digbyp = true;
+ }
+
+ if (fdt_getprop(fdt, subnode, "st,css", NULL) != NULL) {
+ osci->css = true;
+ }
+
+ osci->drive = fdt_read_uint32_default(fdt, subnode, "st,drive", LSEDRV_MEDIUM_HIGH);
+
+ return 0;
+ }
+
+ return 0;
+}
+
+static int stm32_clk_parse_fdt_all_oscillator(void *fdt, struct stm32_clk_platdata *pdata)
+{
+ int fdt_err = 0;
+ uint32_t i = 0;
+ int node = 0;
+
+ node = fdt_path_offset(fdt, "/clocks");
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ for (i = 0; i < pdata->nosci; i++) {
+ const char *name = NULL;
+
+ name = clk_stm32_get_oscillator_name((enum stm32_osc)i);
+ if (name == NULL) {
+ continue;
+ }
+
+ fdt_err = clk_stm32_parse_oscillator_fdt(fdt, node, name, &pdata->osci[i]);
+ if (fdt_err < 0) {
+ panic();
+ }
+ }
+
+ return 0;
+}
+
+#define RCC_PLL_NAME_SIZE 12
+
+static int clk_stm32_load_vco_config(void *fdt, int subnode, struct stm32_pll_vco *vco)
+{
+ int err = 0;
+
+ err = fdt_read_uint32_array(fdt, subnode, "divmn", (int)PLL_DIV_MN_NB, vco->div_mn);
+ if (err != 0) {
+ return err;
+ }
+
+ err = fdt_read_uint32_array(fdt, subnode, "csg", (int)PLL_CSG_NB, vco->csg);
+
+ vco->csg_enabled = (err == 0);
+
+ if (err == -FDT_ERR_NOTFOUND) {
+ err = 0;
+ }
+
+ if (err != 0) {
+ return err;
+ }
+
+ vco->status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | RCC_PLLNCR_DIVREN | RCC_PLLNCR_PLLON;
+
+ vco->frac = fdt_read_uint32_default(fdt, subnode, "frac", 0);
+
+ vco->src = fdt_read_uint32_default(fdt, subnode, "src", UINT32_MAX);
+
+ return 0;
+}
+
+static int clk_stm32_load_output_config(void *fdt, int subnode, struct stm32_pll_output *output)
+{
+ int err = 0;
+
+ err = fdt_read_uint32_array(fdt, subnode, "st,pll_div_pqr", (int)PLL_DIV_PQR_NB,
+ output->output);
+ if (err != 0) {
+ return err;
+ }
+
+ return 0;
+}
+
+static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+ const fdt32_t *cuint = NULL;
+ int subnode_pll = 0;
+ int subnode_vco = 0;
+ int err = 0;
+
+ cuint = fdt_getprop(fdt, subnode, "st,pll", NULL);
+ if (!cuint) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+ if (subnode_pll < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ cuint = fdt_getprop(fdt, subnode_pll, "st,pll_vco", NULL);
+ if (!cuint) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ subnode_vco = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+ if (subnode_vco < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ err = clk_stm32_load_vco_config(fdt, subnode_vco, &pll->vco);
+ if (err != 0) {
+ return err;
+ }
+
+ err = clk_stm32_load_output_config(fdt, subnode_pll, &pll->output);
+ if (err != 0) {
+ return err;
+ }
+
+ return 0;
+}
+
+static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata)
+{
+ size_t i = 0U;
+
+ for (i = _PLL1; i < pdata->npll; i++) {
+ struct stm32_pll_dt_cfg *pll = pdata->pll + i;
+ char name[RCC_PLL_NAME_SIZE];
+ int subnode = 0;
+ int err = 0;
+
+ snprintf(name, sizeof(name), "st,pll@%u", i);
+
+ subnode = fdt_subnode_offset(fdt, node, name);
+ if (!fdt_check_node(subnode)) {
+ continue;
+ }
+
+ err = clk_stm32_parse_pll_fdt(fdt, subnode, pll);
+ if (err != 0) {
+ panic();
+ }
+ }
+
+ return 0;
+}
+
+static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata)
+{
+ void *fdt = NULL;
+ int node;
+ uint32_t err;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -ENOENT;
+ }
+
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+ if (node < 0) {
+ panic();
+ }
+
+ err = stm32_clk_parse_fdt_all_oscillator(fdt, pdata);
+ if (err != 0) {
+ return err;
+ }
+
+ err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata);
+ if (err != 0) {
+ return err;
+ }
+
+ err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clkdiv", pdata->clkdiv, &pdata->nclkdiv);
+ if (err != 0) {
+ return err;
+ }
+
+ err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clksrc", pdata->clksrc, &pdata->nclksrc);
+ if (err != 0) {
+ return err;
+ }
+
+ return 0;
+}
+
+int stm32mp1_clk_init(void)
+{
+ return 0;
+}
+
+int stm32mp1_clk_probe(void)
+{
+ uintptr_t base = RCC_BASE;
+ int ret;
+
+ ret = stm32_clk_parse_fdt(&stm32mp13_clock_pdata);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = clk_stm32_init(&stm32mp13_clock_data, base);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = stm32mp1_init_clock_tree();
+ if (ret != 0) {
+ return ret;
+ }
+
+ clk_stm32_enable_critical_clocks();
+
+ return 0;
+}
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index 534ee3b..aa5db6f 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -232,7 +232,6 @@
struct stm32mp1_pll {
uint8_t refclk_min;
uint8_t refclk_max;
- uint8_t divn_max;
};
struct stm32mp1_clk_gate {
@@ -543,12 +542,10 @@
[PLL_800] = {
.refclk_min = 4,
.refclk_max = 16,
- .divn_max = 99,
},
[PLL_1600] = {
.refclk_min = 8,
.refclk_max = 16,
- .divn_max = 199,
},
};
diff --git a/drivers/st/etzpc/etzpc.c b/drivers/st/etzpc/etzpc.c
index ff52a22..4c3c26d 100644
--- a/drivers/st/etzpc/etzpc.c
+++ b/drivers/st/etzpc/etzpc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -225,20 +225,8 @@
int etzpc_init(void)
{
uint32_t hwcfg;
- int node;
- struct dt_node_info etzpc_info;
-
- node = dt_get_node(&etzpc_info, -1, ETZPC_COMPAT);
- if (node < 0) {
- return -EIO;
- }
-
- /* Check ETZPC is secure only */
- if (etzpc_info.status != DT_SECURE) {
- return -EACCES;
- }
- etzpc_dev.base = etzpc_info.base;
+ etzpc_dev.base = STM32MP1_ETZPC_BASE;
hwcfg = mmio_read_32(etzpc_dev.base + ETZPC_HWCFGR);
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index 3f709a7..6bdd782 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -125,7 +125,11 @@
#define POWER_OFF_DELAY 2
#define POWER_ON_DELAY 1
+#ifndef DT_SDMMC2_COMPAT
#define DT_SDMMC2_COMPAT "st,stm32-sdmmc2"
+#endif
+
+#define SDMMC_FIFO_SIZE 64U
static void stm32_sdmmc2_init(void);
static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd);
@@ -146,6 +150,8 @@
static struct stm32_sdmmc2_params sdmmc2_params;
+static bool next_cmd_is_acmd;
+
#pragma weak plat_sdmmc2_use_dma
bool plat_sdmmc2_use_dma(unsigned int instance, unsigned int memory)
{
@@ -255,6 +261,20 @@
case MMC_CMD(1):
arg_reg |= OCR_POWERUP;
break;
+ case MMC_CMD(6):
+ if ((sdmmc2_params.device_info->mmc_dev_type == MMC_IS_SD_HC) &&
+ (!next_cmd_is_acmd)) {
+ cmd_reg |= SDMMC_CMDR_CMDTRANS;
+ if (sdmmc2_params.use_dma) {
+ flags_data |= SDMMC_STAR_DCRCFAIL |
+ SDMMC_STAR_DTIMEOUT |
+ SDMMC_STAR_DATAEND |
+ SDMMC_STAR_RXOVERR |
+ SDMMC_STAR_IDMATE |
+ SDMMC_STAR_DBCKEND;
+ }
+ }
+ break;
case MMC_CMD(8):
if (sdmmc2_params.device_info->mmc_dev_type == MMC_IS_EMMC) {
cmd_reg |= SDMMC_CMDR_CMDTRANS;
@@ -292,6 +312,8 @@
break;
}
+ next_cmd_is_acmd = (cmd->cmd_idx == MMC_CMD(55));
+
mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS);
/*
@@ -299,8 +321,7 @@
* Skip CMD55 as the next command could be data related, and
* the register could have been set in prepare function.
*/
- if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) &&
- (cmd->cmd_idx != MMC_CMD(55))) {
+ if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) && !next_cmd_is_acmd) {
mmio_write_32(base + SDMMC_DCTRLR, 0U);
}
@@ -625,7 +646,7 @@
return -ETIMEDOUT;
}
- if (size < (8U * sizeof(uint32_t))) {
+ if (size < (SDMMC_FIFO_SIZE / 2U)) {
if ((mmio_read_32(base + SDMMC_DCNTR) > 0U) &&
((status & SDMMC_STAR_RXFIFOE) == 0U)) {
*buffer = mmio_read_32(fifo_reg);
@@ -635,7 +656,8 @@
uint32_t count;
/* Read data from SDMMC Rx FIFO */
- for (count = 0; count < 8U; count++) {
+ for (count = 0; count < (SDMMC_FIFO_SIZE / 2U);
+ count += sizeof(uint32_t)) {
*buffer = mmio_read_32(fifo_reg);
buffer++;
}
@@ -735,8 +757,6 @@
int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params)
{
- int rc;
-
assert((params != NULL) &&
((params->reg_base & MMC_BLOCK_MASK) == 0U) &&
((params->bus_width == MMC_BUS_WIDTH_1) ||
@@ -754,16 +774,20 @@
clk_enable(sdmmc2_params.clock_id);
- rc = stm32mp_reset_assert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS);
- if (rc != 0) {
- panic();
- }
- udelay(2);
- rc = stm32mp_reset_deassert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS);
- if (rc != 0) {
- panic();
+ if ((int)sdmmc2_params.reset_id >= 0) {
+ int rc;
+
+ rc = stm32mp_reset_assert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS);
+ if (rc != 0) {
+ panic();
+ }
+ udelay(2);
+ rc = stm32mp_reset_deassert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS);
+ if (rc != 0) {
+ panic();
+ }
+ mdelay(1);
}
- mdelay(1);
sdmmc2_params.clk_rate = clk_get_rate(sdmmc2_params.clock_id);
sdmmc2_params.device_info->ocr_voltage = OCR_3_2_3_3 | OCR_3_3_3_4;
diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c
index 7030cf5..5b43760 100644
--- a/drivers/st/pmic/stm32mp_pmic.c
+++ b/drivers/st/pmic/stm32mp_pmic.c
@@ -219,17 +219,20 @@
{
int status;
uint16_t buck3_min_mv;
- struct rdev *buck2, *buck3, *ldo3, *vref;
+ struct rdev *buck2, *buck3, *vref;
+ struct rdev *ldo3 __unused;
buck2 = regulator_get_by_name("buck2");
if (buck2 == NULL) {
return -ENOENT;
}
+#if STM32MP15
ldo3 = regulator_get_by_name("ldo3");
if (ldo3 == NULL) {
return -ENOENT;
}
+#endif
vref = regulator_get_by_name("vref_ddr");
if (vref == NULL) {
@@ -238,10 +241,12 @@
switch (ddr_type) {
case STM32MP_DDR3:
+#if STM32MP15
status = regulator_set_flag(ldo3, REGUL_SINK_SOURCE);
if (status != 0) {
return status;
}
+#endif
status = regulator_set_min_voltage(buck2);
if (status != 0) {
@@ -258,10 +263,12 @@
return status;
}
+#if STM32MP15
status = regulator_enable(ldo3);
if (status != 0) {
return status;
}
+#endif
break;
case STM32MP_LPDDR2:
@@ -278,6 +285,7 @@
regulator_get_range(buck3, &buck3_min_mv, NULL);
+#if STM32MP15
if (buck3_min_mv != 1800) {
status = regulator_set_min_voltage(ldo3);
if (status != 0) {
@@ -289,16 +297,19 @@
return status;
}
}
+#endif
status = regulator_set_min_voltage(buck2);
if (status != 0) {
return status;
}
+#if STM32MP15
status = regulator_enable(ldo3);
if (status != 0) {
return status;
}
+#endif
status = regulator_enable(buck2);
if (status != 0) {
@@ -318,6 +329,36 @@
return 0;
}
+int pmic_voltages_init(void)
+{
+#if STM32MP13
+ struct rdev *buck1, *buck4;
+ int status;
+
+ buck1 = regulator_get_by_name("buck1");
+ if (buck1 == NULL) {
+ return -ENOENT;
+ }
+
+ buck4 = regulator_get_by_name("buck4");
+ if (buck4 == NULL) {
+ return -ENOENT;
+ }
+
+ status = regulator_set_min_voltage(buck1);
+ if (status != 0) {
+ return status;
+ }
+
+ status = regulator_set_min_voltage(buck4);
+ if (status != 0) {
+ return status;
+ }
+#endif
+
+ return 0;
+}
+
enum {
STPMIC1_BUCK1 = 0,
STPMIC1_BUCK2,
diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c
index d3c26d9..73aa9ac 100644
--- a/drivers/st/spi/stm32_qspi.c
+++ b/drivers/st/spi/stm32_qspi.c
@@ -1,13 +1,10 @@
/*
- * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
#include <inttypes.h>
-#include <libfdt.h>
-
-#include <platform_def.h>
#include <common/debug.h>
#include <common/fdt_wrappers.h>
@@ -19,6 +16,9 @@
#include <drivers/st/stm32mp_reset.h>
#include <lib/mmio.h>
#include <lib/utils_def.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
/* Timeout for device interface reset */
#define TIMEOUT_US_1_MS 1000U
@@ -139,10 +139,6 @@
int ret = 0;
uint64_t timeout;
- if (op->data.nbytes == 0U) {
- return stm32_qspi_wait_for_not_busy();
- }
-
timeout = timeout_init_us(QSPI_CMD_TIMEOUT_US);
while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_TCF) == 0U) {
if (timeout_elapsed(timeout)) {
@@ -163,6 +159,10 @@
/* Clear flags */
mmio_write_32(qspi_base() + QSPI_FCR, QSPI_FCR_CTCF | QSPI_FCR_CTEF);
+ if (ret == 0) {
+ ret = stm32_qspi_wait_for_not_busy();
+ }
+
return ret;
}
@@ -251,11 +251,6 @@
op->dummy.buswidth, op->data.buswidth,
op->addr.val, op->data.nbytes);
- ret = stm32_qspi_wait_for_not_busy();
- if (ret != 0) {
- return ret;
- }
-
addr_max = op->addr.val + op->data.nbytes + 1U;
if ((op->data.dir == SPI_MEM_DATA_IN) && (op->data.nbytes != 0U)) {
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 3d6d99f..754d173 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -146,11 +146,43 @@
return 0;
}
+static int ufshc_hce_disable(uintptr_t base)
+{
+ unsigned int data;
+ int timeout;
+
+ /* Disable Host Controller */
+ mmio_write_32(base + HCE, HCE_DISABLE);
+ timeout = HCE_DISABLE_TIMEOUT_US;
+ do {
+ data = mmio_read_32(base + HCE);
+ if ((data & HCE_ENABLE) == HCE_DISABLE) {
+ break;
+ }
+ udelay(1);
+ } while (--timeout > 0);
+
+ if (timeout <= 0) {
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+
static int ufshc_reset(uintptr_t base)
{
unsigned int data;
int retries, result;
+ /* disable controller if enabled */
+ if (mmio_read_32(base + HCE) & HCE_ENABLE) {
+ result = ufshc_hce_disable(base);
+ if (result != 0) {
+ return -EIO;
+ }
+ }
+
for (retries = 0; retries < HCE_ENABLE_OUTER_RETRIES; ++retries) {
result = ufshc_hce_enable(base);
if (result == 0) {
@@ -193,8 +225,7 @@
}
continue;
}
- while ((mmio_read_32(base + HCS) & HCS_DP) == 0)
- ;
+ assert((mmio_read_32(base + HCS) & HCS_DP) == 0);
data = mmio_read_32(base + IS);
if (data & UFS_INT_ULSS)
mmio_write_32(base + IS, UFS_INT_ULSS);
@@ -233,7 +264,7 @@
/* clear utrd */
memset((void *)utrd, 0, sizeof(utp_utrd_t));
- base = ufs_params.desc_base + (slot * UFS_DESC_SIZE);
+ base = ufs_params.desc_base + (slot * sizeof(utrd_header_t));
/* clear the descriptor */
memset((void *)base, 0, UFS_DESC_SIZE);
@@ -268,12 +299,6 @@
unsigned int lba_cnt;
int prdt_size;
-
- mmio_write_32(ufs_params.reg_base + UTRLBA,
- utrd->header & UINT32_MAX);
- mmio_write_32(ufs_params.reg_base + UTRLBAU,
- (utrd->upiu >> 32) & UINT32_MAX);
-
hd = (utrd_header_t *)utrd->header;
upiu = (cmd_upiu_t *)utrd->upiu;
@@ -356,7 +381,6 @@
hd->prdto = (utrd->size_upiu + utrd->size_resp_upiu) >> 2;
}
- flush_dcache_range((uintptr_t)utrd, sizeof(utp_utrd_t));
flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE);
return 0;
}
@@ -372,12 +396,6 @@
hd = (utrd_header_t *)utrd->header;
query_upiu = (query_upiu_t *)utrd->upiu;
- mmio_write_32(ufs_params.reg_base + UTRLBA,
- utrd->header & UINT32_MAX);
- mmio_write_32(ufs_params.reg_base + UTRLBAU,
- (utrd->header >> 32) & UINT32_MAX);
-
-
hd->i = 1;
hd->ct = CT_UFS_STORAGE;
hd->ocs = OCS_MASK;
@@ -409,13 +427,12 @@
break;
case QUERY_WRITE_ATTR:
query_upiu->query_func = QUERY_FUNC_STD_WRITE;
- memcpy((void *)&query_upiu->ts.attr.value, (void *)buf, length);
+ query_upiu->ts.attr.value = htobe32(*((uint32_t *)buf));
break;
default:
assert(0);
break;
}
- flush_dcache_range((uintptr_t)utrd, sizeof(utp_utrd_t));
flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE);
return 0;
}
@@ -425,11 +442,6 @@
utrd_header_t *hd;
nop_out_upiu_t *nop_out;
- mmio_write_32(ufs_params.reg_base + UTRLBA,
- utrd->header & UINT32_MAX);
- mmio_write_32(ufs_params.reg_base + UTRLBAU,
- (utrd->header >> 32) & UINT32_MAX);
-
hd = (utrd_header_t *)utrd->header;
nop_out = (nop_out_upiu_t *)utrd->upiu;
@@ -439,7 +451,6 @@
nop_out->trans_type = 0;
nop_out->task_tag = utrd->task_tag;
- flush_dcache_range((uintptr_t)utrd, sizeof(utp_utrd_t));
flush_dcache_range((uintptr_t)utrd->header, UFS_DESC_SIZE);
}
@@ -453,9 +464,7 @@
mmio_write_32(ufs_params.reg_base + IS, ~0);
mmio_write_32(ufs_params.reg_base + UTRLRSR, 1);
- do {
- data = mmio_read_32(ufs_params.reg_base + UTRLRSR);
- } while (data == 0);
+ assert(mmio_read_32(ufs_params.reg_base + UTRLRSR) == 1);
data = UTRIACR_IAEN | UTRIACR_CTR | UTRIACR_IACTH(0x1F) |
UTRIACR_IATOVAL(0xFF);
@@ -473,7 +482,6 @@
hd = (utrd_header_t *)utrd->header;
resp = (resp_upiu_t *)utrd->resp_upiu;
- inv_dcache_range((uintptr_t)hd, UFS_DESC_SIZE);
do {
data = mmio_read_32(ufs_params.reg_base + IS);
if ((data & ~(UFS_INT_UCCS | UFS_INT_UTRCS)) != 0)
@@ -483,6 +491,12 @@
data = mmio_read_32(ufs_params.reg_base + UTRLDBR);
assert((data & (1 << slot)) == 0);
+ /*
+ * Invalidate the header after DMA read operation has
+ * completed to avoid cpu referring to the prefetched
+ * data brought in before DMA completion.
+ */
+ inv_dcache_range((uintptr_t)hd, UFS_DESC_SIZE);
assert(hd->ocs == OCS_SUCCESS);
assert((resp->trans_type & TRANS_TYPE_CODE_MASK) == trans_type);
(void)resp;
@@ -490,6 +504,21 @@
return 0;
}
+static void ufs_send_cmd(utp_utrd_t *utrd, uint8_t cmd_op, uint8_t lun, int lba, uintptr_t buf,
+ size_t length)
+{
+ int result;
+
+ get_utrd(utrd);
+
+ result = ufs_prepare_cmd(utrd, cmd_op, lun, lba, buf, length);
+ assert(result == 0);
+ ufs_send_request(utrd->task_tag);
+ result = ufs_check_resp(utrd, RESPONSE_UPIU);
+ assert(result == 0);
+ (void)result;
+}
+
#ifdef UFS_RESP_DEBUG
static void dump_upiu(utp_utrd_t *utrd)
{
@@ -540,14 +569,7 @@
static void ufs_verify_ready(void)
{
utp_utrd_t utrd;
- int result;
-
- get_utrd(&utrd);
- ufs_prepare_cmd(&utrd, CDBCMD_TEST_UNIT_READY, 0, 0, 0, 0);
- ufs_send_request(utrd.task_tag);
- result = ufs_check_resp(&utrd, RESPONSE_UPIU);
- assert(result == 0);
- (void)result;
+ ufs_send_cmd(&utrd, CDBCMD_TEST_UNIT_READY, 0, 0, 0, 0);
}
static void ufs_query(uint8_t op, uint8_t idn, uint8_t index, uint8_t sel,
@@ -584,12 +606,14 @@
case QUERY_READ_FLAG:
*(uint32_t *)buf = (uint32_t)resp->ts.flag.value;
break;
- case QUERY_READ_ATTR:
case QUERY_READ_DESC:
memcpy((void *)buf,
(void *)(utrd.resp_upiu + sizeof(query_resp_upiu_t)),
size);
break;
+ case QUERY_READ_ATTR:
+ *(uint32_t *)buf = htobe32(resp->ts.attr.value);
+ break;
default:
/* Do nothing in default case */
break;
@@ -641,15 +665,14 @@
ufs_query(QUERY_WRITE_DESC, idn, index, 0, buf, size);
}
-static void ufs_read_capacity(int lun, unsigned int *num, unsigned int *size)
+static int ufs_read_capacity(int lun, unsigned int *num, unsigned int *size)
{
utp_utrd_t utrd;
resp_upiu_t *resp;
sense_data_t *sense;
unsigned char data[CACHE_WRITEBACK_GRANULE << 1];
uintptr_t buf;
- int result;
- int retry;
+ int retries = UFS_READ_CAPACITY_RETRIES;
assert((ufs_params.reg_base != 0) &&
(ufs_params.desc_base != 0) &&
@@ -660,58 +683,52 @@
buf = (uintptr_t)data;
buf = (buf + CACHE_WRITEBACK_GRANULE - 1) &
~(CACHE_WRITEBACK_GRANULE - 1);
- memset((void *)buf, 0, CACHE_WRITEBACK_GRANULE);
- flush_dcache_range(buf, CACHE_WRITEBACK_GRANULE);
do {
- get_utrd(&utrd);
- ufs_prepare_cmd(&utrd, CDBCMD_READ_CAPACITY_10, lun, 0,
- buf, READ_CAPACITY_LENGTH);
- ufs_send_request(utrd.task_tag);
- result = ufs_check_resp(&utrd, RESPONSE_UPIU);
- assert(result == 0);
+ ufs_send_cmd(&utrd, CDBCMD_READ_CAPACITY_10, lun, 0,
+ buf, READ_CAPACITY_LENGTH);
#ifdef UFS_RESP_DEBUG
dump_upiu(&utrd);
#endif
resp = (resp_upiu_t *)utrd.resp_upiu;
- retry = 0;
sense = &resp->sd.sense;
- if (sense->resp_code == SENSE_DATA_VALID) {
- if ((sense->sense_key == SENSE_KEY_UNIT_ATTENTION) &&
- (sense->asc == 0x29) && (sense->ascq == 0)) {
- retry = 1;
- }
+ if (!((sense->resp_code == SENSE_DATA_VALID) &&
+ (sense->sense_key == SENSE_KEY_UNIT_ATTENTION) &&
+ (sense->asc == 0x29) && (sense->ascq == 0))) {
+ inv_dcache_range(buf, CACHE_WRITEBACK_GRANULE);
+ /* last logical block address */
+ *num = be32toh(*(unsigned int *)buf);
+ if (*num)
+ *num += 1;
+ /* logical block length in bytes */
+ *size = be32toh(*(unsigned int *)(buf + 4));
+
+ return 0;
}
- inv_dcache_range(buf, CACHE_WRITEBACK_GRANULE);
- /* last logical block address */
- *num = be32toh(*(unsigned int *)buf);
- if (*num)
- *num += 1;
- /* logical block length in bytes */
- *size = be32toh(*(unsigned int *)(buf + 4));
- } while (retry);
- (void)result;
+
+ } while (retries-- > 0);
+
+ return -ETIMEDOUT;
}
size_t ufs_read_blocks(int lun, int lba, uintptr_t buf, size_t size)
{
utp_utrd_t utrd;
resp_upiu_t *resp;
- int result;
assert((ufs_params.reg_base != 0) &&
(ufs_params.desc_base != 0) &&
(ufs_params.desc_size >= UFS_DESC_SIZE));
- get_utrd(&utrd);
- ufs_prepare_cmd(&utrd, CDBCMD_READ_10, lun, lba, buf, size);
- ufs_send_request(utrd.task_tag);
- result = ufs_check_resp(&utrd, RESPONSE_UPIU);
- assert(result == 0);
+ ufs_send_cmd(&utrd, CDBCMD_READ_10, lun, lba, buf, size);
#ifdef UFS_RESP_DEBUG
dump_upiu(&utrd);
#endif
+ /*
+ * Invalidate prefetched cache contents before cpu
+ * accesses the buf.
+ */
+ inv_dcache_range(buf, size);
resp = (resp_upiu_t *)utrd.resp_upiu;
- (void)result;
return size - resp->res_trans_cnt;
}
@@ -719,48 +736,75 @@
{
utp_utrd_t utrd;
resp_upiu_t *resp;
- int result;
assert((ufs_params.reg_base != 0) &&
(ufs_params.desc_base != 0) &&
(ufs_params.desc_size >= UFS_DESC_SIZE));
- get_utrd(&utrd);
- ufs_prepare_cmd(&utrd, CDBCMD_WRITE_10, lun, lba, buf, size);
- ufs_send_request(utrd.task_tag);
- result = ufs_check_resp(&utrd, RESPONSE_UPIU);
- assert(result == 0);
+ ufs_send_cmd(&utrd, CDBCMD_WRITE_10, lun, lba, buf, size);
#ifdef UFS_RESP_DEBUG
dump_upiu(&utrd);
#endif
resp = (resp_upiu_t *)utrd.resp_upiu;
- (void)result;
return size - resp->res_trans_cnt;
}
+static int ufs_set_fdevice_init(void)
+{
+ unsigned int result;
+ int timeout;
+
+ ufs_set_flag(FLAG_DEVICE_INIT);
+
+ timeout = FDEVICEINIT_TIMEOUT_MS;
+ do {
+ result = ufs_read_flag(FLAG_DEVICE_INIT);
+ if (!result) {
+ break;
+ }
+ mdelay(5);
+ timeout -= 5;
+ } while (timeout > 0);
+
+ if (result != 0U) {
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
static void ufs_enum(void)
{
unsigned int blk_num, blk_size;
- int i;
+ int i, result;
- /* 0 means 1 slot */
- nutrs = (mmio_read_32(ufs_params.reg_base + CAP) & CAP_NUTRS_MASK) + 1;
- if (nutrs > (ufs_params.desc_size / UFS_DESC_SIZE))
- nutrs = ufs_params.desc_size / UFS_DESC_SIZE;
+ mmio_write_32(ufs_params.reg_base + UTRLBA,
+ ufs_params.desc_base & UINT32_MAX);
+ mmio_write_32(ufs_params.reg_base + UTRLBAU,
+ (ufs_params.desc_base >> 32) & UINT32_MAX);
ufs_verify_init();
ufs_verify_ready();
- ufs_set_flag(FLAG_DEVICE_INIT);
- mdelay(200);
+ result = ufs_set_fdevice_init();
+ assert(result == 0);
+
+ blk_num = 0;
+ blk_size = 0;
+
/* dump available LUNs */
for (i = 0; i < UFS_MAX_LUNS; i++) {
- ufs_read_capacity(i, &blk_num, &blk_size);
+ result = ufs_read_capacity(i, &blk_num, &blk_size);
+ if (result != 0) {
+ WARN("UFS LUN%d dump failed\n", i);
+ }
if (blk_num && blk_size) {
INFO("UFS LUN%d contains %d blocks with %d-byte size\n",
i, blk_num, blk_size);
}
}
+
+ (void)result;
}
static void ufs_get_device_info(struct ufs_dev_desc *card_data)
@@ -792,7 +836,19 @@
memcpy(&ufs_params, params, sizeof(ufs_params_t));
+ /* 0 means 1 slot */
+ nutrs = (mmio_read_32(ufs_params.reg_base + CAP) & CAP_NUTRS_MASK) + 1;
+ if (nutrs > (ufs_params.desc_size / UFS_DESC_SIZE)) {
+ nutrs = ufs_params.desc_size / UFS_DESC_SIZE;
+ }
+
+
if (ufs_params.flags & UFS_FLAGS_SKIPINIT) {
+ mmio_write_32(ufs_params.reg_base + UTRLBA,
+ ufs_params.desc_base & UINT32_MAX);
+ mmio_write_32(ufs_params.reg_base + UTRLBAU,
+ (ufs_params.desc_base >> 32) & UINT32_MAX);
+
result = ufshc_dme_get(0x1571, 0, &data);
assert(result == 0);
result = ufshc_dme_get(0x41, 0, &data);
diff --git a/fdts/n1sdp-multi-chip.dts b/fdts/n1sdp-multi-chip.dts
index 8932dfc..852b899 100644
--- a/fdts/n1sdp-multi-chip.dts
+++ b/fdts/n1sdp-multi-chip.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause)
/*
- * Copyright (c) 2019-2020, Arm Limited.
+ * Copyright (c) 2019-2022, Arm Limited.
*/
#include "n1sdp-single-chip.dts"
@@ -54,19 +54,19 @@
<1 1 10>;
};
- smmu_slave_pcie: iommu@4004f400000 {
+ smmu_secondary_pcie: iommu@4004f400000 {
compatible = "arm,smmu-v3";
reg = <0x400 0x4f400000 0 0x40000>;
interrupts = <GIC_SPI 715 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 716 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 717 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "eventq", "cmdq-sync", "gerror";
- msi-parent = <&its2_slave 0>;
+ msi-parent = <&its2_secondary 0>;
#iommu-cells = <1>;
dma-coherent;
};
- pcie_slave_ctlr: pcie@40070000000 {
+ pcie_secondary_ctlr: pcie@40070000000 {
compatible = "arm,n1sdp-pcie";
device_type = "pci";
reg = <0x400 0x70000000 0 0x1200000>;
@@ -84,8 +84,9 @@
<0 0 0 2 &gic 0 0 0 650 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 3 &gic 0 0 0 651 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 4 &gic 0 0 0 652 IRQ_TYPE_LEVEL_HIGH>;
- msi-map = <0 &its_slave_pcie 0 0x10000>;
- iommu-map = <0 &smmu_slave_pcie 0 0x10000>;
+ msi-map = <0 &its_secondary_pcie 0 0x10000>;
+ iommu-map = <0 &smmu_secondary_pcie 0 0x10000>;
+ numa-node-id = <1>;
status = "okay";
};
@@ -97,17 +98,25 @@
<0x0 0x300c0000 0 0x80000>, /* GICR */
<0x400 0x300c0000 0 0x80000>; /* GICR */
- its2_slave: its@40030060000 {
+ its2_secondary: its@40030060000 {
compatible = "arm,gic-v3-its";
msi-controller;
#msi-cells = <1>;
reg = <0x400 0x30060000 0x0 0x20000>;
};
- its_slave_pcie: its@400300a0000 {
+ its_secondary_pcie: its@400300a0000 {
compatible = "arm,gic-v3-its";
msi-controller;
#msi-cells = <1>;
reg = <0x400 0x300a0000 0x0 0x20000>;
};
};
+
+&pcie_ctlr {
+ numa-node-id = <0>;
+};
+
+&ccix_pcie_ctlr {
+ numa-node-id = <0>;
+};
diff --git a/fdts/stm32mp13-bl2.dtsi b/fdts/stm32mp13-bl2.dtsi
new file mode 100644
index 0000000..4e3701c
--- /dev/null
+++ b/fdts/stm32mp13-bl2.dtsi
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ */
+
+/ {
+ aliases {
+#if !STM32MP_EMMC && !STM32MP_SDMMC
+ /delete-property/ mmc0;
+ /delete-property/ mmc1;
+#endif
+ };
+
+ soc {
+#if !STM32MP_USB_PROGRAMMER
+ /delete-node/ usb-otg@49000000;
+#endif
+#if !STM32MP_RAW_NAND
+ /delete-node/ memory-controller@58002000;
+#endif
+#if !STM32MP_SPI_NAND && !STM32MP_SPI_NOR
+ /delete-node/ spi@58003000;
+#endif
+#if !STM32MP_EMMC && !STM32MP_SDMMC
+ /delete-node/ mmc@58005000;
+ /delete-node/ mmc@58007000;
+#endif
+#if !STM32MP_USB_PROGRAMMER
+ /delete-node/ usbh-ohci@5800c000;
+ /delete-node/ usbh-ehci@5800d000;
+#endif
+#if !STM32MP_USB_PROGRAMMER
+ /delete-node/ usbphyc@5a006000;
+#endif
+
+ pinctrl@50002000 {
+#if !STM32MP_EMMC && !STM32MP_SDMMC
+ /delete-node/ sdmmc1-b4-0;
+ /delete-node/ sdmmc2-b4-0;
+#endif
+ };
+ };
+
+ /*
+ * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in
+ * network order (big endian)
+ */
+
+ st-io_policies {
+ fip-handles {
+ compatible = "st,io-fip-handle";
+ fw_cfg_uuid = "5807e16a-8459-47be-8ed5-648e8dddab0e";
+ bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38";
+ bl32_extra1_uuid = "0b70c29b-2a5a-7840-9f65-0a5682738288";
+ bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
+ bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
+ hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
+ tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
+ nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
+ };
+ };
+};
diff --git a/fdts/stm32mp13-ddr.dtsi b/fdts/stm32mp13-ddr.dtsi
new file mode 100644
index 0000000..56eb36e
--- /dev/null
+++ b/fdts/stm32mp13-ddr.dtsi
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ */
+
+&ddr {
+ st,mem-name = DDR_MEM_NAME;
+ st,mem-speed = <DDR_MEM_SPEED>;
+ st,mem-size = <DDR_MEM_SIZE>;
+
+ st,ctl-reg = <
+ DDR_MSTR
+ DDR_MRCTRL0
+ DDR_MRCTRL1
+ DDR_DERATEEN
+ DDR_DERATEINT
+ DDR_PWRCTL
+ DDR_PWRTMG
+ DDR_HWLPCTL
+ DDR_RFSHCTL0
+ DDR_RFSHCTL3
+ DDR_CRCPARCTL0
+ DDR_ZQCTL0
+ DDR_DFITMG0
+ DDR_DFITMG1
+ DDR_DFILPCFG0
+ DDR_DFIUPD0
+ DDR_DFIUPD1
+ DDR_DFIUPD2
+ DDR_DFIPHYMSTR
+ DDR_ODTMAP
+ DDR_DBG0
+ DDR_DBG1
+ DDR_DBGCMD
+ DDR_POISONCFG
+ DDR_PCCFG
+ >;
+
+ st,ctl-timing = <
+ DDR_RFSHTMG
+ DDR_DRAMTMG0
+ DDR_DRAMTMG1
+ DDR_DRAMTMG2
+ DDR_DRAMTMG3
+ DDR_DRAMTMG4
+ DDR_DRAMTMG5
+ DDR_DRAMTMG6
+ DDR_DRAMTMG7
+ DDR_DRAMTMG8
+ DDR_DRAMTMG14
+ DDR_ODTCFG
+ >;
+
+ st,ctl-map = <
+ DDR_ADDRMAP1
+ DDR_ADDRMAP2
+ DDR_ADDRMAP3
+ DDR_ADDRMAP4
+ DDR_ADDRMAP5
+ DDR_ADDRMAP6
+ DDR_ADDRMAP9
+ DDR_ADDRMAP10
+ DDR_ADDRMAP11
+ >;
+
+ st,ctl-perf = <
+ DDR_SCHED
+ DDR_SCHED1
+ DDR_PERFHPR1
+ DDR_PERFLPR1
+ DDR_PERFWR1
+ DDR_PCFGR_0
+ DDR_PCFGW_0
+ DDR_PCFGQOS0_0
+ DDR_PCFGQOS1_0
+ DDR_PCFGWQOS0_0
+ DDR_PCFGWQOS1_0
+ >;
+
+ st,phy-reg = <
+ DDR_PGCR
+ DDR_ACIOCR
+ DDR_DXCCR
+ DDR_DSGCR
+ DDR_DCR
+ DDR_ODTCR
+ DDR_ZQ0CR1
+ DDR_DX0GCR
+ DDR_DX1GCR
+ >;
+
+ st,phy-timing = <
+ DDR_PTR0
+ DDR_PTR1
+ DDR_PTR2
+ DDR_DTPR0
+ DDR_DTPR1
+ DDR_DTPR2
+ DDR_MR0
+ DDR_MR1
+ DDR_MR2
+ DDR_MR3
+ >;
+};
+
+#undef DDR_MEM_NAME
+#undef DDR_MEM_SPEED
+#undef DDR_MEM_SIZE
+#undef DDR_MSTR
+#undef DDR_MRCTRL0
+#undef DDR_MRCTRL1
+#undef DDR_DERATEEN
+#undef DDR_DERATEINT
+#undef DDR_PWRCTL
+#undef DDR_PWRTMG
+#undef DDR_HWLPCTL
+#undef DDR_RFSHCTL0
+#undef DDR_RFSHCTL3
+#undef DDR_RFSHTMG
+#undef DDR_CRCPARCTL0
+#undef DDR_DRAMTMG0
+#undef DDR_DRAMTMG1
+#undef DDR_DRAMTMG2
+#undef DDR_DRAMTMG3
+#undef DDR_DRAMTMG4
+#undef DDR_DRAMTMG5
+#undef DDR_DRAMTMG6
+#undef DDR_DRAMTMG7
+#undef DDR_DRAMTMG8
+#undef DDR_DRAMTMG14
+#undef DDR_ZQCTL0
+#undef DDR_DFITMG0
+#undef DDR_DFITMG1
+#undef DDR_DFILPCFG0
+#undef DDR_DFIUPD0
+#undef DDR_DFIUPD1
+#undef DDR_DFIUPD2
+#undef DDR_DFIPHYMSTR
+#undef DDR_ADDRMAP1
+#undef DDR_ADDRMAP2
+#undef DDR_ADDRMAP3
+#undef DDR_ADDRMAP4
+#undef DDR_ADDRMAP5
+#undef DDR_ADDRMAP6
+#undef DDR_ADDRMAP9
+#undef DDR_ADDRMAP10
+#undef DDR_ADDRMAP11
+#undef DDR_ODTCFG
+#undef DDR_ODTMAP
+#undef DDR_SCHED
+#undef DDR_SCHED1
+#undef DDR_PERFHPR1
+#undef DDR_PERFLPR1
+#undef DDR_PERFWR1
+#undef DDR_DBG0
+#undef DDR_DBG1
+#undef DDR_DBGCMD
+#undef DDR_POISONCFG
+#undef DDR_PCCFG
+#undef DDR_PCFGR_0
+#undef DDR_PCFGW_0
+#undef DDR_PCFGQOS0_0
+#undef DDR_PCFGQOS1_0
+#undef DDR_PCFGWQOS0_0
+#undef DDR_PCFGWQOS1_0
+#undef DDR_PGCR
+#undef DDR_PTR0
+#undef DDR_PTR1
+#undef DDR_PTR2
+#undef DDR_ACIOCR
+#undef DDR_DXCCR
+#undef DDR_DSGCR
+#undef DDR_DCR
+#undef DDR_DTPR0
+#undef DDR_DTPR1
+#undef DDR_DTPR2
+#undef DDR_MR0
+#undef DDR_MR1
+#undef DDR_MR2
+#undef DDR_MR3
+#undef DDR_ODTCR
+#undef DDR_ZQ0CR1
+#undef DDR_DX0GCR
+#undef DDR_DX1GCR
diff --git a/fdts/stm32mp13-ddr3-1x4Gb-1066-binF.dtsi b/fdts/stm32mp13-ddr3-1x4Gb-1066-binF.dtsi
new file mode 100644
index 0000000..a5f7989
--- /dev/null
+++ b/fdts/stm32mp13-ddr3-1x4Gb-1066-binF.dtsi
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * STM32MP135C DISCO BOARD configuration
+ * 1x DDR3L 4Gb, 16-bit, 533MHz.
+ * Reference used MT41K256M16TW-107 P from Micron
+ *
+ * DDR type / Platform DDR3/3L
+ * freq 533MHz
+ * width 16
+ * datasheet 1
+ * DDR density 4
+ * timing mode optimized
+ * Scheduling/QoS options : type = 6
+ * address mapping : RBC
+ * Tc > + 85C : N
+ */
+#define DDR_MEM_NAME "DDR3-1066 bin F 1x4Gb 533MHz v1.53"
+#define DDR_MEM_SPEED 533000
+#define DDR_MEM_SIZE 0x20000000
+
+#define DDR_MSTR 0x00040401
+#define DDR_MRCTRL0 0x00000010
+#define DDR_MRCTRL1 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00800000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00400010
+#define DDR_HWLPCTL 0x00000000
+#define DDR_RFSHCTL0 0x00210000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x0081008B
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_DRAMTMG0 0x121B2414
+#define DDR_DRAMTMG1 0x000A041B
+#define DDR_DRAMTMG2 0x0607080F
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x07040607
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020002
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x00001005
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_ZQCTL0 0xC2000040
+#define DDR_DFITMG0 0x02050105
+#define DDR_DFITMG1 0x00000202
+#define DDR_DFILPCFG0 0x07000000
+#define DDR_DFIUPD0 0xC0400003
+#define DDR_DFIUPD1 0x00000000
+#define DDR_DFIUPD2 0x00000000
+#define DDR_DFIPHYMSTR 0x00000000
+#define DDR_ADDRMAP1 0x00080808
+#define DDR_ADDRMAP2 0x00000000
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x07070707
+#define DDR_ADDRMAP6 0x0F070707
+#define DDR_ADDRMAP9 0x00000000
+#define DDR_ADDRMAP10 0x00000000
+#define DDR_ADDRMAP11 0x00000000
+#define DDR_ODTCFG 0x06000600
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x00000F01
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x00000001
+#define DDR_PERFLPR1 0x04000200
+#define DDR_PERFWR1 0x08000400
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000010
+#define DDR_PCFGR_0 0x00000000
+#define DDR_PCFGW_0 0x00000000
+#define DDR_PCFGQOS0_0 0x00100009
+#define DDR_PCFGQOS1_0 0x00000020
+#define DDR_PCFGWQOS0_0 0x01100B03
+#define DDR_PCFGWQOS1_0 0x01000200
+#define DDR_PGCR 0x01442E02
+#define DDR_PTR0 0x0022AA5B
+#define DDR_PTR1 0x04841104
+#define DDR_PTR2 0x042DA068
+#define DDR_ACIOCR 0x10400812
+#define DDR_DXCCR 0x00000C40
+#define DDR_DSGCR 0xF200011F
+#define DDR_DCR 0x0000000B
+#define DDR_DTPR0 0x36D477D0
+#define DDR_DTPR1 0x098B00D8
+#define DDR_DTPR2 0x10023600
+#define DDR_MR0 0x00000830
+#define DDR_MR1 0x00000000
+#define DDR_MR2 0x00000208
+#define DDR_MR3 0x00000000
+#define DDR_ODTCR 0x00010000
+#define DDR_ZQ0CR1 0x00000038
+#define DDR_DX0GCR 0x0000CE81
+#define DDR_DX1GCR 0x0000CE81
+
+#include "stm32mp13-ddr.dtsi"
diff --git a/fdts/stm32mp13-fw-config.dtsi b/fdts/stm32mp13-fw-config.dtsi
new file mode 100644
index 0000000..4f3bb72
--- /dev/null
+++ b/fdts/stm32mp13-fw-config.dtsi
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+#include <dt-bindings/soc/stm32mp13-tzc400.h>
+
+#include <platform_def.h>
+
+#ifndef DDR_SIZE
+#error "DDR_SIZE is not defined"
+#endif
+
+#define DDR_NS_BASE STM32MP_DDR_BASE
+#define DDR_SEC_SIZE STM32MP_DDR_S_SIZE
+#define DDR_SEC_BASE (STM32MP_DDR_BASE + (DDR_SIZE - DDR_SEC_SIZE))
+#define DDR_NS_SIZE (DDR_SEC_BASE - DDR_NS_BASE)
+
+/dts-v1/;
+
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+
+ hw-config {
+ load-address = <0x0 STM32MP_HW_CONFIG_BASE>;
+ max-size = <STM32MP_HW_CONFIG_MAX_SIZE>;
+ id = <HW_CONFIG_ID>;
+ };
+
+ nt_fw {
+ load-address = <0x0 STM32MP_BL33_BASE>;
+ max-size = <STM32MP_BL33_MAX_SIZE>;
+ id = <BL33_IMAGE_ID>;
+ };
+
+ tos_fw {
+ load-address = <0x0 DDR_SEC_BASE>;
+ max-size = <DDR_SEC_SIZE>;
+ id = <BL32_IMAGE_ID>;
+ };
+ };
+
+ st-mem-firewall {
+ compatible = "st,mem-firewall";
+ memory-ranges = <
+ DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR
+ DDR_SEC_BASE DDR_SEC_SIZE TZC_REGION_S_RDWR 0>;
+ };
+};
diff --git a/fdts/stm32mp13-pinctrl.dtsi b/fdts/stm32mp13-pinctrl.dtsi
new file mode 100644
index 0000000..879da9c
--- /dev/null
+++ b/fdts/stm32mp13-pinctrl.dtsi
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@foss.st.com>
+ */
+#include <dt-bindings/pinctrl/stm32-pinfunc.h>
+
+&pinctrl {
+ i2c4_pins_a: i2c4-0 {
+ pins {
+ pinmux = <STM32_PINMUX('E', 15, AF6)>, /* I2C4_SCL */
+ <STM32_PINMUX('B', 9, AF6)>; /* I2C4_SDA */
+ bias-disable;
+ drive-open-drain;
+ slew-rate = <0>;
+ };
+ };
+
+ sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+ pins {
+ pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
+ <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
+ <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
+ <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
+ <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-disable;
+ };
+ };
+
+ sdmmc1_clk_pins_a: sdmmc1-clk-0 {
+ pins {
+ pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-disable;
+ };
+ };
+
+ sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC2_D0 */
+ <STM32_PINMUX('B', 15, AF10)>, /* SDMMC2_D1 */
+ <STM32_PINMUX('B', 3, AF10)>, /* SDMMC2_D2 */
+ <STM32_PINMUX('B', 4, AF10)>, /* SDMMC2_D3 */
+ <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ };
+
+ sdmmc2_clk_pins_a: sdmmc2-clk-0 {
+ pins {
+ pinmux = <STM32_PINMUX('E', 3, AF10)>; /* SDMMC2_CK */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ };
+
+ uart4_pins_a: uart4-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('D', 6, AF8)>; /* UART4_TX */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 8, AF8)>; /* UART4_RX */
+ bias-disable;
+ };
+ };
+
+ usart1_pins_a: usart1-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('C', 0, AF7)>, /* USART1_TX */
+ <STM32_PINMUX('C', 2, AF7)>; /* USART1_RTS */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('B', 0, AF4)>, /* USART1_RX */
+ <STM32_PINMUX('A', 7, AF7)>; /* USART1_CTS_NSS */
+ bias-pull-up;
+ };
+ };
+
+ uart8_pins_a: uart8-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('E', 1, AF8)>; /* UART8_TX */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('F', 9, AF8)>; /* UART8_RX */
+ bias-pull-up;
+ };
+ };
+};
diff --git a/fdts/stm32mp131.dtsi b/fdts/stm32mp131.dtsi
new file mode 100644
index 0000000..2c62408
--- /dev/null
+++ b/fdts/stm32mp131.dtsi
@@ -0,0 +1,581 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
+ */
+#include <dt-bindings/clock/stm32mp13-clks.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/stm32mp13-resets.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0>;
+ clocks = <&rcc CK_MPU>;
+ clock-names = "cpu";
+ nvmem-cells = <&part_number_otp>;
+ nvmem-cell-names = "part_number";
+ };
+ };
+
+ clocks {
+ clk_csi: clk-csi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <4000000>;
+ };
+
+ clk_hse: clk-hse {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ clk_hsi: clk-hsi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <64000000>;
+ };
+
+ clk_lse: clk-lse {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ clk_lsi: clk-lsi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ };
+ };
+
+ intc: interrupt-controller@a0021000 {
+ compatible = "arm,cortex-a7-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0xa0021000 0x1000>,
+ <0xa0022000 0x2000>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&intc>;
+ ranges;
+
+ usart3: serial@4000f000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x4000f000 0x400>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc USART3_K>;
+ resets = <&rcc USART3_R>;
+ status = "disabled";
+ };
+
+ uart4: serial@40010000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40010000 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc UART4_K>;
+ resets = <&rcc UART4_R>;
+ status = "disabled";
+ };
+
+ uart5: serial@40011000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40011000 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc UART5_K>;
+ resets = <&rcc UART5_R>;
+ status = "disabled";
+ };
+
+ uart7: serial@40018000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40018000 0x400>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc UART7_K>;
+ resets = <&rcc UART7_R>;
+ status = "disabled";
+ };
+
+ uart8: serial@40019000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40019000 0x400>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc UART8_K>;
+ resets = <&rcc UART8_R>;
+ status = "disabled";
+ };
+
+ usart6: serial@44003000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x44003000 0x400>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc USART6_K>;
+ resets = <&rcc USART6_R>;
+ status = "disabled";
+ };
+
+ usbotg_hs: usb-otg@49000000 {
+ compatible = "st,stm32mp15-hsotg", "snps,dwc2";
+ reg = <0x49000000 0x40000>;
+ clocks = <&rcc USBO_K>;
+ clock-names = "otg";
+ resets = <&rcc USBO_R>;
+ reset-names = "dwc2";
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ g-rx-fifo-size = <512>;
+ g-np-tx-fifo-size = <32>;
+ g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
+ dr_mode = "otg";
+ usb33d-supply = <&usb33>;
+ status = "disabled";
+ };
+
+ usart1: serial@4c000000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x4c000000 0x400>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc USART1_K>;
+ resets = <&rcc USART1_R>;
+ status = "disabled";
+ };
+
+ usart2: serial@4c001000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x4c001000 0x400>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc USART2_K>;
+ resets = <&rcc USART2_R>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@4c004000 {
+ compatible = "st,stm32mp13-i2c";
+ reg = <0x4c004000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts-extended = <&exti 23 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C3_K>;
+ resets = <&rcc I2C3_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ st,syscfg-fmp = <&syscfg 0x4 0x4>;
+ i2c-analog-filter;
+ status = "disabled";
+ };
+
+ i2c4: i2c@4c005000 {
+ compatible = "st,stm32mp13-i2c";
+ reg = <0x4c005000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts-extended = <&exti 24 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C4_K>;
+ resets = <&rcc I2C4_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ st,syscfg-fmp = <&syscfg 0x4 0x8>;
+ i2c-analog-filter;
+ status = "disabled";
+ };
+
+ i2c5: i2c@4c006000 {
+ compatible = "st,stm32mp13-i2c";
+ reg = <0x4c006000 0x400>;
+ interrupt-names = "event", "error";
+ interrupts-extended = <&exti 25 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc I2C5_K>;
+ resets = <&rcc I2C5_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ st,syscfg-fmp = <&syscfg 0x4 0x10>;
+ i2c-analog-filter;
+ status = "disabled";
+ };
+
+ rcc: rcc@50000000 {
+ compatible = "st,stm32mp13-rcc", "syscon";
+ reg = <0x50000000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ secure-interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+ secure-interrupt-names = "wakeup";
+ };
+
+ pwr_regulators: pwr@50001000 {
+ compatible = "st,stm32mp1,pwr-reg";
+ reg = <0x50001000 0x10>;
+
+ reg11: reg11 {
+ regulator-name = "reg11";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ reg18: reg18 {
+ regulator-name = "reg18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ usb33: usb33 {
+ regulator-name = "usb33";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+
+ exti: interrupt-controller@5000d000 {
+ compatible = "st,stm32mp13-exti", "syscon";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000d000 0x400>;
+ };
+
+ syscfg: syscon@50020000 {
+ compatible = "st,stm32mp157-syscfg", "syscon";
+ reg = <0x50020000 0x400>;
+ clocks = <&rcc SYSCFG>;
+ };
+
+ hash: hash@54003000 {
+ compatible = "st,stm32mp13-hash";
+ reg = <0x54003000 0x400>;
+ clocks = <&rcc HASH1>;
+ resets = <&rcc HASH1_R>;
+ status = "disabled";
+ };
+
+ rng: rng@54004000 {
+ compatible = "st,stm32mp13-rng";
+ reg = <0x54004000 0x400>;
+ clocks = <&rcc RNG1_K>;
+ resets = <&rcc RNG1_R>;
+ status = "disabled";
+ };
+
+ fmc: memory-controller@58002000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "st,stm32mp1-fmc2-ebi";
+ reg = <0x58002000 0x1000>;
+ clocks = <&rcc FMC_K>;
+ resets = <&rcc FMC_R>;
+ status = "disabled";
+
+ ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */
+ <1 0 0x64000000 0x04000000>, /* EBI CS 2 */
+ <2 0 0x68000000 0x04000000>, /* EBI CS 3 */
+ <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */
+ <4 0 0x80000000 0x10000000>; /* NAND */
+
+ nand-controller@4,0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32mp1-fmc2-nfc";
+ reg = <4 0x00000000 0x1000>,
+ <4 0x08010000 0x1000>,
+ <4 0x08020000 0x1000>,
+ <4 0x01000000 0x1000>,
+ <4 0x09010000 0x1000>,
+ <4 0x09020000 0x1000>;
+ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+ };
+
+ qspi: spi@58003000 {
+ compatible = "st,stm32f469-qspi";
+ reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+ reg-names = "qspi", "qspi_mm";
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc QSPI_K>;
+ resets = <&rcc QSPI_R>;
+ status = "disabled";
+ };
+
+ sdmmc1: mmc@58005000 {
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x20253180>;
+ reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
+ clocks = <&rcc SDMMC1_K>;
+ clock-names = "apb_pclk";
+ resets = <&rcc SDMMC1_R>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <130000000>;
+ status = "disabled";
+ };
+
+ sdmmc2: mmc@58007000 {
+ compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+ arm,primecell-periphid = <0x20253180>;
+ reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
+ clocks = <&rcc SDMMC2_K>;
+ clock-names = "apb_pclk";
+ resets = <&rcc SDMMC2_R>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <130000000>;
+ status = "disabled";
+ };
+
+ usbh_ohci: usbh-ohci@5800c000 {
+ compatible = "generic-ohci";
+ reg = <0x5800c000 0x1000>;
+ clocks = <&rcc USBH>;
+ resets = <&rcc USBH_R>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ usbh_ehci: usbh-ehci@5800d000 {
+ compatible = "generic-ehci";
+ reg = <0x5800d000 0x1000>;
+ clocks = <&rcc USBH>;
+ resets = <&rcc USBH_R>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ companion = <&usbh_ohci>;
+ status = "disabled";
+ };
+
+ iwdg2: watchdog@5a002000 {
+ compatible = "st,stm32mp1-iwdg";
+ reg = <0x5a002000 0x400>;
+ clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
+ clock-names = "pclk", "lsi";
+ status = "disabled";
+ };
+
+ ddr: ddr@5a003000 {
+ compatible = "st,stm32mp13-ddr";
+ reg = <0x5a003000 0x550>, <0x5a004000 0x234>;
+ clocks = <&rcc AXIDCG>,
+ <&rcc DDRC1>,
+ <&rcc DDRPHYC>,
+ <&rcc DDRCAPB>,
+ <&rcc DDRPHYCAPB>;
+ clock-names = "axidcg",
+ "ddrc1",
+ "ddrphyc",
+ "ddrcapb",
+ "ddrphycapb";
+ };
+
+ usbphyc: usbphyc@5a006000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <0>;
+ compatible = "st,stm32mp1-usbphyc";
+ reg = <0x5a006000 0x1000>;
+ clocks = <&rcc USBPHY_K>;
+ resets = <&rcc USBPHY_R>;
+ vdda1v1-supply = <®11>;
+ vdda1v8-supply = <®18>;
+ status = "disabled";
+
+ usbphyc_port0: usb-phy@0 {
+ #phy-cells = <0>;
+ reg = <0>;
+ };
+
+ usbphyc_port1: usb-phy@1 {
+ #phy-cells = <1>;
+ reg = <1>;
+ };
+ };
+
+ iwdg1: watchdog@5c003000 {
+ compatible = "st,stm32mp1-iwdg";
+ reg = <0x5c003000 0x400>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc IWDG1>, <&rcc CK_LSI>;
+ clock-names = "pclk", "lsi";
+ status = "disabled";
+ };
+
+ bsec: efuse@5c005000 {
+ compatible = "st,stm32mp15-bsec";
+ reg = <0x5c005000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cfg0_otp: cfg0_otp@0 {
+ reg = <0x0 0x2>;
+ };
+ part_number_otp: part_number_otp@4 {
+ reg = <0x4 0x2>;
+ };
+ monotonic_otp: monotonic_otp@10 {
+ reg = <0x10 0x4>;
+ };
+ nand_otp: cfg9_otp@24 {
+ reg = <0x24 0x4>;
+ };
+ nand2_otp: cfg10_otp@28 {
+ reg = <0x28 0x4>;
+ };
+ uid_otp: uid_otp@34 {
+ reg = <0x34 0xc>;
+ };
+ hw2_otp: hw2_otp@48 {
+ reg = <0x48 0x4>;
+ };
+ ts_cal1: calib@5c {
+ reg = <0x5c 0x2>;
+ };
+ ts_cal2: calib@5e {
+ reg = <0x5e 0x2>;
+ };
+ pkh_otp: pkh_otp@60 {
+ reg = <0x60 0x20>;
+ };
+ mac_addr: mac_addr@e4 {
+ reg = <0xe4 0xc>;
+ st,non-secure-otp;
+ };
+ };
+ /*
+ * Break node order to solve dependency probe issue between
+ * pinctrl and exti.
+ */
+ pinctrl: pinctrl@50002000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,stm32mp135-pinctrl";
+ ranges = <0 0x50002000 0x8400>;
+ interrupt-parent = <&exti>;
+ st,syscfg = <&exti 0x60 0xff>;
+ pins-are-numbered;
+
+ gpioa: gpio@50002000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x0 0x400>;
+ clocks = <&rcc GPIOA>;
+ st,bank-name = "GPIOA";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 0 16>;
+ };
+
+ gpiob: gpio@50003000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x400>;
+ clocks = <&rcc GPIOB>;
+ st,bank-name = "GPIOB";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 16 16>;
+ };
+
+ gpioc: gpio@50004000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x400>;
+ clocks = <&rcc GPIOC>;
+ st,bank-name = "GPIOC";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 32 16>;
+ };
+
+ gpiod: gpio@50005000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x400>;
+ clocks = <&rcc GPIOD>;
+ st,bank-name = "GPIOD";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 48 16>;
+ };
+
+ gpioe: gpio@50006000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x400>;
+ clocks = <&rcc GPIOE>;
+ st,bank-name = "GPIOE";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 64 16>;
+ };
+
+ gpiof: gpio@50007000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000 0x400>;
+ clocks = <&rcc GPIOF>;
+ st,bank-name = "GPIOF";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 80 16>;
+ };
+
+ gpiog: gpio@50008000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x6000 0x400>;
+ clocks = <&rcc GPIOG>;
+ st,bank-name = "GPIOG";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 96 16>;
+ };
+
+ gpioh: gpio@50009000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x7000 0x400>;
+ clocks = <&rcc GPIOH>;
+ st,bank-name = "GPIOH";
+ ngpios = <15>;
+ gpio-ranges = <&pinctrl 0 112 15>;
+ };
+
+ gpioi: gpio@5000a000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x8000 0x400>;
+ clocks = <&rcc GPIOI>;
+ st,bank-name = "GPIOI";
+ ngpios = <8>;
+ gpio-ranges = <&pinctrl 0 128 8>;
+ };
+ };
+ };
+};
diff --git a/fdts/stm32mp133.dtsi b/fdts/stm32mp133.dtsi
new file mode 100644
index 0000000..bb468c0
--- /dev/null
+++ b/fdts/stm32mp133.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
+ */
+
+#include "stm32mp131.dtsi"
diff --git a/fdts/stm32mp135.dtsi b/fdts/stm32mp135.dtsi
new file mode 100644
index 0000000..b5ebdd9
--- /dev/null
+++ b/fdts/stm32mp135.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
+ */
+
+#include "stm32mp133.dtsi"
diff --git a/fdts/stm32mp135f-dk-fw-config.dts b/fdts/stm32mp135f-dk-fw-config.dts
new file mode 100644
index 0000000..21f8242
--- /dev/null
+++ b/fdts/stm32mp135f-dk-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x20000000 /* 512MB */
+#include "stm32mp13-fw-config.dtsi"
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
new file mode 100644
index 0000000..e58be40
--- /dev/null
+++ b/fdts/stm32mp135f-dk.dts
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/clock/stm32mp13-clksrc.h>
+#include "stm32mp135.dtsi"
+#include "stm32mp13xf.dtsi"
+#include "stm32mp13-ddr3-1x4Gb-1066-binF.dtsi"
+#include "stm32mp13-pinctrl.dtsi"
+
+/ {
+ model = "STMicroelectronics STM32MP135F-DK Discovery Board";
+ compatible = "st,stm32mp135f-dk", "st,stm32mp135";
+
+ aliases {
+ serial0 = &uart4;
+ serial1 = &usart1;
+ serial2 = &uart8;
+ serial3 = &usart2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@c0000000 {
+ device_type = "memory";
+ reg = <0xc0000000 0x20000000>;
+ };
+
+ vin: vin {
+ compatible = "regulator-fixed";
+ regulator-name = "vin";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ v3v3_ao: v3v3_ao {
+ compatible = "regulator-fixed";
+ regulator-name = "v3v3_ao";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+};
+
+&bsec {
+ board_id: board_id@f0 {
+ reg = <0xf0 0x4>;
+ st,non-secure-otp;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vddcpu>;
+};
+
+&hash {
+ status = "okay";
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins_a>;
+ i2c-scl-rising-time-ns = <185>;
+ i2c-scl-falling-time-ns = <20>;
+ clock-frequency = <400000>;
+ status = "disabled";
+ secure-status = "okay";
+
+ pmic: stpmic@33 {
+ compatible = "st,stpmic1";
+ reg = <0x33>;
+
+ status = "disabled";
+ secure-status = "okay";
+
+ regulators {
+ compatible = "st,stpmic1-regulators";
+ buck1-supply = <&vin>;
+ buck2-supply = <&vin>;
+ buck3-supply = <&vin>;
+ buck4-supply = <&vin>;
+ ldo1-supply = <&vin>;
+ ldo4-supply = <&vin>;
+ ldo5-supply = <&vin>;
+ ldo6-supply = <&vin>;
+ vref_ddr-supply = <&vin>;
+ pwr_sw1-supply = <&bst_out>;
+ pwr_sw2-supply = <&v3v3_ao>;
+
+ vddcpu: buck1 {
+ regulator-name = "vddcpu";
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ };
+
+ vdd_ddr: buck2 {
+ regulator-name = "vdd_ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ };
+
+ vdd: buck3 {
+ regulator-name = "vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ st,mask-reset;
+ regulator-over-current-protection;
+ };
+
+ vddcore: buck4 {
+ regulator-name = "vddcore";
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ };
+
+ vdd_adc: ldo1 {
+ regulator-name = "vdd_adc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_usb: ldo4 {
+ regulator-name = "vdd_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_sd: ldo5 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+
+ v1v8_periph: ldo6 {
+ regulator-name = "v1v8_periph";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vref_ddr: vref_ddr {
+ regulator-name = "vref_ddr";
+ regulator-always-on;
+ };
+
+ bst_out: boost {
+ regulator-name = "bst_out";
+ };
+
+ v3v3_sw: pwr_sw2 {
+ regulator-name = "v3v3_sw";
+ regulator-active-discharge = <1>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&iwdg2 {
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&pka {
+ secure-status = "okay";
+};
+
+&pwr_regulators {
+ vdd-supply = <&vdd>;
+ vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
+&rcc {
+ st,clksrc = <
+ CLK_MPU_PLL1P
+ CLK_AXI_PLL2P
+ CLK_MLAHBS_PLL3
+ CLK_CKPER_HSE
+ CLK_RTC_LSE
+ CLK_SDMMC1_PLL4P
+ CLK_SDMMC2_PLL4P
+ CLK_STGEN_HSE
+ CLK_USBPHY_HSE
+ CLK_I2C4_HSI
+ CLK_USBO_USBPHY
+ CLK_I2C12_HSI
+ CLK_UART2_HSI
+ CLK_UART4_HSI
+ CLK_SAES_AXI
+ >;
+
+ st,clkdiv = <
+ DIV(DIV_AXI, 0)
+ DIV(DIV_MLAHB, 0)
+ DIV(DIV_APB1, 1)
+ DIV(DIV_APB2, 1)
+ DIV(DIV_APB3, 1)
+ DIV(DIV_APB4, 1)
+ DIV(DIV_APB5, 2)
+ DIV(DIV_APB6, 1)
+ DIV(DIV_RTC, 0)
+ >;
+
+ st,pll_vco {
+ pll1_vco_1300Mhz: pll1-vco-1300Mhz {
+ src = < CLK_PLL12_HSE >;
+ divmn = < 2 80 >;
+ frac = < 0x800 >;
+ };
+
+ pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+ src = < CLK_PLL12_HSE >;
+ divmn = < 2 65 >;
+ frac = < 0x1400 >;
+ };
+
+ pll3_vco_417_8Mhz: pll2-vco-417_8Mhz {
+ src = < CLK_PLL3_HSE >;
+ divmn = < 1 33 >;
+ frac = < 0x1a04 >;
+ };
+
+ pll4_vco_600Mhz: pll2-vco-600Mhz {
+ src = < CLK_PLL4_HSE >;
+ divmn = < 1 49 >;
+ };
+ };
+
+ /* VCO = 1300.0 MHz => P = 650 (CPU) */
+ pll1:st,pll@0 {
+ compatible = "st,stm32mp1-pll";
+ reg = <0>;
+
+ st,pll = < &pll1_cfg1 >;
+
+ pll1_cfg1: pll1_cfg1 {
+ st,pll_vco = < &pll1_vco_1300Mhz >;
+ st,pll_div_pqr = < 0 1 1 >;
+ };
+ };
+
+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 266, R = 533 (DDR) */
+ pll2:st,pll@1 {
+ compatible = "st,stm32mp1-pll";
+ reg = <1>;
+
+ st,pll = < &pll2_cfg1 >;
+
+ pll2_cfg1: pll2_cfg1 {
+ st,pll_vco = < &pll2_vco_1066Mhz >;
+ st,pll_div_pqr = < 1 1 0 >;
+ };
+ };
+
+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 209 */
+ pll3:st,pll@2 {
+ compatible = "st,stm32mp1-pll";
+ reg = <2>;
+
+ st,pll = < &pll3_cfg1 >;
+
+ pll3_cfg1: pll3_cfg1 {
+ st,pll_vco = < &pll3_vco_417_8Mhz >;
+ st,pll_div_pqr = < 1 16 1 >;
+ };
+ };
+
+ /* VCO = 600.0 MHz => P = 50, Q = 10, R = 100 */
+ pll4:st,pll@3 {
+ compatible = "st,stm32mp1-pll";
+ reg = <3>;
+
+ st,pll = < &pll4_cfg1 >;
+
+ pll4_cfg1: pll4_cfg1 {
+ st,pll_vco = < &pll4_vco_600Mhz >;
+ st,pll_div_pqr = < 11 59 5 >;
+ };
+ };
+};
+
+&rng {
+ status = "okay";
+};
+
+&saes {
+ secure-status = "okay";
+};
+
+&sdmmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_clk_pins_a>;
+ disable-wp;
+ st,neg-edge;
+ bus-width = <4>;
+ vmmc-supply = <&vdd_sd>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins_a>;
+ status = "okay";
+};
+
+&uart8 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart8_pins_a>;
+ status = "disabled";
+};
+
+&usart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usart1_pins_a>;
+ uart-has-rtscts;
+ status = "disabled";
+};
diff --git a/fdts/stm32mp13xa.dtsi b/fdts/stm32mp13xa.dtsi
new file mode 100644
index 0000000..0ef2fce
--- /dev/null
+++ b/fdts/stm32mp13xa.dtsi
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
+ */
diff --git a/fdts/stm32mp13xc.dtsi b/fdts/stm32mp13xc.dtsi
new file mode 100644
index 0000000..4b30c5c
--- /dev/null
+++ b/fdts/stm32mp13xc.dtsi
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
+ */
+
+#include "stm32mp13xa.dtsi"
+
+/ {
+ soc {
+ saes: saes@54005000 {
+ compatible = "st,stm32-saes";
+ reg = <0x54005000 0x400>;
+ clocks = <&rcc SAES_K>;
+ resets = <&rcc SAES_R>;
+ status = "disabled";
+ };
+
+ pka: pka@54006000 {
+ compatible = "st,stm32-pka64";
+ reg = <0x54006000 0x2000>;
+ clocks = <&rcc PKA>;
+ resets = <&rcc PKA_R>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/fdts/stm32mp13xd.dtsi b/fdts/stm32mp13xd.dtsi
new file mode 100644
index 0000000..0ef2fce
--- /dev/null
+++ b/fdts/stm32mp13xd.dtsi
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
+ */
diff --git a/fdts/stm32mp13xf.dtsi b/fdts/stm32mp13xf.dtsi
new file mode 100644
index 0000000..887c4e0
--- /dev/null
+++ b/fdts/stm32mp13xf.dtsi
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
+ */
+#include "stm32mp13xd.dtsi"
+
+/ {
+ soc {
+ saes: saes@54005000 {
+ compatible = "st,stm32-saes";
+ reg = <0x54005000 0x400>;
+ clocks = <&rcc SAES_K>;
+ resets = <&rcc SAES_R>;
+ status = "disabled";
+ };
+
+ pka: pka@54006000 {
+ compatible = "st,stm32-pka64";
+ reg = <0x54006000 0x2000>;
+ clocks = <&rcc PKA>;
+ resets = <&rcc PKA_R>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi
index d00e35b..501b092 100644
--- a/fdts/stm32mp15-bl2.dtsi
+++ b/fdts/stm32mp15-bl2.dtsi
@@ -46,7 +46,7 @@
/delete-node/ i2c@5c009000;
/delete-node/ tamp@5c00a000;
- pin-controller@50002000 {
+ pinctrl@50002000 {
#if !STM32MP_RAW_NAND
/delete-node/ fmc-0;
#endif
diff --git a/fdts/stm32mp15-bl32.dtsi b/fdts/stm32mp15-bl32.dtsi
index ca4bb3e..31b24f6 100644
--- a/fdts/stm32mp15-bl32.dtsi
+++ b/fdts/stm32mp15-bl32.dtsi
@@ -27,7 +27,7 @@
/delete-node/ stgen@5c008000;
/delete-node/ i2c@5c009000;
- pin-controller@50002000 {
+ pinctrl@50002000 {
/delete-node/ fmc-0;
/delete-node/ qspi-clk-0;
/delete-node/ qspi-bk1-0;
diff --git a/fdts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi
new file mode 100644
index 0000000..ff184c2
--- /dev/null
+++ b/fdts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2020, DH electronics - All Rights Reserved
+ *
+ * STM32MP15xx DHSOM configuration
+ * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology.
+ * Reference used W634GU6NB15I from Winbond
+ *
+ * DDR type / Platform DDR3/3L
+ * freq 533MHz
+ * width 32
+ * datasheet 0 = W634GU6NB15I / DDR3-1333
+ * DDR density 8
+ * timing mode optimized
+ * address mapping : RBC
+ * Tc > + 85C : J
+ */
+
+#define DDR_MEM_NAME "DDR3L 32bits 2x4Gb 533MHz"
+#define DDR_MEM_SPEED 533000
+#define DDR_MEM_SIZE 0x40000000
+
+#define DDR_MSTR 0x00040401
+#define DDR_MRCTRL0 0x00000010
+#define DDR_MRCTRL1 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00800000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00400010
+#define DDR_HWLPCTL 0x00000000
+#define DDR_RFSHCTL0 0x00210000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x0040008B
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_DRAMTMG0 0x121B1214
+#define DDR_DRAMTMG1 0x000A041C
+#define DDR_DRAMTMG2 0x0608090F
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x08040608
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020002
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x00001005
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_ZQCTL0 0xC2000040
+#define DDR_DFITMG0 0x02060105
+#define DDR_DFITMG1 0x00000202
+#define DDR_DFILPCFG0 0x07000000
+#define DDR_DFIUPD0 0xC0400003
+#define DDR_DFIUPD1 0x00000000
+#define DDR_DFIUPD2 0x00000000
+#define DDR_DFIPHYMSTR 0x00000000
+#define DDR_ODTCFG 0x06000600
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x00000C01
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x01000001
+#define DDR_PERFLPR1 0x08000200
+#define DDR_PERFWR1 0x08000400
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000010
+#define DDR_PCFGR_0 0x00010000
+#define DDR_PCFGW_0 0x00000000
+#define DDR_PCFGQOS0_0 0x02100C03
+#define DDR_PCFGQOS1_0 0x00800100
+#define DDR_PCFGWQOS0_0 0x01100C03
+#define DDR_PCFGWQOS1_0 0x01000200
+#define DDR_PCFGR_1 0x00010000
+#define DDR_PCFGW_1 0x00000000
+#define DDR_PCFGQOS0_1 0x02100C03
+#define DDR_PCFGQOS1_1 0x00800040
+#define DDR_PCFGWQOS0_1 0x01100C03
+#define DDR_PCFGWQOS1_1 0x01000200
+#define DDR_ADDRMAP1 0x00080808
+#define DDR_ADDRMAP2 0x00000000
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x07070707
+#define DDR_ADDRMAP6 0x0F070707
+#define DDR_ADDRMAP9 0x00000000
+#define DDR_ADDRMAP10 0x00000000
+#define DDR_ADDRMAP11 0x00000000
+#define DDR_PGCR 0x01442E02
+#define DDR_PTR0 0x0022AA5B
+#define DDR_PTR1 0x04841104
+#define DDR_PTR2 0x042DA068
+#define DDR_ACIOCR 0x10400812
+#define DDR_DXCCR 0x00000C40
+#define DDR_DSGCR 0xF200011F
+#define DDR_DCR 0x0000000B
+#define DDR_DTPR0 0x38D488D0
+#define DDR_DTPR1 0x098B00D8
+#define DDR_DTPR2 0x10023600
+#define DDR_MR0 0x00000840
+#define DDR_MR1 0x00000000
+#define DDR_MR2 0x00000248
+#define DDR_MR3 0x00000000
+#define DDR_ODTCR 0x00010000
+#define DDR_ZQ0CR1 0x00000038
+#define DDR_DX0GCR 0x0000CE81
+#define DDR_DX1GCR 0x0000CE81
+#define DDR_DX2GCR 0x0000CE81
+#define DDR_DX3GCR 0x0000CE81
+
+#include "stm32mp15-ddr.dtsi"
diff --git a/fdts/stm32mp15-fw-config.dtsi b/fdts/stm32mp15-fw-config.dtsi
index 8aece28..d583672 100644
--- a/fdts/stm32mp15-fw-config.dtsi
+++ b/fdts/stm32mp15-fw-config.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
*/
#include <common/tbbr/tbbr_img_def.h>
@@ -14,7 +14,7 @@
#define DDR_NS_BASE STM32MP_DDR_BASE
#ifdef AARCH32_SP_OPTEE
-/* OP-TEE reserved shared memory: located at DDR top */
+/* OP-TEE reserved shared memory: located at DDR top or null size */
#define DDR_SHARE_SIZE STM32MP_DDR_SHMEM_SIZE
#define DDR_SHARE_BASE (STM32MP_DDR_BASE + (DDR_SIZE - DDR_SHARE_SIZE))
/* OP-TEE secure memory: located right below OP-TEE reserved shared memory */
@@ -70,8 +70,11 @@
memory-ranges = <
DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR
DDR_SEC_BASE DDR_SEC_SIZE TZC_REGION_S_RDWR 0
+#if STM32MP15_OPTEE_RSV_SHM
DDR_SHARE_BASE DDR_SHARE_SIZE TZC_REGION_S_NONE
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)>;
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)
+#endif
+ >;
#else
memory-ranges = <
DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR>;
diff --git a/fdts/stm32mp15-pinctrl.dtsi b/fdts/stm32mp15-pinctrl.dtsi
index d74dc2b..7d2be0b 100644
--- a/fdts/stm32mp15-pinctrl.dtsi
+++ b/fdts/stm32mp15-pinctrl.dtsi
@@ -114,6 +114,21 @@
drive-push-pull;
bias-pull-up;
};
+ pins2 {
+ pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
+ bias-pull-up;
+ };
+ };
+
+ sdmmc1_dir_pins_b: sdmmc1-dir-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
+ <STM32_PINMUX('E', 14, AF11)>, /* SDMMC1_D123DIR */
+ <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
+ };
pins2{
pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
bias-pull-up;
@@ -182,6 +197,18 @@
};
};
+ sdmmc2_d47_pins_c: sdmmc2-d47-2 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
+ <STM32_PINMUX('A', 15, AF9)>, /* SDMMC2_D5 */
+ <STM32_PINMUX('C', 6, AF10)>, /* SDMMC2_D6 */
+ <STM32_PINMUX('C', 7, AF10)>; /* SDMMC2_D7 */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ };
+
sdmmc2_d47_pins_d: sdmmc2-d47-3 {
pins {
pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi
index 454e124..bb16fda 100644
--- a/fdts/stm32mp151.dtsi
+++ b/fdts/stm32mp151.dtsi
@@ -24,26 +24,6 @@
};
};
- nvmem_layout: nvmem_layout@0 {
- compatible = "st,stm32-nvmem-layout";
-
- nvmem-cells = <&cfg0_otp>,
- <&part_number_otp>,
- <&monotonic_otp>,
- <&nand_otp>,
- <&uid_otp>,
- <&package_otp>,
- <&hw2_otp>;
-
- nvmem-cell-names = "cfg0_otp",
- "part_number_otp",
- "monotonic_otp",
- "nand_otp",
- "uid_otp",
- "package_otp",
- "hw2_otp";
- };
-
psci {
compatible = "arm,psci-1.0";
method = "smc";
@@ -380,7 +360,7 @@
status = "disabled";
};
- ddr: ddr@5a003000{
+ ddr: ddr@5a003000 {
compatible = "st,stm32mp1-ddr";
reg = <0x5A003000 0x550 0x5A004000 0x234>;
clocks = <&rcc AXIDCG>,
@@ -517,8 +497,6 @@
compatible = "st,stm32-etzpc";
reg = <0x5C007000 0x400>;
clocks = <&rcc TZPC>;
- status = "disabled";
- secure-status = "okay";
};
stgen: stgen@5c008000 {
@@ -552,7 +530,7 @@
* Break node order to solve dependency probe issue between
* pinctrl and exti.
*/
- pinctrl: pin-controller@50002000 {
+ pinctrl: pinctrl@50002000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stm32mp157-pinctrl";
@@ -683,7 +661,7 @@
};
};
- pinctrl_z: pin-controller-z@54004000 {
+ pinctrl_z: pinctrl@54004000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "st,stm32mp157-z-pinctrl";
diff --git a/fdts/stm32mp157a-avenger96.dts b/fdts/stm32mp157a-avenger96.dts
index b967736..f0da350 100644
--- a/fdts/stm32mp157a-avenger96.dts
+++ b/fdts/stm32mp157a-avenger96.dts
@@ -115,10 +115,9 @@
vtt_ddr: ldo3 {
regulator-name = "vtt_ddr";
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <750000>;
regulator-always-on;
regulator-over-current-protection;
+ st,regulator-sink-source;
};
vdd_usb: ldo4 {
@@ -143,7 +142,6 @@
vref_ddr: vref_ddr {
regulator-name = "vref_ddr";
regulator-always-on;
- regulator-over-current-protection;
};
bst_out: boost {
@@ -165,7 +163,6 @@
&iwdg2 {
timeout-sec = <32>;
status = "okay";
- secure-status = "okay";
};
&pwr_regulators {
@@ -174,7 +171,6 @@
};
&rcc {
- secure-status = "disabled";
st,clksrc = <
CLK_MPU_PLL1P
CLK_AXI_PLL2P
diff --git a/fdts/stm32mp157a-dhcor-avenger96-fw-config.dts b/fdts/stm32mp157a-dhcor-avenger96-fw-config.dts
new file mode 100644
index 0000000..2abbe50
--- /dev/null
+++ b/fdts/stm32mp157a-dhcor-avenger96-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157a-dhcor-avenger96.dts b/fdts/stm32mp157a-dhcor-avenger96.dts
new file mode 100644
index 0000000..82d48aa
--- /dev/null
+++ b/fdts/stm32mp157a-dhcor-avenger96.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (C) Linaro Ltd 2019 - All Rights Reserved
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ * Copyright (C) 2020 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2022 DH electronics GmbH
+ *
+ * DHCOR STM32MP1 variant:
+ * DHCR-STM32MP157A-C065-R102-V18-SPI-C-01LG
+ * DHCOR PCB number: 586-100 or newer
+ * Avenger96 PCB number: 588-200 or newer
+ */
+
+/dts-v1/;
+
+#include "stm32mp157.dtsi"
+#include "stm32mp15xx-dhcor-som.dtsi"
+#include "stm32mp15xx-dhcor-avenger96.dtsi"
+
+/ {
+ model = "Arrow Electronics STM32MP157A Avenger96 board";
+ compatible = "arrow,stm32mp157a-avenger96", "dh,stm32mp157a-dhcor-som",
+ "st,stm32mp157";
+};
diff --git a/fdts/stm32mp157c-dhcom-pdk2-fw-config.dts b/fdts/stm32mp157c-dhcom-pdk2-fw-config.dts
new file mode 100644
index 0000000..6a5a192
--- /dev/null
+++ b/fdts/stm32mp157c-dhcom-pdk2-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (c) 2022 DH electronics GmbH
+ */
+
+#define DDR_SIZE 0x40000000 /* 1GB */
+#include "stm32mp15-fw-config.dtsi"
diff --git a/fdts/stm32mp157c-dhcom-pdk2.dts b/fdts/stm32mp157c-dhcom-pdk2.dts
new file mode 100644
index 0000000..370a69a
--- /dev/null
+++ b/fdts/stm32mp157c-dhcom-pdk2.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2019-2020 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2022 DH electronics GmbH
+ *
+ * DHCOM STM32MP1 variant:
+ * DHCM-STM32MP157C-C065-R102-F0819-SPI-E2-CAN2-SDR104-RTC-WBT-T-DSI-I-01D2
+ * DHCOM PCB number: 587-200 or newer
+ * PDK2 PCB number: 516-400 or newer
+ */
+/dts-v1/;
+
+#include "stm32mp157.dtsi"
+#include "stm32mp15xc.dtsi"
+#include "stm32mp15xx-dhcom-som.dtsi"
+#include "stm32mp15xx-dhcom-pdk2.dtsi"
+
+/ {
+ model = "DH electronics STM32MP157C DHCOM Premium Developer Kit (2)";
+ compatible = "dh,stm32mp157c-dhcom-pdk2", "dh,stm32mp157c-dhcom-som",
+ "st,stm32mp157";
+};
+
+&cryp1 {
+ status = "okay";
+};
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index 44c7016..d928563 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -195,33 +195,12 @@
status = "okay";
};
-&nvmem_layout {
- nvmem-cells = <&cfg0_otp>,
- <&part_number_otp>,
- <&monotonic_otp>,
- <&nand_otp>,
- <&uid_otp>,
- <&package_otp>,
- <&hw2_otp>,
- <&board_id>;
-
- nvmem-cell-names = "cfg0_otp",
- "part_number_otp",
- "monotonic_otp",
- "nand_otp",
- "uid_otp",
- "package_otp",
- "hw2_otp",
- "board_id";
-};
-
&pwr_regulators {
vdd-supply = <&vdd>;
vdd_3v3_usbfs-supply = <&vdd_usb>;
};
&rcc {
- secure-status = "disabled";
st,clksrc = <
CLK_MPU_PLL1P
CLK_AXI_PLL2P
diff --git a/fdts/stm32mp157c-odyssey-som.dtsi b/fdts/stm32mp157c-odyssey-som.dtsi
index 6bed339..091e327 100644
--- a/fdts/stm32mp157c-odyssey-som.dtsi
+++ b/fdts/stm32mp157c-odyssey-som.dtsi
@@ -140,10 +140,9 @@
vtt_ddr: ldo3 {
regulator-name = "vtt_ddr";
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <750000>;
regulator-always-on;
regulator-over-current-protection;
+ st,regulator-sink-source;
};
vdd_usb: ldo4 {
@@ -170,7 +169,6 @@
vref_ddr: vref_ddr {
regulator-name = "vref_ddr";
regulator-always-on;
- regulator-over-current-protection;
};
bst_out: boost {
@@ -205,7 +203,6 @@
};
&rcc {
- secure-status = "disabled";
st,clksrc = <
CLK_MPU_PLL1P
CLK_AXI_PLL2P
diff --git a/fdts/stm32mp15xx-dhcom-pdk2.dtsi b/fdts/stm32mp15xx-dhcom-pdk2.dtsi
new file mode 100644
index 0000000..1ffc60d
--- /dev/null
+++ b/fdts/stm32mp15xx-dhcom-pdk2.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2019-2020 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2022 DH electronics GmbH
+ */
+
+/ {
+ aliases {
+ serial0 = &uart4;
+ serial1 = &usart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&usart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usart3_pins_a>;
+ status = "okay";
+};
+
+&usbotg_hs {
+ dr_mode = "otg";
+ pinctrl-0 = <&usbotg_hs_pins_a>;
+ pinctrl-names = "default";
+ phy-names = "usb2-phy";
+ phys = <&usbphyc_port1 0>;
+ vbus-supply = <&vbus_otg>;
+ status = "okay";
+};
+
+&usbphyc {
+ status = "okay";
+};
+
+&usbphyc_port0 {
+ phy-supply = <&vdd_usb>;
+};
+
+&usbphyc_port1 {
+ phy-supply = <&vdd_usb>;
+};
diff --git a/fdts/stm32mp15xx-dhcom-som.dtsi b/fdts/stm32mp15xx-dhcom-som.dtsi
new file mode 100644
index 0000000..c9f21b0
--- /dev/null
+++ b/fdts/stm32mp15xx-dhcom-som.dtsi
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2019-2020 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2022 DH electronics GmbH
+ */
+
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxaa-pinctrl.dtsi"
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include "stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi"
+
+/ {
+ memory@c0000000 {
+ device_type = "memory";
+ reg = <0xC0000000 0x40000000>;
+ };
+};
+
+&bsec {
+ board_id: board_id@ec {
+ reg = <0xec 0x4>;
+ st,non-secure-otp;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vddcore>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcore>;
+};
+
+&hash1 {
+ status = "okay";
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins_a>;
+ i2c-scl-rising-time-ns = <185>;
+ i2c-scl-falling-time-ns = <20>;
+ status = "okay";
+
+ pmic: stpmic@33 {
+ compatible = "st,stpmic1";
+ reg = <0x33>;
+ interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "okay";
+
+ regulators {
+ compatible = "st,stpmic1-regulators";
+ ldo1-supply = <&v3v3>;
+ ldo2-supply = <&v3v3>;
+ ldo3-supply = <&vdd_ddr>;
+ ldo5-supply = <&v3v3>;
+ ldo6-supply = <&v3v3>;
+ pwr_sw1-supply = <&bst_out>;
+ pwr_sw2-supply = <&bst_out>;
+
+ vddcore: buck1 {
+ regulator-name = "vddcore";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd_ddr: buck2 {
+ regulator-name = "vdd_ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd: buck3 {
+ regulator-name = "vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ st,mask-reset;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ v3v3: buck4 {
+ regulator-name = "v3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ regulator-initial-mode = <0>;
+ };
+
+ vdda: ldo1 {
+ regulator-name = "vdda";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-always-on;
+ };
+
+ v2v8: ldo2 {
+ regulator-name = "v2v8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vtt_ddr: ldo3 {
+ regulator-name = "vtt_ddr";
+ regulator-always-on;
+ regulator-over-current-protection;
+ st,regulator-sink-source;
+ };
+
+ vdd_usb: ldo4 {
+ regulator-name = "vdd_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_sd: ldo5 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ };
+
+ v1v8: ldo6 {
+ regulator-name = "v1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vref_ddr: vref_ddr {
+ regulator-name = "vref_ddr";
+ regulator-always-on;
+ };
+
+ bst_out: boost {
+ regulator-name = "bst_out";
+ };
+
+ vbus_otg: pwr_sw1 {
+ regulator-name = "vbus_otg";
+ };
+
+ vbus_sw: pwr_sw2 {
+ regulator-name = "vbus_sw";
+ regulator-active-discharge = <1>;
+ };
+ };
+ };
+};
+
+&iwdg2 {
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&pwr_regulators {
+ vdd-supply = <&vdd>;
+ vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>;
+ reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <108000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&rcc {
+ st,clksrc = <
+ CLK_MPU_PLL1P
+ CLK_AXI_PLL2P
+ CLK_MCU_PLL3P
+ CLK_PLL12_HSE
+ CLK_PLL3_HSE
+ CLK_PLL4_HSE
+ CLK_RTC_LSE
+ CLK_MCO1_DISABLED
+ CLK_MCO2_PLL4P
+ >;
+
+ st,clkdiv = <
+ 1 /*MPU*/
+ 0 /*AXI*/
+ 0 /*MCU*/
+ 1 /*APB1*/
+ 1 /*APB2*/
+ 1 /*APB3*/
+ 1 /*APB4*/
+ 2 /*APB5*/
+ 23 /*RTC*/
+ 0 /*MCO1*/
+ 1 /*MCO2*/
+ >;
+
+ st,pkcs = <
+ CLK_CKPER_HSE
+ CLK_FMC_ACLK
+ CLK_QSPI_ACLK
+ CLK_ETH_PLL4P
+ CLK_SDMMC12_PLL4P
+ CLK_DSI_DSIPLL
+ CLK_STGEN_HSE
+ CLK_USBPHY_HSE
+ CLK_SPI2S1_PLL3Q
+ CLK_SPI2S23_PLL3Q
+ CLK_SPI45_HSI
+ CLK_SPI6_HSI
+ CLK_I2C46_HSI
+ CLK_SDMMC3_PLL4P
+ CLK_USBO_USBPHY
+ CLK_ADC_CKPER
+ CLK_CEC_LSE
+ CLK_I2C12_HSI
+ CLK_I2C35_HSI
+ CLK_UART1_HSI
+ CLK_UART24_HSI
+ CLK_UART35_HSI
+ CLK_UART6_HSI
+ CLK_UART78_HSI
+ CLK_SPDIF_PLL4P
+ CLK_FDCAN_PLL4R
+ CLK_SAI1_PLL3Q
+ CLK_SAI2_PLL3Q
+ CLK_SAI3_PLL3Q
+ CLK_SAI4_PLL3Q
+ CLK_RNG1_LSI
+ CLK_RNG2_LSI
+ CLK_LPTIM1_PCLK1
+ CLK_LPTIM23_PCLK3
+ CLK_LPTIM45_LSE
+ >;
+
+ /* VCO = 1300.0 MHz => P = 650 (CPU) */
+ pll1: st,pll@0 {
+ compatible = "st,stm32mp1-pll";
+ reg = <0>;
+ cfg = <2 80 0 0 0 PQR(1,0,0)>;
+ frac = <0x800>;
+ };
+
+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
+ pll2: st,pll@1 {
+ compatible = "st,stm32mp1-pll";
+ reg = <1>;
+ cfg = <2 65 1 0 0 PQR(1,1,1)>;
+ frac = <0x1400>;
+ };
+
+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
+ pll3: st,pll@2 {
+ compatible = "st,stm32mp1-pll";
+ reg = <2>;
+ cfg = <1 33 1 16 36 PQR(1,1,1)>;
+ frac = <0x1a04>;
+ };
+
+ /* VCO = 600.0 MHz => P = 50, Q = 50, R = 50 */
+ pll4: st,pll@3 {
+ compatible = "st,stm32mp1-pll";
+ reg = <3>;
+ cfg = <1 49 5 11 11 PQR(1,1,1)>;
+ };
+};
+
+&rng1 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sdmmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
+ disable-wp;
+ st,sig-dir;
+ st,neg-edge;
+ bus-width = <4>;
+ vmmc-supply = <&vdd_sd>;
+ status = "okay";
+};
+
+&sdmmc1_b4_pins_a {
+ /*
+ * SD bus pull-up resistors:
+ * - optional on SoMs with SD voltage translator
+ * - mandatory on SoMs without SD voltage translator
+ */
+ pins1 {
+ bias-pull-up;
+ };
+ pins2 {
+ bias-pull-up;
+ };
+};
+
+&sdmmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
+ non-removable;
+ no-sd;
+ no-sdio;
+ st,neg-edge;
+ bus-width = <8>;
+ vmmc-supply = <&v3v3>;
+ vqmmc-supply = <&v3v3>;
+ mmc-ddr-3_3v;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins_a>;
+ status = "okay";
+};
diff --git a/fdts/stm32mp15xx-dhcor-avenger96.dtsi b/fdts/stm32mp15xx-dhcor-avenger96.dtsi
new file mode 100644
index 0000000..576e0f1
--- /dev/null
+++ b/fdts/stm32mp15xx-dhcor-avenger96.dtsi
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (C) Linaro Ltd 2019 - All Rights Reserved
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ * Copyright (C) 2020 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2022 DH electronics GmbH
+ */
+
+/* Avenger96 uses DHCOR SoM configured for 1V8 IO operation */
+#include "stm32mp15xx-dhcor-io1v8.dtsi"
+
+/ {
+ aliases {
+ serial0 = &uart4;
+ serial1 = &uart7;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ sd_switch: regulator-sd_switch {
+ compatible = "regulator-gpio";
+ regulator-name = "sd_switch";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-type = "voltage";
+ regulator-always-on;
+
+ gpios = <&gpioi 5 0>;
+ gpios-states = <0>;
+ states = <1800000 0x1>,
+ <2900000 0x0>;
+ };
+};
+
+&sdmmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_b>;
+ disable-wp;
+ st,sig-dir;
+ st,neg-edge;
+ st,use-ckin;
+ bus-width = <4>;
+ vmmc-supply = <&vdd_sd>;
+ vqmmc-supply = <&sd_switch>;
+ status = "okay";
+};
+
+&sdmmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_c>;
+ bus-width = <8>;
+ mmc-ddr-1_8v;
+ no-sd;
+ no-sdio;
+ non-removable;
+ st,neg-edge;
+ vmmc-supply = <&v3v3>;
+ vqmmc-supply = <&vdd_io>;
+ status = "okay";
+};
+
+&uart4 {
+ /* On Low speed expansion header */
+ label = "LS-UART1";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins_b>;
+ status = "okay";
+};
+
+&uart7 {
+ /* On Low speed expansion header */
+ label = "LS-UART0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart7_pins_a>;
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&usbotg_hs {
+ pinctrl-0 = <&usbotg_hs_pins_a>;
+ pinctrl-names = "default";
+ phy-names = "usb2-phy";
+ phys = <&usbphyc_port1 0>;
+ status = "okay";
+ vbus-supply = <&vbus_otg>;
+};
+
+&usbphyc {
+ status = "okay";
+};
+
+&usbphyc_port0 {
+ phy-supply = <&vdd_usb>;
+};
+
+&usbphyc_port1 {
+ phy-supply = <&vdd_usb>;
+};
diff --git a/fdts/stm32mp15xx-dhcor-io1v8.dtsi b/fdts/stm32mp15xx-dhcor-io1v8.dtsi
new file mode 100644
index 0000000..9937b28
--- /dev/null
+++ b/fdts/stm32mp15xx-dhcor-io1v8.dtsi
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+/*
+ * Copyright (C) Linaro Ltd 2019 - All Rights Reserved
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ * Copyright (C) 2020 Marek Vasut <marex@denx.de>
+ */
+
+/ {
+ /* Enpirion EP3A8LQI U2 on the DHCOR */
+ vdd_io: regulator-buck-io {
+ compatible = "regulator-fixed";
+ regulator-name = "buck-io";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vdd>;
+ };
+};
+
+&vdd {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+};
+
+&pwr_regulators {
+ vdd-supply = <&vdd_io>;
+};
diff --git a/fdts/stm32mp15xx-dhcor-som.dtsi b/fdts/stm32mp15xx-dhcor-som.dtsi
new file mode 100644
index 0000000..c241efc
--- /dev/null
+++ b/fdts/stm32mp15xx-dhcor-som.dtsi
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (C) Linaro Ltd 2019 - All Rights Reserved
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ * Copyright (C) 2020 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2022 DH electronics GmbH
+ */
+
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxaa-pinctrl.dtsi"
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include "stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi"
+
+/ {
+ memory@c0000000 {
+ device_type = "memory";
+ reg = <0xc0000000 0x40000000>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vddcore>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcore>;
+};
+
+&hash1 {
+ status = "okay";
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins_a>;
+ i2c-scl-rising-time-ns = <185>;
+ i2c-scl-falling-time-ns = <20>;
+ status = "okay";
+
+ pmic: stpmic@33 {
+ compatible = "st,stpmic1";
+ reg = <0x33>;
+ interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "okay";
+
+ regulators {
+ compatible = "st,stpmic1-regulators";
+ ldo1-supply = <&v3v3>;
+ ldo2-supply = <&v3v3>;
+ ldo3-supply = <&vdd_ddr>;
+ ldo5-supply = <&v3v3>;
+ ldo6-supply = <&v3v3>;
+ pwr_sw1-supply = <&bst_out>;
+ pwr_sw2-supply = <&bst_out>;
+
+ vddcore: buck1 {
+ regulator-name = "vddcore";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd_ddr: buck2 {
+ regulator-name = "vdd_ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd: buck3 {
+ regulator-name = "vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ v3v3: buck4 {
+ regulator-name = "v3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ regulator-initial-mode = <0>;
+ };
+
+ vdda: ldo1 {
+ regulator-name = "vdda";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+ v2v8: ldo2 {
+ regulator-name = "v2v8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vtt_ddr: ldo3 {
+ regulator-name = "vtt_ddr";
+ regulator-always-on;
+ regulator-over-current-protection;
+ st,regulator-sink-source;
+ };
+
+ vdd_usb: ldo4 {
+ regulator-name = "vdd_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_sd: ldo5 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ };
+
+ v1v8: ldo6 {
+ regulator-name = "v1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <300000>;
+ };
+
+ vref_ddr: vref_ddr {
+ regulator-name = "vref_ddr";
+ regulator-always-on;
+ };
+
+ bst_out: boost {
+ regulator-name = "bst_out";
+ };
+
+ vbus_otg: pwr_sw1 {
+ regulator-name = "vbus_otg";
+ regulator-active-discharge = <1>;
+ };
+
+ vbus_sw: pwr_sw2 {
+ regulator-name = "vbus_sw";
+ regulator-active-discharge = <1>;
+ };
+ };
+ };
+};
+
+&iwdg2 {
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&pwr_regulators {
+ vdd-supply = <&vdd>;
+ vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>;
+ reg = <0x58003000 0x1000>, <0x70000000 0x200000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <50000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&rcc {
+ st,clksrc = <
+ CLK_MPU_PLL1P
+ CLK_AXI_PLL2P
+ CLK_MCU_PLL3P
+ CLK_PLL12_HSE
+ CLK_PLL3_HSE
+ CLK_PLL4_HSE
+ CLK_RTC_LSE
+ CLK_MCO1_DISABLED
+ CLK_MCO2_DISABLED
+ >;
+
+ st,clkdiv = <
+ 1 /*MPU*/
+ 0 /*AXI*/
+ 0 /*MCU*/
+ 1 /*APB1*/
+ 1 /*APB2*/
+ 1 /*APB3*/
+ 1 /*APB4*/
+ 2 /*APB5*/
+ 23 /*RTC*/
+ 0 /*MCO1*/
+ 0 /*MCO2*/
+ >;
+
+ st,pkcs = <
+ CLK_CKPER_HSE
+ CLK_FMC_ACLK
+ CLK_QSPI_ACLK
+ CLK_ETH_DISABLED
+ CLK_SDMMC12_PLL4P
+ CLK_DSI_DSIPLL
+ CLK_STGEN_HSE
+ CLK_USBPHY_HSE
+ CLK_SPI2S1_PLL3Q
+ CLK_SPI2S23_PLL3Q
+ CLK_SPI45_HSI
+ CLK_SPI6_HSI
+ CLK_I2C46_HSI
+ CLK_SDMMC3_PLL4P
+ CLK_USBO_USBPHY
+ CLK_ADC_CKPER
+ CLK_CEC_LSE
+ CLK_I2C12_HSI
+ CLK_I2C35_HSI
+ CLK_UART1_HSI
+ CLK_UART24_HSI
+ CLK_UART35_HSI
+ CLK_UART6_HSI
+ CLK_UART78_HSI
+ CLK_SPDIF_PLL4P
+ CLK_FDCAN_PLL4R
+ CLK_SAI1_PLL3Q
+ CLK_SAI2_PLL3Q
+ CLK_SAI3_PLL3Q
+ CLK_SAI4_PLL3Q
+ CLK_RNG1_LSI
+ CLK_RNG2_LSI
+ CLK_LPTIM1_PCLK1
+ CLK_LPTIM23_PCLK3
+ CLK_LPTIM45_LSE
+ >;
+
+ /* VCO = 1300.0 MHz => P = 650 (CPU) */
+ pll1: st,pll@0 {
+ compatible = "st,stm32mp1-pll";
+ reg = <0>;
+ cfg = <2 80 0 0 0 PQR(1,0,0)>;
+ frac = <0x800>;
+ };
+
+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
+ pll2: st,pll@1 {
+ compatible = "st,stm32mp1-pll";
+ reg = <1>;
+ cfg = <2 65 1 0 0 PQR(1,1,1)>;
+ frac = <0x1400>;
+ };
+
+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
+ pll3: st,pll@2 {
+ compatible = "st,stm32mp1-pll";
+ reg = <2>;
+ cfg = <1 33 1 16 36 PQR(1,1,1)>;
+ frac = <0x1a04>;
+ };
+
+ /* VCO = 600.0 MHz => P = 99, Q = 74, R = 99 */
+ pll4: st,pll@3 {
+ compatible = "st,stm32mp1-pll";
+ reg = <3>;
+ cfg = <3 98 5 7 5 PQR(1,1,1)>;
+ };
+};
+
+&rng1 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index 2eb3a57..52d4170 100644
--- a/fdts/stm32mp15xx-dkx.dtsi
+++ b/fdts/stm32mp15xx-dkx.dtsi
@@ -33,11 +33,11 @@
st,digbypass;
};
-&cpu0{
+&cpu0 {
cpu-supply = <&vddcore>;
};
-&cpu1{
+&cpu1 {
cpu-supply = <&vddcore>;
};
@@ -180,36 +180,14 @@
&iwdg2 {
timeout-sec = <32>;
status = "okay";
- secure-status = "okay";
};
-&nvmem_layout {
- nvmem-cells = <&cfg0_otp>,
- <&part_number_otp>,
- <&monotonic_otp>,
- <&nand_otp>,
- <&uid_otp>,
- <&package_otp>,
- <&hw2_otp>,
- <&board_id>;
-
- nvmem-cell-names = "cfg0_otp",
- "part_number_otp",
- "monotonic_otp",
- "nand_otp",
- "uid_otp",
- "package_otp",
- "hw2_otp",
- "board_id";
-};
-
&pwr_regulators {
vdd-supply = <&vdd>;
vdd_3v3_usbfs-supply = <&vdd_usb>;
};
&rcc {
- secure-status = "disabled";
st,clksrc = <
CLK_MPU_PLL1P
CLK_AXI_PLL2P
@@ -324,10 +302,6 @@
status = "okay";
};
-&timers15 {
- secure-status = "okay";
-};
-
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>;
diff --git a/fdts/stm32mp15xx-osd32.dtsi b/fdts/stm32mp15xx-osd32.dtsi
index 76a2561..52a5d38 100644
--- a/fdts/stm32mp15xx-osd32.dtsi
+++ b/fdts/stm32mp15xx-osd32.dtsi
@@ -81,10 +81,9 @@
vtt_ddr: ldo3 {
regulator-name = "vtt_ddr";
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <750000>;
regulator-always-on;
regulator-over-current-protection;
+ st,regulator-sink-source;
};
vdd_usb: ldo4 {
@@ -110,7 +109,6 @@
vref_ddr: vref_ddr {
regulator-name = "vref_ddr";
regulator-always-on;
- regulator-over-current-protection;
};
bst_out: boost {
@@ -169,11 +167,11 @@
st,digbypass;
};
-&cpu0{
+&cpu0 {
cpu-supply = <&vddcore>;
};
-&cpu1{
+&cpu1 {
cpu-supply = <&vddcore>;
};
@@ -183,7 +181,6 @@
/* CLOCK init */
&rcc {
- secure-status = "disabled";
st,clksrc = <
CLK_MPU_PLL1P
CLK_AXI_PLL2P
diff --git a/fdts/tc.dts b/fdts/tc.dts
index 7c0e842..2099229 100644
--- a/fdts/tc.dts
+++ b/fdts/tc.dts
@@ -261,6 +261,12 @@
arm,mhuv2-protocols = <0 1>;
};
+ cmn-pmu {
+ compatible = "arm,ci-700";
+ reg = <0x0 0x50000000 0x0 0x10000000>;
+ interrupts = <0x0 460 0x4>;
+ };
+
scmi {
compatible = "arm,scmi";
mbox-names = "tx", "rx";
diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S
index ad2a039..8b6765a 100644
--- a/include/arch/aarch32/el3_common_macros.S
+++ b/include/arch/aarch32/el3_common_macros.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -398,6 +398,12 @@
ldr r1, =__RW_END__
sub r1, r1, r0
bl inv_dcache_range
+#if defined(IMAGE_BL2) && SEPARATE_BL2_NOLOAD_REGION
+ ldr r0, =__BL2_NOLOAD_START__
+ ldr r1, =__BL2_NOLOAD_END__
+ sub r1, r1, r0
+ bl inv_dcache_range
+#endif
#endif
/*
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 29da33c..3a2a032 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -99,7 +99,6 @@
/*******************************************************************************
* 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
@@ -109,14 +108,14 @@
#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 MPAMVPM0_EL2 S3_4_C10_C6_0
+#define MPAMVPM1_EL2 S3_4_C10_C6_1
+#define MPAMVPM2_EL2 S3_4_C10_C6_2
+#define MPAMVPM3_EL2 S3_4_C10_C6_3
+#define MPAMVPM4_EL2 S3_4_C10_C6_4
+#define MPAMVPM5_EL2 S3_4_C10_C6_5
+#define MPAMVPM6_EL2 S3_4_C10_C6_6
+#define MPAMVPM7_EL2 S3_4_C10_C6_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
@@ -155,39 +154,55 @@
#endif
/* ID_AA64PFR0_EL1 definitions */
-#define ID_AA64PFR0_EL0_SHIFT U(0)
-#define ID_AA64PFR0_EL1_SHIFT U(4)
-#define ID_AA64PFR0_EL2_SHIFT U(8)
-#define ID_AA64PFR0_EL3_SHIFT U(12)
-#define ID_AA64PFR0_AMU_SHIFT U(44)
-#define ID_AA64PFR0_AMU_MASK ULL(0xf)
-#define ID_AA64PFR0_AMU_NOT_SUPPORTED U(0x0)
-#define ID_AA64PFR0_AMU_V1 U(0x1)
-#define ID_AA64PFR0_AMU_V1P1 U(0x2)
-#define ID_AA64PFR0_ELX_MASK ULL(0xf)
-#define ID_AA64PFR0_GIC_SHIFT U(24)
-#define ID_AA64PFR0_GIC_WIDTH U(4)
-#define ID_AA64PFR0_GIC_MASK ULL(0xf)
-#define ID_AA64PFR0_SVE_SHIFT U(32)
-#define ID_AA64PFR0_SVE_MASK ULL(0xf)
-#define ID_AA64PFR0_SVE_LENGTH U(4)
-#define ID_AA64PFR0_SEL2_SHIFT U(36)
-#define ID_AA64PFR0_SEL2_MASK ULL(0xf)
-#define ID_AA64PFR0_MPAM_SHIFT U(40)
-#define ID_AA64PFR0_MPAM_MASK ULL(0xf)
-#define ID_AA64PFR0_DIT_SHIFT U(48)
-#define ID_AA64PFR0_DIT_MASK ULL(0xf)
-#define ID_AA64PFR0_DIT_LENGTH U(4)
-#define ID_AA64PFR0_DIT_SUPPORTED U(1)
-#define ID_AA64PFR0_CSV2_SHIFT U(56)
-#define ID_AA64PFR0_CSV2_MASK ULL(0xf)
-#define ID_AA64PFR0_CSV2_LENGTH U(4)
+#define ID_AA64PFR0_EL0_SHIFT U(0)
+#define ID_AA64PFR0_EL1_SHIFT U(4)
+#define ID_AA64PFR0_EL2_SHIFT U(8)
+#define ID_AA64PFR0_EL3_SHIFT U(12)
+
+#define ID_AA64PFR0_AMU_SHIFT U(44)
+#define ID_AA64PFR0_AMU_MASK ULL(0xf)
+#define ID_AA64PFR0_AMU_NOT_SUPPORTED U(0x0)
+#define ID_AA64PFR0_AMU_V1 ULL(0x1)
+#define ID_AA64PFR0_AMU_V1P1 U(0x2)
+
+#define ID_AA64PFR0_ELX_MASK ULL(0xf)
+
+#define ID_AA64PFR0_GIC_SHIFT U(24)
+#define ID_AA64PFR0_GIC_WIDTH U(4)
+#define ID_AA64PFR0_GIC_MASK ULL(0xf)
+
+#define ID_AA64PFR0_SVE_SHIFT U(32)
+#define ID_AA64PFR0_SVE_MASK ULL(0xf)
+#define ID_AA64PFR0_SVE_SUPPORTED ULL(0x1)
+#define ID_AA64PFR0_SVE_LENGTH U(4)
+
+#define ID_AA64PFR0_SEL2_SHIFT U(36)
+#define ID_AA64PFR0_SEL2_MASK ULL(0xf)
+
+#define ID_AA64PFR0_MPAM_SHIFT U(40)
+#define ID_AA64PFR0_MPAM_MASK ULL(0xf)
+
+#define ID_AA64PFR0_DIT_SHIFT U(48)
+#define ID_AA64PFR0_DIT_MASK ULL(0xf)
+#define ID_AA64PFR0_DIT_LENGTH U(4)
+#define ID_AA64PFR0_DIT_SUPPORTED U(1)
+
+#define ID_AA64PFR0_CSV2_SHIFT U(56)
+#define ID_AA64PFR0_CSV2_MASK ULL(0xf)
+#define ID_AA64PFR0_CSV2_LENGTH U(4)
+#define ID_AA64PFR0_CSV2_2_SUPPORTED ULL(0x2)
+
#define ID_AA64PFR0_FEAT_RME_SHIFT U(52)
#define ID_AA64PFR0_FEAT_RME_MASK ULL(0xf)
#define ID_AA64PFR0_FEAT_RME_LENGTH U(4)
#define ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED U(0)
#define ID_AA64PFR0_FEAT_RME_V1 U(1)
+#define ID_AA64PFR0_RAS_SHIFT U(28)
+#define ID_AA64PFR0_RAS_MASK ULL(0xf)
+#define ID_AA64PFR0_RAS_NOT_SUPPORTED ULL(0x0)
+#define ID_AA64PFR0_RAS_LENGTH U(4)
+
/* Exception level handling */
#define EL_IMPL_NONE ULL(0)
#define EL_IMPL_A64ONLY ULL(1)
@@ -204,8 +219,10 @@
#define ID_AA64DFR0_TRACEFILT_LENGTH U(4)
/* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */
-#define ID_AA64DFR0_PMS_SHIFT U(32)
-#define ID_AA64DFR0_PMS_MASK ULL(0xf)
+#define ID_AA64DFR0_PMS_SHIFT U(32)
+#define ID_AA64DFR0_PMS_MASK ULL(0xf)
+#define ID_AA64DFR0_SPE_SUPPORTED ULL(0x1)
+#define ID_AA64DFR0_SPE_NOT_SUPPORTED ULL(0x0)
/* ID_AA64DFR0_EL1.TraceBuffer definitions */
#define ID_AA64DFR0_TRACEBUFFER_SHIFT U(44)
@@ -217,20 +234,32 @@
#define ID_AA64DFR0_MTPMU_MASK ULL(0xf)
#define ID_AA64DFR0_MTPMU_SUPPORTED ULL(1)
+/* ID_AA64DFR0_EL1.BRBE definitions */
+#define ID_AA64DFR0_BRBE_SHIFT U(52)
+#define ID_AA64DFR0_BRBE_MASK ULL(0xf)
+#define ID_AA64DFR0_BRBE_SUPPORTED ULL(1)
+
/* ID_AA64ISAR0_EL1 definitions */
#define ID_AA64ISAR0_RNDR_SHIFT U(60)
#define ID_AA64ISAR0_RNDR_MASK ULL(0xf)
/* ID_AA64ISAR1_EL1 definitions */
-#define ID_AA64ISAR1_EL1 S3_0_C0_C6_1
-#define ID_AA64ISAR1_GPI_SHIFT U(28)
-#define ID_AA64ISAR1_GPI_MASK ULL(0xf)
-#define ID_AA64ISAR1_GPA_SHIFT U(24)
-#define ID_AA64ISAR1_GPA_MASK ULL(0xf)
-#define ID_AA64ISAR1_API_SHIFT U(8)
-#define ID_AA64ISAR1_API_MASK ULL(0xf)
-#define ID_AA64ISAR1_APA_SHIFT U(4)
-#define ID_AA64ISAR1_APA_MASK ULL(0xf)
+#define ID_AA64ISAR1_EL1 S3_0_C0_C6_1
+
+#define ID_AA64ISAR1_GPI_SHIFT U(28)
+#define ID_AA64ISAR1_GPI_MASK ULL(0xf)
+#define ID_AA64ISAR1_GPA_SHIFT U(24)
+#define ID_AA64ISAR1_GPA_MASK ULL(0xf)
+
+#define ID_AA64ISAR1_API_SHIFT U(8)
+#define ID_AA64ISAR1_API_MASK ULL(0xf)
+#define ID_AA64ISAR1_APA_SHIFT U(4)
+#define ID_AA64ISAR1_APA_MASK ULL(0xf)
+
+#define ID_AA64ISAR1_SB_SHIFT U(36)
+#define ID_AA64ISAR1_SB_MASK ULL(0xf)
+#define ID_AA64ISAR1_SB_SUPPORTED ULL(0x1)
+#define ID_AA64ISAR1_SB_NOT_SUPPORTED ULL(0x0)
/* ID_AA64MMFR0_EL1 definitions */
#define ID_AA64MMFR0_EL1_PARANGE_SHIFT U(0)
@@ -292,17 +321,23 @@
#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED ULL(0x0)
/* ID_AA64MMFR2_EL1 definitions */
-#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
+#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
+
+#define ID_AA64MMFR2_EL1_ST_SHIFT U(28)
+#define ID_AA64MMFR2_EL1_ST_MASK ULL(0xf)
-#define ID_AA64MMFR2_EL1_ST_SHIFT U(28)
-#define ID_AA64MMFR2_EL1_ST_MASK ULL(0xf)
+#define ID_AA64MMFR2_EL1_CCIDX_SHIFT U(20)
+#define ID_AA64MMFR2_EL1_CCIDX_MASK ULL(0xf)
+#define ID_AA64MMFR2_EL1_CCIDX_LENGTH U(4)
-#define ID_AA64MMFR2_EL1_CCIDX_SHIFT U(20)
-#define ID_AA64MMFR2_EL1_CCIDX_MASK ULL(0xf)
-#define ID_AA64MMFR2_EL1_CCIDX_LENGTH U(4)
+#define ID_AA64MMFR2_EL1_CNP_SHIFT U(0)
+#define ID_AA64MMFR2_EL1_CNP_MASK ULL(0xf)
-#define ID_AA64MMFR2_EL1_CNP_SHIFT U(0)
-#define ID_AA64MMFR2_EL1_CNP_MASK ULL(0xf)
+#define ID_AA64MMFR2_EL1_NV_SHIFT U(24)
+#define ID_AA64MMFR2_EL1_NV_MASK ULL(0xf)
+#define ID_AA64MMFR2_EL1_NV_NOT_SUPPORTED ULL(0x0)
+#define ID_AA64MMFR2_EL1_NV_SUPPORTED ULL(0x1)
+#define ID_AA64MMFR2_EL1_NV2_SUPPORTED ULL(0x2)
/* ID_AA64PFR1_EL1 definitions */
#define ID_AA64PFR1_EL1_SSBS_SHIFT U(4)
@@ -318,6 +353,12 @@
#define ID_AA64PFR1_EL1_MTE_SHIFT U(8)
#define ID_AA64PFR1_EL1_MTE_MASK ULL(0xf)
+#define ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT U(28)
+#define ID_AA64PFR1_EL1_RNDR_TRAP_MASK U(0xf)
+
+#define ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED ULL(0x1)
+#define ID_AA64PFR1_EL1_RNG_TRAP_NOT_SUPPORTED ULL(0x0)
+
/* Memory Tagging Extension is not implemented */
#define MTE_UNIMPLEMENTED U(0)
/* FEAT_MTE: MTE instructions accessible at EL0 are implemented */
@@ -450,10 +491,12 @@
#define SCR_GPF_BIT (UL(1) << 48)
#define SCR_TWEDEL_SHIFT U(30)
#define SCR_TWEDEL_MASK ULL(0xf)
+#define SCR_TRNDR_BIT (UL(1) << 40)
#define SCR_HXEn_BIT (UL(1) << 38)
#define SCR_ENTP2_SHIFT U(41)
#define SCR_ENTP2_BIT (UL(1) << SCR_ENTP2_SHIFT)
-#define SCR_AMVOFFEN_BIT (UL(1) << 35)
+#define SCR_AMVOFFEN_SHIFT U(35)
+#define SCR_AMVOFFEN_BIT (UL(1) << SCR_AMVOFFEN_SHIFT)
#define SCR_TWEDEn_BIT (UL(1) << 29)
#define SCR_ECVEN_BIT (UL(1) << 28)
#define SCR_FGTEN_BIT (UL(1) << 27)
@@ -482,6 +525,8 @@
#define MDCR_EnPMSN_BIT (ULL(1) << 36)
#define MDCR_MPMX_BIT (ULL(1) << 35)
#define MDCR_MCCD_BIT (ULL(1) << 34)
+#define MDCR_SBRBE_SHIFT U(32)
+#define MDCR_SBRBE_MASK ULL(0x3)
#define MDCR_NSTB(x) ((x) << 24)
#define MDCR_NSTB_EL1 ULL(0x3)
#define MDCR_NSTBE (ULL(1) << 26)
@@ -1185,7 +1230,8 @@
#define ERXMISC0_EL1 S3_0_C5_C5_0
#define ERXMISC1_EL1 S3_0_C5_C5_1
-#define ERXCTLR_ED_BIT (U(1) << 0)
+#define ERXCTLR_ED_SHIFT U(0)
+#define ERXCTLR_ED_BIT (U(1) << ERXCTLR_ED_SHIFT)
#define ERXCTLR_UE_BIT (U(1) << 4)
#define ERXPFGCTL_UC_BIT (U(1) << 1)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index a260f03..0af5b74 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -129,6 +129,13 @@
ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED);
}
+static inline bool is_feat_rng_trap_present(void)
+{
+ return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
+ ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
+ == ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
+}
+
static inline unsigned int get_armv9_2_feat_rme_support(void)
{
/*
@@ -140,4 +147,107 @@
ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
}
+/*********************************************************************************
+ * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
+ ********************************************************************************/
+static inline bool is_armv8_0_feat_sb_present(void)
+{
+ return (((read_id_aa64isar1_el1() >> ID_AA64ISAR1_SB_SHIFT) &
+ ID_AA64ISAR1_SB_MASK) == ID_AA64ISAR1_SB_SUPPORTED);
+}
+
+/*********************************************************************************
+ * Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2)
+ ********************************************************************************/
+static inline bool is_armv8_0_feat_csv2_2_present(void)
+{
+ return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_CSV2_SHIFT) &
+ ID_AA64PFR0_CSV2_MASK) == ID_AA64PFR0_CSV2_2_SUPPORTED);
+}
+
+/**********************************************************************************
+ * Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
+ *********************************************************************************/
+static inline bool is_armv8_2_feat_spe_present(void)
+{
+ return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT) &
+ ID_AA64DFR0_PMS_MASK) != ID_AA64DFR0_SPE_NOT_SUPPORTED);
+}
+
+/*******************************************************************************
+ * Function to identify the presence of FEAT_SVE (Scalable Vector Extension)
+ ******************************************************************************/
+static inline bool is_armv8_2_feat_sve_present(void)
+{
+ return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) &
+ ID_AA64PFR0_SVE_MASK) == ID_AA64PFR0_SVE_SUPPORTED);
+}
+
+/*******************************************************************************
+ * Function to identify the presence of FEAT_RAS (Reliability,Availability,
+ * and Serviceability Extension)
+ ******************************************************************************/
+static inline bool is_armv8_2_feat_ras_present(void)
+{
+ return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_RAS_SHIFT) &
+ ID_AA64PFR0_RAS_MASK) != ID_AA64PFR0_RAS_NOT_SUPPORTED);
+}
+
+/**************************************************************************
+ * Function to identify the presence of FEAT_DIT (Data Independent Timing)
+ *************************************************************************/
+static inline bool is_armv8_4_feat_dit_present(void)
+{
+ return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
+ ID_AA64PFR0_DIT_MASK) == ID_AA64PFR0_DIT_SUPPORTED);
+}
+
+/*************************************************************************
+ * Function to identify the presence of FEAT_TRF (TraceLift)
+ ************************************************************************/
+static inline bool is_arm8_4_feat_trf_present(void)
+{
+ return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT) &
+ ID_AA64DFR0_TRACEFILT_MASK) == ID_AA64DFR0_TRACEFILT_SUPPORTED);
+}
+
+/*******************************************************************************
+ * Function to identify the presence of FEAT_AMUv1 (Activity Monitors-
+ * Extension v1)
+ ******************************************************************************/
+static inline bool is_armv8_4_feat_amuv1_present(void)
+{
+ return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) &
+ ID_AA64PFR0_AMU_MASK) >= ID_AA64PFR0_AMU_V1);
+}
+
+/********************************************************************************
+ * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
+ * Support)
+ *******************************************************************************/
+static inline unsigned int get_armv8_4_feat_nv_support(void)
+{
+ return (((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_NV_SHIFT) &
+ ID_AA64MMFR2_EL1_NV_MASK));
+}
+
+/*******************************************************************************
+ * Function to identify the presence of FEAT_BRBE (Branch Record Buffer
+ * Extension)
+ ******************************************************************************/
+static inline bool is_feat_brbe_present(void)
+{
+ return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_BRBE_SHIFT) &
+ ID_AA64DFR0_BRBE_MASK) == ID_AA64DFR0_BRBE_SUPPORTED);
+}
+
+/*******************************************************************************
+ * Function to identify the presence of FEAT_TRBE (Trace Buffer Extension)
+ ******************************************************************************/
+static inline bool is_feat_trbe_present(void)
+{
+ return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEBUFFER_SHIFT) &
+ ID_AA64DFR0_TRACEBUFFER_MASK) == ID_AA64DFR0_TRACEBUFFER_SUPPORTED);
+}
+
#endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index d47244e..de2b931 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -469,6 +469,14 @@
sub x1, x1, x0
bl inv_dcache_range
#endif
+#if defined(IMAGE_BL2) && SEPARATE_BL2_NOLOAD_REGION
+ adrp x0, __BL2_NOLOAD_START__
+ add x0, x0, :lo12:__BL2_NOLOAD_START__
+ adrp x1, __BL2_NOLOAD_END__
+ add x1, x1, :lo12:__BL2_NOLOAD_END__
+ sub x1, x1, x0
+ bl inv_dcache_range
+#endif
#endif
adrp x0, __BSS_START__
add x0, x0, :lo12:__BSS_START__
diff --git a/include/arch/aarch64/smccc_helpers.h b/include/arch/aarch64/smccc_helpers.h
index fac6fd9..920f294 100644
--- a/include/arch/aarch64/smccc_helpers.h
+++ b/include/arch/aarch64/smccc_helpers.h
@@ -9,12 +9,26 @@
#include <lib/smccc.h>
+/* Definitions to help the assembler access the SMC/ERET args structure */
+#define SMC_ARGS_SIZE 0x40
+#define SMC_ARG0 0x0
+#define SMC_ARG1 0x8
+#define SMC_ARG2 0x10
+#define SMC_ARG3 0x18
+#define SMC_ARG4 0x20
+#define SMC_ARG5 0x28
+#define SMC_ARG6 0x30
+#define SMC_ARG7 0x38
+#define SMC_ARGS_END 0x40
+
#ifndef __ASSEMBLER__
#include <stdbool.h>
#include <context.h>
+#include <platform_def.h> /* For CACHE_WRITEBACK_GRANULE */
+
/* Convenience macros to return from SMC handler */
#define SMC_RET0(_h) { \
return (uint64_t) (_h); \
@@ -82,6 +96,49 @@
_x4 = read_ctx_reg(regs, CTX_GPREG_X4); \
} while (false)
+typedef struct {
+ uint64_t _regs[SMC_ARGS_END >> 3];
+} __aligned(CACHE_WRITEBACK_GRANULE) smc_args_t;
+
+/*
+ * Ensure that the assembler's view of the size of the tsp_args is the
+ * same as the compilers.
+ */
+CASSERT(sizeof(smc_args_t) == SMC_ARGS_SIZE, assert_sp_args_size_mismatch);
+
+static inline smc_args_t smc_helper(uint32_t func, uint64_t arg0,
+ uint64_t arg1, uint64_t arg2,
+ uint64_t arg3, uint64_t arg4,
+ uint64_t arg5, uint64_t arg6)
+{
+ smc_args_t ret_args = {0};
+
+ register uint64_t r0 __asm__("x0") = func;
+ register uint64_t r1 __asm__("x1") = arg0;
+ register uint64_t r2 __asm__("x2") = arg1;
+ register uint64_t r3 __asm__("x3") = arg2;
+ register uint64_t r4 __asm__("x4") = arg3;
+ register uint64_t r5 __asm__("x5") = arg4;
+ register uint64_t r6 __asm__("x6") = arg5;
+ register uint64_t r7 __asm__("x7") = arg6;
+
+ /* Output registers, also used as inputs ('+' constraint). */
+ __asm__ volatile("smc #0"
+ : "+r"(r0), "+r"(r1), "+r"(r2), "+r"(r3), "+r"(r4),
+ "+r"(r5), "+r"(r6), "+r"(r7));
+
+ ret_args._regs[0] = r0;
+ ret_args._regs[1] = r1;
+ ret_args._regs[2] = r2;
+ ret_args._regs[3] = r3;
+ ret_args._regs[4] = r4;
+ ret_args._regs[5] = r5;
+ ret_args._regs[6] = r6;
+ ret_args._regs[7] = r7;
+
+ return ret_args;
+}
+
#endif /*__ASSEMBLER__*/
#endif /* SMCCC_HELPERS_H */
diff --git a/include/bl31/interrupt_mgmt.h b/include/bl31/interrupt_mgmt.h
index 935bf77..694f1f0 100644
--- a/include/bl31/interrupt_mgmt.h
+++ b/include/bl31/interrupt_mgmt.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -107,15 +107,23 @@
static inline int32_t validate_el3_interrupt_rm(uint32_t x)
{
-#if EL3_EXCEPTION_HANDLING
+#if defined (EL3_EXCEPTION_HANDLING) && !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1))
/*
* With EL3 exception handling, EL3 interrupts are always routed to EL3
- * from both Secure and Non-secure, and therefore INTR_EL3_VALID_RM1 is
- * the only valid routing model.
+ * from both Secure and Non-secure, when the SPMC does not live in S-EL2.
+ * Therefore INTR_EL3_VALID_RM1 is the only valid routing model.
*/
if (x == INTR_EL3_VALID_RM1)
return 0;
#else
+ /*
+ * When EL3_EXCEPTION_HANDLING is not defined both routing modes are
+ * valid. This is the most common case. The exception to this rule is
+ * when EL3_EXCEPTION_HANDLING is defined but also when the SPMC lives
+ * at S-EL2. In this case, Group0 Interrupts are trapped to the SPMC
+ * when running in S-EL0 and S-EL1. The SPMC may handle the interrupt
+ * itself, delegate it to an SP or forward to EL3 for handling.
+ */
if ((x == INTR_EL3_VALID_RM0) || (x == INTR_EL3_VALID_RM1))
return 0;
#endif
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 8cb4990..539280e 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -81,6 +81,10 @@
#define __RODATA_END__ Load$$__RODATA_EPILOGUE__$$Base
#define __RT_SVC_DESCS_START__ Load$$__RT_SVC_DESCS__$$Base
#define __RT_SVC_DESCS_END__ Load$$__RT_SVC_DESCS__$$Limit
+#if SPMC_AT_EL3
+#define __EL3_LP_DESCS_START__ Load$$__EL3_LP_DESCS__$$Base
+#define __EL3_LP_DESCS_END__ Load$$__EL3_LP_DESCS__$$Limit
+#endif
#define __RW_START__ Load$$LR$$LR_RW_DATA$$Base
#define __RW_END__ Load$$LR$$LR_END$$Base
#define __SPM_SHIM_EXCEPTIONS_START__ Load$$__SPM_SHIM_EXCEPTIONS__$$Base
@@ -174,6 +178,7 @@
extern const char build_message[];
extern const char version_string[];
+const char *get_version(void);
void print_entry_point_info(const entry_point_info_t *ep_info);
uintptr_t page_align(uintptr_t value, unsigned dir);
diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h
index 5147e37..080e331 100644
--- a/include/common/bl_common.ld.h
+++ b/include/common/bl_common.ld.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -39,6 +39,16 @@
KEEP(*(rt_svc_descs)) \
__RT_SVC_DESCS_END__ = .;
+#if SPMC_AT_EL3
+#define EL3_LP_DESCS \
+ . = ALIGN(STRUCT_ALIGN); \
+ __EL3_LP_DESCS_START__ = .; \
+ KEEP(*(el3_lp_descs)) \
+ __EL3_LP_DESCS_END__ = .;
+#else
+#define EL3_LP_DESCS
+#endif
+
#define PMF_SVC_DESCS \
. = ALIGN(STRUCT_ALIGN); \
__PMF_SVC_DESCS_START__ = .; \
@@ -70,7 +80,9 @@
*/
#define BASE_XLAT_TABLE \
. = ALIGN(16); \
- *(base_xlat_table)
+ __BASE_XLAT_TABLE_START__ = .; \
+ *(base_xlat_table) \
+ __BASE_XLAT_TABLE_END__ = .;
#if PLAT_RO_XLAT_TABLES
#define BASE_XLAT_TABLE_RO BASE_XLAT_TABLE
@@ -87,7 +99,8 @@
PARSER_LIB_DESCS \
CPU_OPS \
GOT \
- BASE_XLAT_TABLE_RO
+ BASE_XLAT_TABLE_RO \
+ EL3_LP_DESCS
/*
* .data must be placed at a lower address than the stacks if the stack
@@ -210,7 +223,9 @@
*/
#define XLAT_TABLE_SECTION \
xlat_table (NOLOAD) : { \
+ __XLAT_TABLE_START__ = .; \
*(xlat_table) \
+ __XLAT_TABLE_END__ = .; \
}
#endif /* BL_COMMON_LD_H */
diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h
index 7a590b2..9531bdb 100644
--- a/include/common/fdt_fixup.h
+++ b/include/common/fdt_fixup.h
@@ -7,15 +7,32 @@
#ifndef FDT_FIXUP_H
#define FDT_FIXUP_H
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
#define INVALID_BASE_ADDR ((uintptr_t)~0UL)
+struct psci_cpu_idle_state {
+ const char *name;
+ uint32_t power_state;
+ bool local_timer_stop;
+ uint32_t entry_latency_us;
+ uint32_t exit_latency_us;
+ uint32_t min_residency_us;
+ uint32_t wakeup_latency_us;
+};
+
int dt_add_psci_node(void *fdt);
int dt_add_psci_cpu_enable_methods(void *fdt);
int fdt_add_reserved_memory(void *dtb, const char *node_name,
uintptr_t base, size_t size);
int fdt_add_cpus_node(void *dtb, unsigned int afflv0,
unsigned int afflv1, unsigned int afflv2);
+int fdt_add_cpu_idle_states(void *dtb, const struct psci_cpu_idle_state *state);
int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, uintptr_t gicr_base,
unsigned int gicr_frame_size);
+int fdt_set_mac_address(void *dtb, unsigned int ethernet_idx,
+ const uint8_t *mac_addr);
#endif /* FDT_FIXUP_H */
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index 9c7180c..2929fc2 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -44,6 +44,8 @@
int fdtw_for_each_cpu(const void *fdt,
int (*callback)(const void *dtb, int node, uintptr_t mpidr));
+int fdtw_find_or_add_subnode(void *fdt, int parentoffset, const char *name);
+
static inline uint32_t fdt_blob_size(const void *dtb)
{
const uint32_t *dtb_header = dtb;
diff --git a/include/common/feat_detect.h b/include/common/feat_detect.h
new file mode 100644
index 0000000..0f0f105
--- /dev/null
+++ b/include/common/feat_detect.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FEAT_DETECT_H
+#define FEAT_DETECT_H
+
+#include <arch_features.h>
+#include <common/debug.h>
+
+/* Function Prototypes */
+void detect_arch_features(void);
+
+/* Macro Definitions */
+#define FEAT_STATE_1 1
+#define FEAT_STATE_2 2
+#define feat_detect_panic(a, b) ((a) ? (void)0 : feature_panic(b))
+
+/*******************************************************************************
+ * Function : feature_panic
+ * Customised panic module with error logging mechanism to list the feature
+ * not supported by the PE.
+ ******************************************************************************/
+static inline void feature_panic(char *feat_name)
+{
+ ERROR("FEAT_%s not supported by the PE\n", feat_name);
+ panic();
+}
+
+#endif /* FEAT_DETECT_H */
diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h
index 800ad07..e0c2212 100644
--- a/include/common/tbbr/cot_def.h
+++ b/include/common/tbbr/cot_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +14,8 @@
/* TBBR CoT definitions */
#if defined(SPD_spmd)
#define COT_MAX_VERIFIED_PARAMS 8
+#elif defined(ARM_COT_cca)
+#define COT_MAX_VERIFIED_PARAMS 8
#else
#define COT_MAX_VERIFIED_PARAMS 4
#endif
diff --git a/include/common/uuid.h b/include/common/uuid.h
index 5651d0d..c8dd681 100644
--- a/include/common/uuid.h
+++ b/include/common/uuid.h
@@ -1,15 +1,18 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef UUID_H
-#define UUID_H
+#ifndef UUID_COMMON_H
+#define UUID_COMMON_H
#define UUID_BYTES_LENGTH 16
#define UUID_STRING_LENGTH 36
int read_uuid(uint8_t *dest, char *uuid);
+bool uuid_match(uint32_t *uuid1, uint32_t *uuid2);
+void copy_uuid(uint32_t *to_uuid, uint32_t *from_uuid);
+bool is_null_uuid(uint32_t *uuid);
-#endif /* UUID_H */
+#endif /* UUID_COMMON_H */
diff --git a/include/drivers/arm/gic600ae_fmu.h b/include/drivers/arm/gic600ae_fmu.h
index 691ffc7..88b87b9 100644
--- a/include/drivers/arm/gic600ae_fmu.h
+++ b/include/drivers/arm/gic600ae_fmu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -37,6 +37,7 @@
/* SMEN constants */
#define FMU_SMEN_BLK_SHIFT U(8)
#define FMU_SMEN_SMID_SHIFT U(24)
+#define FMU_SMEN_EN_BIT BIT(0)
/* Error record IDs */
#define FMU_BLK_GICD U(0)
@@ -86,10 +87,10 @@
/* Safety Mechamism limit */
#define FMU_SMID_GICD_MAX U(33)
+#define FMU_SMID_PPI_MAX U(12)
+#define FMU_SMID_ITS_MAX U(14)
#define FMU_SMID_SPICOL_MAX U(5)
#define FMU_SMID_WAKERQ_MAX U(2)
-#define FMU_SMID_ITS_MAX U(14)
-#define FMU_SMID_PPI_MAX U(12)
/* MBIST Safety Mechanism ID */
#define GICD_MBIST_REQ_ERROR U(23)
@@ -100,12 +101,17 @@
#define ITS_FMU_CLKGATE_ERROR U(14)
/* ERRSTATUS bits */
-#define FMU_ERRSTATUS_V_BIT BIT(30)
-#define FMU_ERRSTATUS_UE_BIT BIT(29)
-#define FMU_ERRSTATUS_OV_BIT BIT(27)
-#define FMU_ERRSTATUS_CE_BITS (BIT(25) | BIT(24))
-#define FMU_ERRSTATUS_CLEAR (FMU_ERRSTATUS_V_BIT | FMU_ERRSTATUS_UE_BIT | \
- FMU_ERRSTATUS_OV_BIT | FMU_ERRSTATUS_CE_BITS)
+#define FMU_ERRSTATUS_BLKID_SHIFT U(32)
+#define FMU_ERRSTATUS_BLKID_MASK U(0xFF)
+#define FMU_ERRSTATUS_V_BIT BIT(30)
+#define FMU_ERRSTATUS_UE_BIT BIT(29)
+#define FMU_ERRSTATUS_OV_BIT BIT(27)
+#define FMU_ERRSTATUS_CE_BITS (BIT(25) | BIT(24))
+#define FMU_ERRSTATUS_CLEAR (FMU_ERRSTATUS_V_BIT | FMU_ERRSTATUS_UE_BIT | \
+ FMU_ERRSTATUS_OV_BIT | FMU_ERRSTATUS_CE_BITS)
+#define FMU_ERRSTATUS_IERR_MASK U(0xFF)
+#define FMU_ERRSTATUS_IERR_SHIFT U(8)
+#define FMU_ERRSTATUS_SERR_MASK U(0xFF)
/* PINGCTLR constants */
#define FMU_PINGCTLR_INTDIFF_SHIFT U(16)
@@ -137,11 +143,14 @@
void gic_fmu_write_smen(uintptr_t base, uint32_t val);
void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val);
void gic_fmu_write_pingmask(uintptr_t base, uint64_t val);
+void gic_fmu_disable_all_sm_blkid(uintptr_t base, unsigned int blkid);
void gic600_fmu_init(uint64_t base, uint64_t blk_present_mask, bool errctlr_ce_en, bool errctlr_ue_en);
void gic600_fmu_enable_ping(uint64_t base, uint64_t blk_present_mask,
unsigned int timeout_val, unsigned int interval_diff);
void gic600_fmu_print_sm_info(uint64_t base, unsigned int blk, unsigned int smid);
+int gic600_fmu_probe(uint64_t base, int *probe_data);
+int gic600_fmu_ras_handler(uint64_t base, int probe_data);
#endif /* __ASSEMBLER__ */
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 5efefb6..8371dd5 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -76,6 +76,8 @@
#endif /* GIC_EXT_INTID */
+#define GIC_REV(r, p) ((r << 4) | p)
+
/*******************************************************************************
* GICv3 and 3.1 specific Distributor interface register offsets and constants
******************************************************************************/
@@ -192,6 +194,15 @@
#define GICR_CTLR_UWP_SHIFT 31
#define GICR_CTLR_UWP_MASK U(0x1)
#define GICR_CTLR_UWP_BIT BIT_32(GICR_CTLR_UWP_SHIFT)
+#define GICR_CTLR_DPG1S_SHIFT 26
+#define GICR_CTLR_DPG1S_MASK U(0x1)
+#define GICR_CTLR_DPG1S_BIT BIT_32(GICR_CTLR_DPG1S_SHIFT)
+#define GICR_CTLR_DPG1NS_SHIFT 25
+#define GICR_CTLR_DPG1NS_MASK U(0x1)
+#define GICR_CTLR_DPG1NS_BIT BIT_32(GICR_CTLR_DPG1NS_SHIFT)
+#define GICR_CTLR_DPG0_SHIFT 24
+#define GICR_CTLR_DPG0_MASK U(0x1)
+#define GICR_CTLR_DPG0_BIT BIT_32(GICR_CTLR_DPG0_SHIFT)
#define GICR_CTLR_RWP_SHIFT 3
#define GICR_CTLR_RWP_MASK U(0x1)
#define GICR_CTLR_RWP_BIT BIT_32(GICR_CTLR_RWP_SHIFT)
@@ -224,12 +235,40 @@
#define TYPER_PPI_NUM_MASK U(0x1f)
/* GICR_IIDR bit definitions */
-#define IIDR_PRODUCT_ID_MASK U(0xff000000)
-#define IIDR_VARIANT_MASK U(0x000f0000)
-#define IIDR_REVISION_MASK U(0x0000f000)
-#define IIDR_IMPLEMENTER_MASK U(0x00000fff)
-#define IIDR_MODEL_MASK (IIDR_PRODUCT_ID_MASK | \
- IIDR_IMPLEMENTER_MASK)
+#define IIDR_PRODUCT_ID_MASK U(0xff)
+#define IIDR_VARIANT_MASK U(0xf)
+#define IIDR_REV_MASK U(0xf)
+#define IIDR_IMPLEMENTER_MASK U(0xfff)
+#define IIDR_PRODUCT_ID_SHIFT 24
+#define IIDR_VARIANT_SHIFT 16
+#define IIDR_REV_SHIFT 12
+#define IIDR_IMPLEMENTER_SHIFT 0
+#define IIDR_PRODUCT_ID_BIT BIT_32(IIDR_PRODUCT_ID_SHIFT)
+#define IIDR_VARIANT_BIT BIT_32(IIDR_VARIANT_SHIFT)
+#define IIDR_REV_BIT BIT_32(IIDR_REVISION_SHIFT)
+#define IIDR_IMPLEMENTER_BIT BIT_32(IIDR_IMPLEMENTER_SHIFT)
+
+#define IIDR_MODEL_MASK (IIDR_PRODUCT_ID_MASK << IIDR_PRODUCT_ID_SHIFT | \
+ IIDR_IMPLEMENTER_MASK << IIDR_IMPLEMENTER_SHIFT)
+
+#define GIC_PRODUCT_ID_GIC600 U(0x2)
+#define GIC_PRODUCT_ID_GIC600AE U(0x3)
+#define GIC_PRODUCT_ID_GIC700 U(0x4)
+
+/*
+ * Note that below revisions and variants definations are as per GIC600/GIC600AE
+ * specification.
+ */
+#define GIC_REV_P0 U(0x1)
+#define GIC_REV_P1 U(0x3)
+#define GIC_REV_P2 U(0x4)
+#define GIC_REV_P3 U(0x5)
+#define GIC_REV_P4 U(0x6)
+#define GIC_REV_P6 U(0x7)
+
+#define GIC_VARIANT_R0 U(0x0)
+#define GIC_VARIANT_R1 U(0x1)
+#define GIC_VARIANT_R2 U(0x2)
/*******************************************************************************
* GICv3 and 3.1 CPU interface registers & constants
@@ -543,5 +582,17 @@
void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num);
unsigned int gicv3_set_pmr(unsigned int mask);
+void gicv3_get_component_prodid_rev(const uintptr_t gicd_base,
+ unsigned int *gic_prod_id,
+ uint8_t *gic_rev);
+void gicv3_check_erratas_applies(const uintptr_t gicd_base);
+#if GIC600_ERRATA_WA_2384374
+void gicv3_apply_errata_wa_2384374(const uintptr_t gicr_base);
+#else
+static inline void gicv3_apply_errata_wa_2384374(const uintptr_t gicr_base)
+{
+}
+#endif /* GIC600_ERRATA_WA_2384374 */
+
#endif /* __ASSEMBLER__ */
#endif /* GICV3_H */
diff --git a/include/drivers/arm/mhu.h b/include/drivers/arm/mhu.h
new file mode 100644
index 0000000..7745bd9
--- /dev/null
+++ b/include/drivers/arm/mhu.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MHU_H
+#define MHU_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * Generic MHU error enumeration types.
+ */
+enum mhu_error_t {
+ MHU_ERR_NONE = 0,
+ MHU_ERR_NOT_INIT = -1,
+ MHU_ERR_ALREADY_INIT = -2,
+ MHU_ERR_UNSUPPORTED_VERSION = -3,
+ MHU_ERR_UNSUPPORTED = -4,
+ MHU_ERR_INVALID_ARG = -5,
+ MHU_ERR_BUFFER_TOO_SMALL = -6,
+ MHU_ERR_GENERAL = -7,
+};
+
+/**
+ * Initializes sender MHU.
+ *
+ * mhu_sender_base Base address of sender MHU.
+ *
+ * Returns mhu_error_t error code.
+ *
+ * This function must be called before mhu_send_data().
+ */
+enum mhu_error_t mhu_init_sender(uintptr_t mhu_sender_base);
+
+
+/**
+ * Initializes receiver MHU.
+ *
+ * mhu_receiver_base Base address of receiver MHU.
+ *
+ * Returns mhu_error_t error code.
+ *
+ * This function must be called before mhu_receive_data().
+ */
+enum mhu_error_t mhu_init_receiver(uintptr_t mhu_receiver_base);
+
+/**
+ * Sends data over MHU.
+ *
+ * send_buffer Pointer to buffer containing the data to be transmitted.
+ * size Size of the data to be transmitted in bytes.
+ *
+ * Returns mhu_error_t error code.
+ *
+ * The send_buffer must be 4-byte aligned and its length must be at least
+ * (4 - (size % 4)) bytes bigger than the data size to prevent buffer
+ * over-reading.
+ */
+enum mhu_error_t mhu_send_data(const uint8_t *send_buffer, size_t size);
+
+/**
+ * Receives data from MHU.
+ *
+ * receive_buffer Pointer the buffer where to store the received data.
+ * size As input the size of the receive_buffer, as output the
+ * number of bytes received. As a limitation,
+ * the size of the buffer must be a multiple of 4.
+ *
+ * Returns mhu_error_t error code.
+ *
+ * The receive_buffer must be 4-byte aligned and its length must be a
+ * multiple of 4.
+ */
+enum mhu_error_t mhu_receive_data(uint8_t *receive_buffer, size_t *size);
+
+#endif /* MHU_H */
diff --git a/include/drivers/arm/rss_comms.h b/include/drivers/arm/rss_comms.h
new file mode 100644
index 0000000..b96c79f
--- /dev/null
+++ b/include/drivers/arm/rss_comms.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef RSS_COMMS_H
+#define RSS_COMMS_H
+
+#include <stdint.h>
+
+int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base);
+
+#endif /* RSS_COMMS_H */
diff --git a/include/drivers/arm/smmu_v3.h b/include/drivers/arm/smmu_v3.h
index a820a44..37da56f 100644
--- a/include/drivers/arm/smmu_v3.h
+++ b/include/drivers/arm/smmu_v3.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,13 +9,39 @@
#include <stdint.h>
#include <lib/utils_def.h>
+#include <platform_def.h>
/* SMMUv3 register offsets from device base */
+#define SMMU_CR0 U(0x0020)
+#define SMMU_CR0ACK U(0x0024)
#define SMMU_GBPA U(0x0044)
#define SMMU_S_IDR1 U(0x8004)
#define SMMU_S_INIT U(0x803c)
#define SMMU_S_GBPA U(0x8044)
+/*
+ * TODO: SMMU_ROOT_PAGE_OFFSET is platform specific.
+ * Currently defined as a command line model parameter.
+ */
+#if ENABLE_RME
+
+#define SMMU_ROOT_PAGE_OFFSET (PLAT_ARM_SMMUV3_ROOT_REG_OFFSET)
+#define SMMU_ROOT_IDR0 U(SMMU_ROOT_PAGE_OFFSET + 0x0000)
+#define SMMU_ROOT_IIDR U(SMMU_ROOT_PAGE_OFFSET + 0x0008)
+#define SMMU_ROOT_CR0 U(SMMU_ROOT_PAGE_OFFSET + 0x0020)
+#define SMMU_ROOT_CR0ACK U(SMMU_ROOT_PAGE_OFFSET + 0x0024)
+#define SMMU_ROOT_GPT_BASE U(SMMU_ROOT_PAGE_OFFSET + 0x0028)
+#define SMMU_ROOT_GPT_BASE_CFG U(SMMU_ROOT_PAGE_OFFSET + 0x0030)
+#define SMMU_ROOT_GPF_FAR U(SMMU_ROOT_PAGE_OFFSET + 0x0038)
+#define SMMU_ROOT_GPT_CFG_FAR U(SMMU_ROOT_PAGE_OFFSET + 0x0040)
+#define SMMU_ROOT_TLBI U(SMMU_ROOT_PAGE_OFFSET + 0x0050)
+#define SMMU_ROOT_TLBI_CTRL U(SMMU_ROOT_PAGE_OFFSET + 0x0058)
+
+#endif /* ENABLE_RME */
+
+/* SMMU_CR0 and SMMU_CR0ACK register fields */
+#define SMMU_CR0_SMMUEN (1UL << 0)
+
/* SMMU_GBPA register fields */
#define SMMU_GBPA_UPDATE (1UL << 31)
#define SMMU_GBPA_ABORT (1UL << 20)
@@ -30,7 +56,16 @@
#define SMMU_S_GBPA_UPDATE (1UL << 31)
#define SMMU_S_GBPA_ABORT (1UL << 20)
+/* SMMU_ROOT_IDR0 register fields */
+#define SMMU_ROOT_IDR0_ROOT_IMPL (1UL << 0)
+
+/* SMMU_ROOT_CR0 register fields */
+#define SMMU_ROOT_CR0_GPCEN (1UL << 1)
+#define SMMU_ROOT_CR0_ACCESSEN (1UL << 0)
+
int smmuv3_init(uintptr_t smmu_base);
int smmuv3_security_init(uintptr_t smmu_base);
+int smmuv3_ns_set_abort_all(uintptr_t smmu_base);
+
#endif /* SMMU_V3_H */
diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h
index 8ad6d7a..01e261a 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2015-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -80,8 +80,7 @@
#define MBEDTLS_SHA512_C
#else
/* TBB uses SHA-256, what about measured boot? */
-#if defined(TF_MBEDTLS_TPM_HASH_ALG_ID) && \
- (TF_MBEDTLS_TPM_HASH_ALG_ID != TF_MBEDTLS_SHA256)
+#if defined(TF_MBEDTLS_MBOOT_USE_SHA512)
#define MBEDTLS_SHA512_C
#endif
#endif
@@ -141,4 +140,13 @@
#endif
#endif
+/*
+ * Warn if errors from certain functions are ignored.
+ *
+ * The warnings are always enabled (where supported) for critical functions
+ * where ignoring the return value is almost always a bug. This macro extends
+ * the warnings to more functions.
+ */
+#define MBEDTLS_CHECK_RETURN_WARNING
+
#endif /* MBEDTLS_CONFIG_H */
diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h
index 0a19f8a..f4c4fb8 100644
--- a/include/drivers/measured_boot/event_log/event_log.h
+++ b/include/drivers/measured_boot/event_log/event_log.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -78,6 +78,14 @@
#define EVLOG_TB_FW_CONFIG_STRING "TB_FW_CONFIG"
#define EVLOG_TOS_FW_CONFIG_STRING "TOS_FW_CONFIG"
#define EVLOG_RMM_STRING "RMM"
+#define EVLOG_SP1_STRING "SP1"
+#define EVLOG_SP2_STRING "SP2"
+#define EVLOG_SP3_STRING "SP3"
+#define EVLOG_SP4_STRING "SP4"
+#define EVLOG_SP5_STRING "SP5"
+#define EVLOG_SP6_STRING "SP6"
+#define EVLOG_SP7_STRING "SP7"
+#define EVLOG_SP8_STRING "SP8"
typedef struct {
unsigned int id;
diff --git a/include/drivers/measured_boot/rss/rss_measured_boot.h b/include/drivers/measured_boot/rss/rss_measured_boot.h
new file mode 100644
index 0000000..fe88576
--- /dev/null
+++ b/include/drivers/measured_boot/rss/rss_measured_boot.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RSS_MEASURED_BOOT_H
+#define RSS_MEASURED_BOOT_H
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <measured_boot.h>
+
+#define RSS_MBOOT_INVALID_ID UINT32_MAX
+
+/*
+ * Each boot measurement has some metadata (i.e. a string) that identifies
+ * what was measured and how. The sw_type field of the rss_mboot_metadata
+ * structure represents the role of the software component that was measured.
+ * The below macros define strings suitable for the sw_type.
+ * The key thing is to choose meaningful strings so that when the attestation
+ * token is verified, then the different components can be identified.
+ */
+#define RSS_MBOOT_BL2_STRING "BL_2"
+#define RSS_MBOOT_BL31_STRING "SECURE_RT_EL3"
+#define RSS_MBOOT_HW_CONFIG_STRING "HW_CONFIG"
+#define RSS_MBOOT_FW_CONFIG_STRING "FW_CONFIG"
+#define RSS_MBOOT_TB_FW_CONFIG_STRING "TB_FW_CONFIG"
+#define RSS_MBOOT_SOC_FW_CONFIG_STRING "SOC_FW_CONFIG"
+#define RSS_MBOOT_RMM_STRING "RMM"
+
+
+struct rss_mboot_metadata {
+ unsigned int id;
+ uint8_t slot;
+ uint8_t signer_id[SIGNER_ID_MAX_SIZE];
+ size_t signer_id_size;
+ uint8_t version[VERSION_MAX_SIZE];
+ size_t version_size;
+ uint8_t sw_type[SW_TYPE_MAX_SIZE];
+ size_t sw_type_size;
+ bool lock_measurement;
+};
+
+/* Functions' declarations */
+void rss_measured_boot_init(void);
+struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void);
+int rss_mboot_measure_and_record(uintptr_t data_base, uint32_t data_size,
+ uint32_t data_id);
+
+/* TODO: These metadata are currently not available during TF-A boot */
+int rss_mboot_set_signer_id(unsigned int img_id, const void *pk_ptr, size_t pk_len);
+
+#endif /* RSS_MEASURED_BOOT_H */
diff --git a/include/drivers/mmc.h b/include/drivers/mmc.h
index 834a80f..e94693d 100644
--- a/include/drivers/mmc.h
+++ b/include/drivers/mmc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -62,10 +62,12 @@
#define CMD_EXTCSD_HS_TIMING 185
#define CMD_EXTCSD_PART_SWITCH_TIME 199
#define CMD_EXTCSD_SEC_CNT 212
+#define CMD_EXTCSD_BOOT_SIZE_MULT 226
#define EXT_CSD_PART_CONFIG_ACC_MASK GENMASK(2, 0)
#define PART_CFG_BOOT_PARTITION1_ENABLE (U(1) << 3)
#define PART_CFG_BOOT_PARTITION1_ACCESS (U(1) << 0)
+#define PART_CFG_BOOT_PARTITION_NO_ACCESS U(0)
#define PART_CFG_BOOT_PART_EN_MASK GENMASK(5, 3)
#define PART_CFG_BOOT_PART_EN_SHIFT 3
#define PART_CFG_CURRENT_BOOT_PARTITION(x) (((x) & PART_CFG_BOOT_PART_EN_MASK) >> \
@@ -110,6 +112,7 @@
#define MMC_STATE_SLP 10
#define MMC_FLAG_CMD23 (U(1) << 0)
+#define MMC_FLAG_SD_CMD6 (U(1) << 1)
#define CMD8_CHECK_PATTERN U(0xAA)
#define VHS_2_7_3_6_V BIT(8)
@@ -117,6 +120,10 @@
#define SD_SCR_BUS_WIDTH_1 BIT(8)
#define SD_SCR_BUS_WIDTH_4 BIT(10)
+#define SD_SWITCH_FUNC_CHECK 0U
+#define SD_SWITCH_FUNC_SWITCH BIT(31)
+#define SD_SWITCH_ALL_GROUPS_MASK GENMASK(23, 0)
+
struct mmc_cmd {
unsigned int cmd_idx;
unsigned int cmd_arg;
@@ -216,6 +223,27 @@
unsigned int csd_structure: 2;
};
+struct sd_switch_status {
+ unsigned short max_current;
+ unsigned short support_g6;
+ unsigned short support_g5;
+ unsigned short support_g4;
+ unsigned short support_g3;
+ unsigned short support_g2;
+ unsigned short support_g1;
+ unsigned char sel_g6_g5;
+ unsigned char sel_g4_g3;
+ unsigned char sel_g2_g1;
+ unsigned char data_struct_ver;
+ unsigned short busy_g6;
+ unsigned short busy_g5;
+ unsigned short busy_g4;
+ unsigned short busy_g3;
+ unsigned short busy_g2;
+ unsigned short busy_g1;
+ unsigned short reserved[17];
+};
+
enum mmc_device_type {
MMC_IS_EMMC,
MMC_IS_SD,
@@ -233,9 +261,9 @@
size_t mmc_read_blocks(int lba, uintptr_t buf, size_t size);
size_t mmc_write_blocks(int lba, const uintptr_t buf, size_t size);
size_t mmc_erase_blocks(int lba, size_t size);
-size_t mmc_rpmb_read_blocks(int lba, uintptr_t buf, size_t size);
-size_t mmc_rpmb_write_blocks(int lba, const uintptr_t buf, size_t size);
-size_t mmc_rpmb_erase_blocks(int lba, size_t size);
+int mmc_part_switch_current_boot(void);
+int mmc_part_switch_user(void);
+size_t mmc_boot_part_size(void);
size_t mmc_boot_part_read_blocks(int lba, uintptr_t buf, size_t size);
int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
unsigned int width, unsigned int flags,
diff --git a/include/drivers/nand.h b/include/drivers/nand.h
index 1b78ad4..5e5607c 100644
--- a/include/drivers/nand.h
+++ b/include/drivers/nand.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -33,6 +33,8 @@
uintptr_t buffer);
};
+void plat_get_scratch_buffer(void **buffer_addr, size_t *buf_size);
+
/*
* Read bytes from NAND device
*
diff --git a/include/drivers/nxp/crypto/caam/caam.h b/include/drivers/nxp/crypto/caam/caam.h
index 4984b54..6cc1f3d 100644
--- a/include/drivers/nxp/crypto/caam/caam.h
+++ b/include/drivers/nxp/crypto/caam/caam.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 NXP
+ * Copyright 2017-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -15,7 +15,7 @@
/* Job ring 3 is reserved for usage by sec firmware */
#define DEFAULT_JR 3
-#if defined(CONFIG_CHASSIS_3_2) || defined(CONFIG_CHASSIS_2)
+#if defined(CONFIG_CHASSIS_3_2) || defined(CONFIG_CHASSIS_3) || defined(CONFIG_CHASSIS_2)
#define CAAM_JR0_OFFSET 0x10000
#define CAAM_JR1_OFFSET 0x20000
#define CAAM_JR2_OFFSET 0x30000
diff --git a/include/drivers/nxp/dcfg/dcfg.h b/include/drivers/nxp/dcfg/dcfg.h
index 524450a..cf29b12 100644
--- a/include/drivers/nxp/dcfg/dcfg.h
+++ b/include/drivers/nxp/dcfg/dcfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2021 NXP
+ * Copyright 2018-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -12,7 +12,7 @@
#if defined(CONFIG_CHASSIS_2)
#include <dcfg_lsch2.h>
-#elif defined(CONFIG_CHASSIS_3_2)
+#elif defined(CONFIG_CHASSIS_3_2) || defined(CONFIG_CHASSIS_3)
#include <dcfg_lsch3.h>
#endif
diff --git a/include/drivers/nxp/gic/gicv3/plat_gic.h b/include/drivers/nxp/gic/gicv3/plat_gic.h
index f4e12de..794b06b 100644
--- a/include/drivers/nxp/gic/gicv3/plat_gic.h
+++ b/include/drivers/nxp/gic/gicv3/plat_gic.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -21,8 +21,12 @@
#define GICD_CTLR_OFFSET 0x0
#define GICD_CLR_SPI_SR 0x58
#define GICD_IGROUPR_2 0x88
+#define GICD_ISENABLER_1 0x104
+#define GICD_ICENABLER_1 0x184
#define GICD_ISENABLER_2 0x108
#define GICD_ICENABLER_2 0x188
+#define GICD_ISENABLER_3 0x10c
+#define GICD_ICENABLER_3 0x18c
#define GICD_ICPENDR_2 0x288
#define GICD_ICACTIVER_2 0x388
#define GICD_IPRIORITYR_22 0x458
@@ -57,7 +61,6 @@
#define GICR_ICENABLER0_SGI15 0x00008000
#define GICR_CTLR_RWP 0x8
-#define GICR_CTLR_DPG0_MASK 0x2000000
#define GICR_IGROUPR0_SGI15 0x00008000
#define GICR_IGRPMODR0_SGI15 0x00008000
#define GICR_ISENABLER0_SGI15 0x00008000
@@ -69,6 +72,9 @@
#define GIC_IRM_SPI89 0x80000000
#define GICD_IROUTER_VALUE 0x100
+#define GICD_ISENABLER_1_VALUE 0x10000000
+#define GICD_ISENABLER_2_VALUE 0x100
+#define GICD_ISENABLER_3_VALUE 0x20100
#define GICR_WAKER_SLEEP_BIT 0x2
#define GICR_WAKER_ASLEEP (1 << 2 | 1 << 1)
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
index b292ec7..6cb59c3 100644
--- a/include/drivers/partition/partition.h
+++ b/include/drivers/partition/partition.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,11 +29,14 @@
#define LEGACY_PARTITION_BLOCK_SIZE 512
+#define DEFAULT_GPT_HEADER_SIZE 92
+
typedef struct partition_entry {
uint64_t start;
uint64_t length;
char name[EFI_NAMELEN];
struct efi_guid part_guid;
+ struct efi_guid type_guid;
} partition_entry_t;
typedef struct partition_entry_list {
@@ -43,6 +46,7 @@
int load_partition_table(unsigned int image_id);
const partition_entry_t *get_partition_entry(const char *name);
+const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_guid);
const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid);
const partition_entry_list_t *get_partition_entry_list(void);
void partition_init(unsigned int image_id);
diff --git a/include/drivers/st/stm32mp13_rcc.h b/include/drivers/st/stm32mp13_rcc.h
new file mode 100644
index 0000000..1451c9a
--- /dev/null
+++ b/include/drivers/st/stm32mp13_rcc.h
@@ -0,0 +1,1878 @@
+/*
+ * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP13_RCC_H
+#define STM32MP13_RCC_H
+
+#include <lib/utils_def.h>
+
+#define RCC_SECCFGR U(0X0)
+#define RCC_MP_SREQSETR U(0X100)
+#define RCC_MP_SREQCLRR U(0X104)
+#define RCC_MP_APRSTCR U(0X108)
+#define RCC_MP_APRSTSR U(0X10C)
+#define RCC_PWRLPDLYCR U(0X110)
+#define RCC_MP_GRSTCSETR U(0X114)
+#define RCC_BR_RSTSCLRR U(0X118)
+#define RCC_MP_RSTSSETR U(0X11C)
+#define RCC_MP_RSTSCLRR U(0X120)
+#define RCC_MP_IWDGFZSETR U(0X124)
+#define RCC_MP_IWDGFZCLRR U(0X128)
+#define RCC_MP_CIER U(0X200)
+#define RCC_MP_CIFR U(0X204)
+#define RCC_BDCR U(0X400)
+#define RCC_RDLSICR U(0X404)
+#define RCC_OCENSETR U(0X420)
+#define RCC_OCENCLRR U(0X424)
+#define RCC_OCRDYR U(0X428)
+#define RCC_HSICFGR U(0X440)
+#define RCC_CSICFGR U(0X444)
+#define RCC_MCO1CFGR U(0X460)
+#define RCC_MCO2CFGR U(0X464)
+#define RCC_DBGCFGR U(0X468)
+#define RCC_RCK12SELR U(0X480)
+#define RCC_RCK3SELR U(0X484)
+#define RCC_RCK4SELR U(0X488)
+#define RCC_PLL1CR U(0X4A0)
+#define RCC_PLL1CFGR1 U(0X4A4)
+#define RCC_PLL1CFGR2 U(0X4A8)
+#define RCC_PLL1FRACR U(0X4AC)
+#define RCC_PLL1CSGR U(0X4B0)
+#define RCC_PLL2CR U(0X4D0)
+#define RCC_PLL2CFGR1 U(0X4D4)
+#define RCC_PLL2CFGR2 U(0X4D8)
+#define RCC_PLL2FRACR U(0X4DC)
+#define RCC_PLL2CSGR U(0X4E0)
+#define RCC_PLL3CR U(0X500)
+#define RCC_PLL3CFGR1 U(0X504)
+#define RCC_PLL3CFGR2 U(0X508)
+#define RCC_PLL3FRACR U(0X50C)
+#define RCC_PLL3CSGR U(0X510)
+#define RCC_PLL4CR U(0X520)
+#define RCC_PLL4CFGR1 U(0X524)
+#define RCC_PLL4CFGR2 U(0X528)
+#define RCC_PLL4FRACR U(0X52C)
+#define RCC_PLL4CSGR U(0X530)
+#define RCC_MPCKSELR U(0X540)
+#define RCC_ASSCKSELR U(0X544)
+#define RCC_MSSCKSELR U(0X548)
+#define RCC_CPERCKSELR U(0X54C)
+#define RCC_RTCDIVR U(0X560)
+#define RCC_MPCKDIVR U(0X564)
+#define RCC_AXIDIVR U(0X568)
+#define RCC_MLAHBDIVR U(0X56C)
+#define RCC_APB1DIVR U(0X570)
+#define RCC_APB2DIVR U(0X574)
+#define RCC_APB3DIVR U(0X578)
+#define RCC_APB4DIVR U(0X57C)
+#define RCC_APB5DIVR U(0X580)
+#define RCC_APB6DIVR U(0X584)
+#define RCC_TIMG1PRER U(0X5A0)
+#define RCC_TIMG2PRER U(0X5A4)
+#define RCC_TIMG3PRER U(0X5A8)
+#define RCC_DDRITFCR U(0X5C0)
+#define RCC_I2C12CKSELR U(0X600)
+#define RCC_I2C345CKSELR U(0X604)
+#define RCC_SPI2S1CKSELR U(0X608)
+#define RCC_SPI2S23CKSELR U(0X60C)
+#define RCC_SPI45CKSELR U(0X610)
+#define RCC_UART12CKSELR U(0X614)
+#define RCC_UART35CKSELR U(0X618)
+#define RCC_UART4CKSELR U(0X61C)
+#define RCC_UART6CKSELR U(0X620)
+#define RCC_UART78CKSELR U(0X624)
+#define RCC_LPTIM1CKSELR U(0X628)
+#define RCC_LPTIM23CKSELR U(0X62C)
+#define RCC_LPTIM45CKSELR U(0X630)
+#define RCC_SAI1CKSELR U(0X634)
+#define RCC_SAI2CKSELR U(0X638)
+#define RCC_FDCANCKSELR U(0X63C)
+#define RCC_SPDIFCKSELR U(0X640)
+#define RCC_ADC12CKSELR U(0X644)
+#define RCC_SDMMC12CKSELR U(0X648)
+#define RCC_ETH12CKSELR U(0X64C)
+#define RCC_USBCKSELR U(0X650)
+#define RCC_QSPICKSELR U(0X654)
+#define RCC_FMCCKSELR U(0X658)
+#define RCC_RNG1CKSELR U(0X65C)
+#define RCC_STGENCKSELR U(0X660)
+#define RCC_DCMIPPCKSELR U(0X664)
+#define RCC_SAESCKSELR U(0X668)
+#define RCC_APB1RSTSETR U(0X6A0)
+#define RCC_APB1RSTCLRR U(0X6A4)
+#define RCC_APB2RSTSETR U(0X6A8)
+#define RCC_APB2RSTCLRR U(0X6AC)
+#define RCC_APB3RSTSETR U(0X6B0)
+#define RCC_APB3RSTCLRR U(0X6B4)
+#define RCC_APB4RSTSETR U(0X6B8)
+#define RCC_APB4RSTCLRR U(0X6BC)
+#define RCC_APB5RSTSETR U(0X6C0)
+#define RCC_APB5RSTCLRR U(0X6C4)
+#define RCC_APB6RSTSETR U(0X6C8)
+#define RCC_APB6RSTCLRR U(0X6CC)
+#define RCC_AHB2RSTSETR U(0X6D0)
+#define RCC_AHB2RSTCLRR U(0X6D4)
+#define RCC_AHB4RSTSETR U(0X6E0)
+#define RCC_AHB4RSTCLRR U(0X6E4)
+#define RCC_AHB5RSTSETR U(0X6E8)
+#define RCC_AHB5RSTCLRR U(0X6EC)
+#define RCC_AHB6RSTSETR U(0X6F0)
+#define RCC_AHB6RSTCLRR U(0X6F4)
+#define RCC_MP_APB1ENSETR U(0X700)
+#define RCC_MP_APB1ENCLRR U(0X704)
+#define RCC_MP_APB2ENSETR U(0X708)
+#define RCC_MP_APB2ENCLRR U(0X70C)
+#define RCC_MP_APB3ENSETR U(0X710)
+#define RCC_MP_APB3ENCLRR U(0X714)
+#define RCC_MP_S_APB3ENSETR U(0X718)
+#define RCC_MP_S_APB3ENCLRR U(0X71C)
+#define RCC_MP_NS_APB3ENSETR U(0X720)
+#define RCC_MP_NS_APB3ENCLRR U(0X724)
+#define RCC_MP_APB4ENSETR U(0X728)
+#define RCC_MP_APB4ENCLRR U(0X72C)
+#define RCC_MP_S_APB4ENSETR U(0X730)
+#define RCC_MP_S_APB4ENCLRR U(0X734)
+#define RCC_MP_NS_APB4ENSETR U(0X738)
+#define RCC_MP_NS_APB4ENCLRR U(0X73C)
+#define RCC_MP_APB5ENSETR U(0X740)
+#define RCC_MP_APB5ENCLRR U(0X744)
+#define RCC_MP_APB6ENSETR U(0X748)
+#define RCC_MP_APB6ENCLRR U(0X74C)
+#define RCC_MP_AHB2ENSETR U(0X750)
+#define RCC_MP_AHB2ENCLRR U(0X754)
+#define RCC_MP_AHB4ENSETR U(0X760)
+#define RCC_MP_AHB4ENCLRR U(0X764)
+#define RCC_MP_S_AHB4ENSETR U(0X768)
+#define RCC_MP_S_AHB4ENCLRR U(0X76C)
+#define RCC_MP_NS_AHB4ENSETR U(0X770)
+#define RCC_MP_NS_AHB4ENCLRR U(0X774)
+#define RCC_MP_AHB5ENSETR U(0X778)
+#define RCC_MP_AHB5ENCLRR U(0X77C)
+#define RCC_MP_AHB6ENSETR U(0X780)
+#define RCC_MP_AHB6ENCLRR U(0X784)
+#define RCC_MP_S_AHB6ENSETR U(0X788)
+#define RCC_MP_S_AHB6ENCLRR U(0X78C)
+#define RCC_MP_NS_AHB6ENSETR U(0X790)
+#define RCC_MP_NS_AHB6ENCLRR U(0X794)
+#define RCC_MP_APB1LPENSETR U(0X800)
+#define RCC_MP_APB1LPENCLRR U(0X804)
+#define RCC_MP_APB2LPENSETR U(0X808)
+#define RCC_MP_APB2LPENCLRR U(0X80C)
+#define RCC_MP_APB3LPENSETR U(0X810)
+#define RCC_MP_APB3LPENCLRR U(0X814)
+#define RCC_MP_S_APB3LPENSETR U(0X818)
+#define RCC_MP_S_APB3LPENCLRR U(0X81C)
+#define RCC_MP_NS_APB3LPENSETR U(0X820)
+#define RCC_MP_NS_APB3LPENCLRR U(0X824)
+#define RCC_MP_APB4LPENSETR U(0X828)
+#define RCC_MP_APB4LPENCLRR U(0X82C)
+#define RCC_MP_S_APB4LPENSETR U(0X830)
+#define RCC_MP_S_APB4LPENCLRR U(0X834)
+#define RCC_MP_NS_APB4LPENSETR U(0X838)
+#define RCC_MP_NS_APB4LPENCLRR U(0X83C)
+#define RCC_MP_APB5LPENSETR U(0X840)
+#define RCC_MP_APB5LPENCLRR U(0X844)
+#define RCC_MP_APB6LPENSETR U(0X848)
+#define RCC_MP_APB6LPENCLRR U(0X84C)
+#define RCC_MP_AHB2LPENSETR U(0X850)
+#define RCC_MP_AHB2LPENCLRR U(0X854)
+#define RCC_MP_AHB4LPENSETR U(0X858)
+#define RCC_MP_AHB4LPENCLRR U(0X85C)
+#define RCC_MP_S_AHB4LPENSETR U(0X868)
+#define RCC_MP_S_AHB4LPENCLRR U(0X86C)
+#define RCC_MP_NS_AHB4LPENSETR U(0X870)
+#define RCC_MP_NS_AHB4LPENCLRR U(0X874)
+#define RCC_MP_AHB5LPENSETR U(0X878)
+#define RCC_MP_AHB5LPENCLRR U(0X87C)
+#define RCC_MP_AHB6LPENSETR U(0X880)
+#define RCC_MP_AHB6LPENCLRR U(0X884)
+#define RCC_MP_S_AHB6LPENSETR U(0X888)
+#define RCC_MP_S_AHB6LPENCLRR U(0X88C)
+#define RCC_MP_NS_AHB6LPENSETR U(0X890)
+#define RCC_MP_NS_AHB6LPENCLRR U(0X894)
+#define RCC_MP_S_AXIMLPENSETR U(0X898)
+#define RCC_MP_S_AXIMLPENCLRR U(0X89C)
+#define RCC_MP_NS_AXIMLPENSETR U(0X8A0)
+#define RCC_MP_NS_AXIMLPENCLRR U(0X8A4)
+#define RCC_MP_MLAHBLPENSETR U(0X8A8)
+#define RCC_MP_MLAHBLPENCLRR U(0X8AC)
+#define RCC_APB3SECSR U(0X8C0)
+#define RCC_APB4SECSR U(0X8C4)
+#define RCC_APB5SECSR U(0X8C8)
+#define RCC_APB6SECSR U(0X8CC)
+#define RCC_AHB2SECSR U(0X8D0)
+#define RCC_AHB4SECSR U(0X8D4)
+#define RCC_AHB5SECSR U(0X8D8)
+#define RCC_AHB6SECSR U(0X8DC)
+#define RCC_VERR U(0XFF4)
+#define RCC_IDR U(0XFF8)
+#define RCC_SIDR U(0XFFC)
+
+/* RCC_SECCFGR register fields */
+#define RCC_SECCFGR_HSISEC BIT(0)
+#define RCC_SECCFGR_CSISEC BIT(1)
+#define RCC_SECCFGR_HSESEC BIT(2)
+#define RCC_SECCFGR_LSISEC BIT(3)
+#define RCC_SECCFGR_LSESEC BIT(4)
+#define RCC_SECCFGR_PLL12SEC BIT(8)
+#define RCC_SECCFGR_PLL3SEC BIT(9)
+#define RCC_SECCFGR_PLL4SEC BIT(10)
+#define RCC_SECCFGR_MPUSEC BIT(11)
+#define RCC_SECCFGR_AXISEC BIT(12)
+#define RCC_SECCFGR_MLAHBSEC BIT(13)
+#define RCC_SECCFGR_APB3DIVSEC BIT(16)
+#define RCC_SECCFGR_APB4DIVSEC BIT(17)
+#define RCC_SECCFGR_APB5DIVSEC BIT(18)
+#define RCC_SECCFGR_APB6DIVSEC BIT(19)
+#define RCC_SECCFGR_TIMG3SEC BIT(20)
+#define RCC_SECCFGR_CPERSEC BIT(21)
+#define RCC_SECCFGR_MCO1SEC BIT(22)
+#define RCC_SECCFGR_MCO2SEC BIT(23)
+#define RCC_SECCFGR_STPSEC BIT(24)
+#define RCC_SECCFGR_RSTSEC BIT(25)
+#define RCC_SECCFGR_PWRSEC BIT(31)
+
+/* RCC_MP_SREQSETR register fields */
+#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0)
+
+/* RCC_MP_SREQCLRR register fields */
+#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0)
+
+/* RCC_MP_APRSTCR register fields */
+#define RCC_MP_APRSTCR_RDCTLEN BIT(0)
+#define RCC_MP_APRSTCR_RSTTO_MASK GENMASK(14, 8)
+#define RCC_MP_APRSTCR_RSTTO_SHIFT 8
+
+/* RCC_MP_APRSTSR register fields */
+#define RCC_MP_APRSTSR_RSTTOV_MASK GENMASK(14, 8)
+#define RCC_MP_APRSTSR_RSTTOV_SHIFT 8
+
+/* RCC_PWRLPDLYCR register fields */
+#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK(21, 0)
+#define RCC_PWRLPDLYCR_PWRLP_DLY_SHIFT 0
+
+/* RCC_MP_GRSTCSETR register fields */
+#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0)
+#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4)
+
+/* RCC_BR_RSTSCLRR register fields */
+#define RCC_BR_RSTSCLRR_PORRSTF BIT(0)
+#define RCC_BR_RSTSCLRR_BORRSTF BIT(1)
+#define RCC_BR_RSTSCLRR_PADRSTF BIT(2)
+#define RCC_BR_RSTSCLRR_HCSSRSTF BIT(3)
+#define RCC_BR_RSTSCLRR_VCORERSTF BIT(4)
+#define RCC_BR_RSTSCLRR_VCPURSTF BIT(5)
+#define RCC_BR_RSTSCLRR_MPSYSRSTF BIT(6)
+#define RCC_BR_RSTSCLRR_IWDG1RSTF BIT(8)
+#define RCC_BR_RSTSCLRR_IWDG2RSTF BIT(9)
+#define RCC_BR_RSTSCLRR_MPUP0RSTF BIT(13)
+
+/* RCC_MP_RSTSSETR register fields */
+#define RCC_MP_RSTSSETR_PORRSTF BIT(0)
+#define RCC_MP_RSTSSETR_BORRSTF BIT(1)
+#define RCC_MP_RSTSSETR_PADRSTF BIT(2)
+#define RCC_MP_RSTSSETR_HCSSRSTF BIT(3)
+#define RCC_MP_RSTSSETR_VCORERSTF BIT(4)
+#define RCC_MP_RSTSSETR_VCPURSTF BIT(5)
+#define RCC_MP_RSTSSETR_MPSYSRSTF BIT(6)
+#define RCC_MP_RSTSSETR_IWDG1RSTF BIT(8)
+#define RCC_MP_RSTSSETR_IWDG2RSTF BIT(9)
+#define RCC_MP_RSTSSETR_STP2RSTF BIT(10)
+#define RCC_MP_RSTSSETR_STDBYRSTF BIT(11)
+#define RCC_MP_RSTSSETR_CSTDBYRSTF BIT(12)
+#define RCC_MP_RSTSSETR_MPUP0RSTF BIT(13)
+#define RCC_MP_RSTSSETR_SPARE BIT(15)
+
+/* RCC_MP_RSTSCLRR register fields */
+#define RCC_MP_RSTSCLRR_PORRSTF BIT(0)
+#define RCC_MP_RSTSCLRR_BORRSTF BIT(1)
+#define RCC_MP_RSTSCLRR_PADRSTF BIT(2)
+#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3)
+#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4)
+#define RCC_MP_RSTSCLRR_VCPURSTF BIT(5)
+#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6)
+#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8)
+#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9)
+#define RCC_MP_RSTSCLRR_STP2RSTF BIT(10)
+#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11)
+#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12)
+#define RCC_MP_RSTSCLRR_MPUP0RSTF BIT(13)
+#define RCC_MP_RSTSCLRR_SPARE BIT(15)
+
+/* RCC_MP_IWDGFZSETR register fields */
+#define RCC_MP_IWDGFZSETR_FZ_IWDG1 BIT(0)
+#define RCC_MP_IWDGFZSETR_FZ_IWDG2 BIT(1)
+
+/* RCC_MP_IWDGFZCLRR register fields */
+#define RCC_MP_IWDGFZCLRR_FZ_IWDG1 BIT(0)
+#define RCC_MP_IWDGFZCLRR_FZ_IWDG2 BIT(1)
+
+/* RCC_MP_CIER register fields */
+#define RCC_MP_CIER_LSIRDYIE BIT(0)
+#define RCC_MP_CIER_LSERDYIE BIT(1)
+#define RCC_MP_CIER_HSIRDYIE BIT(2)
+#define RCC_MP_CIER_HSERDYIE BIT(3)
+#define RCC_MP_CIER_CSIRDYIE BIT(4)
+#define RCC_MP_CIER_PLL1DYIE BIT(8)
+#define RCC_MP_CIER_PLL2DYIE BIT(9)
+#define RCC_MP_CIER_PLL3DYIE BIT(10)
+#define RCC_MP_CIER_PLL4DYIE BIT(11)
+#define RCC_MP_CIER_LSECSSIE BIT(16)
+#define RCC_MP_CIER_WKUPIE BIT(20)
+
+/* RCC_MP_CIFR register fields */
+#define RCC_MP_CIFR_LSIRDYF BIT(0)
+#define RCC_MP_CIFR_LSERDYF BIT(1)
+#define RCC_MP_CIFR_HSIRDYF BIT(2)
+#define RCC_MP_CIFR_HSERDYF BIT(3)
+#define RCC_MP_CIFR_CSIRDYF BIT(4)
+#define RCC_MP_CIFR_PLL1DYF BIT(8)
+#define RCC_MP_CIFR_PLL2DYF BIT(9)
+#define RCC_MP_CIFR_PLL3DYF BIT(10)
+#define RCC_MP_CIFR_PLL4DYF BIT(11)
+#define RCC_MP_CIFR_LSECSSF BIT(16)
+#define RCC_MP_CIFR_WKUPF BIT(20)
+
+/* RCC_BDCR register fields */
+#define RCC_BDCR_LSEON BIT(0)
+#define RCC_BDCR_LSEBYP BIT(1)
+#define RCC_BDCR_LSERDY BIT(2)
+#define RCC_BDCR_DIGBYP BIT(3)
+#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4)
+#define RCC_BDCR_LSEDRV_SHIFT 4
+#define RCC_BDCR_LSECSSON BIT(8)
+#define RCC_BDCR_LSECSSD BIT(9)
+#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16)
+#define RCC_BDCR_RTCSRC_SHIFT 16
+#define RCC_BDCR_RTCCKEN BIT(20)
+#define RCC_BDCR_VSWRST BIT(31)
+
+#define RCC_BDCR_LSEBYP_BIT 1
+#define RCC_BDCR_LSERDY_BIT 2
+#define RCC_BDCR_DIGBYP_BIT 3
+#define RCC_BDCR_LSECSSON_BIT 8
+
+#define RCC_BDCR_LSEDRV_WIDTH 2
+
+/* RCC_RDLSICR register fields */
+#define RCC_RDLSICR_LSION BIT(0)
+#define RCC_RDLSICR_LSIRDY BIT(1)
+#define RCC_RDLSICR_MRD_MASK GENMASK(20, 16)
+#define RCC_RDLSICR_MRD_SHIFT 16
+#define RCC_RDLSICR_EADLY_MASK GENMASK(26, 24)
+#define RCC_RDLSICR_EADLY_SHIFT 24
+#define RCC_RDLSICR_SPARE_MASK GENMASK(31, 27)
+#define RCC_RDLSICR_SPARE_SHIFT 27
+
+#define RCC_RDLSICR_LSIRDY_BIT 1
+
+/* RCC_OCENSETR register fields */
+#define RCC_OCENSETR_HSION BIT(0)
+#define RCC_OCENSETR_HSIKERON BIT(1)
+#define RCC_OCENSETR_CSION BIT(4)
+#define RCC_OCENSETR_CSIKERON BIT(5)
+#define RCC_OCENSETR_DIGBYP BIT(7)
+#define RCC_OCENSETR_HSEON BIT(8)
+#define RCC_OCENSETR_HSEKERON BIT(9)
+#define RCC_OCENSETR_HSEBYP BIT(10)
+#define RCC_OCENSETR_HSECSSON BIT(11)
+
+#define RCC_OCENR_DIGBYP_BIT 7
+#define RCC_OCENR_HSEBYP_BIT 10
+#define RCC_OCENR_HSECSSON_BIT 11
+
+/* RCC_OCENCLRR register fields */
+#define RCC_OCENCLRR_HSION BIT(0)
+#define RCC_OCENCLRR_HSIKERON BIT(1)
+#define RCC_OCENCLRR_CSION BIT(4)
+#define RCC_OCENCLRR_CSIKERON BIT(5)
+#define RCC_OCENCLRR_DIGBYP BIT(7)
+#define RCC_OCENCLRR_HSEON BIT(8)
+#define RCC_OCENCLRR_HSEKERON BIT(9)
+#define RCC_OCENCLRR_HSEBYP BIT(10)
+
+/* RCC_OCRDYR register fields */
+#define RCC_OCRDYR_HSIRDY BIT(0)
+#define RCC_OCRDYR_HSIDIVRDY BIT(2)
+#define RCC_OCRDYR_CSIRDY BIT(4)
+#define RCC_OCRDYR_HSERDY BIT(8)
+#define RCC_OCRDYR_MPUCKRDY BIT(23)
+#define RCC_OCRDYR_AXICKRDY BIT(24)
+
+#define RCC_OCRDYR_HSIRDY_BIT 0
+#define RCC_OCRDYR_HSIDIVRDY_BIT 2
+#define RCC_OCRDYR_CSIRDY_BIT 4
+#define RCC_OCRDYR_HSERDY_BIT 8
+
+/* RCC_HSICFGR register fields */
+#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0)
+#define RCC_HSICFGR_HSIDIV_SHIFT 0
+#define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8)
+#define RCC_HSICFGR_HSITRIM_SHIFT 8
+#define RCC_HSICFGR_HSICAL_MASK GENMASK(27, 16)
+#define RCC_HSICFGR_HSICAL_SHIFT 16
+
+/* RCC_CSICFGR register fields */
+#define RCC_CSICFGR_CSITRIM_MASK GENMASK(12, 8)
+#define RCC_CSICFGR_CSITRIM_SHIFT 8
+#define RCC_CSICFGR_CSICAL_MASK GENMASK(23, 16)
+#define RCC_CSICFGR_CSICAL_SHIFT 16
+
+/* RCC_MCO1CFGR register fields */
+#define RCC_MCO1CFGR_MCO1SEL_MASK GENMASK(2, 0)
+#define RCC_MCO1CFGR_MCO1SEL_SHIFT 0
+#define RCC_MCO1CFGR_MCO1DIV_MASK GENMASK(7, 4)
+#define RCC_MCO1CFGR_MCO1DIV_SHIFT 4
+#define RCC_MCO1CFGR_MCO1ON BIT(12)
+
+/* RCC_MCO2CFGR register fields */
+#define RCC_MCO2CFGR_MCO2SEL_MASK GENMASK(2, 0)
+#define RCC_MCO2CFGR_MCO2SEL_SHIFT 0
+#define RCC_MCO2CFGR_MCO2DIV_MASK GENMASK(7, 4)
+#define RCC_MCO2CFGR_MCO2DIV_SHIFT 4
+#define RCC_MCO2CFGR_MCO2ON BIT(12)
+
+/* RCC_DBGCFGR register fields */
+#define RCC_DBGCFGR_TRACEDIV_MASK GENMASK(2, 0)
+#define RCC_DBGCFGR_TRACEDIV_SHIFT 0
+#define RCC_DBGCFGR_DBGCKEN BIT(8)
+#define RCC_DBGCFGR_TRACECKEN BIT(9)
+#define RCC_DBGCFGR_DBGRST BIT(12)
+
+/* RCC_RCK12SELR register fields */
+#define RCC_RCK12SELR_PLL12SRC_MASK GENMASK(1, 0)
+#define RCC_RCK12SELR_PLL12SRC_SHIFT 0
+#define RCC_RCK12SELR_PLL12SRCRDY BIT(31)
+
+/* RCC_RCK3SELR register fields */
+#define RCC_RCK3SELR_PLL3SRC_MASK GENMASK(1, 0)
+#define RCC_RCK3SELR_PLL3SRC_SHIFT 0
+#define RCC_RCK3SELR_PLL3SRCRDY BIT(31)
+
+/* RCC_RCK4SELR register fields */
+#define RCC_RCK4SELR_PLL4SRC_MASK GENMASK(1, 0)
+#define RCC_RCK4SELR_PLL4SRC_SHIFT 0
+#define RCC_RCK4SELR_PLL4SRCRDY BIT(31)
+
+/* RCC_PLL1CR register fields */
+#define RCC_PLL1CR_PLLON BIT(0)
+#define RCC_PLL1CR_PLL1RDY BIT(1)
+#define RCC_PLL1CR_SSCG_CTRL BIT(2)
+#define RCC_PLL1CR_DIVPEN BIT(4)
+#define RCC_PLL1CR_DIVQEN BIT(5)
+#define RCC_PLL1CR_DIVREN BIT(6)
+
+/* RCC_PLL1CFGR1 register fields */
+#define RCC_PLL1CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL1CFGR1_DIVN_SHIFT 0
+#define RCC_PLL1CFGR1_DIVM1_MASK GENMASK(21, 16)
+#define RCC_PLL1CFGR1_DIVM1_SHIFT 16
+
+/* RCC_PLL1CFGR2 register fields */
+#define RCC_PLL1CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL1CFGR2_DIVP_SHIFT 0
+#define RCC_PLL1CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL1CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL1CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL1CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL1FRACR register fields */
+#define RCC_PLL1FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL1FRACR_FRACV_SHIFT 3
+#define RCC_PLL1FRACR_FRACLE BIT(16)
+
+/* RCC_PLL1CSGR register fields */
+#define RCC_PLL1CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL1CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL1CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL1CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL1CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL1CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL1CSGR_INC_STEP_SHIFT 16
+
+/* RCC_PLL2CR register fields */
+#define RCC_PLL2CR_PLLON BIT(0)
+#define RCC_PLL2CR_PLL2RDY BIT(1)
+#define RCC_PLL2CR_SSCG_CTRL BIT(2)
+#define RCC_PLL2CR_DIVPEN BIT(4)
+#define RCC_PLL2CR_DIVQEN BIT(5)
+#define RCC_PLL2CR_DIVREN BIT(6)
+
+/* RCC_PLL2CFGR1 register fields */
+#define RCC_PLL2CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL2CFGR1_DIVN_SHIFT 0
+#define RCC_PLL2CFGR1_DIVM2_MASK GENMASK(21, 16)
+#define RCC_PLL2CFGR1_DIVM2_SHIFT 16
+
+/* RCC_PLL2CFGR2 register fields */
+#define RCC_PLL2CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL2CFGR2_DIVP_SHIFT 0
+#define RCC_PLL2CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL2CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL2CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL2CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL2FRACR register fields */
+#define RCC_PLL2FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL2FRACR_FRACV_SHIFT 3
+#define RCC_PLL2FRACR_FRACLE BIT(16)
+
+/* RCC_PLL2CSGR register fields */
+#define RCC_PLL2CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL2CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL2CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL2CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL2CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL2CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL2CSGR_INC_STEP_SHIFT 16
+
+/* RCC_PLL3CR register fields */
+#define RCC_PLL3CR_PLLON BIT(0)
+#define RCC_PLL3CR_PLL3RDY BIT(1)
+#define RCC_PLL3CR_SSCG_CTRL BIT(2)
+#define RCC_PLL3CR_DIVPEN BIT(4)
+#define RCC_PLL3CR_DIVQEN BIT(5)
+#define RCC_PLL3CR_DIVREN BIT(6)
+
+/* RCC_PLL3CFGR1 register fields */
+#define RCC_PLL3CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL3CFGR1_DIVN_SHIFT 0
+#define RCC_PLL3CFGR1_DIVM3_MASK GENMASK(21, 16)
+#define RCC_PLL3CFGR1_DIVM3_SHIFT 16
+#define RCC_PLL3CFGR1_IFRGE_MASK GENMASK(25, 24)
+#define RCC_PLL3CFGR1_IFRGE_SHIFT 24
+
+/* RCC_PLL3CFGR2 register fields */
+#define RCC_PLL3CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL3CFGR2_DIVP_SHIFT 0
+#define RCC_PLL3CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL3CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL3CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL3CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL3FRACR register fields */
+#define RCC_PLL3FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL3FRACR_FRACV_SHIFT 3
+#define RCC_PLL3FRACR_FRACLE BIT(16)
+
+/* RCC_PLL3CSGR register fields */
+#define RCC_PLL3CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL3CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL3CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL3CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL3CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL3CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL3CSGR_INC_STEP_SHIFT 16
+
+/* RCC_PLL4CR register fields */
+#define RCC_PLL4CR_PLLON BIT(0)
+#define RCC_PLL4CR_PLL4RDY BIT(1)
+#define RCC_PLL4CR_SSCG_CTRL BIT(2)
+#define RCC_PLL4CR_DIVPEN BIT(4)
+#define RCC_PLL4CR_DIVQEN BIT(5)
+#define RCC_PLL4CR_DIVREN BIT(6)
+
+/* RCC_PLL4CFGR1 register fields */
+#define RCC_PLL4CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL4CFGR1_DIVN_SHIFT 0
+#define RCC_PLL4CFGR1_DIVM4_MASK GENMASK(21, 16)
+#define RCC_PLL4CFGR1_DIVM4_SHIFT 16
+#define RCC_PLL4CFGR1_IFRGE_MASK GENMASK(25, 24)
+#define RCC_PLL4CFGR1_IFRGE_SHIFT 24
+
+/* RCC_PLL4CFGR2 register fields */
+#define RCC_PLL4CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL4CFGR2_DIVP_SHIFT 0
+#define RCC_PLL4CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL4CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL4CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL4CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL4FRACR register fields */
+#define RCC_PLL4FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL4FRACR_FRACV_SHIFT 3
+#define RCC_PLL4FRACR_FRACLE BIT(16)
+
+/* RCC_PLL4CSGR register fields */
+#define RCC_PLL4CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL4CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL4CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL4CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL4CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL4CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL4CSGR_INC_STEP_SHIFT 16
+
+/* RCC_MPCKSELR register fields */
+#define RCC_MPCKSELR_MPUSRC_MASK GENMASK(1, 0)
+#define RCC_MPCKSELR_MPUSRC_SHIFT 0
+#define RCC_MPCKSELR_MPUSRCRDY BIT(31)
+
+/* RCC_ASSCKSELR register fields */
+#define RCC_ASSCKSELR_AXISSRC_MASK GENMASK(2, 0)
+#define RCC_ASSCKSELR_AXISSRC_SHIFT 0
+#define RCC_ASSCKSELR_AXISSRCRDY BIT(31)
+
+/* RCC_MSSCKSELR register fields */
+#define RCC_MSSCKSELR_MLAHBSSRC_MASK GENMASK(1, 0)
+#define RCC_MSSCKSELR_MLAHBSSRC_SHIFT 0
+#define RCC_MSSCKSELR_MLAHBSSRCRDY BIT(31)
+
+/* RCC_CPERCKSELR register fields */
+#define RCC_CPERCKSELR_CKPERSRC_MASK GENMASK(1, 0)
+#define RCC_CPERCKSELR_CKPERSRC_SHIFT 0
+
+/* RCC_RTCDIVR register fields */
+#define RCC_RTCDIVR_RTCDIV_MASK GENMASK(5, 0)
+#define RCC_RTCDIVR_RTCDIV_SHIFT 0
+
+/* RCC_MPCKDIVR register fields */
+#define RCC_MPCKDIVR_MPUDIV_MASK GENMASK(3, 0)
+#define RCC_MPCKDIVR_MPUDIV_SHIFT 0
+#define RCC_MPCKDIVR_MPUDIVRDY BIT(31)
+
+/* RCC_AXIDIVR register fields */
+#define RCC_AXIDIVR_AXIDIV_MASK GENMASK(2, 0)
+#define RCC_AXIDIVR_AXIDIV_SHIFT 0
+#define RCC_AXIDIVR_AXIDIVRDY BIT(31)
+
+/* RCC_MLAHBDIVR register fields */
+#define RCC_MLAHBDIVR_MLAHBDIV_MASK GENMASK(3, 0)
+#define RCC_MLAHBDIVR_MLAHBDIV_SHIFT 0
+#define RCC_MLAHBDIVR_MLAHBDIVRDY BIT(31)
+
+/* RCC_APB1DIVR register fields */
+#define RCC_APB1DIVR_APB1DIV_MASK GENMASK(2, 0)
+#define RCC_APB1DIVR_APB1DIV_SHIFT 0
+#define RCC_APB1DIVR_APB1DIVRDY BIT(31)
+
+/* RCC_APB2DIVR register fields */
+#define RCC_APB2DIVR_APB2DIV_MASK GENMASK(2, 0)
+#define RCC_APB2DIVR_APB2DIV_SHIFT 0
+#define RCC_APB2DIVR_APB2DIVRDY BIT(31)
+
+/* RCC_APB3DIVR register fields */
+#define RCC_APB3DIVR_APB3DIV_MASK GENMASK(2, 0)
+#define RCC_APB3DIVR_APB3DIV_SHIFT 0
+#define RCC_APB3DIVR_APB3DIVRDY BIT(31)
+
+/* RCC_APB4DIVR register fields */
+#define RCC_APB4DIVR_APB4DIV_MASK GENMASK(2, 0)
+#define RCC_APB4DIVR_APB4DIV_SHIFT 0
+#define RCC_APB4DIVR_APB4DIVRDY BIT(31)
+
+/* RCC_APB5DIVR register fields */
+#define RCC_APB5DIVR_APB5DIV_MASK GENMASK(2, 0)
+#define RCC_APB5DIVR_APB5DIV_SHIFT 0
+#define RCC_APB5DIVR_APB5DIVRDY BIT(31)
+
+/* RCC_APB6DIVR register fields */
+#define RCC_APB6DIVR_APB6DIV_MASK GENMASK(2, 0)
+#define RCC_APB6DIVR_APB6DIV_SHIFT 0
+#define RCC_APB6DIVR_APB6DIVRDY BIT(31)
+
+/* RCC_TIMG1PRER register fields */
+#define RCC_TIMG1PRER_TIMG1PRE BIT(0)
+#define RCC_TIMG1PRER_TIMG1PRERDY BIT(31)
+
+/* RCC_TIMG2PRER register fields */
+#define RCC_TIMG2PRER_TIMG2PRE BIT(0)
+#define RCC_TIMG2PRER_TIMG2PRERDY BIT(31)
+
+/* RCC_TIMG3PRER register fields */
+#define RCC_TIMG3PRER_TIMG3PRE BIT(0)
+#define RCC_TIMG3PRER_TIMG3PRERDY BIT(31)
+
+/* RCC_DDRITFCR register fields */
+#define RCC_DDRITFCR_DDRC1EN BIT(0)
+#define RCC_DDRITFCR_DDRC1LPEN BIT(1)
+#define RCC_DDRITFCR_DDRPHYCEN BIT(4)
+#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5)
+#define RCC_DDRITFCR_DDRCAPBEN BIT(6)
+#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7)
+#define RCC_DDRITFCR_AXIDCGEN BIT(8)
+#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9)
+#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10)
+#define RCC_DDRITFCR_KERDCG_DLY_MASK GENMASK(13, 11)
+#define RCC_DDRITFCR_KERDCG_DLY_SHIFT 11
+#define RCC_DDRITFCR_DDRCAPBRST BIT(14)
+#define RCC_DDRITFCR_DDRCAXIRST BIT(15)
+#define RCC_DDRITFCR_DDRCORERST BIT(16)
+#define RCC_DDRITFCR_DPHYAPBRST BIT(17)
+#define RCC_DDRITFCR_DPHYRST BIT(18)
+#define RCC_DDRITFCR_DPHYCTLRST BIT(19)
+#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20)
+#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20
+#define RCC_DDRITFCR_GSKPMOD BIT(23)
+#define RCC_DDRITFCR_GSKPCTRL BIT(24)
+#define RCC_DDRITFCR_DFILP_WIDTH_MASK GENMASK(27, 25)
+#define RCC_DDRITFCR_DFILP_WIDTH_SHIFT 25
+#define RCC_DDRITFCR_GSKP_DUR_MASK GENMASK(31, 28)
+#define RCC_DDRITFCR_GSKP_DUR_SHIFT 28
+
+/* RCC_I2C12CKSELR register fields */
+#define RCC_I2C12CKSELR_I2C12SRC_MASK GENMASK(2, 0)
+#define RCC_I2C12CKSELR_I2C12SRC_SHIFT 0
+
+/* RCC_I2C345CKSELR register fields */
+#define RCC_I2C345CKSELR_I2C3SRC_MASK GENMASK(2, 0)
+#define RCC_I2C345CKSELR_I2C3SRC_SHIFT 0
+#define RCC_I2C345CKSELR_I2C4SRC_MASK GENMASK(5, 3)
+#define RCC_I2C345CKSELR_I2C4SRC_SHIFT 3
+#define RCC_I2C345CKSELR_I2C5SRC_MASK GENMASK(8, 6)
+#define RCC_I2C345CKSELR_I2C5SRC_SHIFT 6
+
+/* RCC_SPI2S1CKSELR register fields */
+#define RCC_SPI2S1CKSELR_SPI1SRC_MASK GENMASK(2, 0)
+#define RCC_SPI2S1CKSELR_SPI1SRC_SHIFT 0
+
+/* RCC_SPI2S23CKSELR register fields */
+#define RCC_SPI2S23CKSELR_SPI23SRC_MASK GENMASK(2, 0)
+#define RCC_SPI2S23CKSELR_SPI23SRC_SHIFT 0
+
+/* RCC_SPI45CKSELR register fields */
+#define RCC_SPI45CKSELR_SPI4SRC_MASK GENMASK(2, 0)
+#define RCC_SPI45CKSELR_SPI4SRC_SHIFT 0
+#define RCC_SPI45CKSELR_SPI5SRC_MASK GENMASK(5, 3)
+#define RCC_SPI45CKSELR_SPI5SRC_SHIFT 3
+
+/* RCC_UART12CKSELR register fields */
+#define RCC_UART12CKSELR_UART1SRC_MASK GENMASK(2, 0)
+#define RCC_UART12CKSELR_UART1SRC_SHIFT 0
+#define RCC_UART12CKSELR_UART2SRC_MASK GENMASK(5, 3)
+#define RCC_UART12CKSELR_UART2SRC_SHIFT 3
+
+/* RCC_UART35CKSELR register fields */
+#define RCC_UART35CKSELR_UART35SRC_MASK GENMASK(2, 0)
+#define RCC_UART35CKSELR_UART35SRC_SHIFT 0
+
+/* RCC_UART4CKSELR register fields */
+#define RCC_UART4CKSELR_UART4SRC_MASK GENMASK(2, 0)
+#define RCC_UART4CKSELR_UART4SRC_SHIFT 0
+
+/* RCC_UART6CKSELR register fields */
+#define RCC_UART6CKSELR_UART6SRC_MASK GENMASK(2, 0)
+#define RCC_UART6CKSELR_UART6SRC_SHIFT 0
+
+/* RCC_UART78CKSELR register fields */
+#define RCC_UART78CKSELR_UART78SRC_MASK GENMASK(2, 0)
+#define RCC_UART78CKSELR_UART78SRC_SHIFT 0
+
+/* RCC_LPTIM1CKSELR register fields */
+#define RCC_LPTIM1CKSELR_LPTIM1SRC_MASK GENMASK(2, 0)
+#define RCC_LPTIM1CKSELR_LPTIM1SRC_SHIFT 0
+
+/* RCC_LPTIM23CKSELR register fields */
+#define RCC_LPTIM23CKSELR_LPTIM2SRC_MASK GENMASK(2, 0)
+#define RCC_LPTIM23CKSELR_LPTIM2SRC_SHIFT 0
+#define RCC_LPTIM23CKSELR_LPTIM3SRC_MASK GENMASK(5, 3)
+#define RCC_LPTIM23CKSELR_LPTIM3SRC_SHIFT 3
+
+/* RCC_LPTIM45CKSELR register fields */
+#define RCC_LPTIM45CKSELR_LPTIM45SRC_MASK GENMASK(2, 0)
+#define RCC_LPTIM45CKSELR_LPTIM45SRC_SHIFT 0
+
+/* RCC_SAI1CKSELR register fields */
+#define RCC_SAI1CKSELR_SAI1SRC_MASK GENMASK(2, 0)
+#define RCC_SAI1CKSELR_SAI1SRC_SHIFT 0
+
+/* RCC_SAI2CKSELR register fields */
+#define RCC_SAI2CKSELR_SAI2SRC_MASK GENMASK(2, 0)
+#define RCC_SAI2CKSELR_SAI2SRC_SHIFT 0
+
+/* RCC_FDCANCKSELR register fields */
+#define RCC_FDCANCKSELR_FDCANSRC_MASK GENMASK(1, 0)
+#define RCC_FDCANCKSELR_FDCANSRC_SHIFT 0
+
+/* RCC_SPDIFCKSELR register fields */
+#define RCC_SPDIFCKSELR_SPDIFSRC_MASK GENMASK(1, 0)
+#define RCC_SPDIFCKSELR_SPDIFSRC_SHIFT 0
+
+/* RCC_ADC12CKSELR register fields */
+#define RCC_ADC12CKSELR_ADC1SRC_MASK GENMASK(1, 0)
+#define RCC_ADC12CKSELR_ADC1SRC_SHIFT 0
+#define RCC_ADC12CKSELR_ADC2SRC_MASK GENMASK(3, 2)
+#define RCC_ADC12CKSELR_ADC2SRC_SHIFT 2
+
+/* RCC_SDMMC12CKSELR register fields */
+#define RCC_SDMMC12CKSELR_SDMMC1SRC_MASK GENMASK(2, 0)
+#define RCC_SDMMC12CKSELR_SDMMC1SRC_SHIFT 0
+#define RCC_SDMMC12CKSELR_SDMMC2SRC_MASK GENMASK(5, 3)
+#define RCC_SDMMC12CKSELR_SDMMC2SRC_SHIFT 3
+
+/* RCC_ETH12CKSELR register fields */
+#define RCC_ETH12CKSELR_ETH1SRC_MASK GENMASK(1, 0)
+#define RCC_ETH12CKSELR_ETH1SRC_SHIFT 0
+#define RCC_ETH12CKSELR_ETH1PTPDIV_MASK GENMASK(7, 4)
+#define RCC_ETH12CKSELR_ETH1PTPDIV_SHIFT 4
+#define RCC_ETH12CKSELR_ETH2SRC_MASK GENMASK(9, 8)
+#define RCC_ETH12CKSELR_ETH2SRC_SHIFT 8
+#define RCC_ETH12CKSELR_ETH2PTPDIV_MASK GENMASK(15, 12)
+#define RCC_ETH12CKSELR_ETH2PTPDIV_SHIFT 12
+
+/* RCC_USBCKSELR register fields */
+#define RCC_USBCKSELR_USBPHYSRC_MASK GENMASK(1, 0)
+#define RCC_USBCKSELR_USBPHYSRC_SHIFT 0
+#define RCC_USBCKSELR_USBOSRC BIT(4)
+
+/* RCC_QSPICKSELR register fields */
+#define RCC_QSPICKSELR_QSPISRC_MASK GENMASK(1, 0)
+#define RCC_QSPICKSELR_QSPISRC_SHIFT 0
+
+/* RCC_FMCCKSELR register fields */
+#define RCC_FMCCKSELR_FMCSRC_MASK GENMASK(1, 0)
+#define RCC_FMCCKSELR_FMCSRC_SHIFT 0
+
+/* RCC_RNG1CKSELR register fields */
+#define RCC_RNG1CKSELR_RNG1SRC_MASK GENMASK(1, 0)
+#define RCC_RNG1CKSELR_RNG1SRC_SHIFT 0
+
+/* RCC_STGENCKSELR register fields */
+#define RCC_STGENCKSELR_STGENSRC_MASK GENMASK(1, 0)
+#define RCC_STGENCKSELR_STGENSRC_SHIFT 0
+
+/* RCC_DCMIPPCKSELR register fields */
+#define RCC_DCMIPPCKSELR_DCMIPPSRC_MASK GENMASK(1, 0)
+#define RCC_DCMIPPCKSELR_DCMIPPSRC_SHIFT 0
+
+/* RCC_SAESCKSELR register fields */
+#define RCC_SAESCKSELR_SAESSRC_MASK GENMASK(1, 0)
+#define RCC_SAESCKSELR_SAESSRC_SHIFT 0
+
+/* RCC_APB1RSTSETR register fields */
+#define RCC_APB1RSTSETR_TIM2RST BIT(0)
+#define RCC_APB1RSTSETR_TIM3RST BIT(1)
+#define RCC_APB1RSTSETR_TIM4RST BIT(2)
+#define RCC_APB1RSTSETR_TIM5RST BIT(3)
+#define RCC_APB1RSTSETR_TIM6RST BIT(4)
+#define RCC_APB1RSTSETR_TIM7RST BIT(5)
+#define RCC_APB1RSTSETR_LPTIM1RST BIT(9)
+#define RCC_APB1RSTSETR_SPI2RST BIT(11)
+#define RCC_APB1RSTSETR_SPI3RST BIT(12)
+#define RCC_APB1RSTSETR_USART3RST BIT(15)
+#define RCC_APB1RSTSETR_UART4RST BIT(16)
+#define RCC_APB1RSTSETR_UART5RST BIT(17)
+#define RCC_APB1RSTSETR_UART7RST BIT(18)
+#define RCC_APB1RSTSETR_UART8RST BIT(19)
+#define RCC_APB1RSTSETR_I2C1RST BIT(21)
+#define RCC_APB1RSTSETR_I2C2RST BIT(22)
+#define RCC_APB1RSTSETR_SPDIFRST BIT(26)
+
+/* RCC_APB1RSTCLRR register fields */
+#define RCC_APB1RSTCLRR_TIM2RST BIT(0)
+#define RCC_APB1RSTCLRR_TIM3RST BIT(1)
+#define RCC_APB1RSTCLRR_TIM4RST BIT(2)
+#define RCC_APB1RSTCLRR_TIM5RST BIT(3)
+#define RCC_APB1RSTCLRR_TIM6RST BIT(4)
+#define RCC_APB1RSTCLRR_TIM7RST BIT(5)
+#define RCC_APB1RSTCLRR_LPTIM1RST BIT(9)
+#define RCC_APB1RSTCLRR_SPI2RST BIT(11)
+#define RCC_APB1RSTCLRR_SPI3RST BIT(12)
+#define RCC_APB1RSTCLRR_USART3RST BIT(15)
+#define RCC_APB1RSTCLRR_UART4RST BIT(16)
+#define RCC_APB1RSTCLRR_UART5RST BIT(17)
+#define RCC_APB1RSTCLRR_UART7RST BIT(18)
+#define RCC_APB1RSTCLRR_UART8RST BIT(19)
+#define RCC_APB1RSTCLRR_I2C1RST BIT(21)
+#define RCC_APB1RSTCLRR_I2C2RST BIT(22)
+#define RCC_APB1RSTCLRR_SPDIFRST BIT(26)
+
+/* RCC_APB2RSTSETR register fields */
+#define RCC_APB2RSTSETR_TIM1RST BIT(0)
+#define RCC_APB2RSTSETR_TIM8RST BIT(1)
+#define RCC_APB2RSTSETR_SPI1RST BIT(8)
+#define RCC_APB2RSTSETR_USART6RST BIT(13)
+#define RCC_APB2RSTSETR_SAI1RST BIT(16)
+#define RCC_APB2RSTSETR_SAI2RST BIT(17)
+#define RCC_APB2RSTSETR_DFSDMRST BIT(20)
+#define RCC_APB2RSTSETR_FDCANRST BIT(24)
+
+/* RCC_APB2RSTCLRR register fields */
+#define RCC_APB2RSTCLRR_TIM1RST BIT(0)
+#define RCC_APB2RSTCLRR_TIM8RST BIT(1)
+#define RCC_APB2RSTCLRR_SPI1RST BIT(8)
+#define RCC_APB2RSTCLRR_USART6RST BIT(13)
+#define RCC_APB2RSTCLRR_SAI1RST BIT(16)
+#define RCC_APB2RSTCLRR_SAI2RST BIT(17)
+#define RCC_APB2RSTCLRR_DFSDMRST BIT(20)
+#define RCC_APB2RSTCLRR_FDCANRST BIT(24)
+
+/* RCC_APB3RSTSETR register fields */
+#define RCC_APB3RSTSETR_LPTIM2RST BIT(0)
+#define RCC_APB3RSTSETR_LPTIM3RST BIT(1)
+#define RCC_APB3RSTSETR_LPTIM4RST BIT(2)
+#define RCC_APB3RSTSETR_LPTIM5RST BIT(3)
+#define RCC_APB3RSTSETR_SYSCFGRST BIT(11)
+#define RCC_APB3RSTSETR_VREFRST BIT(13)
+#define RCC_APB3RSTSETR_DTSRST BIT(16)
+#define RCC_APB3RSTSETR_PMBCTRLRST BIT(17)
+
+/* RCC_APB3RSTCLRR register fields */
+#define RCC_APB3RSTCLRR_LPTIM2RST BIT(0)
+#define RCC_APB3RSTCLRR_LPTIM3RST BIT(1)
+#define RCC_APB3RSTCLRR_LPTIM4RST BIT(2)
+#define RCC_APB3RSTCLRR_LPTIM5RST BIT(3)
+#define RCC_APB3RSTCLRR_SYSCFGRST BIT(11)
+#define RCC_APB3RSTCLRR_VREFRST BIT(13)
+#define RCC_APB3RSTCLRR_DTSRST BIT(16)
+#define RCC_APB3RSTCLRR_PMBCTRLRST BIT(17)
+
+/* RCC_APB4RSTSETR register fields */
+#define RCC_APB4RSTSETR_LTDCRST BIT(0)
+#define RCC_APB4RSTSETR_DCMIPPRST BIT(1)
+#define RCC_APB4RSTSETR_DDRPERFMRST BIT(8)
+#define RCC_APB4RSTSETR_USBPHYRST BIT(16)
+
+/* RCC_APB4RSTCLRR register fields */
+#define RCC_APB4RSTCLRR_LTDCRST BIT(0)
+#define RCC_APB4RSTCLRR_DCMIPPRST BIT(1)
+#define RCC_APB4RSTCLRR_DDRPERFMRST BIT(8)
+#define RCC_APB4RSTCLRR_USBPHYRST BIT(16)
+
+/* RCC_APB5RSTSETR register fields */
+#define RCC_APB5RSTSETR_STGENRST BIT(20)
+
+/* RCC_APB5RSTCLRR register fields */
+#define RCC_APB5RSTCLRR_STGENRST BIT(20)
+
+/* RCC_APB6RSTSETR register fields */
+#define RCC_APB6RSTSETR_USART1RST BIT(0)
+#define RCC_APB6RSTSETR_USART2RST BIT(1)
+#define RCC_APB6RSTSETR_SPI4RST BIT(2)
+#define RCC_APB6RSTSETR_SPI5RST BIT(3)
+#define RCC_APB6RSTSETR_I2C3RST BIT(4)
+#define RCC_APB6RSTSETR_I2C4RST BIT(5)
+#define RCC_APB6RSTSETR_I2C5RST BIT(6)
+#define RCC_APB6RSTSETR_TIM12RST BIT(7)
+#define RCC_APB6RSTSETR_TIM13RST BIT(8)
+#define RCC_APB6RSTSETR_TIM14RST BIT(9)
+#define RCC_APB6RSTSETR_TIM15RST BIT(10)
+#define RCC_APB6RSTSETR_TIM16RST BIT(11)
+#define RCC_APB6RSTSETR_TIM17RST BIT(12)
+
+/* RCC_APB6RSTCLRR register fields */
+#define RCC_APB6RSTCLRR_USART1RST BIT(0)
+#define RCC_APB6RSTCLRR_USART2RST BIT(1)
+#define RCC_APB6RSTCLRR_SPI4RST BIT(2)
+#define RCC_APB6RSTCLRR_SPI5RST BIT(3)
+#define RCC_APB6RSTCLRR_I2C3RST BIT(4)
+#define RCC_APB6RSTCLRR_I2C4RST BIT(5)
+#define RCC_APB6RSTCLRR_I2C5RST BIT(6)
+#define RCC_APB6RSTCLRR_TIM12RST BIT(7)
+#define RCC_APB6RSTCLRR_TIM13RST BIT(8)
+#define RCC_APB6RSTCLRR_TIM14RST BIT(9)
+#define RCC_APB6RSTCLRR_TIM15RST BIT(10)
+#define RCC_APB6RSTCLRR_TIM16RST BIT(11)
+#define RCC_APB6RSTCLRR_TIM17RST BIT(12)
+
+/* RCC_AHB2RSTSETR register fields */
+#define RCC_AHB2RSTSETR_DMA1RST BIT(0)
+#define RCC_AHB2RSTSETR_DMA2RST BIT(1)
+#define RCC_AHB2RSTSETR_DMAMUX1RST BIT(2)
+#define RCC_AHB2RSTSETR_DMA3RST BIT(3)
+#define RCC_AHB2RSTSETR_DMAMUX2RST BIT(4)
+#define RCC_AHB2RSTSETR_ADC1RST BIT(5)
+#define RCC_AHB2RSTSETR_ADC2RST BIT(6)
+#define RCC_AHB2RSTSETR_USBORST BIT(8)
+
+/* RCC_AHB2RSTCLRR register fields */
+#define RCC_AHB2RSTCLRR_DMA1RST BIT(0)
+#define RCC_AHB2RSTCLRR_DMA2RST BIT(1)
+#define RCC_AHB2RSTCLRR_DMAMUX1RST BIT(2)
+#define RCC_AHB2RSTCLRR_DMA3RST BIT(3)
+#define RCC_AHB2RSTCLRR_DMAMUX2RST BIT(4)
+#define RCC_AHB2RSTCLRR_ADC1RST BIT(5)
+#define RCC_AHB2RSTCLRR_ADC2RST BIT(6)
+#define RCC_AHB2RSTCLRR_USBORST BIT(8)
+
+/* RCC_AHB4RSTSETR register fields */
+#define RCC_AHB4RSTSETR_GPIOARST BIT(0)
+#define RCC_AHB4RSTSETR_GPIOBRST BIT(1)
+#define RCC_AHB4RSTSETR_GPIOCRST BIT(2)
+#define RCC_AHB4RSTSETR_GPIODRST BIT(3)
+#define RCC_AHB4RSTSETR_GPIOERST BIT(4)
+#define RCC_AHB4RSTSETR_GPIOFRST BIT(5)
+#define RCC_AHB4RSTSETR_GPIOGRST BIT(6)
+#define RCC_AHB4RSTSETR_GPIOHRST BIT(7)
+#define RCC_AHB4RSTSETR_GPIOIRST BIT(8)
+#define RCC_AHB4RSTSETR_TSCRST BIT(15)
+
+/* RCC_AHB4RSTCLRR register fields */
+#define RCC_AHB4RSTCLRR_GPIOARST BIT(0)
+#define RCC_AHB4RSTCLRR_GPIOBRST BIT(1)
+#define RCC_AHB4RSTCLRR_GPIOCRST BIT(2)
+#define RCC_AHB4RSTCLRR_GPIODRST BIT(3)
+#define RCC_AHB4RSTCLRR_GPIOERST BIT(4)
+#define RCC_AHB4RSTCLRR_GPIOFRST BIT(5)
+#define RCC_AHB4RSTCLRR_GPIOGRST BIT(6)
+#define RCC_AHB4RSTCLRR_GPIOHRST BIT(7)
+#define RCC_AHB4RSTCLRR_GPIOIRST BIT(8)
+#define RCC_AHB4RSTCLRR_TSCRST BIT(15)
+
+/* RCC_AHB5RSTSETR register fields */
+#define RCC_AHB5RSTSETR_PKARST BIT(2)
+#define RCC_AHB5RSTSETR_SAESRST BIT(3)
+#define RCC_AHB5RSTSETR_CRYP1RST BIT(4)
+#define RCC_AHB5RSTSETR_HASH1RST BIT(5)
+#define RCC_AHB5RSTSETR_RNG1RST BIT(6)
+#define RCC_AHB5RSTSETR_AXIMCRST BIT(16)
+
+/* RCC_AHB5RSTCLRR register fields */
+#define RCC_AHB5RSTCLRR_PKARST BIT(2)
+#define RCC_AHB5RSTCLRR_SAESRST BIT(3)
+#define RCC_AHB5RSTCLRR_CRYP1RST BIT(4)
+#define RCC_AHB5RSTCLRR_HASH1RST BIT(5)
+#define RCC_AHB5RSTCLRR_RNG1RST BIT(6)
+#define RCC_AHB5RSTCLRR_AXIMCRST BIT(16)
+
+/* RCC_AHB6RSTSETR register fields */
+#define RCC_AHB6RSTSETR_MDMARST BIT(0)
+#define RCC_AHB6RSTSETR_MCERST BIT(1)
+#define RCC_AHB6RSTSETR_ETH1MACRST BIT(10)
+#define RCC_AHB6RSTSETR_FMCRST BIT(12)
+#define RCC_AHB6RSTSETR_QSPIRST BIT(14)
+#define RCC_AHB6RSTSETR_SDMMC1RST BIT(16)
+#define RCC_AHB6RSTSETR_SDMMC2RST BIT(17)
+#define RCC_AHB6RSTSETR_CRC1RST BIT(20)
+#define RCC_AHB6RSTSETR_USBHRST BIT(24)
+#define RCC_AHB6RSTSETR_ETH2MACRST BIT(30)
+
+/* RCC_AHB6RSTCLRR register fields */
+#define RCC_AHB6RSTCLRR_MDMARST BIT(0)
+#define RCC_AHB6RSTCLRR_MCERST BIT(1)
+#define RCC_AHB6RSTCLRR_ETH1MACRST BIT(10)
+#define RCC_AHB6RSTCLRR_FMCRST BIT(12)
+#define RCC_AHB6RSTCLRR_QSPIRST BIT(14)
+#define RCC_AHB6RSTCLRR_SDMMC1RST BIT(16)
+#define RCC_AHB6RSTCLRR_SDMMC2RST BIT(17)
+#define RCC_AHB6RSTCLRR_CRC1RST BIT(20)
+#define RCC_AHB6RSTCLRR_USBHRST BIT(24)
+#define RCC_AHB6RSTCLRR_ETH2MACRST BIT(30)
+
+/* RCC_MP_APB1ENSETR register fields */
+#define RCC_MP_APB1ENSETR_TIM2EN BIT(0)
+#define RCC_MP_APB1ENSETR_TIM3EN BIT(1)
+#define RCC_MP_APB1ENSETR_TIM4EN BIT(2)
+#define RCC_MP_APB1ENSETR_TIM5EN BIT(3)
+#define RCC_MP_APB1ENSETR_TIM6EN BIT(4)
+#define RCC_MP_APB1ENSETR_TIM7EN BIT(5)
+#define RCC_MP_APB1ENSETR_LPTIM1EN BIT(9)
+#define RCC_MP_APB1ENSETR_SPI2EN BIT(11)
+#define RCC_MP_APB1ENSETR_SPI3EN BIT(12)
+#define RCC_MP_APB1ENSETR_USART3EN BIT(15)
+#define RCC_MP_APB1ENSETR_UART4EN BIT(16)
+#define RCC_MP_APB1ENSETR_UART5EN BIT(17)
+#define RCC_MP_APB1ENSETR_UART7EN BIT(18)
+#define RCC_MP_APB1ENSETR_UART8EN BIT(19)
+#define RCC_MP_APB1ENSETR_I2C1EN BIT(21)
+#define RCC_MP_APB1ENSETR_I2C2EN BIT(22)
+#define RCC_MP_APB1ENSETR_SPDIFEN BIT(26)
+
+/* RCC_MP_APB1ENCLRR register fields */
+#define RCC_MP_APB1ENCLRR_TIM2EN BIT(0)
+#define RCC_MP_APB1ENCLRR_TIM3EN BIT(1)
+#define RCC_MP_APB1ENCLRR_TIM4EN BIT(2)
+#define RCC_MP_APB1ENCLRR_TIM5EN BIT(3)
+#define RCC_MP_APB1ENCLRR_TIM6EN BIT(4)
+#define RCC_MP_APB1ENCLRR_TIM7EN BIT(5)
+#define RCC_MP_APB1ENCLRR_LPTIM1EN BIT(9)
+#define RCC_MP_APB1ENCLRR_SPI2EN BIT(11)
+#define RCC_MP_APB1ENCLRR_SPI3EN BIT(12)
+#define RCC_MP_APB1ENCLRR_USART3EN BIT(15)
+#define RCC_MP_APB1ENCLRR_UART4EN BIT(16)
+#define RCC_MP_APB1ENCLRR_UART5EN BIT(17)
+#define RCC_MP_APB1ENCLRR_UART7EN BIT(18)
+#define RCC_MP_APB1ENCLRR_UART8EN BIT(19)
+#define RCC_MP_APB1ENCLRR_I2C1EN BIT(21)
+#define RCC_MP_APB1ENCLRR_I2C2EN BIT(22)
+#define RCC_MP_APB1ENCLRR_SPDIFEN BIT(26)
+
+/* RCC_MP_APB2ENSETR register fields */
+#define RCC_MP_APB2ENSETR_TIM1EN BIT(0)
+#define RCC_MP_APB2ENSETR_TIM8EN BIT(1)
+#define RCC_MP_APB2ENSETR_SPI1EN BIT(8)
+#define RCC_MP_APB2ENSETR_USART6EN BIT(13)
+#define RCC_MP_APB2ENSETR_SAI1EN BIT(16)
+#define RCC_MP_APB2ENSETR_SAI2EN BIT(17)
+#define RCC_MP_APB2ENSETR_DFSDMEN BIT(20)
+#define RCC_MP_APB2ENSETR_ADFSDMEN BIT(21)
+#define RCC_MP_APB2ENSETR_FDCANEN BIT(24)
+
+/* RCC_MP_APB2ENCLRR register fields */
+#define RCC_MP_APB2ENCLRR_TIM1EN BIT(0)
+#define RCC_MP_APB2ENCLRR_TIM8EN BIT(1)
+#define RCC_MP_APB2ENCLRR_SPI1EN BIT(8)
+#define RCC_MP_APB2ENCLRR_USART6EN BIT(13)
+#define RCC_MP_APB2ENCLRR_SAI1EN BIT(16)
+#define RCC_MP_APB2ENCLRR_SAI2EN BIT(17)
+#define RCC_MP_APB2ENCLRR_DFSDMEN BIT(20)
+#define RCC_MP_APB2ENCLRR_ADFSDMEN BIT(21)
+#define RCC_MP_APB2ENCLRR_FDCANEN BIT(24)
+
+/* RCC_MP_APB3ENSETR register fields */
+#define RCC_MP_APB3ENSETR_LPTIM2EN BIT(0)
+#define RCC_MP_APB3ENSETR_LPTIM3EN BIT(1)
+#define RCC_MP_APB3ENSETR_LPTIM4EN BIT(2)
+#define RCC_MP_APB3ENSETR_LPTIM5EN BIT(3)
+#define RCC_MP_APB3ENSETR_VREFEN BIT(13)
+#define RCC_MP_APB3ENSETR_DTSEN BIT(16)
+#define RCC_MP_APB3ENSETR_PMBCTRLEN BIT(17)
+#define RCC_MP_APB3ENSETR_HDPEN BIT(20)
+
+/* RCC_MP_APB3ENCLRR register fields */
+#define RCC_MP_APB3ENCLRR_LPTIM2EN BIT(0)
+#define RCC_MP_APB3ENCLRR_LPTIM3EN BIT(1)
+#define RCC_MP_APB3ENCLRR_LPTIM4EN BIT(2)
+#define RCC_MP_APB3ENCLRR_LPTIM5EN BIT(3)
+#define RCC_MP_APB3ENCLRR_VREFEN BIT(13)
+#define RCC_MP_APB3ENCLRR_DTSEN BIT(16)
+#define RCC_MP_APB3ENCLRR_PMBCTRLEN BIT(17)
+#define RCC_MP_APB3ENCLRR_HDPEN BIT(20)
+
+/* RCC_MP_S_APB3ENSETR register fields */
+#define RCC_MP_S_APB3ENSETR_SYSCFGEN BIT(0)
+
+/* RCC_MP_S_APB3ENCLRR register fields */
+#define RCC_MP_S_APB3ENCLRR_SYSCFGEN BIT(0)
+
+/* RCC_MP_NS_APB3ENSETR register fields */
+#define RCC_MP_NS_APB3ENSETR_SYSCFGEN BIT(0)
+
+/* RCC_MP_NS_APB3ENCLRR register fields */
+#define RCC_MP_NS_APB3ENCLRR_SYSCFGEN BIT(0)
+
+/* RCC_MP_APB4ENSETR register fields */
+#define RCC_MP_APB4ENSETR_DCMIPPEN BIT(1)
+#define RCC_MP_APB4ENSETR_DDRPERFMEN BIT(8)
+#define RCC_MP_APB4ENSETR_IWDG2APBEN BIT(15)
+#define RCC_MP_APB4ENSETR_USBPHYEN BIT(16)
+#define RCC_MP_APB4ENSETR_STGENROEN BIT(20)
+
+/* RCC_MP_APB4ENCLRR register fields */
+#define RCC_MP_APB4ENCLRR_DCMIPPEN BIT(1)
+#define RCC_MP_APB4ENCLRR_DDRPERFMEN BIT(8)
+#define RCC_MP_APB4ENCLRR_IWDG2APBEN BIT(15)
+#define RCC_MP_APB4ENCLRR_USBPHYEN BIT(16)
+#define RCC_MP_APB4ENCLRR_STGENROEN BIT(20)
+
+/* RCC_MP_S_APB4ENSETR register fields */
+#define RCC_MP_S_APB4ENSETR_LTDCEN BIT(0)
+
+/* RCC_MP_S_APB4ENCLRR register fields */
+#define RCC_MP_S_APB4ENCLRR_LTDCEN BIT(0)
+
+/* RCC_MP_NS_APB4ENSETR register fields */
+#define RCC_MP_NS_APB4ENSETR_LTDCEN BIT(0)
+
+/* RCC_MP_NS_APB4ENCLRR register fields */
+#define RCC_MP_NS_APB4ENCLRR_LTDCEN BIT(0)
+
+/* RCC_MP_APB5ENSETR register fields */
+#define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8)
+#define RCC_MP_APB5ENSETR_TZCEN BIT(11)
+#define RCC_MP_APB5ENSETR_ETZPCEN BIT(13)
+#define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15)
+#define RCC_MP_APB5ENSETR_BSECEN BIT(16)
+#define RCC_MP_APB5ENSETR_STGENCEN BIT(20)
+
+/* RCC_MP_APB5ENCLRR register fields */
+#define RCC_MP_APB5ENCLRR_RTCAPBEN BIT(8)
+#define RCC_MP_APB5ENCLRR_TZCEN BIT(11)
+#define RCC_MP_APB5ENCLRR_ETZPCEN BIT(13)
+#define RCC_MP_APB5ENCLRR_IWDG1APBEN BIT(15)
+#define RCC_MP_APB5ENCLRR_BSECEN BIT(16)
+#define RCC_MP_APB5ENCLRR_STGENCEN BIT(20)
+
+/* RCC_MP_APB6ENSETR register fields */
+#define RCC_MP_APB6ENSETR_USART1EN BIT(0)
+#define RCC_MP_APB6ENSETR_USART2EN BIT(1)
+#define RCC_MP_APB6ENSETR_SPI4EN BIT(2)
+#define RCC_MP_APB6ENSETR_SPI5EN BIT(3)
+#define RCC_MP_APB6ENSETR_I2C3EN BIT(4)
+#define RCC_MP_APB6ENSETR_I2C4EN BIT(5)
+#define RCC_MP_APB6ENSETR_I2C5EN BIT(6)
+#define RCC_MP_APB6ENSETR_TIM12EN BIT(7)
+#define RCC_MP_APB6ENSETR_TIM13EN BIT(8)
+#define RCC_MP_APB6ENSETR_TIM14EN BIT(9)
+#define RCC_MP_APB6ENSETR_TIM15EN BIT(10)
+#define RCC_MP_APB6ENSETR_TIM16EN BIT(11)
+#define RCC_MP_APB6ENSETR_TIM17EN BIT(12)
+
+/* RCC_MP_APB6ENCLRR register fields */
+#define RCC_MP_APB6ENCLRR_USART1EN BIT(0)
+#define RCC_MP_APB6ENCLRR_USART2EN BIT(1)
+#define RCC_MP_APB6ENCLRR_SPI4EN BIT(2)
+#define RCC_MP_APB6ENCLRR_SPI5EN BIT(3)
+#define RCC_MP_APB6ENCLRR_I2C3EN BIT(4)
+#define RCC_MP_APB6ENCLRR_I2C4EN BIT(5)
+#define RCC_MP_APB6ENCLRR_I2C5EN BIT(6)
+#define RCC_MP_APB6ENCLRR_TIM12EN BIT(7)
+#define RCC_MP_APB6ENCLRR_TIM13EN BIT(8)
+#define RCC_MP_APB6ENCLRR_TIM14EN BIT(9)
+#define RCC_MP_APB6ENCLRR_TIM15EN BIT(10)
+#define RCC_MP_APB6ENCLRR_TIM16EN BIT(11)
+#define RCC_MP_APB6ENCLRR_TIM17EN BIT(12)
+
+/* RCC_MP_AHB2ENSETR register fields */
+#define RCC_MP_AHB2ENSETR_DMA1EN BIT(0)
+#define RCC_MP_AHB2ENSETR_DMA2EN BIT(1)
+#define RCC_MP_AHB2ENSETR_DMAMUX1EN BIT(2)
+#define RCC_MP_AHB2ENSETR_DMA3EN BIT(3)
+#define RCC_MP_AHB2ENSETR_DMAMUX2EN BIT(4)
+#define RCC_MP_AHB2ENSETR_ADC1EN BIT(5)
+#define RCC_MP_AHB2ENSETR_ADC2EN BIT(6)
+#define RCC_MP_AHB2ENSETR_USBOEN BIT(8)
+
+/* RCC_MP_AHB2ENCLRR register fields */
+#define RCC_MP_AHB2ENCLRR_DMA1EN BIT(0)
+#define RCC_MP_AHB2ENCLRR_DMA2EN BIT(1)
+#define RCC_MP_AHB2ENCLRR_DMAMUX1EN BIT(2)
+#define RCC_MP_AHB2ENCLRR_DMA3EN BIT(3)
+#define RCC_MP_AHB2ENCLRR_DMAMUX2EN BIT(4)
+#define RCC_MP_AHB2ENCLRR_ADC1EN BIT(5)
+#define RCC_MP_AHB2ENCLRR_ADC2EN BIT(6)
+#define RCC_MP_AHB2ENCLRR_USBOEN BIT(8)
+
+/* RCC_MP_AHB4ENSETR register fields */
+#define RCC_MP_AHB4ENSETR_TSCEN BIT(15)
+
+/* RCC_MP_AHB4ENCLRR register fields */
+#define RCC_MP_AHB4ENCLRR_TSCEN BIT(15)
+
+/* RCC_MP_S_AHB4ENSETR register fields */
+#define RCC_MP_S_AHB4ENSETR_GPIOAEN BIT(0)
+#define RCC_MP_S_AHB4ENSETR_GPIOBEN BIT(1)
+#define RCC_MP_S_AHB4ENSETR_GPIOCEN BIT(2)
+#define RCC_MP_S_AHB4ENSETR_GPIODEN BIT(3)
+#define RCC_MP_S_AHB4ENSETR_GPIOEEN BIT(4)
+#define RCC_MP_S_AHB4ENSETR_GPIOFEN BIT(5)
+#define RCC_MP_S_AHB4ENSETR_GPIOGEN BIT(6)
+#define RCC_MP_S_AHB4ENSETR_GPIOHEN BIT(7)
+#define RCC_MP_S_AHB4ENSETR_GPIOIEN BIT(8)
+
+/* RCC_MP_S_AHB4ENCLRR register fields */
+#define RCC_MP_S_AHB4ENCLRR_GPIOAEN BIT(0)
+#define RCC_MP_S_AHB4ENCLRR_GPIOBEN BIT(1)
+#define RCC_MP_S_AHB4ENCLRR_GPIOCEN BIT(2)
+#define RCC_MP_S_AHB4ENCLRR_GPIODEN BIT(3)
+#define RCC_MP_S_AHB4ENCLRR_GPIOEEN BIT(4)
+#define RCC_MP_S_AHB4ENCLRR_GPIOFEN BIT(5)
+#define RCC_MP_S_AHB4ENCLRR_GPIOGEN BIT(6)
+#define RCC_MP_S_AHB4ENCLRR_GPIOHEN BIT(7)
+#define RCC_MP_S_AHB4ENCLRR_GPIOIEN BIT(8)
+
+/* RCC_MP_NS_AHB4ENSETR register fields */
+#define RCC_MP_NS_AHB4ENSETR_GPIOAEN BIT(0)
+#define RCC_MP_NS_AHB4ENSETR_GPIOBEN BIT(1)
+#define RCC_MP_NS_AHB4ENSETR_GPIOCEN BIT(2)
+#define RCC_MP_NS_AHB4ENSETR_GPIODEN BIT(3)
+#define RCC_MP_NS_AHB4ENSETR_GPIOEEN BIT(4)
+#define RCC_MP_NS_AHB4ENSETR_GPIOFEN BIT(5)
+#define RCC_MP_NS_AHB4ENSETR_GPIOGEN BIT(6)
+#define RCC_MP_NS_AHB4ENSETR_GPIOHEN BIT(7)
+#define RCC_MP_NS_AHB4ENSETR_GPIOIEN BIT(8)
+
+/* RCC_MP_NS_AHB4ENCLRR register fields */
+#define RCC_MP_NS_AHB4ENCLRR_GPIOAEN BIT(0)
+#define RCC_MP_NS_AHB4ENCLRR_GPIOBEN BIT(1)
+#define RCC_MP_NS_AHB4ENCLRR_GPIOCEN BIT(2)
+#define RCC_MP_NS_AHB4ENCLRR_GPIODEN BIT(3)
+#define RCC_MP_NS_AHB4ENCLRR_GPIOEEN BIT(4)
+#define RCC_MP_NS_AHB4ENCLRR_GPIOFEN BIT(5)
+#define RCC_MP_NS_AHB4ENCLRR_GPIOGEN BIT(6)
+#define RCC_MP_NS_AHB4ENCLRR_GPIOHEN BIT(7)
+#define RCC_MP_NS_AHB4ENCLRR_GPIOIEN BIT(8)
+
+/* RCC_MP_AHB5ENSETR register fields */
+#define RCC_MP_AHB5ENSETR_PKAEN BIT(2)
+#define RCC_MP_AHB5ENSETR_SAESEN BIT(3)
+#define RCC_MP_AHB5ENSETR_CRYP1EN BIT(4)
+#define RCC_MP_AHB5ENSETR_HASH1EN BIT(5)
+#define RCC_MP_AHB5ENSETR_RNG1EN BIT(6)
+#define RCC_MP_AHB5ENSETR_BKPSRAMEN BIT(8)
+#define RCC_MP_AHB5ENSETR_AXIMCEN BIT(16)
+
+/* RCC_MP_AHB5ENCLRR register fields */
+#define RCC_MP_AHB5ENCLRR_PKAEN BIT(2)
+#define RCC_MP_AHB5ENCLRR_SAESEN BIT(3)
+#define RCC_MP_AHB5ENCLRR_CRYP1EN BIT(4)
+#define RCC_MP_AHB5ENCLRR_HASH1EN BIT(5)
+#define RCC_MP_AHB5ENCLRR_RNG1EN BIT(6)
+#define RCC_MP_AHB5ENCLRR_BKPSRAMEN BIT(8)
+#define RCC_MP_AHB5ENCLRR_AXIMCEN BIT(16)
+
+/* RCC_MP_AHB6ENSETR register fields */
+#define RCC_MP_AHB6ENSETR_MCEEN BIT(1)
+#define RCC_MP_AHB6ENSETR_ETH1CKEN BIT(7)
+#define RCC_MP_AHB6ENSETR_ETH1TXEN BIT(8)
+#define RCC_MP_AHB6ENSETR_ETH1RXEN BIT(9)
+#define RCC_MP_AHB6ENSETR_ETH1MACEN BIT(10)
+#define RCC_MP_AHB6ENSETR_FMCEN BIT(12)
+#define RCC_MP_AHB6ENSETR_QSPIEN BIT(14)
+#define RCC_MP_AHB6ENSETR_SDMMC1EN BIT(16)
+#define RCC_MP_AHB6ENSETR_SDMMC2EN BIT(17)
+#define RCC_MP_AHB6ENSETR_CRC1EN BIT(20)
+#define RCC_MP_AHB6ENSETR_USBHEN BIT(24)
+#define RCC_MP_AHB6ENSETR_ETH2CKEN BIT(27)
+#define RCC_MP_AHB6ENSETR_ETH2TXEN BIT(28)
+#define RCC_MP_AHB6ENSETR_ETH2RXEN BIT(29)
+#define RCC_MP_AHB6ENSETR_ETH2MACEN BIT(30)
+
+/* RCC_MP_AHB6ENCLRR register fields */
+#define RCC_MP_AHB6ENCLRR_MCEEN BIT(1)
+#define RCC_MP_AHB6ENCLRR_ETH1CKEN BIT(7)
+#define RCC_MP_AHB6ENCLRR_ETH1TXEN BIT(8)
+#define RCC_MP_AHB6ENCLRR_ETH1RXEN BIT(9)
+#define RCC_MP_AHB6ENCLRR_ETH1MACEN BIT(10)
+#define RCC_MP_AHB6ENCLRR_FMCEN BIT(12)
+#define RCC_MP_AHB6ENCLRR_QSPIEN BIT(14)
+#define RCC_MP_AHB6ENCLRR_SDMMC1EN BIT(16)
+#define RCC_MP_AHB6ENCLRR_SDMMC2EN BIT(17)
+#define RCC_MP_AHB6ENCLRR_CRC1EN BIT(20)
+#define RCC_MP_AHB6ENCLRR_USBHEN BIT(24)
+#define RCC_MP_AHB6ENCLRR_ETH2CKEN BIT(27)
+#define RCC_MP_AHB6ENCLRR_ETH2TXEN BIT(28)
+#define RCC_MP_AHB6ENCLRR_ETH2RXEN BIT(29)
+#define RCC_MP_AHB6ENCLRR_ETH2MACEN BIT(30)
+
+/* RCC_MP_S_AHB6ENSETR register fields */
+#define RCC_MP_S_AHB6ENSETR_MDMAEN BIT(0)
+
+/* RCC_MP_S_AHB6ENCLRR register fields */
+#define RCC_MP_S_AHB6ENCLRR_MDMAEN BIT(0)
+
+/* RCC_MP_NS_AHB6ENSETR register fields */
+#define RCC_MP_NS_AHB6ENSETR_MDMAEN BIT(0)
+
+/* RCC_MP_NS_AHB6ENCLRR register fields */
+#define RCC_MP_NS_AHB6ENCLRR_MDMAEN BIT(0)
+
+/* RCC_MP_APB1LPENSETR register fields */
+#define RCC_MP_APB1LPENSETR_TIM2LPEN BIT(0)
+#define RCC_MP_APB1LPENSETR_TIM3LPEN BIT(1)
+#define RCC_MP_APB1LPENSETR_TIM4LPEN BIT(2)
+#define RCC_MP_APB1LPENSETR_TIM5LPEN BIT(3)
+#define RCC_MP_APB1LPENSETR_TIM6LPEN BIT(4)
+#define RCC_MP_APB1LPENSETR_TIM7LPEN BIT(5)
+#define RCC_MP_APB1LPENSETR_LPTIM1LPEN BIT(9)
+#define RCC_MP_APB1LPENSETR_SPI2LPEN BIT(11)
+#define RCC_MP_APB1LPENSETR_SPI3LPEN BIT(12)
+#define RCC_MP_APB1LPENSETR_USART3LPEN BIT(15)
+#define RCC_MP_APB1LPENSETR_UART4LPEN BIT(16)
+#define RCC_MP_APB1LPENSETR_UART5LPEN BIT(17)
+#define RCC_MP_APB1LPENSETR_UART7LPEN BIT(18)
+#define RCC_MP_APB1LPENSETR_UART8LPEN BIT(19)
+#define RCC_MP_APB1LPENSETR_I2C1LPEN BIT(21)
+#define RCC_MP_APB1LPENSETR_I2C2LPEN BIT(22)
+#define RCC_MP_APB1LPENSETR_SPDIFLPEN BIT(26)
+
+/* RCC_MP_APB1LPENCLRR register fields */
+#define RCC_MP_APB1LPENCLRR_TIM2LPEN BIT(0)
+#define RCC_MP_APB1LPENCLRR_TIM3LPEN BIT(1)
+#define RCC_MP_APB1LPENCLRR_TIM4LPEN BIT(2)
+#define RCC_MP_APB1LPENCLRR_TIM5LPEN BIT(3)
+#define RCC_MP_APB1LPENCLRR_TIM6LPEN BIT(4)
+#define RCC_MP_APB1LPENCLRR_TIM7LPEN BIT(5)
+#define RCC_MP_APB1LPENCLRR_LPTIM1LPEN BIT(9)
+#define RCC_MP_APB1LPENCLRR_SPI2LPEN BIT(11)
+#define RCC_MP_APB1LPENCLRR_SPI3LPEN BIT(12)
+#define RCC_MP_APB1LPENCLRR_USART3LPEN BIT(15)
+#define RCC_MP_APB1LPENCLRR_UART4LPEN BIT(16)
+#define RCC_MP_APB1LPENCLRR_UART5LPEN BIT(17)
+#define RCC_MP_APB1LPENCLRR_UART7LPEN BIT(18)
+#define RCC_MP_APB1LPENCLRR_UART8LPEN BIT(19)
+#define RCC_MP_APB1LPENCLRR_I2C1LPEN BIT(21)
+#define RCC_MP_APB1LPENCLRR_I2C2LPEN BIT(22)
+#define RCC_MP_APB1LPENCLRR_SPDIFLPEN BIT(26)
+
+/* RCC_MP_APB2LPENSETR register fields */
+#define RCC_MP_APB2LPENSETR_TIM1LPEN BIT(0)
+#define RCC_MP_APB2LPENSETR_TIM8LPEN BIT(1)
+#define RCC_MP_APB2LPENSETR_SPI1LPEN BIT(8)
+#define RCC_MP_APB2LPENSETR_USART6LPEN BIT(13)
+#define RCC_MP_APB2LPENSETR_SAI1LPEN BIT(16)
+#define RCC_MP_APB2LPENSETR_SAI2LPEN BIT(17)
+#define RCC_MP_APB2LPENSETR_DFSDMLPEN BIT(20)
+#define RCC_MP_APB2LPENSETR_ADFSDMLPEN BIT(21)
+#define RCC_MP_APB2LPENSETR_FDCANLPEN BIT(24)
+
+/* RCC_MP_APB2LPENCLRR register fields */
+#define RCC_MP_APB2LPENCLRR_TIM1LPEN BIT(0)
+#define RCC_MP_APB2LPENCLRR_TIM8LPEN BIT(1)
+#define RCC_MP_APB2LPENCLRR_SPI1LPEN BIT(8)
+#define RCC_MP_APB2LPENCLRR_USART6LPEN BIT(13)
+#define RCC_MP_APB2LPENCLRR_SAI1LPEN BIT(16)
+#define RCC_MP_APB2LPENCLRR_SAI2LPEN BIT(17)
+#define RCC_MP_APB2LPENCLRR_DFSDMLPEN BIT(20)
+#define RCC_MP_APB2LPENCLRR_ADFSDMLPEN BIT(21)
+#define RCC_MP_APB2LPENCLRR_FDCANLPEN BIT(24)
+
+/* RCC_MP_APB3LPENSETR register fields */
+#define RCC_MP_APB3LPENSETR_LPTIM2LPEN BIT(0)
+#define RCC_MP_APB3LPENSETR_LPTIM3LPEN BIT(1)
+#define RCC_MP_APB3LPENSETR_LPTIM4LPEN BIT(2)
+#define RCC_MP_APB3LPENSETR_LPTIM5LPEN BIT(3)
+#define RCC_MP_APB3LPENSETR_VREFLPEN BIT(13)
+#define RCC_MP_APB3LPENSETR_DTSLPEN BIT(16)
+#define RCC_MP_APB3LPENSETR_PMBCTRLLPEN BIT(17)
+
+/* RCC_MP_APB3LPENCLRR register fields */
+#define RCC_MP_APB3LPENCLRR_LPTIM2LPEN BIT(0)
+#define RCC_MP_APB3LPENCLRR_LPTIM3LPEN BIT(1)
+#define RCC_MP_APB3LPENCLRR_LPTIM4LPEN BIT(2)
+#define RCC_MP_APB3LPENCLRR_LPTIM5LPEN BIT(3)
+#define RCC_MP_APB3LPENCLRR_VREFLPEN BIT(13)
+#define RCC_MP_APB3LPENCLRR_DTSLPEN BIT(16)
+#define RCC_MP_APB3LPENCLRR_PMBCTRLLPEN BIT(17)
+
+/* RCC_MP_S_APB3LPENSETR register fields */
+#define RCC_MP_S_APB3LPENSETR_SYSCFGLPEN BIT(0)
+
+/* RCC_MP_S_APB3LPENCLRR register fields */
+#define RCC_MP_S_APB3LPENCLRR_SYSCFGLPEN BIT(0)
+
+/* RCC_MP_NS_APB3LPENSETR register fields */
+#define RCC_MP_NS_APB3LPENSETR_SYSCFGLPEN BIT(0)
+
+/* RCC_MP_NS_APB3LPENCLRR register fields */
+#define RCC_MP_NS_APB3LPENCLRR_SYSCFGLPEN BIT(0)
+
+/* RCC_MP_APB4LPENSETR register fields */
+#define RCC_MP_APB4LPENSETR_DCMIPPLPEN BIT(1)
+#define RCC_MP_APB4LPENSETR_DDRPERFMLPEN BIT(8)
+#define RCC_MP_APB4LPENSETR_IWDG2APBLPEN BIT(15)
+#define RCC_MP_APB4LPENSETR_USBPHYLPEN BIT(16)
+#define RCC_MP_APB4LPENSETR_STGENROLPEN BIT(20)
+#define RCC_MP_APB4LPENSETR_STGENROSTPEN BIT(21)
+
+/* RCC_MP_APB4LPENCLRR register fields */
+#define RCC_MP_APB4LPENCLRR_DCMIPPLPEN BIT(1)
+#define RCC_MP_APB4LPENCLRR_DDRPERFMLPEN BIT(8)
+#define RCC_MP_APB4LPENCLRR_IWDG2APBLPEN BIT(15)
+#define RCC_MP_APB4LPENCLRR_USBPHYLPEN BIT(16)
+#define RCC_MP_APB4LPENCLRR_STGENROLPEN BIT(20)
+#define RCC_MP_APB4LPENCLRR_STGENROSTPEN BIT(21)
+
+/* RCC_MP_S_APB4LPENSETR register fields */
+#define RCC_MP_S_APB4LPENSETR_LTDCLPEN BIT(0)
+
+/* RCC_MP_S_APB4LPENCLRR register fields */
+#define RCC_MP_S_APB4LPENCLRR_LTDCLPEN BIT(0)
+
+/* RCC_MP_NS_APB4LPENSETR register fields */
+#define RCC_MP_NS_APB4LPENSETR_LTDCLPEN BIT(0)
+
+/* RCC_MP_NS_APB4LPENCLRR register fields */
+#define RCC_MP_NS_APB4LPENCLRR_LTDCLPEN BIT(0)
+
+/* RCC_MP_APB5LPENSETR register fields */
+#define RCC_MP_APB5LPENSETR_RTCAPBLPEN BIT(8)
+#define RCC_MP_APB5LPENSETR_TZCLPEN BIT(11)
+#define RCC_MP_APB5LPENSETR_ETZPCLPEN BIT(13)
+#define RCC_MP_APB5LPENSETR_IWDG1APBLPEN BIT(15)
+#define RCC_MP_APB5LPENSETR_BSECLPEN BIT(16)
+#define RCC_MP_APB5LPENSETR_STGENCLPEN BIT(20)
+#define RCC_MP_APB5LPENSETR_STGENCSTPEN BIT(21)
+
+/* RCC_MP_APB5LPENCLRR register fields */
+#define RCC_MP_APB5LPENCLRR_RTCAPBLPEN BIT(8)
+#define RCC_MP_APB5LPENCLRR_TZCLPEN BIT(11)
+#define RCC_MP_APB5LPENCLRR_ETZPCLPEN BIT(13)
+#define RCC_MP_APB5LPENCLRR_IWDG1APBLPEN BIT(15)
+#define RCC_MP_APB5LPENCLRR_BSECLPEN BIT(16)
+#define RCC_MP_APB5LPENCLRR_STGENCLPEN BIT(20)
+#define RCC_MP_APB5LPENCLRR_STGENCSTPEN BIT(21)
+
+/* RCC_MP_APB6LPENSETR register fields */
+#define RCC_MP_APB6LPENSETR_USART1LPEN BIT(0)
+#define RCC_MP_APB6LPENSETR_USART2LPEN BIT(1)
+#define RCC_MP_APB6LPENSETR_SPI4LPEN BIT(2)
+#define RCC_MP_APB6LPENSETR_SPI5LPEN BIT(3)
+#define RCC_MP_APB6LPENSETR_I2C3LPEN BIT(4)
+#define RCC_MP_APB6LPENSETR_I2C4LPEN BIT(5)
+#define RCC_MP_APB6LPENSETR_I2C5LPEN BIT(6)
+#define RCC_MP_APB6LPENSETR_TIM12LPEN BIT(7)
+#define RCC_MP_APB6LPENSETR_TIM13LPEN BIT(8)
+#define RCC_MP_APB6LPENSETR_TIM14LPEN BIT(9)
+#define RCC_MP_APB6LPENSETR_TIM15LPEN BIT(10)
+#define RCC_MP_APB6LPENSETR_TIM16LPEN BIT(11)
+#define RCC_MP_APB6LPENSETR_TIM17LPEN BIT(12)
+
+/* RCC_MP_APB6LPENCLRR register fields */
+#define RCC_MP_APB6LPENCLRR_USART1LPEN BIT(0)
+#define RCC_MP_APB6LPENCLRR_USART2LPEN BIT(1)
+#define RCC_MP_APB6LPENCLRR_SPI4LPEN BIT(2)
+#define RCC_MP_APB6LPENCLRR_SPI5LPEN BIT(3)
+#define RCC_MP_APB6LPENCLRR_I2C3LPEN BIT(4)
+#define RCC_MP_APB6LPENCLRR_I2C4LPEN BIT(5)
+#define RCC_MP_APB6LPENCLRR_I2C5LPEN BIT(6)
+#define RCC_MP_APB6LPENCLRR_TIM12LPEN BIT(7)
+#define RCC_MP_APB6LPENCLRR_TIM13LPEN BIT(8)
+#define RCC_MP_APB6LPENCLRR_TIM14LPEN BIT(9)
+#define RCC_MP_APB6LPENCLRR_TIM15LPEN BIT(10)
+#define RCC_MP_APB6LPENCLRR_TIM16LPEN BIT(11)
+#define RCC_MP_APB6LPENCLRR_TIM17LPEN BIT(12)
+
+/* RCC_MP_AHB2LPENSETR register fields */
+#define RCC_MP_AHB2LPENSETR_DMA1LPEN BIT(0)
+#define RCC_MP_AHB2LPENSETR_DMA2LPEN BIT(1)
+#define RCC_MP_AHB2LPENSETR_DMAMUX1LPEN BIT(2)
+#define RCC_MP_AHB2LPENSETR_DMA3LPEN BIT(3)
+#define RCC_MP_AHB2LPENSETR_DMAMUX2LPEN BIT(4)
+#define RCC_MP_AHB2LPENSETR_ADC1LPEN BIT(5)
+#define RCC_MP_AHB2LPENSETR_ADC2LPEN BIT(6)
+#define RCC_MP_AHB2LPENSETR_USBOLPEN BIT(8)
+
+/* RCC_MP_AHB2LPENCLRR register fields */
+#define RCC_MP_AHB2LPENCLRR_DMA1LPEN BIT(0)
+#define RCC_MP_AHB2LPENCLRR_DMA2LPEN BIT(1)
+#define RCC_MP_AHB2LPENCLRR_DMAMUX1LPEN BIT(2)
+#define RCC_MP_AHB2LPENCLRR_DMA3LPEN BIT(3)
+#define RCC_MP_AHB2LPENCLRR_DMAMUX2LPEN BIT(4)
+#define RCC_MP_AHB2LPENCLRR_ADC1LPEN BIT(5)
+#define RCC_MP_AHB2LPENCLRR_ADC2LPEN BIT(6)
+#define RCC_MP_AHB2LPENCLRR_USBOLPEN BIT(8)
+
+/* RCC_MP_AHB4LPENSETR register fields */
+#define RCC_MP_AHB4LPENSETR_TSCLPEN BIT(15)
+
+/* RCC_MP_AHB4LPENCLRR register fields */
+#define RCC_MP_AHB4LPENCLRR_TSCLPEN BIT(15)
+
+/* RCC_MP_S_AHB4LPENSETR register fields */
+#define RCC_MP_S_AHB4LPENSETR_GPIOALPEN BIT(0)
+#define RCC_MP_S_AHB4LPENSETR_GPIOBLPEN BIT(1)
+#define RCC_MP_S_AHB4LPENSETR_GPIOCLPEN BIT(2)
+#define RCC_MP_S_AHB4LPENSETR_GPIODLPEN BIT(3)
+#define RCC_MP_S_AHB4LPENSETR_GPIOELPEN BIT(4)
+#define RCC_MP_S_AHB4LPENSETR_GPIOFLPEN BIT(5)
+#define RCC_MP_S_AHB4LPENSETR_GPIOGLPEN BIT(6)
+#define RCC_MP_S_AHB4LPENSETR_GPIOHLPEN BIT(7)
+#define RCC_MP_S_AHB4LPENSETR_GPIOILPEN BIT(8)
+
+/* RCC_MP_S_AHB4LPENCLRR register fields */
+#define RCC_MP_S_AHB4LPENCLRR_GPIOALPEN BIT(0)
+#define RCC_MP_S_AHB4LPENCLRR_GPIOBLPEN BIT(1)
+#define RCC_MP_S_AHB4LPENCLRR_GPIOCLPEN BIT(2)
+#define RCC_MP_S_AHB4LPENCLRR_GPIODLPEN BIT(3)
+#define RCC_MP_S_AHB4LPENCLRR_GPIOELPEN BIT(4)
+#define RCC_MP_S_AHB4LPENCLRR_GPIOFLPEN BIT(5)
+#define RCC_MP_S_AHB4LPENCLRR_GPIOGLPEN BIT(6)
+#define RCC_MP_S_AHB4LPENCLRR_GPIOHLPEN BIT(7)
+#define RCC_MP_S_AHB4LPENCLRR_GPIOILPEN BIT(8)
+
+/* RCC_MP_NS_AHB4LPENSETR register fields */
+#define RCC_MP_NS_AHB4LPENSETR_GPIOALPEN BIT(0)
+#define RCC_MP_NS_AHB4LPENSETR_GPIOBLPEN BIT(1)
+#define RCC_MP_NS_AHB4LPENSETR_GPIOCLPEN BIT(2)
+#define RCC_MP_NS_AHB4LPENSETR_GPIODLPEN BIT(3)
+#define RCC_MP_NS_AHB4LPENSETR_GPIOELPEN BIT(4)
+#define RCC_MP_NS_AHB4LPENSETR_GPIOFLPEN BIT(5)
+#define RCC_MP_NS_AHB4LPENSETR_GPIOGLPEN BIT(6)
+#define RCC_MP_NS_AHB4LPENSETR_GPIOHLPEN BIT(7)
+#define RCC_MP_NS_AHB4LPENSETR_GPIOILPEN BIT(8)
+
+/* RCC_MP_NS_AHB4LPENCLRR register fields */
+#define RCC_MP_NS_AHB4LPENCLRR_GPIOALPEN BIT(0)
+#define RCC_MP_NS_AHB4LPENCLRR_GPIOBLPEN BIT(1)
+#define RCC_MP_NS_AHB4LPENCLRR_GPIOCLPEN BIT(2)
+#define RCC_MP_NS_AHB4LPENCLRR_GPIODLPEN BIT(3)
+#define RCC_MP_NS_AHB4LPENCLRR_GPIOELPEN BIT(4)
+#define RCC_MP_NS_AHB4LPENCLRR_GPIOFLPEN BIT(5)
+#define RCC_MP_NS_AHB4LPENCLRR_GPIOGLPEN BIT(6)
+#define RCC_MP_NS_AHB4LPENCLRR_GPIOHLPEN BIT(7)
+#define RCC_MP_NS_AHB4LPENCLRR_GPIOILPEN BIT(8)
+
+/* RCC_MP_AHB5LPENSETR register fields */
+#define RCC_MP_AHB5LPENSETR_PKALPEN BIT(2)
+#define RCC_MP_AHB5LPENSETR_SAESLPEN BIT(3)
+#define RCC_MP_AHB5LPENSETR_CRYP1LPEN BIT(4)
+#define RCC_MP_AHB5LPENSETR_HASH1LPEN BIT(5)
+#define RCC_MP_AHB5LPENSETR_RNG1LPEN BIT(6)
+#define RCC_MP_AHB5LPENSETR_BKPSRAMLPEN BIT(8)
+
+/* RCC_MP_AHB5LPENCLRR register fields */
+#define RCC_MP_AHB5LPENCLRR_PKALPEN BIT(2)
+#define RCC_MP_AHB5LPENCLRR_SAESLPEN BIT(3)
+#define RCC_MP_AHB5LPENCLRR_CRYP1LPEN BIT(4)
+#define RCC_MP_AHB5LPENCLRR_HASH1LPEN BIT(5)
+#define RCC_MP_AHB5LPENCLRR_RNG1LPEN BIT(6)
+#define RCC_MP_AHB5LPENCLRR_BKPSRAMLPEN BIT(8)
+
+/* RCC_MP_AHB6LPENSETR register fields */
+#define RCC_MP_AHB6LPENSETR_MCELPEN BIT(1)
+#define RCC_MP_AHB6LPENSETR_ETH1CKLPEN BIT(7)
+#define RCC_MP_AHB6LPENSETR_ETH1TXLPEN BIT(8)
+#define RCC_MP_AHB6LPENSETR_ETH1RXLPEN BIT(9)
+#define RCC_MP_AHB6LPENSETR_ETH1MACLPEN BIT(10)
+#define RCC_MP_AHB6LPENSETR_ETH1STPEN BIT(11)
+#define RCC_MP_AHB6LPENSETR_FMCLPEN BIT(12)
+#define RCC_MP_AHB6LPENSETR_QSPILPEN BIT(14)
+#define RCC_MP_AHB6LPENSETR_SDMMC1LPEN BIT(16)
+#define RCC_MP_AHB6LPENSETR_SDMMC2LPEN BIT(17)
+#define RCC_MP_AHB6LPENSETR_CRC1LPEN BIT(20)
+#define RCC_MP_AHB6LPENSETR_USBHLPEN BIT(24)
+#define RCC_MP_AHB6LPENSETR_ETH2CKLPEN BIT(27)
+#define RCC_MP_AHB6LPENSETR_ETH2TXLPEN BIT(28)
+#define RCC_MP_AHB6LPENSETR_ETH2RXLPEN BIT(29)
+#define RCC_MP_AHB6LPENSETR_ETH2MACLPEN BIT(30)
+#define RCC_MP_AHB6LPENSETR_ETH2STPEN BIT(31)
+
+/* RCC_MP_AHB6LPENCLRR register fields */
+#define RCC_MP_AHB6LPENCLRR_MCELPEN BIT(1)
+#define RCC_MP_AHB6LPENCLRR_ETH1CKLPEN BIT(7)
+#define RCC_MP_AHB6LPENCLRR_ETH1TXLPEN BIT(8)
+#define RCC_MP_AHB6LPENCLRR_ETH1RXLPEN BIT(9)
+#define RCC_MP_AHB6LPENCLRR_ETH1MACLPEN BIT(10)
+#define RCC_MP_AHB6LPENCLRR_ETH1STPEN BIT(11)
+#define RCC_MP_AHB6LPENCLRR_FMCLPEN BIT(12)
+#define RCC_MP_AHB6LPENCLRR_QSPILPEN BIT(14)
+#define RCC_MP_AHB6LPENCLRR_SDMMC1LPEN BIT(16)
+#define RCC_MP_AHB6LPENCLRR_SDMMC2LPEN BIT(17)
+#define RCC_MP_AHB6LPENCLRR_CRC1LPEN BIT(20)
+#define RCC_MP_AHB6LPENCLRR_USBHLPEN BIT(24)
+#define RCC_MP_AHB6LPENCLRR_ETH2CKLPEN BIT(27)
+#define RCC_MP_AHB6LPENCLRR_ETH2TXLPEN BIT(28)
+#define RCC_MP_AHB6LPENCLRR_ETH2RXLPEN BIT(29)
+#define RCC_MP_AHB6LPENCLRR_ETH2MACLPEN BIT(30)
+#define RCC_MP_AHB6LPENCLRR_ETH2STPEN BIT(31)
+
+/* RCC_MP_S_AHB6LPENSETR register fields */
+#define RCC_MP_S_AHB6LPENSETR_MDMALPEN BIT(0)
+
+/* RCC_MP_S_AHB6LPENCLRR register fields */
+#define RCC_MP_S_AHB6LPENCLRR_MDMALPEN BIT(0)
+
+/* RCC_MP_NS_AHB6LPENSETR register fields */
+#define RCC_MP_NS_AHB6LPENSETR_MDMALPEN BIT(0)
+
+/* RCC_MP_NS_AHB6LPENCLRR register fields */
+#define RCC_MP_NS_AHB6LPENCLRR_MDMALPEN BIT(0)
+
+/* RCC_MP_S_AXIMLPENSETR register fields */
+#define RCC_MP_S_AXIMLPENSETR_SYSRAMLPEN BIT(0)
+
+/* RCC_MP_S_AXIMLPENCLRR register fields */
+#define RCC_MP_S_AXIMLPENCLRR_SYSRAMLPEN BIT(0)
+
+/* RCC_MP_NS_AXIMLPENSETR register fields */
+#define RCC_MP_NS_AXIMLPENSETR_SYSRAMLPEN BIT(0)
+
+/* RCC_MP_NS_AXIMLPENCLRR register fields */
+#define RCC_MP_NS_AXIMLPENCLRR_SYSRAMLPEN BIT(0)
+
+/* RCC_MP_MLAHBLPENSETR register fields */
+#define RCC_MP_MLAHBLPENSETR_SRAM1LPEN BIT(0)
+#define RCC_MP_MLAHBLPENSETR_SRAM2LPEN BIT(1)
+#define RCC_MP_MLAHBLPENSETR_SRAM3LPEN BIT(2)
+
+/* RCC_MP_MLAHBLPENCLRR register fields */
+#define RCC_MP_MLAHBLPENCLRR_SRAM1LPEN BIT(0)
+#define RCC_MP_MLAHBLPENCLRR_SRAM2LPEN BIT(1)
+#define RCC_MP_MLAHBLPENCLRR_SRAM3LPEN BIT(2)
+
+/* RCC_APB3SECSR register fields */
+#define RCC_APB3SECSR_LPTIM2SECF BIT(0)
+#define RCC_APB3SECSR_LPTIM3SECF BIT(1)
+#define RCC_APB3SECSR_VREFSECF BIT(13)
+
+/* RCC_APB4SECSR register fields */
+#define RCC_APB4SECSR_DCMIPPSECF BIT(1)
+#define RCC_APB4SECSR_USBPHYSECF BIT(16)
+
+/* RCC_APB5SECSR register fields */
+#define RCC_APB5SECSR_RTCSECF BIT(8)
+#define RCC_APB5SECSR_TZCSECF BIT(11)
+#define RCC_APB5SECSR_ETZPCSECF BIT(13)
+#define RCC_APB5SECSR_IWDG1SECF BIT(15)
+#define RCC_APB5SECSR_BSECSECF BIT(16)
+#define RCC_APB5SECSR_STGENCSECF_MASK GENMASK(21, 20)
+#define RCC_APB5SECSR_STGENCSECF_SHIFT 20
+
+/* RCC_APB6SECSR register fields */
+#define RCC_APB6SECSR_USART1SECF BIT(0)
+#define RCC_APB6SECSR_USART2SECF BIT(1)
+#define RCC_APB6SECSR_SPI4SECF BIT(2)
+#define RCC_APB6SECSR_SPI5SECF BIT(3)
+#define RCC_APB6SECSR_I2C3SECF BIT(4)
+#define RCC_APB6SECSR_I2C4SECF BIT(5)
+#define RCC_APB6SECSR_I2C5SECF BIT(6)
+#define RCC_APB6SECSR_TIM12SECF BIT(7)
+#define RCC_APB6SECSR_TIM13SECF BIT(8)
+#define RCC_APB6SECSR_TIM14SECF BIT(9)
+#define RCC_APB6SECSR_TIM15SECF BIT(10)
+#define RCC_APB6SECSR_TIM16SECF BIT(11)
+#define RCC_APB6SECSR_TIM17SECF BIT(12)
+
+/* RCC_AHB2SECSR register fields */
+#define RCC_AHB2SECSR_DMA3SECF BIT(3)
+#define RCC_AHB2SECSR_DMAMUX2SECF BIT(4)
+#define RCC_AHB2SECSR_ADC1SECF BIT(5)
+#define RCC_AHB2SECSR_ADC2SECF BIT(6)
+#define RCC_AHB2SECSR_USBOSECF BIT(8)
+
+/* RCC_AHB4SECSR register fields */
+#define RCC_AHB4SECSR_TSCSECF BIT(15)
+
+/* RCC_AHB5SECSR register fields */
+#define RCC_AHB5SECSR_PKASECF BIT(2)
+#define RCC_AHB5SECSR_SAESSECF BIT(3)
+#define RCC_AHB5SECSR_CRYP1SECF BIT(4)
+#define RCC_AHB5SECSR_HASH1SECF BIT(5)
+#define RCC_AHB5SECSR_RNG1SECF BIT(6)
+#define RCC_AHB5SECSR_BKPSRAMSECF BIT(8)
+
+/* RCC_AHB6SECSR register fields */
+#define RCC_AHB6SECSR_MCESECF BIT(1)
+#define RCC_AHB6SECSR_ETH1SECF_MASK GENMASK(11, 7)
+#define RCC_AHB6SECSR_ETH1SECF_SHIFT 7
+#define RCC_AHB6SECSR_FMCSECF BIT(12)
+#define RCC_AHB6SECSR_QSPISECF BIT(14)
+#define RCC_AHB6SECSR_SDMMC1SECF BIT(16)
+#define RCC_AHB6SECSR_SDMMC2SECF BIT(17)
+#define RCC_AHB6SECSR_ETH2SECF_MASK GENMASK(31, 27)
+#define RCC_AHB6SECSR_ETH2SECF_SHIFT 27
+
+/* RCC_VERR register fields */
+#define RCC_VERR_MINREV_MASK GENMASK(3, 0)
+#define RCC_VERR_MINREV_SHIFT 0
+#define RCC_VERR_MAJREV_MASK GENMASK(7, 4)
+#define RCC_VERR_MAJREV_SHIFT 4
+
+/* RCC_IDR register fields */
+#define RCC_IDR_ID_MASK GENMASK(31, 0)
+#define RCC_IDR_ID_SHIFT 0
+
+/* RCC_SIDR register fields */
+#define RCC_SIDR_SID_MASK GENMASK(31, 0)
+#define RCC_SIDR_SID_SHIFT 0
+
+/* Used for all RCC_PLL<n>CR registers */
+#define RCC_PLLNCR_PLLON BIT(0)
+#define RCC_PLLNCR_PLLRDY BIT(1)
+#define RCC_PLLNCR_SSCG_CTRL BIT(2)
+#define RCC_PLLNCR_DIVPEN BIT(4)
+#define RCC_PLLNCR_DIVQEN BIT(5)
+#define RCC_PLLNCR_DIVREN BIT(6)
+#define RCC_PLLNCR_DIVEN_SHIFT 4
+
+/* Used for all RCC_PLL<n>CFGR1 registers */
+#define RCC_PLLNCFGR1_DIVM_SHIFT 16
+#define RCC_PLLNCFGR1_DIVM_MASK GENMASK(21, 16)
+#define RCC_PLLNCFGR1_DIVN_SHIFT 0
+#define RCC_PLLNCFGR1_DIVN_MASK GENMASK(8, 0)
+
+/* Only for PLL3 and PLL4 */
+#define RCC_PLLNCFGR1_IFRGE_SHIFT 24
+#define RCC_PLLNCFGR1_IFRGE_MASK GENMASK(25, 24)
+
+/* Used for all RCC_PLL<n>CFGR2 registers */
+#define RCC_PLLNCFGR2_DIVX_MASK GENMASK(6, 0)
+#define RCC_PLLNCFGR2_DIVP_SHIFT 0
+#define RCC_PLLNCFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLLNCFGR2_DIVQ_SHIFT 8
+#define RCC_PLLNCFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLLNCFGR2_DIVR_SHIFT 16
+#define RCC_PLLNCFGR2_DIVR_MASK GENMASK(22, 16)
+
+/* Used for all RCC_PLL<n>FRACR registers */
+#define RCC_PLLNFRACR_FRACV_SHIFT 3
+#define RCC_PLLNFRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLLNFRACR_FRACLE BIT(16)
+
+/* Used for all RCC_PLL<n>CSGR registers */
+#define RCC_PLLNCSGR_INC_STEP_SHIFT 16
+#define RCC_PLLNCSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLLNCSGR_MOD_PER_SHIFT 0
+#define RCC_PLLNCSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLLNCSGR_SSCG_MODE_SHIFT 15
+#define RCC_PLLNCSGR_SSCG_MODE_MASK BIT(15)
+
+/* Used for most of RCC_<x>SELR registers */
+#define RCC_SELR_SRC_MASK GENMASK(2, 0)
+#define RCC_SELR_REFCLK_SRC_MASK GENMASK(1, 0)
+#define RCC_SELR_SRCRDY BIT(31)
+
+/* Values of RCC_MPCKSELR register */
+#define RCC_MPCKSELR_HSI 0x00000000
+#define RCC_MPCKSELR_HSE 0x00000001
+#define RCC_MPCKSELR_PLL 0x00000002
+#define RCC_MPCKSELR_PLL_MPUDIV 0x00000003
+
+/* Values of RCC_ASSCKSELR register */
+#define RCC_ASSCKSELR_HSI 0x00000000
+#define RCC_ASSCKSELR_HSE 0x00000001
+#define RCC_ASSCKSELR_PLL 0x00000002
+
+/* Values of RCC_MSSCKSELR register */
+#define RCC_MSSCKSELR_HSI 0x00000000
+#define RCC_MSSCKSELR_HSE 0x00000001
+#define RCC_MSSCKSELR_CSI 0x00000002
+#define RCC_MSSCKSELR_PLL 0x00000003
+
+/* Values of RCC_CPERCKSELR register */
+#define RCC_CPERCKSELR_HSI 0x00000000
+#define RCC_CPERCKSELR_CSI 0x00000001
+#define RCC_CPERCKSELR_HSE 0x00000002
+
+/* Used for most of DIVR register: max div for RTC */
+#define RCC_DIVR_DIV_MASK GENMASK(5, 0)
+#define RCC_DIVR_DIVRDY BIT(31)
+
+/* Masks for specific DIVR registers */
+#define RCC_APBXDIV_MASK GENMASK(2, 0)
+#define RCC_MPUDIV_MASK GENMASK(2, 0)
+#define RCC_AXIDIV_MASK GENMASK(2, 0)
+#define RCC_MLAHBDIV_MASK GENMASK(3, 0)
+
+/* Used for TIMER Prescaler */
+#define RCC_TIMGXPRER_TIMGXPRE BIT(0)
+
+/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */
+#define RCC_MP_ENCLRR_OFFSET U(4)
+
+/* Offset between RCC_xxxRSTSETR and RCC_xxxRSTCLRR registers */
+#define RCC_RSTCLRR_OFFSET U(4)
+
+/* RCC_OCENSETR register fields */
+#define RCC_OCENR_HSION BIT(0)
+#define RCC_OCENR_HSIKERON BIT(1)
+#define RCC_OCENR_CSION BIT(4)
+#define RCC_OCENR_CSIKERON BIT(5)
+#define RCC_OCENR_DIGBYP BIT(7)
+#define RCC_OCENR_HSEON BIT(8)
+#define RCC_OCENR_HSEKERON BIT(9)
+#define RCC_OCENR_HSEBYP BIT(10)
+#define RCC_OCENR_HSECSSON BIT(11)
+
+#define RCC_OCENR_DIGBYP_BIT 7
+#define RCC_OCENR_HSEBYP_BIT 10
+#define RCC_OCENR_HSECSSON_BIT 11
+
+/* Used for RCC_MCO related operations */
+#define RCC_MCOCFG_MCOON BIT(12)
+#define RCC_MCOCFG_MCODIV_MASK GENMASK(7, 4)
+#define RCC_MCOCFG_MCODIV_SHIFT 4
+#define RCC_MCOCFG_MCOSRC_MASK GENMASK(2, 0)
+
+#define RCC_UART4CKSELR_HSI 0x00000002
+
+#define RCC_CPERCKSELR_PERSRC_MASK GENMASK(1, 0)
+#define RCC_CPERCKSELR_PERSRC_SHIFT 0
+
+#define RCC_USBCKSELR_USBOSRC_MASK BIT(4)
+#define RCC_USBCKSELR_USBOSRC_SHIFT 4
+
+#define RCC_DDRITFCR_DDRCKMOD_SSR 0
+#define RCC_DDRITFCR_DDRCKMOD_ASR1 BIT(20)
+#define RCC_DDRITFCR_DDRCKMOD_HSR1 BIT(21)
+
+#define RCC_DDRITFCR_DDRC2EN BIT(0)
+#define RCC_DDRITFCR_DDRC2LPEN BIT(1)
+
+#define RCC_MP_CIFR_MASK U(0x110F1F)
+#define RCC_OFFSET_MASK GENMASK(11, 0)
+
+#endif /* STM32MP1_RCC_H */
diff --git a/include/drivers/st/stm32mp15_rcc.h b/include/drivers/st/stm32mp15_rcc.h
new file mode 100644
index 0000000..ddc0397
--- /dev/null
+++ b/include/drivers/st/stm32mp15_rcc.h
@@ -0,0 +1,2328 @@
+/*
+ * Copyright (c) 2015-2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_RCC_H
+#define STM32MP1_RCC_H
+
+#include <lib/utils_def.h>
+
+#define RCC_TZCR U(0x00)
+#define RCC_OCENSETR U(0x0C)
+#define RCC_OCENCLRR U(0x10)
+#define RCC_HSICFGR U(0x18)
+#define RCC_CSICFGR U(0x1C)
+#define RCC_MPCKSELR U(0x20)
+#define RCC_ASSCKSELR U(0x24)
+#define RCC_RCK12SELR U(0x28)
+#define RCC_MPCKDIVR U(0x2C)
+#define RCC_AXIDIVR U(0x30)
+#define RCC_APB4DIVR U(0x3C)
+#define RCC_APB5DIVR U(0x40)
+#define RCC_RTCDIVR U(0x44)
+#define RCC_MSSCKSELR U(0x48)
+#define RCC_PLL1CR U(0x80)
+#define RCC_PLL1CFGR1 U(0x84)
+#define RCC_PLL1CFGR2 U(0x88)
+#define RCC_PLL1FRACR U(0x8C)
+#define RCC_PLL1CSGR U(0x90)
+#define RCC_PLL2CR U(0x94)
+#define RCC_PLL2CFGR1 U(0x98)
+#define RCC_PLL2CFGR2 U(0x9C)
+#define RCC_PLL2FRACR U(0xA0)
+#define RCC_PLL2CSGR U(0xA4)
+#define RCC_I2C46CKSELR U(0xC0)
+#define RCC_SPI6CKSELR U(0xC4)
+#define RCC_UART1CKSELR U(0xC8)
+#define RCC_RNG1CKSELR U(0xCC)
+#define RCC_CPERCKSELR U(0xD0)
+#define RCC_STGENCKSELR U(0xD4)
+#define RCC_DDRITFCR U(0xD8)
+#define RCC_MP_BOOTCR U(0x100)
+#define RCC_MP_SREQSETR U(0x104)
+#define RCC_MP_SREQCLRR U(0x108)
+#define RCC_MP_GCR U(0x10C)
+#define RCC_MP_APRSTCR U(0x110)
+#define RCC_MP_APRSTSR U(0x114)
+#define RCC_BDCR U(0x140)
+#define RCC_RDLSICR U(0x144)
+#define RCC_APB4RSTSETR U(0x180)
+#define RCC_APB4RSTCLRR U(0x184)
+#define RCC_APB5RSTSETR U(0x188)
+#define RCC_APB5RSTCLRR U(0x18C)
+#define RCC_AHB5RSTSETR U(0x190)
+#define RCC_AHB5RSTCLRR U(0x194)
+#define RCC_AHB6RSTSETR U(0x198)
+#define RCC_AHB6RSTCLRR U(0x19C)
+#define RCC_TZAHB6RSTSETR U(0x1A0)
+#define RCC_TZAHB6RSTCLRR U(0x1A4)
+#define RCC_MP_APB4ENSETR U(0x200)
+#define RCC_MP_APB4ENCLRR U(0x204)
+#define RCC_MP_APB5ENSETR U(0x208)
+#define RCC_MP_APB5ENCLRR U(0x20C)
+#define RCC_MP_AHB5ENSETR U(0x210)
+#define RCC_MP_AHB5ENCLRR U(0x214)
+#define RCC_MP_AHB6ENSETR U(0x218)
+#define RCC_MP_AHB6ENCLRR U(0x21C)
+#define RCC_MP_TZAHB6ENSETR U(0x220)
+#define RCC_MP_TZAHB6ENCLRR U(0x224)
+#define RCC_MC_APB4ENSETR U(0x280)
+#define RCC_MC_APB4ENCLRR U(0x284)
+#define RCC_MC_APB5ENSETR U(0x288)
+#define RCC_MC_APB5ENCLRR U(0x28C)
+#define RCC_MC_AHB5ENSETR U(0x290)
+#define RCC_MC_AHB5ENCLRR U(0x294)
+#define RCC_MC_AHB6ENSETR U(0x298)
+#define RCC_MC_AHB6ENCLRR U(0x29C)
+#define RCC_MP_APB4LPENSETR U(0x300)
+#define RCC_MP_APB4LPENCLRR U(0x304)
+#define RCC_MP_APB5LPENSETR U(0x308)
+#define RCC_MP_APB5LPENCLRR U(0x30C)
+#define RCC_MP_AHB5LPENSETR U(0x310)
+#define RCC_MP_AHB5LPENCLRR U(0x314)
+#define RCC_MP_AHB6LPENSETR U(0x318)
+#define RCC_MP_AHB6LPENCLRR U(0x31C)
+#define RCC_MP_TZAHB6LPENSETR U(0x320)
+#define RCC_MP_TZAHB6LPENCLRR U(0x324)
+#define RCC_MC_APB4LPENSETR U(0x380)
+#define RCC_MC_APB4LPENCLRR U(0x384)
+#define RCC_MC_APB5LPENSETR U(0x388)
+#define RCC_MC_APB5LPENCLRR U(0x38C)
+#define RCC_MC_AHB5LPENSETR U(0x390)
+#define RCC_MC_AHB5LPENCLRR U(0x394)
+#define RCC_MC_AHB6LPENSETR U(0x398)
+#define RCC_MC_AHB6LPENCLRR U(0x39C)
+#define RCC_BR_RSTSCLRR U(0x400)
+#define RCC_MP_GRSTCSETR U(0x404)
+#define RCC_MP_RSTSCLRR U(0x408)
+#define RCC_MP_IWDGFZSETR U(0x40C)
+#define RCC_MP_IWDGFZCLRR U(0x410)
+#define RCC_MP_CIER U(0x414)
+#define RCC_MP_CIFR U(0x418)
+#define RCC_PWRLPDLYCR U(0x41C)
+#define RCC_MP_RSTSSETR U(0x420)
+#define RCC_MCO1CFGR U(0x800)
+#define RCC_MCO2CFGR U(0x804)
+#define RCC_OCRDYR U(0x808)
+#define RCC_DBGCFGR U(0x80C)
+#define RCC_RCK3SELR U(0x820)
+#define RCC_RCK4SELR U(0x824)
+#define RCC_TIMG1PRER U(0x828)
+#define RCC_TIMG2PRER U(0x82C)
+#define RCC_MCUDIVR U(0x830)
+#define RCC_APB1DIVR U(0x834)
+#define RCC_APB2DIVR U(0x838)
+#define RCC_APB3DIVR U(0x83C)
+#define RCC_PLL3CR U(0x880)
+#define RCC_PLL3CFGR1 U(0x884)
+#define RCC_PLL3CFGR2 U(0x888)
+#define RCC_PLL3FRACR U(0x88C)
+#define RCC_PLL3CSGR U(0x890)
+#define RCC_PLL4CR U(0x894)
+#define RCC_PLL4CFGR1 U(0x898)
+#define RCC_PLL4CFGR2 U(0x89C)
+#define RCC_PLL4FRACR U(0x8A0)
+#define RCC_PLL4CSGR U(0x8A4)
+#define RCC_I2C12CKSELR U(0x8C0)
+#define RCC_I2C35CKSELR U(0x8C4)
+#define RCC_SAI1CKSELR U(0x8C8)
+#define RCC_SAI2CKSELR U(0x8CC)
+#define RCC_SAI3CKSELR U(0x8D0)
+#define RCC_SAI4CKSELR U(0x8D4)
+#define RCC_SPI2S1CKSELR U(0x8D8)
+#define RCC_SPI2S23CKSELR U(0x8DC)
+#define RCC_SPI45CKSELR U(0x8E0)
+#define RCC_UART6CKSELR U(0x8E4)
+#define RCC_UART24CKSELR U(0x8E8)
+#define RCC_UART35CKSELR U(0x8EC)
+#define RCC_UART78CKSELR U(0x8F0)
+#define RCC_SDMMC12CKSELR U(0x8F4)
+#define RCC_SDMMC3CKSELR U(0x8F8)
+#define RCC_ETHCKSELR U(0x8FC)
+#define RCC_QSPICKSELR U(0x900)
+#define RCC_FMCCKSELR U(0x904)
+#define RCC_FDCANCKSELR U(0x90C)
+#define RCC_SPDIFCKSELR U(0x914)
+#define RCC_CECCKSELR U(0x918)
+#define RCC_USBCKSELR U(0x91C)
+#define RCC_RNG2CKSELR U(0x920)
+#define RCC_DSICKSELR U(0x924)
+#define RCC_ADCCKSELR U(0x928)
+#define RCC_LPTIM45CKSELR U(0x92C)
+#define RCC_LPTIM23CKSELR U(0x930)
+#define RCC_LPTIM1CKSELR U(0x934)
+#define RCC_APB1RSTSETR U(0x980)
+#define RCC_APB1RSTCLRR U(0x984)
+#define RCC_APB2RSTSETR U(0x988)
+#define RCC_APB2RSTCLRR U(0x98C)
+#define RCC_APB3RSTSETR U(0x990)
+#define RCC_APB3RSTCLRR U(0x994)
+#define RCC_AHB2RSTSETR U(0x998)
+#define RCC_AHB2RSTCLRR U(0x99C)
+#define RCC_AHB3RSTSETR U(0x9A0)
+#define RCC_AHB3RSTCLRR U(0x9A4)
+#define RCC_AHB4RSTSETR U(0x9A8)
+#define RCC_AHB4RSTCLRR U(0x9AC)
+#define RCC_MP_APB1ENSETR U(0xA00)
+#define RCC_MP_APB1ENCLRR U(0xA04)
+#define RCC_MP_APB2ENSETR U(0xA08)
+#define RCC_MP_APB2ENCLRR U(0xA0C)
+#define RCC_MP_APB3ENSETR U(0xA10)
+#define RCC_MP_APB3ENCLRR U(0xA14)
+#define RCC_MP_AHB2ENSETR U(0xA18)
+#define RCC_MP_AHB2ENCLRR U(0xA1C)
+#define RCC_MP_AHB3ENSETR U(0xA20)
+#define RCC_MP_AHB3ENCLRR U(0xA24)
+#define RCC_MP_AHB4ENSETR U(0xA28)
+#define RCC_MP_AHB4ENCLRR U(0xA2C)
+#define RCC_MP_MLAHBENSETR U(0xA38)
+#define RCC_MP_MLAHBENCLRR U(0xA3C)
+#define RCC_MC_APB1ENSETR U(0xA80)
+#define RCC_MC_APB1ENCLRR U(0xA84)
+#define RCC_MC_APB2ENSETR U(0xA88)
+#define RCC_MC_APB2ENCLRR U(0xA8C)
+#define RCC_MC_APB3ENSETR U(0xA90)
+#define RCC_MC_APB3ENCLRR U(0xA94)
+#define RCC_MC_AHB2ENSETR U(0xA98)
+#define RCC_MC_AHB2ENCLRR U(0xA9C)
+#define RCC_MC_AHB3ENSETR U(0xAA0)
+#define RCC_MC_AHB3ENCLRR U(0xAA4)
+#define RCC_MC_AHB4ENSETR U(0xAA8)
+#define RCC_MC_AHB4ENCLRR U(0xAAC)
+#define RCC_MC_AXIMENSETR U(0xAB0)
+#define RCC_MC_AXIMENCLRR U(0xAB4)
+#define RCC_MC_MLAHBENSETR U(0xAB8)
+#define RCC_MC_MLAHBENCLRR U(0xABC)
+#define RCC_MP_APB1LPENSETR U(0xB00)
+#define RCC_MP_APB1LPENCLRR U(0xB04)
+#define RCC_MP_APB2LPENSETR U(0xB08)
+#define RCC_MP_APB2LPENCLRR U(0xB0C)
+#define RCC_MP_APB3LPENSETR U(0xB10)
+#define RCC_MP_APB3LPENCLRR U(0xB14)
+#define RCC_MP_AHB2LPENSETR U(0xB18)
+#define RCC_MP_AHB2LPENCLRR U(0xB1C)
+#define RCC_MP_AHB3LPENSETR U(0xB20)
+#define RCC_MP_AHB3LPENCLRR U(0xB24)
+#define RCC_MP_AHB4LPENSETR U(0xB28)
+#define RCC_MP_AHB4LPENCLRR U(0xB2C)
+#define RCC_MP_AXIMLPENSETR U(0xB30)
+#define RCC_MP_AXIMLPENCLRR U(0xB34)
+#define RCC_MP_MLAHBLPENSETR U(0xB38)
+#define RCC_MP_MLAHBLPENCLRR U(0xB3C)
+#define RCC_MC_APB1LPENSETR U(0xB80)
+#define RCC_MC_APB1LPENCLRR U(0xB84)
+#define RCC_MC_APB2LPENSETR U(0xB88)
+#define RCC_MC_APB2LPENCLRR U(0xB8C)
+#define RCC_MC_APB3LPENSETR U(0xB90)
+#define RCC_MC_APB3LPENCLRR U(0xB94)
+#define RCC_MC_AHB2LPENSETR U(0xB98)
+#define RCC_MC_AHB2LPENCLRR U(0xB9C)
+#define RCC_MC_AHB3LPENSETR U(0xBA0)
+#define RCC_MC_AHB3LPENCLRR U(0xBA4)
+#define RCC_MC_AHB4LPENSETR U(0xBA8)
+#define RCC_MC_AHB4LPENCLRR U(0xBAC)
+#define RCC_MC_AXIMLPENSETR U(0xBB0)
+#define RCC_MC_AXIMLPENCLRR U(0xBB4)
+#define RCC_MC_MLAHBLPENSETR U(0xBB8)
+#define RCC_MC_MLAHBLPENCLRR U(0xBBC)
+#define RCC_MC_RSTSCLRR U(0xC00)
+#define RCC_MC_CIER U(0xC14)
+#define RCC_MC_CIFR U(0xC18)
+#define RCC_VERR U(0xFF4)
+#define RCC_IDR U(0xFF8)
+#define RCC_SIDR U(0xFFC)
+
+/* RCC_TZCR register fields */
+#define RCC_TZCR_TZEN BIT(0)
+#define RCC_TZCR_MCKPROT BIT(1)
+
+/* RCC_OCENSETR register fields */
+#define RCC_OCENSETR_HSION BIT(0)
+#define RCC_OCENSETR_HSIKERON BIT(1)
+#define RCC_OCENSETR_CSION BIT(4)
+#define RCC_OCENSETR_CSIKERON BIT(5)
+#define RCC_OCENSETR_DIGBYP BIT(7)
+#define RCC_OCENSETR_HSEON BIT(8)
+#define RCC_OCENSETR_HSEKERON BIT(9)
+#define RCC_OCENSETR_HSEBYP BIT(10)
+#define RCC_OCENSETR_HSECSSON BIT(11)
+
+/* RCC_OCENCLRR register fields */
+#define RCC_OCENCLRR_HSION BIT(0)
+#define RCC_OCENCLRR_HSIKERON BIT(1)
+#define RCC_OCENCLRR_CSION BIT(4)
+#define RCC_OCENCLRR_CSIKERON BIT(5)
+#define RCC_OCENCLRR_DIGBYP BIT(7)
+#define RCC_OCENCLRR_HSEON BIT(8)
+#define RCC_OCENCLRR_HSEKERON BIT(9)
+#define RCC_OCENCLRR_HSEBYP BIT(10)
+
+/* RCC_HSICFGR register fields */
+#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0)
+#define RCC_HSICFGR_HSIDIV_SHIFT 0
+#define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8)
+#define RCC_HSICFGR_HSITRIM_SHIFT 8
+#define RCC_HSICFGR_HSICAL_MASK GENMASK(24, 16)
+#define RCC_HSICFGR_HSICAL_SHIFT 16
+#define RCC_HSICFGR_HSICAL_TEMP_MASK GENMASK(27, 25)
+
+/* RCC_CSICFGR register fields */
+#define RCC_CSICFGR_CSITRIM_MASK GENMASK(12, 8)
+#define RCC_CSICFGR_CSITRIM_SHIFT 8
+#define RCC_CSICFGR_CSICAL_MASK GENMASK(23, 16)
+#define RCC_CSICFGR_CSICAL_SHIFT 16
+
+/* RCC_MPCKSELR register fields */
+#define RCC_MPCKSELR_HSI 0x00000000
+#define RCC_MPCKSELR_HSE 0x00000001
+#define RCC_MPCKSELR_PLL 0x00000002
+#define RCC_MPCKSELR_PLL_MPUDIV 0x00000003
+#define RCC_MPCKSELR_MPUSRC_MASK GENMASK(1, 0)
+#define RCC_MPCKSELR_MPUSRC_SHIFT 0
+#define RCC_MPCKSELR_MPUSRCRDY BIT(31)
+
+/* RCC_ASSCKSELR register fields */
+#define RCC_ASSCKSELR_HSI 0x00000000
+#define RCC_ASSCKSELR_HSE 0x00000001
+#define RCC_ASSCKSELR_PLL 0x00000002
+#define RCC_ASSCKSELR_AXISSRC_MASK GENMASK(2, 0)
+#define RCC_ASSCKSELR_AXISSRC_SHIFT 0
+#define RCC_ASSCKSELR_AXISSRCRDY BIT(31)
+
+/* RCC_RCK12SELR register fields */
+#define RCC_RCK12SELR_PLL12SRC_MASK GENMASK(1, 0)
+#define RCC_RCK12SELR_PLL12SRC_SHIFT 0
+#define RCC_RCK12SELR_PLL12SRCRDY BIT(31)
+
+/* RCC_MPCKDIVR register fields */
+#define RCC_MPCKDIVR_MPUDIV_MASK GENMASK(2, 0)
+#define RCC_MPCKDIVR_MPUDIV_SHIFT 0
+#define RCC_MPCKDIVR_MPUDIVRDY BIT(31)
+
+/* RCC_AXIDIVR register fields */
+#define RCC_AXIDIVR_AXIDIV_MASK GENMASK(2, 0)
+#define RCC_AXIDIVR_AXIDIV_SHIFT 0
+#define RCC_AXIDIVR_AXIDIVRDY BIT(31)
+
+/* RCC_APB4DIVR register fields */
+#define RCC_APB4DIVR_APB4DIV_MASK GENMASK(2, 0)
+#define RCC_APB4DIVR_APB4DIV_SHIFT 0
+#define RCC_APB4DIVR_APB4DIVRDY BIT(31)
+
+/* RCC_APB5DIVR register fields */
+#define RCC_APB5DIVR_APB5DIV_MASK GENMASK(2, 0)
+#define RCC_APB5DIVR_APB5DIV_SHIFT 0
+#define RCC_APB5DIVR_APB5DIVRDY BIT(31)
+
+/* RCC_RTCDIVR register fields */
+#define RCC_RTCDIVR_RTCDIV_MASK GENMASK(5, 0)
+#define RCC_RTCDIVR_RTCDIV_SHIFT 0
+
+/* RCC_MSSCKSELR register fields */
+#define RCC_MSSCKSELR_HSI 0x00000000
+#define RCC_MSSCKSELR_HSE 0x00000001
+#define RCC_MSSCKSELR_CSI 0x00000002
+#define RCC_MSSCKSELR_PLL 0x00000003
+#define RCC_MSSCKSELR_MCUSSRC_MASK GENMASK(1, 0)
+#define RCC_MSSCKSELR_MCUSSRC_SHIFT 0
+#define RCC_MSSCKSELR_MCUSSRCRDY BIT(31)
+
+/* RCC_PLL1CR register fields */
+#define RCC_PLL1CR_PLLON BIT(0)
+#define RCC_PLL1CR_PLL1RDY BIT(1)
+#define RCC_PLL1CR_SSCG_CTRL BIT(2)
+#define RCC_PLL1CR_DIVPEN BIT(4)
+#define RCC_PLL1CR_DIVQEN BIT(5)
+#define RCC_PLL1CR_DIVREN BIT(6)
+
+/* RCC_PLL1CFGR1 register fields */
+#define RCC_PLL1CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL1CFGR1_DIVN_SHIFT 0
+#define RCC_PLL1CFGR1_DIVM1_MASK GENMASK(21, 16)
+#define RCC_PLL1CFGR1_DIVM1_SHIFT 16
+
+/* RCC_PLL1CFGR2 register fields */
+#define RCC_PLL1CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL1CFGR2_DIVP_SHIFT 0
+#define RCC_PLL1CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL1CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL1CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL1CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL1FRACR register fields */
+#define RCC_PLL1FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL1FRACR_FRACV_SHIFT 3
+#define RCC_PLL1FRACR_FRACLE BIT(16)
+
+/* RCC_PLL1CSGR register fields */
+#define RCC_PLL1CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL1CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL1CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL1CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL1CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL1CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL1CSGR_INC_STEP_SHIFT 16
+
+/* RCC_PLL2CR register fields */
+#define RCC_PLL2CR_PLLON BIT(0)
+#define RCC_PLL2CR_PLL2RDY BIT(1)
+#define RCC_PLL2CR_SSCG_CTRL BIT(2)
+#define RCC_PLL2CR_DIVPEN BIT(4)
+#define RCC_PLL2CR_DIVQEN BIT(5)
+#define RCC_PLL2CR_DIVREN BIT(6)
+
+/* RCC_PLL2CFGR1 register fields */
+#define RCC_PLL2CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL2CFGR1_DIVN_SHIFT 0
+#define RCC_PLL2CFGR1_DIVM2_MASK GENMASK(21, 16)
+#define RCC_PLL2CFGR1_DIVM2_SHIFT 16
+
+/* RCC_PLL2CFGR2 register fields */
+#define RCC_PLL2CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL2CFGR2_DIVP_SHIFT 0
+#define RCC_PLL2CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL2CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL2CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL2CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL2FRACR register fields */
+#define RCC_PLL2FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL2FRACR_FRACV_SHIFT 3
+#define RCC_PLL2FRACR_FRACLE BIT(16)
+
+/* RCC_PLL2CSGR register fields */
+#define RCC_PLL2CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL2CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL2CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL2CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL2CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL2CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL2CSGR_INC_STEP_SHIFT 16
+
+/* RCC_I2C46CKSELR register fields */
+#define RCC_I2C46CKSELR_I2C46SRC_MASK GENMASK(2, 0)
+#define RCC_I2C46CKSELR_I2C46SRC_SHIFT 0
+
+/* RCC_SPI6CKSELR register fields */
+#define RCC_SPI6CKSELR_SPI6SRC_MASK GENMASK(2, 0)
+#define RCC_SPI6CKSELR_SPI6SRC_SHIFT 0
+
+/* RCC_UART1CKSELR register fields */
+#define RCC_UART1CKSELR_UART1SRC_MASK GENMASK(2, 0)
+#define RCC_UART1CKSELR_UART1SRC_SHIFT 0
+
+/* RCC_RNG1CKSELR register fields */
+#define RCC_RNG1CKSELR_RNG1SRC_MASK GENMASK(1, 0)
+#define RCC_RNG1CKSELR_RNG1SRC_SHIFT 0
+
+/* RCC_CPERCKSELR register fields */
+#define RCC_CPERCKSELR_HSI 0x00000000
+#define RCC_CPERCKSELR_CSI 0x00000001
+#define RCC_CPERCKSELR_HSE 0x00000002
+#define RCC_CPERCKSELR_CKPERSRC_MASK GENMASK(1, 0)
+#define RCC_CPERCKSELR_CKPERSRC_SHIFT 0
+
+/* RCC_STGENCKSELR register fields */
+#define RCC_STGENCKSELR_STGENSRC_MASK GENMASK(1, 0)
+#define RCC_STGENCKSELR_STGENSRC_SHIFT 0
+
+/* RCC_DDRITFCR register fields */
+#define RCC_DDRITFCR_DDRC1EN BIT(0)
+#define RCC_DDRITFCR_DDRC1LPEN BIT(1)
+#define RCC_DDRITFCR_DDRC2EN BIT(2)
+#define RCC_DDRITFCR_DDRC2LPEN BIT(3)
+#define RCC_DDRITFCR_DDRPHYCEN BIT(4)
+#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5)
+#define RCC_DDRITFCR_DDRCAPBEN BIT(6)
+#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7)
+#define RCC_DDRITFCR_AXIDCGEN BIT(8)
+#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9)
+#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10)
+#define RCC_DDRITFCR_KERDCG_DLY_MASK GENMASK(13, 11)
+#define RCC_DDRITFCR_KERDCG_DLY_SHIFT 11
+#define RCC_DDRITFCR_DDRCAPBRST BIT(14)
+#define RCC_DDRITFCR_DDRCAXIRST BIT(15)
+#define RCC_DDRITFCR_DDRCORERST BIT(16)
+#define RCC_DDRITFCR_DPHYAPBRST BIT(17)
+#define RCC_DDRITFCR_DPHYRST BIT(18)
+#define RCC_DDRITFCR_DPHYCTLRST BIT(19)
+#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20)
+#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20
+#define RCC_DDRITFCR_DDRCKMOD_SSR 0
+#define RCC_DDRITFCR_DDRCKMOD_ASR1 BIT(20)
+#define RCC_DDRITFCR_DDRCKMOD_HSR1 BIT(21)
+#define RCC_DDRITFCR_GSKPMOD BIT(23)
+#define RCC_DDRITFCR_GSKPCTRL BIT(24)
+#define RCC_DDRITFCR_DFILP_WIDTH_MASK GENMASK(27, 25)
+#define RCC_DDRITFCR_DFILP_WIDTH_SHIFT 25
+#define RCC_DDRITFCR_GSKP_DUR_MASK GENMASK(31, 28)
+#define RCC_DDRITFCR_GSKP_DUR_SHIFT 28
+
+/* RCC_MP_BOOTCR register fields */
+#define RCC_MP_BOOTCR_MCU_BEN BIT(0)
+#define RCC_MP_BOOTCR_MPU_BEN BIT(1)
+
+/* RCC_MP_SREQSETR register fields */
+#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0)
+#define RCC_MP_SREQSETR_STPREQ_P1 BIT(1)
+
+/* RCC_MP_SREQCLRR register fields */
+#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0)
+#define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1)
+
+/* RCC_MP_GCR register fields */
+#define RCC_MP_GCR_BOOT_MCU BIT(0)
+
+/* RCC_MP_APRSTCR register fields */
+#define RCC_MP_APRSTCR_RDCTLEN BIT(0)
+#define RCC_MP_APRSTCR_RSTTO_MASK GENMASK(14, 8)
+#define RCC_MP_APRSTCR_RSTTO_SHIFT 8
+
+/* RCC_MP_APRSTSR register fields */
+#define RCC_MP_APRSTSR_RSTTOV_MASK GENMASK(14, 8)
+#define RCC_MP_APRSTSR_RSTTOV_SHIFT 8
+
+/* RCC_BDCR register fields */
+#define RCC_BDCR_LSEON BIT(0)
+#define RCC_BDCR_LSEBYP BIT(1)
+#define RCC_BDCR_LSERDY BIT(2)
+#define RCC_BDCR_DIGBYP BIT(3)
+#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4)
+#define RCC_BDCR_LSEDRV_SHIFT 4
+#define RCC_BDCR_LSECSSON BIT(8)
+#define RCC_BDCR_LSECSSD BIT(9)
+#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16)
+#define RCC_BDCR_RTCSRC_SHIFT 16
+#define RCC_BDCR_RTCCKEN BIT(20)
+#define RCC_BDCR_VSWRST BIT(31)
+
+/* RCC_RDLSICR register fields */
+#define RCC_RDLSICR_LSION BIT(0)
+#define RCC_RDLSICR_LSIRDY BIT(1)
+#define RCC_RDLSICR_MRD_MASK GENMASK(20, 16)
+#define RCC_RDLSICR_MRD_SHIFT 16
+#define RCC_RDLSICR_EADLY_MASK GENMASK(26, 24)
+#define RCC_RDLSICR_EADLY_SHIFT 24
+#define RCC_RDLSICR_SPARE_MASK GENMASK(31, 27)
+#define RCC_RDLSICR_SPARE_SHIFT 27
+
+/* RCC_APB4RSTSETR register fields */
+#define RCC_APB4RSTSETR_LTDCRST BIT(0)
+#define RCC_APB4RSTSETR_DSIRST BIT(4)
+#define RCC_APB4RSTSETR_DDRPERFMRST BIT(8)
+#define RCC_APB4RSTSETR_USBPHYRST BIT(16)
+
+/* RCC_APB4RSTCLRR register fields */
+#define RCC_APB4RSTCLRR_LTDCRST BIT(0)
+#define RCC_APB4RSTCLRR_DSIRST BIT(4)
+#define RCC_APB4RSTCLRR_DDRPERFMRST BIT(8)
+#define RCC_APB4RSTCLRR_USBPHYRST BIT(16)
+
+/* RCC_APB5RSTSETR register fields */
+#define RCC_APB5RSTSETR_SPI6RST BIT(0)
+#define RCC_APB5RSTSETR_I2C4RST BIT(2)
+#define RCC_APB5RSTSETR_I2C6RST BIT(3)
+#define RCC_APB5RSTSETR_USART1RST BIT(4)
+#define RCC_APB5RSTSETR_STGENRST BIT(20)
+
+/* RCC_APB5RSTCLRR register fields */
+#define RCC_APB5RSTCLRR_SPI6RST BIT(0)
+#define RCC_APB5RSTCLRR_I2C4RST BIT(2)
+#define RCC_APB5RSTCLRR_I2C6RST BIT(3)
+#define RCC_APB5RSTCLRR_USART1RST BIT(4)
+#define RCC_APB5RSTCLRR_STGENRST BIT(20)
+
+/* RCC_AHB5RSTSETR register fields */
+#define RCC_AHB5RSTSETR_GPIOZRST BIT(0)
+#define RCC_AHB5RSTSETR_CRYP1RST BIT(4)
+#define RCC_AHB5RSTSETR_HASH1RST BIT(5)
+#define RCC_AHB5RSTSETR_RNG1RST BIT(6)
+#define RCC_AHB5RSTSETR_AXIMCRST BIT(16)
+
+/* RCC_AHB5RSTCLRR register fields */
+#define RCC_AHB5RSTCLRR_GPIOZRST BIT(0)
+#define RCC_AHB5RSTCLRR_CRYP1RST BIT(4)
+#define RCC_AHB5RSTCLRR_HASH1RST BIT(5)
+#define RCC_AHB5RSTCLRR_RNG1RST BIT(6)
+#define RCC_AHB5RSTCLRR_AXIMCRST BIT(16)
+
+/* RCC_AHB6RSTSETR register fields */
+#define RCC_AHB6RSTSETR_GPURST BIT(5)
+#define RCC_AHB6RSTSETR_ETHMACRST BIT(10)
+#define RCC_AHB6RSTSETR_FMCRST BIT(12)
+#define RCC_AHB6RSTSETR_QSPIRST BIT(14)
+#define RCC_AHB6RSTSETR_SDMMC1RST BIT(16)
+#define RCC_AHB6RSTSETR_SDMMC2RST BIT(17)
+#define RCC_AHB6RSTSETR_CRC1RST BIT(20)
+#define RCC_AHB6RSTSETR_USBHRST BIT(24)
+
+/* RCC_AHB6RSTCLRR register fields */
+#define RCC_AHB6RSTCLRR_ETHMACRST BIT(10)
+#define RCC_AHB6RSTCLRR_FMCRST BIT(12)
+#define RCC_AHB6RSTCLRR_QSPIRST BIT(14)
+#define RCC_AHB6RSTCLRR_SDMMC1RST BIT(16)
+#define RCC_AHB6RSTCLRR_SDMMC2RST BIT(17)
+#define RCC_AHB6RSTCLRR_CRC1RST BIT(20)
+#define RCC_AHB6RSTCLRR_USBHRST BIT(24)
+
+/* RCC_TZAHB6RSTSETR register fields */
+#define RCC_TZAHB6RSTSETR_MDMARST BIT(0)
+
+/* RCC_TZAHB6RSTCLRR register fields */
+#define RCC_TZAHB6RSTCLRR_MDMARST BIT(0)
+
+/* RCC_MP_APB4ENSETR register fields */
+#define RCC_MP_APB4ENSETR_LTDCEN BIT(0)
+#define RCC_MP_APB4ENSETR_DSIEN BIT(4)
+#define RCC_MP_APB4ENSETR_DDRPERFMEN BIT(8)
+#define RCC_MP_APB4ENSETR_IWDG2APBEN BIT(15)
+#define RCC_MP_APB4ENSETR_USBPHYEN BIT(16)
+#define RCC_MP_APB4ENSETR_STGENROEN BIT(20)
+
+/* RCC_MP_APB4ENCLRR register fields */
+#define RCC_MP_APB4ENCLRR_LTDCEN BIT(0)
+#define RCC_MP_APB4ENCLRR_DSIEN BIT(4)
+#define RCC_MP_APB4ENCLRR_DDRPERFMEN BIT(8)
+#define RCC_MP_APB4ENCLRR_IWDG2APBEN BIT(15)
+#define RCC_MP_APB4ENCLRR_USBPHYEN BIT(16)
+#define RCC_MP_APB4ENCLRR_STGENROEN BIT(20)
+
+/* RCC_MP_APB5ENSETR register fields */
+#define RCC_MP_APB5ENSETR_SPI6EN BIT(0)
+#define RCC_MP_APB5ENSETR_I2C4EN BIT(2)
+#define RCC_MP_APB5ENSETR_I2C6EN BIT(3)
+#define RCC_MP_APB5ENSETR_USART1EN BIT(4)
+#define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8)
+#define RCC_MP_APB5ENSETR_TZC1EN BIT(11)
+#define RCC_MP_APB5ENSETR_TZC2EN BIT(12)
+#define RCC_MP_APB5ENSETR_TZPCEN BIT(13)
+#define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15)
+#define RCC_MP_APB5ENSETR_BSECEN BIT(16)
+#define RCC_MP_APB5ENSETR_STGENEN BIT(20)
+
+/* RCC_MP_APB5ENCLRR register fields */
+#define RCC_MP_APB5ENCLRR_SPI6EN BIT(0)
+#define RCC_MP_APB5ENCLRR_I2C4EN BIT(2)
+#define RCC_MP_APB5ENCLRR_I2C6EN BIT(3)
+#define RCC_MP_APB5ENCLRR_USART1EN BIT(4)
+#define RCC_MP_APB5ENCLRR_RTCAPBEN BIT(8)
+#define RCC_MP_APB5ENCLRR_TZC1EN BIT(11)
+#define RCC_MP_APB5ENCLRR_TZC2EN BIT(12)
+#define RCC_MP_APB5ENCLRR_TZPCEN BIT(13)
+#define RCC_MP_APB5ENCLRR_IWDG1APBEN BIT(15)
+#define RCC_MP_APB5ENCLRR_BSECEN BIT(16)
+#define RCC_MP_APB5ENCLRR_STGENEN BIT(20)
+
+/* RCC_MP_AHB5ENSETR register fields */
+#define RCC_MP_AHB5ENSETR_GPIOZEN BIT(0)
+#define RCC_MP_AHB5ENSETR_CRYP1EN BIT(4)
+#define RCC_MP_AHB5ENSETR_HASH1EN BIT(5)
+#define RCC_MP_AHB5ENSETR_RNG1EN BIT(6)
+#define RCC_MP_AHB5ENSETR_BKPSRAMEN BIT(8)
+#define RCC_MP_AHB5ENSETR_AXIMCEN BIT(16)
+
+/* RCC_MP_AHB5ENCLRR register fields */
+#define RCC_MP_AHB5ENCLRR_GPIOZEN BIT(0)
+#define RCC_MP_AHB5ENCLRR_CRYP1EN BIT(4)
+#define RCC_MP_AHB5ENCLRR_HASH1EN BIT(5)
+#define RCC_MP_AHB5ENCLRR_RNG1EN BIT(6)
+#define RCC_MP_AHB5ENCLRR_BKPSRAMEN BIT(8)
+#define RCC_MP_AHB5ENCLRR_AXIMCEN BIT(16)
+
+/* RCC_MP_AHB6ENSETR register fields */
+#define RCC_MP_AHB6ENSETR_MDMAEN BIT(0)
+#define RCC_MP_AHB6ENSETR_GPUEN BIT(5)
+#define RCC_MP_AHB6ENSETR_ETHCKEN BIT(7)
+#define RCC_MP_AHB6ENSETR_ETHTXEN BIT(8)
+#define RCC_MP_AHB6ENSETR_ETHRXEN BIT(9)
+#define RCC_MP_AHB6ENSETR_ETHMACEN BIT(10)
+#define RCC_MP_AHB6ENSETR_FMCEN BIT(12)
+#define RCC_MP_AHB6ENSETR_QSPIEN BIT(14)
+#define RCC_MP_AHB6ENSETR_SDMMC1EN BIT(16)
+#define RCC_MP_AHB6ENSETR_SDMMC2EN BIT(17)
+#define RCC_MP_AHB6ENSETR_CRC1EN BIT(20)
+#define RCC_MP_AHB6ENSETR_USBHEN BIT(24)
+
+/* RCC_MP_AHB6ENCLRR register fields */
+#define RCC_MP_AHB6ENCLRR_MDMAEN BIT(0)
+#define RCC_MP_AHB6ENCLRR_GPUEN BIT(5)
+#define RCC_MP_AHB6ENCLRR_ETHCKEN BIT(7)
+#define RCC_MP_AHB6ENCLRR_ETHTXEN BIT(8)
+#define RCC_MP_AHB6ENCLRR_ETHRXEN BIT(9)
+#define RCC_MP_AHB6ENCLRR_ETHMACEN BIT(10)
+#define RCC_MP_AHB6ENCLRR_FMCEN BIT(12)
+#define RCC_MP_AHB6ENCLRR_QSPIEN BIT(14)
+#define RCC_MP_AHB6ENCLRR_SDMMC1EN BIT(16)
+#define RCC_MP_AHB6ENCLRR_SDMMC2EN BIT(17)
+#define RCC_MP_AHB6ENCLRR_CRC1EN BIT(20)
+#define RCC_MP_AHB6ENCLRR_USBHEN BIT(24)
+
+/* RCC_MP_TZAHB6ENSETR register fields */
+#define RCC_MP_TZAHB6ENSETR_MDMAEN BIT(0)
+
+/* RCC_MP_TZAHB6ENCLRR register fields */
+#define RCC_MP_TZAHB6ENCLRR_MDMAEN BIT(0)
+
+/* RCC_MC_APB4ENSETR register fields */
+#define RCC_MC_APB4ENSETR_LTDCEN BIT(0)
+#define RCC_MC_APB4ENSETR_DSIEN BIT(4)
+#define RCC_MC_APB4ENSETR_DDRPERFMEN BIT(8)
+#define RCC_MC_APB4ENSETR_USBPHYEN BIT(16)
+#define RCC_MC_APB4ENSETR_STGENROEN BIT(20)
+
+/* RCC_MC_APB4ENCLRR register fields */
+#define RCC_MC_APB4ENCLRR_LTDCEN BIT(0)
+#define RCC_MC_APB4ENCLRR_DSIEN BIT(4)
+#define RCC_MC_APB4ENCLRR_DDRPERFMEN BIT(8)
+#define RCC_MC_APB4ENCLRR_USBPHYEN BIT(16)
+#define RCC_MC_APB4ENCLRR_STGENROEN BIT(20)
+
+/* RCC_MC_APB5ENSETR register fields */
+#define RCC_MC_APB5ENSETR_SPI6EN BIT(0)
+#define RCC_MC_APB5ENSETR_I2C4EN BIT(2)
+#define RCC_MC_APB5ENSETR_I2C6EN BIT(3)
+#define RCC_MC_APB5ENSETR_USART1EN BIT(4)
+#define RCC_MC_APB5ENSETR_RTCAPBEN BIT(8)
+#define RCC_MC_APB5ENSETR_TZC1EN BIT(11)
+#define RCC_MC_APB5ENSETR_TZC2EN BIT(12)
+#define RCC_MC_APB5ENSETR_TZPCEN BIT(13)
+#define RCC_MC_APB5ENSETR_BSECEN BIT(16)
+#define RCC_MC_APB5ENSETR_STGENEN BIT(20)
+
+/* RCC_MC_APB5ENCLRR register fields */
+#define RCC_MC_APB5ENCLRR_SPI6EN BIT(0)
+#define RCC_MC_APB5ENCLRR_I2C4EN BIT(2)
+#define RCC_MC_APB5ENCLRR_I2C6EN BIT(3)
+#define RCC_MC_APB5ENCLRR_USART1EN BIT(4)
+#define RCC_MC_APB5ENCLRR_RTCAPBEN BIT(8)
+#define RCC_MC_APB5ENCLRR_TZC1EN BIT(11)
+#define RCC_MC_APB5ENCLRR_TZC2EN BIT(12)
+#define RCC_MC_APB5ENCLRR_TZPCEN BIT(13)
+#define RCC_MC_APB5ENCLRR_BSECEN BIT(16)
+#define RCC_MC_APB5ENCLRR_STGENEN BIT(20)
+
+/* RCC_MC_AHB5ENSETR register fields */
+#define RCC_MC_AHB5ENSETR_GPIOZEN BIT(0)
+#define RCC_MC_AHB5ENSETR_CRYP1EN BIT(4)
+#define RCC_MC_AHB5ENSETR_HASH1EN BIT(5)
+#define RCC_MC_AHB5ENSETR_RNG1EN BIT(6)
+#define RCC_MC_AHB5ENSETR_BKPSRAMEN BIT(8)
+
+/* RCC_MC_AHB5ENCLRR register fields */
+#define RCC_MC_AHB5ENCLRR_GPIOZEN BIT(0)
+#define RCC_MC_AHB5ENCLRR_CRYP1EN BIT(4)
+#define RCC_MC_AHB5ENCLRR_HASH1EN BIT(5)
+#define RCC_MC_AHB5ENCLRR_RNG1EN BIT(6)
+#define RCC_MC_AHB5ENCLRR_BKPSRAMEN BIT(8)
+
+/* RCC_MC_AHB6ENSETR register fields */
+#define RCC_MC_AHB6ENSETR_MDMAEN BIT(0)
+#define RCC_MC_AHB6ENSETR_GPUEN BIT(5)
+#define RCC_MC_AHB6ENSETR_ETHCKEN BIT(7)
+#define RCC_MC_AHB6ENSETR_ETHTXEN BIT(8)
+#define RCC_MC_AHB6ENSETR_ETHRXEN BIT(9)
+#define RCC_MC_AHB6ENSETR_ETHMACEN BIT(10)
+#define RCC_MC_AHB6ENSETR_FMCEN BIT(12)
+#define RCC_MC_AHB6ENSETR_QSPIEN BIT(14)
+#define RCC_MC_AHB6ENSETR_SDMMC1EN BIT(16)
+#define RCC_MC_AHB6ENSETR_SDMMC2EN BIT(17)
+#define RCC_MC_AHB6ENSETR_CRC1EN BIT(20)
+#define RCC_MC_AHB6ENSETR_USBHEN BIT(24)
+
+/* RCC_MC_AHB6ENCLRR register fields */
+#define RCC_MC_AHB6ENCLRR_MDMAEN BIT(0)
+#define RCC_MC_AHB6ENCLRR_GPUEN BIT(5)
+#define RCC_MC_AHB6ENCLRR_ETHCKEN BIT(7)
+#define RCC_MC_AHB6ENCLRR_ETHTXEN BIT(8)
+#define RCC_MC_AHB6ENCLRR_ETHRXEN BIT(9)
+#define RCC_MC_AHB6ENCLRR_ETHMACEN BIT(10)
+#define RCC_MC_AHB6ENCLRR_FMCEN BIT(12)
+#define RCC_MC_AHB6ENCLRR_QSPIEN BIT(14)
+#define RCC_MC_AHB6ENCLRR_SDMMC1EN BIT(16)
+#define RCC_MC_AHB6ENCLRR_SDMMC2EN BIT(17)
+#define RCC_MC_AHB6ENCLRR_CRC1EN BIT(20)
+#define RCC_MC_AHB6ENCLRR_USBHEN BIT(24)
+
+/* RCC_MP_APB4LPENSETR register fields */
+#define RCC_MP_APB4LPENSETR_LTDCLPEN BIT(0)
+#define RCC_MP_APB4LPENSETR_DSILPEN BIT(4)
+#define RCC_MP_APB4LPENSETR_DDRPERFMLPEN BIT(8)
+#define RCC_MP_APB4LPENSETR_IWDG2APBLPEN BIT(15)
+#define RCC_MP_APB4LPENSETR_USBPHYLPEN BIT(16)
+#define RCC_MP_APB4LPENSETR_STGENROLPEN BIT(20)
+#define RCC_MP_APB4LPENSETR_STGENROSTPEN BIT(21)
+
+/* RCC_MP_APB4LPENCLRR register fields */
+#define RCC_MP_APB4LPENCLRR_LTDCLPEN BIT(0)
+#define RCC_MP_APB4LPENCLRR_DSILPEN BIT(4)
+#define RCC_MP_APB4LPENCLRR_DDRPERFMLPEN BIT(8)
+#define RCC_MP_APB4LPENCLRR_IWDG2APBLPEN BIT(15)
+#define RCC_MP_APB4LPENCLRR_USBPHYLPEN BIT(16)
+#define RCC_MP_APB4LPENCLRR_STGENROLPEN BIT(20)
+#define RCC_MP_APB4LPENCLRR_STGENROSTPEN BIT(21)
+
+/* RCC_MP_APB5LPENSETR register fields */
+#define RCC_MP_APB5LPENSETR_SPI6LPEN BIT(0)
+#define RCC_MP_APB5LPENSETR_I2C4LPEN BIT(2)
+#define RCC_MP_APB5LPENSETR_I2C6LPEN BIT(3)
+#define RCC_MP_APB5LPENSETR_USART1LPEN BIT(4)
+#define RCC_MP_APB5LPENSETR_RTCAPBLPEN BIT(8)
+#define RCC_MP_APB5LPENSETR_TZC1LPEN BIT(11)
+#define RCC_MP_APB5LPENSETR_TZC2LPEN BIT(12)
+#define RCC_MP_APB5LPENSETR_TZPCLPEN BIT(13)
+#define RCC_MP_APB5LPENSETR_IWDG1APBLPEN BIT(15)
+#define RCC_MP_APB5LPENSETR_BSECLPEN BIT(16)
+#define RCC_MP_APB5LPENSETR_STGENLPEN BIT(20)
+#define RCC_MP_APB5LPENSETR_STGENSTPEN BIT(21)
+
+/* RCC_MP_APB5LPENCLRR register fields */
+#define RCC_MP_APB5LPENCLRR_SPI6LPEN BIT(0)
+#define RCC_MP_APB5LPENCLRR_I2C4LPEN BIT(2)
+#define RCC_MP_APB5LPENCLRR_I2C6LPEN BIT(3)
+#define RCC_MP_APB5LPENCLRR_USART1LPEN BIT(4)
+#define RCC_MP_APB5LPENCLRR_RTCAPBLPEN BIT(8)
+#define RCC_MP_APB5LPENCLRR_TZC1LPEN BIT(11)
+#define RCC_MP_APB5LPENCLRR_TZC2LPEN BIT(12)
+#define RCC_MP_APB5LPENCLRR_TZPCLPEN BIT(13)
+#define RCC_MP_APB5LPENCLRR_IWDG1APBLPEN BIT(15)
+#define RCC_MP_APB5LPENCLRR_BSECLPEN BIT(16)
+#define RCC_MP_APB5LPENCLRR_STGENLPEN BIT(20)
+#define RCC_MP_APB5LPENCLRR_STGENSTPEN BIT(21)
+
+/* RCC_MP_AHB5LPENSETR register fields */
+#define RCC_MP_AHB5LPENSETR_GPIOZLPEN BIT(0)
+#define RCC_MP_AHB5LPENSETR_CRYP1LPEN BIT(4)
+#define RCC_MP_AHB5LPENSETR_HASH1LPEN BIT(5)
+#define RCC_MP_AHB5LPENSETR_RNG1LPEN BIT(6)
+#define RCC_MP_AHB5LPENSETR_BKPSRAMLPEN BIT(8)
+
+/* RCC_MP_AHB5LPENCLRR register fields */
+#define RCC_MP_AHB5LPENCLRR_GPIOZLPEN BIT(0)
+#define RCC_MP_AHB5LPENCLRR_CRYP1LPEN BIT(4)
+#define RCC_MP_AHB5LPENCLRR_HASH1LPEN BIT(5)
+#define RCC_MP_AHB5LPENCLRR_RNG1LPEN BIT(6)
+#define RCC_MP_AHB5LPENCLRR_BKPSRAMLPEN BIT(8)
+
+/* RCC_MP_AHB6LPENSETR register fields */
+#define RCC_MP_AHB6LPENSETR_MDMALPEN BIT(0)
+#define RCC_MP_AHB6LPENSETR_GPULPEN BIT(5)
+#define RCC_MP_AHB6LPENSETR_ETHCKLPEN BIT(7)
+#define RCC_MP_AHB6LPENSETR_ETHTXLPEN BIT(8)
+#define RCC_MP_AHB6LPENSETR_ETHRXLPEN BIT(9)
+#define RCC_MP_AHB6LPENSETR_ETHMACLPEN BIT(10)
+#define RCC_MP_AHB6LPENSETR_ETHSTPEN BIT(11)
+#define RCC_MP_AHB6LPENSETR_FMCLPEN BIT(12)
+#define RCC_MP_AHB6LPENSETR_QSPILPEN BIT(14)
+#define RCC_MP_AHB6LPENSETR_SDMMC1LPEN BIT(16)
+#define RCC_MP_AHB6LPENSETR_SDMMC2LPEN BIT(17)
+#define RCC_MP_AHB6LPENSETR_CRC1LPEN BIT(20)
+#define RCC_MP_AHB6LPENSETR_USBHLPEN BIT(24)
+
+/* RCC_MP_AHB6LPENCLRR register fields */
+#define RCC_MP_AHB6LPENCLRR_MDMALPEN BIT(0)
+#define RCC_MP_AHB6LPENCLRR_GPULPEN BIT(5)
+#define RCC_MP_AHB6LPENCLRR_ETHCKLPEN BIT(7)
+#define RCC_MP_AHB6LPENCLRR_ETHTXLPEN BIT(8)
+#define RCC_MP_AHB6LPENCLRR_ETHRXLPEN BIT(9)
+#define RCC_MP_AHB6LPENCLRR_ETHMACLPEN BIT(10)
+#define RCC_MP_AHB6LPENCLRR_ETHSTPEN BIT(11)
+#define RCC_MP_AHB6LPENCLRR_FMCLPEN BIT(12)
+#define RCC_MP_AHB6LPENCLRR_QSPILPEN BIT(14)
+#define RCC_MP_AHB6LPENCLRR_SDMMC1LPEN BIT(16)
+#define RCC_MP_AHB6LPENCLRR_SDMMC2LPEN BIT(17)
+#define RCC_MP_AHB6LPENCLRR_CRC1LPEN BIT(20)
+#define RCC_MP_AHB6LPENCLRR_USBHLPEN BIT(24)
+
+/* RCC_MP_TZAHB6LPENSETR register fields */
+#define RCC_MP_TZAHB6LPENSETR_MDMALPEN BIT(0)
+
+/* RCC_MP_TZAHB6LPENCLRR register fields */
+#define RCC_MP_TZAHB6LPENCLRR_MDMALPEN BIT(0)
+
+/* RCC_MC_APB4LPENSETR register fields */
+#define RCC_MC_APB4LPENSETR_LTDCLPEN BIT(0)
+#define RCC_MC_APB4LPENSETR_DSILPEN BIT(4)
+#define RCC_MC_APB4LPENSETR_DDRPERFMLPEN BIT(8)
+#define RCC_MC_APB4LPENSETR_USBPHYLPEN BIT(16)
+#define RCC_MC_APB4LPENSETR_STGENROLPEN BIT(20)
+#define RCC_MC_APB4LPENSETR_STGENROSTPEN BIT(21)
+
+/* RCC_MC_APB4LPENCLRR register fields */
+#define RCC_MC_APB4LPENCLRR_LTDCLPEN BIT(0)
+#define RCC_MC_APB4LPENCLRR_DSILPEN BIT(4)
+#define RCC_MC_APB4LPENCLRR_DDRPERFMLPEN BIT(8)
+#define RCC_MC_APB4LPENCLRR_USBPHYLPEN BIT(16)
+#define RCC_MC_APB4LPENCLRR_STGENROLPEN BIT(20)
+#define RCC_MC_APB4LPENCLRR_STGENROSTPEN BIT(21)
+
+/* RCC_MC_APB5LPENSETR register fields */
+#define RCC_MC_APB5LPENSETR_SPI6LPEN BIT(0)
+#define RCC_MC_APB5LPENSETR_I2C4LPEN BIT(2)
+#define RCC_MC_APB5LPENSETR_I2C6LPEN BIT(3)
+#define RCC_MC_APB5LPENSETR_USART1LPEN BIT(4)
+#define RCC_MC_APB5LPENSETR_RTCAPBLPEN BIT(8)
+#define RCC_MC_APB5LPENSETR_TZC1LPEN BIT(11)
+#define RCC_MC_APB5LPENSETR_TZC2LPEN BIT(12)
+#define RCC_MC_APB5LPENSETR_TZPCLPEN BIT(13)
+#define RCC_MC_APB5LPENSETR_BSECLPEN BIT(16)
+#define RCC_MC_APB5LPENSETR_STGENLPEN BIT(20)
+#define RCC_MC_APB5LPENSETR_STGENSTPEN BIT(21)
+
+/* RCC_MC_APB5LPENCLRR register fields */
+#define RCC_MC_APB5LPENCLRR_SPI6LPEN BIT(0)
+#define RCC_MC_APB5LPENCLRR_I2C4LPEN BIT(2)
+#define RCC_MC_APB5LPENCLRR_I2C6LPEN BIT(3)
+#define RCC_MC_APB5LPENCLRR_USART1LPEN BIT(4)
+#define RCC_MC_APB5LPENCLRR_RTCAPBLPEN BIT(8)
+#define RCC_MC_APB5LPENCLRR_TZC1LPEN BIT(11)
+#define RCC_MC_APB5LPENCLRR_TZC2LPEN BIT(12)
+#define RCC_MC_APB5LPENCLRR_TZPCLPEN BIT(13)
+#define RCC_MC_APB5LPENCLRR_BSECLPEN BIT(16)
+#define RCC_MC_APB5LPENCLRR_STGENLPEN BIT(20)
+#define RCC_MC_APB5LPENCLRR_STGENSTPEN BIT(21)
+
+/* RCC_MC_AHB5LPENSETR register fields */
+#define RCC_MC_AHB5LPENSETR_GPIOZLPEN BIT(0)
+#define RCC_MC_AHB5LPENSETR_CRYP1LPEN BIT(4)
+#define RCC_MC_AHB5LPENSETR_HASH1LPEN BIT(5)
+#define RCC_MC_AHB5LPENSETR_RNG1LPEN BIT(6)
+#define RCC_MC_AHB5LPENSETR_BKPSRAMLPEN BIT(8)
+
+/* RCC_MC_AHB5LPENCLRR register fields */
+#define RCC_MC_AHB5LPENCLRR_GPIOZLPEN BIT(0)
+#define RCC_MC_AHB5LPENCLRR_CRYP1LPEN BIT(4)
+#define RCC_MC_AHB5LPENCLRR_HASH1LPEN BIT(5)
+#define RCC_MC_AHB5LPENCLRR_RNG1LPEN BIT(6)
+#define RCC_MC_AHB5LPENCLRR_BKPSRAMLPEN BIT(8)
+
+/* RCC_MC_AHB6LPENSETR register fields */
+#define RCC_MC_AHB6LPENSETR_MDMALPEN BIT(0)
+#define RCC_MC_AHB6LPENSETR_GPULPEN BIT(5)
+#define RCC_MC_AHB6LPENSETR_ETHCKLPEN BIT(7)
+#define RCC_MC_AHB6LPENSETR_ETHTXLPEN BIT(8)
+#define RCC_MC_AHB6LPENSETR_ETHRXLPEN BIT(9)
+#define RCC_MC_AHB6LPENSETR_ETHMACLPEN BIT(10)
+#define RCC_MC_AHB6LPENSETR_ETHSTPEN BIT(11)
+#define RCC_MC_AHB6LPENSETR_FMCLPEN BIT(12)
+#define RCC_MC_AHB6LPENSETR_QSPILPEN BIT(14)
+#define RCC_MC_AHB6LPENSETR_SDMMC1LPEN BIT(16)
+#define RCC_MC_AHB6LPENSETR_SDMMC2LPEN BIT(17)
+#define RCC_MC_AHB6LPENSETR_CRC1LPEN BIT(20)
+#define RCC_MC_AHB6LPENSETR_USBHLPEN BIT(24)
+
+/* RCC_MC_AHB6LPENCLRR register fields */
+#define RCC_MC_AHB6LPENCLRR_MDMALPEN BIT(0)
+#define RCC_MC_AHB6LPENCLRR_GPULPEN BIT(5)
+#define RCC_MC_AHB6LPENCLRR_ETHCKLPEN BIT(7)
+#define RCC_MC_AHB6LPENCLRR_ETHTXLPEN BIT(8)
+#define RCC_MC_AHB6LPENCLRR_ETHRXLPEN BIT(9)
+#define RCC_MC_AHB6LPENCLRR_ETHMACLPEN BIT(10)
+#define RCC_MC_AHB6LPENCLRR_ETHSTPEN BIT(11)
+#define RCC_MC_AHB6LPENCLRR_FMCLPEN BIT(12)
+#define RCC_MC_AHB6LPENCLRR_QSPILPEN BIT(14)
+#define RCC_MC_AHB6LPENCLRR_SDMMC1LPEN BIT(16)
+#define RCC_MC_AHB6LPENCLRR_SDMMC2LPEN BIT(17)
+#define RCC_MC_AHB6LPENCLRR_CRC1LPEN BIT(20)
+#define RCC_MC_AHB6LPENCLRR_USBHLPEN BIT(24)
+
+/* RCC_BR_RSTSCLRR register fields */
+#define RCC_BR_RSTSCLRR_PORRSTF BIT(0)
+#define RCC_BR_RSTSCLRR_BORRSTF BIT(1)
+#define RCC_BR_RSTSCLRR_PADRSTF BIT(2)
+#define RCC_BR_RSTSCLRR_HCSSRSTF BIT(3)
+#define RCC_BR_RSTSCLRR_VCORERSTF BIT(4)
+#define RCC_BR_RSTSCLRR_MPSYSRSTF BIT(6)
+#define RCC_BR_RSTSCLRR_MCSYSRSTF BIT(7)
+#define RCC_BR_RSTSCLRR_IWDG1RSTF BIT(8)
+#define RCC_BR_RSTSCLRR_IWDG2RSTF BIT(9)
+#define RCC_BR_RSTSCLRR_MPUP0RSTF BIT(13)
+#define RCC_BR_RSTSCLRR_MPUP1RSTF BIT(14)
+
+/* RCC_MP_GRSTCSETR register fields */
+#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0)
+#define RCC_MP_GRSTCSETR_MCURST BIT(1)
+#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4)
+#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5)
+
+/* RCC_MP_RSTSCLRR register fields */
+#define RCC_MP_RSTSCLRR_PORRSTF BIT(0)
+#define RCC_MP_RSTSCLRR_BORRSTF BIT(1)
+#define RCC_MP_RSTSCLRR_PADRSTF BIT(2)
+#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3)
+#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4)
+#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6)
+#define RCC_MP_RSTSCLRR_MCSYSRSTF BIT(7)
+#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8)
+#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9)
+#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11)
+#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12)
+#define RCC_MP_RSTSCLRR_MPUP0RSTF BIT(13)
+#define RCC_MP_RSTSCLRR_MPUP1RSTF BIT(14)
+#define RCC_MP_RSTSCLRR_SPARE BIT(15)
+
+/* RCC_MP_IWDGFZSETR register fields */
+#define RCC_MP_IWDGFZSETR_FZ_IWDG1 BIT(0)
+#define RCC_MP_IWDGFZSETR_FZ_IWDG2 BIT(1)
+
+/* RCC_MP_IWDGFZCLRR register fields */
+#define RCC_MP_IWDGFZCLRR_FZ_IWDG1 BIT(0)
+#define RCC_MP_IWDGFZCLRR_FZ_IWDG2 BIT(1)
+
+/* RCC_MP_CIER register fields */
+#define RCC_MP_CIER_LSIRDYIE BIT(0)
+#define RCC_MP_CIER_LSERDYIE BIT(1)
+#define RCC_MP_CIER_HSIRDYIE BIT(2)
+#define RCC_MP_CIER_HSERDYIE BIT(3)
+#define RCC_MP_CIER_CSIRDYIE BIT(4)
+#define RCC_MP_CIER_PLL1DYIE BIT(8)
+#define RCC_MP_CIER_PLL2DYIE BIT(9)
+#define RCC_MP_CIER_PLL3DYIE BIT(10)
+#define RCC_MP_CIER_PLL4DYIE BIT(11)
+#define RCC_MP_CIER_LSECSSIE BIT(16)
+#define RCC_MP_CIER_WKUPIE BIT(20)
+
+/* RCC_MP_CIFR register fields */
+#define RCC_MP_CIFR_MASK U(0x110F1F)
+#define RCC_MP_CIFR_LSIRDYF BIT(0)
+#define RCC_MP_CIFR_LSERDYF BIT(1)
+#define RCC_MP_CIFR_HSIRDYF BIT(2)
+#define RCC_MP_CIFR_HSERDYF BIT(3)
+#define RCC_MP_CIFR_CSIRDYF BIT(4)
+#define RCC_MP_CIFR_PLL1DYF BIT(8)
+#define RCC_MP_CIFR_PLL2DYF BIT(9)
+#define RCC_MP_CIFR_PLL3DYF BIT(10)
+#define RCC_MP_CIFR_PLL4DYF BIT(11)
+#define RCC_MP_CIFR_LSECSSF BIT(16)
+#define RCC_MP_CIFR_WKUPF BIT(20)
+
+/* RCC_PWRLPDLYCR register fields */
+#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK(21, 0)
+#define RCC_PWRLPDLYCR_PWRLP_DLY_SHIFT 0
+#define RCC_PWRLPDLYCR_MCTMPSKP BIT(24)
+
+/* RCC_MP_RSTSSETR register fields */
+#define RCC_MP_RSTSSETR_PORRSTF BIT(0)
+#define RCC_MP_RSTSSETR_BORRSTF BIT(1)
+#define RCC_MP_RSTSSETR_PADRSTF BIT(2)
+#define RCC_MP_RSTSSETR_HCSSRSTF BIT(3)
+#define RCC_MP_RSTSSETR_VCORERSTF BIT(4)
+#define RCC_MP_RSTSSETR_MPSYSRSTF BIT(6)
+#define RCC_MP_RSTSSETR_MCSYSRSTF BIT(7)
+#define RCC_MP_RSTSSETR_IWDG1RSTF BIT(8)
+#define RCC_MP_RSTSSETR_IWDG2RSTF BIT(9)
+#define RCC_MP_RSTSSETR_STDBYRSTF BIT(11)
+#define RCC_MP_RSTSSETR_CSTDBYRSTF BIT(12)
+#define RCC_MP_RSTSSETR_MPUP0RSTF BIT(13)
+#define RCC_MP_RSTSSETR_MPUP1RSTF BIT(14)
+#define RCC_MP_RSTSSETR_SPARE BIT(15)
+
+/* RCC_MCO1CFGR register fields */
+#define RCC_MCO1CFGR_MCO1SEL_MASK GENMASK(2, 0)
+#define RCC_MCO1CFGR_MCO1SEL_SHIFT 0
+#define RCC_MCO1CFGR_MCO1DIV_MASK GENMASK(7, 4)
+#define RCC_MCO1CFGR_MCO1DIV_SHIFT 4
+#define RCC_MCO1CFGR_MCO1ON BIT(12)
+
+/* RCC_MCO2CFGR register fields */
+#define RCC_MCO2CFGR_MCO2SEL_MASK GENMASK(2, 0)
+#define RCC_MCO2CFGR_MCO2SEL_SHIFT 0
+#define RCC_MCO2CFGR_MCO2DIV_MASK GENMASK(7, 4)
+#define RCC_MCO2CFGR_MCO2DIV_SHIFT 4
+#define RCC_MCO2CFGR_MCO2ON BIT(12)
+
+/* RCC_OCRDYR register fields */
+#define RCC_OCRDYR_HSIRDY BIT(0)
+#define RCC_OCRDYR_HSIDIVRDY BIT(2)
+#define RCC_OCRDYR_CSIRDY BIT(4)
+#define RCC_OCRDYR_HSERDY BIT(8)
+#define RCC_OCRDYR_MPUCKRDY BIT(23)
+#define RCC_OCRDYR_AXICKRDY BIT(24)
+#define RCC_OCRDYR_CKREST BIT(25)
+
+/* RCC_DBGCFGR register fields */
+#define RCC_DBGCFGR_TRACEDIV_MASK GENMASK(2, 0)
+#define RCC_DBGCFGR_TRACEDIV_SHIFT 0
+#define RCC_DBGCFGR_DBGCKEN BIT(8)
+#define RCC_DBGCFGR_TRACECKEN BIT(9)
+#define RCC_DBGCFGR_DBGRST BIT(12)
+
+/* RCC_RCK3SELR register fields */
+#define RCC_RCK3SELR_PLL3SRC_MASK GENMASK(1, 0)
+#define RCC_RCK3SELR_PLL3SRC_SHIFT 0
+#define RCC_RCK3SELR_PLL3SRCRDY BIT(31)
+
+/* RCC_RCK4SELR register fields */
+#define RCC_RCK4SELR_PLL4SRC_MASK GENMASK(1, 0)
+#define RCC_RCK4SELR_PLL4SRC_SHIFT 0
+#define RCC_RCK4SELR_PLL4SRCRDY BIT(31)
+
+/* RCC_TIMG1PRER register fields */
+#define RCC_TIMG1PRER_TIMG1PRE BIT(0)
+#define RCC_TIMG1PRER_TIMG1PRERDY BIT(31)
+
+/* RCC_TIMG2PRER register fields */
+#define RCC_TIMG2PRER_TIMG2PRE BIT(0)
+#define RCC_TIMG2PRER_TIMG2PRERDY BIT(31)
+
+/* RCC_MCUDIVR register fields */
+#define RCC_MCUDIVR_MCUDIV_MASK GENMASK(3, 0)
+#define RCC_MCUDIVR_MCUDIV_SHIFT 0
+#define RCC_MCUDIVR_MCUDIVRDY BIT(31)
+
+/* RCC_APB1DIVR register fields */
+#define RCC_APB1DIVR_APB1DIV_MASK GENMASK(2, 0)
+#define RCC_APB1DIVR_APB1DIV_SHIFT 0
+#define RCC_APB1DIVR_APB1DIVRDY BIT(31)
+
+/* RCC_APB2DIVR register fields */
+#define RCC_APB2DIVR_APB2DIV_MASK GENMASK(2, 0)
+#define RCC_APB2DIVR_APB2DIV_SHIFT 0
+#define RCC_APB2DIVR_APB2DIVRDY BIT(31)
+
+/* RCC_APB3DIVR register fields */
+#define RCC_APB3DIVR_APB3DIV_MASK GENMASK(2, 0)
+#define RCC_APB3DIVR_APB3DIV_SHIFT 0
+#define RCC_APB3DIVR_APB3DIVRDY BIT(31)
+
+/* RCC_PLL3CR register fields */
+#define RCC_PLL3CR_PLLON BIT(0)
+#define RCC_PLL3CR_PLL3RDY BIT(1)
+#define RCC_PLL3CR_SSCG_CTRL BIT(2)
+#define RCC_PLL3CR_DIVPEN BIT(4)
+#define RCC_PLL3CR_DIVQEN BIT(5)
+#define RCC_PLL3CR_DIVREN BIT(6)
+
+/* RCC_PLL3CFGR1 register fields */
+#define RCC_PLL3CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL3CFGR1_DIVN_SHIFT 0
+#define RCC_PLL3CFGR1_DIVM3_MASK GENMASK(21, 16)
+#define RCC_PLL3CFGR1_DIVM3_SHIFT 16
+#define RCC_PLL3CFGR1_IFRGE_MASK GENMASK(25, 24)
+#define RCC_PLL3CFGR1_IFRGE_SHIFT 24
+
+/* RCC_PLL3CFGR2 register fields */
+#define RCC_PLL3CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL3CFGR2_DIVP_SHIFT 0
+#define RCC_PLL3CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL3CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL3CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL3CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL3FRACR register fields */
+#define RCC_PLL3FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL3FRACR_FRACV_SHIFT 3
+#define RCC_PLL3FRACR_FRACLE BIT(16)
+
+/* RCC_PLL3CSGR register fields */
+#define RCC_PLL3CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL3CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL3CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL3CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL3CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL3CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL3CSGR_INC_STEP_SHIFT 16
+
+/* RCC_PLL4CR register fields */
+#define RCC_PLL4CR_PLLON BIT(0)
+#define RCC_PLL4CR_PLL4RDY BIT(1)
+#define RCC_PLL4CR_SSCG_CTRL BIT(2)
+#define RCC_PLL4CR_DIVPEN BIT(4)
+#define RCC_PLL4CR_DIVQEN BIT(5)
+#define RCC_PLL4CR_DIVREN BIT(6)
+
+/* RCC_PLL4CFGR1 register fields */
+#define RCC_PLL4CFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLL4CFGR1_DIVN_SHIFT 0
+#define RCC_PLL4CFGR1_DIVM4_MASK GENMASK(21, 16)
+#define RCC_PLL4CFGR1_DIVM4_SHIFT 16
+#define RCC_PLL4CFGR1_IFRGE_MASK GENMASK(25, 24)
+#define RCC_PLL4CFGR1_IFRGE_SHIFT 24
+
+/* RCC_PLL4CFGR2 register fields */
+#define RCC_PLL4CFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLL4CFGR2_DIVP_SHIFT 0
+#define RCC_PLL4CFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLL4CFGR2_DIVQ_SHIFT 8
+#define RCC_PLL4CFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLL4CFGR2_DIVR_SHIFT 16
+
+/* RCC_PLL4FRACR register fields */
+#define RCC_PLL4FRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLL4FRACR_FRACV_SHIFT 3
+#define RCC_PLL4FRACR_FRACLE BIT(16)
+
+/* RCC_PLL4CSGR register fields */
+#define RCC_PLL4CSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLL4CSGR_MOD_PER_SHIFT 0
+#define RCC_PLL4CSGR_TPDFN_DIS BIT(13)
+#define RCC_PLL4CSGR_RPDFN_DIS BIT(14)
+#define RCC_PLL4CSGR_SSCG_MODE BIT(15)
+#define RCC_PLL4CSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLL4CSGR_INC_STEP_SHIFT 16
+
+/* RCC_I2C12CKSELR register fields */
+#define RCC_I2C12CKSELR_I2C12SRC_MASK GENMASK(2, 0)
+#define RCC_I2C12CKSELR_I2C12SRC_SHIFT 0
+
+/* RCC_I2C35CKSELR register fields */
+#define RCC_I2C35CKSELR_I2C35SRC_MASK GENMASK(2, 0)
+#define RCC_I2C35CKSELR_I2C35SRC_SHIFT 0
+
+/* RCC_SAI1CKSELR register fields */
+#define RCC_SAI1CKSELR_SAI1SRC_MASK GENMASK(2, 0)
+#define RCC_SAI1CKSELR_SAI1SRC_SHIFT 0
+
+/* RCC_SAI2CKSELR register fields */
+#define RCC_SAI2CKSELR_SAI2SRC_MASK GENMASK(2, 0)
+#define RCC_SAI2CKSELR_SAI2SRC_SHIFT 0
+
+/* RCC_SAI3CKSELR register fields */
+#define RCC_SAI3CKSELR_SAI3SRC_MASK GENMASK(2, 0)
+#define RCC_SAI3CKSELR_SAI3SRC_SHIFT 0
+
+/* RCC_SAI4CKSELR register fields */
+#define RCC_SAI4CKSELR_SAI4SRC_MASK GENMASK(2, 0)
+#define RCC_SAI4CKSELR_SAI4SRC_SHIFT 0
+
+/* RCC_SPI2S1CKSELR register fields */
+#define RCC_SPI2S1CKSELR_SPI1SRC_MASK GENMASK(2, 0)
+#define RCC_SPI2S1CKSELR_SPI1SRC_SHIFT 0
+
+/* RCC_SPI2S23CKSELR register fields */
+#define RCC_SPI2S23CKSELR_SPI23SRC_MASK GENMASK(2, 0)
+#define RCC_SPI2S23CKSELR_SPI23SRC_SHIFT 0
+
+/* RCC_SPI45CKSELR register fields */
+#define RCC_SPI45CKSELR_SPI45SRC_MASK GENMASK(2, 0)
+#define RCC_SPI45CKSELR_SPI45SRC_SHIFT 0
+
+/* RCC_UART6CKSELR register fields */
+#define RCC_UART6CKSELR_UART6SRC_MASK GENMASK(2, 0)
+#define RCC_UART6CKSELR_UART6SRC_SHIFT 0
+
+/* RCC_UART24CKSELR register fields */
+#define RCC_UART24CKSELR_HSI 0x00000002
+#define RCC_UART24CKSELR_UART24SRC_MASK GENMASK(2, 0)
+#define RCC_UART24CKSELR_UART24SRC_SHIFT 0
+
+/* RCC_UART35CKSELR register fields */
+#define RCC_UART35CKSELR_UART35SRC_MASK GENMASK(2, 0)
+#define RCC_UART35CKSELR_UART35SRC_SHIFT 0
+
+/* RCC_UART78CKSELR register fields */
+#define RCC_UART78CKSELR_UART78SRC_MASK GENMASK(2, 0)
+#define RCC_UART78CKSELR_UART78SRC_SHIFT 0
+
+/* RCC_SDMMC12CKSELR register fields */
+#define RCC_SDMMC12CKSELR_SDMMC12SRC_MASK GENMASK(2, 0)
+#define RCC_SDMMC12CKSELR_SDMMC12SRC_SHIFT 0
+
+/* RCC_SDMMC3CKSELR register fields */
+#define RCC_SDMMC3CKSELR_SDMMC3SRC_MASK GENMASK(2, 0)
+#define RCC_SDMMC3CKSELR_SDMMC3SRC_SHIFT 0
+
+/* RCC_ETHCKSELR register fields */
+#define RCC_ETHCKSELR_ETHSRC_MASK GENMASK(1, 0)
+#define RCC_ETHCKSELR_ETHSRC_SHIFT 0
+#define RCC_ETHCKSELR_ETHPTPDIV_MASK GENMASK(7, 4)
+#define RCC_ETHCKSELR_ETHPTPDIV_SHIFT 4
+
+/* RCC_QSPICKSELR register fields */
+#define RCC_QSPICKSELR_QSPISRC_MASK GENMASK(1, 0)
+#define RCC_QSPICKSELR_QSPISRC_SHIFT 0
+
+/* RCC_FMCCKSELR register fields */
+#define RCC_FMCCKSELR_FMCSRC_MASK GENMASK(1, 0)
+#define RCC_FMCCKSELR_FMCSRC_SHIFT 0
+
+/* RCC_FDCANCKSELR register fields */
+#define RCC_FDCANCKSELR_FDCANSRC_MASK GENMASK(1, 0)
+#define RCC_FDCANCKSELR_FDCANSRC_SHIFT 0
+
+/* RCC_SPDIFCKSELR register fields */
+#define RCC_SPDIFCKSELR_SPDIFSRC_MASK GENMASK(1, 0)
+#define RCC_SPDIFCKSELR_SPDIFSRC_SHIFT 0
+
+/* RCC_CECCKSELR register fields */
+#define RCC_CECCKSELR_CECSRC_MASK GENMASK(1, 0)
+#define RCC_CECCKSELR_CECSRC_SHIFT 0
+
+/* RCC_USBCKSELR register fields */
+#define RCC_USBCKSELR_USBPHYSRC_MASK GENMASK(1, 0)
+#define RCC_USBCKSELR_USBPHYSRC_SHIFT 0
+#define RCC_USBCKSELR_USBOSRC BIT(4)
+#define RCC_USBCKSELR_USBOSRC_MASK BIT(4)
+#define RCC_USBCKSELR_USBOSRC_SHIFT 4
+
+/* RCC_RNG2CKSELR register fields */
+#define RCC_RNG2CKSELR_RNG2SRC_MASK GENMASK(1, 0)
+#define RCC_RNG2CKSELR_RNG2SRC_SHIFT 0
+
+/* RCC_DSICKSELR register fields */
+#define RCC_DSICKSELR_DSISRC BIT(0)
+
+/* RCC_ADCCKSELR register fields */
+#define RCC_ADCCKSELR_ADCSRC_MASK GENMASK(1, 0)
+#define RCC_ADCCKSELR_ADCSRC_SHIFT 0
+
+/* RCC_LPTIM45CKSELR register fields */
+#define RCC_LPTIM45CKSELR_LPTIM45SRC_MASK GENMASK(2, 0)
+#define RCC_LPTIM45CKSELR_LPTIM45SRC_SHIFT 0
+
+/* RCC_LPTIM23CKSELR register fields */
+#define RCC_LPTIM23CKSELR_LPTIM23SRC_MASK GENMASK(2, 0)
+#define RCC_LPTIM23CKSELR_LPTIM23SRC_SHIFT 0
+
+/* RCC_LPTIM1CKSELR register fields */
+#define RCC_LPTIM1CKSELR_LPTIM1SRC_MASK GENMASK(2, 0)
+#define RCC_LPTIM1CKSELR_LPTIM1SRC_SHIFT 0
+
+/* RCC_APB1RSTSETR register fields */
+#define RCC_APB1RSTSETR_TIM2RST BIT(0)
+#define RCC_APB1RSTSETR_TIM3RST BIT(1)
+#define RCC_APB1RSTSETR_TIM4RST BIT(2)
+#define RCC_APB1RSTSETR_TIM5RST BIT(3)
+#define RCC_APB1RSTSETR_TIM6RST BIT(4)
+#define RCC_APB1RSTSETR_TIM7RST BIT(5)
+#define RCC_APB1RSTSETR_TIM12RST BIT(6)
+#define RCC_APB1RSTSETR_TIM13RST BIT(7)
+#define RCC_APB1RSTSETR_TIM14RST BIT(8)
+#define RCC_APB1RSTSETR_LPTIM1RST BIT(9)
+#define RCC_APB1RSTSETR_SPI2RST BIT(11)
+#define RCC_APB1RSTSETR_SPI3RST BIT(12)
+#define RCC_APB1RSTSETR_USART2RST BIT(14)
+#define RCC_APB1RSTSETR_USART3RST BIT(15)
+#define RCC_APB1RSTSETR_UART4RST BIT(16)
+#define RCC_APB1RSTSETR_UART5RST BIT(17)
+#define RCC_APB1RSTSETR_UART7RST BIT(18)
+#define RCC_APB1RSTSETR_UART8RST BIT(19)
+#define RCC_APB1RSTSETR_I2C1RST BIT(21)
+#define RCC_APB1RSTSETR_I2C2RST BIT(22)
+#define RCC_APB1RSTSETR_I2C3RST BIT(23)
+#define RCC_APB1RSTSETR_I2C5RST BIT(24)
+#define RCC_APB1RSTSETR_SPDIFRST BIT(26)
+#define RCC_APB1RSTSETR_CECRST BIT(27)
+#define RCC_APB1RSTSETR_DAC12RST BIT(29)
+#define RCC_APB1RSTSETR_MDIOSRST BIT(31)
+
+/* RCC_APB1RSTCLRR register fields */
+#define RCC_APB1RSTCLRR_TIM2RST BIT(0)
+#define RCC_APB1RSTCLRR_TIM3RST BIT(1)
+#define RCC_APB1RSTCLRR_TIM4RST BIT(2)
+#define RCC_APB1RSTCLRR_TIM5RST BIT(3)
+#define RCC_APB1RSTCLRR_TIM6RST BIT(4)
+#define RCC_APB1RSTCLRR_TIM7RST BIT(5)
+#define RCC_APB1RSTCLRR_TIM12RST BIT(6)
+#define RCC_APB1RSTCLRR_TIM13RST BIT(7)
+#define RCC_APB1RSTCLRR_TIM14RST BIT(8)
+#define RCC_APB1RSTCLRR_LPTIM1RST BIT(9)
+#define RCC_APB1RSTCLRR_SPI2RST BIT(11)
+#define RCC_APB1RSTCLRR_SPI3RST BIT(12)
+#define RCC_APB1RSTCLRR_USART2RST BIT(14)
+#define RCC_APB1RSTCLRR_USART3RST BIT(15)
+#define RCC_APB1RSTCLRR_UART4RST BIT(16)
+#define RCC_APB1RSTCLRR_UART5RST BIT(17)
+#define RCC_APB1RSTCLRR_UART7RST BIT(18)
+#define RCC_APB1RSTCLRR_UART8RST BIT(19)
+#define RCC_APB1RSTCLRR_I2C1RST BIT(21)
+#define RCC_APB1RSTCLRR_I2C2RST BIT(22)
+#define RCC_APB1RSTCLRR_I2C3RST BIT(23)
+#define RCC_APB1RSTCLRR_I2C5RST BIT(24)
+#define RCC_APB1RSTCLRR_SPDIFRST BIT(26)
+#define RCC_APB1RSTCLRR_CECRST BIT(27)
+#define RCC_APB1RSTCLRR_DAC12RST BIT(29)
+#define RCC_APB1RSTCLRR_MDIOSRST BIT(31)
+
+/* RCC_APB2RSTSETR register fields */
+#define RCC_APB2RSTSETR_TIM1RST BIT(0)
+#define RCC_APB2RSTSETR_TIM8RST BIT(1)
+#define RCC_APB2RSTSETR_TIM15RST BIT(2)
+#define RCC_APB2RSTSETR_TIM16RST BIT(3)
+#define RCC_APB2RSTSETR_TIM17RST BIT(4)
+#define RCC_APB2RSTSETR_SPI1RST BIT(8)
+#define RCC_APB2RSTSETR_SPI4RST BIT(9)
+#define RCC_APB2RSTSETR_SPI5RST BIT(10)
+#define RCC_APB2RSTSETR_USART6RST BIT(13)
+#define RCC_APB2RSTSETR_SAI1RST BIT(16)
+#define RCC_APB2RSTSETR_SAI2RST BIT(17)
+#define RCC_APB2RSTSETR_SAI3RST BIT(18)
+#define RCC_APB2RSTSETR_DFSDMRST BIT(20)
+#define RCC_APB2RSTSETR_FDCANRST BIT(24)
+
+/* RCC_APB2RSTCLRR register fields */
+#define RCC_APB2RSTCLRR_TIM1RST BIT(0)
+#define RCC_APB2RSTCLRR_TIM8RST BIT(1)
+#define RCC_APB2RSTCLRR_TIM15RST BIT(2)
+#define RCC_APB2RSTCLRR_TIM16RST BIT(3)
+#define RCC_APB2RSTCLRR_TIM17RST BIT(4)
+#define RCC_APB2RSTCLRR_SPI1RST BIT(8)
+#define RCC_APB2RSTCLRR_SPI4RST BIT(9)
+#define RCC_APB2RSTCLRR_SPI5RST BIT(10)
+#define RCC_APB2RSTCLRR_USART6RST BIT(13)
+#define RCC_APB2RSTCLRR_SAI1RST BIT(16)
+#define RCC_APB2RSTCLRR_SAI2RST BIT(17)
+#define RCC_APB2RSTCLRR_SAI3RST BIT(18)
+#define RCC_APB2RSTCLRR_DFSDMRST BIT(20)
+#define RCC_APB2RSTCLRR_FDCANRST BIT(24)
+
+/* RCC_APB3RSTSETR register fields */
+#define RCC_APB3RSTSETR_LPTIM2RST BIT(0)
+#define RCC_APB3RSTSETR_LPTIM3RST BIT(1)
+#define RCC_APB3RSTSETR_LPTIM4RST BIT(2)
+#define RCC_APB3RSTSETR_LPTIM5RST BIT(3)
+#define RCC_APB3RSTSETR_SAI4RST BIT(8)
+#define RCC_APB3RSTSETR_SYSCFGRST BIT(11)
+#define RCC_APB3RSTSETR_VREFRST BIT(13)
+#define RCC_APB3RSTSETR_TMPSENSRST BIT(16)
+#define RCC_APB3RSTSETR_PMBCTRLRST BIT(17)
+
+/* RCC_APB3RSTCLRR register fields */
+#define RCC_APB3RSTCLRR_LPTIM2RST BIT(0)
+#define RCC_APB3RSTCLRR_LPTIM3RST BIT(1)
+#define RCC_APB3RSTCLRR_LPTIM4RST BIT(2)
+#define RCC_APB3RSTCLRR_LPTIM5RST BIT(3)
+#define RCC_APB3RSTCLRR_SAI4RST BIT(8)
+#define RCC_APB3RSTCLRR_SYSCFGRST BIT(11)
+#define RCC_APB3RSTCLRR_VREFRST BIT(13)
+#define RCC_APB3RSTCLRR_TMPSENSRST BIT(16)
+#define RCC_APB3RSTCLRR_PMBCTRLRST BIT(17)
+
+/* RCC_AHB2RSTSETR register fields */
+#define RCC_AHB2RSTSETR_DMA1RST BIT(0)
+#define RCC_AHB2RSTSETR_DMA2RST BIT(1)
+#define RCC_AHB2RSTSETR_DMAMUXRST BIT(2)
+#define RCC_AHB2RSTSETR_ADC12RST BIT(5)
+#define RCC_AHB2RSTSETR_USBORST BIT(8)
+#define RCC_AHB2RSTSETR_SDMMC3RST BIT(16)
+
+/* RCC_AHB2RSTCLRR register fields */
+#define RCC_AHB2RSTCLRR_DMA1RST BIT(0)
+#define RCC_AHB2RSTCLRR_DMA2RST BIT(1)
+#define RCC_AHB2RSTCLRR_DMAMUXRST BIT(2)
+#define RCC_AHB2RSTCLRR_ADC12RST BIT(5)
+#define RCC_AHB2RSTCLRR_USBORST BIT(8)
+#define RCC_AHB2RSTCLRR_SDMMC3RST BIT(16)
+
+/* RCC_AHB3RSTSETR register fields */
+#define RCC_AHB3RSTSETR_DCMIRST BIT(0)
+#define RCC_AHB3RSTSETR_CRYP2RST BIT(4)
+#define RCC_AHB3RSTSETR_HASH2RST BIT(5)
+#define RCC_AHB3RSTSETR_RNG2RST BIT(6)
+#define RCC_AHB3RSTSETR_CRC2RST BIT(7)
+#define RCC_AHB3RSTSETR_HSEMRST BIT(11)
+#define RCC_AHB3RSTSETR_IPCCRST BIT(12)
+
+/* RCC_AHB3RSTCLRR register fields */
+#define RCC_AHB3RSTCLRR_DCMIRST BIT(0)
+#define RCC_AHB3RSTCLRR_CRYP2RST BIT(4)
+#define RCC_AHB3RSTCLRR_HASH2RST BIT(5)
+#define RCC_AHB3RSTCLRR_RNG2RST BIT(6)
+#define RCC_AHB3RSTCLRR_CRC2RST BIT(7)
+#define RCC_AHB3RSTCLRR_HSEMRST BIT(11)
+#define RCC_AHB3RSTCLRR_IPCCRST BIT(12)
+
+/* RCC_AHB4RSTSETR register fields */
+#define RCC_AHB4RSTSETR_GPIOARST BIT(0)
+#define RCC_AHB4RSTSETR_GPIOBRST BIT(1)
+#define RCC_AHB4RSTSETR_GPIOCRST BIT(2)
+#define RCC_AHB4RSTSETR_GPIODRST BIT(3)
+#define RCC_AHB4RSTSETR_GPIOERST BIT(4)
+#define RCC_AHB4RSTSETR_GPIOFRST BIT(5)
+#define RCC_AHB4RSTSETR_GPIOGRST BIT(6)
+#define RCC_AHB4RSTSETR_GPIOHRST BIT(7)
+#define RCC_AHB4RSTSETR_GPIOIRST BIT(8)
+#define RCC_AHB4RSTSETR_GPIOJRST BIT(9)
+#define RCC_AHB4RSTSETR_GPIOKRST BIT(10)
+
+/* RCC_AHB4RSTCLRR register fields */
+#define RCC_AHB4RSTCLRR_GPIOARST BIT(0)
+#define RCC_AHB4RSTCLRR_GPIOBRST BIT(1)
+#define RCC_AHB4RSTCLRR_GPIOCRST BIT(2)
+#define RCC_AHB4RSTCLRR_GPIODRST BIT(3)
+#define RCC_AHB4RSTCLRR_GPIOERST BIT(4)
+#define RCC_AHB4RSTCLRR_GPIOFRST BIT(5)
+#define RCC_AHB4RSTCLRR_GPIOGRST BIT(6)
+#define RCC_AHB4RSTCLRR_GPIOHRST BIT(7)
+#define RCC_AHB4RSTCLRR_GPIOIRST BIT(8)
+#define RCC_AHB4RSTCLRR_GPIOJRST BIT(9)
+#define RCC_AHB4RSTCLRR_GPIOKRST BIT(10)
+
+/* RCC_MP_APB1ENSETR register fields */
+#define RCC_MP_APB1ENSETR_TIM2EN BIT(0)
+#define RCC_MP_APB1ENSETR_TIM3EN BIT(1)
+#define RCC_MP_APB1ENSETR_TIM4EN BIT(2)
+#define RCC_MP_APB1ENSETR_TIM5EN BIT(3)
+#define RCC_MP_APB1ENSETR_TIM6EN BIT(4)
+#define RCC_MP_APB1ENSETR_TIM7EN BIT(5)
+#define RCC_MP_APB1ENSETR_TIM12EN BIT(6)
+#define RCC_MP_APB1ENSETR_TIM13EN BIT(7)
+#define RCC_MP_APB1ENSETR_TIM14EN BIT(8)
+#define RCC_MP_APB1ENSETR_LPTIM1EN BIT(9)
+#define RCC_MP_APB1ENSETR_SPI2EN BIT(11)
+#define RCC_MP_APB1ENSETR_SPI3EN BIT(12)
+#define RCC_MP_APB1ENSETR_USART2EN BIT(14)
+#define RCC_MP_APB1ENSETR_USART3EN BIT(15)
+#define RCC_MP_APB1ENSETR_UART4EN BIT(16)
+#define RCC_MP_APB1ENSETR_UART5EN BIT(17)
+#define RCC_MP_APB1ENSETR_UART7EN BIT(18)
+#define RCC_MP_APB1ENSETR_UART8EN BIT(19)
+#define RCC_MP_APB1ENSETR_I2C1EN BIT(21)
+#define RCC_MP_APB1ENSETR_I2C2EN BIT(22)
+#define RCC_MP_APB1ENSETR_I2C3EN BIT(23)
+#define RCC_MP_APB1ENSETR_I2C5EN BIT(24)
+#define RCC_MP_APB1ENSETR_SPDIFEN BIT(26)
+#define RCC_MP_APB1ENSETR_CECEN BIT(27)
+#define RCC_MP_APB1ENSETR_DAC12EN BIT(29)
+#define RCC_MP_APB1ENSETR_MDIOSEN BIT(31)
+
+/* RCC_MP_APB1ENCLRR register fields */
+#define RCC_MP_APB1ENCLRR_TIM2EN BIT(0)
+#define RCC_MP_APB1ENCLRR_TIM3EN BIT(1)
+#define RCC_MP_APB1ENCLRR_TIM4EN BIT(2)
+#define RCC_MP_APB1ENCLRR_TIM5EN BIT(3)
+#define RCC_MP_APB1ENCLRR_TIM6EN BIT(4)
+#define RCC_MP_APB1ENCLRR_TIM7EN BIT(5)
+#define RCC_MP_APB1ENCLRR_TIM12EN BIT(6)
+#define RCC_MP_APB1ENCLRR_TIM13EN BIT(7)
+#define RCC_MP_APB1ENCLRR_TIM14EN BIT(8)
+#define RCC_MP_APB1ENCLRR_LPTIM1EN BIT(9)
+#define RCC_MP_APB1ENCLRR_SPI2EN BIT(11)
+#define RCC_MP_APB1ENCLRR_SPI3EN BIT(12)
+#define RCC_MP_APB1ENCLRR_USART2EN BIT(14)
+#define RCC_MP_APB1ENCLRR_USART3EN BIT(15)
+#define RCC_MP_APB1ENCLRR_UART4EN BIT(16)
+#define RCC_MP_APB1ENCLRR_UART5EN BIT(17)
+#define RCC_MP_APB1ENCLRR_UART7EN BIT(18)
+#define RCC_MP_APB1ENCLRR_UART8EN BIT(19)
+#define RCC_MP_APB1ENCLRR_I2C1EN BIT(21)
+#define RCC_MP_APB1ENCLRR_I2C2EN BIT(22)
+#define RCC_MP_APB1ENCLRR_I2C3EN BIT(23)
+#define RCC_MP_APB1ENCLRR_I2C5EN BIT(24)
+#define RCC_MP_APB1ENCLRR_SPDIFEN BIT(26)
+#define RCC_MP_APB1ENCLRR_CECEN BIT(27)
+#define RCC_MP_APB1ENCLRR_DAC12EN BIT(29)
+#define RCC_MP_APB1ENCLRR_MDIOSEN BIT(31)
+
+/* RCC_MP_APB2ENSETR register fields */
+#define RCC_MP_APB2ENSETR_TIM1EN BIT(0)
+#define RCC_MP_APB2ENSETR_TIM8EN BIT(1)
+#define RCC_MP_APB2ENSETR_TIM15EN BIT(2)
+#define RCC_MP_APB2ENSETR_TIM16EN BIT(3)
+#define RCC_MP_APB2ENSETR_TIM17EN BIT(4)
+#define RCC_MP_APB2ENSETR_SPI1EN BIT(8)
+#define RCC_MP_APB2ENSETR_SPI4EN BIT(9)
+#define RCC_MP_APB2ENSETR_SPI5EN BIT(10)
+#define RCC_MP_APB2ENSETR_USART6EN BIT(13)
+#define RCC_MP_APB2ENSETR_SAI1EN BIT(16)
+#define RCC_MP_APB2ENSETR_SAI2EN BIT(17)
+#define RCC_MP_APB2ENSETR_SAI3EN BIT(18)
+#define RCC_MP_APB2ENSETR_DFSDMEN BIT(20)
+#define RCC_MP_APB2ENSETR_ADFSDMEN BIT(21)
+#define RCC_MP_APB2ENSETR_FDCANEN BIT(24)
+
+/* RCC_MP_APB2ENCLRR register fields */
+#define RCC_MP_APB2ENCLRR_TIM1EN BIT(0)
+#define RCC_MP_APB2ENCLRR_TIM8EN BIT(1)
+#define RCC_MP_APB2ENCLRR_TIM15EN BIT(2)
+#define RCC_MP_APB2ENCLRR_TIM16EN BIT(3)
+#define RCC_MP_APB2ENCLRR_TIM17EN BIT(4)
+#define RCC_MP_APB2ENCLRR_SPI1EN BIT(8)
+#define RCC_MP_APB2ENCLRR_SPI4EN BIT(9)
+#define RCC_MP_APB2ENCLRR_SPI5EN BIT(10)
+#define RCC_MP_APB2ENCLRR_USART6EN BIT(13)
+#define RCC_MP_APB2ENCLRR_SAI1EN BIT(16)
+#define RCC_MP_APB2ENCLRR_SAI2EN BIT(17)
+#define RCC_MP_APB2ENCLRR_SAI3EN BIT(18)
+#define RCC_MP_APB2ENCLRR_DFSDMEN BIT(20)
+#define RCC_MP_APB2ENCLRR_ADFSDMEN BIT(21)
+#define RCC_MP_APB2ENCLRR_FDCANEN BIT(24)
+
+/* RCC_MP_APB3ENSETR register fields */
+#define RCC_MP_APB3ENSETR_LPTIM2EN BIT(0)
+#define RCC_MP_APB3ENSETR_LPTIM3EN BIT(1)
+#define RCC_MP_APB3ENSETR_LPTIM4EN BIT(2)
+#define RCC_MP_APB3ENSETR_LPTIM5EN BIT(3)
+#define RCC_MP_APB3ENSETR_SAI4EN BIT(8)
+#define RCC_MP_APB3ENSETR_SYSCFGEN BIT(11)
+#define RCC_MP_APB3ENSETR_VREFEN BIT(13)
+#define RCC_MP_APB3ENSETR_TMPSENSEN BIT(16)
+#define RCC_MP_APB3ENSETR_PMBCTRLEN BIT(17)
+#define RCC_MP_APB3ENSETR_HDPEN BIT(20)
+
+/* RCC_MP_APB3ENCLRR register fields */
+#define RCC_MP_APB3ENCLRR_LPTIM2EN BIT(0)
+#define RCC_MP_APB3ENCLRR_LPTIM3EN BIT(1)
+#define RCC_MP_APB3ENCLRR_LPTIM4EN BIT(2)
+#define RCC_MP_APB3ENCLRR_LPTIM5EN BIT(3)
+#define RCC_MP_APB3ENCLRR_SAI4EN BIT(8)
+#define RCC_MP_APB3ENCLRR_SYSCFGEN BIT(11)
+#define RCC_MP_APB3ENCLRR_VREFEN BIT(13)
+#define RCC_MP_APB3ENCLRR_TMPSENSEN BIT(16)
+#define RCC_MP_APB3ENCLRR_PMBCTRLEN BIT(17)
+#define RCC_MP_APB3ENCLRR_HDPEN BIT(20)
+
+/* RCC_MP_AHB2ENSETR register fields */
+#define RCC_MP_AHB2ENSETR_DMA1EN BIT(0)
+#define RCC_MP_AHB2ENSETR_DMA2EN BIT(1)
+#define RCC_MP_AHB2ENSETR_DMAMUXEN BIT(2)
+#define RCC_MP_AHB2ENSETR_ADC12EN BIT(5)
+#define RCC_MP_AHB2ENSETR_USBOEN BIT(8)
+#define RCC_MP_AHB2ENSETR_SDMMC3EN BIT(16)
+
+/* RCC_MP_AHB2ENCLRR register fields */
+#define RCC_MP_AHB2ENCLRR_DMA1EN BIT(0)
+#define RCC_MP_AHB2ENCLRR_DMA2EN BIT(1)
+#define RCC_MP_AHB2ENCLRR_DMAMUXEN BIT(2)
+#define RCC_MP_AHB2ENCLRR_ADC12EN BIT(5)
+#define RCC_MP_AHB2ENCLRR_USBOEN BIT(8)
+#define RCC_MP_AHB2ENCLRR_SDMMC3EN BIT(16)
+
+/* RCC_MP_AHB3ENSETR register fields */
+#define RCC_MP_AHB3ENSETR_DCMIEN BIT(0)
+#define RCC_MP_AHB3ENSETR_CRYP2EN BIT(4)
+#define RCC_MP_AHB3ENSETR_HASH2EN BIT(5)
+#define RCC_MP_AHB3ENSETR_RNG2EN BIT(6)
+#define RCC_MP_AHB3ENSETR_CRC2EN BIT(7)
+#define RCC_MP_AHB3ENSETR_HSEMEN BIT(11)
+#define RCC_MP_AHB3ENSETR_IPCCEN BIT(12)
+
+/* RCC_MP_AHB3ENCLRR register fields */
+#define RCC_MP_AHB3ENCLRR_DCMIEN BIT(0)
+#define RCC_MP_AHB3ENCLRR_CRYP2EN BIT(4)
+#define RCC_MP_AHB3ENCLRR_HASH2EN BIT(5)
+#define RCC_MP_AHB3ENCLRR_RNG2EN BIT(6)
+#define RCC_MP_AHB3ENCLRR_CRC2EN BIT(7)
+#define RCC_MP_AHB3ENCLRR_HSEMEN BIT(11)
+#define RCC_MP_AHB3ENCLRR_IPCCEN BIT(12)
+
+/* RCC_MP_AHB4ENSETR register fields */
+#define RCC_MP_AHB4ENSETR_GPIOAEN BIT(0)
+#define RCC_MP_AHB4ENSETR_GPIOBEN BIT(1)
+#define RCC_MP_AHB4ENSETR_GPIOCEN BIT(2)
+#define RCC_MP_AHB4ENSETR_GPIODEN BIT(3)
+#define RCC_MP_AHB4ENSETR_GPIOEEN BIT(4)
+#define RCC_MP_AHB4ENSETR_GPIOFEN BIT(5)
+#define RCC_MP_AHB4ENSETR_GPIOGEN BIT(6)
+#define RCC_MP_AHB4ENSETR_GPIOHEN BIT(7)
+#define RCC_MP_AHB4ENSETR_GPIOIEN BIT(8)
+#define RCC_MP_AHB4ENSETR_GPIOJEN BIT(9)
+#define RCC_MP_AHB4ENSETR_GPIOKEN BIT(10)
+
+/* RCC_MP_AHB4ENCLRR register fields */
+#define RCC_MP_AHB4ENCLRR_GPIOAEN BIT(0)
+#define RCC_MP_AHB4ENCLRR_GPIOBEN BIT(1)
+#define RCC_MP_AHB4ENCLRR_GPIOCEN BIT(2)
+#define RCC_MP_AHB4ENCLRR_GPIODEN BIT(3)
+#define RCC_MP_AHB4ENCLRR_GPIOEEN BIT(4)
+#define RCC_MP_AHB4ENCLRR_GPIOFEN BIT(5)
+#define RCC_MP_AHB4ENCLRR_GPIOGEN BIT(6)
+#define RCC_MP_AHB4ENCLRR_GPIOHEN BIT(7)
+#define RCC_MP_AHB4ENCLRR_GPIOIEN BIT(8)
+#define RCC_MP_AHB4ENCLRR_GPIOJEN BIT(9)
+#define RCC_MP_AHB4ENCLRR_GPIOKEN BIT(10)
+
+/* RCC_MP_MLAHBENSETR register fields */
+#define RCC_MP_MLAHBENSETR_RETRAMEN BIT(4)
+
+/* RCC_MP_MLAHBENCLRR register fields */
+#define RCC_MP_MLAHBENCLRR_RETRAMEN BIT(4)
+
+/* RCC_MC_APB1ENSETR register fields */
+#define RCC_MC_APB1ENSETR_TIM2EN BIT(0)
+#define RCC_MC_APB1ENSETR_TIM3EN BIT(1)
+#define RCC_MC_APB1ENSETR_TIM4EN BIT(2)
+#define RCC_MC_APB1ENSETR_TIM5EN BIT(3)
+#define RCC_MC_APB1ENSETR_TIM6EN BIT(4)
+#define RCC_MC_APB1ENSETR_TIM7EN BIT(5)
+#define RCC_MC_APB1ENSETR_TIM12EN BIT(6)
+#define RCC_MC_APB1ENSETR_TIM13EN BIT(7)
+#define RCC_MC_APB1ENSETR_TIM14EN BIT(8)
+#define RCC_MC_APB1ENSETR_LPTIM1EN BIT(9)
+#define RCC_MC_APB1ENSETR_SPI2EN BIT(11)
+#define RCC_MC_APB1ENSETR_SPI3EN BIT(12)
+#define RCC_MC_APB1ENSETR_USART2EN BIT(14)
+#define RCC_MC_APB1ENSETR_USART3EN BIT(15)
+#define RCC_MC_APB1ENSETR_UART4EN BIT(16)
+#define RCC_MC_APB1ENSETR_UART5EN BIT(17)
+#define RCC_MC_APB1ENSETR_UART7EN BIT(18)
+#define RCC_MC_APB1ENSETR_UART8EN BIT(19)
+#define RCC_MC_APB1ENSETR_I2C1EN BIT(21)
+#define RCC_MC_APB1ENSETR_I2C2EN BIT(22)
+#define RCC_MC_APB1ENSETR_I2C3EN BIT(23)
+#define RCC_MC_APB1ENSETR_I2C5EN BIT(24)
+#define RCC_MC_APB1ENSETR_SPDIFEN BIT(26)
+#define RCC_MC_APB1ENSETR_CECEN BIT(27)
+#define RCC_MC_APB1ENSETR_WWDG1EN BIT(28)
+#define RCC_MC_APB1ENSETR_DAC12EN BIT(29)
+#define RCC_MC_APB1ENSETR_MDIOSEN BIT(31)
+
+/* RCC_MC_APB1ENCLRR register fields */
+#define RCC_MC_APB1ENCLRR_TIM2EN BIT(0)
+#define RCC_MC_APB1ENCLRR_TIM3EN BIT(1)
+#define RCC_MC_APB1ENCLRR_TIM4EN BIT(2)
+#define RCC_MC_APB1ENCLRR_TIM5EN BIT(3)
+#define RCC_MC_APB1ENCLRR_TIM6EN BIT(4)
+#define RCC_MC_APB1ENCLRR_TIM7EN BIT(5)
+#define RCC_MC_APB1ENCLRR_TIM12EN BIT(6)
+#define RCC_MC_APB1ENCLRR_TIM13EN BIT(7)
+#define RCC_MC_APB1ENCLRR_TIM14EN BIT(8)
+#define RCC_MC_APB1ENCLRR_LPTIM1EN BIT(9)
+#define RCC_MC_APB1ENCLRR_SPI2EN BIT(11)
+#define RCC_MC_APB1ENCLRR_SPI3EN BIT(12)
+#define RCC_MC_APB1ENCLRR_USART2EN BIT(14)
+#define RCC_MC_APB1ENCLRR_USART3EN BIT(15)
+#define RCC_MC_APB1ENCLRR_UART4EN BIT(16)
+#define RCC_MC_APB1ENCLRR_UART5EN BIT(17)
+#define RCC_MC_APB1ENCLRR_UART7EN BIT(18)
+#define RCC_MC_APB1ENCLRR_UART8EN BIT(19)
+#define RCC_MC_APB1ENCLRR_I2C1EN BIT(21)
+#define RCC_MC_APB1ENCLRR_I2C2EN BIT(22)
+#define RCC_MC_APB1ENCLRR_I2C3EN BIT(23)
+#define RCC_MC_APB1ENCLRR_I2C5EN BIT(24)
+#define RCC_MC_APB1ENCLRR_SPDIFEN BIT(26)
+#define RCC_MC_APB1ENCLRR_CECEN BIT(27)
+#define RCC_MC_APB1ENCLRR_DAC12EN BIT(29)
+#define RCC_MC_APB1ENCLRR_MDIOSEN BIT(31)
+
+/* RCC_MC_APB2ENSETR register fields */
+#define RCC_MC_APB2ENSETR_TIM1EN BIT(0)
+#define RCC_MC_APB2ENSETR_TIM8EN BIT(1)
+#define RCC_MC_APB2ENSETR_TIM15EN BIT(2)
+#define RCC_MC_APB2ENSETR_TIM16EN BIT(3)
+#define RCC_MC_APB2ENSETR_TIM17EN BIT(4)
+#define RCC_MC_APB2ENSETR_SPI1EN BIT(8)
+#define RCC_MC_APB2ENSETR_SPI4EN BIT(9)
+#define RCC_MC_APB2ENSETR_SPI5EN BIT(10)
+#define RCC_MC_APB2ENSETR_USART6EN BIT(13)
+#define RCC_MC_APB2ENSETR_SAI1EN BIT(16)
+#define RCC_MC_APB2ENSETR_SAI2EN BIT(17)
+#define RCC_MC_APB2ENSETR_SAI3EN BIT(18)
+#define RCC_MC_APB2ENSETR_DFSDMEN BIT(20)
+#define RCC_MC_APB2ENSETR_ADFSDMEN BIT(21)
+#define RCC_MC_APB2ENSETR_FDCANEN BIT(24)
+
+/* RCC_MC_APB2ENCLRR register fields */
+#define RCC_MC_APB2ENCLRR_TIM1EN BIT(0)
+#define RCC_MC_APB2ENCLRR_TIM8EN BIT(1)
+#define RCC_MC_APB2ENCLRR_TIM15EN BIT(2)
+#define RCC_MC_APB2ENCLRR_TIM16EN BIT(3)
+#define RCC_MC_APB2ENCLRR_TIM17EN BIT(4)
+#define RCC_MC_APB2ENCLRR_SPI1EN BIT(8)
+#define RCC_MC_APB2ENCLRR_SPI4EN BIT(9)
+#define RCC_MC_APB2ENCLRR_SPI5EN BIT(10)
+#define RCC_MC_APB2ENCLRR_USART6EN BIT(13)
+#define RCC_MC_APB2ENCLRR_SAI1EN BIT(16)
+#define RCC_MC_APB2ENCLRR_SAI2EN BIT(17)
+#define RCC_MC_APB2ENCLRR_SAI3EN BIT(18)
+#define RCC_MC_APB2ENCLRR_DFSDMEN BIT(20)
+#define RCC_MC_APB2ENCLRR_ADFSDMEN BIT(21)
+#define RCC_MC_APB2ENCLRR_FDCANEN BIT(24)
+
+/* RCC_MC_APB3ENSETR register fields */
+#define RCC_MC_APB3ENSETR_LPTIM2EN BIT(0)
+#define RCC_MC_APB3ENSETR_LPTIM3EN BIT(1)
+#define RCC_MC_APB3ENSETR_LPTIM4EN BIT(2)
+#define RCC_MC_APB3ENSETR_LPTIM5EN BIT(3)
+#define RCC_MC_APB3ENSETR_SAI4EN BIT(8)
+#define RCC_MC_APB3ENSETR_SYSCFGEN BIT(11)
+#define RCC_MC_APB3ENSETR_VREFEN BIT(13)
+#define RCC_MC_APB3ENSETR_TMPSENSEN BIT(16)
+#define RCC_MC_APB3ENSETR_PMBCTRLEN BIT(17)
+#define RCC_MC_APB3ENSETR_HDPEN BIT(20)
+
+/* RCC_MC_APB3ENCLRR register fields */
+#define RCC_MC_APB3ENCLRR_LPTIM2EN BIT(0)
+#define RCC_MC_APB3ENCLRR_LPTIM3EN BIT(1)
+#define RCC_MC_APB3ENCLRR_LPTIM4EN BIT(2)
+#define RCC_MC_APB3ENCLRR_LPTIM5EN BIT(3)
+#define RCC_MC_APB3ENCLRR_SAI4EN BIT(8)
+#define RCC_MC_APB3ENCLRR_SYSCFGEN BIT(11)
+#define RCC_MC_APB3ENCLRR_VREFEN BIT(13)
+#define RCC_MC_APB3ENCLRR_TMPSENSEN BIT(16)
+#define RCC_MC_APB3ENCLRR_PMBCTRLEN BIT(17)
+#define RCC_MC_APB3ENCLRR_HDPEN BIT(20)
+
+/* RCC_MC_AHB2ENSETR register fields */
+#define RCC_MC_AHB2ENSETR_DMA1EN BIT(0)
+#define RCC_MC_AHB2ENSETR_DMA2EN BIT(1)
+#define RCC_MC_AHB2ENSETR_DMAMUXEN BIT(2)
+#define RCC_MC_AHB2ENSETR_ADC12EN BIT(5)
+#define RCC_MC_AHB2ENSETR_USBOEN BIT(8)
+#define RCC_MC_AHB2ENSETR_SDMMC3EN BIT(16)
+
+/* RCC_MC_AHB2ENCLRR register fields */
+#define RCC_MC_AHB2ENCLRR_DMA1EN BIT(0)
+#define RCC_MC_AHB2ENCLRR_DMA2EN BIT(1)
+#define RCC_MC_AHB2ENCLRR_DMAMUXEN BIT(2)
+#define RCC_MC_AHB2ENCLRR_ADC12EN BIT(5)
+#define RCC_MC_AHB2ENCLRR_USBOEN BIT(8)
+#define RCC_MC_AHB2ENCLRR_SDMMC3EN BIT(16)
+
+/* RCC_MC_AHB3ENSETR register fields */
+#define RCC_MC_AHB3ENSETR_DCMIEN BIT(0)
+#define RCC_MC_AHB3ENSETR_CRYP2EN BIT(4)
+#define RCC_MC_AHB3ENSETR_HASH2EN BIT(5)
+#define RCC_MC_AHB3ENSETR_RNG2EN BIT(6)
+#define RCC_MC_AHB3ENSETR_CRC2EN BIT(7)
+#define RCC_MC_AHB3ENSETR_HSEMEN BIT(11)
+#define RCC_MC_AHB3ENSETR_IPCCEN BIT(12)
+
+/* RCC_MC_AHB3ENCLRR register fields */
+#define RCC_MC_AHB3ENCLRR_DCMIEN BIT(0)
+#define RCC_MC_AHB3ENCLRR_CRYP2EN BIT(4)
+#define RCC_MC_AHB3ENCLRR_HASH2EN BIT(5)
+#define RCC_MC_AHB3ENCLRR_RNG2EN BIT(6)
+#define RCC_MC_AHB3ENCLRR_CRC2EN BIT(7)
+#define RCC_MC_AHB3ENCLRR_HSEMEN BIT(11)
+#define RCC_MC_AHB3ENCLRR_IPCCEN BIT(12)
+
+/* RCC_MC_AHB4ENSETR register fields */
+#define RCC_MC_AHB4ENSETR_GPIOAEN BIT(0)
+#define RCC_MC_AHB4ENSETR_GPIOBEN BIT(1)
+#define RCC_MC_AHB4ENSETR_GPIOCEN BIT(2)
+#define RCC_MC_AHB4ENSETR_GPIODEN BIT(3)
+#define RCC_MC_AHB4ENSETR_GPIOEEN BIT(4)
+#define RCC_MC_AHB4ENSETR_GPIOFEN BIT(5)
+#define RCC_MC_AHB4ENSETR_GPIOGEN BIT(6)
+#define RCC_MC_AHB4ENSETR_GPIOHEN BIT(7)
+#define RCC_MC_AHB4ENSETR_GPIOIEN BIT(8)
+#define RCC_MC_AHB4ENSETR_GPIOJEN BIT(9)
+#define RCC_MC_AHB4ENSETR_GPIOKEN BIT(10)
+
+/* RCC_MC_AHB4ENCLRR register fields */
+#define RCC_MC_AHB4ENCLRR_GPIOAEN BIT(0)
+#define RCC_MC_AHB4ENCLRR_GPIOBEN BIT(1)
+#define RCC_MC_AHB4ENCLRR_GPIOCEN BIT(2)
+#define RCC_MC_AHB4ENCLRR_GPIODEN BIT(3)
+#define RCC_MC_AHB4ENCLRR_GPIOEEN BIT(4)
+#define RCC_MC_AHB4ENCLRR_GPIOFEN BIT(5)
+#define RCC_MC_AHB4ENCLRR_GPIOGEN BIT(6)
+#define RCC_MC_AHB4ENCLRR_GPIOHEN BIT(7)
+#define RCC_MC_AHB4ENCLRR_GPIOIEN BIT(8)
+#define RCC_MC_AHB4ENCLRR_GPIOJEN BIT(9)
+#define RCC_MC_AHB4ENCLRR_GPIOKEN BIT(10)
+
+/* RCC_MC_AXIMENSETR register fields */
+#define RCC_MC_AXIMENSETR_SYSRAMEN BIT(0)
+
+/* RCC_MC_AXIMENCLRR register fields */
+#define RCC_MC_AXIMENCLRR_SYSRAMEN BIT(0)
+
+/* RCC_MC_MLAHBENSETR register fields */
+#define RCC_MC_MLAHBENSETR_RETRAMEN BIT(4)
+
+/* RCC_MC_MLAHBENCLRR register fields */
+#define RCC_MC_MLAHBENCLRR_RETRAMEN BIT(4)
+
+/* RCC_MP_APB1LPENSETR register fields */
+#define RCC_MP_APB1LPENSETR_TIM2LPEN BIT(0)
+#define RCC_MP_APB1LPENSETR_TIM3LPEN BIT(1)
+#define RCC_MP_APB1LPENSETR_TIM4LPEN BIT(2)
+#define RCC_MP_APB1LPENSETR_TIM5LPEN BIT(3)
+#define RCC_MP_APB1LPENSETR_TIM6LPEN BIT(4)
+#define RCC_MP_APB1LPENSETR_TIM7LPEN BIT(5)
+#define RCC_MP_APB1LPENSETR_TIM12LPEN BIT(6)
+#define RCC_MP_APB1LPENSETR_TIM13LPEN BIT(7)
+#define RCC_MP_APB1LPENSETR_TIM14LPEN BIT(8)
+#define RCC_MP_APB1LPENSETR_LPTIM1LPEN BIT(9)
+#define RCC_MP_APB1LPENSETR_SPI2LPEN BIT(11)
+#define RCC_MP_APB1LPENSETR_SPI3LPEN BIT(12)
+#define RCC_MP_APB1LPENSETR_USART2LPEN BIT(14)
+#define RCC_MP_APB1LPENSETR_USART3LPEN BIT(15)
+#define RCC_MP_APB1LPENSETR_UART4LPEN BIT(16)
+#define RCC_MP_APB1LPENSETR_UART5LPEN BIT(17)
+#define RCC_MP_APB1LPENSETR_UART7LPEN BIT(18)
+#define RCC_MP_APB1LPENSETR_UART8LPEN BIT(19)
+#define RCC_MP_APB1LPENSETR_I2C1LPEN BIT(21)
+#define RCC_MP_APB1LPENSETR_I2C2LPEN BIT(22)
+#define RCC_MP_APB1LPENSETR_I2C3LPEN BIT(23)
+#define RCC_MP_APB1LPENSETR_I2C5LPEN BIT(24)
+#define RCC_MP_APB1LPENSETR_SPDIFLPEN BIT(26)
+#define RCC_MP_APB1LPENSETR_CECLPEN BIT(27)
+#define RCC_MP_APB1LPENSETR_DAC12LPEN BIT(29)
+#define RCC_MP_APB1LPENSETR_MDIOSLPEN BIT(31)
+
+/* RCC_MP_APB1LPENCLRR register fields */
+#define RCC_MP_APB1LPENCLRR_TIM2LPEN BIT(0)
+#define RCC_MP_APB1LPENCLRR_TIM3LPEN BIT(1)
+#define RCC_MP_APB1LPENCLRR_TIM4LPEN BIT(2)
+#define RCC_MP_APB1LPENCLRR_TIM5LPEN BIT(3)
+#define RCC_MP_APB1LPENCLRR_TIM6LPEN BIT(4)
+#define RCC_MP_APB1LPENCLRR_TIM7LPEN BIT(5)
+#define RCC_MP_APB1LPENCLRR_TIM12LPEN BIT(6)
+#define RCC_MP_APB1LPENCLRR_TIM13LPEN BIT(7)
+#define RCC_MP_APB1LPENCLRR_TIM14LPEN BIT(8)
+#define RCC_MP_APB1LPENCLRR_LPTIM1LPEN BIT(9)
+#define RCC_MP_APB1LPENCLRR_SPI2LPEN BIT(11)
+#define RCC_MP_APB1LPENCLRR_SPI3LPEN BIT(12)
+#define RCC_MP_APB1LPENCLRR_USART2LPEN BIT(14)
+#define RCC_MP_APB1LPENCLRR_USART3LPEN BIT(15)
+#define RCC_MP_APB1LPENCLRR_UART4LPEN BIT(16)
+#define RCC_MP_APB1LPENCLRR_UART5LPEN BIT(17)
+#define RCC_MP_APB1LPENCLRR_UART7LPEN BIT(18)
+#define RCC_MP_APB1LPENCLRR_UART8LPEN BIT(19)
+#define RCC_MP_APB1LPENCLRR_I2C1LPEN BIT(21)
+#define RCC_MP_APB1LPENCLRR_I2C2LPEN BIT(22)
+#define RCC_MP_APB1LPENCLRR_I2C3LPEN BIT(23)
+#define RCC_MP_APB1LPENCLRR_I2C5LPEN BIT(24)
+#define RCC_MP_APB1LPENCLRR_SPDIFLPEN BIT(26)
+#define RCC_MP_APB1LPENCLRR_CECLPEN BIT(27)
+#define RCC_MP_APB1LPENCLRR_DAC12LPEN BIT(29)
+#define RCC_MP_APB1LPENCLRR_MDIOSLPEN BIT(31)
+
+/* RCC_MP_APB2LPENSETR register fields */
+#define RCC_MP_APB2LPENSETR_TIM1LPEN BIT(0)
+#define RCC_MP_APB2LPENSETR_TIM8LPEN BIT(1)
+#define RCC_MP_APB2LPENSETR_TIM15LPEN BIT(2)
+#define RCC_MP_APB2LPENSETR_TIM16LPEN BIT(3)
+#define RCC_MP_APB2LPENSETR_TIM17LPEN BIT(4)
+#define RCC_MP_APB2LPENSETR_SPI1LPEN BIT(8)
+#define RCC_MP_APB2LPENSETR_SPI4LPEN BIT(9)
+#define RCC_MP_APB2LPENSETR_SPI5LPEN BIT(10)
+#define RCC_MP_APB2LPENSETR_USART6LPEN BIT(13)
+#define RCC_MP_APB2LPENSETR_SAI1LPEN BIT(16)
+#define RCC_MP_APB2LPENSETR_SAI2LPEN BIT(17)
+#define RCC_MP_APB2LPENSETR_SAI3LPEN BIT(18)
+#define RCC_MP_APB2LPENSETR_DFSDMLPEN BIT(20)
+#define RCC_MP_APB2LPENSETR_ADFSDMLPEN BIT(21)
+#define RCC_MP_APB2LPENSETR_FDCANLPEN BIT(24)
+
+/* RCC_MP_APB2LPENCLRR register fields */
+#define RCC_MP_APB2LPENCLRR_TIM1LPEN BIT(0)
+#define RCC_MP_APB2LPENCLRR_TIM8LPEN BIT(1)
+#define RCC_MP_APB2LPENCLRR_TIM15LPEN BIT(2)
+#define RCC_MP_APB2LPENCLRR_TIM16LPEN BIT(3)
+#define RCC_MP_APB2LPENCLRR_TIM17LPEN BIT(4)
+#define RCC_MP_APB2LPENCLRR_SPI1LPEN BIT(8)
+#define RCC_MP_APB2LPENCLRR_SPI4LPEN BIT(9)
+#define RCC_MP_APB2LPENCLRR_SPI5LPEN BIT(10)
+#define RCC_MP_APB2LPENCLRR_USART6LPEN BIT(13)
+#define RCC_MP_APB2LPENCLRR_SAI1LPEN BIT(16)
+#define RCC_MP_APB2LPENCLRR_SAI2LPEN BIT(17)
+#define RCC_MP_APB2LPENCLRR_SAI3LPEN BIT(18)
+#define RCC_MP_APB2LPENCLRR_DFSDMLPEN BIT(20)
+#define RCC_MP_APB2LPENCLRR_ADFSDMLPEN BIT(21)
+#define RCC_MP_APB2LPENCLRR_FDCANLPEN BIT(24)
+
+/* RCC_MP_APB3LPENSETR register fields */
+#define RCC_MP_APB3LPENSETR_LPTIM2LPEN BIT(0)
+#define RCC_MP_APB3LPENSETR_LPTIM3LPEN BIT(1)
+#define RCC_MP_APB3LPENSETR_LPTIM4LPEN BIT(2)
+#define RCC_MP_APB3LPENSETR_LPTIM5LPEN BIT(3)
+#define RCC_MP_APB3LPENSETR_SAI4LPEN BIT(8)
+#define RCC_MP_APB3LPENSETR_SYSCFGLPEN BIT(11)
+#define RCC_MP_APB3LPENSETR_VREFLPEN BIT(13)
+#define RCC_MP_APB3LPENSETR_TMPSENSLPEN BIT(16)
+#define RCC_MP_APB3LPENSETR_PMBCTRLLPEN BIT(17)
+
+/* RCC_MP_APB3LPENCLRR register fields */
+#define RCC_MP_APB3LPENCLRR_LPTIM2LPEN BIT(0)
+#define RCC_MP_APB3LPENCLRR_LPTIM3LPEN BIT(1)
+#define RCC_MP_APB3LPENCLRR_LPTIM4LPEN BIT(2)
+#define RCC_MP_APB3LPENCLRR_LPTIM5LPEN BIT(3)
+#define RCC_MP_APB3LPENCLRR_SAI4LPEN BIT(8)
+#define RCC_MP_APB3LPENCLRR_SYSCFGLPEN BIT(11)
+#define RCC_MP_APB3LPENCLRR_VREFLPEN BIT(13)
+#define RCC_MP_APB3LPENCLRR_TMPSENSLPEN BIT(16)
+#define RCC_MP_APB3LPENCLRR_PMBCTRLLPEN BIT(17)
+
+/* RCC_MP_AHB2LPENSETR register fields */
+#define RCC_MP_AHB2LPENSETR_DMA1LPEN BIT(0)
+#define RCC_MP_AHB2LPENSETR_DMA2LPEN BIT(1)
+#define RCC_MP_AHB2LPENSETR_DMAMUXLPEN BIT(2)
+#define RCC_MP_AHB2LPENSETR_ADC12LPEN BIT(5)
+#define RCC_MP_AHB2LPENSETR_USBOLPEN BIT(8)
+#define RCC_MP_AHB2LPENSETR_SDMMC3LPEN BIT(16)
+
+/* RCC_MP_AHB2LPENCLRR register fields */
+#define RCC_MP_AHB2LPENCLRR_DMA1LPEN BIT(0)
+#define RCC_MP_AHB2LPENCLRR_DMA2LPEN BIT(1)
+#define RCC_MP_AHB2LPENCLRR_DMAMUXLPEN BIT(2)
+#define RCC_MP_AHB2LPENCLRR_ADC12LPEN BIT(5)
+#define RCC_MP_AHB2LPENCLRR_USBOLPEN BIT(8)
+#define RCC_MP_AHB2LPENCLRR_SDMMC3LPEN BIT(16)
+
+/* RCC_MP_AHB3LPENSETR register fields */
+#define RCC_MP_AHB3LPENSETR_DCMILPEN BIT(0)
+#define RCC_MP_AHB3LPENSETR_CRYP2LPEN BIT(4)
+#define RCC_MP_AHB3LPENSETR_HASH2LPEN BIT(5)
+#define RCC_MP_AHB3LPENSETR_RNG2LPEN BIT(6)
+#define RCC_MP_AHB3LPENSETR_CRC2LPEN BIT(7)
+#define RCC_MP_AHB3LPENSETR_HSEMLPEN BIT(11)
+#define RCC_MP_AHB3LPENSETR_IPCCLPEN BIT(12)
+
+/* RCC_MP_AHB3LPENCLRR register fields */
+#define RCC_MP_AHB3LPENCLRR_DCMILPEN BIT(0)
+#define RCC_MP_AHB3LPENCLRR_CRYP2LPEN BIT(4)
+#define RCC_MP_AHB3LPENCLRR_HASH2LPEN BIT(5)
+#define RCC_MP_AHB3LPENCLRR_RNG2LPEN BIT(6)
+#define RCC_MP_AHB3LPENCLRR_CRC2LPEN BIT(7)
+#define RCC_MP_AHB3LPENCLRR_HSEMLPEN BIT(11)
+#define RCC_MP_AHB3LPENCLRR_IPCCLPEN BIT(12)
+
+/* RCC_MP_AHB4LPENSETR register fields */
+#define RCC_MP_AHB4LPENSETR_GPIOALPEN BIT(0)
+#define RCC_MP_AHB4LPENSETR_GPIOBLPEN BIT(1)
+#define RCC_MP_AHB4LPENSETR_GPIOCLPEN BIT(2)
+#define RCC_MP_AHB4LPENSETR_GPIODLPEN BIT(3)
+#define RCC_MP_AHB4LPENSETR_GPIOELPEN BIT(4)
+#define RCC_MP_AHB4LPENSETR_GPIOFLPEN BIT(5)
+#define RCC_MP_AHB4LPENSETR_GPIOGLPEN BIT(6)
+#define RCC_MP_AHB4LPENSETR_GPIOHLPEN BIT(7)
+#define RCC_MP_AHB4LPENSETR_GPIOILPEN BIT(8)
+#define RCC_MP_AHB4LPENSETR_GPIOJLPEN BIT(9)
+#define RCC_MP_AHB4LPENSETR_GPIOKLPEN BIT(10)
+
+/* RCC_MP_AHB4LPENCLRR register fields */
+#define RCC_MP_AHB4LPENCLRR_GPIOALPEN BIT(0)
+#define RCC_MP_AHB4LPENCLRR_GPIOBLPEN BIT(1)
+#define RCC_MP_AHB4LPENCLRR_GPIOCLPEN BIT(2)
+#define RCC_MP_AHB4LPENCLRR_GPIODLPEN BIT(3)
+#define RCC_MP_AHB4LPENCLRR_GPIOELPEN BIT(4)
+#define RCC_MP_AHB4LPENCLRR_GPIOFLPEN BIT(5)
+#define RCC_MP_AHB4LPENCLRR_GPIOGLPEN BIT(6)
+#define RCC_MP_AHB4LPENCLRR_GPIOHLPEN BIT(7)
+#define RCC_MP_AHB4LPENCLRR_GPIOILPEN BIT(8)
+#define RCC_MP_AHB4LPENCLRR_GPIOJLPEN BIT(9)
+#define RCC_MP_AHB4LPENCLRR_GPIOKLPEN BIT(10)
+
+/* RCC_MP_AXIMLPENSETR register fields */
+#define RCC_MP_AXIMLPENSETR_SYSRAMLPEN BIT(0)
+
+/* RCC_MP_AXIMLPENCLRR register fields */
+#define RCC_MP_AXIMLPENCLRR_SYSRAMLPEN BIT(0)
+
+/* RCC_MP_MLAHBLPENSETR register fields */
+#define RCC_MP_MLAHBLPENSETR_SRAM1LPEN BIT(0)
+#define RCC_MP_MLAHBLPENSETR_SRAM2LPEN BIT(1)
+#define RCC_MP_MLAHBLPENSETR_SRAM34LPEN BIT(2)
+#define RCC_MP_MLAHBLPENSETR_RETRAMLPEN BIT(4)
+
+/* RCC_MP_MLAHBLPENCLRR register fields */
+#define RCC_MP_MLAHBLPENCLRR_SRAM1LPEN BIT(0)
+#define RCC_MP_MLAHBLPENCLRR_SRAM2LPEN BIT(1)
+#define RCC_MP_MLAHBLPENCLRR_SRAM34LPEN BIT(2)
+#define RCC_MP_MLAHBLPENCLRR_RETRAMLPEN BIT(4)
+
+/* RCC_MC_APB1LPENSETR register fields */
+#define RCC_MC_APB1LPENSETR_TIM2LPEN BIT(0)
+#define RCC_MC_APB1LPENSETR_TIM3LPEN BIT(1)
+#define RCC_MC_APB1LPENSETR_TIM4LPEN BIT(2)
+#define RCC_MC_APB1LPENSETR_TIM5LPEN BIT(3)
+#define RCC_MC_APB1LPENSETR_TIM6LPEN BIT(4)
+#define RCC_MC_APB1LPENSETR_TIM7LPEN BIT(5)
+#define RCC_MC_APB1LPENSETR_TIM12LPEN BIT(6)
+#define RCC_MC_APB1LPENSETR_TIM13LPEN BIT(7)
+#define RCC_MC_APB1LPENSETR_TIM14LPEN BIT(8)
+#define RCC_MC_APB1LPENSETR_LPTIM1LPEN BIT(9)
+#define RCC_MC_APB1LPENSETR_SPI2LPEN BIT(11)
+#define RCC_MC_APB1LPENSETR_SPI3LPEN BIT(12)
+#define RCC_MC_APB1LPENSETR_USART2LPEN BIT(14)
+#define RCC_MC_APB1LPENSETR_USART3LPEN BIT(15)
+#define RCC_MC_APB1LPENSETR_UART4LPEN BIT(16)
+#define RCC_MC_APB1LPENSETR_UART5LPEN BIT(17)
+#define RCC_MC_APB1LPENSETR_UART7LPEN BIT(18)
+#define RCC_MC_APB1LPENSETR_UART8LPEN BIT(19)
+#define RCC_MC_APB1LPENSETR_I2C1LPEN BIT(21)
+#define RCC_MC_APB1LPENSETR_I2C2LPEN BIT(22)
+#define RCC_MC_APB1LPENSETR_I2C3LPEN BIT(23)
+#define RCC_MC_APB1LPENSETR_I2C5LPEN BIT(24)
+#define RCC_MC_APB1LPENSETR_SPDIFLPEN BIT(26)
+#define RCC_MC_APB1LPENSETR_CECLPEN BIT(27)
+#define RCC_MC_APB1LPENSETR_WWDG1LPEN BIT(28)
+#define RCC_MC_APB1LPENSETR_DAC12LPEN BIT(29)
+#define RCC_MC_APB1LPENSETR_MDIOSLPEN BIT(31)
+
+/* RCC_MC_APB1LPENCLRR register fields */
+#define RCC_MC_APB1LPENCLRR_TIM2LPEN BIT(0)
+#define RCC_MC_APB1LPENCLRR_TIM3LPEN BIT(1)
+#define RCC_MC_APB1LPENCLRR_TIM4LPEN BIT(2)
+#define RCC_MC_APB1LPENCLRR_TIM5LPEN BIT(3)
+#define RCC_MC_APB1LPENCLRR_TIM6LPEN BIT(4)
+#define RCC_MC_APB1LPENCLRR_TIM7LPEN BIT(5)
+#define RCC_MC_APB1LPENCLRR_TIM12LPEN BIT(6)
+#define RCC_MC_APB1LPENCLRR_TIM13LPEN BIT(7)
+#define RCC_MC_APB1LPENCLRR_TIM14LPEN BIT(8)
+#define RCC_MC_APB1LPENCLRR_LPTIM1LPEN BIT(9)
+#define RCC_MC_APB1LPENCLRR_SPI2LPEN BIT(11)
+#define RCC_MC_APB1LPENCLRR_SPI3LPEN BIT(12)
+#define RCC_MC_APB1LPENCLRR_USART2LPEN BIT(14)
+#define RCC_MC_APB1LPENCLRR_USART3LPEN BIT(15)
+#define RCC_MC_APB1LPENCLRR_UART4LPEN BIT(16)
+#define RCC_MC_APB1LPENCLRR_UART5LPEN BIT(17)
+#define RCC_MC_APB1LPENCLRR_UART7LPEN BIT(18)
+#define RCC_MC_APB1LPENCLRR_UART8LPEN BIT(19)
+#define RCC_MC_APB1LPENCLRR_I2C1LPEN BIT(21)
+#define RCC_MC_APB1LPENCLRR_I2C2LPEN BIT(22)
+#define RCC_MC_APB1LPENCLRR_I2C3LPEN BIT(23)
+#define RCC_MC_APB1LPENCLRR_I2C5LPEN BIT(24)
+#define RCC_MC_APB1LPENCLRR_SPDIFLPEN BIT(26)
+#define RCC_MC_APB1LPENCLRR_CECLPEN BIT(27)
+#define RCC_MC_APB1LPENCLRR_WWDG1LPEN BIT(28)
+#define RCC_MC_APB1LPENCLRR_DAC12LPEN BIT(29)
+#define RCC_MC_APB1LPENCLRR_MDIOSLPEN BIT(31)
+
+/* RCC_MC_APB2LPENSETR register fields */
+#define RCC_MC_APB2LPENSETR_TIM1LPEN BIT(0)
+#define RCC_MC_APB2LPENSETR_TIM8LPEN BIT(1)
+#define RCC_MC_APB2LPENSETR_TIM15LPEN BIT(2)
+#define RCC_MC_APB2LPENSETR_TIM16LPEN BIT(3)
+#define RCC_MC_APB2LPENSETR_TIM17LPEN BIT(4)
+#define RCC_MC_APB2LPENSETR_SPI1LPEN BIT(8)
+#define RCC_MC_APB2LPENSETR_SPI4LPEN BIT(9)
+#define RCC_MC_APB2LPENSETR_SPI5LPEN BIT(10)
+#define RCC_MC_APB2LPENSETR_USART6LPEN BIT(13)
+#define RCC_MC_APB2LPENSETR_SAI1LPEN BIT(16)
+#define RCC_MC_APB2LPENSETR_SAI2LPEN BIT(17)
+#define RCC_MC_APB2LPENSETR_SAI3LPEN BIT(18)
+#define RCC_MC_APB2LPENSETR_DFSDMLPEN BIT(20)
+#define RCC_MC_APB2LPENSETR_ADFSDMLPEN BIT(21)
+#define RCC_MC_APB2LPENSETR_FDCANLPEN BIT(24)
+
+/* RCC_MC_APB2LPENCLRR register fields */
+#define RCC_MC_APB2LPENCLRR_TIM1LPEN BIT(0)
+#define RCC_MC_APB2LPENCLRR_TIM8LPEN BIT(1)
+#define RCC_MC_APB2LPENCLRR_TIM15LPEN BIT(2)
+#define RCC_MC_APB2LPENCLRR_TIM16LPEN BIT(3)
+#define RCC_MC_APB2LPENCLRR_TIM17LPEN BIT(4)
+#define RCC_MC_APB2LPENCLRR_SPI1LPEN BIT(8)
+#define RCC_MC_APB2LPENCLRR_SPI4LPEN BIT(9)
+#define RCC_MC_APB2LPENCLRR_SPI5LPEN BIT(10)
+#define RCC_MC_APB2LPENCLRR_USART6LPEN BIT(13)
+#define RCC_MC_APB2LPENCLRR_SAI1LPEN BIT(16)
+#define RCC_MC_APB2LPENCLRR_SAI2LPEN BIT(17)
+#define RCC_MC_APB2LPENCLRR_SAI3LPEN BIT(18)
+#define RCC_MC_APB2LPENCLRR_DFSDMLPEN BIT(20)
+#define RCC_MC_APB2LPENCLRR_ADFSDMLPEN BIT(21)
+#define RCC_MC_APB2LPENCLRR_FDCANLPEN BIT(24)
+
+/* RCC_MC_APB3LPENSETR register fields */
+#define RCC_MC_APB3LPENSETR_LPTIM2LPEN BIT(0)
+#define RCC_MC_APB3LPENSETR_LPTIM3LPEN BIT(1)
+#define RCC_MC_APB3LPENSETR_LPTIM4LPEN BIT(2)
+#define RCC_MC_APB3LPENSETR_LPTIM5LPEN BIT(3)
+#define RCC_MC_APB3LPENSETR_SAI4LPEN BIT(8)
+#define RCC_MC_APB3LPENSETR_SYSCFGLPEN BIT(11)
+#define RCC_MC_APB3LPENSETR_VREFLPEN BIT(13)
+#define RCC_MC_APB3LPENSETR_TMPSENSLPEN BIT(16)
+#define RCC_MC_APB3LPENSETR_PMBCTRLLPEN BIT(17)
+
+/* RCC_MC_APB3LPENCLRR register fields */
+#define RCC_MC_APB3LPENCLRR_LPTIM2LPEN BIT(0)
+#define RCC_MC_APB3LPENCLRR_LPTIM3LPEN BIT(1)
+#define RCC_MC_APB3LPENCLRR_LPTIM4LPEN BIT(2)
+#define RCC_MC_APB3LPENCLRR_LPTIM5LPEN BIT(3)
+#define RCC_MC_APB3LPENCLRR_SAI4LPEN BIT(8)
+#define RCC_MC_APB3LPENCLRR_SYSCFGLPEN BIT(11)
+#define RCC_MC_APB3LPENCLRR_VREFLPEN BIT(13)
+#define RCC_MC_APB3LPENCLRR_TMPSENSLPEN BIT(16)
+#define RCC_MC_APB3LPENCLRR_PMBCTRLLPEN BIT(17)
+
+/* RCC_MC_AHB2LPENSETR register fields */
+#define RCC_MC_AHB2LPENSETR_DMA1LPEN BIT(0)
+#define RCC_MC_AHB2LPENSETR_DMA2LPEN BIT(1)
+#define RCC_MC_AHB2LPENSETR_DMAMUXLPEN BIT(2)
+#define RCC_MC_AHB2LPENSETR_ADC12LPEN BIT(5)
+#define RCC_MC_AHB2LPENSETR_USBOLPEN BIT(8)
+#define RCC_MC_AHB2LPENSETR_SDMMC3LPEN BIT(16)
+
+/* RCC_MC_AHB2LPENCLRR register fields */
+#define RCC_MC_AHB2LPENCLRR_DMA1LPEN BIT(0)
+#define RCC_MC_AHB2LPENCLRR_DMA2LPEN BIT(1)
+#define RCC_MC_AHB2LPENCLRR_DMAMUXLPEN BIT(2)
+#define RCC_MC_AHB2LPENCLRR_ADC12LPEN BIT(5)
+#define RCC_MC_AHB2LPENCLRR_USBOLPEN BIT(8)
+#define RCC_MC_AHB2LPENCLRR_SDMMC3LPEN BIT(16)
+
+/* RCC_MC_AHB3LPENSETR register fields */
+#define RCC_MC_AHB3LPENSETR_DCMILPEN BIT(0)
+#define RCC_MC_AHB3LPENSETR_CRYP2LPEN BIT(4)
+#define RCC_MC_AHB3LPENSETR_HASH2LPEN BIT(5)
+#define RCC_MC_AHB3LPENSETR_RNG2LPEN BIT(6)
+#define RCC_MC_AHB3LPENSETR_CRC2LPEN BIT(7)
+#define RCC_MC_AHB3LPENSETR_HSEMLPEN BIT(11)
+#define RCC_MC_AHB3LPENSETR_IPCCLPEN BIT(12)
+
+/* RCC_MC_AHB3LPENCLRR register fields */
+#define RCC_MC_AHB3LPENCLRR_DCMILPEN BIT(0)
+#define RCC_MC_AHB3LPENCLRR_CRYP2LPEN BIT(4)
+#define RCC_MC_AHB3LPENCLRR_HASH2LPEN BIT(5)
+#define RCC_MC_AHB3LPENCLRR_RNG2LPEN BIT(6)
+#define RCC_MC_AHB3LPENCLRR_CRC2LPEN BIT(7)
+#define RCC_MC_AHB3LPENCLRR_HSEMLPEN BIT(11)
+#define RCC_MC_AHB3LPENCLRR_IPCCLPEN BIT(12)
+
+/* RCC_MC_AHB4LPENSETR register fields */
+#define RCC_MC_AHB4LPENSETR_GPIOALPEN BIT(0)
+#define RCC_MC_AHB4LPENSETR_GPIOBLPEN BIT(1)
+#define RCC_MC_AHB4LPENSETR_GPIOCLPEN BIT(2)
+#define RCC_MC_AHB4LPENSETR_GPIODLPEN BIT(3)
+#define RCC_MC_AHB4LPENSETR_GPIOELPEN BIT(4)
+#define RCC_MC_AHB4LPENSETR_GPIOFLPEN BIT(5)
+#define RCC_MC_AHB4LPENSETR_GPIOGLPEN BIT(6)
+#define RCC_MC_AHB4LPENSETR_GPIOHLPEN BIT(7)
+#define RCC_MC_AHB4LPENSETR_GPIOILPEN BIT(8)
+#define RCC_MC_AHB4LPENSETR_GPIOJLPEN BIT(9)
+#define RCC_MC_AHB4LPENSETR_GPIOKLPEN BIT(10)
+
+/* RCC_MC_AHB4LPENCLRR register fields */
+#define RCC_MC_AHB4LPENCLRR_GPIOALPEN BIT(0)
+#define RCC_MC_AHB4LPENCLRR_GPIOBLPEN BIT(1)
+#define RCC_MC_AHB4LPENCLRR_GPIOCLPEN BIT(2)
+#define RCC_MC_AHB4LPENCLRR_GPIODLPEN BIT(3)
+#define RCC_MC_AHB4LPENCLRR_GPIOELPEN BIT(4)
+#define RCC_MC_AHB4LPENCLRR_GPIOFLPEN BIT(5)
+#define RCC_MC_AHB4LPENCLRR_GPIOGLPEN BIT(6)
+#define RCC_MC_AHB4LPENCLRR_GPIOHLPEN BIT(7)
+#define RCC_MC_AHB4LPENCLRR_GPIOILPEN BIT(8)
+#define RCC_MC_AHB4LPENCLRR_GPIOJLPEN BIT(9)
+#define RCC_MC_AHB4LPENCLRR_GPIOKLPEN BIT(10)
+
+/* RCC_MC_AXIMLPENSETR register fields */
+#define RCC_MC_AXIMLPENSETR_SYSRAMLPEN BIT(0)
+
+/* RCC_MC_AXIMLPENCLRR register fields */
+#define RCC_MC_AXIMLPENCLRR_SYSRAMLPEN BIT(0)
+
+/* RCC_MC_MLAHBLPENSETR register fields */
+#define RCC_MC_MLAHBLPENSETR_SRAM1LPEN BIT(0)
+#define RCC_MC_MLAHBLPENSETR_SRAM2LPEN BIT(1)
+#define RCC_MC_MLAHBLPENSETR_SRAM34LPEN BIT(2)
+#define RCC_MC_MLAHBLPENSETR_RETRAMLPEN BIT(4)
+
+/* RCC_MC_MLAHBLPENCLRR register fields */
+#define RCC_MC_MLAHBLPENCLRR_SRAM1LPEN BIT(0)
+#define RCC_MC_MLAHBLPENCLRR_SRAM2LPEN BIT(1)
+#define RCC_MC_MLAHBLPENCLRR_SRAM34LPEN BIT(2)
+#define RCC_MC_MLAHBLPENCLRR_RETRAMLPEN BIT(4)
+
+/* RCC_MC_RSTSCLRR register fields */
+#define RCC_MC_RSTSCLRR_PORRSTF BIT(0)
+#define RCC_MC_RSTSCLRR_BORRSTF BIT(1)
+#define RCC_MC_RSTSCLRR_PADRSTF BIT(2)
+#define RCC_MC_RSTSCLRR_HCSSRSTF BIT(3)
+#define RCC_MC_RSTSCLRR_VCORERSTF BIT(4)
+#define RCC_MC_RSTSCLRR_MCURSTF BIT(5)
+#define RCC_MC_RSTSCLRR_MPSYSRSTF BIT(6)
+#define RCC_MC_RSTSCLRR_MCSYSRSTF BIT(7)
+#define RCC_MC_RSTSCLRR_IWDG1RSTF BIT(8)
+#define RCC_MC_RSTSCLRR_IWDG2RSTF BIT(9)
+#define RCC_MC_RSTSCLRR_WWDG1RSTF BIT(10)
+
+/* RCC_MC_CIER register fields */
+#define RCC_MC_CIER_LSIRDYIE BIT(0)
+#define RCC_MC_CIER_LSERDYIE BIT(1)
+#define RCC_MC_CIER_HSIRDYIE BIT(2)
+#define RCC_MC_CIER_HSERDYIE BIT(3)
+#define RCC_MC_CIER_CSIRDYIE BIT(4)
+#define RCC_MC_CIER_PLL1DYIE BIT(8)
+#define RCC_MC_CIER_PLL2DYIE BIT(9)
+#define RCC_MC_CIER_PLL3DYIE BIT(10)
+#define RCC_MC_CIER_PLL4DYIE BIT(11)
+#define RCC_MC_CIER_LSECSSIE BIT(16)
+#define RCC_MC_CIER_WKUPIE BIT(20)
+
+/* RCC_MC_CIFR register fields */
+#define RCC_MC_CIFR_LSIRDYF BIT(0)
+#define RCC_MC_CIFR_LSERDYF BIT(1)
+#define RCC_MC_CIFR_HSIRDYF BIT(2)
+#define RCC_MC_CIFR_HSERDYF BIT(3)
+#define RCC_MC_CIFR_CSIRDYF BIT(4)
+#define RCC_MC_CIFR_PLL1DYF BIT(8)
+#define RCC_MC_CIFR_PLL2DYF BIT(9)
+#define RCC_MC_CIFR_PLL3DYF BIT(10)
+#define RCC_MC_CIFR_PLL4DYF BIT(11)
+#define RCC_MC_CIFR_LSECSSF BIT(16)
+#define RCC_MC_CIFR_WKUPF BIT(20)
+
+/* RCC_VERR register fields */
+#define RCC_VERR_MINREV_MASK GENMASK(3, 0)
+#define RCC_VERR_MINREV_SHIFT 0
+#define RCC_VERR_MAJREV_MASK GENMASK(7, 4)
+#define RCC_VERR_MAJREV_SHIFT 4
+
+/* Used for RCC_OCENSETR and RCC_OCENCLRR registers */
+#define RCC_OCENR_HSION BIT(0)
+#define RCC_OCENR_HSIKERON BIT(1)
+#define RCC_OCENR_CSION BIT(4)
+#define RCC_OCENR_CSIKERON BIT(5)
+#define RCC_OCENR_DIGBYP BIT(7)
+#define RCC_OCENR_HSEON BIT(8)
+#define RCC_OCENR_HSEKERON BIT(9)
+#define RCC_OCENR_HSEBYP BIT(10)
+#define RCC_OCENR_HSECSSON BIT(11)
+
+/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */
+#define RCC_MP_ENCLRR_OFFSET U(4)
+
+/* Offset between RCC_xxxRSTSETR and RCC_xxxRSTCLRR registers */
+#define RCC_RSTCLRR_OFFSET U(4)
+
+/* Used for most of DIVR register: max div for RTC */
+#define RCC_DIVR_DIV_MASK GENMASK(5, 0)
+#define RCC_DIVR_DIVRDY BIT(31)
+
+/* Masks for specific DIVR registers */
+#define RCC_APBXDIV_MASK GENMASK(2, 0)
+#define RCC_MPUDIV_MASK GENMASK(2, 0)
+#define RCC_AXIDIV_MASK GENMASK(2, 0)
+#define RCC_MCUDIV_MASK GENMASK(3, 0)
+
+/* Used for most of RCC_<x>SELR registers */
+#define RCC_SELR_SRC_MASK GENMASK(2, 0)
+#define RCC_SELR_REFCLK_SRC_MASK GENMASK(1, 0)
+#define RCC_SELR_SRCRDY BIT(31)
+
+/* Used for all RCC_PLL<n>CR registers */
+#define RCC_PLLNCR_PLLON BIT(0)
+#define RCC_PLLNCR_PLLRDY BIT(1)
+#define RCC_PLLNCR_SSCG_CTRL BIT(2)
+#define RCC_PLLNCR_DIVPEN BIT(4)
+#define RCC_PLLNCR_DIVQEN BIT(5)
+#define RCC_PLLNCR_DIVREN BIT(6)
+#define RCC_PLLNCR_DIVEN_SHIFT 4
+
+/* Used for all RCC_PLL<n>CFGR1 registers */
+#define RCC_PLLNCFGR1_DIVM_MASK GENMASK(21, 16)
+#define RCC_PLLNCFGR1_DIVM_SHIFT 16
+#define RCC_PLLNCFGR1_DIVN_MASK GENMASK(8, 0)
+#define RCC_PLLNCFGR1_DIVN_SHIFT 0
+
+/* Only for PLL3 and PLL4 */
+#define RCC_PLLNCFGR1_IFRGE_MASK GENMASK(25, 24)
+#define RCC_PLLNCFGR1_IFRGE_SHIFT 24
+
+/* Used for all RCC_PLL<n>CFGR2 registers */
+#define RCC_PLLNCFGR2_DIVX_MASK GENMASK(6, 0)
+#define RCC_PLLNCFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLLNCFGR2_DIVP_SHIFT 0
+#define RCC_PLLNCFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLLNCFGR2_DIVQ_SHIFT 8
+#define RCC_PLLNCFGR2_DIVR_MASK GENMASK(22, 16)
+#define RCC_PLLNCFGR2_DIVR_SHIFT 16
+
+/* Used for all RCC_PLL<n>FRACR registers */
+#define RCC_PLLNFRACR_FRACV_SHIFT 3
+#define RCC_PLLNFRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLLNFRACR_FRACLE BIT(16)
+
+/* Used for all RCC_PLL<n>CSGR registers */
+#define RCC_PLLNCSGR_INC_STEP_SHIFT 16
+#define RCC_PLLNCSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLLNCSGR_MOD_PER_SHIFT 0
+#define RCC_PLLNCSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLLNCSGR_SSCG_MODE_SHIFT 15
+#define RCC_PLLNCSGR_SSCG_MODE_MASK BIT(15)
+
+/* Used for TIMER Prescaler */
+#define RCC_TIMGXPRER_TIMGXPRE BIT(0)
+
+/* Used for RCC_MCO related operations */
+#define RCC_MCOCFG_MCOON BIT(12)
+#define RCC_MCOCFG_MCODIV_MASK GENMASK(7, 4)
+#define RCC_MCOCFG_MCODIV_SHIFT 4
+#define RCC_MCOCFG_MCOSRC_MASK GENMASK(2, 0)
+
+#endif /* STM32MP1_RCC_H */
diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h
index 14f93fd..d794225 100644
--- a/include/drivers/st/stm32mp1_rcc.h
+++ b/include/drivers/st/stm32mp1_rcc.h
@@ -1,2328 +1,12 @@
/*
- * Copyright (c) 2015-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef STM32MP1_RCC_H
-#define STM32MP1_RCC_H
-
-#include <lib/utils_def.h>
-
-#define RCC_TZCR U(0x00)
-#define RCC_OCENSETR U(0x0C)
-#define RCC_OCENCLRR U(0x10)
-#define RCC_HSICFGR U(0x18)
-#define RCC_CSICFGR U(0x1C)
-#define RCC_MPCKSELR U(0x20)
-#define RCC_ASSCKSELR U(0x24)
-#define RCC_RCK12SELR U(0x28)
-#define RCC_MPCKDIVR U(0x2C)
-#define RCC_AXIDIVR U(0x30)
-#define RCC_APB4DIVR U(0x3C)
-#define RCC_APB5DIVR U(0x40)
-#define RCC_RTCDIVR U(0x44)
-#define RCC_MSSCKSELR U(0x48)
-#define RCC_PLL1CR U(0x80)
-#define RCC_PLL1CFGR1 U(0x84)
-#define RCC_PLL1CFGR2 U(0x88)
-#define RCC_PLL1FRACR U(0x8C)
-#define RCC_PLL1CSGR U(0x90)
-#define RCC_PLL2CR U(0x94)
-#define RCC_PLL2CFGR1 U(0x98)
-#define RCC_PLL2CFGR2 U(0x9C)
-#define RCC_PLL2FRACR U(0xA0)
-#define RCC_PLL2CSGR U(0xA4)
-#define RCC_I2C46CKSELR U(0xC0)
-#define RCC_SPI6CKSELR U(0xC4)
-#define RCC_UART1CKSELR U(0xC8)
-#define RCC_RNG1CKSELR U(0xCC)
-#define RCC_CPERCKSELR U(0xD0)
-#define RCC_STGENCKSELR U(0xD4)
-#define RCC_DDRITFCR U(0xD8)
-#define RCC_MP_BOOTCR U(0x100)
-#define RCC_MP_SREQSETR U(0x104)
-#define RCC_MP_SREQCLRR U(0x108)
-#define RCC_MP_GCR U(0x10C)
-#define RCC_MP_APRSTCR U(0x110)
-#define RCC_MP_APRSTSR U(0x114)
-#define RCC_BDCR U(0x140)
-#define RCC_RDLSICR U(0x144)
-#define RCC_APB4RSTSETR U(0x180)
-#define RCC_APB4RSTCLRR U(0x184)
-#define RCC_APB5RSTSETR U(0x188)
-#define RCC_APB5RSTCLRR U(0x18C)
-#define RCC_AHB5RSTSETR U(0x190)
-#define RCC_AHB5RSTCLRR U(0x194)
-#define RCC_AHB6RSTSETR U(0x198)
-#define RCC_AHB6RSTCLRR U(0x19C)
-#define RCC_TZAHB6RSTSETR U(0x1A0)
-#define RCC_TZAHB6RSTCLRR U(0x1A4)
-#define RCC_MP_APB4ENSETR U(0x200)
-#define RCC_MP_APB4ENCLRR U(0x204)
-#define RCC_MP_APB5ENSETR U(0x208)
-#define RCC_MP_APB5ENCLRR U(0x20C)
-#define RCC_MP_AHB5ENSETR U(0x210)
-#define RCC_MP_AHB5ENCLRR U(0x214)
-#define RCC_MP_AHB6ENSETR U(0x218)
-#define RCC_MP_AHB6ENCLRR U(0x21C)
-#define RCC_MP_TZAHB6ENSETR U(0x220)
-#define RCC_MP_TZAHB6ENCLRR U(0x224)
-#define RCC_MC_APB4ENSETR U(0x280)
-#define RCC_MC_APB4ENCLRR U(0x284)
-#define RCC_MC_APB5ENSETR U(0x288)
-#define RCC_MC_APB5ENCLRR U(0x28C)
-#define RCC_MC_AHB5ENSETR U(0x290)
-#define RCC_MC_AHB5ENCLRR U(0x294)
-#define RCC_MC_AHB6ENSETR U(0x298)
-#define RCC_MC_AHB6ENCLRR U(0x29C)
-#define RCC_MP_APB4LPENSETR U(0x300)
-#define RCC_MP_APB4LPENCLRR U(0x304)
-#define RCC_MP_APB5LPENSETR U(0x308)
-#define RCC_MP_APB5LPENCLRR U(0x30C)
-#define RCC_MP_AHB5LPENSETR U(0x310)
-#define RCC_MP_AHB5LPENCLRR U(0x314)
-#define RCC_MP_AHB6LPENSETR U(0x318)
-#define RCC_MP_AHB6LPENCLRR U(0x31C)
-#define RCC_MP_TZAHB6LPENSETR U(0x320)
-#define RCC_MP_TZAHB6LPENCLRR U(0x324)
-#define RCC_MC_APB4LPENSETR U(0x380)
-#define RCC_MC_APB4LPENCLRR U(0x384)
-#define RCC_MC_APB5LPENSETR U(0x388)
-#define RCC_MC_APB5LPENCLRR U(0x38C)
-#define RCC_MC_AHB5LPENSETR U(0x390)
-#define RCC_MC_AHB5LPENCLRR U(0x394)
-#define RCC_MC_AHB6LPENSETR U(0x398)
-#define RCC_MC_AHB6LPENCLRR U(0x39C)
-#define RCC_BR_RSTSCLRR U(0x400)
-#define RCC_MP_GRSTCSETR U(0x404)
-#define RCC_MP_RSTSCLRR U(0x408)
-#define RCC_MP_IWDGFZSETR U(0x40C)
-#define RCC_MP_IWDGFZCLRR U(0x410)
-#define RCC_MP_CIER U(0x414)
-#define RCC_MP_CIFR U(0x418)
-#define RCC_PWRLPDLYCR U(0x41C)
-#define RCC_MP_RSTSSETR U(0x420)
-#define RCC_MCO1CFGR U(0x800)
-#define RCC_MCO2CFGR U(0x804)
-#define RCC_OCRDYR U(0x808)
-#define RCC_DBGCFGR U(0x80C)
-#define RCC_RCK3SELR U(0x820)
-#define RCC_RCK4SELR U(0x824)
-#define RCC_TIMG1PRER U(0x828)
-#define RCC_TIMG2PRER U(0x82C)
-#define RCC_MCUDIVR U(0x830)
-#define RCC_APB1DIVR U(0x834)
-#define RCC_APB2DIVR U(0x838)
-#define RCC_APB3DIVR U(0x83C)
-#define RCC_PLL3CR U(0x880)
-#define RCC_PLL3CFGR1 U(0x884)
-#define RCC_PLL3CFGR2 U(0x888)
-#define RCC_PLL3FRACR U(0x88C)
-#define RCC_PLL3CSGR U(0x890)
-#define RCC_PLL4CR U(0x894)
-#define RCC_PLL4CFGR1 U(0x898)
-#define RCC_PLL4CFGR2 U(0x89C)
-#define RCC_PLL4FRACR U(0x8A0)
-#define RCC_PLL4CSGR U(0x8A4)
-#define RCC_I2C12CKSELR U(0x8C0)
-#define RCC_I2C35CKSELR U(0x8C4)
-#define RCC_SAI1CKSELR U(0x8C8)
-#define RCC_SAI2CKSELR U(0x8CC)
-#define RCC_SAI3CKSELR U(0x8D0)
-#define RCC_SAI4CKSELR U(0x8D4)
-#define RCC_SPI2S1CKSELR U(0x8D8)
-#define RCC_SPI2S23CKSELR U(0x8DC)
-#define RCC_SPI45CKSELR U(0x8E0)
-#define RCC_UART6CKSELR U(0x8E4)
-#define RCC_UART24CKSELR U(0x8E8)
-#define RCC_UART35CKSELR U(0x8EC)
-#define RCC_UART78CKSELR U(0x8F0)
-#define RCC_SDMMC12CKSELR U(0x8F4)
-#define RCC_SDMMC3CKSELR U(0x8F8)
-#define RCC_ETHCKSELR U(0x8FC)
-#define RCC_QSPICKSELR U(0x900)
-#define RCC_FMCCKSELR U(0x904)
-#define RCC_FDCANCKSELR U(0x90C)
-#define RCC_SPDIFCKSELR U(0x914)
-#define RCC_CECCKSELR U(0x918)
-#define RCC_USBCKSELR U(0x91C)
-#define RCC_RNG2CKSELR U(0x920)
-#define RCC_DSICKSELR U(0x924)
-#define RCC_ADCCKSELR U(0x928)
-#define RCC_LPTIM45CKSELR U(0x92C)
-#define RCC_LPTIM23CKSELR U(0x930)
-#define RCC_LPTIM1CKSELR U(0x934)
-#define RCC_APB1RSTSETR U(0x980)
-#define RCC_APB1RSTCLRR U(0x984)
-#define RCC_APB2RSTSETR U(0x988)
-#define RCC_APB2RSTCLRR U(0x98C)
-#define RCC_APB3RSTSETR U(0x990)
-#define RCC_APB3RSTCLRR U(0x994)
-#define RCC_AHB2RSTSETR U(0x998)
-#define RCC_AHB2RSTCLRR U(0x99C)
-#define RCC_AHB3RSTSETR U(0x9A0)
-#define RCC_AHB3RSTCLRR U(0x9A4)
-#define RCC_AHB4RSTSETR U(0x9A8)
-#define RCC_AHB4RSTCLRR U(0x9AC)
-#define RCC_MP_APB1ENSETR U(0xA00)
-#define RCC_MP_APB1ENCLRR U(0xA04)
-#define RCC_MP_APB2ENSETR U(0xA08)
-#define RCC_MP_APB2ENCLRR U(0xA0C)
-#define RCC_MP_APB3ENSETR U(0xA10)
-#define RCC_MP_APB3ENCLRR U(0xA14)
-#define RCC_MP_AHB2ENSETR U(0xA18)
-#define RCC_MP_AHB2ENCLRR U(0xA1C)
-#define RCC_MP_AHB3ENSETR U(0xA20)
-#define RCC_MP_AHB3ENCLRR U(0xA24)
-#define RCC_MP_AHB4ENSETR U(0xA28)
-#define RCC_MP_AHB4ENCLRR U(0xA2C)
-#define RCC_MP_MLAHBENSETR U(0xA38)
-#define RCC_MP_MLAHBENCLRR U(0xA3C)
-#define RCC_MC_APB1ENSETR U(0xA80)
-#define RCC_MC_APB1ENCLRR U(0xA84)
-#define RCC_MC_APB2ENSETR U(0xA88)
-#define RCC_MC_APB2ENCLRR U(0xA8C)
-#define RCC_MC_APB3ENSETR U(0xA90)
-#define RCC_MC_APB3ENCLRR U(0xA94)
-#define RCC_MC_AHB2ENSETR U(0xA98)
-#define RCC_MC_AHB2ENCLRR U(0xA9C)
-#define RCC_MC_AHB3ENSETR U(0xAA0)
-#define RCC_MC_AHB3ENCLRR U(0xAA4)
-#define RCC_MC_AHB4ENSETR U(0xAA8)
-#define RCC_MC_AHB4ENCLRR U(0xAAC)
-#define RCC_MC_AXIMENSETR U(0xAB0)
-#define RCC_MC_AXIMENCLRR U(0xAB4)
-#define RCC_MC_MLAHBENSETR U(0xAB8)
-#define RCC_MC_MLAHBENCLRR U(0xABC)
-#define RCC_MP_APB1LPENSETR U(0xB00)
-#define RCC_MP_APB1LPENCLRR U(0xB04)
-#define RCC_MP_APB2LPENSETR U(0xB08)
-#define RCC_MP_APB2LPENCLRR U(0xB0C)
-#define RCC_MP_APB3LPENSETR U(0xB10)
-#define RCC_MP_APB3LPENCLRR U(0xB14)
-#define RCC_MP_AHB2LPENSETR U(0xB18)
-#define RCC_MP_AHB2LPENCLRR U(0xB1C)
-#define RCC_MP_AHB3LPENSETR U(0xB20)
-#define RCC_MP_AHB3LPENCLRR U(0xB24)
-#define RCC_MP_AHB4LPENSETR U(0xB28)
-#define RCC_MP_AHB4LPENCLRR U(0xB2C)
-#define RCC_MP_AXIMLPENSETR U(0xB30)
-#define RCC_MP_AXIMLPENCLRR U(0xB34)
-#define RCC_MP_MLAHBLPENSETR U(0xB38)
-#define RCC_MP_MLAHBLPENCLRR U(0xB3C)
-#define RCC_MC_APB1LPENSETR U(0xB80)
-#define RCC_MC_APB1LPENCLRR U(0xB84)
-#define RCC_MC_APB2LPENSETR U(0xB88)
-#define RCC_MC_APB2LPENCLRR U(0xB8C)
-#define RCC_MC_APB3LPENSETR U(0xB90)
-#define RCC_MC_APB3LPENCLRR U(0xB94)
-#define RCC_MC_AHB2LPENSETR U(0xB98)
-#define RCC_MC_AHB2LPENCLRR U(0xB9C)
-#define RCC_MC_AHB3LPENSETR U(0xBA0)
-#define RCC_MC_AHB3LPENCLRR U(0xBA4)
-#define RCC_MC_AHB4LPENSETR U(0xBA8)
-#define RCC_MC_AHB4LPENCLRR U(0xBAC)
-#define RCC_MC_AXIMLPENSETR U(0xBB0)
-#define RCC_MC_AXIMLPENCLRR U(0xBB4)
-#define RCC_MC_MLAHBLPENSETR U(0xBB8)
-#define RCC_MC_MLAHBLPENCLRR U(0xBBC)
-#define RCC_MC_RSTSCLRR U(0xC00)
-#define RCC_MC_CIER U(0xC14)
-#define RCC_MC_CIFR U(0xC18)
-#define RCC_VERR U(0xFF4)
-#define RCC_IDR U(0xFF8)
-#define RCC_SIDR U(0xFFC)
-
-/* RCC_TZCR register fields */
-#define RCC_TZCR_TZEN BIT(0)
-#define RCC_TZCR_MCKPROT BIT(1)
-
-/* RCC_OCENSETR register fields */
-#define RCC_OCENSETR_HSION BIT(0)
-#define RCC_OCENSETR_HSIKERON BIT(1)
-#define RCC_OCENSETR_CSION BIT(4)
-#define RCC_OCENSETR_CSIKERON BIT(5)
-#define RCC_OCENSETR_DIGBYP BIT(7)
-#define RCC_OCENSETR_HSEON BIT(8)
-#define RCC_OCENSETR_HSEKERON BIT(9)
-#define RCC_OCENSETR_HSEBYP BIT(10)
-#define RCC_OCENSETR_HSECSSON BIT(11)
-
-/* RCC_OCENCLRR register fields */
-#define RCC_OCENCLRR_HSION BIT(0)
-#define RCC_OCENCLRR_HSIKERON BIT(1)
-#define RCC_OCENCLRR_CSION BIT(4)
-#define RCC_OCENCLRR_CSIKERON BIT(5)
-#define RCC_OCENCLRR_DIGBYP BIT(7)
-#define RCC_OCENCLRR_HSEON BIT(8)
-#define RCC_OCENCLRR_HSEKERON BIT(9)
-#define RCC_OCENCLRR_HSEBYP BIT(10)
-
-/* RCC_HSICFGR register fields */
-#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0)
-#define RCC_HSICFGR_HSIDIV_SHIFT 0
-#define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8)
-#define RCC_HSICFGR_HSITRIM_SHIFT 8
-#define RCC_HSICFGR_HSICAL_MASK GENMASK(24, 16)
-#define RCC_HSICFGR_HSICAL_SHIFT 16
-#define RCC_HSICFGR_HSICAL_TEMP_MASK GENMASK(27, 25)
-
-/* RCC_CSICFGR register fields */
-#define RCC_CSICFGR_CSITRIM_MASK GENMASK(12, 8)
-#define RCC_CSICFGR_CSITRIM_SHIFT 8
-#define RCC_CSICFGR_CSICAL_MASK GENMASK(23, 16)
-#define RCC_CSICFGR_CSICAL_SHIFT 16
-
-/* RCC_MPCKSELR register fields */
-#define RCC_MPCKSELR_HSI 0x00000000
-#define RCC_MPCKSELR_HSE 0x00000001
-#define RCC_MPCKSELR_PLL 0x00000002
-#define RCC_MPCKSELR_PLL_MPUDIV 0x00000003
-#define RCC_MPCKSELR_MPUSRC_MASK GENMASK(1, 0)
-#define RCC_MPCKSELR_MPUSRC_SHIFT 0
-#define RCC_MPCKSELR_MPUSRCRDY BIT(31)
-
-/* RCC_ASSCKSELR register fields */
-#define RCC_ASSCKSELR_HSI 0x00000000
-#define RCC_ASSCKSELR_HSE 0x00000001
-#define RCC_ASSCKSELR_PLL 0x00000002
-#define RCC_ASSCKSELR_AXISSRC_MASK GENMASK(2, 0)
-#define RCC_ASSCKSELR_AXISSRC_SHIFT 0
-#define RCC_ASSCKSELR_AXISSRCRDY BIT(31)
-
-/* RCC_RCK12SELR register fields */
-#define RCC_RCK12SELR_PLL12SRC_MASK GENMASK(1, 0)
-#define RCC_RCK12SELR_PLL12SRC_SHIFT 0
-#define RCC_RCK12SELR_PLL12SRCRDY BIT(31)
-
-/* RCC_MPCKDIVR register fields */
-#define RCC_MPCKDIVR_MPUDIV_MASK GENMASK(2, 0)
-#define RCC_MPCKDIVR_MPUDIV_SHIFT 0
-#define RCC_MPCKDIVR_MPUDIVRDY BIT(31)
-
-/* RCC_AXIDIVR register fields */
-#define RCC_AXIDIVR_AXIDIV_MASK GENMASK(2, 0)
-#define RCC_AXIDIVR_AXIDIV_SHIFT 0
-#define RCC_AXIDIVR_AXIDIVRDY BIT(31)
-
-/* RCC_APB4DIVR register fields */
-#define RCC_APB4DIVR_APB4DIV_MASK GENMASK(2, 0)
-#define RCC_APB4DIVR_APB4DIV_SHIFT 0
-#define RCC_APB4DIVR_APB4DIVRDY BIT(31)
-
-/* RCC_APB5DIVR register fields */
-#define RCC_APB5DIVR_APB5DIV_MASK GENMASK(2, 0)
-#define RCC_APB5DIVR_APB5DIV_SHIFT 0
-#define RCC_APB5DIVR_APB5DIVRDY BIT(31)
-
-/* RCC_RTCDIVR register fields */
-#define RCC_RTCDIVR_RTCDIV_MASK GENMASK(5, 0)
-#define RCC_RTCDIVR_RTCDIV_SHIFT 0
-
-/* RCC_MSSCKSELR register fields */
-#define RCC_MSSCKSELR_HSI 0x00000000
-#define RCC_MSSCKSELR_HSE 0x00000001
-#define RCC_MSSCKSELR_CSI 0x00000002
-#define RCC_MSSCKSELR_PLL 0x00000003
-#define RCC_MSSCKSELR_MCUSSRC_MASK GENMASK(1, 0)
-#define RCC_MSSCKSELR_MCUSSRC_SHIFT 0
-#define RCC_MSSCKSELR_MCUSSRCRDY BIT(31)
-
-/* RCC_PLL1CR register fields */
-#define RCC_PLL1CR_PLLON BIT(0)
-#define RCC_PLL1CR_PLL1RDY BIT(1)
-#define RCC_PLL1CR_SSCG_CTRL BIT(2)
-#define RCC_PLL1CR_DIVPEN BIT(4)
-#define RCC_PLL1CR_DIVQEN BIT(5)
-#define RCC_PLL1CR_DIVREN BIT(6)
-
-/* RCC_PLL1CFGR1 register fields */
-#define RCC_PLL1CFGR1_DIVN_MASK GENMASK(8, 0)
-#define RCC_PLL1CFGR1_DIVN_SHIFT 0
-#define RCC_PLL1CFGR1_DIVM1_MASK GENMASK(21, 16)
-#define RCC_PLL1CFGR1_DIVM1_SHIFT 16
-
-/* RCC_PLL1CFGR2 register fields */
-#define RCC_PLL1CFGR2_DIVP_MASK GENMASK(6, 0)
-#define RCC_PLL1CFGR2_DIVP_SHIFT 0
-#define RCC_PLL1CFGR2_DIVQ_MASK GENMASK(14, 8)
-#define RCC_PLL1CFGR2_DIVQ_SHIFT 8
-#define RCC_PLL1CFGR2_DIVR_MASK GENMASK(22, 16)
-#define RCC_PLL1CFGR2_DIVR_SHIFT 16
-
-/* RCC_PLL1FRACR register fields */
-#define RCC_PLL1FRACR_FRACV_MASK GENMASK(15, 3)
-#define RCC_PLL1FRACR_FRACV_SHIFT 3
-#define RCC_PLL1FRACR_FRACLE BIT(16)
-
-/* RCC_PLL1CSGR register fields */
-#define RCC_PLL1CSGR_MOD_PER_MASK GENMASK(12, 0)
-#define RCC_PLL1CSGR_MOD_PER_SHIFT 0
-#define RCC_PLL1CSGR_TPDFN_DIS BIT(13)
-#define RCC_PLL1CSGR_RPDFN_DIS BIT(14)
-#define RCC_PLL1CSGR_SSCG_MODE BIT(15)
-#define RCC_PLL1CSGR_INC_STEP_MASK GENMASK(30, 16)
-#define RCC_PLL1CSGR_INC_STEP_SHIFT 16
-
-/* RCC_PLL2CR register fields */
-#define RCC_PLL2CR_PLLON BIT(0)
-#define RCC_PLL2CR_PLL2RDY BIT(1)
-#define RCC_PLL2CR_SSCG_CTRL BIT(2)
-#define RCC_PLL2CR_DIVPEN BIT(4)
-#define RCC_PLL2CR_DIVQEN BIT(5)
-#define RCC_PLL2CR_DIVREN BIT(6)
-
-/* RCC_PLL2CFGR1 register fields */
-#define RCC_PLL2CFGR1_DIVN_MASK GENMASK(8, 0)
-#define RCC_PLL2CFGR1_DIVN_SHIFT 0
-#define RCC_PLL2CFGR1_DIVM2_MASK GENMASK(21, 16)
-#define RCC_PLL2CFGR1_DIVM2_SHIFT 16
-
-/* RCC_PLL2CFGR2 register fields */
-#define RCC_PLL2CFGR2_DIVP_MASK GENMASK(6, 0)
-#define RCC_PLL2CFGR2_DIVP_SHIFT 0
-#define RCC_PLL2CFGR2_DIVQ_MASK GENMASK(14, 8)
-#define RCC_PLL2CFGR2_DIVQ_SHIFT 8
-#define RCC_PLL2CFGR2_DIVR_MASK GENMASK(22, 16)
-#define RCC_PLL2CFGR2_DIVR_SHIFT 16
-
-/* RCC_PLL2FRACR register fields */
-#define RCC_PLL2FRACR_FRACV_MASK GENMASK(15, 3)
-#define RCC_PLL2FRACR_FRACV_SHIFT 3
-#define RCC_PLL2FRACR_FRACLE BIT(16)
-
-/* RCC_PLL2CSGR register fields */
-#define RCC_PLL2CSGR_MOD_PER_MASK GENMASK(12, 0)
-#define RCC_PLL2CSGR_MOD_PER_SHIFT 0
-#define RCC_PLL2CSGR_TPDFN_DIS BIT(13)
-#define RCC_PLL2CSGR_RPDFN_DIS BIT(14)
-#define RCC_PLL2CSGR_SSCG_MODE BIT(15)
-#define RCC_PLL2CSGR_INC_STEP_MASK GENMASK(30, 16)
-#define RCC_PLL2CSGR_INC_STEP_SHIFT 16
-
-/* RCC_I2C46CKSELR register fields */
-#define RCC_I2C46CKSELR_I2C46SRC_MASK GENMASK(2, 0)
-#define RCC_I2C46CKSELR_I2C46SRC_SHIFT 0
-
-/* RCC_SPI6CKSELR register fields */
-#define RCC_SPI6CKSELR_SPI6SRC_MASK GENMASK(2, 0)
-#define RCC_SPI6CKSELR_SPI6SRC_SHIFT 0
-
-/* RCC_UART1CKSELR register fields */
-#define RCC_UART1CKSELR_UART1SRC_MASK GENMASK(2, 0)
-#define RCC_UART1CKSELR_UART1SRC_SHIFT 0
-
-/* RCC_RNG1CKSELR register fields */
-#define RCC_RNG1CKSELR_RNG1SRC_MASK GENMASK(1, 0)
-#define RCC_RNG1CKSELR_RNG1SRC_SHIFT 0
-
-/* RCC_CPERCKSELR register fields */
-#define RCC_CPERCKSELR_HSI 0x00000000
-#define RCC_CPERCKSELR_CSI 0x00000001
-#define RCC_CPERCKSELR_HSE 0x00000002
-#define RCC_CPERCKSELR_CKPERSRC_MASK GENMASK(1, 0)
-#define RCC_CPERCKSELR_CKPERSRC_SHIFT 0
-
-/* RCC_STGENCKSELR register fields */
-#define RCC_STGENCKSELR_STGENSRC_MASK GENMASK(1, 0)
-#define RCC_STGENCKSELR_STGENSRC_SHIFT 0
-
-/* RCC_DDRITFCR register fields */
-#define RCC_DDRITFCR_DDRC1EN BIT(0)
-#define RCC_DDRITFCR_DDRC1LPEN BIT(1)
-#define RCC_DDRITFCR_DDRC2EN BIT(2)
-#define RCC_DDRITFCR_DDRC2LPEN BIT(3)
-#define RCC_DDRITFCR_DDRPHYCEN BIT(4)
-#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5)
-#define RCC_DDRITFCR_DDRCAPBEN BIT(6)
-#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7)
-#define RCC_DDRITFCR_AXIDCGEN BIT(8)
-#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9)
-#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10)
-#define RCC_DDRITFCR_KERDCG_DLY_MASK GENMASK(13, 11)
-#define RCC_DDRITFCR_KERDCG_DLY_SHIFT 11
-#define RCC_DDRITFCR_DDRCAPBRST BIT(14)
-#define RCC_DDRITFCR_DDRCAXIRST BIT(15)
-#define RCC_DDRITFCR_DDRCORERST BIT(16)
-#define RCC_DDRITFCR_DPHYAPBRST BIT(17)
-#define RCC_DDRITFCR_DPHYRST BIT(18)
-#define RCC_DDRITFCR_DPHYCTLRST BIT(19)
-#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20)
-#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20
-#define RCC_DDRITFCR_DDRCKMOD_SSR 0
-#define RCC_DDRITFCR_DDRCKMOD_ASR1 BIT(20)
-#define RCC_DDRITFCR_DDRCKMOD_HSR1 BIT(21)
-#define RCC_DDRITFCR_GSKPMOD BIT(23)
-#define RCC_DDRITFCR_GSKPCTRL BIT(24)
-#define RCC_DDRITFCR_DFILP_WIDTH_MASK GENMASK(27, 25)
-#define RCC_DDRITFCR_DFILP_WIDTH_SHIFT 25
-#define RCC_DDRITFCR_GSKP_DUR_MASK GENMASK(31, 28)
-#define RCC_DDRITFCR_GSKP_DUR_SHIFT 28
-
-/* RCC_MP_BOOTCR register fields */
-#define RCC_MP_BOOTCR_MCU_BEN BIT(0)
-#define RCC_MP_BOOTCR_MPU_BEN BIT(1)
-
-/* RCC_MP_SREQSETR register fields */
-#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0)
-#define RCC_MP_SREQSETR_STPREQ_P1 BIT(1)
-
-/* RCC_MP_SREQCLRR register fields */
-#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0)
-#define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1)
-
-/* RCC_MP_GCR register fields */
-#define RCC_MP_GCR_BOOT_MCU BIT(0)
-
-/* RCC_MP_APRSTCR register fields */
-#define RCC_MP_APRSTCR_RDCTLEN BIT(0)
-#define RCC_MP_APRSTCR_RSTTO_MASK GENMASK(14, 8)
-#define RCC_MP_APRSTCR_RSTTO_SHIFT 8
-
-/* RCC_MP_APRSTSR register fields */
-#define RCC_MP_APRSTSR_RSTTOV_MASK GENMASK(14, 8)
-#define RCC_MP_APRSTSR_RSTTOV_SHIFT 8
-
-/* RCC_BDCR register fields */
-#define RCC_BDCR_LSEON BIT(0)
-#define RCC_BDCR_LSEBYP BIT(1)
-#define RCC_BDCR_LSERDY BIT(2)
-#define RCC_BDCR_DIGBYP BIT(3)
-#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4)
-#define RCC_BDCR_LSEDRV_SHIFT 4
-#define RCC_BDCR_LSECSSON BIT(8)
-#define RCC_BDCR_LSECSSD BIT(9)
-#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16)
-#define RCC_BDCR_RTCSRC_SHIFT 16
-#define RCC_BDCR_RTCCKEN BIT(20)
-#define RCC_BDCR_VSWRST BIT(31)
-
-/* RCC_RDLSICR register fields */
-#define RCC_RDLSICR_LSION BIT(0)
-#define RCC_RDLSICR_LSIRDY BIT(1)
-#define RCC_RDLSICR_MRD_MASK GENMASK(20, 16)
-#define RCC_RDLSICR_MRD_SHIFT 16
-#define RCC_RDLSICR_EADLY_MASK GENMASK(26, 24)
-#define RCC_RDLSICR_EADLY_SHIFT 24
-#define RCC_RDLSICR_SPARE_MASK GENMASK(31, 27)
-#define RCC_RDLSICR_SPARE_SHIFT 27
-
-/* RCC_APB4RSTSETR register fields */
-#define RCC_APB4RSTSETR_LTDCRST BIT(0)
-#define RCC_APB4RSTSETR_DSIRST BIT(4)
-#define RCC_APB4RSTSETR_DDRPERFMRST BIT(8)
-#define RCC_APB4RSTSETR_USBPHYRST BIT(16)
-
-/* RCC_APB4RSTCLRR register fields */
-#define RCC_APB4RSTCLRR_LTDCRST BIT(0)
-#define RCC_APB4RSTCLRR_DSIRST BIT(4)
-#define RCC_APB4RSTCLRR_DDRPERFMRST BIT(8)
-#define RCC_APB4RSTCLRR_USBPHYRST BIT(16)
-
-/* RCC_APB5RSTSETR register fields */
-#define RCC_APB5RSTSETR_SPI6RST BIT(0)
-#define RCC_APB5RSTSETR_I2C4RST BIT(2)
-#define RCC_APB5RSTSETR_I2C6RST BIT(3)
-#define RCC_APB5RSTSETR_USART1RST BIT(4)
-#define RCC_APB5RSTSETR_STGENRST BIT(20)
-
-/* RCC_APB5RSTCLRR register fields */
-#define RCC_APB5RSTCLRR_SPI6RST BIT(0)
-#define RCC_APB5RSTCLRR_I2C4RST BIT(2)
-#define RCC_APB5RSTCLRR_I2C6RST BIT(3)
-#define RCC_APB5RSTCLRR_USART1RST BIT(4)
-#define RCC_APB5RSTCLRR_STGENRST BIT(20)
-
-/* RCC_AHB5RSTSETR register fields */
-#define RCC_AHB5RSTSETR_GPIOZRST BIT(0)
-#define RCC_AHB5RSTSETR_CRYP1RST BIT(4)
-#define RCC_AHB5RSTSETR_HASH1RST BIT(5)
-#define RCC_AHB5RSTSETR_RNG1RST BIT(6)
-#define RCC_AHB5RSTSETR_AXIMCRST BIT(16)
-
-/* RCC_AHB5RSTCLRR register fields */
-#define RCC_AHB5RSTCLRR_GPIOZRST BIT(0)
-#define RCC_AHB5RSTCLRR_CRYP1RST BIT(4)
-#define RCC_AHB5RSTCLRR_HASH1RST BIT(5)
-#define RCC_AHB5RSTCLRR_RNG1RST BIT(6)
-#define RCC_AHB5RSTCLRR_AXIMCRST BIT(16)
-
-/* RCC_AHB6RSTSETR register fields */
-#define RCC_AHB6RSTSETR_GPURST BIT(5)
-#define RCC_AHB6RSTSETR_ETHMACRST BIT(10)
-#define RCC_AHB6RSTSETR_FMCRST BIT(12)
-#define RCC_AHB6RSTSETR_QSPIRST BIT(14)
-#define RCC_AHB6RSTSETR_SDMMC1RST BIT(16)
-#define RCC_AHB6RSTSETR_SDMMC2RST BIT(17)
-#define RCC_AHB6RSTSETR_CRC1RST BIT(20)
-#define RCC_AHB6RSTSETR_USBHRST BIT(24)
-
-/* RCC_AHB6RSTCLRR register fields */
-#define RCC_AHB6RSTCLRR_ETHMACRST BIT(10)
-#define RCC_AHB6RSTCLRR_FMCRST BIT(12)
-#define RCC_AHB6RSTCLRR_QSPIRST BIT(14)
-#define RCC_AHB6RSTCLRR_SDMMC1RST BIT(16)
-#define RCC_AHB6RSTCLRR_SDMMC2RST BIT(17)
-#define RCC_AHB6RSTCLRR_CRC1RST BIT(20)
-#define RCC_AHB6RSTCLRR_USBHRST BIT(24)
-
-/* RCC_TZAHB6RSTSETR register fields */
-#define RCC_TZAHB6RSTSETR_MDMARST BIT(0)
-
-/* RCC_TZAHB6RSTCLRR register fields */
-#define RCC_TZAHB6RSTCLRR_MDMARST BIT(0)
-
-/* RCC_MP_APB4ENSETR register fields */
-#define RCC_MP_APB4ENSETR_LTDCEN BIT(0)
-#define RCC_MP_APB4ENSETR_DSIEN BIT(4)
-#define RCC_MP_APB4ENSETR_DDRPERFMEN BIT(8)
-#define RCC_MP_APB4ENSETR_IWDG2APBEN BIT(15)
-#define RCC_MP_APB4ENSETR_USBPHYEN BIT(16)
-#define RCC_MP_APB4ENSETR_STGENROEN BIT(20)
-
-/* RCC_MP_APB4ENCLRR register fields */
-#define RCC_MP_APB4ENCLRR_LTDCEN BIT(0)
-#define RCC_MP_APB4ENCLRR_DSIEN BIT(4)
-#define RCC_MP_APB4ENCLRR_DDRPERFMEN BIT(8)
-#define RCC_MP_APB4ENCLRR_IWDG2APBEN BIT(15)
-#define RCC_MP_APB4ENCLRR_USBPHYEN BIT(16)
-#define RCC_MP_APB4ENCLRR_STGENROEN BIT(20)
-
-/* RCC_MP_APB5ENSETR register fields */
-#define RCC_MP_APB5ENSETR_SPI6EN BIT(0)
-#define RCC_MP_APB5ENSETR_I2C4EN BIT(2)
-#define RCC_MP_APB5ENSETR_I2C6EN BIT(3)
-#define RCC_MP_APB5ENSETR_USART1EN BIT(4)
-#define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8)
-#define RCC_MP_APB5ENSETR_TZC1EN BIT(11)
-#define RCC_MP_APB5ENSETR_TZC2EN BIT(12)
-#define RCC_MP_APB5ENSETR_TZPCEN BIT(13)
-#define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15)
-#define RCC_MP_APB5ENSETR_BSECEN BIT(16)
-#define RCC_MP_APB5ENSETR_STGENEN BIT(20)
-
-/* RCC_MP_APB5ENCLRR register fields */
-#define RCC_MP_APB5ENCLRR_SPI6EN BIT(0)
-#define RCC_MP_APB5ENCLRR_I2C4EN BIT(2)
-#define RCC_MP_APB5ENCLRR_I2C6EN BIT(3)
-#define RCC_MP_APB5ENCLRR_USART1EN BIT(4)
-#define RCC_MP_APB5ENCLRR_RTCAPBEN BIT(8)
-#define RCC_MP_APB5ENCLRR_TZC1EN BIT(11)
-#define RCC_MP_APB5ENCLRR_TZC2EN BIT(12)
-#define RCC_MP_APB5ENCLRR_TZPCEN BIT(13)
-#define RCC_MP_APB5ENCLRR_IWDG1APBEN BIT(15)
-#define RCC_MP_APB5ENCLRR_BSECEN BIT(16)
-#define RCC_MP_APB5ENCLRR_STGENEN BIT(20)
-
-/* RCC_MP_AHB5ENSETR register fields */
-#define RCC_MP_AHB5ENSETR_GPIOZEN BIT(0)
-#define RCC_MP_AHB5ENSETR_CRYP1EN BIT(4)
-#define RCC_MP_AHB5ENSETR_HASH1EN BIT(5)
-#define RCC_MP_AHB5ENSETR_RNG1EN BIT(6)
-#define RCC_MP_AHB5ENSETR_BKPSRAMEN BIT(8)
-#define RCC_MP_AHB5ENSETR_AXIMCEN BIT(16)
-
-/* RCC_MP_AHB5ENCLRR register fields */
-#define RCC_MP_AHB5ENCLRR_GPIOZEN BIT(0)
-#define RCC_MP_AHB5ENCLRR_CRYP1EN BIT(4)
-#define RCC_MP_AHB5ENCLRR_HASH1EN BIT(5)
-#define RCC_MP_AHB5ENCLRR_RNG1EN BIT(6)
-#define RCC_MP_AHB5ENCLRR_BKPSRAMEN BIT(8)
-#define RCC_MP_AHB5ENCLRR_AXIMCEN BIT(16)
-
-/* RCC_MP_AHB6ENSETR register fields */
-#define RCC_MP_AHB6ENSETR_MDMAEN BIT(0)
-#define RCC_MP_AHB6ENSETR_GPUEN BIT(5)
-#define RCC_MP_AHB6ENSETR_ETHCKEN BIT(7)
-#define RCC_MP_AHB6ENSETR_ETHTXEN BIT(8)
-#define RCC_MP_AHB6ENSETR_ETHRXEN BIT(9)
-#define RCC_MP_AHB6ENSETR_ETHMACEN BIT(10)
-#define RCC_MP_AHB6ENSETR_FMCEN BIT(12)
-#define RCC_MP_AHB6ENSETR_QSPIEN BIT(14)
-#define RCC_MP_AHB6ENSETR_SDMMC1EN BIT(16)
-#define RCC_MP_AHB6ENSETR_SDMMC2EN BIT(17)
-#define RCC_MP_AHB6ENSETR_CRC1EN BIT(20)
-#define RCC_MP_AHB6ENSETR_USBHEN BIT(24)
-
-/* RCC_MP_AHB6ENCLRR register fields */
-#define RCC_MP_AHB6ENCLRR_MDMAEN BIT(0)
-#define RCC_MP_AHB6ENCLRR_GPUEN BIT(5)
-#define RCC_MP_AHB6ENCLRR_ETHCKEN BIT(7)
-#define RCC_MP_AHB6ENCLRR_ETHTXEN BIT(8)
-#define RCC_MP_AHB6ENCLRR_ETHRXEN BIT(9)
-#define RCC_MP_AHB6ENCLRR_ETHMACEN BIT(10)
-#define RCC_MP_AHB6ENCLRR_FMCEN BIT(12)
-#define RCC_MP_AHB6ENCLRR_QSPIEN BIT(14)
-#define RCC_MP_AHB6ENCLRR_SDMMC1EN BIT(16)
-#define RCC_MP_AHB6ENCLRR_SDMMC2EN BIT(17)
-#define RCC_MP_AHB6ENCLRR_CRC1EN BIT(20)
-#define RCC_MP_AHB6ENCLRR_USBHEN BIT(24)
-
-/* RCC_MP_TZAHB6ENSETR register fields */
-#define RCC_MP_TZAHB6ENSETR_MDMAEN BIT(0)
-
-/* RCC_MP_TZAHB6ENCLRR register fields */
-#define RCC_MP_TZAHB6ENCLRR_MDMAEN BIT(0)
-
-/* RCC_MC_APB4ENSETR register fields */
-#define RCC_MC_APB4ENSETR_LTDCEN BIT(0)
-#define RCC_MC_APB4ENSETR_DSIEN BIT(4)
-#define RCC_MC_APB4ENSETR_DDRPERFMEN BIT(8)
-#define RCC_MC_APB4ENSETR_USBPHYEN BIT(16)
-#define RCC_MC_APB4ENSETR_STGENROEN BIT(20)
-
-/* RCC_MC_APB4ENCLRR register fields */
-#define RCC_MC_APB4ENCLRR_LTDCEN BIT(0)
-#define RCC_MC_APB4ENCLRR_DSIEN BIT(4)
-#define RCC_MC_APB4ENCLRR_DDRPERFMEN BIT(8)
-#define RCC_MC_APB4ENCLRR_USBPHYEN BIT(16)
-#define RCC_MC_APB4ENCLRR_STGENROEN BIT(20)
-
-/* RCC_MC_APB5ENSETR register fields */
-#define RCC_MC_APB5ENSETR_SPI6EN BIT(0)
-#define RCC_MC_APB5ENSETR_I2C4EN BIT(2)
-#define RCC_MC_APB5ENSETR_I2C6EN BIT(3)
-#define RCC_MC_APB5ENSETR_USART1EN BIT(4)
-#define RCC_MC_APB5ENSETR_RTCAPBEN BIT(8)
-#define RCC_MC_APB5ENSETR_TZC1EN BIT(11)
-#define RCC_MC_APB5ENSETR_TZC2EN BIT(12)
-#define RCC_MC_APB5ENSETR_TZPCEN BIT(13)
-#define RCC_MC_APB5ENSETR_BSECEN BIT(16)
-#define RCC_MC_APB5ENSETR_STGENEN BIT(20)
-
-/* RCC_MC_APB5ENCLRR register fields */
-#define RCC_MC_APB5ENCLRR_SPI6EN BIT(0)
-#define RCC_MC_APB5ENCLRR_I2C4EN BIT(2)
-#define RCC_MC_APB5ENCLRR_I2C6EN BIT(3)
-#define RCC_MC_APB5ENCLRR_USART1EN BIT(4)
-#define RCC_MC_APB5ENCLRR_RTCAPBEN BIT(8)
-#define RCC_MC_APB5ENCLRR_TZC1EN BIT(11)
-#define RCC_MC_APB5ENCLRR_TZC2EN BIT(12)
-#define RCC_MC_APB5ENCLRR_TZPCEN BIT(13)
-#define RCC_MC_APB5ENCLRR_BSECEN BIT(16)
-#define RCC_MC_APB5ENCLRR_STGENEN BIT(20)
-
-/* RCC_MC_AHB5ENSETR register fields */
-#define RCC_MC_AHB5ENSETR_GPIOZEN BIT(0)
-#define RCC_MC_AHB5ENSETR_CRYP1EN BIT(4)
-#define RCC_MC_AHB5ENSETR_HASH1EN BIT(5)
-#define RCC_MC_AHB5ENSETR_RNG1EN BIT(6)
-#define RCC_MC_AHB5ENSETR_BKPSRAMEN BIT(8)
-
-/* RCC_MC_AHB5ENCLRR register fields */
-#define RCC_MC_AHB5ENCLRR_GPIOZEN BIT(0)
-#define RCC_MC_AHB5ENCLRR_CRYP1EN BIT(4)
-#define RCC_MC_AHB5ENCLRR_HASH1EN BIT(5)
-#define RCC_MC_AHB5ENCLRR_RNG1EN BIT(6)
-#define RCC_MC_AHB5ENCLRR_BKPSRAMEN BIT(8)
-
-/* RCC_MC_AHB6ENSETR register fields */
-#define RCC_MC_AHB6ENSETR_MDMAEN BIT(0)
-#define RCC_MC_AHB6ENSETR_GPUEN BIT(5)
-#define RCC_MC_AHB6ENSETR_ETHCKEN BIT(7)
-#define RCC_MC_AHB6ENSETR_ETHTXEN BIT(8)
-#define RCC_MC_AHB6ENSETR_ETHRXEN BIT(9)
-#define RCC_MC_AHB6ENSETR_ETHMACEN BIT(10)
-#define RCC_MC_AHB6ENSETR_FMCEN BIT(12)
-#define RCC_MC_AHB6ENSETR_QSPIEN BIT(14)
-#define RCC_MC_AHB6ENSETR_SDMMC1EN BIT(16)
-#define RCC_MC_AHB6ENSETR_SDMMC2EN BIT(17)
-#define RCC_MC_AHB6ENSETR_CRC1EN BIT(20)
-#define RCC_MC_AHB6ENSETR_USBHEN BIT(24)
-
-/* RCC_MC_AHB6ENCLRR register fields */
-#define RCC_MC_AHB6ENCLRR_MDMAEN BIT(0)
-#define RCC_MC_AHB6ENCLRR_GPUEN BIT(5)
-#define RCC_MC_AHB6ENCLRR_ETHCKEN BIT(7)
-#define RCC_MC_AHB6ENCLRR_ETHTXEN BIT(8)
-#define RCC_MC_AHB6ENCLRR_ETHRXEN BIT(9)
-#define RCC_MC_AHB6ENCLRR_ETHMACEN BIT(10)
-#define RCC_MC_AHB6ENCLRR_FMCEN BIT(12)
-#define RCC_MC_AHB6ENCLRR_QSPIEN BIT(14)
-#define RCC_MC_AHB6ENCLRR_SDMMC1EN BIT(16)
-#define RCC_MC_AHB6ENCLRR_SDMMC2EN BIT(17)
-#define RCC_MC_AHB6ENCLRR_CRC1EN BIT(20)
-#define RCC_MC_AHB6ENCLRR_USBHEN BIT(24)
-
-/* RCC_MP_APB4LPENSETR register fields */
-#define RCC_MP_APB4LPENSETR_LTDCLPEN BIT(0)
-#define RCC_MP_APB4LPENSETR_DSILPEN BIT(4)
-#define RCC_MP_APB4LPENSETR_DDRPERFMLPEN BIT(8)
-#define RCC_MP_APB4LPENSETR_IWDG2APBLPEN BIT(15)
-#define RCC_MP_APB4LPENSETR_USBPHYLPEN BIT(16)
-#define RCC_MP_APB4LPENSETR_STGENROLPEN BIT(20)
-#define RCC_MP_APB4LPENSETR_STGENROSTPEN BIT(21)
-
-/* RCC_MP_APB4LPENCLRR register fields */
-#define RCC_MP_APB4LPENCLRR_LTDCLPEN BIT(0)
-#define RCC_MP_APB4LPENCLRR_DSILPEN BIT(4)
-#define RCC_MP_APB4LPENCLRR_DDRPERFMLPEN BIT(8)
-#define RCC_MP_APB4LPENCLRR_IWDG2APBLPEN BIT(15)
-#define RCC_MP_APB4LPENCLRR_USBPHYLPEN BIT(16)
-#define RCC_MP_APB4LPENCLRR_STGENROLPEN BIT(20)
-#define RCC_MP_APB4LPENCLRR_STGENROSTPEN BIT(21)
-
-/* RCC_MP_APB5LPENSETR register fields */
-#define RCC_MP_APB5LPENSETR_SPI6LPEN BIT(0)
-#define RCC_MP_APB5LPENSETR_I2C4LPEN BIT(2)
-#define RCC_MP_APB5LPENSETR_I2C6LPEN BIT(3)
-#define RCC_MP_APB5LPENSETR_USART1LPEN BIT(4)
-#define RCC_MP_APB5LPENSETR_RTCAPBLPEN BIT(8)
-#define RCC_MP_APB5LPENSETR_TZC1LPEN BIT(11)
-#define RCC_MP_APB5LPENSETR_TZC2LPEN BIT(12)
-#define RCC_MP_APB5LPENSETR_TZPCLPEN BIT(13)
-#define RCC_MP_APB5LPENSETR_IWDG1APBLPEN BIT(15)
-#define RCC_MP_APB5LPENSETR_BSECLPEN BIT(16)
-#define RCC_MP_APB5LPENSETR_STGENLPEN BIT(20)
-#define RCC_MP_APB5LPENSETR_STGENSTPEN BIT(21)
-
-/* RCC_MP_APB5LPENCLRR register fields */
-#define RCC_MP_APB5LPENCLRR_SPI6LPEN BIT(0)
-#define RCC_MP_APB5LPENCLRR_I2C4LPEN BIT(2)
-#define RCC_MP_APB5LPENCLRR_I2C6LPEN BIT(3)
-#define RCC_MP_APB5LPENCLRR_USART1LPEN BIT(4)
-#define RCC_MP_APB5LPENCLRR_RTCAPBLPEN BIT(8)
-#define RCC_MP_APB5LPENCLRR_TZC1LPEN BIT(11)
-#define RCC_MP_APB5LPENCLRR_TZC2LPEN BIT(12)
-#define RCC_MP_APB5LPENCLRR_TZPCLPEN BIT(13)
-#define RCC_MP_APB5LPENCLRR_IWDG1APBLPEN BIT(15)
-#define RCC_MP_APB5LPENCLRR_BSECLPEN BIT(16)
-#define RCC_MP_APB5LPENCLRR_STGENLPEN BIT(20)
-#define RCC_MP_APB5LPENCLRR_STGENSTPEN BIT(21)
-
-/* RCC_MP_AHB5LPENSETR register fields */
-#define RCC_MP_AHB5LPENSETR_GPIOZLPEN BIT(0)
-#define RCC_MP_AHB5LPENSETR_CRYP1LPEN BIT(4)
-#define RCC_MP_AHB5LPENSETR_HASH1LPEN BIT(5)
-#define RCC_MP_AHB5LPENSETR_RNG1LPEN BIT(6)
-#define RCC_MP_AHB5LPENSETR_BKPSRAMLPEN BIT(8)
-
-/* RCC_MP_AHB5LPENCLRR register fields */
-#define RCC_MP_AHB5LPENCLRR_GPIOZLPEN BIT(0)
-#define RCC_MP_AHB5LPENCLRR_CRYP1LPEN BIT(4)
-#define RCC_MP_AHB5LPENCLRR_HASH1LPEN BIT(5)
-#define RCC_MP_AHB5LPENCLRR_RNG1LPEN BIT(6)
-#define RCC_MP_AHB5LPENCLRR_BKPSRAMLPEN BIT(8)
-
-/* RCC_MP_AHB6LPENSETR register fields */
-#define RCC_MP_AHB6LPENSETR_MDMALPEN BIT(0)
-#define RCC_MP_AHB6LPENSETR_GPULPEN BIT(5)
-#define RCC_MP_AHB6LPENSETR_ETHCKLPEN BIT(7)
-#define RCC_MP_AHB6LPENSETR_ETHTXLPEN BIT(8)
-#define RCC_MP_AHB6LPENSETR_ETHRXLPEN BIT(9)
-#define RCC_MP_AHB6LPENSETR_ETHMACLPEN BIT(10)
-#define RCC_MP_AHB6LPENSETR_ETHSTPEN BIT(11)
-#define RCC_MP_AHB6LPENSETR_FMCLPEN BIT(12)
-#define RCC_MP_AHB6LPENSETR_QSPILPEN BIT(14)
-#define RCC_MP_AHB6LPENSETR_SDMMC1LPEN BIT(16)
-#define RCC_MP_AHB6LPENSETR_SDMMC2LPEN BIT(17)
-#define RCC_MP_AHB6LPENSETR_CRC1LPEN BIT(20)
-#define RCC_MP_AHB6LPENSETR_USBHLPEN BIT(24)
-
-/* RCC_MP_AHB6LPENCLRR register fields */
-#define RCC_MP_AHB6LPENCLRR_MDMALPEN BIT(0)
-#define RCC_MP_AHB6LPENCLRR_GPULPEN BIT(5)
-#define RCC_MP_AHB6LPENCLRR_ETHCKLPEN BIT(7)
-#define RCC_MP_AHB6LPENCLRR_ETHTXLPEN BIT(8)
-#define RCC_MP_AHB6LPENCLRR_ETHRXLPEN BIT(9)
-#define RCC_MP_AHB6LPENCLRR_ETHMACLPEN BIT(10)
-#define RCC_MP_AHB6LPENCLRR_ETHSTPEN BIT(11)
-#define RCC_MP_AHB6LPENCLRR_FMCLPEN BIT(12)
-#define RCC_MP_AHB6LPENCLRR_QSPILPEN BIT(14)
-#define RCC_MP_AHB6LPENCLRR_SDMMC1LPEN BIT(16)
-#define RCC_MP_AHB6LPENCLRR_SDMMC2LPEN BIT(17)
-#define RCC_MP_AHB6LPENCLRR_CRC1LPEN BIT(20)
-#define RCC_MP_AHB6LPENCLRR_USBHLPEN BIT(24)
-
-/* RCC_MP_TZAHB6LPENSETR register fields */
-#define RCC_MP_TZAHB6LPENSETR_MDMALPEN BIT(0)
-
-/* RCC_MP_TZAHB6LPENCLRR register fields */
-#define RCC_MP_TZAHB6LPENCLRR_MDMALPEN BIT(0)
-
-/* RCC_MC_APB4LPENSETR register fields */
-#define RCC_MC_APB4LPENSETR_LTDCLPEN BIT(0)
-#define RCC_MC_APB4LPENSETR_DSILPEN BIT(4)
-#define RCC_MC_APB4LPENSETR_DDRPERFMLPEN BIT(8)
-#define RCC_MC_APB4LPENSETR_USBPHYLPEN BIT(16)
-#define RCC_MC_APB4LPENSETR_STGENROLPEN BIT(20)
-#define RCC_MC_APB4LPENSETR_STGENROSTPEN BIT(21)
-
-/* RCC_MC_APB4LPENCLRR register fields */
-#define RCC_MC_APB4LPENCLRR_LTDCLPEN BIT(0)
-#define RCC_MC_APB4LPENCLRR_DSILPEN BIT(4)
-#define RCC_MC_APB4LPENCLRR_DDRPERFMLPEN BIT(8)
-#define RCC_MC_APB4LPENCLRR_USBPHYLPEN BIT(16)
-#define RCC_MC_APB4LPENCLRR_STGENROLPEN BIT(20)
-#define RCC_MC_APB4LPENCLRR_STGENROSTPEN BIT(21)
-
-/* RCC_MC_APB5LPENSETR register fields */
-#define RCC_MC_APB5LPENSETR_SPI6LPEN BIT(0)
-#define RCC_MC_APB5LPENSETR_I2C4LPEN BIT(2)
-#define RCC_MC_APB5LPENSETR_I2C6LPEN BIT(3)
-#define RCC_MC_APB5LPENSETR_USART1LPEN BIT(4)
-#define RCC_MC_APB5LPENSETR_RTCAPBLPEN BIT(8)
-#define RCC_MC_APB5LPENSETR_TZC1LPEN BIT(11)
-#define RCC_MC_APB5LPENSETR_TZC2LPEN BIT(12)
-#define RCC_MC_APB5LPENSETR_TZPCLPEN BIT(13)
-#define RCC_MC_APB5LPENSETR_BSECLPEN BIT(16)
-#define RCC_MC_APB5LPENSETR_STGENLPEN BIT(20)
-#define RCC_MC_APB5LPENSETR_STGENSTPEN BIT(21)
-
-/* RCC_MC_APB5LPENCLRR register fields */
-#define RCC_MC_APB5LPENCLRR_SPI6LPEN BIT(0)
-#define RCC_MC_APB5LPENCLRR_I2C4LPEN BIT(2)
-#define RCC_MC_APB5LPENCLRR_I2C6LPEN BIT(3)
-#define RCC_MC_APB5LPENCLRR_USART1LPEN BIT(4)
-#define RCC_MC_APB5LPENCLRR_RTCAPBLPEN BIT(8)
-#define RCC_MC_APB5LPENCLRR_TZC1LPEN BIT(11)
-#define RCC_MC_APB5LPENCLRR_TZC2LPEN BIT(12)
-#define RCC_MC_APB5LPENCLRR_TZPCLPEN BIT(13)
-#define RCC_MC_APB5LPENCLRR_BSECLPEN BIT(16)
-#define RCC_MC_APB5LPENCLRR_STGENLPEN BIT(20)
-#define RCC_MC_APB5LPENCLRR_STGENSTPEN BIT(21)
-
-/* RCC_MC_AHB5LPENSETR register fields */
-#define RCC_MC_AHB5LPENSETR_GPIOZLPEN BIT(0)
-#define RCC_MC_AHB5LPENSETR_CRYP1LPEN BIT(4)
-#define RCC_MC_AHB5LPENSETR_HASH1LPEN BIT(5)
-#define RCC_MC_AHB5LPENSETR_RNG1LPEN BIT(6)
-#define RCC_MC_AHB5LPENSETR_BKPSRAMLPEN BIT(8)
-
-/* RCC_MC_AHB5LPENCLRR register fields */
-#define RCC_MC_AHB5LPENCLRR_GPIOZLPEN BIT(0)
-#define RCC_MC_AHB5LPENCLRR_CRYP1LPEN BIT(4)
-#define RCC_MC_AHB5LPENCLRR_HASH1LPEN BIT(5)
-#define RCC_MC_AHB5LPENCLRR_RNG1LPEN BIT(6)
-#define RCC_MC_AHB5LPENCLRR_BKPSRAMLPEN BIT(8)
-
-/* RCC_MC_AHB6LPENSETR register fields */
-#define RCC_MC_AHB6LPENSETR_MDMALPEN BIT(0)
-#define RCC_MC_AHB6LPENSETR_GPULPEN BIT(5)
-#define RCC_MC_AHB6LPENSETR_ETHCKLPEN BIT(7)
-#define RCC_MC_AHB6LPENSETR_ETHTXLPEN BIT(8)
-#define RCC_MC_AHB6LPENSETR_ETHRXLPEN BIT(9)
-#define RCC_MC_AHB6LPENSETR_ETHMACLPEN BIT(10)
-#define RCC_MC_AHB6LPENSETR_ETHSTPEN BIT(11)
-#define RCC_MC_AHB6LPENSETR_FMCLPEN BIT(12)
-#define RCC_MC_AHB6LPENSETR_QSPILPEN BIT(14)
-#define RCC_MC_AHB6LPENSETR_SDMMC1LPEN BIT(16)
-#define RCC_MC_AHB6LPENSETR_SDMMC2LPEN BIT(17)
-#define RCC_MC_AHB6LPENSETR_CRC1LPEN BIT(20)
-#define RCC_MC_AHB6LPENSETR_USBHLPEN BIT(24)
-
-/* RCC_MC_AHB6LPENCLRR register fields */
-#define RCC_MC_AHB6LPENCLRR_MDMALPEN BIT(0)
-#define RCC_MC_AHB6LPENCLRR_GPULPEN BIT(5)
-#define RCC_MC_AHB6LPENCLRR_ETHCKLPEN BIT(7)
-#define RCC_MC_AHB6LPENCLRR_ETHTXLPEN BIT(8)
-#define RCC_MC_AHB6LPENCLRR_ETHRXLPEN BIT(9)
-#define RCC_MC_AHB6LPENCLRR_ETHMACLPEN BIT(10)
-#define RCC_MC_AHB6LPENCLRR_ETHSTPEN BIT(11)
-#define RCC_MC_AHB6LPENCLRR_FMCLPEN BIT(12)
-#define RCC_MC_AHB6LPENCLRR_QSPILPEN BIT(14)
-#define RCC_MC_AHB6LPENCLRR_SDMMC1LPEN BIT(16)
-#define RCC_MC_AHB6LPENCLRR_SDMMC2LPEN BIT(17)
-#define RCC_MC_AHB6LPENCLRR_CRC1LPEN BIT(20)
-#define RCC_MC_AHB6LPENCLRR_USBHLPEN BIT(24)
-
-/* RCC_BR_RSTSCLRR register fields */
-#define RCC_BR_RSTSCLRR_PORRSTF BIT(0)
-#define RCC_BR_RSTSCLRR_BORRSTF BIT(1)
-#define RCC_BR_RSTSCLRR_PADRSTF BIT(2)
-#define RCC_BR_RSTSCLRR_HCSSRSTF BIT(3)
-#define RCC_BR_RSTSCLRR_VCORERSTF BIT(4)
-#define RCC_BR_RSTSCLRR_MPSYSRSTF BIT(6)
-#define RCC_BR_RSTSCLRR_MCSYSRSTF BIT(7)
-#define RCC_BR_RSTSCLRR_IWDG1RSTF BIT(8)
-#define RCC_BR_RSTSCLRR_IWDG2RSTF BIT(9)
-#define RCC_BR_RSTSCLRR_MPUP0RSTF BIT(13)
-#define RCC_BR_RSTSCLRR_MPUP1RSTF BIT(14)
-
-/* RCC_MP_GRSTCSETR register fields */
-#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0)
-#define RCC_MP_GRSTCSETR_MCURST BIT(1)
-#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4)
-#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5)
-
-/* RCC_MP_RSTSCLRR register fields */
-#define RCC_MP_RSTSCLRR_PORRSTF BIT(0)
-#define RCC_MP_RSTSCLRR_BORRSTF BIT(1)
-#define RCC_MP_RSTSCLRR_PADRSTF BIT(2)
-#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3)
-#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4)
-#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6)
-#define RCC_MP_RSTSCLRR_MCSYSRSTF BIT(7)
-#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8)
-#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9)
-#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11)
-#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12)
-#define RCC_MP_RSTSCLRR_MPUP0RSTF BIT(13)
-#define RCC_MP_RSTSCLRR_MPUP1RSTF BIT(14)
-#define RCC_MP_RSTSCLRR_SPARE BIT(15)
-
-/* RCC_MP_IWDGFZSETR register fields */
-#define RCC_MP_IWDGFZSETR_FZ_IWDG1 BIT(0)
-#define RCC_MP_IWDGFZSETR_FZ_IWDG2 BIT(1)
-
-/* RCC_MP_IWDGFZCLRR register fields */
-#define RCC_MP_IWDGFZCLRR_FZ_IWDG1 BIT(0)
-#define RCC_MP_IWDGFZCLRR_FZ_IWDG2 BIT(1)
-
-/* RCC_MP_CIER register fields */
-#define RCC_MP_CIER_LSIRDYIE BIT(0)
-#define RCC_MP_CIER_LSERDYIE BIT(1)
-#define RCC_MP_CIER_HSIRDYIE BIT(2)
-#define RCC_MP_CIER_HSERDYIE BIT(3)
-#define RCC_MP_CIER_CSIRDYIE BIT(4)
-#define RCC_MP_CIER_PLL1DYIE BIT(8)
-#define RCC_MP_CIER_PLL2DYIE BIT(9)
-#define RCC_MP_CIER_PLL3DYIE BIT(10)
-#define RCC_MP_CIER_PLL4DYIE BIT(11)
-#define RCC_MP_CIER_LSECSSIE BIT(16)
-#define RCC_MP_CIER_WKUPIE BIT(20)
-
-/* RCC_MP_CIFR register fields */
-#define RCC_MP_CIFR_MASK U(0x110F1F)
-#define RCC_MP_CIFR_LSIRDYF BIT(0)
-#define RCC_MP_CIFR_LSERDYF BIT(1)
-#define RCC_MP_CIFR_HSIRDYF BIT(2)
-#define RCC_MP_CIFR_HSERDYF BIT(3)
-#define RCC_MP_CIFR_CSIRDYF BIT(4)
-#define RCC_MP_CIFR_PLL1DYF BIT(8)
-#define RCC_MP_CIFR_PLL2DYF BIT(9)
-#define RCC_MP_CIFR_PLL3DYF BIT(10)
-#define RCC_MP_CIFR_PLL4DYF BIT(11)
-#define RCC_MP_CIFR_LSECSSF BIT(16)
-#define RCC_MP_CIFR_WKUPF BIT(20)
-
-/* RCC_PWRLPDLYCR register fields */
-#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK(21, 0)
-#define RCC_PWRLPDLYCR_PWRLP_DLY_SHIFT 0
-#define RCC_PWRLPDLYCR_MCTMPSKP BIT(24)
-
-/* RCC_MP_RSTSSETR register fields */
-#define RCC_MP_RSTSSETR_PORRSTF BIT(0)
-#define RCC_MP_RSTSSETR_BORRSTF BIT(1)
-#define RCC_MP_RSTSSETR_PADRSTF BIT(2)
-#define RCC_MP_RSTSSETR_HCSSRSTF BIT(3)
-#define RCC_MP_RSTSSETR_VCORERSTF BIT(4)
-#define RCC_MP_RSTSSETR_MPSYSRSTF BIT(6)
-#define RCC_MP_RSTSSETR_MCSYSRSTF BIT(7)
-#define RCC_MP_RSTSSETR_IWDG1RSTF BIT(8)
-#define RCC_MP_RSTSSETR_IWDG2RSTF BIT(9)
-#define RCC_MP_RSTSSETR_STDBYRSTF BIT(11)
-#define RCC_MP_RSTSSETR_CSTDBYRSTF BIT(12)
-#define RCC_MP_RSTSSETR_MPUP0RSTF BIT(13)
-#define RCC_MP_RSTSSETR_MPUP1RSTF BIT(14)
-#define RCC_MP_RSTSSETR_SPARE BIT(15)
-
-/* RCC_MCO1CFGR register fields */
-#define RCC_MCO1CFGR_MCO1SEL_MASK GENMASK(2, 0)
-#define RCC_MCO1CFGR_MCO1SEL_SHIFT 0
-#define RCC_MCO1CFGR_MCO1DIV_MASK GENMASK(7, 4)
-#define RCC_MCO1CFGR_MCO1DIV_SHIFT 4
-#define RCC_MCO1CFGR_MCO1ON BIT(12)
-
-/* RCC_MCO2CFGR register fields */
-#define RCC_MCO2CFGR_MCO2SEL_MASK GENMASK(2, 0)
-#define RCC_MCO2CFGR_MCO2SEL_SHIFT 0
-#define RCC_MCO2CFGR_MCO2DIV_MASK GENMASK(7, 4)
-#define RCC_MCO2CFGR_MCO2DIV_SHIFT 4
-#define RCC_MCO2CFGR_MCO2ON BIT(12)
-
-/* RCC_OCRDYR register fields */
-#define RCC_OCRDYR_HSIRDY BIT(0)
-#define RCC_OCRDYR_HSIDIVRDY BIT(2)
-#define RCC_OCRDYR_CSIRDY BIT(4)
-#define RCC_OCRDYR_HSERDY BIT(8)
-#define RCC_OCRDYR_MPUCKRDY BIT(23)
-#define RCC_OCRDYR_AXICKRDY BIT(24)
-#define RCC_OCRDYR_CKREST BIT(25)
-
-/* RCC_DBGCFGR register fields */
-#define RCC_DBGCFGR_TRACEDIV_MASK GENMASK(2, 0)
-#define RCC_DBGCFGR_TRACEDIV_SHIFT 0
-#define RCC_DBGCFGR_DBGCKEN BIT(8)
-#define RCC_DBGCFGR_TRACECKEN BIT(9)
-#define RCC_DBGCFGR_DBGRST BIT(12)
-
-/* RCC_RCK3SELR register fields */
-#define RCC_RCK3SELR_PLL3SRC_MASK GENMASK(1, 0)
-#define RCC_RCK3SELR_PLL3SRC_SHIFT 0
-#define RCC_RCK3SELR_PLL3SRCRDY BIT(31)
-
-/* RCC_RCK4SELR register fields */
-#define RCC_RCK4SELR_PLL4SRC_MASK GENMASK(1, 0)
-#define RCC_RCK4SELR_PLL4SRC_SHIFT 0
-#define RCC_RCK4SELR_PLL4SRCRDY BIT(31)
-
-/* RCC_TIMG1PRER register fields */
-#define RCC_TIMG1PRER_TIMG1PRE BIT(0)
-#define RCC_TIMG1PRER_TIMG1PRERDY BIT(31)
-
-/* RCC_TIMG2PRER register fields */
-#define RCC_TIMG2PRER_TIMG2PRE BIT(0)
-#define RCC_TIMG2PRER_TIMG2PRERDY BIT(31)
-
-/* RCC_MCUDIVR register fields */
-#define RCC_MCUDIVR_MCUDIV_MASK GENMASK(3, 0)
-#define RCC_MCUDIVR_MCUDIV_SHIFT 0
-#define RCC_MCUDIVR_MCUDIVRDY BIT(31)
-
-/* RCC_APB1DIVR register fields */
-#define RCC_APB1DIVR_APB1DIV_MASK GENMASK(2, 0)
-#define RCC_APB1DIVR_APB1DIV_SHIFT 0
-#define RCC_APB1DIVR_APB1DIVRDY BIT(31)
-
-/* RCC_APB2DIVR register fields */
-#define RCC_APB2DIVR_APB2DIV_MASK GENMASK(2, 0)
-#define RCC_APB2DIVR_APB2DIV_SHIFT 0
-#define RCC_APB2DIVR_APB2DIVRDY BIT(31)
-
-/* RCC_APB3DIVR register fields */
-#define RCC_APB3DIVR_APB3DIV_MASK GENMASK(2, 0)
-#define RCC_APB3DIVR_APB3DIV_SHIFT 0
-#define RCC_APB3DIVR_APB3DIVRDY BIT(31)
-
-/* RCC_PLL3CR register fields */
-#define RCC_PLL3CR_PLLON BIT(0)
-#define RCC_PLL3CR_PLL3RDY BIT(1)
-#define RCC_PLL3CR_SSCG_CTRL BIT(2)
-#define RCC_PLL3CR_DIVPEN BIT(4)
-#define RCC_PLL3CR_DIVQEN BIT(5)
-#define RCC_PLL3CR_DIVREN BIT(6)
-
-/* RCC_PLL3CFGR1 register fields */
-#define RCC_PLL3CFGR1_DIVN_MASK GENMASK(8, 0)
-#define RCC_PLL3CFGR1_DIVN_SHIFT 0
-#define RCC_PLL3CFGR1_DIVM3_MASK GENMASK(21, 16)
-#define RCC_PLL3CFGR1_DIVM3_SHIFT 16
-#define RCC_PLL3CFGR1_IFRGE_MASK GENMASK(25, 24)
-#define RCC_PLL3CFGR1_IFRGE_SHIFT 24
-
-/* RCC_PLL3CFGR2 register fields */
-#define RCC_PLL3CFGR2_DIVP_MASK GENMASK(6, 0)
-#define RCC_PLL3CFGR2_DIVP_SHIFT 0
-#define RCC_PLL3CFGR2_DIVQ_MASK GENMASK(14, 8)
-#define RCC_PLL3CFGR2_DIVQ_SHIFT 8
-#define RCC_PLL3CFGR2_DIVR_MASK GENMASK(22, 16)
-#define RCC_PLL3CFGR2_DIVR_SHIFT 16
-
-/* RCC_PLL3FRACR register fields */
-#define RCC_PLL3FRACR_FRACV_MASK GENMASK(15, 3)
-#define RCC_PLL3FRACR_FRACV_SHIFT 3
-#define RCC_PLL3FRACR_FRACLE BIT(16)
-
-/* RCC_PLL3CSGR register fields */
-#define RCC_PLL3CSGR_MOD_PER_MASK GENMASK(12, 0)
-#define RCC_PLL3CSGR_MOD_PER_SHIFT 0
-#define RCC_PLL3CSGR_TPDFN_DIS BIT(13)
-#define RCC_PLL3CSGR_RPDFN_DIS BIT(14)
-#define RCC_PLL3CSGR_SSCG_MODE BIT(15)
-#define RCC_PLL3CSGR_INC_STEP_MASK GENMASK(30, 16)
-#define RCC_PLL3CSGR_INC_STEP_SHIFT 16
-
-/* RCC_PLL4CR register fields */
-#define RCC_PLL4CR_PLLON BIT(0)
-#define RCC_PLL4CR_PLL4RDY BIT(1)
-#define RCC_PLL4CR_SSCG_CTRL BIT(2)
-#define RCC_PLL4CR_DIVPEN BIT(4)
-#define RCC_PLL4CR_DIVQEN BIT(5)
-#define RCC_PLL4CR_DIVREN BIT(6)
-
-/* RCC_PLL4CFGR1 register fields */
-#define RCC_PLL4CFGR1_DIVN_MASK GENMASK(8, 0)
-#define RCC_PLL4CFGR1_DIVN_SHIFT 0
-#define RCC_PLL4CFGR1_DIVM4_MASK GENMASK(21, 16)
-#define RCC_PLL4CFGR1_DIVM4_SHIFT 16
-#define RCC_PLL4CFGR1_IFRGE_MASK GENMASK(25, 24)
-#define RCC_PLL4CFGR1_IFRGE_SHIFT 24
-
-/* RCC_PLL4CFGR2 register fields */
-#define RCC_PLL4CFGR2_DIVP_MASK GENMASK(6, 0)
-#define RCC_PLL4CFGR2_DIVP_SHIFT 0
-#define RCC_PLL4CFGR2_DIVQ_MASK GENMASK(14, 8)
-#define RCC_PLL4CFGR2_DIVQ_SHIFT 8
-#define RCC_PLL4CFGR2_DIVR_MASK GENMASK(22, 16)
-#define RCC_PLL4CFGR2_DIVR_SHIFT 16
-
-/* RCC_PLL4FRACR register fields */
-#define RCC_PLL4FRACR_FRACV_MASK GENMASK(15, 3)
-#define RCC_PLL4FRACR_FRACV_SHIFT 3
-#define RCC_PLL4FRACR_FRACLE BIT(16)
-
-/* RCC_PLL4CSGR register fields */
-#define RCC_PLL4CSGR_MOD_PER_MASK GENMASK(12, 0)
-#define RCC_PLL4CSGR_MOD_PER_SHIFT 0
-#define RCC_PLL4CSGR_TPDFN_DIS BIT(13)
-#define RCC_PLL4CSGR_RPDFN_DIS BIT(14)
-#define RCC_PLL4CSGR_SSCG_MODE BIT(15)
-#define RCC_PLL4CSGR_INC_STEP_MASK GENMASK(30, 16)
-#define RCC_PLL4CSGR_INC_STEP_SHIFT 16
-
-/* RCC_I2C12CKSELR register fields */
-#define RCC_I2C12CKSELR_I2C12SRC_MASK GENMASK(2, 0)
-#define RCC_I2C12CKSELR_I2C12SRC_SHIFT 0
-
-/* RCC_I2C35CKSELR register fields */
-#define RCC_I2C35CKSELR_I2C35SRC_MASK GENMASK(2, 0)
-#define RCC_I2C35CKSELR_I2C35SRC_SHIFT 0
-
-/* RCC_SAI1CKSELR register fields */
-#define RCC_SAI1CKSELR_SAI1SRC_MASK GENMASK(2, 0)
-#define RCC_SAI1CKSELR_SAI1SRC_SHIFT 0
-
-/* RCC_SAI2CKSELR register fields */
-#define RCC_SAI2CKSELR_SAI2SRC_MASK GENMASK(2, 0)
-#define RCC_SAI2CKSELR_SAI2SRC_SHIFT 0
-
-/* RCC_SAI3CKSELR register fields */
-#define RCC_SAI3CKSELR_SAI3SRC_MASK GENMASK(2, 0)
-#define RCC_SAI3CKSELR_SAI3SRC_SHIFT 0
-
-/* RCC_SAI4CKSELR register fields */
-#define RCC_SAI4CKSELR_SAI4SRC_MASK GENMASK(2, 0)
-#define RCC_SAI4CKSELR_SAI4SRC_SHIFT 0
-
-/* RCC_SPI2S1CKSELR register fields */
-#define RCC_SPI2S1CKSELR_SPI1SRC_MASK GENMASK(2, 0)
-#define RCC_SPI2S1CKSELR_SPI1SRC_SHIFT 0
-
-/* RCC_SPI2S23CKSELR register fields */
-#define RCC_SPI2S23CKSELR_SPI23SRC_MASK GENMASK(2, 0)
-#define RCC_SPI2S23CKSELR_SPI23SRC_SHIFT 0
-
-/* RCC_SPI45CKSELR register fields */
-#define RCC_SPI45CKSELR_SPI45SRC_MASK GENMASK(2, 0)
-#define RCC_SPI45CKSELR_SPI45SRC_SHIFT 0
-
-/* RCC_UART6CKSELR register fields */
-#define RCC_UART6CKSELR_UART6SRC_MASK GENMASK(2, 0)
-#define RCC_UART6CKSELR_UART6SRC_SHIFT 0
-
-/* RCC_UART24CKSELR register fields */
-#define RCC_UART24CKSELR_HSI 0x00000002
-#define RCC_UART24CKSELR_UART24SRC_MASK GENMASK(2, 0)
-#define RCC_UART24CKSELR_UART24SRC_SHIFT 0
-
-/* RCC_UART35CKSELR register fields */
-#define RCC_UART35CKSELR_UART35SRC_MASK GENMASK(2, 0)
-#define RCC_UART35CKSELR_UART35SRC_SHIFT 0
-
-/* RCC_UART78CKSELR register fields */
-#define RCC_UART78CKSELR_UART78SRC_MASK GENMASK(2, 0)
-#define RCC_UART78CKSELR_UART78SRC_SHIFT 0
-
-/* RCC_SDMMC12CKSELR register fields */
-#define RCC_SDMMC12CKSELR_SDMMC12SRC_MASK GENMASK(2, 0)
-#define RCC_SDMMC12CKSELR_SDMMC12SRC_SHIFT 0
-
-/* RCC_SDMMC3CKSELR register fields */
-#define RCC_SDMMC3CKSELR_SDMMC3SRC_MASK GENMASK(2, 0)
-#define RCC_SDMMC3CKSELR_SDMMC3SRC_SHIFT 0
-
-/* RCC_ETHCKSELR register fields */
-#define RCC_ETHCKSELR_ETHSRC_MASK GENMASK(1, 0)
-#define RCC_ETHCKSELR_ETHSRC_SHIFT 0
-#define RCC_ETHCKSELR_ETHPTPDIV_MASK GENMASK(7, 4)
-#define RCC_ETHCKSELR_ETHPTPDIV_SHIFT 4
-
-/* RCC_QSPICKSELR register fields */
-#define RCC_QSPICKSELR_QSPISRC_MASK GENMASK(1, 0)
-#define RCC_QSPICKSELR_QSPISRC_SHIFT 0
-
-/* RCC_FMCCKSELR register fields */
-#define RCC_FMCCKSELR_FMCSRC_MASK GENMASK(1, 0)
-#define RCC_FMCCKSELR_FMCSRC_SHIFT 0
-
-/* RCC_FDCANCKSELR register fields */
-#define RCC_FDCANCKSELR_FDCANSRC_MASK GENMASK(1, 0)
-#define RCC_FDCANCKSELR_FDCANSRC_SHIFT 0
-
-/* RCC_SPDIFCKSELR register fields */
-#define RCC_SPDIFCKSELR_SPDIFSRC_MASK GENMASK(1, 0)
-#define RCC_SPDIFCKSELR_SPDIFSRC_SHIFT 0
-
-/* RCC_CECCKSELR register fields */
-#define RCC_CECCKSELR_CECSRC_MASK GENMASK(1, 0)
-#define RCC_CECCKSELR_CECSRC_SHIFT 0
-
-/* RCC_USBCKSELR register fields */
-#define RCC_USBCKSELR_USBPHYSRC_MASK GENMASK(1, 0)
-#define RCC_USBCKSELR_USBPHYSRC_SHIFT 0
-#define RCC_USBCKSELR_USBOSRC BIT(4)
-#define RCC_USBCKSELR_USBOSRC_MASK BIT(4)
-#define RCC_USBCKSELR_USBOSRC_SHIFT 4
-
-/* RCC_RNG2CKSELR register fields */
-#define RCC_RNG2CKSELR_RNG2SRC_MASK GENMASK(1, 0)
-#define RCC_RNG2CKSELR_RNG2SRC_SHIFT 0
-
-/* RCC_DSICKSELR register fields */
-#define RCC_DSICKSELR_DSISRC BIT(0)
-
-/* RCC_ADCCKSELR register fields */
-#define RCC_ADCCKSELR_ADCSRC_MASK GENMASK(1, 0)
-#define RCC_ADCCKSELR_ADCSRC_SHIFT 0
-
-/* RCC_LPTIM45CKSELR register fields */
-#define RCC_LPTIM45CKSELR_LPTIM45SRC_MASK GENMASK(2, 0)
-#define RCC_LPTIM45CKSELR_LPTIM45SRC_SHIFT 0
-
-/* RCC_LPTIM23CKSELR register fields */
-#define RCC_LPTIM23CKSELR_LPTIM23SRC_MASK GENMASK(2, 0)
-#define RCC_LPTIM23CKSELR_LPTIM23SRC_SHIFT 0
-
-/* RCC_LPTIM1CKSELR register fields */
-#define RCC_LPTIM1CKSELR_LPTIM1SRC_MASK GENMASK(2, 0)
-#define RCC_LPTIM1CKSELR_LPTIM1SRC_SHIFT 0
-
-/* RCC_APB1RSTSETR register fields */
-#define RCC_APB1RSTSETR_TIM2RST BIT(0)
-#define RCC_APB1RSTSETR_TIM3RST BIT(1)
-#define RCC_APB1RSTSETR_TIM4RST BIT(2)
-#define RCC_APB1RSTSETR_TIM5RST BIT(3)
-#define RCC_APB1RSTSETR_TIM6RST BIT(4)
-#define RCC_APB1RSTSETR_TIM7RST BIT(5)
-#define RCC_APB1RSTSETR_TIM12RST BIT(6)
-#define RCC_APB1RSTSETR_TIM13RST BIT(7)
-#define RCC_APB1RSTSETR_TIM14RST BIT(8)
-#define RCC_APB1RSTSETR_LPTIM1RST BIT(9)
-#define RCC_APB1RSTSETR_SPI2RST BIT(11)
-#define RCC_APB1RSTSETR_SPI3RST BIT(12)
-#define RCC_APB1RSTSETR_USART2RST BIT(14)
-#define RCC_APB1RSTSETR_USART3RST BIT(15)
-#define RCC_APB1RSTSETR_UART4RST BIT(16)
-#define RCC_APB1RSTSETR_UART5RST BIT(17)
-#define RCC_APB1RSTSETR_UART7RST BIT(18)
-#define RCC_APB1RSTSETR_UART8RST BIT(19)
-#define RCC_APB1RSTSETR_I2C1RST BIT(21)
-#define RCC_APB1RSTSETR_I2C2RST BIT(22)
-#define RCC_APB1RSTSETR_I2C3RST BIT(23)
-#define RCC_APB1RSTSETR_I2C5RST BIT(24)
-#define RCC_APB1RSTSETR_SPDIFRST BIT(26)
-#define RCC_APB1RSTSETR_CECRST BIT(27)
-#define RCC_APB1RSTSETR_DAC12RST BIT(29)
-#define RCC_APB1RSTSETR_MDIOSRST BIT(31)
-
-/* RCC_APB1RSTCLRR register fields */
-#define RCC_APB1RSTCLRR_TIM2RST BIT(0)
-#define RCC_APB1RSTCLRR_TIM3RST BIT(1)
-#define RCC_APB1RSTCLRR_TIM4RST BIT(2)
-#define RCC_APB1RSTCLRR_TIM5RST BIT(3)
-#define RCC_APB1RSTCLRR_TIM6RST BIT(4)
-#define RCC_APB1RSTCLRR_TIM7RST BIT(5)
-#define RCC_APB1RSTCLRR_TIM12RST BIT(6)
-#define RCC_APB1RSTCLRR_TIM13RST BIT(7)
-#define RCC_APB1RSTCLRR_TIM14RST BIT(8)
-#define RCC_APB1RSTCLRR_LPTIM1RST BIT(9)
-#define RCC_APB1RSTCLRR_SPI2RST BIT(11)
-#define RCC_APB1RSTCLRR_SPI3RST BIT(12)
-#define RCC_APB1RSTCLRR_USART2RST BIT(14)
-#define RCC_APB1RSTCLRR_USART3RST BIT(15)
-#define RCC_APB1RSTCLRR_UART4RST BIT(16)
-#define RCC_APB1RSTCLRR_UART5RST BIT(17)
-#define RCC_APB1RSTCLRR_UART7RST BIT(18)
-#define RCC_APB1RSTCLRR_UART8RST BIT(19)
-#define RCC_APB1RSTCLRR_I2C1RST BIT(21)
-#define RCC_APB1RSTCLRR_I2C2RST BIT(22)
-#define RCC_APB1RSTCLRR_I2C3RST BIT(23)
-#define RCC_APB1RSTCLRR_I2C5RST BIT(24)
-#define RCC_APB1RSTCLRR_SPDIFRST BIT(26)
-#define RCC_APB1RSTCLRR_CECRST BIT(27)
-#define RCC_APB1RSTCLRR_DAC12RST BIT(29)
-#define RCC_APB1RSTCLRR_MDIOSRST BIT(31)
-
-/* RCC_APB2RSTSETR register fields */
-#define RCC_APB2RSTSETR_TIM1RST BIT(0)
-#define RCC_APB2RSTSETR_TIM8RST BIT(1)
-#define RCC_APB2RSTSETR_TIM15RST BIT(2)
-#define RCC_APB2RSTSETR_TIM16RST BIT(3)
-#define RCC_APB2RSTSETR_TIM17RST BIT(4)
-#define RCC_APB2RSTSETR_SPI1RST BIT(8)
-#define RCC_APB2RSTSETR_SPI4RST BIT(9)
-#define RCC_APB2RSTSETR_SPI5RST BIT(10)
-#define RCC_APB2RSTSETR_USART6RST BIT(13)
-#define RCC_APB2RSTSETR_SAI1RST BIT(16)
-#define RCC_APB2RSTSETR_SAI2RST BIT(17)
-#define RCC_APB2RSTSETR_SAI3RST BIT(18)
-#define RCC_APB2RSTSETR_DFSDMRST BIT(20)
-#define RCC_APB2RSTSETR_FDCANRST BIT(24)
-
-/* RCC_APB2RSTCLRR register fields */
-#define RCC_APB2RSTCLRR_TIM1RST BIT(0)
-#define RCC_APB2RSTCLRR_TIM8RST BIT(1)
-#define RCC_APB2RSTCLRR_TIM15RST BIT(2)
-#define RCC_APB2RSTCLRR_TIM16RST BIT(3)
-#define RCC_APB2RSTCLRR_TIM17RST BIT(4)
-#define RCC_APB2RSTCLRR_SPI1RST BIT(8)
-#define RCC_APB2RSTCLRR_SPI4RST BIT(9)
-#define RCC_APB2RSTCLRR_SPI5RST BIT(10)
-#define RCC_APB2RSTCLRR_USART6RST BIT(13)
-#define RCC_APB2RSTCLRR_SAI1RST BIT(16)
-#define RCC_APB2RSTCLRR_SAI2RST BIT(17)
-#define RCC_APB2RSTCLRR_SAI3RST BIT(18)
-#define RCC_APB2RSTCLRR_DFSDMRST BIT(20)
-#define RCC_APB2RSTCLRR_FDCANRST BIT(24)
-
-/* RCC_APB3RSTSETR register fields */
-#define RCC_APB3RSTSETR_LPTIM2RST BIT(0)
-#define RCC_APB3RSTSETR_LPTIM3RST BIT(1)
-#define RCC_APB3RSTSETR_LPTIM4RST BIT(2)
-#define RCC_APB3RSTSETR_LPTIM5RST BIT(3)
-#define RCC_APB3RSTSETR_SAI4RST BIT(8)
-#define RCC_APB3RSTSETR_SYSCFGRST BIT(11)
-#define RCC_APB3RSTSETR_VREFRST BIT(13)
-#define RCC_APB3RSTSETR_TMPSENSRST BIT(16)
-#define RCC_APB3RSTSETR_PMBCTRLRST BIT(17)
-
-/* RCC_APB3RSTCLRR register fields */
-#define RCC_APB3RSTCLRR_LPTIM2RST BIT(0)
-#define RCC_APB3RSTCLRR_LPTIM3RST BIT(1)
-#define RCC_APB3RSTCLRR_LPTIM4RST BIT(2)
-#define RCC_APB3RSTCLRR_LPTIM5RST BIT(3)
-#define RCC_APB3RSTCLRR_SAI4RST BIT(8)
-#define RCC_APB3RSTCLRR_SYSCFGRST BIT(11)
-#define RCC_APB3RSTCLRR_VREFRST BIT(13)
-#define RCC_APB3RSTCLRR_TMPSENSRST BIT(16)
-#define RCC_APB3RSTCLRR_PMBCTRLRST BIT(17)
-
-/* RCC_AHB2RSTSETR register fields */
-#define RCC_AHB2RSTSETR_DMA1RST BIT(0)
-#define RCC_AHB2RSTSETR_DMA2RST BIT(1)
-#define RCC_AHB2RSTSETR_DMAMUXRST BIT(2)
-#define RCC_AHB2RSTSETR_ADC12RST BIT(5)
-#define RCC_AHB2RSTSETR_USBORST BIT(8)
-#define RCC_AHB2RSTSETR_SDMMC3RST BIT(16)
-
-/* RCC_AHB2RSTCLRR register fields */
-#define RCC_AHB2RSTCLRR_DMA1RST BIT(0)
-#define RCC_AHB2RSTCLRR_DMA2RST BIT(1)
-#define RCC_AHB2RSTCLRR_DMAMUXRST BIT(2)
-#define RCC_AHB2RSTCLRR_ADC12RST BIT(5)
-#define RCC_AHB2RSTCLRR_USBORST BIT(8)
-#define RCC_AHB2RSTCLRR_SDMMC3RST BIT(16)
-
-/* RCC_AHB3RSTSETR register fields */
-#define RCC_AHB3RSTSETR_DCMIRST BIT(0)
-#define RCC_AHB3RSTSETR_CRYP2RST BIT(4)
-#define RCC_AHB3RSTSETR_HASH2RST BIT(5)
-#define RCC_AHB3RSTSETR_RNG2RST BIT(6)
-#define RCC_AHB3RSTSETR_CRC2RST BIT(7)
-#define RCC_AHB3RSTSETR_HSEMRST BIT(11)
-#define RCC_AHB3RSTSETR_IPCCRST BIT(12)
-
-/* RCC_AHB3RSTCLRR register fields */
-#define RCC_AHB3RSTCLRR_DCMIRST BIT(0)
-#define RCC_AHB3RSTCLRR_CRYP2RST BIT(4)
-#define RCC_AHB3RSTCLRR_HASH2RST BIT(5)
-#define RCC_AHB3RSTCLRR_RNG2RST BIT(6)
-#define RCC_AHB3RSTCLRR_CRC2RST BIT(7)
-#define RCC_AHB3RSTCLRR_HSEMRST BIT(11)
-#define RCC_AHB3RSTCLRR_IPCCRST BIT(12)
-
-/* RCC_AHB4RSTSETR register fields */
-#define RCC_AHB4RSTSETR_GPIOARST BIT(0)
-#define RCC_AHB4RSTSETR_GPIOBRST BIT(1)
-#define RCC_AHB4RSTSETR_GPIOCRST BIT(2)
-#define RCC_AHB4RSTSETR_GPIODRST BIT(3)
-#define RCC_AHB4RSTSETR_GPIOERST BIT(4)
-#define RCC_AHB4RSTSETR_GPIOFRST BIT(5)
-#define RCC_AHB4RSTSETR_GPIOGRST BIT(6)
-#define RCC_AHB4RSTSETR_GPIOHRST BIT(7)
-#define RCC_AHB4RSTSETR_GPIOIRST BIT(8)
-#define RCC_AHB4RSTSETR_GPIOJRST BIT(9)
-#define RCC_AHB4RSTSETR_GPIOKRST BIT(10)
-
-/* RCC_AHB4RSTCLRR register fields */
-#define RCC_AHB4RSTCLRR_GPIOARST BIT(0)
-#define RCC_AHB4RSTCLRR_GPIOBRST BIT(1)
-#define RCC_AHB4RSTCLRR_GPIOCRST BIT(2)
-#define RCC_AHB4RSTCLRR_GPIODRST BIT(3)
-#define RCC_AHB4RSTCLRR_GPIOERST BIT(4)
-#define RCC_AHB4RSTCLRR_GPIOFRST BIT(5)
-#define RCC_AHB4RSTCLRR_GPIOGRST BIT(6)
-#define RCC_AHB4RSTCLRR_GPIOHRST BIT(7)
-#define RCC_AHB4RSTCLRR_GPIOIRST BIT(8)
-#define RCC_AHB4RSTCLRR_GPIOJRST BIT(9)
-#define RCC_AHB4RSTCLRR_GPIOKRST BIT(10)
-
-/* RCC_MP_APB1ENSETR register fields */
-#define RCC_MP_APB1ENSETR_TIM2EN BIT(0)
-#define RCC_MP_APB1ENSETR_TIM3EN BIT(1)
-#define RCC_MP_APB1ENSETR_TIM4EN BIT(2)
-#define RCC_MP_APB1ENSETR_TIM5EN BIT(3)
-#define RCC_MP_APB1ENSETR_TIM6EN BIT(4)
-#define RCC_MP_APB1ENSETR_TIM7EN BIT(5)
-#define RCC_MP_APB1ENSETR_TIM12EN BIT(6)
-#define RCC_MP_APB1ENSETR_TIM13EN BIT(7)
-#define RCC_MP_APB1ENSETR_TIM14EN BIT(8)
-#define RCC_MP_APB1ENSETR_LPTIM1EN BIT(9)
-#define RCC_MP_APB1ENSETR_SPI2EN BIT(11)
-#define RCC_MP_APB1ENSETR_SPI3EN BIT(12)
-#define RCC_MP_APB1ENSETR_USART2EN BIT(14)
-#define RCC_MP_APB1ENSETR_USART3EN BIT(15)
-#define RCC_MP_APB1ENSETR_UART4EN BIT(16)
-#define RCC_MP_APB1ENSETR_UART5EN BIT(17)
-#define RCC_MP_APB1ENSETR_UART7EN BIT(18)
-#define RCC_MP_APB1ENSETR_UART8EN BIT(19)
-#define RCC_MP_APB1ENSETR_I2C1EN BIT(21)
-#define RCC_MP_APB1ENSETR_I2C2EN BIT(22)
-#define RCC_MP_APB1ENSETR_I2C3EN BIT(23)
-#define RCC_MP_APB1ENSETR_I2C5EN BIT(24)
-#define RCC_MP_APB1ENSETR_SPDIFEN BIT(26)
-#define RCC_MP_APB1ENSETR_CECEN BIT(27)
-#define RCC_MP_APB1ENSETR_DAC12EN BIT(29)
-#define RCC_MP_APB1ENSETR_MDIOSEN BIT(31)
-
-/* RCC_MP_APB1ENCLRR register fields */
-#define RCC_MP_APB1ENCLRR_TIM2EN BIT(0)
-#define RCC_MP_APB1ENCLRR_TIM3EN BIT(1)
-#define RCC_MP_APB1ENCLRR_TIM4EN BIT(2)
-#define RCC_MP_APB1ENCLRR_TIM5EN BIT(3)
-#define RCC_MP_APB1ENCLRR_TIM6EN BIT(4)
-#define RCC_MP_APB1ENCLRR_TIM7EN BIT(5)
-#define RCC_MP_APB1ENCLRR_TIM12EN BIT(6)
-#define RCC_MP_APB1ENCLRR_TIM13EN BIT(7)
-#define RCC_MP_APB1ENCLRR_TIM14EN BIT(8)
-#define RCC_MP_APB1ENCLRR_LPTIM1EN BIT(9)
-#define RCC_MP_APB1ENCLRR_SPI2EN BIT(11)
-#define RCC_MP_APB1ENCLRR_SPI3EN BIT(12)
-#define RCC_MP_APB1ENCLRR_USART2EN BIT(14)
-#define RCC_MP_APB1ENCLRR_USART3EN BIT(15)
-#define RCC_MP_APB1ENCLRR_UART4EN BIT(16)
-#define RCC_MP_APB1ENCLRR_UART5EN BIT(17)
-#define RCC_MP_APB1ENCLRR_UART7EN BIT(18)
-#define RCC_MP_APB1ENCLRR_UART8EN BIT(19)
-#define RCC_MP_APB1ENCLRR_I2C1EN BIT(21)
-#define RCC_MP_APB1ENCLRR_I2C2EN BIT(22)
-#define RCC_MP_APB1ENCLRR_I2C3EN BIT(23)
-#define RCC_MP_APB1ENCLRR_I2C5EN BIT(24)
-#define RCC_MP_APB1ENCLRR_SPDIFEN BIT(26)
-#define RCC_MP_APB1ENCLRR_CECEN BIT(27)
-#define RCC_MP_APB1ENCLRR_DAC12EN BIT(29)
-#define RCC_MP_APB1ENCLRR_MDIOSEN BIT(31)
-
-/* RCC_MP_APB2ENSETR register fields */
-#define RCC_MP_APB2ENSETR_TIM1EN BIT(0)
-#define RCC_MP_APB2ENSETR_TIM8EN BIT(1)
-#define RCC_MP_APB2ENSETR_TIM15EN BIT(2)
-#define RCC_MP_APB2ENSETR_TIM16EN BIT(3)
-#define RCC_MP_APB2ENSETR_TIM17EN BIT(4)
-#define RCC_MP_APB2ENSETR_SPI1EN BIT(8)
-#define RCC_MP_APB2ENSETR_SPI4EN BIT(9)
-#define RCC_MP_APB2ENSETR_SPI5EN BIT(10)
-#define RCC_MP_APB2ENSETR_USART6EN BIT(13)
-#define RCC_MP_APB2ENSETR_SAI1EN BIT(16)
-#define RCC_MP_APB2ENSETR_SAI2EN BIT(17)
-#define RCC_MP_APB2ENSETR_SAI3EN BIT(18)
-#define RCC_MP_APB2ENSETR_DFSDMEN BIT(20)
-#define RCC_MP_APB2ENSETR_ADFSDMEN BIT(21)
-#define RCC_MP_APB2ENSETR_FDCANEN BIT(24)
-
-/* RCC_MP_APB2ENCLRR register fields */
-#define RCC_MP_APB2ENCLRR_TIM1EN BIT(0)
-#define RCC_MP_APB2ENCLRR_TIM8EN BIT(1)
-#define RCC_MP_APB2ENCLRR_TIM15EN BIT(2)
-#define RCC_MP_APB2ENCLRR_TIM16EN BIT(3)
-#define RCC_MP_APB2ENCLRR_TIM17EN BIT(4)
-#define RCC_MP_APB2ENCLRR_SPI1EN BIT(8)
-#define RCC_MP_APB2ENCLRR_SPI4EN BIT(9)
-#define RCC_MP_APB2ENCLRR_SPI5EN BIT(10)
-#define RCC_MP_APB2ENCLRR_USART6EN BIT(13)
-#define RCC_MP_APB2ENCLRR_SAI1EN BIT(16)
-#define RCC_MP_APB2ENCLRR_SAI2EN BIT(17)
-#define RCC_MP_APB2ENCLRR_SAI3EN BIT(18)
-#define RCC_MP_APB2ENCLRR_DFSDMEN BIT(20)
-#define RCC_MP_APB2ENCLRR_ADFSDMEN BIT(21)
-#define RCC_MP_APB2ENCLRR_FDCANEN BIT(24)
-
-/* RCC_MP_APB3ENSETR register fields */
-#define RCC_MP_APB3ENSETR_LPTIM2EN BIT(0)
-#define RCC_MP_APB3ENSETR_LPTIM3EN BIT(1)
-#define RCC_MP_APB3ENSETR_LPTIM4EN BIT(2)
-#define RCC_MP_APB3ENSETR_LPTIM5EN BIT(3)
-#define RCC_MP_APB3ENSETR_SAI4EN BIT(8)
-#define RCC_MP_APB3ENSETR_SYSCFGEN BIT(11)
-#define RCC_MP_APB3ENSETR_VREFEN BIT(13)
-#define RCC_MP_APB3ENSETR_TMPSENSEN BIT(16)
-#define RCC_MP_APB3ENSETR_PMBCTRLEN BIT(17)
-#define RCC_MP_APB3ENSETR_HDPEN BIT(20)
-
-/* RCC_MP_APB3ENCLRR register fields */
-#define RCC_MP_APB3ENCLRR_LPTIM2EN BIT(0)
-#define RCC_MP_APB3ENCLRR_LPTIM3EN BIT(1)
-#define RCC_MP_APB3ENCLRR_LPTIM4EN BIT(2)
-#define RCC_MP_APB3ENCLRR_LPTIM5EN BIT(3)
-#define RCC_MP_APB3ENCLRR_SAI4EN BIT(8)
-#define RCC_MP_APB3ENCLRR_SYSCFGEN BIT(11)
-#define RCC_MP_APB3ENCLRR_VREFEN BIT(13)
-#define RCC_MP_APB3ENCLRR_TMPSENSEN BIT(16)
-#define RCC_MP_APB3ENCLRR_PMBCTRLEN BIT(17)
-#define RCC_MP_APB3ENCLRR_HDPEN BIT(20)
-
-/* RCC_MP_AHB2ENSETR register fields */
-#define RCC_MP_AHB2ENSETR_DMA1EN BIT(0)
-#define RCC_MP_AHB2ENSETR_DMA2EN BIT(1)
-#define RCC_MP_AHB2ENSETR_DMAMUXEN BIT(2)
-#define RCC_MP_AHB2ENSETR_ADC12EN BIT(5)
-#define RCC_MP_AHB2ENSETR_USBOEN BIT(8)
-#define RCC_MP_AHB2ENSETR_SDMMC3EN BIT(16)
-
-/* RCC_MP_AHB2ENCLRR register fields */
-#define RCC_MP_AHB2ENCLRR_DMA1EN BIT(0)
-#define RCC_MP_AHB2ENCLRR_DMA2EN BIT(1)
-#define RCC_MP_AHB2ENCLRR_DMAMUXEN BIT(2)
-#define RCC_MP_AHB2ENCLRR_ADC12EN BIT(5)
-#define RCC_MP_AHB2ENCLRR_USBOEN BIT(8)
-#define RCC_MP_AHB2ENCLRR_SDMMC3EN BIT(16)
-
-/* RCC_MP_AHB3ENSETR register fields */
-#define RCC_MP_AHB3ENSETR_DCMIEN BIT(0)
-#define RCC_MP_AHB3ENSETR_CRYP2EN BIT(4)
-#define RCC_MP_AHB3ENSETR_HASH2EN BIT(5)
-#define RCC_MP_AHB3ENSETR_RNG2EN BIT(6)
-#define RCC_MP_AHB3ENSETR_CRC2EN BIT(7)
-#define RCC_MP_AHB3ENSETR_HSEMEN BIT(11)
-#define RCC_MP_AHB3ENSETR_IPCCEN BIT(12)
-
-/* RCC_MP_AHB3ENCLRR register fields */
-#define RCC_MP_AHB3ENCLRR_DCMIEN BIT(0)
-#define RCC_MP_AHB3ENCLRR_CRYP2EN BIT(4)
-#define RCC_MP_AHB3ENCLRR_HASH2EN BIT(5)
-#define RCC_MP_AHB3ENCLRR_RNG2EN BIT(6)
-#define RCC_MP_AHB3ENCLRR_CRC2EN BIT(7)
-#define RCC_MP_AHB3ENCLRR_HSEMEN BIT(11)
-#define RCC_MP_AHB3ENCLRR_IPCCEN BIT(12)
-
-/* RCC_MP_AHB4ENSETR register fields */
-#define RCC_MP_AHB4ENSETR_GPIOAEN BIT(0)
-#define RCC_MP_AHB4ENSETR_GPIOBEN BIT(1)
-#define RCC_MP_AHB4ENSETR_GPIOCEN BIT(2)
-#define RCC_MP_AHB4ENSETR_GPIODEN BIT(3)
-#define RCC_MP_AHB4ENSETR_GPIOEEN BIT(4)
-#define RCC_MP_AHB4ENSETR_GPIOFEN BIT(5)
-#define RCC_MP_AHB4ENSETR_GPIOGEN BIT(6)
-#define RCC_MP_AHB4ENSETR_GPIOHEN BIT(7)
-#define RCC_MP_AHB4ENSETR_GPIOIEN BIT(8)
-#define RCC_MP_AHB4ENSETR_GPIOJEN BIT(9)
-#define RCC_MP_AHB4ENSETR_GPIOKEN BIT(10)
-
-/* RCC_MP_AHB4ENCLRR register fields */
-#define RCC_MP_AHB4ENCLRR_GPIOAEN BIT(0)
-#define RCC_MP_AHB4ENCLRR_GPIOBEN BIT(1)
-#define RCC_MP_AHB4ENCLRR_GPIOCEN BIT(2)
-#define RCC_MP_AHB4ENCLRR_GPIODEN BIT(3)
-#define RCC_MP_AHB4ENCLRR_GPIOEEN BIT(4)
-#define RCC_MP_AHB4ENCLRR_GPIOFEN BIT(5)
-#define RCC_MP_AHB4ENCLRR_GPIOGEN BIT(6)
-#define RCC_MP_AHB4ENCLRR_GPIOHEN BIT(7)
-#define RCC_MP_AHB4ENCLRR_GPIOIEN BIT(8)
-#define RCC_MP_AHB4ENCLRR_GPIOJEN BIT(9)
-#define RCC_MP_AHB4ENCLRR_GPIOKEN BIT(10)
-
-/* RCC_MP_MLAHBENSETR register fields */
-#define RCC_MP_MLAHBENSETR_RETRAMEN BIT(4)
-
-/* RCC_MP_MLAHBENCLRR register fields */
-#define RCC_MP_MLAHBENCLRR_RETRAMEN BIT(4)
-
-/* RCC_MC_APB1ENSETR register fields */
-#define RCC_MC_APB1ENSETR_TIM2EN BIT(0)
-#define RCC_MC_APB1ENSETR_TIM3EN BIT(1)
-#define RCC_MC_APB1ENSETR_TIM4EN BIT(2)
-#define RCC_MC_APB1ENSETR_TIM5EN BIT(3)
-#define RCC_MC_APB1ENSETR_TIM6EN BIT(4)
-#define RCC_MC_APB1ENSETR_TIM7EN BIT(5)
-#define RCC_MC_APB1ENSETR_TIM12EN BIT(6)
-#define RCC_MC_APB1ENSETR_TIM13EN BIT(7)
-#define RCC_MC_APB1ENSETR_TIM14EN BIT(8)
-#define RCC_MC_APB1ENSETR_LPTIM1EN BIT(9)
-#define RCC_MC_APB1ENSETR_SPI2EN BIT(11)
-#define RCC_MC_APB1ENSETR_SPI3EN BIT(12)
-#define RCC_MC_APB1ENSETR_USART2EN BIT(14)
-#define RCC_MC_APB1ENSETR_USART3EN BIT(15)
-#define RCC_MC_APB1ENSETR_UART4EN BIT(16)
-#define RCC_MC_APB1ENSETR_UART5EN BIT(17)
-#define RCC_MC_APB1ENSETR_UART7EN BIT(18)
-#define RCC_MC_APB1ENSETR_UART8EN BIT(19)
-#define RCC_MC_APB1ENSETR_I2C1EN BIT(21)
-#define RCC_MC_APB1ENSETR_I2C2EN BIT(22)
-#define RCC_MC_APB1ENSETR_I2C3EN BIT(23)
-#define RCC_MC_APB1ENSETR_I2C5EN BIT(24)
-#define RCC_MC_APB1ENSETR_SPDIFEN BIT(26)
-#define RCC_MC_APB1ENSETR_CECEN BIT(27)
-#define RCC_MC_APB1ENSETR_WWDG1EN BIT(28)
-#define RCC_MC_APB1ENSETR_DAC12EN BIT(29)
-#define RCC_MC_APB1ENSETR_MDIOSEN BIT(31)
-
-/* RCC_MC_APB1ENCLRR register fields */
-#define RCC_MC_APB1ENCLRR_TIM2EN BIT(0)
-#define RCC_MC_APB1ENCLRR_TIM3EN BIT(1)
-#define RCC_MC_APB1ENCLRR_TIM4EN BIT(2)
-#define RCC_MC_APB1ENCLRR_TIM5EN BIT(3)
-#define RCC_MC_APB1ENCLRR_TIM6EN BIT(4)
-#define RCC_MC_APB1ENCLRR_TIM7EN BIT(5)
-#define RCC_MC_APB1ENCLRR_TIM12EN BIT(6)
-#define RCC_MC_APB1ENCLRR_TIM13EN BIT(7)
-#define RCC_MC_APB1ENCLRR_TIM14EN BIT(8)
-#define RCC_MC_APB1ENCLRR_LPTIM1EN BIT(9)
-#define RCC_MC_APB1ENCLRR_SPI2EN BIT(11)
-#define RCC_MC_APB1ENCLRR_SPI3EN BIT(12)
-#define RCC_MC_APB1ENCLRR_USART2EN BIT(14)
-#define RCC_MC_APB1ENCLRR_USART3EN BIT(15)
-#define RCC_MC_APB1ENCLRR_UART4EN BIT(16)
-#define RCC_MC_APB1ENCLRR_UART5EN BIT(17)
-#define RCC_MC_APB1ENCLRR_UART7EN BIT(18)
-#define RCC_MC_APB1ENCLRR_UART8EN BIT(19)
-#define RCC_MC_APB1ENCLRR_I2C1EN BIT(21)
-#define RCC_MC_APB1ENCLRR_I2C2EN BIT(22)
-#define RCC_MC_APB1ENCLRR_I2C3EN BIT(23)
-#define RCC_MC_APB1ENCLRR_I2C5EN BIT(24)
-#define RCC_MC_APB1ENCLRR_SPDIFEN BIT(26)
-#define RCC_MC_APB1ENCLRR_CECEN BIT(27)
-#define RCC_MC_APB1ENCLRR_DAC12EN BIT(29)
-#define RCC_MC_APB1ENCLRR_MDIOSEN BIT(31)
-
-/* RCC_MC_APB2ENSETR register fields */
-#define RCC_MC_APB2ENSETR_TIM1EN BIT(0)
-#define RCC_MC_APB2ENSETR_TIM8EN BIT(1)
-#define RCC_MC_APB2ENSETR_TIM15EN BIT(2)
-#define RCC_MC_APB2ENSETR_TIM16EN BIT(3)
-#define RCC_MC_APB2ENSETR_TIM17EN BIT(4)
-#define RCC_MC_APB2ENSETR_SPI1EN BIT(8)
-#define RCC_MC_APB2ENSETR_SPI4EN BIT(9)
-#define RCC_MC_APB2ENSETR_SPI5EN BIT(10)
-#define RCC_MC_APB2ENSETR_USART6EN BIT(13)
-#define RCC_MC_APB2ENSETR_SAI1EN BIT(16)
-#define RCC_MC_APB2ENSETR_SAI2EN BIT(17)
-#define RCC_MC_APB2ENSETR_SAI3EN BIT(18)
-#define RCC_MC_APB2ENSETR_DFSDMEN BIT(20)
-#define RCC_MC_APB2ENSETR_ADFSDMEN BIT(21)
-#define RCC_MC_APB2ENSETR_FDCANEN BIT(24)
-
-/* RCC_MC_APB2ENCLRR register fields */
-#define RCC_MC_APB2ENCLRR_TIM1EN BIT(0)
-#define RCC_MC_APB2ENCLRR_TIM8EN BIT(1)
-#define RCC_MC_APB2ENCLRR_TIM15EN BIT(2)
-#define RCC_MC_APB2ENCLRR_TIM16EN BIT(3)
-#define RCC_MC_APB2ENCLRR_TIM17EN BIT(4)
-#define RCC_MC_APB2ENCLRR_SPI1EN BIT(8)
-#define RCC_MC_APB2ENCLRR_SPI4EN BIT(9)
-#define RCC_MC_APB2ENCLRR_SPI5EN BIT(10)
-#define RCC_MC_APB2ENCLRR_USART6EN BIT(13)
-#define RCC_MC_APB2ENCLRR_SAI1EN BIT(16)
-#define RCC_MC_APB2ENCLRR_SAI2EN BIT(17)
-#define RCC_MC_APB2ENCLRR_SAI3EN BIT(18)
-#define RCC_MC_APB2ENCLRR_DFSDMEN BIT(20)
-#define RCC_MC_APB2ENCLRR_ADFSDMEN BIT(21)
-#define RCC_MC_APB2ENCLRR_FDCANEN BIT(24)
-
-/* RCC_MC_APB3ENSETR register fields */
-#define RCC_MC_APB3ENSETR_LPTIM2EN BIT(0)
-#define RCC_MC_APB3ENSETR_LPTIM3EN BIT(1)
-#define RCC_MC_APB3ENSETR_LPTIM4EN BIT(2)
-#define RCC_MC_APB3ENSETR_LPTIM5EN BIT(3)
-#define RCC_MC_APB3ENSETR_SAI4EN BIT(8)
-#define RCC_MC_APB3ENSETR_SYSCFGEN BIT(11)
-#define RCC_MC_APB3ENSETR_VREFEN BIT(13)
-#define RCC_MC_APB3ENSETR_TMPSENSEN BIT(16)
-#define RCC_MC_APB3ENSETR_PMBCTRLEN BIT(17)
-#define RCC_MC_APB3ENSETR_HDPEN BIT(20)
-
-/* RCC_MC_APB3ENCLRR register fields */
-#define RCC_MC_APB3ENCLRR_LPTIM2EN BIT(0)
-#define RCC_MC_APB3ENCLRR_LPTIM3EN BIT(1)
-#define RCC_MC_APB3ENCLRR_LPTIM4EN BIT(2)
-#define RCC_MC_APB3ENCLRR_LPTIM5EN BIT(3)
-#define RCC_MC_APB3ENCLRR_SAI4EN BIT(8)
-#define RCC_MC_APB3ENCLRR_SYSCFGEN BIT(11)
-#define RCC_MC_APB3ENCLRR_VREFEN BIT(13)
-#define RCC_MC_APB3ENCLRR_TMPSENSEN BIT(16)
-#define RCC_MC_APB3ENCLRR_PMBCTRLEN BIT(17)
-#define RCC_MC_APB3ENCLRR_HDPEN BIT(20)
-
-/* RCC_MC_AHB2ENSETR register fields */
-#define RCC_MC_AHB2ENSETR_DMA1EN BIT(0)
-#define RCC_MC_AHB2ENSETR_DMA2EN BIT(1)
-#define RCC_MC_AHB2ENSETR_DMAMUXEN BIT(2)
-#define RCC_MC_AHB2ENSETR_ADC12EN BIT(5)
-#define RCC_MC_AHB2ENSETR_USBOEN BIT(8)
-#define RCC_MC_AHB2ENSETR_SDMMC3EN BIT(16)
-
-/* RCC_MC_AHB2ENCLRR register fields */
-#define RCC_MC_AHB2ENCLRR_DMA1EN BIT(0)
-#define RCC_MC_AHB2ENCLRR_DMA2EN BIT(1)
-#define RCC_MC_AHB2ENCLRR_DMAMUXEN BIT(2)
-#define RCC_MC_AHB2ENCLRR_ADC12EN BIT(5)
-#define RCC_MC_AHB2ENCLRR_USBOEN BIT(8)
-#define RCC_MC_AHB2ENCLRR_SDMMC3EN BIT(16)
-
-/* RCC_MC_AHB3ENSETR register fields */
-#define RCC_MC_AHB3ENSETR_DCMIEN BIT(0)
-#define RCC_MC_AHB3ENSETR_CRYP2EN BIT(4)
-#define RCC_MC_AHB3ENSETR_HASH2EN BIT(5)
-#define RCC_MC_AHB3ENSETR_RNG2EN BIT(6)
-#define RCC_MC_AHB3ENSETR_CRC2EN BIT(7)
-#define RCC_MC_AHB3ENSETR_HSEMEN BIT(11)
-#define RCC_MC_AHB3ENSETR_IPCCEN BIT(12)
-
-/* RCC_MC_AHB3ENCLRR register fields */
-#define RCC_MC_AHB3ENCLRR_DCMIEN BIT(0)
-#define RCC_MC_AHB3ENCLRR_CRYP2EN BIT(4)
-#define RCC_MC_AHB3ENCLRR_HASH2EN BIT(5)
-#define RCC_MC_AHB3ENCLRR_RNG2EN BIT(6)
-#define RCC_MC_AHB3ENCLRR_CRC2EN BIT(7)
-#define RCC_MC_AHB3ENCLRR_HSEMEN BIT(11)
-#define RCC_MC_AHB3ENCLRR_IPCCEN BIT(12)
-
-/* RCC_MC_AHB4ENSETR register fields */
-#define RCC_MC_AHB4ENSETR_GPIOAEN BIT(0)
-#define RCC_MC_AHB4ENSETR_GPIOBEN BIT(1)
-#define RCC_MC_AHB4ENSETR_GPIOCEN BIT(2)
-#define RCC_MC_AHB4ENSETR_GPIODEN BIT(3)
-#define RCC_MC_AHB4ENSETR_GPIOEEN BIT(4)
-#define RCC_MC_AHB4ENSETR_GPIOFEN BIT(5)
-#define RCC_MC_AHB4ENSETR_GPIOGEN BIT(6)
-#define RCC_MC_AHB4ENSETR_GPIOHEN BIT(7)
-#define RCC_MC_AHB4ENSETR_GPIOIEN BIT(8)
-#define RCC_MC_AHB4ENSETR_GPIOJEN BIT(9)
-#define RCC_MC_AHB4ENSETR_GPIOKEN BIT(10)
-
-/* RCC_MC_AHB4ENCLRR register fields */
-#define RCC_MC_AHB4ENCLRR_GPIOAEN BIT(0)
-#define RCC_MC_AHB4ENCLRR_GPIOBEN BIT(1)
-#define RCC_MC_AHB4ENCLRR_GPIOCEN BIT(2)
-#define RCC_MC_AHB4ENCLRR_GPIODEN BIT(3)
-#define RCC_MC_AHB4ENCLRR_GPIOEEN BIT(4)
-#define RCC_MC_AHB4ENCLRR_GPIOFEN BIT(5)
-#define RCC_MC_AHB4ENCLRR_GPIOGEN BIT(6)
-#define RCC_MC_AHB4ENCLRR_GPIOHEN BIT(7)
-#define RCC_MC_AHB4ENCLRR_GPIOIEN BIT(8)
-#define RCC_MC_AHB4ENCLRR_GPIOJEN BIT(9)
-#define RCC_MC_AHB4ENCLRR_GPIOKEN BIT(10)
-
-/* RCC_MC_AXIMENSETR register fields */
-#define RCC_MC_AXIMENSETR_SYSRAMEN BIT(0)
-
-/* RCC_MC_AXIMENCLRR register fields */
-#define RCC_MC_AXIMENCLRR_SYSRAMEN BIT(0)
-
-/* RCC_MC_MLAHBENSETR register fields */
-#define RCC_MC_MLAHBENSETR_RETRAMEN BIT(4)
-
-/* RCC_MC_MLAHBENCLRR register fields */
-#define RCC_MC_MLAHBENCLRR_RETRAMEN BIT(4)
-
-/* RCC_MP_APB1LPENSETR register fields */
-#define RCC_MP_APB1LPENSETR_TIM2LPEN BIT(0)
-#define RCC_MP_APB1LPENSETR_TIM3LPEN BIT(1)
-#define RCC_MP_APB1LPENSETR_TIM4LPEN BIT(2)
-#define RCC_MP_APB1LPENSETR_TIM5LPEN BIT(3)
-#define RCC_MP_APB1LPENSETR_TIM6LPEN BIT(4)
-#define RCC_MP_APB1LPENSETR_TIM7LPEN BIT(5)
-#define RCC_MP_APB1LPENSETR_TIM12LPEN BIT(6)
-#define RCC_MP_APB1LPENSETR_TIM13LPEN BIT(7)
-#define RCC_MP_APB1LPENSETR_TIM14LPEN BIT(8)
-#define RCC_MP_APB1LPENSETR_LPTIM1LPEN BIT(9)
-#define RCC_MP_APB1LPENSETR_SPI2LPEN BIT(11)
-#define RCC_MP_APB1LPENSETR_SPI3LPEN BIT(12)
-#define RCC_MP_APB1LPENSETR_USART2LPEN BIT(14)
-#define RCC_MP_APB1LPENSETR_USART3LPEN BIT(15)
-#define RCC_MP_APB1LPENSETR_UART4LPEN BIT(16)
-#define RCC_MP_APB1LPENSETR_UART5LPEN BIT(17)
-#define RCC_MP_APB1LPENSETR_UART7LPEN BIT(18)
-#define RCC_MP_APB1LPENSETR_UART8LPEN BIT(19)
-#define RCC_MP_APB1LPENSETR_I2C1LPEN BIT(21)
-#define RCC_MP_APB1LPENSETR_I2C2LPEN BIT(22)
-#define RCC_MP_APB1LPENSETR_I2C3LPEN BIT(23)
-#define RCC_MP_APB1LPENSETR_I2C5LPEN BIT(24)
-#define RCC_MP_APB1LPENSETR_SPDIFLPEN BIT(26)
-#define RCC_MP_APB1LPENSETR_CECLPEN BIT(27)
-#define RCC_MP_APB1LPENSETR_DAC12LPEN BIT(29)
-#define RCC_MP_APB1LPENSETR_MDIOSLPEN BIT(31)
-
-/* RCC_MP_APB1LPENCLRR register fields */
-#define RCC_MP_APB1LPENCLRR_TIM2LPEN BIT(0)
-#define RCC_MP_APB1LPENCLRR_TIM3LPEN BIT(1)
-#define RCC_MP_APB1LPENCLRR_TIM4LPEN BIT(2)
-#define RCC_MP_APB1LPENCLRR_TIM5LPEN BIT(3)
-#define RCC_MP_APB1LPENCLRR_TIM6LPEN BIT(4)
-#define RCC_MP_APB1LPENCLRR_TIM7LPEN BIT(5)
-#define RCC_MP_APB1LPENCLRR_TIM12LPEN BIT(6)
-#define RCC_MP_APB1LPENCLRR_TIM13LPEN BIT(7)
-#define RCC_MP_APB1LPENCLRR_TIM14LPEN BIT(8)
-#define RCC_MP_APB1LPENCLRR_LPTIM1LPEN BIT(9)
-#define RCC_MP_APB1LPENCLRR_SPI2LPEN BIT(11)
-#define RCC_MP_APB1LPENCLRR_SPI3LPEN BIT(12)
-#define RCC_MP_APB1LPENCLRR_USART2LPEN BIT(14)
-#define RCC_MP_APB1LPENCLRR_USART3LPEN BIT(15)
-#define RCC_MP_APB1LPENCLRR_UART4LPEN BIT(16)
-#define RCC_MP_APB1LPENCLRR_UART5LPEN BIT(17)
-#define RCC_MP_APB1LPENCLRR_UART7LPEN BIT(18)
-#define RCC_MP_APB1LPENCLRR_UART8LPEN BIT(19)
-#define RCC_MP_APB1LPENCLRR_I2C1LPEN BIT(21)
-#define RCC_MP_APB1LPENCLRR_I2C2LPEN BIT(22)
-#define RCC_MP_APB1LPENCLRR_I2C3LPEN BIT(23)
-#define RCC_MP_APB1LPENCLRR_I2C5LPEN BIT(24)
-#define RCC_MP_APB1LPENCLRR_SPDIFLPEN BIT(26)
-#define RCC_MP_APB1LPENCLRR_CECLPEN BIT(27)
-#define RCC_MP_APB1LPENCLRR_DAC12LPEN BIT(29)
-#define RCC_MP_APB1LPENCLRR_MDIOSLPEN BIT(31)
-
-/* RCC_MP_APB2LPENSETR register fields */
-#define RCC_MP_APB2LPENSETR_TIM1LPEN BIT(0)
-#define RCC_MP_APB2LPENSETR_TIM8LPEN BIT(1)
-#define RCC_MP_APB2LPENSETR_TIM15LPEN BIT(2)
-#define RCC_MP_APB2LPENSETR_TIM16LPEN BIT(3)
-#define RCC_MP_APB2LPENSETR_TIM17LPEN BIT(4)
-#define RCC_MP_APB2LPENSETR_SPI1LPEN BIT(8)
-#define RCC_MP_APB2LPENSETR_SPI4LPEN BIT(9)
-#define RCC_MP_APB2LPENSETR_SPI5LPEN BIT(10)
-#define RCC_MP_APB2LPENSETR_USART6LPEN BIT(13)
-#define RCC_MP_APB2LPENSETR_SAI1LPEN BIT(16)
-#define RCC_MP_APB2LPENSETR_SAI2LPEN BIT(17)
-#define RCC_MP_APB2LPENSETR_SAI3LPEN BIT(18)
-#define RCC_MP_APB2LPENSETR_DFSDMLPEN BIT(20)
-#define RCC_MP_APB2LPENSETR_ADFSDMLPEN BIT(21)
-#define RCC_MP_APB2LPENSETR_FDCANLPEN BIT(24)
-
-/* RCC_MP_APB2LPENCLRR register fields */
-#define RCC_MP_APB2LPENCLRR_TIM1LPEN BIT(0)
-#define RCC_MP_APB2LPENCLRR_TIM8LPEN BIT(1)
-#define RCC_MP_APB2LPENCLRR_TIM15LPEN BIT(2)
-#define RCC_MP_APB2LPENCLRR_TIM16LPEN BIT(3)
-#define RCC_MP_APB2LPENCLRR_TIM17LPEN BIT(4)
-#define RCC_MP_APB2LPENCLRR_SPI1LPEN BIT(8)
-#define RCC_MP_APB2LPENCLRR_SPI4LPEN BIT(9)
-#define RCC_MP_APB2LPENCLRR_SPI5LPEN BIT(10)
-#define RCC_MP_APB2LPENCLRR_USART6LPEN BIT(13)
-#define RCC_MP_APB2LPENCLRR_SAI1LPEN BIT(16)
-#define RCC_MP_APB2LPENCLRR_SAI2LPEN BIT(17)
-#define RCC_MP_APB2LPENCLRR_SAI3LPEN BIT(18)
-#define RCC_MP_APB2LPENCLRR_DFSDMLPEN BIT(20)
-#define RCC_MP_APB2LPENCLRR_ADFSDMLPEN BIT(21)
-#define RCC_MP_APB2LPENCLRR_FDCANLPEN BIT(24)
-
-/* RCC_MP_APB3LPENSETR register fields */
-#define RCC_MP_APB3LPENSETR_LPTIM2LPEN BIT(0)
-#define RCC_MP_APB3LPENSETR_LPTIM3LPEN BIT(1)
-#define RCC_MP_APB3LPENSETR_LPTIM4LPEN BIT(2)
-#define RCC_MP_APB3LPENSETR_LPTIM5LPEN BIT(3)
-#define RCC_MP_APB3LPENSETR_SAI4LPEN BIT(8)
-#define RCC_MP_APB3LPENSETR_SYSCFGLPEN BIT(11)
-#define RCC_MP_APB3LPENSETR_VREFLPEN BIT(13)
-#define RCC_MP_APB3LPENSETR_TMPSENSLPEN BIT(16)
-#define RCC_MP_APB3LPENSETR_PMBCTRLLPEN BIT(17)
-
-/* RCC_MP_APB3LPENCLRR register fields */
-#define RCC_MP_APB3LPENCLRR_LPTIM2LPEN BIT(0)
-#define RCC_MP_APB3LPENCLRR_LPTIM3LPEN BIT(1)
-#define RCC_MP_APB3LPENCLRR_LPTIM4LPEN BIT(2)
-#define RCC_MP_APB3LPENCLRR_LPTIM5LPEN BIT(3)
-#define RCC_MP_APB3LPENCLRR_SAI4LPEN BIT(8)
-#define RCC_MP_APB3LPENCLRR_SYSCFGLPEN BIT(11)
-#define RCC_MP_APB3LPENCLRR_VREFLPEN BIT(13)
-#define RCC_MP_APB3LPENCLRR_TMPSENSLPEN BIT(16)
-#define RCC_MP_APB3LPENCLRR_PMBCTRLLPEN BIT(17)
-
-/* RCC_MP_AHB2LPENSETR register fields */
-#define RCC_MP_AHB2LPENSETR_DMA1LPEN BIT(0)
-#define RCC_MP_AHB2LPENSETR_DMA2LPEN BIT(1)
-#define RCC_MP_AHB2LPENSETR_DMAMUXLPEN BIT(2)
-#define RCC_MP_AHB2LPENSETR_ADC12LPEN BIT(5)
-#define RCC_MP_AHB2LPENSETR_USBOLPEN BIT(8)
-#define RCC_MP_AHB2LPENSETR_SDMMC3LPEN BIT(16)
-
-/* RCC_MP_AHB2LPENCLRR register fields */
-#define RCC_MP_AHB2LPENCLRR_DMA1LPEN BIT(0)
-#define RCC_MP_AHB2LPENCLRR_DMA2LPEN BIT(1)
-#define RCC_MP_AHB2LPENCLRR_DMAMUXLPEN BIT(2)
-#define RCC_MP_AHB2LPENCLRR_ADC12LPEN BIT(5)
-#define RCC_MP_AHB2LPENCLRR_USBOLPEN BIT(8)
-#define RCC_MP_AHB2LPENCLRR_SDMMC3LPEN BIT(16)
-
-/* RCC_MP_AHB3LPENSETR register fields */
-#define RCC_MP_AHB3LPENSETR_DCMILPEN BIT(0)
-#define RCC_MP_AHB3LPENSETR_CRYP2LPEN BIT(4)
-#define RCC_MP_AHB3LPENSETR_HASH2LPEN BIT(5)
-#define RCC_MP_AHB3LPENSETR_RNG2LPEN BIT(6)
-#define RCC_MP_AHB3LPENSETR_CRC2LPEN BIT(7)
-#define RCC_MP_AHB3LPENSETR_HSEMLPEN BIT(11)
-#define RCC_MP_AHB3LPENSETR_IPCCLPEN BIT(12)
-
-/* RCC_MP_AHB3LPENCLRR register fields */
-#define RCC_MP_AHB3LPENCLRR_DCMILPEN BIT(0)
-#define RCC_MP_AHB3LPENCLRR_CRYP2LPEN BIT(4)
-#define RCC_MP_AHB3LPENCLRR_HASH2LPEN BIT(5)
-#define RCC_MP_AHB3LPENCLRR_RNG2LPEN BIT(6)
-#define RCC_MP_AHB3LPENCLRR_CRC2LPEN BIT(7)
-#define RCC_MP_AHB3LPENCLRR_HSEMLPEN BIT(11)
-#define RCC_MP_AHB3LPENCLRR_IPCCLPEN BIT(12)
-
-/* RCC_MP_AHB4LPENSETR register fields */
-#define RCC_MP_AHB4LPENSETR_GPIOALPEN BIT(0)
-#define RCC_MP_AHB4LPENSETR_GPIOBLPEN BIT(1)
-#define RCC_MP_AHB4LPENSETR_GPIOCLPEN BIT(2)
-#define RCC_MP_AHB4LPENSETR_GPIODLPEN BIT(3)
-#define RCC_MP_AHB4LPENSETR_GPIOELPEN BIT(4)
-#define RCC_MP_AHB4LPENSETR_GPIOFLPEN BIT(5)
-#define RCC_MP_AHB4LPENSETR_GPIOGLPEN BIT(6)
-#define RCC_MP_AHB4LPENSETR_GPIOHLPEN BIT(7)
-#define RCC_MP_AHB4LPENSETR_GPIOILPEN BIT(8)
-#define RCC_MP_AHB4LPENSETR_GPIOJLPEN BIT(9)
-#define RCC_MP_AHB4LPENSETR_GPIOKLPEN BIT(10)
-
-/* RCC_MP_AHB4LPENCLRR register fields */
-#define RCC_MP_AHB4LPENCLRR_GPIOALPEN BIT(0)
-#define RCC_MP_AHB4LPENCLRR_GPIOBLPEN BIT(1)
-#define RCC_MP_AHB4LPENCLRR_GPIOCLPEN BIT(2)
-#define RCC_MP_AHB4LPENCLRR_GPIODLPEN BIT(3)
-#define RCC_MP_AHB4LPENCLRR_GPIOELPEN BIT(4)
-#define RCC_MP_AHB4LPENCLRR_GPIOFLPEN BIT(5)
-#define RCC_MP_AHB4LPENCLRR_GPIOGLPEN BIT(6)
-#define RCC_MP_AHB4LPENCLRR_GPIOHLPEN BIT(7)
-#define RCC_MP_AHB4LPENCLRR_GPIOILPEN BIT(8)
-#define RCC_MP_AHB4LPENCLRR_GPIOJLPEN BIT(9)
-#define RCC_MP_AHB4LPENCLRR_GPIOKLPEN BIT(10)
-
-/* RCC_MP_AXIMLPENSETR register fields */
-#define RCC_MP_AXIMLPENSETR_SYSRAMLPEN BIT(0)
-
-/* RCC_MP_AXIMLPENCLRR register fields */
-#define RCC_MP_AXIMLPENCLRR_SYSRAMLPEN BIT(0)
-
-/* RCC_MP_MLAHBLPENSETR register fields */
-#define RCC_MP_MLAHBLPENSETR_SRAM1LPEN BIT(0)
-#define RCC_MP_MLAHBLPENSETR_SRAM2LPEN BIT(1)
-#define RCC_MP_MLAHBLPENSETR_SRAM34LPEN BIT(2)
-#define RCC_MP_MLAHBLPENSETR_RETRAMLPEN BIT(4)
-
-/* RCC_MP_MLAHBLPENCLRR register fields */
-#define RCC_MP_MLAHBLPENCLRR_SRAM1LPEN BIT(0)
-#define RCC_MP_MLAHBLPENCLRR_SRAM2LPEN BIT(1)
-#define RCC_MP_MLAHBLPENCLRR_SRAM34LPEN BIT(2)
-#define RCC_MP_MLAHBLPENCLRR_RETRAMLPEN BIT(4)
-
-/* RCC_MC_APB1LPENSETR register fields */
-#define RCC_MC_APB1LPENSETR_TIM2LPEN BIT(0)
-#define RCC_MC_APB1LPENSETR_TIM3LPEN BIT(1)
-#define RCC_MC_APB1LPENSETR_TIM4LPEN BIT(2)
-#define RCC_MC_APB1LPENSETR_TIM5LPEN BIT(3)
-#define RCC_MC_APB1LPENSETR_TIM6LPEN BIT(4)
-#define RCC_MC_APB1LPENSETR_TIM7LPEN BIT(5)
-#define RCC_MC_APB1LPENSETR_TIM12LPEN BIT(6)
-#define RCC_MC_APB1LPENSETR_TIM13LPEN BIT(7)
-#define RCC_MC_APB1LPENSETR_TIM14LPEN BIT(8)
-#define RCC_MC_APB1LPENSETR_LPTIM1LPEN BIT(9)
-#define RCC_MC_APB1LPENSETR_SPI2LPEN BIT(11)
-#define RCC_MC_APB1LPENSETR_SPI3LPEN BIT(12)
-#define RCC_MC_APB1LPENSETR_USART2LPEN BIT(14)
-#define RCC_MC_APB1LPENSETR_USART3LPEN BIT(15)
-#define RCC_MC_APB1LPENSETR_UART4LPEN BIT(16)
-#define RCC_MC_APB1LPENSETR_UART5LPEN BIT(17)
-#define RCC_MC_APB1LPENSETR_UART7LPEN BIT(18)
-#define RCC_MC_APB1LPENSETR_UART8LPEN BIT(19)
-#define RCC_MC_APB1LPENSETR_I2C1LPEN BIT(21)
-#define RCC_MC_APB1LPENSETR_I2C2LPEN BIT(22)
-#define RCC_MC_APB1LPENSETR_I2C3LPEN BIT(23)
-#define RCC_MC_APB1LPENSETR_I2C5LPEN BIT(24)
-#define RCC_MC_APB1LPENSETR_SPDIFLPEN BIT(26)
-#define RCC_MC_APB1LPENSETR_CECLPEN BIT(27)
-#define RCC_MC_APB1LPENSETR_WWDG1LPEN BIT(28)
-#define RCC_MC_APB1LPENSETR_DAC12LPEN BIT(29)
-#define RCC_MC_APB1LPENSETR_MDIOSLPEN BIT(31)
-
-/* RCC_MC_APB1LPENCLRR register fields */
-#define RCC_MC_APB1LPENCLRR_TIM2LPEN BIT(0)
-#define RCC_MC_APB1LPENCLRR_TIM3LPEN BIT(1)
-#define RCC_MC_APB1LPENCLRR_TIM4LPEN BIT(2)
-#define RCC_MC_APB1LPENCLRR_TIM5LPEN BIT(3)
-#define RCC_MC_APB1LPENCLRR_TIM6LPEN BIT(4)
-#define RCC_MC_APB1LPENCLRR_TIM7LPEN BIT(5)
-#define RCC_MC_APB1LPENCLRR_TIM12LPEN BIT(6)
-#define RCC_MC_APB1LPENCLRR_TIM13LPEN BIT(7)
-#define RCC_MC_APB1LPENCLRR_TIM14LPEN BIT(8)
-#define RCC_MC_APB1LPENCLRR_LPTIM1LPEN BIT(9)
-#define RCC_MC_APB1LPENCLRR_SPI2LPEN BIT(11)
-#define RCC_MC_APB1LPENCLRR_SPI3LPEN BIT(12)
-#define RCC_MC_APB1LPENCLRR_USART2LPEN BIT(14)
-#define RCC_MC_APB1LPENCLRR_USART3LPEN BIT(15)
-#define RCC_MC_APB1LPENCLRR_UART4LPEN BIT(16)
-#define RCC_MC_APB1LPENCLRR_UART5LPEN BIT(17)
-#define RCC_MC_APB1LPENCLRR_UART7LPEN BIT(18)
-#define RCC_MC_APB1LPENCLRR_UART8LPEN BIT(19)
-#define RCC_MC_APB1LPENCLRR_I2C1LPEN BIT(21)
-#define RCC_MC_APB1LPENCLRR_I2C2LPEN BIT(22)
-#define RCC_MC_APB1LPENCLRR_I2C3LPEN BIT(23)
-#define RCC_MC_APB1LPENCLRR_I2C5LPEN BIT(24)
-#define RCC_MC_APB1LPENCLRR_SPDIFLPEN BIT(26)
-#define RCC_MC_APB1LPENCLRR_CECLPEN BIT(27)
-#define RCC_MC_APB1LPENCLRR_WWDG1LPEN BIT(28)
-#define RCC_MC_APB1LPENCLRR_DAC12LPEN BIT(29)
-#define RCC_MC_APB1LPENCLRR_MDIOSLPEN BIT(31)
-
-/* RCC_MC_APB2LPENSETR register fields */
-#define RCC_MC_APB2LPENSETR_TIM1LPEN BIT(0)
-#define RCC_MC_APB2LPENSETR_TIM8LPEN BIT(1)
-#define RCC_MC_APB2LPENSETR_TIM15LPEN BIT(2)
-#define RCC_MC_APB2LPENSETR_TIM16LPEN BIT(3)
-#define RCC_MC_APB2LPENSETR_TIM17LPEN BIT(4)
-#define RCC_MC_APB2LPENSETR_SPI1LPEN BIT(8)
-#define RCC_MC_APB2LPENSETR_SPI4LPEN BIT(9)
-#define RCC_MC_APB2LPENSETR_SPI5LPEN BIT(10)
-#define RCC_MC_APB2LPENSETR_USART6LPEN BIT(13)
-#define RCC_MC_APB2LPENSETR_SAI1LPEN BIT(16)
-#define RCC_MC_APB2LPENSETR_SAI2LPEN BIT(17)
-#define RCC_MC_APB2LPENSETR_SAI3LPEN BIT(18)
-#define RCC_MC_APB2LPENSETR_DFSDMLPEN BIT(20)
-#define RCC_MC_APB2LPENSETR_ADFSDMLPEN BIT(21)
-#define RCC_MC_APB2LPENSETR_FDCANLPEN BIT(24)
-
-/* RCC_MC_APB2LPENCLRR register fields */
-#define RCC_MC_APB2LPENCLRR_TIM1LPEN BIT(0)
-#define RCC_MC_APB2LPENCLRR_TIM8LPEN BIT(1)
-#define RCC_MC_APB2LPENCLRR_TIM15LPEN BIT(2)
-#define RCC_MC_APB2LPENCLRR_TIM16LPEN BIT(3)
-#define RCC_MC_APB2LPENCLRR_TIM17LPEN BIT(4)
-#define RCC_MC_APB2LPENCLRR_SPI1LPEN BIT(8)
-#define RCC_MC_APB2LPENCLRR_SPI4LPEN BIT(9)
-#define RCC_MC_APB2LPENCLRR_SPI5LPEN BIT(10)
-#define RCC_MC_APB2LPENCLRR_USART6LPEN BIT(13)
-#define RCC_MC_APB2LPENCLRR_SAI1LPEN BIT(16)
-#define RCC_MC_APB2LPENCLRR_SAI2LPEN BIT(17)
-#define RCC_MC_APB2LPENCLRR_SAI3LPEN BIT(18)
-#define RCC_MC_APB2LPENCLRR_DFSDMLPEN BIT(20)
-#define RCC_MC_APB2LPENCLRR_ADFSDMLPEN BIT(21)
-#define RCC_MC_APB2LPENCLRR_FDCANLPEN BIT(24)
-
-/* RCC_MC_APB3LPENSETR register fields */
-#define RCC_MC_APB3LPENSETR_LPTIM2LPEN BIT(0)
-#define RCC_MC_APB3LPENSETR_LPTIM3LPEN BIT(1)
-#define RCC_MC_APB3LPENSETR_LPTIM4LPEN BIT(2)
-#define RCC_MC_APB3LPENSETR_LPTIM5LPEN BIT(3)
-#define RCC_MC_APB3LPENSETR_SAI4LPEN BIT(8)
-#define RCC_MC_APB3LPENSETR_SYSCFGLPEN BIT(11)
-#define RCC_MC_APB3LPENSETR_VREFLPEN BIT(13)
-#define RCC_MC_APB3LPENSETR_TMPSENSLPEN BIT(16)
-#define RCC_MC_APB3LPENSETR_PMBCTRLLPEN BIT(17)
-
-/* RCC_MC_APB3LPENCLRR register fields */
-#define RCC_MC_APB3LPENCLRR_LPTIM2LPEN BIT(0)
-#define RCC_MC_APB3LPENCLRR_LPTIM3LPEN BIT(1)
-#define RCC_MC_APB3LPENCLRR_LPTIM4LPEN BIT(2)
-#define RCC_MC_APB3LPENCLRR_LPTIM5LPEN BIT(3)
-#define RCC_MC_APB3LPENCLRR_SAI4LPEN BIT(8)
-#define RCC_MC_APB3LPENCLRR_SYSCFGLPEN BIT(11)
-#define RCC_MC_APB3LPENCLRR_VREFLPEN BIT(13)
-#define RCC_MC_APB3LPENCLRR_TMPSENSLPEN BIT(16)
-#define RCC_MC_APB3LPENCLRR_PMBCTRLLPEN BIT(17)
-
-/* RCC_MC_AHB2LPENSETR register fields */
-#define RCC_MC_AHB2LPENSETR_DMA1LPEN BIT(0)
-#define RCC_MC_AHB2LPENSETR_DMA2LPEN BIT(1)
-#define RCC_MC_AHB2LPENSETR_DMAMUXLPEN BIT(2)
-#define RCC_MC_AHB2LPENSETR_ADC12LPEN BIT(5)
-#define RCC_MC_AHB2LPENSETR_USBOLPEN BIT(8)
-#define RCC_MC_AHB2LPENSETR_SDMMC3LPEN BIT(16)
-
-/* RCC_MC_AHB2LPENCLRR register fields */
-#define RCC_MC_AHB2LPENCLRR_DMA1LPEN BIT(0)
-#define RCC_MC_AHB2LPENCLRR_DMA2LPEN BIT(1)
-#define RCC_MC_AHB2LPENCLRR_DMAMUXLPEN BIT(2)
-#define RCC_MC_AHB2LPENCLRR_ADC12LPEN BIT(5)
-#define RCC_MC_AHB2LPENCLRR_USBOLPEN BIT(8)
-#define RCC_MC_AHB2LPENCLRR_SDMMC3LPEN BIT(16)
-
-/* RCC_MC_AHB3LPENSETR register fields */
-#define RCC_MC_AHB3LPENSETR_DCMILPEN BIT(0)
-#define RCC_MC_AHB3LPENSETR_CRYP2LPEN BIT(4)
-#define RCC_MC_AHB3LPENSETR_HASH2LPEN BIT(5)
-#define RCC_MC_AHB3LPENSETR_RNG2LPEN BIT(6)
-#define RCC_MC_AHB3LPENSETR_CRC2LPEN BIT(7)
-#define RCC_MC_AHB3LPENSETR_HSEMLPEN BIT(11)
-#define RCC_MC_AHB3LPENSETR_IPCCLPEN BIT(12)
-
-/* RCC_MC_AHB3LPENCLRR register fields */
-#define RCC_MC_AHB3LPENCLRR_DCMILPEN BIT(0)
-#define RCC_MC_AHB3LPENCLRR_CRYP2LPEN BIT(4)
-#define RCC_MC_AHB3LPENCLRR_HASH2LPEN BIT(5)
-#define RCC_MC_AHB3LPENCLRR_RNG2LPEN BIT(6)
-#define RCC_MC_AHB3LPENCLRR_CRC2LPEN BIT(7)
-#define RCC_MC_AHB3LPENCLRR_HSEMLPEN BIT(11)
-#define RCC_MC_AHB3LPENCLRR_IPCCLPEN BIT(12)
-
-/* RCC_MC_AHB4LPENSETR register fields */
-#define RCC_MC_AHB4LPENSETR_GPIOALPEN BIT(0)
-#define RCC_MC_AHB4LPENSETR_GPIOBLPEN BIT(1)
-#define RCC_MC_AHB4LPENSETR_GPIOCLPEN BIT(2)
-#define RCC_MC_AHB4LPENSETR_GPIODLPEN BIT(3)
-#define RCC_MC_AHB4LPENSETR_GPIOELPEN BIT(4)
-#define RCC_MC_AHB4LPENSETR_GPIOFLPEN BIT(5)
-#define RCC_MC_AHB4LPENSETR_GPIOGLPEN BIT(6)
-#define RCC_MC_AHB4LPENSETR_GPIOHLPEN BIT(7)
-#define RCC_MC_AHB4LPENSETR_GPIOILPEN BIT(8)
-#define RCC_MC_AHB4LPENSETR_GPIOJLPEN BIT(9)
-#define RCC_MC_AHB4LPENSETR_GPIOKLPEN BIT(10)
-
-/* RCC_MC_AHB4LPENCLRR register fields */
-#define RCC_MC_AHB4LPENCLRR_GPIOALPEN BIT(0)
-#define RCC_MC_AHB4LPENCLRR_GPIOBLPEN BIT(1)
-#define RCC_MC_AHB4LPENCLRR_GPIOCLPEN BIT(2)
-#define RCC_MC_AHB4LPENCLRR_GPIODLPEN BIT(3)
-#define RCC_MC_AHB4LPENCLRR_GPIOELPEN BIT(4)
-#define RCC_MC_AHB4LPENCLRR_GPIOFLPEN BIT(5)
-#define RCC_MC_AHB4LPENCLRR_GPIOGLPEN BIT(6)
-#define RCC_MC_AHB4LPENCLRR_GPIOHLPEN BIT(7)
-#define RCC_MC_AHB4LPENCLRR_GPIOILPEN BIT(8)
-#define RCC_MC_AHB4LPENCLRR_GPIOJLPEN BIT(9)
-#define RCC_MC_AHB4LPENCLRR_GPIOKLPEN BIT(10)
-
-/* RCC_MC_AXIMLPENSETR register fields */
-#define RCC_MC_AXIMLPENSETR_SYSRAMLPEN BIT(0)
-
-/* RCC_MC_AXIMLPENCLRR register fields */
-#define RCC_MC_AXIMLPENCLRR_SYSRAMLPEN BIT(0)
-
-/* RCC_MC_MLAHBLPENSETR register fields */
-#define RCC_MC_MLAHBLPENSETR_SRAM1LPEN BIT(0)
-#define RCC_MC_MLAHBLPENSETR_SRAM2LPEN BIT(1)
-#define RCC_MC_MLAHBLPENSETR_SRAM34LPEN BIT(2)
-#define RCC_MC_MLAHBLPENSETR_RETRAMLPEN BIT(4)
-
-/* RCC_MC_MLAHBLPENCLRR register fields */
-#define RCC_MC_MLAHBLPENCLRR_SRAM1LPEN BIT(0)
-#define RCC_MC_MLAHBLPENCLRR_SRAM2LPEN BIT(1)
-#define RCC_MC_MLAHBLPENCLRR_SRAM34LPEN BIT(2)
-#define RCC_MC_MLAHBLPENCLRR_RETRAMLPEN BIT(4)
-
-/* RCC_MC_RSTSCLRR register fields */
-#define RCC_MC_RSTSCLRR_PORRSTF BIT(0)
-#define RCC_MC_RSTSCLRR_BORRSTF BIT(1)
-#define RCC_MC_RSTSCLRR_PADRSTF BIT(2)
-#define RCC_MC_RSTSCLRR_HCSSRSTF BIT(3)
-#define RCC_MC_RSTSCLRR_VCORERSTF BIT(4)
-#define RCC_MC_RSTSCLRR_MCURSTF BIT(5)
-#define RCC_MC_RSTSCLRR_MPSYSRSTF BIT(6)
-#define RCC_MC_RSTSCLRR_MCSYSRSTF BIT(7)
-#define RCC_MC_RSTSCLRR_IWDG1RSTF BIT(8)
-#define RCC_MC_RSTSCLRR_IWDG2RSTF BIT(9)
-#define RCC_MC_RSTSCLRR_WWDG1RSTF BIT(10)
-
-/* RCC_MC_CIER register fields */
-#define RCC_MC_CIER_LSIRDYIE BIT(0)
-#define RCC_MC_CIER_LSERDYIE BIT(1)
-#define RCC_MC_CIER_HSIRDYIE BIT(2)
-#define RCC_MC_CIER_HSERDYIE BIT(3)
-#define RCC_MC_CIER_CSIRDYIE BIT(4)
-#define RCC_MC_CIER_PLL1DYIE BIT(8)
-#define RCC_MC_CIER_PLL2DYIE BIT(9)
-#define RCC_MC_CIER_PLL3DYIE BIT(10)
-#define RCC_MC_CIER_PLL4DYIE BIT(11)
-#define RCC_MC_CIER_LSECSSIE BIT(16)
-#define RCC_MC_CIER_WKUPIE BIT(20)
-
-/* RCC_MC_CIFR register fields */
-#define RCC_MC_CIFR_LSIRDYF BIT(0)
-#define RCC_MC_CIFR_LSERDYF BIT(1)
-#define RCC_MC_CIFR_HSIRDYF BIT(2)
-#define RCC_MC_CIFR_HSERDYF BIT(3)
-#define RCC_MC_CIFR_CSIRDYF BIT(4)
-#define RCC_MC_CIFR_PLL1DYF BIT(8)
-#define RCC_MC_CIFR_PLL2DYF BIT(9)
-#define RCC_MC_CIFR_PLL3DYF BIT(10)
-#define RCC_MC_CIFR_PLL4DYF BIT(11)
-#define RCC_MC_CIFR_LSECSSF BIT(16)
-#define RCC_MC_CIFR_WKUPF BIT(20)
-
-/* RCC_VERR register fields */
-#define RCC_VERR_MINREV_MASK GENMASK(3, 0)
-#define RCC_VERR_MINREV_SHIFT 0
-#define RCC_VERR_MAJREV_MASK GENMASK(7, 4)
-#define RCC_VERR_MAJREV_SHIFT 4
-
-/* Used for RCC_OCENSETR and RCC_OCENCLRR registers */
-#define RCC_OCENR_HSION BIT(0)
-#define RCC_OCENR_HSIKERON BIT(1)
-#define RCC_OCENR_CSION BIT(4)
-#define RCC_OCENR_CSIKERON BIT(5)
-#define RCC_OCENR_DIGBYP BIT(7)
-#define RCC_OCENR_HSEON BIT(8)
-#define RCC_OCENR_HSEKERON BIT(9)
-#define RCC_OCENR_HSEBYP BIT(10)
-#define RCC_OCENR_HSECSSON BIT(11)
-
-/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */
-#define RCC_MP_ENCLRR_OFFSET U(4)
-
-/* Offset between RCC_xxxRSTSETR and RCC_xxxRSTCLRR registers */
-#define RCC_RSTCLRR_OFFSET U(4)
-
-/* Used for most of DIVR register: max div for RTC */
-#define RCC_DIVR_DIV_MASK GENMASK(5, 0)
-#define RCC_DIVR_DIVRDY BIT(31)
-
-/* Masks for specific DIVR registers */
-#define RCC_APBXDIV_MASK GENMASK(2, 0)
-#define RCC_MPUDIV_MASK GENMASK(2, 0)
-#define RCC_AXIDIV_MASK GENMASK(2, 0)
-#define RCC_MCUDIV_MASK GENMASK(3, 0)
-
-/* Used for most of RCC_<x>SELR registers */
-#define RCC_SELR_SRC_MASK GENMASK(2, 0)
-#define RCC_SELR_REFCLK_SRC_MASK GENMASK(1, 0)
-#define RCC_SELR_SRCRDY BIT(31)
-
-/* Used for all RCC_PLL<n>CR registers */
-#define RCC_PLLNCR_PLLON BIT(0)
-#define RCC_PLLNCR_PLLRDY BIT(1)
-#define RCC_PLLNCR_SSCG_CTRL BIT(2)
-#define RCC_PLLNCR_DIVPEN BIT(4)
-#define RCC_PLLNCR_DIVQEN BIT(5)
-#define RCC_PLLNCR_DIVREN BIT(6)
-#define RCC_PLLNCR_DIVEN_SHIFT 4
-
-/* Used for all RCC_PLL<n>CFGR1 registers */
-#define RCC_PLLNCFGR1_DIVM_MASK GENMASK(21, 16)
-#define RCC_PLLNCFGR1_DIVM_SHIFT 16
-#define RCC_PLLNCFGR1_DIVN_MASK GENMASK(8, 0)
-#define RCC_PLLNCFGR1_DIVN_SHIFT 0
-
-/* Only for PLL3 and PLL4 */
-#define RCC_PLLNCFGR1_IFRGE_MASK GENMASK(25, 24)
-#define RCC_PLLNCFGR1_IFRGE_SHIFT 24
-
-/* Used for all RCC_PLL<n>CFGR2 registers */
-#define RCC_PLLNCFGR2_DIVX_MASK GENMASK(6, 0)
-#define RCC_PLLNCFGR2_DIVP_MASK GENMASK(6, 0)
-#define RCC_PLLNCFGR2_DIVP_SHIFT 0
-#define RCC_PLLNCFGR2_DIVQ_MASK GENMASK(14, 8)
-#define RCC_PLLNCFGR2_DIVQ_SHIFT 8
-#define RCC_PLLNCFGR2_DIVR_MASK GENMASK(22, 16)
-#define RCC_PLLNCFGR2_DIVR_SHIFT 16
-
-/* Used for all RCC_PLL<n>FRACR registers */
-#define RCC_PLLNFRACR_FRACV_SHIFT 3
-#define RCC_PLLNFRACR_FRACV_MASK GENMASK(15, 3)
-#define RCC_PLLNFRACR_FRACLE BIT(16)
-
-/* Used for all RCC_PLL<n>CSGR registers */
-#define RCC_PLLNCSGR_INC_STEP_SHIFT 16
-#define RCC_PLLNCSGR_INC_STEP_MASK GENMASK(30, 16)
-#define RCC_PLLNCSGR_MOD_PER_SHIFT 0
-#define RCC_PLLNCSGR_MOD_PER_MASK GENMASK(12, 0)
-#define RCC_PLLNCSGR_SSCG_MODE_SHIFT 15
-#define RCC_PLLNCSGR_SSCG_MODE_MASK BIT(15)
-
-/* Used for TIMER Prescaler */
-#define RCC_TIMGXPRER_TIMGXPRE BIT(0)
-
-/* Used for RCC_MCO related operations */
-#define RCC_MCOCFG_MCOON BIT(12)
-#define RCC_MCOCFG_MCODIV_MASK GENMASK(7, 4)
-#define RCC_MCOCFG_MCODIV_SHIFT 4
-#define RCC_MCOCFG_MCOSRC_MASK GENMASK(2, 0)
-
-#endif /* STM32MP1_RCC_H */
+#if STM32MP13
+#include "stm32mp13_rcc.h"
+#endif
+#if STM32MP15
+#include "stm32mp15_rcc.h"
+#endif
diff --git a/include/drivers/st/stm32mp_pmic.h b/include/drivers/st/stm32mp_pmic.h
index 4dfb038..303c571 100644
--- a/include/drivers/st/stm32mp_pmic.h
+++ b/include/drivers/st/stm32mp_pmic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -48,4 +48,11 @@
*/
int pmic_ddr_power_init(enum ddr_type ddr_type);
+/*
+ * pmic_voltages_init - Update voltages for platform init
+ *
+ * Returns 0 on success, and negative values on errors
+ */
+int pmic_voltages_init(void);
+
#endif /* STM32MP_PMIC_H */
diff --git a/include/drivers/ufs.h b/include/drivers/ufs.h
index c074e85..09b8b72 100644
--- a/include/drivers/ufs.h
+++ b/include/drivers/ufs.h
@@ -69,6 +69,7 @@
/* Host Controller Enable */
#define HCE 0x34
#define HCE_ENABLE 1
+#define HCE_DISABLE 0
/* Host UIC Error Code PHY Adapter Layer */
#define UECPA 0x38
@@ -258,12 +259,18 @@
/* maximum number of retries for a general UIC command */
#define UFS_UIC_COMMAND_RETRIES 3
+/* maximum number of retries for reading UFS capacity */
+#define UFS_READ_CAPACITY_RETRIES 10
+
/* maximum number of link-startup retries */
#define DME_LINKSTARTUP_RETRIES 10
#define HCE_ENABLE_OUTER_RETRIES 3
#define HCE_ENABLE_INNER_RETRIES 50
#define HCE_ENABLE_TIMEOUT_US 100
+#define HCE_DISABLE_TIMEOUT_US 1000
+
+#define FDEVICEINIT_TIMEOUT_MS 1500
/**
* ufs_dev_desc - ufs device details from the device descriptor
diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h
index 67e66b2..0d25ded 100644
--- a/include/dt-bindings/clock/stm32mp1-clks.h
+++ b/include/dt-bindings/clock/stm32mp1-clks.h
@@ -1,278 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/*
- * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Copyright (C) STMicroelectronics 2018-2022 - All Rights Reserved
* Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
*/
-#ifndef _DT_BINDINGS_STM32MP1_CLKS_H_
-#define _DT_BINDINGS_STM32MP1_CLKS_H_
-
-/* OSCILLATOR clocks */
-#define CK_HSE 0
-#define CK_CSI 1
-#define CK_LSI 2
-#define CK_LSE 3
-#define CK_HSI 4
-#define CK_HSE_DIV2 5
-
-/* Bus clocks */
-#define TIM2 6
-#define TIM3 7
-#define TIM4 8
-#define TIM5 9
-#define TIM6 10
-#define TIM7 11
-#define TIM12 12
-#define TIM13 13
-#define TIM14 14
-#define LPTIM1 15
-#define SPI2 16
-#define SPI3 17
-#define USART2 18
-#define USART3 19
-#define UART4 20
-#define UART5 21
-#define UART7 22
-#define UART8 23
-#define I2C1 24
-#define I2C2 25
-#define I2C3 26
-#define I2C5 27
-#define SPDIF 28
-#define CEC 29
-#define DAC12 30
-#define MDIO 31
-#define TIM1 32
-#define TIM8 33
-#define TIM15 34
-#define TIM16 35
-#define TIM17 36
-#define SPI1 37
-#define SPI4 38
-#define SPI5 39
-#define USART6 40
-#define SAI1 41
-#define SAI2 42
-#define SAI3 43
-#define DFSDM 44
-#define FDCAN 45
-#define LPTIM2 46
-#define LPTIM3 47
-#define LPTIM4 48
-#define LPTIM5 49
-#define SAI4 50
-#define SYSCFG 51
-#define VREF 52
-#define TMPSENS 53
-#define PMBCTRL 54
-#define HDP 55
-#define LTDC 56
-#define DSI 57
-#define IWDG2 58
-#define USBPHY 59
-#define STGENRO 60
-#define SPI6 61
-#define I2C4 62
-#define I2C6 63
-#define USART1 64
-#define RTCAPB 65
-#define TZC1 66
-#define TZPC 67
-#define IWDG1 68
-#define BSEC 69
-#define STGEN 70
-#define DMA1 71
-#define DMA2 72
-#define DMAMUX 73
-#define ADC12 74
-#define USBO 75
-#define SDMMC3 76
-#define DCMI 77
-#define CRYP2 78
-#define HASH2 79
-#define RNG2 80
-#define CRC2 81
-#define HSEM 82
-#define IPCC 83
-#define GPIOA 84
-#define GPIOB 85
-#define GPIOC 86
-#define GPIOD 87
-#define GPIOE 88
-#define GPIOF 89
-#define GPIOG 90
-#define GPIOH 91
-#define GPIOI 92
-#define GPIOJ 93
-#define GPIOK 94
-#define GPIOZ 95
-#define CRYP1 96
-#define HASH1 97
-#define RNG1 98
-#define BKPSRAM 99
-#define MDMA 100
-#define GPU 101
-#define ETHCK 102
-#define ETHTX 103
-#define ETHRX 104
-#define ETHMAC 105
-#define FMC 106
-#define QSPI 107
-#define SDMMC1 108
-#define SDMMC2 109
-#define CRC1 110
-#define USBH 111
-#define ETHSTP 112
-#define TZC2 113
-
-/* Kernel clocks */
-#define SDMMC1_K 118
-#define SDMMC2_K 119
-#define SDMMC3_K 120
-#define FMC_K 121
-#define QSPI_K 122
-#define ETHCK_K 123
-#define RNG1_K 124
-#define RNG2_K 125
-#define GPU_K 126
-#define USBPHY_K 127
-#define STGEN_K 128
-#define SPDIF_K 129
-#define SPI1_K 130
-#define SPI2_K 131
-#define SPI3_K 132
-#define SPI4_K 133
-#define SPI5_K 134
-#define SPI6_K 135
-#define CEC_K 136
-#define I2C1_K 137
-#define I2C2_K 138
-#define I2C3_K 139
-#define I2C4_K 140
-#define I2C5_K 141
-#define I2C6_K 142
-#define LPTIM1_K 143
-#define LPTIM2_K 144
-#define LPTIM3_K 145
-#define LPTIM4_K 146
-#define LPTIM5_K 147
-#define USART1_K 148
-#define USART2_K 149
-#define USART3_K 150
-#define UART4_K 151
-#define UART5_K 152
-#define USART6_K 153
-#define UART7_K 154
-#define UART8_K 155
-#define DFSDM_K 156
-#define FDCAN_K 157
-#define SAI1_K 158
-#define SAI2_K 159
-#define SAI3_K 160
-#define SAI4_K 161
-#define ADC12_K 162
-#define DSI_K 163
-#define DSI_PX 164
-#define ADFSDM_K 165
-#define USBO_K 166
-#define LTDC_PX 167
-#define DAC12_K 168
-#define ETHPTP_K 169
-
-/* PLL */
-#define PLL1 176
-#define PLL2 177
-#define PLL3 178
-#define PLL4 179
-
-/* ODF */
-#define PLL1_P 180
-#define PLL1_Q 181
-#define PLL1_R 182
-#define PLL2_P 183
-#define PLL2_Q 184
-#define PLL2_R 185
-#define PLL3_P 186
-#define PLL3_Q 187
-#define PLL3_R 188
-#define PLL4_P 189
-#define PLL4_Q 190
-#define PLL4_R 191
-
-/* AUX */
-#define RTC 192
-
-/* MCLK */
-#define CK_PER 193
-#define CK_MPU 194
-#define CK_AXI 195
-#define CK_MCU 196
-
-/* Time base */
-#define TIM2_K 197
-#define TIM3_K 198
-#define TIM4_K 199
-#define TIM5_K 200
-#define TIM6_K 201
-#define TIM7_K 202
-#define TIM12_K 203
-#define TIM13_K 204
-#define TIM14_K 205
-#define TIM1_K 206
-#define TIM8_K 207
-#define TIM15_K 208
-#define TIM16_K 209
-#define TIM17_K 210
-
-/* MCO clocks */
-#define CK_MCO1 211
-#define CK_MCO2 212
-
-/* TRACE & DEBUG clocks */
-#define CK_DBG 214
-#define CK_TRACE 215
-
-/* DDR */
-#define DDRC1 220
-#define DDRC1LP 221
-#define DDRC2 222
-#define DDRC2LP 223
-#define DDRPHYC 224
-#define DDRPHYCLP 225
-#define DDRCAPB 226
-#define DDRCAPBLP 227
-#define AXIDCG 228
-#define DDRPHYCAPB 229
-#define DDRPHYCAPBLP 230
-#define DDRPERFM 231
-
-#define STM32MP1_LAST_CLK 232
-
-/* SCMI clock identifiers */
-#define CK_SCMI0_HSE 0
-#define CK_SCMI0_HSI 1
-#define CK_SCMI0_CSI 2
-#define CK_SCMI0_LSE 3
-#define CK_SCMI0_LSI 4
-#define CK_SCMI0_PLL2_Q 5
-#define CK_SCMI0_PLL2_R 6
-#define CK_SCMI0_MPU 7
-#define CK_SCMI0_AXI 8
-#define CK_SCMI0_BSEC 9
-#define CK_SCMI0_CRYP1 10
-#define CK_SCMI0_GPIOZ 11
-#define CK_SCMI0_HASH1 12
-#define CK_SCMI0_I2C4 13
-#define CK_SCMI0_I2C6 14
-#define CK_SCMI0_IWDG1 15
-#define CK_SCMI0_RNG1 16
-#define CK_SCMI0_RTC 17
-#define CK_SCMI0_RTCAPB 18
-#define CK_SCMI0_SPI6 19
-#define CK_SCMI0_USART1 20
-
-#define CK_SCMI1_PLL3_Q 0
-#define CK_SCMI1_PLL3_R 1
-#define CK_SCMI1_MCU 2
-
-#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */
+#if STM32MP13
+#include "stm32mp13-clks.h"
+#endif
+#if STM32MP15
+#include "stm32mp15-clks.h"
+#endif
diff --git a/include/dt-bindings/clock/stm32mp1-clksrc.h b/include/dt-bindings/clock/stm32mp1-clksrc.h
index 818f4b7..d02ddcd 100644
--- a/include/dt-bindings/clock/stm32mp1-clksrc.h
+++ b/include/dt-bindings/clock/stm32mp1-clksrc.h
@@ -1,283 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/*
- * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2017-2022, STMicroelectronics - All Rights Reserved
*/
-#ifndef _DT_BINDINGS_CLOCK_STM32MP1_CLKSRC_H_
-#define _DT_BINDINGS_CLOCK_STM32MP1_CLKSRC_H_
-
-/* PLL output is enable when x=1, with x=p,q or r */
-#define PQR(p, q, r) (((p) & 1) | (((q) & 1) << 1) | (((r) & 1) << 2))
-
-/* st,clksrc: mandatory clock source */
-
-#define CLK_MPU_HSI 0x00000200
-#define CLK_MPU_HSE 0x00000201
-#define CLK_MPU_PLL1P 0x00000202
-#define CLK_MPU_PLL1P_DIV 0x00000203
-
-#define CLK_AXI_HSI 0x00000240
-#define CLK_AXI_HSE 0x00000241
-#define CLK_AXI_PLL2P 0x00000242
-
-#define CLK_MCU_HSI 0x00000480
-#define CLK_MCU_HSE 0x00000481
-#define CLK_MCU_CSI 0x00000482
-#define CLK_MCU_PLL3P 0x00000483
-
-#define CLK_PLL12_HSI 0x00000280
-#define CLK_PLL12_HSE 0x00000281
-
-#define CLK_PLL3_HSI 0x00008200
-#define CLK_PLL3_HSE 0x00008201
-#define CLK_PLL3_CSI 0x00008202
-
-#define CLK_PLL4_HSI 0x00008240
-#define CLK_PLL4_HSE 0x00008241
-#define CLK_PLL4_CSI 0x00008242
-#define CLK_PLL4_I2SCKIN 0x00008243
-
-#define CLK_RTC_DISABLED 0x00001400
-#define CLK_RTC_LSE 0x00001401
-#define CLK_RTC_LSI 0x00001402
-#define CLK_RTC_HSE 0x00001403
-
-#define CLK_MCO1_HSI 0x00008000
-#define CLK_MCO1_HSE 0x00008001
-#define CLK_MCO1_CSI 0x00008002
-#define CLK_MCO1_LSI 0x00008003
-#define CLK_MCO1_LSE 0x00008004
-#define CLK_MCO1_DISABLED 0x0000800F
-
-#define CLK_MCO2_MPU 0x00008040
-#define CLK_MCO2_AXI 0x00008041
-#define CLK_MCO2_MCU 0x00008042
-#define CLK_MCO2_PLL4P 0x00008043
-#define CLK_MCO2_HSE 0x00008044
-#define CLK_MCO2_HSI 0x00008045
-#define CLK_MCO2_DISABLED 0x0000804F
-
-/* st,pkcs: peripheral kernel clock source */
-
-#define CLK_I2C12_PCLK1 0x00008C00
-#define CLK_I2C12_PLL4R 0x00008C01
-#define CLK_I2C12_HSI 0x00008C02
-#define CLK_I2C12_CSI 0x00008C03
-#define CLK_I2C12_DISABLED 0x00008C07
-
-#define CLK_I2C35_PCLK1 0x00008C40
-#define CLK_I2C35_PLL4R 0x00008C41
-#define CLK_I2C35_HSI 0x00008C42
-#define CLK_I2C35_CSI 0x00008C43
-#define CLK_I2C35_DISABLED 0x00008C47
-
-#define CLK_I2C46_PCLK5 0x00000C00
-#define CLK_I2C46_PLL3Q 0x00000C01
-#define CLK_I2C46_HSI 0x00000C02
-#define CLK_I2C46_CSI 0x00000C03
-#define CLK_I2C46_DISABLED 0x00000C07
-
-#define CLK_SAI1_PLL4Q 0x00008C80
-#define CLK_SAI1_PLL3Q 0x00008C81
-#define CLK_SAI1_I2SCKIN 0x00008C82
-#define CLK_SAI1_CKPER 0x00008C83
-#define CLK_SAI1_PLL3R 0x00008C84
-#define CLK_SAI1_DISABLED 0x00008C87
-
-#define CLK_SAI2_PLL4Q 0x00008CC0
-#define CLK_SAI2_PLL3Q 0x00008CC1
-#define CLK_SAI2_I2SCKIN 0x00008CC2
-#define CLK_SAI2_CKPER 0x00008CC3
-#define CLK_SAI2_SPDIF 0x00008CC4
-#define CLK_SAI2_PLL3R 0x00008CC5
-#define CLK_SAI2_DISABLED 0x00008CC7
-
-#define CLK_SAI3_PLL4Q 0x00008D00
-#define CLK_SAI3_PLL3Q 0x00008D01
-#define CLK_SAI3_I2SCKIN 0x00008D02
-#define CLK_SAI3_CKPER 0x00008D03
-#define CLK_SAI3_PLL3R 0x00008D04
-#define CLK_SAI3_DISABLED 0x00008D07
-
-#define CLK_SAI4_PLL4Q 0x00008D40
-#define CLK_SAI4_PLL3Q 0x00008D41
-#define CLK_SAI4_I2SCKIN 0x00008D42
-#define CLK_SAI4_CKPER 0x00008D43
-#define CLK_SAI4_PLL3R 0x00008D44
-#define CLK_SAI4_DISABLED 0x00008D47
-
-#define CLK_SPI2S1_PLL4P 0x00008D80
-#define CLK_SPI2S1_PLL3Q 0x00008D81
-#define CLK_SPI2S1_I2SCKIN 0x00008D82
-#define CLK_SPI2S1_CKPER 0x00008D83
-#define CLK_SPI2S1_PLL3R 0x00008D84
-#define CLK_SPI2S1_DISABLED 0x00008D87
-
-#define CLK_SPI2S23_PLL4P 0x00008DC0
-#define CLK_SPI2S23_PLL3Q 0x00008DC1
-#define CLK_SPI2S23_I2SCKIN 0x00008DC2
-#define CLK_SPI2S23_CKPER 0x00008DC3
-#define CLK_SPI2S23_PLL3R 0x00008DC4
-#define CLK_SPI2S23_DISABLED 0x00008DC7
-
-#define CLK_SPI45_PCLK2 0x00008E00
-#define CLK_SPI45_PLL4Q 0x00008E01
-#define CLK_SPI45_HSI 0x00008E02
-#define CLK_SPI45_CSI 0x00008E03
-#define CLK_SPI45_HSE 0x00008E04
-#define CLK_SPI45_DISABLED 0x00008E07
-
-#define CLK_SPI6_PCLK5 0x00000C40
-#define CLK_SPI6_PLL4Q 0x00000C41
-#define CLK_SPI6_HSI 0x00000C42
-#define CLK_SPI6_CSI 0x00000C43
-#define CLK_SPI6_HSE 0x00000C44
-#define CLK_SPI6_PLL3Q 0x00000C45
-#define CLK_SPI6_DISABLED 0x00000C47
-
-#define CLK_UART6_PCLK2 0x00008E40
-#define CLK_UART6_PLL4Q 0x00008E41
-#define CLK_UART6_HSI 0x00008E42
-#define CLK_UART6_CSI 0x00008E43
-#define CLK_UART6_HSE 0x00008E44
-#define CLK_UART6_DISABLED 0x00008E47
-
-#define CLK_UART24_PCLK1 0x00008E80
-#define CLK_UART24_PLL4Q 0x00008E81
-#define CLK_UART24_HSI 0x00008E82
-#define CLK_UART24_CSI 0x00008E83
-#define CLK_UART24_HSE 0x00008E84
-#define CLK_UART24_DISABLED 0x00008E87
-
-#define CLK_UART35_PCLK1 0x00008EC0
-#define CLK_UART35_PLL4Q 0x00008EC1
-#define CLK_UART35_HSI 0x00008EC2
-#define CLK_UART35_CSI 0x00008EC3
-#define CLK_UART35_HSE 0x00008EC4
-#define CLK_UART35_DISABLED 0x00008EC7
-
-#define CLK_UART78_PCLK1 0x00008F00
-#define CLK_UART78_PLL4Q 0x00008F01
-#define CLK_UART78_HSI 0x00008F02
-#define CLK_UART78_CSI 0x00008F03
-#define CLK_UART78_HSE 0x00008F04
-#define CLK_UART78_DISABLED 0x00008F07
-
-#define CLK_UART1_PCLK5 0x00000C80
-#define CLK_UART1_PLL3Q 0x00000C81
-#define CLK_UART1_HSI 0x00000C82
-#define CLK_UART1_CSI 0x00000C83
-#define CLK_UART1_PLL4Q 0x00000C84
-#define CLK_UART1_HSE 0x00000C85
-#define CLK_UART1_DISABLED 0x00000C87
-
-#define CLK_SDMMC12_HCLK6 0x00008F40
-#define CLK_SDMMC12_PLL3R 0x00008F41
-#define CLK_SDMMC12_PLL4P 0x00008F42
-#define CLK_SDMMC12_HSI 0x00008F43
-#define CLK_SDMMC12_DISABLED 0x00008F47
-
-#define CLK_SDMMC3_HCLK2 0x00008F80
-#define CLK_SDMMC3_PLL3R 0x00008F81
-#define CLK_SDMMC3_PLL4P 0x00008F82
-#define CLK_SDMMC3_HSI 0x00008F83
-#define CLK_SDMMC3_DISABLED 0x00008F87
-
-#define CLK_ETH_PLL4P 0x00008FC0
-#define CLK_ETH_PLL3Q 0x00008FC1
-#define CLK_ETH_DISABLED 0x00008FC3
-
-#define CLK_QSPI_ACLK 0x00009000
-#define CLK_QSPI_PLL3R 0x00009001
-#define CLK_QSPI_PLL4P 0x00009002
-#define CLK_QSPI_CKPER 0x00009003
-
-#define CLK_FMC_ACLK 0x00009040
-#define CLK_FMC_PLL3R 0x00009041
-#define CLK_FMC_PLL4P 0x00009042
-#define CLK_FMC_CKPER 0x00009043
-
-#define CLK_FDCAN_HSE 0x000090C0
-#define CLK_FDCAN_PLL3Q 0x000090C1
-#define CLK_FDCAN_PLL4Q 0x000090C2
-#define CLK_FDCAN_PLL4R 0x000090C3
-
-#define CLK_SPDIF_PLL4P 0x00009140
-#define CLK_SPDIF_PLL3Q 0x00009141
-#define CLK_SPDIF_HSI 0x00009142
-#define CLK_SPDIF_DISABLED 0x00009143
-
-#define CLK_CEC_LSE 0x00009180
-#define CLK_CEC_LSI 0x00009181
-#define CLK_CEC_CSI_DIV122 0x00009182
-#define CLK_CEC_DISABLED 0x00009183
-
-#define CLK_USBPHY_HSE 0x000091C0
-#define CLK_USBPHY_PLL4R 0x000091C1
-#define CLK_USBPHY_HSE_DIV2 0x000091C2
-#define CLK_USBPHY_DISABLED 0x000091C3
-
-#define CLK_USBO_PLL4R 0x800091C0
-#define CLK_USBO_USBPHY 0x800091C1
-
-#define CLK_RNG1_CSI 0x00000CC0
-#define CLK_RNG1_PLL4R 0x00000CC1
-#define CLK_RNG1_LSE 0x00000CC2
-#define CLK_RNG1_LSI 0x00000CC3
-
-#define CLK_RNG2_CSI 0x00009200
-#define CLK_RNG2_PLL4R 0x00009201
-#define CLK_RNG2_LSE 0x00009202
-#define CLK_RNG2_LSI 0x00009203
-
-#define CLK_CKPER_HSI 0x00000D00
-#define CLK_CKPER_CSI 0x00000D01
-#define CLK_CKPER_HSE 0x00000D02
-#define CLK_CKPER_DISABLED 0x00000D03
-
-#define CLK_STGEN_HSI 0x00000D40
-#define CLK_STGEN_HSE 0x00000D41
-#define CLK_STGEN_DISABLED 0x00000D43
-
-#define CLK_DSI_DSIPLL 0x00009240
-#define CLK_DSI_PLL4P 0x00009241
-
-#define CLK_ADC_PLL4R 0x00009280
-#define CLK_ADC_CKPER 0x00009281
-#define CLK_ADC_PLL3Q 0x00009282
-#define CLK_ADC_DISABLED 0x00009283
-
-#define CLK_LPTIM45_PCLK3 0x000092C0
-#define CLK_LPTIM45_PLL4P 0x000092C1
-#define CLK_LPTIM45_PLL3Q 0x000092C2
-#define CLK_LPTIM45_LSE 0x000092C3
-#define CLK_LPTIM45_LSI 0x000092C4
-#define CLK_LPTIM45_CKPER 0x000092C5
-#define CLK_LPTIM45_DISABLED 0x000092C7
-
-#define CLK_LPTIM23_PCLK3 0x00009300
-#define CLK_LPTIM23_PLL4Q 0x00009301
-#define CLK_LPTIM23_CKPER 0x00009302
-#define CLK_LPTIM23_LSE 0x00009303
-#define CLK_LPTIM23_LSI 0x00009304
-#define CLK_LPTIM23_DISABLED 0x00009307
-
-#define CLK_LPTIM1_PCLK1 0x00009340
-#define CLK_LPTIM1_PLL4P 0x00009341
-#define CLK_LPTIM1_PLL3Q 0x00009342
-#define CLK_LPTIM1_LSE 0x00009343
-#define CLK_LPTIM1_LSI 0x00009344
-#define CLK_LPTIM1_CKPER 0x00009345
-#define CLK_LPTIM1_DISABLED 0x00009347
-
-/* define for st,pll /csg */
-#define SSCG_MODE_CENTER_SPREAD 0
-#define SSCG_MODE_DOWN_SPREAD 1
-
-/* define for st,drive */
-#define LSEDRV_LOWEST 0
-#define LSEDRV_MEDIUM_LOW 1
-#define LSEDRV_MEDIUM_HIGH 2
-#define LSEDRV_HIGHEST 3
-
+#if STM32MP13
+#include "stm32mp13-clksrc.h"
+#endif
+#if STM32MP15
+#include "stm32mp15-clksrc.h"
#endif
diff --git a/include/dt-bindings/clock/stm32mp13-clks.h b/include/dt-bindings/clock/stm32mp13-clks.h
new file mode 100644
index 0000000..1d5bb78
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp13-clks.h
@@ -0,0 +1,230 @@
+/* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32MP13_CLKS_H_
+#define _DT_BINDINGS_STM32MP13_CLKS_H_
+
+/* OSCILLATOR clocks */
+#define CK_HSE 0
+#define CK_CSI 1
+#define CK_LSI 2
+#define CK_LSE 3
+#define CK_HSI 4
+#define CK_HSE_DIV2 5
+
+/* PLL */
+#define PLL1 6
+#define PLL2 7
+#define PLL3 8
+#define PLL4 9
+
+/* ODF */
+#define PLL1_P 10
+#define PLL1_Q 11
+#define PLL1_R 12
+#define PLL2_P 13
+#define PLL2_Q 14
+#define PLL2_R 15
+#define PLL3_P 16
+#define PLL3_Q 17
+#define PLL3_R 18
+#define PLL4_P 19
+#define PLL4_Q 20
+#define PLL4_R 21
+
+#define PCLK1 22
+#define PCLK2 23
+#define PCLK3 24
+#define PCLK4 25
+#define PCLK5 26
+#define PCLK6 27
+
+/* SYSTEM CLOCK */
+#define CK_PER 28
+#define CK_MPU 29
+#define CK_AXI 30
+#define CK_MLAHB 31
+
+/* BASE TIMER */
+#define CK_TIMG1 32
+#define CK_TIMG2 33
+#define CK_TIMG3 34
+
+/* AUX */
+#define RTC 35
+
+/* TRACE & DEBUG clocks */
+#define CK_DBG 36
+#define CK_TRACE 37
+
+/* MCO clocks */
+#define CK_MCO1 38
+#define CK_MCO2 39
+
+/* IP clocks */
+#define SYSCFG 40
+#define VREF 41
+#define TMPSENS 42
+#define PMBCTRL 43
+#define HDP 44
+#define IWDG2 45
+#define STGENRO 46
+#define USART1 47
+#define RTCAPB 48
+#define TZC 49
+#define TZPC 50
+#define IWDG1 51
+#define BSEC 52
+#define DMA1 53
+#define DMA2 54
+#define DMAMUX1 55
+#define DMAMUX2 56
+#define GPIOA 57
+#define GPIOB 58
+#define GPIOC 59
+#define GPIOD 60
+#define GPIOE 61
+#define GPIOF 62
+#define GPIOG 63
+#define GPIOH 64
+#define GPIOI 65
+#define CRYP1 66
+#define HASH1 67
+#define BKPSRAM 68
+#define MDMA 69
+#define CRC1 70
+#define USBH 71
+#define DMA3 72
+#define TSC 73
+#define PKA 74
+#define AXIMC 75
+#define MCE 76
+#define ETH1TX 77
+#define ETH2TX 78
+#define ETH1RX 79
+#define ETH2RX 80
+#define ETH1MAC 81
+#define ETH2MAC 82
+#define ETH1STP 83
+#define ETH2STP 84
+
+/* IP clocks with parents */
+#define SDMMC1_K 85
+#define SDMMC2_K 86
+#define ADC1_K 87
+#define ADC2_K 88
+#define FMC_K 89
+#define QSPI_K 90
+#define RNG1_K 91
+#define USBPHY_K 92
+#define STGEN_K 93
+#define SPDIF_K 94
+#define SPI1_K 95
+#define SPI2_K 96
+#define SPI3_K 97
+#define SPI4_K 98
+#define SPI5_K 99
+#define I2C1_K 100
+#define I2C2_K 101
+#define I2C3_K 102
+#define I2C4_K 103
+#define I2C5_K 104
+#define TIM2_K 105
+#define TIM3_K 106
+#define TIM4_K 107
+#define TIM5_K 108
+#define TIM6_K 109
+#define TIM7_K 110
+#define TIM12_K 111
+#define TIM13_K 112
+#define TIM14_K 113
+#define TIM1_K 114
+#define TIM8_K 115
+#define TIM15_K 116
+#define TIM16_K 117
+#define TIM17_K 118
+#define LPTIM1_K 119
+#define LPTIM2_K 120
+#define LPTIM3_K 121
+#define LPTIM4_K 122
+#define LPTIM5_K 123
+#define USART1_K 124
+#define USART2_K 125
+#define USART3_K 126
+#define UART4_K 127
+#define UART5_K 128
+#define USART6_K 129
+#define UART7_K 130
+#define UART8_K 131
+#define DFSDM_K 132
+#define FDCAN_K 133
+#define SAI1_K 134
+#define SAI2_K 135
+#define ADFSDM_K 136
+#define USBO_K 137
+#define LTDC_PX 138
+#define ETH1CK_K 139
+#define ETH1PTP_K 140
+#define ETH2CK_K 141
+#define ETH2PTP_K 142
+#define DCMIPP_K 143
+#define SAES_K 144
+#define DTS_K 145
+
+/* DDR */
+#define DDRC1 146
+#define DDRC1LP 147
+#define DDRC2 148
+#define DDRC2LP 149
+#define DDRPHYC 150
+#define DDRPHYCLP 151
+#define DDRCAPB 152
+#define DDRCAPBLP 153
+#define AXIDCG 154
+#define DDRPHYCAPB 155
+#define DDRPHYCAPBLP 156
+#define DDRPERFM 157
+
+#define ADC1 158
+#define ADC2 159
+#define SAI1 160
+#define SAI2 161
+
+#define STM32MP1_LAST_CLK 162
+
+/* SCMI clock identifiers */
+#define CK_SCMI0_HSE 0
+#define CK_SCMI0_HSI 1
+#define CK_SCMI0_CSI 2
+#define CK_SCMI0_LSE 3
+#define CK_SCMI0_LSI 4
+#define CK_SCMI0_HSE_DIV2 5
+#define CK_SCMI0_PLL2_Q 6
+#define CK_SCMI0_PLL2_R 7
+#define CK_SCMI0_PLL3_P 8
+#define CK_SCMI0_PLL3_Q 9
+#define CK_SCMI0_PLL3_R 10
+#define CK_SCMI0_PLL4_P 11
+#define CK_SCMI0_PLL4_Q 12
+#define CK_SCMI0_PLL4_R 13
+#define CK_SCMI0_MPU 14
+#define CK_SCMI0_AXI 15
+#define CK_SCMI0_MLAHB 16
+#define CK_SCMI0_CKPER 17
+#define CK_SCMI0_PCLK1 18
+#define CK_SCMI0_PCLK2 19
+#define CK_SCMI0_PCLK3 20
+#define CK_SCMI0_PCLK4 21
+#define CK_SCMI0_PCLK5 22
+#define CK_SCMI0_PCLK6 23
+#define CK_SCMI0_CKTIMG1 24
+#define CK_SCMI0_CKTIMG2 25
+#define CK_SCMI0_CKTIMG3 26
+#define CK_SCMI0_RTC 27
+#define CK_SCMI0_RTCAPB 28
+#define CK_SCMI0_BSEC 29
+
+#endif /* _DT_BINDINGS_STM32MP13_CLKS_H_ */
diff --git a/include/dt-bindings/clock/stm32mp13-clksrc.h b/include/dt-bindings/clock/stm32mp13-clksrc.h
new file mode 100644
index 0000000..0d54ab9
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp13-clksrc.h
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_STM32MP13_CLKSRC_H_
+#define _DT_BINDINGS_CLOCK_STM32MP13_CLKSRC_H_
+
+#define CMD_DIV 0
+#define CMD_MUX 1
+#define CMD_CLK 2
+#define CMD_RESERVED1 3
+
+#define CMD_SHIFT 26
+#define CMD_MASK 0xFC000000
+#define CMD_DATA_MASK 0x03FFFFFF
+
+#define DIV_ID_SHIFT 8
+#define DIV_ID_MASK 0x0000FF00
+
+#define DIV_DIVN_SHIFT 0
+#define DIV_DIVN_MASK 0x000000FF
+
+#define MUX_ID_SHIFT 4
+#define MUX_ID_MASK 0x00000FF0
+
+#define MUX_SEL_SHIFT 0
+#define MUX_SEL_MASK 0x0000000F
+
+#define CLK_ID_MASK GENMASK_32(19, 11)
+#define CLK_ID_SHIFT 11
+#define CLK_ON_MASK 0x00000400
+#define CLK_ON_SHIFT 10
+#define CLK_DIV_MASK GENMASK_32(9, 4)
+#define CLK_DIV_SHIFT 4
+#define CLK_SEL_MASK GENMASK_32(3, 0)
+#define CLK_SEL_SHIFT 0
+
+#define DIV_PLL1DIVP 0
+#define DIV_PLL2DIVP 1
+#define DIV_PLL2DIVQ 2
+#define DIV_PLL2DIVR 3
+#define DIV_PLL3DIVP 4
+#define DIV_PLL3DIVQ 5
+#define DIV_PLL3DIVR 6
+#define DIV_PLL4DIVP 7
+#define DIV_PLL4DIVQ 8
+#define DIV_PLL4DIVR 9
+#define DIV_MPU 10
+#define DIV_AXI 11
+#define DIV_MLAHB 12
+#define DIV_APB1 13
+#define DIV_APB2 14
+#define DIV_APB3 15
+#define DIV_APB4 16
+#define DIV_APB5 17
+#define DIV_APB6 18
+#define DIV_RTC 19
+#define DIV_MCO1 20
+#define DIV_MCO2 21
+#define DIV_HSI 22
+#define DIV_TRACE 23
+#define DIV_ETH1PTP 24
+#define DIV_ETH2PTP 25
+#define DIV_MAX 26
+
+#define DIV(div_id, div) ((CMD_DIV << CMD_SHIFT) |\
+ ((div_id) << DIV_ID_SHIFT |\
+ (div)))
+
+#define CLKSRC(mux_id, sel) ((CMD_MUX << CMD_SHIFT) |\
+ ((mux_id) << MUX_ID_SHIFT |\
+ (sel)))
+
+/* MCO output is enable */
+#define MCO_SRC(mco_id, sel) ((CMD_CLK << CMD_SHIFT) |\
+ (((mco_id) << CLK_ID_SHIFT) |\
+ (sel)) | CLK_ON_MASK)
+
+#define MCO_DISABLED(mco_id) ((CMD_CLK << CMD_SHIFT) |\
+ ((mco_id) << CLK_ID_SHIFT))
+
+/* CLK output is enable */
+#define CLK_SRC(clk_id, sel) ((CMD_CLK << CMD_SHIFT) |\
+ (((clk_id) << CLK_ID_SHIFT) |\
+ (sel)) | CLK_ON_MASK)
+
+#define CLK_DISABLED(clk_id) ((CMD_CLK << CMD_SHIFT) |\
+ ((clk_id) << CLK_ID_SHIFT))
+
+#define MUX_MPU 0
+#define MUX_AXI 1
+#define MUX_MLAHB 2
+#define MUX_PLL12 3
+#define MUX_PLL3 4
+#define MUX_PLL4 5
+#define MUX_RTC 6
+#define MUX_MCO1 7
+#define MUX_MCO2 8
+#define MUX_CKPER 9
+#define MUX_KERNEL_BEGIN 10
+#define MUX_ADC1 10
+#define MUX_ADC2 11
+#define MUX_DCMIPP 12
+#define MUX_ETH1 13
+#define MUX_ETH2 14
+#define MUX_FDCAN 15
+#define MUX_FMC 16
+#define MUX_I2C12 17
+#define MUX_I2C3 18
+#define MUX_I2C4 19
+#define MUX_I2C5 20
+#define MUX_LPTIM1 21
+#define MUX_LPTIM2 22
+#define MUX_LPTIM3 23
+#define MUX_LPTIM45 24
+#define MUX_QSPI 25
+#define MUX_RNG1 26
+#define MUX_SAES 27
+#define MUX_SAI1 28
+#define MUX_SAI2 29
+#define MUX_SDMMC1 30
+#define MUX_SDMMC2 31
+#define MUX_SPDIF 32
+#define MUX_SPI1 33
+#define MUX_SPI23 34
+#define MUX_SPI4 35
+#define MUX_SPI5 36
+#define MUX_STGEN 37
+#define MUX_UART1 38
+#define MUX_UART2 39
+#define MUX_UART35 40
+#define MUX_UART4 41
+#define MUX_UART6 42
+#define MUX_UART78 43
+#define MUX_USBO 44
+#define MUX_USBPHY 45
+#define MUX_MAX 46
+
+#define CLK_MPU_HSI CLKSRC(MUX_MPU, 0)
+#define CLK_MPU_HSE CLKSRC(MUX_MPU, 1)
+#define CLK_MPU_PLL1P CLKSRC(MUX_MPU, 2)
+#define CLK_MPU_PLL1P_DIV CLKSRC(MUX_MPU, 3)
+
+#define CLK_AXI_HSI CLKSRC(MUX_AXI, 0)
+#define CLK_AXI_HSE CLKSRC(MUX_AXI, 1)
+#define CLK_AXI_PLL2P CLKSRC(MUX_AXI, 2)
+
+#define CLK_MLAHBS_HSI CLKSRC(MUX_MLAHB, 0)
+#define CLK_MLAHBS_HSE CLKSRC(MUX_MLAHB, 1)
+#define CLK_MLAHBS_CSI CLKSRC(MUX_MLAHB, 2)
+#define CLK_MLAHBS_PLL3 CLKSRC(MUX_MLAHB, 3)
+
+#define CLK_PLL12_HSI CLKSRC(MUX_PLL12, 0)
+#define CLK_PLL12_HSE CLKSRC(MUX_PLL12, 1)
+
+#define CLK_PLL3_HSI CLKSRC(MUX_PLL3, 0)
+#define CLK_PLL3_HSE CLKSRC(MUX_PLL3, 1)
+#define CLK_PLL3_CSI CLKSRC(MUX_PLL3, 2)
+
+#define CLK_PLL4_HSI CLKSRC(MUX_PLL4, 0)
+#define CLK_PLL4_HSE CLKSRC(MUX_PLL4, 1)
+#define CLK_PLL4_CSI CLKSRC(MUX_PLL4, 2)
+
+#define CLK_RTC_DISABLED CLK_DISABLED(RTC)
+#define CLK_RTC_LSE CLK_SRC(RTC, 1)
+#define CLK_RTC_LSI CLK_SRC(RTC, 2)
+#define CLK_RTC_HSE CLK_SRC(RTC, 3)
+
+#define CLK_MCO1_HSI CLK_SRC(CK_MCO1, 0)
+#define CLK_MCO1_HSE CLK_SRC(CK_MCO1, 1)
+#define CLK_MCO1_CSI CLK_SRC(CK_MCO1, 2)
+#define CLK_MCO1_LSI CLK_SRC(CK_MCO1, 3)
+#define CLK_MCO1_LSE CLK_SRC(CK_MCO1, 4)
+#define CLK_MCO1_DISABLED CLK_DISABLED(CK_MCO1)
+
+#define CLK_MCO2_MPU CLK_SRC(CK_MCO2, 0)
+#define CLK_MCO2_AXI CLK_SRC(CK_MCO2, 1)
+#define CLK_MCO2_MLAHB CLK_SRC(CK_MCO2, 2)
+#define CLK_MCO2_PLL4 CLK_SRC(CK_MCO2, 3)
+#define CLK_MCO2_HSE CLK_SRC(CK_MCO2, 4)
+#define CLK_MCO2_HSI CLK_SRC(CK_MCO2, 5)
+#define CLK_MCO2_DISABLED CLK_DISABLED(CK_MCO2)
+
+#define CLK_CKPER_HSI CLKSRC(MUX_CKPER, 0)
+#define CLK_CKPER_CSI CLKSRC(MUX_CKPER, 1)
+#define CLK_CKPER_HSE CLKSRC(MUX_CKPER, 2)
+#define CLK_CKPER_DISABLED CLKSRC(MUX_CKPER, 3)
+
+#define CLK_I2C12_PCLK1 CLKSRC(MUX_I2C12, 0)
+#define CLK_I2C12_PLL4R CLKSRC(MUX_I2C12, 1)
+#define CLK_I2C12_HSI CLKSRC(MUX_I2C12, 2)
+#define CLK_I2C12_CSI CLKSRC(MUX_I2C12, 3)
+
+#define CLK_I2C3_PCLK6 CLKSRC(MUX_I2C3, 0)
+#define CLK_I2C3_PLL4R CLKSRC(MUX_I2C3, 1)
+#define CLK_I2C3_HSI CLKSRC(MUX_I2C3, 2)
+#define CLK_I2C3_CSI CLKSRC(MUX_I2C3, 3)
+
+#define CLK_I2C4_PCLK6 CLKSRC(MUX_I2C4, 0)
+#define CLK_I2C4_PLL4R CLKSRC(MUX_I2C4, 1)
+#define CLK_I2C4_HSI CLKSRC(MUX_I2C4, 2)
+#define CLK_I2C4_CSI CLKSRC(MUX_I2C4, 3)
+
+#define CLK_I2C5_PCLK6 CLKSRC(MUX_I2C5, 0)
+#define CLK_I2C5_PLL4R CLKSRC(MUX_I2C5, 1)
+#define CLK_I2C5_HSI CLKSRC(MUX_I2C5, 2)
+#define CLK_I2C5_CSI CLKSRC(MUX_I2C5, 3)
+
+#define CLK_SPI1_PLL4P CLKSRC(MUX_SPI1, 0)
+#define CLK_SPI1_PLL3Q CLKSRC(MUX_SPI1, 1)
+#define CLK_SPI1_I2SCKIN CLKSRC(MUX_SPI1, 2)
+#define CLK_SPI1_CKPER CLKSRC(MUX_SPI1, 3)
+#define CLK_SPI1_PLL3R CLKSRC(MUX_SPI1, 4)
+
+#define CLK_SPI23_PLL4P CLKSRC(MUX_SPI23, 0)
+#define CLK_SPI23_PLL3Q CLKSRC(MUX_SPI23, 1)
+#define CLK_SPI23_I2SCKIN CLKSRC(MUX_SPI23, 2)
+#define CLK_SPI23_CKPER CLKSRC(MUX_SPI23, 3)
+#define CLK_SPI23_PLL3R CLKSRC(MUX_SPI23, 4)
+
+#define CLK_SPI4_PCLK6 CLKSRC(MUX_SPI4, 0)
+#define CLK_SPI4_PLL4Q CLKSRC(MUX_SPI4, 1)
+#define CLK_SPI4_HSI CLKSRC(MUX_SPI4, 2)
+#define CLK_SPI4_CSI CLKSRC(MUX_SPI4, 3)
+#define CLK_SPI4_HSE CLKSRC(MUX_SPI4, 4)
+#define CLK_SPI4_I2SCKIN CLKSRC(MUX_SPI4, 5)
+
+#define CLK_SPI5_PCLK6 CLKSRC(MUX_SPI5, 0)
+#define CLK_SPI5_PLL4Q CLKSRC(MUX_SPI5, 1)
+#define CLK_SPI5_HSI CLKSRC(MUX_SPI5, 2)
+#define CLK_SPI5_CSI CLKSRC(MUX_SPI5, 3)
+#define CLK_SPI5_HSE CLKSRC(MUX_SPI5, 4)
+
+#define CLK_UART1_PCLK6 CLKSRC(MUX_UART1, 0)
+#define CLK_UART1_PLL3Q CLKSRC(MUX_UART1, 1)
+#define CLK_UART1_HSI CLKSRC(MUX_UART1, 2)
+#define CLK_UART1_CSI CLKSRC(MUX_UART1, 3)
+#define CLK_UART1_PLL4Q CLKSRC(MUX_UART1, 4)
+#define CLK_UART1_HSE CLKSRC(MUX_UART1, 5)
+
+#define CLK_UART2_PCLK6 CLKSRC(MUX_UART2, 0)
+#define CLK_UART2_PLL3Q CLKSRC(MUX_UART2, 1)
+#define CLK_UART2_HSI CLKSRC(MUX_UART2, 2)
+#define CLK_UART2_CSI CLKSRC(MUX_UART2, 3)
+#define CLK_UART2_PLL4Q CLKSRC(MUX_UART2, 4)
+#define CLK_UART2_HSE CLKSRC(MUX_UART2, 5)
+
+#define CLK_UART35_PCLK1 CLKSRC(MUX_UART35, 0)
+#define CLK_UART35_PLL4Q CLKSRC(MUX_UART35, 1)
+#define CLK_UART35_HSI CLKSRC(MUX_UART35, 2)
+#define CLK_UART35_CSI CLKSRC(MUX_UART35, 3)
+#define CLK_UART35_HSE CLKSRC(MUX_UART35, 4)
+
+#define CLK_UART4_PCLK1 CLKSRC(MUX_UART4, 0)
+#define CLK_UART4_PLL4Q CLKSRC(MUX_UART4, 1)
+#define CLK_UART4_HSI CLKSRC(MUX_UART4, 2)
+#define CLK_UART4_CSI CLKSRC(MUX_UART4, 3)
+#define CLK_UART4_HSE CLKSRC(MUX_UART4, 4)
+
+#define CLK_UART6_PCLK2 CLKSRC(MUX_UART6, 0)
+#define CLK_UART6_PLL4Q CLKSRC(MUX_UART6, 1)
+#define CLK_UART6_HSI CLKSRC(MUX_UART6, 2)
+#define CLK_UART6_CSI CLKSRC(MUX_UART6, 3)
+#define CLK_UART6_HSE CLKSRC(MUX_UART6, 4)
+
+#define CLK_UART78_PCLK1 CLKSRC(MUX_UART78, 0)
+#define CLK_UART78_PLL4Q CLKSRC(MUX_UART78, 1)
+#define CLK_UART78_HSI CLKSRC(MUX_UART78, 2)
+#define CLK_UART78_CSI CLKSRC(MUX_UART78, 3)
+#define CLK_UART78_HSE CLKSRC(MUX_UART78, 4)
+
+#define CLK_LPTIM1_PCLK1 CLKSRC(MUX_LPTIM1, 0)
+#define CLK_LPTIM1_PLL4P CLKSRC(MUX_LPTIM1, 1)
+#define CLK_LPTIM1_PLL3Q CLKSRC(MUX_LPTIM1, 2)
+#define CLK_LPTIM1_LSE CLKSRC(MUX_LPTIM1, 3)
+#define CLK_LPTIM1_LSI CLKSRC(MUX_LPTIM1, 4)
+#define CLK_LPTIM1_CKPER CLKSRC(MUX_LPTIM1, 5)
+
+#define CLK_LPTIM2_PCLK3 CLKSRC(MUX_LPTIM2, 0)
+#define CLK_LPTIM2_PLL4Q CLKSRC(MUX_LPTIM2, 1)
+#define CLK_LPTIM2_CKPER CLKSRC(MUX_LPTIM2, 2)
+#define CLK_LPTIM2_LSE CLKSRC(MUX_LPTIM2, 3)
+#define CLK_LPTIM2_LSI CLKSRC(MUX_LPTIM2, 4)
+
+#define CLK_LPTIM3_PCLK3 CLKSRC(MUX_LPTIM3, 0)
+#define CLK_LPTIM3_PLL4Q CLKSRC(MUX_LPTIM3, 1)
+#define CLK_LPTIM3_CKPER CLKSRC(MUX_LPTIM3, 2)
+#define CLK_LPTIM3_LSE CLKSRC(MUX_LPTIM3, 3)
+#define CLK_LPTIM3_LSI CLKSRC(MUX_LPTIM3, 4)
+
+#define CLK_LPTIM45_PCLK3 CLKSRC(MUX_LPTIM45, 0)
+#define CLK_LPTIM45_PLL4P CLKSRC(MUX_LPTIM45, 1)
+#define CLK_LPTIM45_PLL3Q CLKSRC(MUX_LPTIM45, 2)
+#define CLK_LPTIM45_LSE CLKSRC(MUX_LPTIM45, 3)
+#define CLK_LPTIM45_LSI CLKSRC(MUX_LPTIM45, 4)
+#define CLK_LPTIM45_CKPER CLKSRC(MUX_LPTIM45, 5)
+
+#define CLK_SAI1_PLL4Q CLKSRC(MUX_SAI1, 0)
+#define CLK_SAI1_PLL3Q CLKSRC(MUX_SAI1, 1)
+#define CLK_SAI1_I2SCKIN CLKSRC(MUX_SAI1, 2)
+#define CLK_SAI1_CKPER CLKSRC(MUX_SAI1, 3)
+#define CLK_SAI1_PLL3R CLKSRC(MUX_SAI1, 4)
+
+#define CLK_SAI2_PLL4Q CLKSRC(MUX_SAI2, 0)
+#define CLK_SAI2_PLL3Q CLKSRC(MUX_SAI2, 1)
+#define CLK_SAI2_I2SCKIN CLKSRC(MUX_SAI2, 2)
+#define CLK_SAI2_CKPER CLKSRC(MUX_SAI2, 3)
+#define CLK_SAI2_SPDIF CLKSRC(MUX_SAI2, 4)
+#define CLK_SAI2_PLL3R CLKSRC(MUX_SAI2, 5)
+
+#define CLK_FDCAN_HSE CLKSRC(MUX_FDCAN, 0)
+#define CLK_FDCAN_PLL3Q CLKSRC(MUX_FDCAN, 1)
+#define CLK_FDCAN_PLL4Q CLKSRC(MUX_FDCAN, 2)
+#define CLK_FDCAN_PLL4R CLKSRC(MUX_FDCAN, 3)
+
+#define CLK_SPDIF_PLL4P CLKSRC(MUX_SPDIF, 0)
+#define CLK_SPDIF_PLL3Q CLKSRC(MUX_SPDIF, 1)
+#define CLK_SPDIF_HSI CLKSRC(MUX_SPDIF, 2)
+
+#define CLK_ADC1_PLL4R CLKSRC(MUX_ADC1, 0)
+#define CLK_ADC1_CKPER CLKSRC(MUX_ADC1, 1)
+#define CLK_ADC1_PLL3Q CLKSRC(MUX_ADC1, 2)
+
+#define CLK_ADC2_PLL4R CLKSRC(MUX_ADC2, 0)
+#define CLK_ADC2_CKPER CLKSRC(MUX_ADC2, 1)
+#define CLK_ADC2_PLL3Q CLKSRC(MUX_ADC2, 2)
+
+#define CLK_SDMMC1_HCLK6 CLKSRC(MUX_SDMMC1, 0)
+#define CLK_SDMMC1_PLL3R CLKSRC(MUX_SDMMC1, 1)
+#define CLK_SDMMC1_PLL4P CLKSRC(MUX_SDMMC1, 2)
+#define CLK_SDMMC1_HSI CLKSRC(MUX_SDMMC1, 3)
+
+#define CLK_SDMMC2_HCLK6 CLKSRC(MUX_SDMMC2, 0)
+#define CLK_SDMMC2_PLL3R CLKSRC(MUX_SDMMC2, 1)
+#define CLK_SDMMC2_PLL4P CLKSRC(MUX_SDMMC2, 2)
+#define CLK_SDMMC2_HSI CLKSRC(MUX_SDMMC2, 3)
+
+#define CLK_ETH1_PLL4P CLKSRC(MUX_ETH1, 0)
+#define CLK_ETH1_PLL3Q CLKSRC(MUX_ETH1, 1)
+
+#define CLK_ETH2_PLL4P CLKSRC(MUX_ETH2, 0)
+#define CLK_ETH2_PLL3Q CLKSRC(MUX_ETH2, 1)
+
+#define CLK_USBPHY_HSE CLKSRC(MUX_USBPHY, 0)
+#define CLK_USBPHY_PLL4R CLKSRC(MUX_USBPHY, 1)
+#define CLK_USBPHY_HSE_DIV2 CLKSRC(MUX_USBPHY, 2)
+
+#define CLK_USBO_PLL4R CLKSRC(MUX_USBO, 0)
+#define CLK_USBO_USBPHY CLKSRC(MUX_USBO, 1)
+
+#define CLK_QSPI_ACLK CLKSRC(MUX_QSPI, 0)
+#define CLK_QSPI_PLL3R CLKSRC(MUX_QSPI, 1)
+#define CLK_QSPI_PLL4P CLKSRC(MUX_QSPI, 2)
+#define CLK_QSPI_CKPER CLKSRC(MUX_QSPI, 3)
+
+#define CLK_FMC_ACLK CLKSRC(MUX_FMC, 0)
+#define CLK_FMC_PLL3R CLKSRC(MUX_FMC, 1)
+#define CLK_FMC_PLL4P CLKSRC(MUX_FMC, 2)
+#define CLK_FMC_CKPER CLKSRC(MUX_FMC, 3)
+
+#define CLK_RNG1_CSI CLKSRC(MUX_RNG1, 0)
+#define CLK_RNG1_PLL4R CLKSRC(MUX_RNG1, 1)
+/* WARNING: POSITION 2 OF RNG1 MUX IS RESERVED */
+#define CLK_RNG1_LSI CLKSRC(MUX_RNG1, 3)
+
+#define CLK_STGEN_HSI CLKSRC(MUX_STGEN, 0)
+#define CLK_STGEN_HSE CLKSRC(MUX_STGEN, 1)
+
+#define CLK_DCMIPP_ACLK CLKSRC(MUX_DCMIPP, 0)
+#define CLK_DCMIPP_PLL2Q CLKSRC(MUX_DCMIPP, 1)
+#define CLK_DCMIPP_PLL4P CLKSRC(MUX_DCMIPP, 2)
+#define CLK_DCMIPP_CKPER CLKSRC(MUX_DCMIPP, 3)
+
+#define CLK_SAES_AXI CLKSRC(MUX_SAES, 0)
+#define CLK_SAES_CKPER CLKSRC(MUX_SAES, 1)
+#define CLK_SAES_PLL4R CLKSRC(MUX_SAES, 2)
+#define CLK_SAES_LSI CLKSRC(MUX_SAES, 3)
+
+/* PLL output is enable when x=1, with x=p,q or r */
+#define PQR(p, q, r) (((p) & 1) | (((q) & 1) << 1) | (((r) & 1) << 2))
+
+/* define for st,pll /csg */
+#define SSCG_MODE_CENTER_SPREAD 0
+#define SSCG_MODE_DOWN_SPREAD 1
+
+/* define for st,drive */
+#define LSEDRV_LOWEST 0
+#define LSEDRV_MEDIUM_LOW 1
+#define LSEDRV_MEDIUM_HIGH 2
+#define LSEDRV_HIGHEST 3
+
+#endif /* _DT_BINDINGS_CLOCK_STM32MP13_CLKSRC_H_ */
diff --git a/include/dt-bindings/clock/stm32mp15-clks.h b/include/dt-bindings/clock/stm32mp15-clks.h
new file mode 100644
index 0000000..bef1368
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp15-clks.h
@@ -0,0 +1,278 @@
+/* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2018-2022 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32MP1_CLKS_H_
+#define _DT_BINDINGS_STM32MP1_CLKS_H_
+
+/* OSCILLATOR clocks */
+#define CK_HSE 0
+#define CK_CSI 1
+#define CK_LSI 2
+#define CK_LSE 3
+#define CK_HSI 4
+#define CK_HSE_DIV2 5
+
+/* Bus clocks */
+#define TIM2 6
+#define TIM3 7
+#define TIM4 8
+#define TIM5 9
+#define TIM6 10
+#define TIM7 11
+#define TIM12 12
+#define TIM13 13
+#define TIM14 14
+#define LPTIM1 15
+#define SPI2 16
+#define SPI3 17
+#define USART2 18
+#define USART3 19
+#define UART4 20
+#define UART5 21
+#define UART7 22
+#define UART8 23
+#define I2C1 24
+#define I2C2 25
+#define I2C3 26
+#define I2C5 27
+#define SPDIF 28
+#define CEC 29
+#define DAC12 30
+#define MDIO 31
+#define TIM1 32
+#define TIM8 33
+#define TIM15 34
+#define TIM16 35
+#define TIM17 36
+#define SPI1 37
+#define SPI4 38
+#define SPI5 39
+#define USART6 40
+#define SAI1 41
+#define SAI2 42
+#define SAI3 43
+#define DFSDM 44
+#define FDCAN 45
+#define LPTIM2 46
+#define LPTIM3 47
+#define LPTIM4 48
+#define LPTIM5 49
+#define SAI4 50
+#define SYSCFG 51
+#define VREF 52
+#define TMPSENS 53
+#define PMBCTRL 54
+#define HDP 55
+#define LTDC 56
+#define DSI 57
+#define IWDG2 58
+#define USBPHY 59
+#define STGENRO 60
+#define SPI6 61
+#define I2C4 62
+#define I2C6 63
+#define USART1 64
+#define RTCAPB 65
+#define TZC1 66
+#define TZPC 67
+#define IWDG1 68
+#define BSEC 69
+#define STGEN 70
+#define DMA1 71
+#define DMA2 72
+#define DMAMUX 73
+#define ADC12 74
+#define USBO 75
+#define SDMMC3 76
+#define DCMI 77
+#define CRYP2 78
+#define HASH2 79
+#define RNG2 80
+#define CRC2 81
+#define HSEM 82
+#define IPCC 83
+#define GPIOA 84
+#define GPIOB 85
+#define GPIOC 86
+#define GPIOD 87
+#define GPIOE 88
+#define GPIOF 89
+#define GPIOG 90
+#define GPIOH 91
+#define GPIOI 92
+#define GPIOJ 93
+#define GPIOK 94
+#define GPIOZ 95
+#define CRYP1 96
+#define HASH1 97
+#define RNG1 98
+#define BKPSRAM 99
+#define MDMA 100
+#define GPU 101
+#define ETHCK 102
+#define ETHTX 103
+#define ETHRX 104
+#define ETHMAC 105
+#define FMC 106
+#define QSPI 107
+#define SDMMC1 108
+#define SDMMC2 109
+#define CRC1 110
+#define USBH 111
+#define ETHSTP 112
+#define TZC2 113
+
+/* Kernel clocks */
+#define SDMMC1_K 118
+#define SDMMC2_K 119
+#define SDMMC3_K 120
+#define FMC_K 121
+#define QSPI_K 122
+#define ETHCK_K 123
+#define RNG1_K 124
+#define RNG2_K 125
+#define GPU_K 126
+#define USBPHY_K 127
+#define STGEN_K 128
+#define SPDIF_K 129
+#define SPI1_K 130
+#define SPI2_K 131
+#define SPI3_K 132
+#define SPI4_K 133
+#define SPI5_K 134
+#define SPI6_K 135
+#define CEC_K 136
+#define I2C1_K 137
+#define I2C2_K 138
+#define I2C3_K 139
+#define I2C4_K 140
+#define I2C5_K 141
+#define I2C6_K 142
+#define LPTIM1_K 143
+#define LPTIM2_K 144
+#define LPTIM3_K 145
+#define LPTIM4_K 146
+#define LPTIM5_K 147
+#define USART1_K 148
+#define USART2_K 149
+#define USART3_K 150
+#define UART4_K 151
+#define UART5_K 152
+#define USART6_K 153
+#define UART7_K 154
+#define UART8_K 155
+#define DFSDM_K 156
+#define FDCAN_K 157
+#define SAI1_K 158
+#define SAI2_K 159
+#define SAI3_K 160
+#define SAI4_K 161
+#define ADC12_K 162
+#define DSI_K 163
+#define DSI_PX 164
+#define ADFSDM_K 165
+#define USBO_K 166
+#define LTDC_PX 167
+#define DAC12_K 168
+#define ETHPTP_K 169
+
+/* PLL */
+#define PLL1 176
+#define PLL2 177
+#define PLL3 178
+#define PLL4 179
+
+/* ODF */
+#define PLL1_P 180
+#define PLL1_Q 181
+#define PLL1_R 182
+#define PLL2_P 183
+#define PLL2_Q 184
+#define PLL2_R 185
+#define PLL3_P 186
+#define PLL3_Q 187
+#define PLL3_R 188
+#define PLL4_P 189
+#define PLL4_Q 190
+#define PLL4_R 191
+
+/* AUX */
+#define RTC 192
+
+/* MCLK */
+#define CK_PER 193
+#define CK_MPU 194
+#define CK_AXI 195
+#define CK_MCU 196
+
+/* Time base */
+#define TIM2_K 197
+#define TIM3_K 198
+#define TIM4_K 199
+#define TIM5_K 200
+#define TIM6_K 201
+#define TIM7_K 202
+#define TIM12_K 203
+#define TIM13_K 204
+#define TIM14_K 205
+#define TIM1_K 206
+#define TIM8_K 207
+#define TIM15_K 208
+#define TIM16_K 209
+#define TIM17_K 210
+
+/* MCO clocks */
+#define CK_MCO1 211
+#define CK_MCO2 212
+
+/* TRACE & DEBUG clocks */
+#define CK_DBG 214
+#define CK_TRACE 215
+
+/* DDR */
+#define DDRC1 220
+#define DDRC1LP 221
+#define DDRC2 222
+#define DDRC2LP 223
+#define DDRPHYC 224
+#define DDRPHYCLP 225
+#define DDRCAPB 226
+#define DDRCAPBLP 227
+#define AXIDCG 228
+#define DDRPHYCAPB 229
+#define DDRPHYCAPBLP 230
+#define DDRPERFM 231
+
+#define STM32MP1_LAST_CLK 232
+
+/* SCMI clock identifiers */
+#define CK_SCMI0_HSE 0
+#define CK_SCMI0_HSI 1
+#define CK_SCMI0_CSI 2
+#define CK_SCMI0_LSE 3
+#define CK_SCMI0_LSI 4
+#define CK_SCMI0_PLL2_Q 5
+#define CK_SCMI0_PLL2_R 6
+#define CK_SCMI0_MPU 7
+#define CK_SCMI0_AXI 8
+#define CK_SCMI0_BSEC 9
+#define CK_SCMI0_CRYP1 10
+#define CK_SCMI0_GPIOZ 11
+#define CK_SCMI0_HASH1 12
+#define CK_SCMI0_I2C4 13
+#define CK_SCMI0_I2C6 14
+#define CK_SCMI0_IWDG1 15
+#define CK_SCMI0_RNG1 16
+#define CK_SCMI0_RTC 17
+#define CK_SCMI0_RTCAPB 18
+#define CK_SCMI0_SPI6 19
+#define CK_SCMI0_USART1 20
+
+#define CK_SCMI1_PLL3_Q 0
+#define CK_SCMI1_PLL3_R 1
+#define CK_SCMI1_MCU 2
+
+#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */
diff --git a/include/dt-bindings/clock/stm32mp15-clksrc.h b/include/dt-bindings/clock/stm32mp15-clksrc.h
new file mode 100644
index 0000000..3a3792d
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp15-clksrc.h
@@ -0,0 +1,282 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2017-2022, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_STM32MP15_CLKSRC_H_
+#define _DT_BINDINGS_CLOCK_STM32MP15_CLKSRC_H_
+
+/* PLL output is enable when x=1, with x=p,q or r */
+#define PQR(p, q, r) (((p) & 1) | (((q) & 1) << 1) | (((r) & 1) << 2))
+
+/* st,clksrc: mandatory clock source */
+#define CLK_MPU_HSI 0x00000200
+#define CLK_MPU_HSE 0x00000201
+#define CLK_MPU_PLL1P 0x00000202
+#define CLK_MPU_PLL1P_DIV 0x00000203
+
+#define CLK_AXI_HSI 0x00000240
+#define CLK_AXI_HSE 0x00000241
+#define CLK_AXI_PLL2P 0x00000242
+
+#define CLK_MCU_HSI 0x00000480
+#define CLK_MCU_HSE 0x00000481
+#define CLK_MCU_CSI 0x00000482
+#define CLK_MCU_PLL3P 0x00000483
+
+#define CLK_PLL12_HSI 0x00000280
+#define CLK_PLL12_HSE 0x00000281
+
+#define CLK_PLL3_HSI 0x00008200
+#define CLK_PLL3_HSE 0x00008201
+#define CLK_PLL3_CSI 0x00008202
+
+#define CLK_PLL4_HSI 0x00008240
+#define CLK_PLL4_HSE 0x00008241
+#define CLK_PLL4_CSI 0x00008242
+#define CLK_PLL4_I2SCKIN 0x00008243
+
+#define CLK_RTC_DISABLED 0x00001400
+#define CLK_RTC_LSE 0x00001401
+#define CLK_RTC_LSI 0x00001402
+#define CLK_RTC_HSE 0x00001403
+
+#define CLK_MCO1_HSI 0x00008000
+#define CLK_MCO1_HSE 0x00008001
+#define CLK_MCO1_CSI 0x00008002
+#define CLK_MCO1_LSI 0x00008003
+#define CLK_MCO1_LSE 0x00008004
+#define CLK_MCO1_DISABLED 0x0000800F
+
+#define CLK_MCO2_MPU 0x00008040
+#define CLK_MCO2_AXI 0x00008041
+#define CLK_MCO2_MCU 0x00008042
+#define CLK_MCO2_PLL4P 0x00008043
+#define CLK_MCO2_HSE 0x00008044
+#define CLK_MCO2_HSI 0x00008045
+#define CLK_MCO2_DISABLED 0x0000804F
+
+/* st,pkcs: peripheral kernel clock source */
+
+#define CLK_I2C12_PCLK1 0x00008C00
+#define CLK_I2C12_PLL4R 0x00008C01
+#define CLK_I2C12_HSI 0x00008C02
+#define CLK_I2C12_CSI 0x00008C03
+#define CLK_I2C12_DISABLED 0x00008C07
+
+#define CLK_I2C35_PCLK1 0x00008C40
+#define CLK_I2C35_PLL4R 0x00008C41
+#define CLK_I2C35_HSI 0x00008C42
+#define CLK_I2C35_CSI 0x00008C43
+#define CLK_I2C35_DISABLED 0x00008C47
+
+#define CLK_I2C46_PCLK5 0x00000C00
+#define CLK_I2C46_PLL3Q 0x00000C01
+#define CLK_I2C46_HSI 0x00000C02
+#define CLK_I2C46_CSI 0x00000C03
+#define CLK_I2C46_DISABLED 0x00000C07
+
+#define CLK_SAI1_PLL4Q 0x00008C80
+#define CLK_SAI1_PLL3Q 0x00008C81
+#define CLK_SAI1_I2SCKIN 0x00008C82
+#define CLK_SAI1_CKPER 0x00008C83
+#define CLK_SAI1_PLL3R 0x00008C84
+#define CLK_SAI1_DISABLED 0x00008C87
+
+#define CLK_SAI2_PLL4Q 0x00008CC0
+#define CLK_SAI2_PLL3Q 0x00008CC1
+#define CLK_SAI2_I2SCKIN 0x00008CC2
+#define CLK_SAI2_CKPER 0x00008CC3
+#define CLK_SAI2_SPDIF 0x00008CC4
+#define CLK_SAI2_PLL3R 0x00008CC5
+#define CLK_SAI2_DISABLED 0x00008CC7
+
+#define CLK_SAI3_PLL4Q 0x00008D00
+#define CLK_SAI3_PLL3Q 0x00008D01
+#define CLK_SAI3_I2SCKIN 0x00008D02
+#define CLK_SAI3_CKPER 0x00008D03
+#define CLK_SAI3_PLL3R 0x00008D04
+#define CLK_SAI3_DISABLED 0x00008D07
+
+#define CLK_SAI4_PLL4Q 0x00008D40
+#define CLK_SAI4_PLL3Q 0x00008D41
+#define CLK_SAI4_I2SCKIN 0x00008D42
+#define CLK_SAI4_CKPER 0x00008D43
+#define CLK_SAI4_PLL3R 0x00008D44
+#define CLK_SAI4_DISABLED 0x00008D47
+
+#define CLK_SPI2S1_PLL4P 0x00008D80
+#define CLK_SPI2S1_PLL3Q 0x00008D81
+#define CLK_SPI2S1_I2SCKIN 0x00008D82
+#define CLK_SPI2S1_CKPER 0x00008D83
+#define CLK_SPI2S1_PLL3R 0x00008D84
+#define CLK_SPI2S1_DISABLED 0x00008D87
+
+#define CLK_SPI2S23_PLL4P 0x00008DC0
+#define CLK_SPI2S23_PLL3Q 0x00008DC1
+#define CLK_SPI2S23_I2SCKIN 0x00008DC2
+#define CLK_SPI2S23_CKPER 0x00008DC3
+#define CLK_SPI2S23_PLL3R 0x00008DC4
+#define CLK_SPI2S23_DISABLED 0x00008DC7
+
+#define CLK_SPI45_PCLK2 0x00008E00
+#define CLK_SPI45_PLL4Q 0x00008E01
+#define CLK_SPI45_HSI 0x00008E02
+#define CLK_SPI45_CSI 0x00008E03
+#define CLK_SPI45_HSE 0x00008E04
+#define CLK_SPI45_DISABLED 0x00008E07
+
+#define CLK_SPI6_PCLK5 0x00000C40
+#define CLK_SPI6_PLL4Q 0x00000C41
+#define CLK_SPI6_HSI 0x00000C42
+#define CLK_SPI6_CSI 0x00000C43
+#define CLK_SPI6_HSE 0x00000C44
+#define CLK_SPI6_PLL3Q 0x00000C45
+#define CLK_SPI6_DISABLED 0x00000C47
+
+#define CLK_UART6_PCLK2 0x00008E40
+#define CLK_UART6_PLL4Q 0x00008E41
+#define CLK_UART6_HSI 0x00008E42
+#define CLK_UART6_CSI 0x00008E43
+#define CLK_UART6_HSE 0x00008E44
+#define CLK_UART6_DISABLED 0x00008E47
+
+#define CLK_UART24_PCLK1 0x00008E80
+#define CLK_UART24_PLL4Q 0x00008E81
+#define CLK_UART24_HSI 0x00008E82
+#define CLK_UART24_CSI 0x00008E83
+#define CLK_UART24_HSE 0x00008E84
+#define CLK_UART24_DISABLED 0x00008E87
+
+#define CLK_UART35_PCLK1 0x00008EC0
+#define CLK_UART35_PLL4Q 0x00008EC1
+#define CLK_UART35_HSI 0x00008EC2
+#define CLK_UART35_CSI 0x00008EC3
+#define CLK_UART35_HSE 0x00008EC4
+#define CLK_UART35_DISABLED 0x00008EC7
+
+#define CLK_UART78_PCLK1 0x00008F00
+#define CLK_UART78_PLL4Q 0x00008F01
+#define CLK_UART78_HSI 0x00008F02
+#define CLK_UART78_CSI 0x00008F03
+#define CLK_UART78_HSE 0x00008F04
+#define CLK_UART78_DISABLED 0x00008F07
+
+#define CLK_UART1_PCLK5 0x00000C80
+#define CLK_UART1_PLL3Q 0x00000C81
+#define CLK_UART1_HSI 0x00000C82
+#define CLK_UART1_CSI 0x00000C83
+#define CLK_UART1_PLL4Q 0x00000C84
+#define CLK_UART1_HSE 0x00000C85
+#define CLK_UART1_DISABLED 0x00000C87
+
+#define CLK_SDMMC12_HCLK6 0x00008F40
+#define CLK_SDMMC12_PLL3R 0x00008F41
+#define CLK_SDMMC12_PLL4P 0x00008F42
+#define CLK_SDMMC12_HSI 0x00008F43
+#define CLK_SDMMC12_DISABLED 0x00008F47
+
+#define CLK_SDMMC3_HCLK2 0x00008F80
+#define CLK_SDMMC3_PLL3R 0x00008F81
+#define CLK_SDMMC3_PLL4P 0x00008F82
+#define CLK_SDMMC3_HSI 0x00008F83
+#define CLK_SDMMC3_DISABLED 0x00008F87
+
+#define CLK_ETH_PLL4P 0x00008FC0
+#define CLK_ETH_PLL3Q 0x00008FC1
+#define CLK_ETH_DISABLED 0x00008FC3
+
+#define CLK_QSPI_ACLK 0x00009000
+#define CLK_QSPI_PLL3R 0x00009001
+#define CLK_QSPI_PLL4P 0x00009002
+#define CLK_QSPI_CKPER 0x00009003
+
+#define CLK_FMC_ACLK 0x00009040
+#define CLK_FMC_PLL3R 0x00009041
+#define CLK_FMC_PLL4P 0x00009042
+#define CLK_FMC_CKPER 0x00009043
+
+#define CLK_FDCAN_HSE 0x000090C0
+#define CLK_FDCAN_PLL3Q 0x000090C1
+#define CLK_FDCAN_PLL4Q 0x000090C2
+#define CLK_FDCAN_PLL4R 0x000090C3
+
+#define CLK_SPDIF_PLL4P 0x00009140
+#define CLK_SPDIF_PLL3Q 0x00009141
+#define CLK_SPDIF_HSI 0x00009142
+#define CLK_SPDIF_DISABLED 0x00009143
+
+#define CLK_CEC_LSE 0x00009180
+#define CLK_CEC_LSI 0x00009181
+#define CLK_CEC_CSI_DIV122 0x00009182
+#define CLK_CEC_DISABLED 0x00009183
+
+#define CLK_USBPHY_HSE 0x000091C0
+#define CLK_USBPHY_PLL4R 0x000091C1
+#define CLK_USBPHY_HSE_DIV2 0x000091C2
+#define CLK_USBPHY_DISABLED 0x000091C3
+
+#define CLK_USBO_PLL4R 0x800091C0
+#define CLK_USBO_USBPHY 0x800091C1
+
+#define CLK_RNG1_CSI 0x00000CC0
+#define CLK_RNG1_PLL4R 0x00000CC1
+#define CLK_RNG1_LSE 0x00000CC2
+#define CLK_RNG1_LSI 0x00000CC3
+
+#define CLK_RNG2_CSI 0x00009200
+#define CLK_RNG2_PLL4R 0x00009201
+#define CLK_RNG2_LSE 0x00009202
+#define CLK_RNG2_LSI 0x00009203
+
+#define CLK_CKPER_HSI 0x00000D00
+#define CLK_CKPER_CSI 0x00000D01
+#define CLK_CKPER_HSE 0x00000D02
+#define CLK_CKPER_DISABLED 0x00000D03
+
+#define CLK_STGEN_HSI 0x00000D40
+#define CLK_STGEN_HSE 0x00000D41
+#define CLK_STGEN_DISABLED 0x00000D43
+
+#define CLK_DSI_DSIPLL 0x00009240
+#define CLK_DSI_PLL4P 0x00009241
+
+#define CLK_ADC_PLL4R 0x00009280
+#define CLK_ADC_CKPER 0x00009281
+#define CLK_ADC_PLL3Q 0x00009282
+#define CLK_ADC_DISABLED 0x00009283
+
+#define CLK_LPTIM45_PCLK3 0x000092C0
+#define CLK_LPTIM45_PLL4P 0x000092C1
+#define CLK_LPTIM45_PLL3Q 0x000092C2
+#define CLK_LPTIM45_LSE 0x000092C3
+#define CLK_LPTIM45_LSI 0x000092C4
+#define CLK_LPTIM45_CKPER 0x000092C5
+#define CLK_LPTIM45_DISABLED 0x000092C7
+
+#define CLK_LPTIM23_PCLK3 0x00009300
+#define CLK_LPTIM23_PLL4Q 0x00009301
+#define CLK_LPTIM23_CKPER 0x00009302
+#define CLK_LPTIM23_LSE 0x00009303
+#define CLK_LPTIM23_LSI 0x00009304
+#define CLK_LPTIM23_DISABLED 0x00009307
+
+#define CLK_LPTIM1_PCLK1 0x00009340
+#define CLK_LPTIM1_PLL4P 0x00009341
+#define CLK_LPTIM1_PLL3Q 0x00009342
+#define CLK_LPTIM1_LSE 0x00009343
+#define CLK_LPTIM1_LSI 0x00009344
+#define CLK_LPTIM1_CKPER 0x00009345
+#define CLK_LPTIM1_DISABLED 0x00009347
+
+/* define for st,pll /csg */
+#define SSCG_MODE_CENTER_SPREAD 0
+#define SSCG_MODE_DOWN_SPREAD 1
+
+/* define for st,drive */
+#define LSEDRV_LOWEST 0
+#define LSEDRV_MEDIUM_LOW 1
+#define LSEDRV_MEDIUM_HIGH 2
+#define LSEDRV_HIGHEST 3
+
+#endif
diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h
index bc71924..d40b1a2 100644
--- a/include/dt-bindings/reset/stm32mp1-resets.h
+++ b/include/dt-bindings/reset/stm32mp1-resets.h
@@ -1,121 +1,11 @@
-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/*
- * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
- * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ * Copyright (C) 2020-2022, STMicroelectronics - All Rights Reserved
*/
-#ifndef _DT_BINDINGS_STM32MP1_RESET_H_
-#define _DT_BINDINGS_STM32MP1_RESET_H_
-
-#define LTDC_R 3072
-#define DSI_R 3076
-#define DDRPERFM_R 3080
-#define USBPHY_R 3088
-#define SPI6_R 3136
-#define I2C4_R 3138
-#define I2C6_R 3139
-#define USART1_R 3140
-#define STGEN_R 3156
-#define GPIOZ_R 3200
-#define CRYP1_R 3204
-#define HASH1_R 3205
-#define RNG1_R 3206
-#define AXIM_R 3216
-#define GPU_R 3269
-#define ETHMAC_R 3274
-#define FMC_R 3276
-#define QSPI_R 3278
-#define SDMMC1_R 3280
-#define SDMMC2_R 3281
-#define CRC1_R 3284
-#define USBH_R 3288
-#define MDMA_R 3328
-#define MCU_R 8225
-#define TIM2_R 19456
-#define TIM3_R 19457
-#define TIM4_R 19458
-#define TIM5_R 19459
-#define TIM6_R 19460
-#define TIM7_R 19461
-#define TIM12_R 16462
-#define TIM13_R 16463
-#define TIM14_R 16464
-#define LPTIM1_R 19465
-#define SPI2_R 19467
-#define SPI3_R 19468
-#define USART2_R 19470
-#define USART3_R 19471
-#define UART4_R 19472
-#define UART5_R 19473
-#define UART7_R 19474
-#define UART8_R 19475
-#define I2C1_R 19477
-#define I2C2_R 19478
-#define I2C3_R 19479
-#define I2C5_R 19480
-#define SPDIF_R 19482
-#define CEC_R 19483
-#define DAC12_R 19485
-#define MDIO_R 19847
-#define TIM1_R 19520
-#define TIM8_R 19521
-#define TIM15_R 19522
-#define TIM16_R 19523
-#define TIM17_R 19524
-#define SPI1_R 19528
-#define SPI4_R 19529
-#define SPI5_R 19530
-#define USART6_R 19533
-#define SAI1_R 19536
-#define SAI2_R 19537
-#define SAI3_R 19538
-#define DFSDM_R 19540
-#define FDCAN_R 19544
-#define LPTIM2_R 19584
-#define LPTIM3_R 19585
-#define LPTIM4_R 19586
-#define LPTIM5_R 19587
-#define SAI4_R 19592
-#define SYSCFG_R 19595
-#define VREF_R 19597
-#define TMPSENS_R 19600
-#define PMBCTRL_R 19601
-#define DMA1_R 19648
-#define DMA2_R 19649
-#define DMAMUX_R 19650
-#define ADC12_R 19653
-#define USBO_R 19656
-#define SDMMC3_R 19664
-#define CAMITF_R 19712
-#define CRYP2_R 19716
-#define HASH2_R 19717
-#define RNG2_R 19718
-#define CRC2_R 19719
-#define HSEM_R 19723
-#define MBOX_R 19724
-#define GPIOA_R 19776
-#define GPIOB_R 19777
-#define GPIOC_R 19778
-#define GPIOD_R 19779
-#define GPIOE_R 19780
-#define GPIOF_R 19781
-#define GPIOG_R 19782
-#define GPIOH_R 19783
-#define GPIOI_R 19784
-#define GPIOJ_R 19785
-#define GPIOK_R 19786
-
-/* SCMI reset domain identifiers */
-#define RST_SCMI0_SPI6 0
-#define RST_SCMI0_I2C4 1
-#define RST_SCMI0_I2C6 2
-#define RST_SCMI0_USART1 3
-#define RST_SCMI0_STGEN 4
-#define RST_SCMI0_GPIOZ 5
-#define RST_SCMI0_CRYP1 6
-#define RST_SCMI0_HASH1 7
-#define RST_SCMI0_RNG1 8
-#define RST_SCMI0_MDMA 9
-#define RST_SCMI0_MCU 10
-
-#endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */
+#if STM32MP13
+#include "stm32mp13-resets.h"
+#endif
+#if STM32MP15
+#include "stm32mp15-resets.h"
+#endif
diff --git a/include/dt-bindings/reset/stm32mp13-resets.h b/include/dt-bindings/reset/stm32mp13-resets.h
new file mode 100644
index 0000000..8a0f80e
--- /dev/null
+++ b/include/dt-bindings/reset/stm32mp13-resets.h
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32MP13_RESET_H_
+#define _DT_BINDINGS_STM32MP13_RESET_H_
+
+#define TIM2_R 13568
+#define TIM3_R 13569
+#define TIM4_R 13570
+#define TIM5_R 13571
+#define TIM6_R 13572
+#define TIM7_R 13573
+#define LPTIM1_R 13577
+#define SPI2_R 13579
+#define SPI3_R 13580
+#define USART3_R 13583
+#define UART4_R 13584
+#define UART5_R 13585
+#define UART7_R 13586
+#define UART8_R 13587
+#define I2C1_R 13589
+#define I2C2_R 13590
+#define SPDIF_R 13594
+#define TIM1_R 13632
+#define TIM8_R 13633
+#define SPI1_R 13640
+#define USART6_R 13645
+#define SAI1_R 13648
+#define SAI2_R 13649
+#define DFSDM_R 13652
+#define FDCAN_R 13656
+#define LPTIM2_R 13696
+#define LPTIM3_R 13697
+#define LPTIM4_R 13698
+#define LPTIM5_R 13699
+#define SYSCFG_R 13707
+#define VREF_R 13709
+#define DTS_R 13712
+#define PMBCTRL_R 13713
+#define LTDC_R 13760
+#define DCMIPP_R 13761
+#define DDRPERFM_R 13768
+#define USBPHY_R 13776
+#define STGEN_R 13844
+#define USART1_R 13888
+#define USART2_R 13889
+#define SPI4_R 13890
+#define SPI5_R 13891
+#define I2C3_R 13892
+#define I2C4_R 13893
+#define I2C5_R 13894
+#define TIM12_R 13895
+#define TIM13_R 13896
+#define TIM14_R 13897
+#define TIM15_R 13898
+#define TIM16_R 13899
+#define TIM17_R 13900
+#define DMA1_R 13952
+#define DMA2_R 13953
+#define DMAMUX1_R 13954
+#define DMA3_R 13955
+#define DMAMUX2_R 13956
+#define ADC1_R 13957
+#define ADC2_R 13958
+#define USBO_R 13960
+#define GPIOA_R 14080
+#define GPIOB_R 14081
+#define GPIOC_R 14082
+#define GPIOD_R 14083
+#define GPIOE_R 14084
+#define GPIOF_R 14085
+#define GPIOG_R 14086
+#define GPIOH_R 14087
+#define GPIOI_R 14088
+#define TSC_R 14095
+#define PKA_R 14146
+#define SAES_R 14147
+#define CRYP1_R 14148
+#define HASH1_R 14149
+#define RNG1_R 14150
+#define AXIMC_R 14160
+#define MDMA_R 14208
+#define MCE_R 14209
+#define ETH1MAC_R 14218
+#define FMC_R 14220
+#define QSPI_R 14222
+#define SDMMC1_R 14224
+#define SDMMC2_R 14225
+#define CRC1_R 14228
+#define USBH_R 14232
+#define ETH2MAC_R 14238
+
+#endif /* _DT_BINDINGS_STM32MP13_RESET_H_ */
diff --git a/include/dt-bindings/reset/stm32mp15-resets.h b/include/dt-bindings/reset/stm32mp15-resets.h
new file mode 100644
index 0000000..2b34864
--- /dev/null
+++ b/include/dt-bindings/reset/stm32mp15-resets.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2018-2022 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32MP15_RESET_H_
+#define _DT_BINDINGS_STM32MP15_RESET_H_
+
+#define MCU_HOLD_BOOT_R 2144
+#define LTDC_R 3072
+#define DSI_R 3076
+#define DDRPERFM_R 3080
+#define USBPHY_R 3088
+#define SPI6_R 3136
+#define I2C4_R 3138
+#define I2C6_R 3139
+#define USART1_R 3140
+#define STGEN_R 3156
+#define GPIOZ_R 3200
+#define CRYP1_R 3204
+#define HASH1_R 3205
+#define RNG1_R 3206
+#define AXIM_R 3216
+#define GPU_R 3269
+#define ETHMAC_R 3274
+#define FMC_R 3276
+#define QSPI_R 3278
+#define SDMMC1_R 3280
+#define SDMMC2_R 3281
+#define CRC1_R 3284
+#define USBH_R 3288
+#define MDMA_R 3328
+#define MCU_R 8225
+#define TIM2_R 19456
+#define TIM3_R 19457
+#define TIM4_R 19458
+#define TIM5_R 19459
+#define TIM6_R 19460
+#define TIM7_R 19461
+#define TIM12_R 16462
+#define TIM13_R 16463
+#define TIM14_R 16464
+#define LPTIM1_R 19465
+#define SPI2_R 19467
+#define SPI3_R 19468
+#define USART2_R 19470
+#define USART3_R 19471
+#define UART4_R 19472
+#define UART5_R 19473
+#define UART7_R 19474
+#define UART8_R 19475
+#define I2C1_R 19477
+#define I2C2_R 19478
+#define I2C3_R 19479
+#define I2C5_R 19480
+#define SPDIF_R 19482
+#define CEC_R 19483
+#define DAC12_R 19485
+#define MDIO_R 19847
+#define TIM1_R 19520
+#define TIM8_R 19521
+#define TIM15_R 19522
+#define TIM16_R 19523
+#define TIM17_R 19524
+#define SPI1_R 19528
+#define SPI4_R 19529
+#define SPI5_R 19530
+#define USART6_R 19533
+#define SAI1_R 19536
+#define SAI2_R 19537
+#define SAI3_R 19538
+#define DFSDM_R 19540
+#define FDCAN_R 19544
+#define LPTIM2_R 19584
+#define LPTIM3_R 19585
+#define LPTIM4_R 19586
+#define LPTIM5_R 19587
+#define SAI4_R 19592
+#define SYSCFG_R 19595
+#define VREF_R 19597
+#define TMPSENS_R 19600
+#define PMBCTRL_R 19601
+#define DMA1_R 19648
+#define DMA2_R 19649
+#define DMAMUX_R 19650
+#define ADC12_R 19653
+#define USBO_R 19656
+#define SDMMC3_R 19664
+#define CAMITF_R 19712
+#define CRYP2_R 19716
+#define HASH2_R 19717
+#define RNG2_R 19718
+#define CRC2_R 19719
+#define HSEM_R 19723
+#define MBOX_R 19724
+#define GPIOA_R 19776
+#define GPIOB_R 19777
+#define GPIOC_R 19778
+#define GPIOD_R 19779
+#define GPIOE_R 19780
+#define GPIOF_R 19781
+#define GPIOG_R 19782
+#define GPIOH_R 19783
+#define GPIOI_R 19784
+#define GPIOJ_R 19785
+#define GPIOK_R 19786
+
+/* SCMI reset domain identifiers */
+#define RST_SCMI0_SPI6 0
+#define RST_SCMI0_I2C4 1
+#define RST_SCMI0_I2C6 2
+#define RST_SCMI0_USART1 3
+#define RST_SCMI0_STGEN 4
+#define RST_SCMI0_GPIOZ 5
+#define RST_SCMI0_CRYP1 6
+#define RST_SCMI0_HASH1 7
+#define RST_SCMI0_RNG1 8
+#define RST_SCMI0_MDMA 9
+#define RST_SCMI0_MCU 10
+#define RST_SCMI0_MCU_HOLD_BOOT 11
+
+#endif /* _DT_BINDINGS_STM32MP15_RESET_H_ */
diff --git a/include/dt-bindings/soc/stm32mp13-tzc400.h b/include/dt-bindings/soc/stm32mp13-tzc400.h
new file mode 100644
index 0000000..1cb2326
--- /dev/null
+++ b/include/dt-bindings/soc/stm32mp13-tzc400.h
@@ -0,0 +1,35 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ *
+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef _DT_BINDINGS_STM32MP13_TZC400_H
+#define _DT_BINDINGS_STM32MP13_TZC400_H
+
+#include <drivers/arm/tzc_common.h>
+
+#define STM32MP1_TZC_A7_ID U(0)
+#define STM32MP1_TZC_LCD_ID U(3)
+#define STM32MP1_TZC_MDMA_ID U(5)
+#define STM32MP1_TZC_DMA_ID U(6)
+#define STM32MP1_TZC_USB_HOST_ID U(7)
+#define STM32MP1_TZC_USB_OTG_ID U(8)
+#define STM32MP1_TZC_SDMMC_ID U(9)
+#define STM32MP1_TZC_ETH_ID U(10)
+#define STM32MP1_TZC_DCMIPP_ID U(11)
+#define STM32MP1_TZC_DAP_ID U(15)
+
+#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \
+ (TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DCMIPP_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID))
+
+#endif /* _DT_BINDINGS_STM32MP13_TZC400_H */
diff --git a/include/export/common/bl_common_exp.h b/include/export/common/bl_common_exp.h
index 8f09017..2cc7c54 100644
--- a/include/export/common/bl_common_exp.h
+++ b/include/export/common/bl_common_exp.h
@@ -39,8 +39,8 @@
*****************************************************************************/
typedef struct image_info {
param_header_t h;
- uintptr_t image_base; /* physical address of base of image */
- uint32_t image_size; /* bytes read from image file */
+ uintptr_t image_base; /* physical address of base of image */
+ uint32_t image_size; /* bytes read from image file */
uint32_t image_max_size;
} image_info_t;
diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h
index 98544c0..98a0099 100644
--- a/include/export/common/tbbr/tbbr_img_def_exp.h
+++ b/include/export/common/tbbr/tbbr_img_def_exp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -104,7 +104,16 @@
/* Realm Monitor Manager (RMM) */
#define RMM_IMAGE_ID U(34)
+/* CCA Content Certificate ID */
+#define CCA_CONTENT_CERT_ID U(35)
+
+/* Core SWD Key Certificate ID */
+#define CORE_SWD_KEY_CERT_ID U(36)
+
+/* Platform Key Certificate ID */
+#define PLAT_KEY_CERT_ID U(37)
+
/* Max Images */
-#define MAX_IMAGE_IDS U(35)
+#define MAX_IMAGE_IDS U(38)
#endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */
diff --git a/include/lib/cpus/aarch64/a64fx.h b/include/lib/cpus/aarch64/a64fx.h
new file mode 100644
index 0000000..b7342b0
--- /dev/null
+++ b/include/lib/cpus/aarch64/a64fx.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022, Fujitsu Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef A64FX_H
+#define A64FX_H
+
+#include <lib/utils_def.h>
+
+/* A64FX midr for revision 0 */
+#define A64FX_MIDR U(0x461f0010)
+
+#endif /* A64FX_H */
diff --git a/include/lib/cpus/aarch64/cortex_a510.h b/include/lib/cpus/aarch64/cortex_a510.h
index 2b8db14..af38734 100644
--- a/include/lib/cpus/aarch64/cortex_a510.h
+++ b/include/lib/cpus/aarch64/cortex_a510.h
@@ -17,6 +17,8 @@
#define CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_DISABLE U(1)
#define CORTEX_A510_CPUECTLR_EL1_RSCTL_SHIFT U(23)
#define CORTEX_A510_CPUECTLR_EL1_NTCTL_SHIFT U(46)
+#define CORTEX_A510_CPUECTLR_EL1_ATOM_EXECALLINSTRNEAR U(2)
+#define CORTEX_A510_CPUECTLR_EL1_ATOM U(38)
/*******************************************************************************
* CPU Power Control register specific definitions
@@ -33,5 +35,6 @@
* Auxiliary control register specific definitions
******************************************************************************/
#define CORTEX_A510_CPUACTLR_EL1 S3_0_C15_C1_0
+#define CORTEX_A510_CPUACTLR_EL1_BIT_17 (ULL(1) << 17)
-#endif /* CORTEX_A510_H */
+#endif /* CORTEX_A510_H */
\ No newline at end of file
diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h
index 09614ee..e33b9d5 100644
--- a/include/lib/cpus/aarch64/cortex_a710.h
+++ b/include/lib/cpus/aarch64/cortex_a710.h
@@ -35,12 +35,14 @@
* CPU Auxiliary Control register 2 specific definitions.
******************************************************************************/
#define CORTEX_A710_CPUACTLR2_EL1 S3_0_C15_C1_1
+#define CORTEX_A710_CPUACTLR2_EL1_BIT_40 (ULL(1) << 40)
/*******************************************************************************
* CPU Auxiliary Control register 5 specific definitions.
******************************************************************************/
#define CORTEX_A710_CPUACTLR5_EL1 S3_0_C15_C8_0
#define CORTEX_A710_CPUACTLR5_EL1_BIT_13 (ULL(1) << 13)
+#define CORTEX_A710_CPUACTLR5_EL1_BIT_17 (ULL(1) << 17)
#define CORTEX_A710_CPUACTLR5_EL1_BIT_44 (ULL(1) << 44)
/*******************************************************************************
@@ -51,4 +53,12 @@
#define CPUECTLR2_EL1_PF_MODE_LSB U(11)
#define CPUECTLR2_EL1_PF_MODE_WIDTH U(4)
+/*******************************************************************************
+ * CPU Selected Instruction Private register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A710_CPUPSELR_EL3 S3_6_C15_C8_0
+#define CORTEX_A710_CPUPCR_EL3 S3_6_C15_C8_1
+#define CORTEX_A710_CPUPOR_EL3 S3_6_C15_C8_2
+#define CORTEX_A710_CPUPMR_EL3 S3_6_C15_C8_3
+
#endif /* CORTEX_A710_H */
diff --git a/include/lib/cpus/aarch64/cortex_a76ae.h b/include/lib/cpus/aarch64/cortex_a76ae.h
index 9e34efb..0d30f70 100644
--- a/include/lib/cpus/aarch64/cortex_a76ae.h
+++ b/include/lib/cpus/aarch64/cortex_a76ae.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,9 @@
/* Cortex-A76AE MIDR for revision 0 */
#define CORTEX_A76AE_MIDR U(0x410FD0E0)
+/* Cortex-A76 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A76AE_BHB_LOOP_COUNT U(24)
+
/*******************************************************************************
* CPU Extended Control register specific definitions.
******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h
index 4a87168..63f155f 100644
--- a/include/lib/cpus/aarch64/cortex_a77.h
+++ b/include/lib/cpus/aarch64/cortex_a77.h
@@ -32,6 +32,7 @@
******************************************************************************/
#define CORTEX_A77_ACTLR2_EL1 S3_0_C15_C1_1
#define CORTEX_A77_ACTLR2_EL1_BIT_2 (ULL(1) << 2)
+#define CORTEX_A77_ACTLR2_EL1_BIT_0 ULL(1)
#define CORTEX_A77_CPUPSELR_EL3 S3_6_C15_C8_0
#define CORTEX_A77_CPUPCR_EL3 S3_6_C15_C8_1
diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h
index f3cb39f..31da99e 100644
--- a/include/lib/cpus/aarch64/cortex_a78.h
+++ b/include/lib/cpus/aarch64/cortex_a78.h
@@ -35,8 +35,10 @@
#define CORTEX_A78_ACTLR_TAM_BIT (ULL(1) << 30)
#define CORTEX_A78_ACTLR2_EL1 S3_0_C15_C1_1
+#define CORTEX_A78_ACTLR2_EL1_BIT_0 (ULL(1) << 0)
#define CORTEX_A78_ACTLR2_EL1_BIT_1 (ULL(1) << 1)
#define CORTEX_A78_ACTLR2_EL1_BIT_2 (ULL(1) << 2)
+#define CORTEX_A78_ACTLR2_EL1_BIT_40 (ULL(1) << 40)
/*******************************************************************************
* CPU Activity Monitor Unit register specific definitions.
diff --git a/include/lib/cpus/aarch64/cortex_a78_ae.h b/include/lib/cpus/aarch64/cortex_a78_ae.h
index 0c8adcf..b68ec1e 100644
--- a/include/lib/cpus/aarch64/cortex_a78_ae.h
+++ b/include/lib/cpus/aarch64/cortex_a78_ae.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
- * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +10,10 @@
#include <cortex_a78.h>
-#define CORTEX_A78_AE_MIDR U(0x410FD420)
+#define CORTEX_A78_AE_MIDR U(0x410FD420)
+
+/* Cortex-A78AE loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A78_AE_BHB_LOOP_COUNT U(32)
/*******************************************************************************
* CPU Extended Control register specific definitions.
@@ -18,4 +21,11 @@
#define CORTEX_A78_AE_CPUECTLR_EL1 CORTEX_A78_CPUECTLR_EL1
#define CORTEX_A78_AE_CPUECTLR_EL1_BIT_8 CORTEX_A78_CPUECTLR_EL1_BIT_8
+/*******************************************************************************
+ * CPU Auxiliary Control register 2 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A78_AE_ACTLR2_EL1 CORTEX_A78_ACTLR2_EL1
+#define CORTEX_A78_AE_ACTLR2_EL1_BIT_0 CORTEX_A78_ACTLR2_EL1_BIT_0
+#define CORTEX_A78_AE_ACTLR2_EL1_BIT_40 CORTEX_A78_ACTLR2_EL1_BIT_40
+
#endif /* CORTEX_A78_AE_H */
diff --git a/include/lib/cpus/aarch64/cortex_a78c.h b/include/lib/cpus/aarch64/cortex_a78c.h
index adb13bc..35e543c 100644
--- a/include/lib/cpus/aarch64/cortex_a78c.h
+++ b/include/lib/cpus/aarch64/cortex_a78c.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,10 +10,22 @@
#define CORTEX_A78C_MIDR U(0x410FD4B1)
+/* Cortex-A76 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A78C_BHB_LOOP_COUNT U(32)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 2 specific definitions.
+ * ****************************************************************************/
+#define CORTEX_A78C_CPUACTLR2_EL1 S3_0_C15_C1_1
+#define CORTEX_A78C_CPUACTLR2_EL1_BIT_0 (ULL(1) << 0)
+#define CORTEX_A78C_CPUACTLR2_EL1_BIT_40 (ULL(1) << 40)
+
/*******************************************************************************
* CPU Extended Control register specific definitions.
******************************************************************************/
#define CORTEX_A78C_CPUECTLR_EL1 S3_0_C15_C1_4
+#define CORTEX_A78C_CPUECTLR_EL1_BIT_6 (ULL(1) << 6)
+#define CORTEX_A78C_CPUECTLR_EL1_BIT_7 (ULL(1) << 7)
/*******************************************************************************
* CPU Power Control register specific definitions
@@ -21,4 +33,12 @@
#define CORTEX_A78C_CPUPWRCTLR_EL1 S3_0_C15_C2_7
#define CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT U(1)
+/*******************************************************************************
+ * CPU Implementation Specific Selected Instruction registers
+ ******************************************************************************/
+#define CORTEX_A78C_IMP_CPUPSELR_EL3 S3_6_C15_C8_0
+#define CORTEX_A78C_IMP_CPUPCR_EL3 S3_6_C15_C8_1
+#define CORTEX_A78C_IMP_CPUPOR_EL3 S3_6_C15_C8_2
+#define CORTEX_A78C_IMP_CPUPMR_EL3 S3_6_C15_C8_3
+
#endif /* CORTEX_A78C_H */
diff --git a/include/lib/cpus/aarch64/cortex_hunter.h b/include/lib/cpus/aarch64/cortex_hunter.h
index 8b59fd9..24bd217 100644
--- a/include/lib/cpus/aarch64/cortex_hunter.h
+++ b/include/lib/cpus/aarch64/cortex_hunter.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,9 @@
#define CORTEX_HUNTER_MIDR U(0x410FD810)
+/* Cortex Hunter loop count for CVE-2022-23960 mitigation */
+#define CORTEX_HUNTER_BHB_LOOP_COUNT U(132)
+
/*******************************************************************************
* CPU Extended Control register specific definitions
******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_makalu.h b/include/lib/cpus/aarch64/cortex_makalu.h
index 4e0dc86..ee59657 100644
--- a/include/lib/cpus/aarch64/cortex_makalu.h
+++ b/include/lib/cpus/aarch64/cortex_makalu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,9 @@
#define CORTEX_MAKALU_MIDR U(0x410FD4D0)
+/* Cortex Makalu loop count for CVE-2022-23960 mitigation */
+#define CORTEX_MAKALU_BHB_LOOP_COUNT U(38)
+
/*******************************************************************************
* CPU Extended Control register specific definitions
******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_makalu_elp_arm.h b/include/lib/cpus/aarch64/cortex_makalu_elp_arm.h
index a0d788e..9ed5ee3 100644
--- a/include/lib/cpus/aarch64/cortex_makalu_elp_arm.h
+++ b/include/lib/cpus/aarch64/cortex_makalu_elp_arm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,9 @@
#define CORTEX_MAKALU_ELP_ARM_MIDR U(0x410FD4E0)
+/* Cortex Makalu ELP loop count for CVE-2022-23960 mitigation */
+#define CORTEX_MAKALU_ELP_ARM_BHB_LOOP_COUNT U(132)
+
/*******************************************************************************
* CPU Extended Control register specific definitions
******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_x1.h b/include/lib/cpus/aarch64/cortex_x1.h
new file mode 100644
index 0000000..e3661a8
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_x1.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_X1_H
+#define CORTEX_X1_H
+
+/* Cortex-X1 MIDR for r1p0 */
+#define CORTEX_X1_MIDR U(0x411fd440)
+
+/* Cortex-X1 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_X1_BHB_LOOP_COUNT U(32)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_X1_CPUECTLR_EL1 S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_X1_ACTLR2_EL1 S3_0_C15_C1_1
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X1_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CORTEX_X1_CORE_PWRDN_EN_MASK U(0x1)
+
+#endif /* CORTEX_X1_H */
diff --git a/include/lib/cpus/aarch64/cortex_x2.h b/include/lib/cpus/aarch64/cortex_x2.h
index 62530e2..863b8c8 100644
--- a/include/lib/cpus/aarch64/cortex_x2.h
+++ b/include/lib/cpus/aarch64/cortex_x2.h
@@ -34,6 +34,18 @@
#define CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
/*******************************************************************************
+ * CPU Auxiliary Control Register definitions
+ ******************************************************************************/
+#define CORTEX_X2_CPUACTLR_EL1 S3_0_C15_C1_0
+#define CORTEX_X2_CPUACTLR_EL1_BIT_22 (ULL(1) << 22)
+
+/*******************************************************************************
+ * CPU Auxiliary Control Register 2 definitions
+ ******************************************************************************/
+#define CORTEX_X2_CPUACTLR2_EL1 S3_0_C15_C1_1
+#define CORTEX_X2_CPUACTLR2_EL1_BIT_40 (ULL(1) << 40)
+
+/*******************************************************************************
* CPU Auxiliary Control Register 5 definitions
******************************************************************************/
#define CORTEX_X2_CPUACTLR5_EL1 S3_0_C15_C8_0
diff --git a/include/lib/cpus/aarch64/dsu_def.h b/include/lib/cpus/aarch64/dsu_def.h
index 0969acf..577de61 100644
--- a/include/lib/cpus/aarch64/dsu_def.h
+++ b/include/lib/cpus/aarch64/dsu_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,6 +32,7 @@
#define CLUSTERACTLR_EL1 S3_0_C15_C3_3
#define CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING (ULL(1) << 15)
+#define CLUSTERACTLR_EL1_DISABLE_SCLK_GATING (ULL(3) << 15)
/********************************************************************
* Masks applied for DSU errata workarounds
diff --git a/include/lib/cpus/aarch64/neoverse_demeter.h b/include/lib/cpus/aarch64/neoverse_demeter.h
index 230ed66..f1afae7 100644
--- a/include/lib/cpus/aarch64/neoverse_demeter.h
+++ b/include/lib/cpus/aarch64/neoverse_demeter.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,9 @@
#define NEOVERSE_DEMETER_MIDR U(0x410FD4F0)
+/* Neoverse Demeter loop count for CVE-2022-23960 mitigation */
+#define NEOVERSE_DEMETER_BHB_LOOP_COUNT U(132)
+
/*******************************************************************************
* CPU Extended Control register specific definitions
******************************************************************************/
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index 0452b39..3ff817c 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -37,7 +37,9 @@
* CPU Auxiliary Control register 2 specific definitions.
******************************************************************************/
#define NEOVERSE_N2_CPUACTLR2_EL1 S3_0_C15_C1_1
+#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_0 (ULL(1) << 0)
#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2)
+#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_40 (ULL(1) << 40)
/*******************************************************************************
* CPU Auxiliary Control register 5 specific definitions.
diff --git a/include/lib/cpus/aarch64/neoverse_poseidon.h b/include/lib/cpus/aarch64/neoverse_poseidon.h
index 0a8b1d1..798ecd1 100644
--- a/include/lib/cpus/aarch64/neoverse_poseidon.h
+++ b/include/lib/cpus/aarch64/neoverse_poseidon.h
@@ -10,6 +10,9 @@
#define NEOVERSE_POSEIDON_MIDR U(0x410FD830)
+/* Neoverse Poseidon loop count for CVE-2022-23960 mitigation */
+#define NEOVERSE_POSEIDON_BHB_LOOP_COUNT U(132)
+
/*******************************************************************************
* CPU Extended Control register specific definitions.
******************************************************************************/
diff --git a/include/lib/cpus/aarch64/neoverse_v1.h b/include/lib/cpus/aarch64/neoverse_v1.h
index a904c04..9c7e967 100644
--- a/include/lib/cpus/aarch64/neoverse_v1.h
+++ b/include/lib/cpus/aarch64/neoverse_v1.h
@@ -16,6 +16,10 @@
* CPU Extended Control register specific definitions.
******************************************************************************/
#define NEOVERSE_V1_CPUECTLR_EL1 S3_0_C15_C1_4
+#define NEOVERSE_V1_CPUPSELR_EL3 S3_6_C15_C8_0
+#define NEOVERSE_V1_CPUPOR_EL3 S3_6_C15_C8_2
+#define NEOVERSE_V1_CPUPMR_EL3 S3_6_C15_C8_3
+#define NEOVERSE_V1_CPUPCR_EL3 S3_6_C15_C8_1
#define NEOVERSE_V1_CPUECTLR_EL1_BIT_8 (ULL(1) << 8)
#define NEOVERSE_V1_CPUECTLR_EL1_BIT_53 (ULL(1) << 53)
#define NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV ULL(3)
@@ -32,7 +36,9 @@
* CPU Auxiliary Control register specific definitions.
******************************************************************************/
#define NEOVERSE_V1_ACTLR2_EL1 S3_0_C15_C1_1
+#define NEOVERSE_V1_ACTLR2_EL1_BIT_0 ULL(1)
#define NEOVERSE_V1_ACTLR2_EL1_BIT_2 (ULL(1) << 2)
#define NEOVERSE_V1_ACTLR2_EL1_BIT_28 (ULL(1) << 28)
+#define NEOVERSE_V1_ACTLR2_EL1_BIT_40 (ULL(1) << 40)
#endif /* NEOVERSE_V1_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 512d196..6c13166 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -217,23 +217,20 @@
// Starting with Armv8.4
#define CTX_CONTEXTIDR_EL2 U(0x198)
-#define CTX_SDER32_EL2 U(0x1a0)
-#define CTX_TTBR1_EL2 U(0x1a8)
-#define CTX_VDISR_EL2 U(0x1b0)
+#define CTX_TTBR1_EL2 U(0x1a0)
+#define CTX_VDISR_EL2 U(0x1a8)
+#define CTX_VSESR_EL2 U(0x1b0)
#define CTX_VNCR_EL2 U(0x1b8)
-#define CTX_VSESR_EL2 U(0x1c0)
-#define CTX_VSTCR_EL2 U(0x1c8)
-#define CTX_VSTTBR_EL2 U(0x1d0)
-#define CTX_TRFCR_EL2 U(0x1d8)
+#define CTX_TRFCR_EL2 U(0x1c0)
// Starting with Armv8.5
-#define CTX_SCXTNUM_EL2 U(0x1e0)
+#define CTX_SCXTNUM_EL2 U(0x1c8)
// Register for FEAT_HCX
-#define CTX_HCRX_EL2 U(0x1e8)
+#define CTX_HCRX_EL2 U(0x1d0)
/* Align to the next 16 byte boundary */
-#define CTX_EL2_SYSREGS_END U(0x1f0)
+#define CTX_EL2_SYSREGS_END U(0x1e0)
#endif /* CTX_INCLUDE_EL2_REGS */
@@ -512,9 +509,53 @@
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
+void el2_sysregs_context_save_common(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_common(el2_sysregs_t *regs);
+#if ENABLE_SPE_FOR_LOWER_ELS
+void el2_sysregs_context_save_spe(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_spe(el2_sysregs_t *regs);
+#endif /* ENABLE_SPE_FOR_LOWER_ELS */
+#if CTX_INCLUDE_MTE_REGS
+void el2_sysregs_context_save_mte(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_mte(el2_sysregs_t *regs);
+#endif /* CTX_INCLUDE_MTE_REGS */
+#if ENABLE_MPAM_FOR_LOWER_ELS
+void el2_sysregs_context_save_mpam(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_mpam(el2_sysregs_t *regs);
+#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
+#if ENABLE_FEAT_FGT
+void el2_sysregs_context_save_fgt(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_fgt(el2_sysregs_t *regs);
+#endif /* ENABLE_FEAT_FGT */
+#if ENABLE_FEAT_ECV
+void el2_sysregs_context_save_ecv(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_ecv(el2_sysregs_t *regs);
+#endif /* ENABLE_FEAT_ECV */
+#if ENABLE_FEAT_VHE
+void el2_sysregs_context_save_vhe(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_vhe(el2_sysregs_t *regs);
+#endif /* ENABLE_FEAT_VHE */
+#if RAS_EXTENSION
+void el2_sysregs_context_save_ras(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_ras(el2_sysregs_t *regs);
+#endif /* RAS_EXTENSION */
+#if CTX_INCLUDE_NEVE_REGS
+void el2_sysregs_context_save_nv2(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_nv2(el2_sysregs_t *regs);
+#endif /* CTX_INCLUDE_NEVE_REGS */
+#if ENABLE_TRF_FOR_NS
+void el2_sysregs_context_save_trf(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_trf(el2_sysregs_t *regs);
+#endif /* ENABLE_TRF_FOR_NS */
+#if ENABLE_FEAT_CSV2_2
+void el2_sysregs_context_save_csv2(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_csv2(el2_sysregs_t *regs);
+#endif /* ENABLE_FEAT_CSV2_2 */
+#if ENABLE_FEAT_HCX
+void el2_sysregs_context_save_hcx(el2_sysregs_t *regs);
+void el2_sysregs_context_restore_hcx(el2_sysregs_t *regs);
+#endif /* ENABLE_FEAT_HCX */
+#endif /* CTX_INCLUDE_EL2_REGS */
#if CTX_INCLUDE_FPREGS
void fpregs_context_save(fp_regs_t *regs);
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index 2090687..1a76d8e 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -34,6 +34,7 @@
const struct entry_point_info *ep);
void cm_setup_context(cpu_context_t *ctx, const struct entry_point_info *ep);
void cm_prepare_el3_exit(uint32_t security_state);
+void cm_prepare_el3_exit_ns(void);
#ifdef __aarch64__
#if CTX_INCLUDE_EL2_REGS
diff --git a/include/lib/extensions/brbe.h b/include/lib/extensions/brbe.h
new file mode 100644
index 0000000..aac1ace
--- /dev/null
+++ b/include/lib/extensions/brbe.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BRBE_H
+#define BRBE_H
+
+void brbe_enable(void);
+
+#endif /* BRBE_H */
diff --git a/include/lib/extensions/twed.h b/include/lib/extensions/twed.h
deleted file mode 100644
index eac4aa3..0000000
--- a/include/lib/extensions/twed.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TWED_H
-#define TWED_H
-
-#include <stdint.h>
-
-#define TWED_DISABLED U(0xFFFFFFFF)
-
-uint32_t plat_arm_set_twedel_scr_el3(void);
-
-#endif /* TWEDE_H */
diff --git a/include/lib/fconf/fconf_dyn_cfg_getter.h b/include/lib/fconf/fconf_dyn_cfg_getter.h
index ff51c6c..43f298e 100644
--- a/include/lib/fconf/fconf_dyn_cfg_getter.h
+++ b/include/lib/fconf/fconf_dyn_cfg_getter.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,6 +18,13 @@
uintptr_t config_addr;
uint32_t config_max_size;
unsigned int config_id;
+ /*
+ * Load address in non-secure memory. Only needed by those
+ * configuration files which require being loaded in secure
+ * memory (at config_addr) as well as in non-secure memory
+ * - e.g. HW_CONFIG
+ */
+ uintptr_t ns_config_addr;
};
unsigned int dyn_cfg_dtb_info_get_index(unsigned int config_id);
@@ -25,7 +32,8 @@
int fconf_populate_dtb_registry(uintptr_t config);
/* Set config information in global DTB array */
-void set_config_info(uintptr_t config_addr, uint32_t config_max_size,
- unsigned int config_id);
+void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+ uint32_t config_max_size,
+ unsigned int config_id);
#endif /* FCONF_DYN_CFG_GETTER_H */
diff --git a/include/lib/libc/cdefs.h b/include/lib/libc/cdefs.h
index 0d00722..423f0db 100644
--- a/include/lib/libc/cdefs.h
+++ b/include/lib/libc/cdefs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,7 @@
#define __packed __attribute__((__packed__))
#define __used __attribute__((__used__))
#define __unused __attribute__((__unused__))
+#define __maybe_unused __attribute__((__unused__))
#define __aligned(x) __attribute__((__aligned__(x)))
#define __section(x) __attribute__((__section__(x)))
#if RECLAIM_INIT_CODE
diff --git a/include/lib/psa/initial_attestation.h b/include/lib/psa/initial_attestation.h
new file mode 100644
index 0000000..93169f0
--- /dev/null
+++ b/include/lib/psa/initial_attestation.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_INITIAL_ATTESTATION_H
+#define PSA_INITIAL_ATTESTATION_H
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "psa/error.h"
+
+/*
+ * Initial attestation API version is: 1.0.0
+ */
+#define PSA_INITIAL_ATTEST_API_VERSION_MAJOR (1)
+#define PSA_INITIAL_ATTEST_API_VERSION_MINOR (0)
+
+/* The allowed size of input challenge in bytes. */
+#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32 32U
+#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48 48U
+#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 64U
+
+/* Initial Attestation message types that distinguish Attest services. */
+#define RSS_ATTEST_GET_TOKEN 1001U
+#define RSS_ATTEST_GET_TOKEN_SIZE 1002U
+#define RSS_ATTEST_GET_DELEGATED_KEY 1003U
+
+/**
+ * Get the platform attestation token.
+ *
+ * auth_challenge Pointer to buffer where challenge input is stored. This
+ * must be the hash of the public part of the delegated
+ * attestation key.
+ * challenge_size Size of challenge object in bytes.
+ * token_buf Pointer to the buffer where attestation token will be
+ * stored.
+ * token_buf_size Size of allocated buffer for token, in bytes.
+ * token_size Size of the token that has been returned, in bytes.
+ *
+ * Returns error code as specified in psa_status_t.
+ */
+psa_status_t
+psa_initial_attest_get_token(const uint8_t *auth_challenge,
+ size_t challenge_size,
+ uint8_t *token_buf,
+ size_t token_buf_size,
+ size_t *token_size);
+
+#endif /* PSA_INITIAL_ATTESTATION_H */
diff --git a/include/lib/psa/measured_boot.h b/include/lib/psa/measured_boot.h
new file mode 100644
index 0000000..bdb79d5
--- /dev/null
+++ b/include/lib/psa/measured_boot.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_MEASURED_BOOT_H
+#define PSA_MEASURED_BOOT_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "psa/error.h"
+
+/* Minimum measurement value size that can be requested to store */
+#define MEASUREMENT_VALUE_MIN_SIZE 32U
+/* Maximum measurement value size that can be requested to store */
+#define MEASUREMENT_VALUE_MAX_SIZE 64U
+/* Minimum signer id size that can be requested to store */
+#define SIGNER_ID_MIN_SIZE MEASUREMENT_VALUE_MIN_SIZE
+/* Maximum signer id size that can be requested to store */
+#define SIGNER_ID_MAX_SIZE MEASUREMENT_VALUE_MAX_SIZE
+/* The theoretical maximum image version is: "255.255.65535\0" */
+#define VERSION_MAX_SIZE 14U
+/* Example sw_type: "BL_2, BL_33, etc." */
+#define SW_TYPE_MAX_SIZE 20U
+#define NUM_OF_MEASUREMENT_SLOTS 32U
+
+
+/**
+ * Extends and stores a measurement to the requested slot.
+ *
+ * index Slot number in which measurement is to be stored
+ * signer_id Pointer to signer_id buffer.
+ * signer_id_size Size of the signer_id buffer in bytes.
+ * version Pointer to version buffer.
+ * version_size Size of the version buffer in bytes.
+ * measurement_algo Algorithm identifier used for measurement.
+ * sw_type Pointer to sw_type buffer.
+ * sw_type_size Size of the sw_type buffer in bytes.
+ * measurement_value Pointer to measurement_value buffer.
+ * measurement_value_size Size of the measurement_value buffer in bytes.
+ * lock_measurement Boolean flag requesting whether the measurement
+ * is to be locked.
+ *
+ * PSA_SUCCESS:
+ * - Success.
+ * PSA_ERROR_INVALID_ARGUMENT:
+ * - The size of any argument is invalid OR
+ * - Input Measurement value is NULL OR
+ * - Input Signer ID is NULL OR
+ * - Requested slot index is invalid.
+ * PSA_ERROR_BAD_STATE:
+ * - Request to lock, when slot is already locked.
+ * PSA_ERROR_NOT_PERMITTED:
+ * - When the requested slot is not accessible to the caller.
+ */
+
+/* Not a standard PSA API, just an extension therefore use the 'rss_' prefix
+ * rather than the usual 'psa_'.
+ */
+psa_status_t
+rss_measured_boot_extend_measurement(uint8_t index,
+ const uint8_t *signer_id,
+ size_t signer_id_size,
+ const uint8_t *version,
+ size_t version_size,
+ uint32_t measurement_algo,
+ const uint8_t *sw_type,
+ size_t sw_type_size,
+ const uint8_t *measurement_value,
+ size_t measurement_value_size,
+ bool lock_measurement);
+
+#endif /* PSA_MEASURED_BOOT_H */
diff --git a/include/lib/psa/psa/client.h b/include/lib/psa/psa/client.h
new file mode 100644
index 0000000..56fe028
--- /dev/null
+++ b/include/lib/psa/psa/client.h
@@ -0,0 +1,102 @@
+
+/*
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_CLIENT_H
+#define PSA_CLIENT_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <psa/error.h>
+
+#ifndef IOVEC_LEN
+#define IOVEC_LEN(arr) ((uint32_t)(sizeof(arr)/sizeof(arr[0])))
+#endif
+/*********************** PSA Client Macros and Types *************************/
+/**
+ * The version of the PSA Framework API that is being used to build the calling
+ * firmware. Only part of features of FF-M v1.1 have been implemented. FF-M v1.1
+ * is compatible with v1.0.
+ */
+#define PSA_FRAMEWORK_VERSION (0x0101u)
+/**
+ * Return value from psa_version() if the requested RoT Service is not present
+ * in the system.
+ */
+#define PSA_VERSION_NONE (0u)
+/**
+ * The zero-value null handle can be assigned to variables used in clients and
+ * RoT Services, indicating that there is no current connection or message.
+ */
+#define PSA_NULL_HANDLE ((psa_handle_t)0)
+/**
+ * Tests whether a handle value returned by psa_connect() is valid.
+ */
+#define PSA_HANDLE_IS_VALID(handle) ((psa_handle_t)(handle) > 0)
+/**
+ * Converts the handle value returned from a failed call psa_connect() into
+ * an error code.
+ */
+#define PSA_HANDLE_TO_ERROR(handle) ((psa_status_t)(handle))
+/**
+ * Maximum number of input and output vectors for a request to psa_call().
+ */
+#define PSA_MAX_IOVEC (4u)
+/**
+ * An IPC message type that indicates a generic client request.
+ */
+#define PSA_IPC_CALL (0)
+typedef int32_t psa_handle_t;
+/**
+ * A read-only input memory region provided to an RoT Service.
+ */
+typedef struct psa_invec {
+ const void *base; /*!< the start address of the memory buffer */
+ size_t len; /*!< the size in bytes */
+} psa_invec;
+/**
+ * A writable output memory region provided to an RoT Service.
+ */
+typedef struct psa_outvec {
+ void *base; /*!< the start address of the memory buffer */
+ size_t len; /*!< the size in bytes */
+} psa_outvec;
+
+/**
+ * Call an RoT Service on an established connection.
+ *
+ * handle A handle to an established connection.
+ * type The request type. Must be zero(PSA_IPC_CALL) or positive.
+ * in_vec Array of input psa_invec structures.
+ * in_len Number of input psa_invec structures.
+ * out_vec Array of output psa_outvec structures.
+ * out_len Number of output psa_outvec structures.
+ *
+ * Return value >=0 RoT Service-specific status value.
+ * Return value <0 RoT Service-specific error code.
+ *
+ * PSA_ERROR_PROGRAMMER_ERROR:
+ * - The connection has been terminated by the RoT Service.
+ *
+ * The call is a PROGRAMMER ERROR if one or more of the following are true:
+ * - An invalid handle was passed.
+ * - The connection is already handling a request.
+ * - type < 0.
+ * - An invalid memory reference was provided.
+ * - in_len + out_len > PSA_MAX_IOVEC.
+ * - The message is unrecognized by the RoT.
+ * - Service or incorrectly formatted.
+ */
+psa_status_t psa_call(psa_handle_t handle,
+ int32_t type,
+ const psa_invec *in_vec,
+ size_t in_len,
+ psa_outvec *out_vec,
+ size_t out_len);
+
+#endif /* PSA_CLIENT_H */
diff --git a/include/lib/psa/psa/error.h b/include/lib/psa/psa/error.h
new file mode 100644
index 0000000..8a6eb7b
--- /dev/null
+++ b/include/lib/psa/psa/error.h
@@ -0,0 +1,42 @@
+
+/*
+ * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_ERROR_H
+#define PSA_ERROR_H
+
+#include <stdint.h>
+
+typedef int32_t psa_status_t;
+
+#define PSA_SUCCESS ((psa_status_t)0)
+#define PSA_SUCCESS_REBOOT ((psa_status_t)1)
+#define PSA_SUCCESS_RESTART ((psa_status_t)2)
+#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t)-129)
+#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t)-130)
+#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t)-131)
+#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132)
+#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133)
+#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134)
+#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135)
+#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
+#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
+#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138)
+#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139)
+#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140)
+#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141)
+#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142)
+#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
+#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t)-144)
+#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145)
+#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146)
+#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147)
+#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149)
+#define PSA_ERROR_DEPENDENCY_NEEDED ((psa_status_t)-156)
+#define PSA_ERROR_CURRENTLY_INSTALLING ((psa_status_t)-157)
+
+#endif /* PSA_ERROR_H */
diff --git a/include/lib/psa/psa_manifest/sid.h b/include/lib/psa/psa_manifest/sid.h
new file mode 100644
index 0000000..580a4cf
--- /dev/null
+++ b/include/lib/psa/psa_manifest/sid.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_MANIFEST_SID_H
+#define PSA_MANIFEST_SID_H
+
+/******** PSA_SP_INITIAL_ATTESTATION ********/
+#define RSS_ATTESTATION_SERVICE_HANDLE (0x40000103U)
+
+/******** PSA_SP_MEASURED_BOOT ********/
+#define RSS_MEASURED_BOOT_HANDLE (0x40000110U)
+
+#endif /* PSA_MANIFEST_SID_H */
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index 1ac45ad..43e2f96 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -91,6 +91,8 @@
entry_point_info_t *next_image_info);
int psci_stop_other_cores(unsigned int wait_ms,
void (*stop_func)(u_register_t mpidr));
+bool psci_is_last_on_cpu_safe(void);
+
#endif /* __ASSEMBLER__ */
#endif /* PSCI_LIB_H */
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 7a7012d..198b890 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -104,6 +104,13 @@
#define round_down(value, boundary) \
((value) & ~round_boundary(value, boundary))
+/**
+ * Helper macro to ensure a value lies on a given boundary.
+ */
+#define is_aligned(value, boundary) \
+ (round_up((uintptr_t) value, boundary) == \
+ round_down((uintptr_t) value, boundary))
+
/*
* Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
* Both arguments must be unsigned pointer values (i.e. uintptr_t).
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 2af8c11..ab0e4ff 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -79,6 +79,7 @@
* - SCP TZC DRAM: If present, DRAM reserved for SCP use
* - L1 GPT DRAM: Reserved for L1 GPT if RME is enabled
* - REALM DRAM: Reserved for Realm world if RME is enabled
+ * - TF-A <-> RMM SHARED: Area shared for communication between TF-A and RMM
* - AP TZC DRAM: The remaining TZC secured DRAM reserved for AP use
*
* RME enabled(64MB) RME not enabled(16MB)
@@ -87,11 +88,16 @@
* | AP TZC (~28MB) | | AP TZC (~14MB) |
* -------------------- -------------------
* | | | |
- * | REALM (32MB) | | EL3 TZC (2MB) |
- * -------------------- -------------------
- * | | | |
- * | EL3 TZC (3MB) | | SCP TZC |
- * -------------------- 0xFFFF_FFFF-------------------
+ * | REALM (RMM) | | EL3 TZC (2MB) |
+ * | (32MB - 4KB) | -------------------
+ * -------------------- | |
+ * | | | SCP TZC |
+ * | TF-A <-> RMM | 0xFFFF_FFFF-------------------
+ * | SHARED (4KB) |
+ * --------------------
+ * | |
+ * | EL3 TZC (3MB) |
+ * --------------------
* | L1 GPT + SCP TZC |
* | (~1MB) |
* 0xFFFF_FFFF --------------------
@@ -106,12 +112,17 @@
*/
#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00300000) /* 3MB */
#define ARM_L1_GPT_SIZE UL(0x00100000) /* 1MB */
-#define ARM_REALM_SIZE UL(0x02000000) /* 32MB */
+
+/* 32MB - ARM_EL3_RMM_SHARED_SIZE */
+#define ARM_REALM_SIZE (UL(0x02000000) - \
+ ARM_EL3_RMM_SHARED_SIZE)
+#define ARM_EL3_RMM_SHARED_SIZE (PAGE_SIZE) /* 4KB */
#else
#define ARM_TZC_DRAM1_SIZE UL(0x01000000) /* 16MB */
#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00200000) /* 2MB */
#define ARM_L1_GPT_SIZE UL(0)
#define ARM_REALM_SIZE UL(0)
+#define ARM_EL3_RMM_SHARED_SIZE UL(0)
#endif /* ENABLE_RME */
#define ARM_SCP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \
@@ -128,13 +139,20 @@
#define ARM_L1_GPT_END (ARM_L1_GPT_ADDR_BASE + \
ARM_L1_GPT_SIZE - 1U)
-#define ARM_REALM_BASE (ARM_DRAM1_BASE + \
- ARM_DRAM1_SIZE - \
- (ARM_SCP_TZC_DRAM1_SIZE + \
- ARM_EL3_TZC_DRAM1_SIZE + \
- ARM_REALM_SIZE + \
- ARM_L1_GPT_SIZE))
+#define ARM_REALM_BASE (ARM_EL3_RMM_SHARED_BASE - \
+ ARM_REALM_SIZE)
+
#define ARM_REALM_END (ARM_REALM_BASE + ARM_REALM_SIZE - 1U)
+
+#define ARM_EL3_RMM_SHARED_BASE (ARM_DRAM1_BASE + \
+ ARM_DRAM1_SIZE - \
+ (ARM_SCP_TZC_DRAM1_SIZE + \
+ ARM_L1_GPT_SIZE + \
+ ARM_EL3_RMM_SHARED_SIZE + \
+ ARM_EL3_TZC_DRAM1_SIZE))
+
+#define ARM_EL3_RMM_SHARED_END (ARM_EL3_RMM_SHARED_BASE + \
+ ARM_EL3_RMM_SHARED_SIZE - 1U)
#endif /* ENABLE_RME */
#define ARM_EL3_TZC_DRAM1_BASE (ARM_SCP_TZC_DRAM1_BASE - \
@@ -148,6 +166,7 @@
#define ARM_AP_TZC_DRAM1_SIZE (ARM_TZC_DRAM1_SIZE - \
(ARM_SCP_TZC_DRAM1_SIZE + \
ARM_EL3_TZC_DRAM1_SIZE + \
+ ARM_EL3_RMM_SHARED_SIZE + \
ARM_REALM_SIZE + \
ARM_L1_GPT_SIZE))
#define ARM_AP_TZC_DRAM1_END (ARM_AP_TZC_DRAM1_BASE + \
@@ -197,6 +216,7 @@
#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE
#define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \
ARM_TZC_DRAM1_SIZE)
+
#define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \
ARM_NS_DRAM1_SIZE - 1U)
#ifdef PLAT_ARM_DRAM1_BASE
@@ -284,17 +304,20 @@
ARM_EL3_TZC_DRAM1_SIZE, \
MT_MEMORY | MT_RW | EL3_PAS)
-#if defined(SPD_spmd)
#define ARM_MAP_TRUSTED_DRAM MAP_REGION_FLAT( \
PLAT_ARM_TRUSTED_DRAM_BASE, \
PLAT_ARM_TRUSTED_DRAM_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
-#endif
#if ENABLE_RME
+/*
+ * We add the EL3_RMM_SHARED size to RMM mapping to map the region as a block.
+ * Else we end up requiring more pagetables in BL2 for ROMLIB build.
+ */
#define ARM_MAP_RMM_DRAM MAP_REGION_FLAT( \
PLAT_ARM_RMM_BASE, \
- PLAT_ARM_RMM_SIZE, \
+ (PLAT_ARM_RMM_SIZE + \
+ ARM_EL3_RMM_SHARED_SIZE), \
MT_MEMORY | MT_RW | MT_REALM)
@@ -303,6 +326,12 @@
ARM_L1_GPT_SIZE, \
MT_MEMORY | MT_RW | EL3_PAS)
+#define ARM_MAP_EL3_RMM_SHARED_MEM \
+ MAP_REGION_FLAT( \
+ ARM_EL3_RMM_SHARED_BASE, \
+ ARM_EL3_RMM_SHARED_SIZE, \
+ MT_MEMORY | MT_RW | MT_REALM)
+
#endif /* ENABLE_RME */
/*
@@ -522,9 +551,20 @@
* BL2 specific defines.
******************************************************************************/
#if BL2_AT_EL3
+#if ENABLE_PIE
+/*
+ * As the BL31 image size appears to be increased when built with the ENABLE_PIE
+ * option, set BL2 base address to have enough space for BL31 in Trusted SRAM.
+ */
+#define BL2_BASE (ARM_TRUSTED_SRAM_BASE + \
+ (PLAT_ARM_TRUSTED_SRAM_SIZE >> 1) + \
+ 0x3000)
+#else
/* Put BL2 towards the middle of the Trusted SRAM */
#define BL2_BASE (ARM_TRUSTED_SRAM_BASE + \
- (PLAT_ARM_TRUSTED_SRAM_SIZE >> 1) + 0x2000)
+ (PLAT_ARM_TRUSTED_SRAM_SIZE >> 1) + \
+ 0x2000)
+#endif /* ENABLE_PIE */
#define BL2_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
#else
@@ -586,6 +626,8 @@
#if ENABLE_RME
#define RMM_BASE (ARM_REALM_BASE)
#define RMM_LIMIT (RMM_BASE + ARM_REALM_SIZE)
+#define RMM_SHARED_BASE (ARM_EL3_RMM_SHARED_BASE)
+#define RMM_SHARED_SIZE (ARM_EL3_RMM_SHARED_SIZE)
#endif
#if !defined(__aarch64__) || JUNO_AARCH32_EL3_RUNTIME
@@ -620,7 +662,7 @@
* Trusted DRAM (if available) or the DRAM region secured by the TrustZone
* controller.
*/
-# if SPM_MM
+# if SPM_MM || SPMC_AT_EL3
# define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
# define TSP_SEC_MEM_SIZE (ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
# define BL32_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
@@ -666,12 +708,13 @@
/*
* BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is no
- * SPD and no SPM-MM, as they are the only ones that can be used as BL32.
+ * SPD and no SPM-MM and no SPMC-AT-EL3, as they are the only ones that can be
+ * used as BL32.
*/
#if defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME
-# if defined(SPD_none) && !SPM_MM
+# if defined(SPD_none) && !SPM_MM && !SPMC_AT_EL3
# undef BL32_BASE
-# endif /* defined(SPD_none) && !SPM_MM */
+# endif /* defined(SPD_none) && !SPM_MM || !SPMC_AT_EL3 */
#endif /* defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME */
/*******************************************************************************
diff --git a/include/plat/arm/common/arm_pas_def.h b/include/plat/arm/common/arm_pas_def.h
index 4fee41b..c199302 100644
--- a/include/plat/arm/common/arm_pas_def.h
+++ b/include/plat/arm/common/arm_pas_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -61,6 +61,10 @@
#define ARM_PAS_2_BASE (ARM_PAS_1_BASE + ARM_PAS_1_SIZE)
#define ARM_PAS_2_SIZE (ARM_NS_DRAM1_SIZE)
+/* Shared area between EL3 and RMM */
+#define ARM_PAS_SHARED_BASE (ARM_EL3_RMM_SHARED_BASE)
+#define ARM_PAS_SHARED_SIZE (ARM_EL3_RMM_SHARED_SIZE)
+
/* Secure TZC region */
#define ARM_PAS_3_BASE (ARM_AP_TZC_DRAM1_BASE)
#define ARM_PAS_3_SIZE (ARM_AP_TZC_DRAM1_SIZE)
@@ -76,8 +80,13 @@
ARM_PAS_3_SIZE, \
GPT_GPI_SECURE)
+/*
+ * REALM and Shared area share the same PAS, so consider them a single
+ * PAS region to configure in GPT.
+ */
#define ARM_PAS_REALM GPT_MAP_REGION_GRANULE(ARM_REALM_BASE, \
- ARM_REALM_SIZE, \
+ (ARM_PAS_SHARED_SIZE + \
+ ARM_REALM_SIZE), \
GPT_GPI_REALM)
#define ARM_PAS_EL3_DRAM GPT_MAP_REGION_GRANULE(ARM_EL3_TZC_DRAM1_BASE, \
diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S
index 717f65e..788e9ff 100644
--- a/include/plat/arm/common/arm_reclaim_init.ld.S
+++ b/include/plat/arm/common/arm_reclaim_init.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +12,7 @@
. = . + PLATFORM_STACK_SIZE;
. = ALIGN(PAGE_SIZE);
__INIT_CODE_START__ = .;
- *(*text.init*);
+ *(*text.init.*);
__INIT_CODE_END__ = .;
INIT_CODE_END_ALIGNED = ALIGN(PAGE_SIZE);
} >RAM
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 9618700..d060332 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -57,7 +57,8 @@
{ARM_EL3_TZC_DRAM1_BASE, ARM_L1_GPT_END, TZC_REGION_S_RDWR, 0}, \
{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}, \
- {ARM_REALM_BASE, ARM_REALM_END, ARM_TZC_NS_DRAM_S_ACCESS, \
+ /* Realm and Shared area share the same PAS */ \
+ {ARM_REALM_BASE, ARM_EL3_RMM_SHARED_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}, \
{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 509fd58..184606a 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,9 @@
#if defined(SPD_spmd)
#include <services/spm_core_manifest.h>
#endif
+#if ENABLE_RME
+#include <services/rmm_core_manifest.h>
+#endif
#if TRNG_SUPPORT
#include "plat_trng.h"
#endif
@@ -303,6 +306,18 @@
unsigned int ncpu);
/*******************************************************************************
+ * Mandatory BL31 functions when ENABLE_RME=1
+ ******************************************************************************/
+#if ENABLE_RME
+int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
+ uintptr_t hash, size_t hash_size);
+int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
+ unsigned int type);
+size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
+int plat_rmmd_load_manifest(rmm_manifest_t *manifest);
+#endif
+
+/*******************************************************************************
* Optional BL31 functions (may be overridden)
******************************************************************************/
void bl31_plat_enable_mmu(uint32_t flags);
@@ -339,6 +354,10 @@
int plat_spm_core_manifest_load(spmc_manifest_attribute_t *manifest,
const void *pm_addr);
#endif
+#if defined(SPMC_AT_EL3)
+int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size);
+#endif
+
/*******************************************************************************
* Mandatory BL image load functions(may be overridden).
******************************************************************************/
diff --git a/include/services/el3_spmc_ffa_memory.h b/include/services/el3_spmc_ffa_memory.h
new file mode 100644
index 0000000..2037eca
--- /dev/null
+++ b/include/services/el3_spmc_ffa_memory.h
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EL3_SPMC_FFA_MEM_H
+#define EL3_SPMC_FFA_MEM_H
+
+#include <assert.h>
+
+/*
+ * Subset of Arm Firmware Framework for Armv8-A
+ * (https://developer.arm.com/docs/den0077/a) needed for shared memory.
+ */
+
+/**
+ * typedef ffa_endpoint_id16_t - Endpoint ID
+ *
+ * Current implementation only supports VM IDs. FF-A spec also support stream
+ * endpoint ids.
+ */
+typedef uint16_t ffa_endpoint_id16_t;
+
+/**
+ * struct ffa_cons_mrd - Constituent memory region descriptor
+ * @address:
+ * Start address of contiguous memory region. Must be 4K page aligned.
+ * @page_count:
+ * Number of 4K pages in region.
+ * @reserved_12_15:
+ * Reserve bytes 12-15 to pad struct size to 16 bytes.
+ */
+struct ffa_cons_mrd {
+ uint64_t address;
+ uint32_t page_count;
+ uint32_t reserved_12_15;
+};
+CASSERT(sizeof(struct ffa_cons_mrd) == 16, assert_ffa_cons_mrd_size_mismatch);
+
+/**
+ * struct ffa_comp_mrd - Composite memory region descriptor
+ * @total_page_count:
+ * Number of 4k pages in memory region. Must match sum of
+ * @address_range_array[].page_count.
+ * @address_range_count:
+ * Number of entries in @address_range_array.
+ * @reserved_8_15:
+ * Reserve bytes 8-15 to pad struct size to 16 byte alignment and
+ * make @address_range_array 16 byte aligned.
+ * @address_range_array:
+ * Array of &struct ffa_cons_mrd entries.
+ */
+struct ffa_comp_mrd {
+ uint32_t total_page_count;
+ uint32_t address_range_count;
+ uint64_t reserved_8_15;
+ struct ffa_cons_mrd address_range_array[];
+};
+CASSERT(sizeof(struct ffa_comp_mrd) == 16, assert_ffa_comp_mrd_size_mismatch);
+
+/**
+ * typedef ffa_mem_attr8_t - Memory region attributes v1.0.
+ * typedef ffa_mem_attr16_t - Memory region attributes v1.1.
+ *
+ * * @FFA_MEM_ATTR_NS_BIT:
+ * Memory security state.
+ * * @FFA_MEM_ATTR_DEVICE_NGNRNE:
+ * Device-nGnRnE.
+ * * @FFA_MEM_ATTR_DEVICE_NGNRE:
+ * Device-nGnRE.
+ * * @FFA_MEM_ATTR_DEVICE_NGRE:
+ * Device-nGRE.
+ * * @FFA_MEM_ATTR_DEVICE_GRE:
+ * Device-GRE.
+ * * @FFA_MEM_ATTR_NORMAL_MEMORY_UNCACHED
+ * Normal memory. Non-cacheable.
+ * * @FFA_MEM_ATTR_NORMAL_MEMORY_CACHED_WB
+ * Normal memory. Write-back cached.
+ * * @FFA_MEM_ATTR_NON_SHAREABLE
+ * Non-shareable. Combine with FFA_MEM_ATTR_NORMAL_MEMORY_*.
+ * * @FFA_MEM_ATTR_OUTER_SHAREABLE
+ * Outer Shareable. Combine with FFA_MEM_ATTR_NORMAL_MEMORY_*.
+ * * @FFA_MEM_ATTR_INNER_SHAREABLE
+ * Inner Shareable. Combine with FFA_MEM_ATTR_NORMAL_MEMORY_*.
+ */
+typedef uint8_t ffa_mem_attr8_t;
+typedef uint16_t ffa_mem_attr16_t;
+#define FFA_MEM_ATTR_NS_BIT (0x1U << 6)
+#define FFA_MEM_ATTR_DEVICE_NGNRNE ((1U << 4) | (0x0U << 2))
+#define FFA_MEM_ATTR_DEVICE_NGNRE ((1U << 4) | (0x1U << 2))
+#define FFA_MEM_ATTR_DEVICE_NGRE ((1U << 4) | (0x2U << 2))
+#define FFA_MEM_ATTR_DEVICE_GRE ((1U << 4) | (0x3U << 2))
+#define FFA_MEM_ATTR_NORMAL_MEMORY_UNCACHED ((2U << 4) | (0x1U << 2))
+#define FFA_MEM_ATTR_NORMAL_MEMORY_CACHED_WB ((2U << 4) | (0x3U << 2))
+#define FFA_MEM_ATTR_NON_SHAREABLE (0x0U << 0)
+#define FFA_MEM_ATTR_OUTER_SHAREABLE (0x2U << 0)
+#define FFA_MEM_ATTR_INNER_SHAREABLE (0x3U << 0)
+
+/**
+ * typedef ffa_mem_perm8_t - Memory access permissions
+ *
+ * * @FFA_MEM_ATTR_RO
+ * Request or specify read-only mapping.
+ * * @FFA_MEM_ATTR_RW
+ * Request or allow read-write mapping.
+ * * @FFA_MEM_PERM_NX
+ * Deny executable mapping.
+ * * @FFA_MEM_PERM_X
+ * Request executable mapping.
+ */
+typedef uint8_t ffa_mem_perm8_t;
+#define FFA_MEM_PERM_RO (1U << 0)
+#define FFA_MEM_PERM_RW (1U << 1)
+#define FFA_MEM_PERM_NX (1U << 2)
+#define FFA_MEM_PERM_X (1U << 3)
+
+/**
+ * typedef ffa_mem_flag8_t - Endpoint memory flags
+ *
+ * * @FFA_MEM_FLAG_NON_RETRIEVAL_BORROWER
+ * Non-retrieval Borrower. Memory region must not be or was not retrieved on
+ * behalf of this endpoint.
+ */
+typedef uint8_t ffa_mem_flag8_t;
+#define FFA_MEM_FLAG_NON_RETRIEVAL_BORROWER (1U << 0)
+
+/**
+ * typedef ffa_mtd_flag32_t - Memory transaction descriptor flags
+ *
+ * * @FFA_MTD_FLAG_ZERO_MEMORY
+ * Zero memory after unmapping from sender (must be 0 for share).
+ * * @FFA_MTD_FLAG_TIME_SLICING
+ * Not supported by this implementation.
+ * * @FFA_MTD_FLAG_ZERO_MEMORY_AFTER_RELINQUISH
+ * Zero memory after unmapping from borrowers (must be 0 for share).
+ * * @FFA_MTD_FLAG_TYPE_MASK
+ * Bit-mask to extract memory management transaction type from flags.
+ * * @FFA_MTD_FLAG_TYPE_SHARE_MEMORY
+ * Share memory transaction flag.
+ * Used by @SMC_FC_FFA_MEM_RETRIEVE_RESP to indicate that memory came from
+ * @SMC_FC_FFA_MEM_SHARE and by @SMC_FC_FFA_MEM_RETRIEVE_REQ to specify that
+ * it must have.
+ * * @FFA_MTD_FLAG_ADDRESS_RANGE_ALIGNMENT_HINT_MASK
+ * Not supported by this implementation.
+ */
+typedef uint32_t ffa_mtd_flag32_t;
+#define FFA_MTD_FLAG_ZERO_MEMORY (1U << 0)
+#define FFA_MTD_FLAG_TIME_SLICING (1U << 1)
+#define FFA_MTD_FLAG_ZERO_MEMORY_AFTER_RELINQUISH (1U << 2)
+#define FFA_MTD_FLAG_TYPE_MASK (3U << 3)
+#define FFA_MTD_FLAG_TYPE_SHARE_MEMORY (1U << 3)
+#define FFA_MTD_FLAG_TYPE_LEND_MEMORY (1U << 4)
+#define FFA_MTD_FLAG_ADDRESS_RANGE_ALIGNMENT_HINT_MASK (0x1FU << 5)
+
+/**
+ * struct ffa_mapd - Memory access permissions descriptor
+ * @endpoint_id:
+ * Endpoint id that @memory_access_permissions and @flags apply to.
+ * (&typedef ffa_endpoint_id16_t).
+ * @memory_access_permissions:
+ * FFA_MEM_PERM_* values or'ed together (&typedef ffa_mem_perm8_t).
+ * @flags:
+ * FFA_MEM_FLAG_* values or'ed together (&typedef ffa_mem_flag8_t).
+ */
+struct ffa_mapd {
+ ffa_endpoint_id16_t endpoint_id;
+ ffa_mem_perm8_t memory_access_permissions;
+ ffa_mem_flag8_t flags;
+};
+CASSERT(sizeof(struct ffa_mapd) == 4, assert_ffa_mapd_size_mismatch);
+
+/**
+ * struct ffa_emad_v1_0 - Endpoint memory access descriptor.
+ * @mapd: &struct ffa_mapd.
+ * @comp_mrd_offset:
+ * Offset of &struct ffa_comp_mrd from start of &struct ffa_mtd_v1_0.
+ * @reserved_8_15:
+ * Reserved bytes 8-15. Must be 0.
+ */
+struct ffa_emad_v1_0 {
+ struct ffa_mapd mapd;
+ uint32_t comp_mrd_offset;
+ uint64_t reserved_8_15;
+};
+CASSERT(sizeof(struct ffa_emad_v1_0) == 16, assert_ffa_emad_v1_0_size_mismatch);
+
+/**
+ * struct ffa_mtd_v1_0 - Memory transaction descriptor.
+ * @sender_id:
+ * Sender endpoint id.
+ * @memory_region_attributes:
+ * FFA_MEM_ATTR_* values or'ed together (&typedef ffa_mem_attr8_t).
+ * @reserved_3:
+ * Reserved bytes 3. Must be 0.
+ * @flags:
+ * FFA_MTD_FLAG_* values or'ed together (&typedef ffa_mtd_flag32_t).
+ * @handle:
+ * Id of shared memory object. Must be 0 for MEM_SHARE or MEM_LEND.
+ * @tag: Client allocated tag. Must match original value.
+ * @reserved_24_27:
+ * Reserved bytes 24-27. Must be 0.
+ * @emad_count:
+ * Number of entries in @emad.
+ * @emad:
+ * Endpoint memory access descriptor array (see @struct ffa_emad_v1_0).
+ */
+struct ffa_mtd_v1_0 {
+ ffa_endpoint_id16_t sender_id;
+ ffa_mem_attr8_t memory_region_attributes;
+ uint8_t reserved_3;
+ ffa_mtd_flag32_t flags;
+ uint64_t handle;
+ uint64_t tag;
+ uint32_t reserved_24_27;
+ uint32_t emad_count;
+ struct ffa_emad_v1_0 emad[];
+};
+CASSERT(sizeof(struct ffa_mtd_v1_0) == 32, assert_ffa_mtd_size_v1_0_mismatch);
+
+/**
+ * struct ffa_mtd - Memory transaction descriptor for FF-A v1.1.
+ * @sender_id:
+ * Sender endpoint id.
+ * @memory_region_attributes:
+ * FFA_MEM_ATTR_* values or'ed together (&typedef ffa_mem_attr16_t).
+ * @flags:
+ * FFA_MTD_FLAG_* values or'ed together (&typedef ffa_mtd_flag32_t).
+ * @handle:
+ * Id of shared memory object. Must be 0 for MEM_SHARE or MEM_LEND.
+ * @tag: Client allocated tag. Must match original value.
+ * @emad_size:
+ * Size of the emad descriptor.
+ * @emad_count:
+ * Number of entries in the emad array.
+ * @emad_offset:
+ * Offset from the beginning of the descriptor to the location of the
+ * memory access descriptor array (see @struct ffa_emad_v1_0).
+ * @reserved_36_39:
+ * Reserved bytes 36-39. Must be 0.
+ * @reserved_40_47:
+ * Reserved bytes 44-47. Must be 0.
+ */
+struct ffa_mtd {
+ ffa_endpoint_id16_t sender_id;
+ ffa_mem_attr16_t memory_region_attributes;
+ ffa_mtd_flag32_t flags;
+ uint64_t handle;
+ uint64_t tag;
+ uint32_t emad_size;
+ uint32_t emad_count;
+ uint32_t emad_offset;
+ uint32_t reserved_36_39;
+ uint64_t reserved_40_47;
+};
+CASSERT(sizeof(struct ffa_mtd) == 48, assert_ffa_mtd_size_mismatch);
+
+#endif /* EL3_SPMC_FFA_MEM_H */
diff --git a/include/services/el3_spmc_logical_sp.h b/include/services/el3_spmc_logical_sp.h
new file mode 100644
index 0000000..7ec9958
--- /dev/null
+++ b/include/services/el3_spmc_logical_sp.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef EL3_SP_H
+#define EL3_SP_H
+
+#include <common/bl_common.h>
+#include <lib/cassert.h>
+
+/*******************************************************************************
+ * Structure definition, typedefs & constants for the Logical SPs.
+ ******************************************************************************/
+
+typedef uint64_t (*direct_msg_handler)(uint32_t smc_fid, bool secure_origin,
+ uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, void *cookie, void *handle,
+ uint64_t flags);
+
+/* Prototype for logical partition initializing function. */
+typedef int32_t (*ffa_partition_init_t)(void);
+
+/* Logical Partition Descriptor. */
+struct el3_lp_desc {
+ ffa_partition_init_t init;
+ uint16_t sp_id;
+ uint32_t properties;
+ uint32_t uuid[4]; /* Little Endian. */
+ direct_msg_handler direct_req;
+ const char *debug_name;
+};
+
+/* Convenience macro to declare a logical partition descriptor. */
+#define DECLARE_LOGICAL_PARTITION(_name, _init, _sp_id, _uuid, _properties, \
+ _direct_req) \
+ static const struct el3_lp_desc __partition_desc_ ## _name \
+ __section("el3_lp_descs") __used = { \
+ .debug_name = #_name, \
+ .init = (_init), \
+ .sp_id = (_sp_id), \
+ .uuid = _uuid, \
+ .properties = (_properties), \
+ .direct_req = (_direct_req), \
+ }
+
+
+/*******************************************************************************
+ * Function & variable prototypes.
+ ******************************************************************************/
+int el3_sp_desc_validate(void);
+uintptr_t handle_el3_sp(uint32_t smc_fid, void *cookie, void *handle,
+ unsigned int flags);
+IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_START__, EL3_LP_DESCS_START);
+IMPORT_SYM(uintptr_t, __EL3_LP_DESCS_END__, EL3_LP_DESCS_END);
+
+#define EL3_LP_DESCS_COUNT ((EL3_LP_DESCS_END - EL3_LP_DESCS_START) \
+ / sizeof(struct el3_lp_desc))
+
+#endif /* EL3_SP_H */
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index 9a7c489..da016fd 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,8 @@
#ifndef FFA_SVC_H
#define FFA_SVC_H
+#include <stdbool.h>
+
#include <lib/smccc.h>
#include <lib/utils_def.h>
#include <tools_share/uuid.h>
@@ -36,6 +38,7 @@
#define FFA_VERSION_MINOR_SHIFT 0
#define FFA_VERSION_MINOR_MASK U(0xFFFF)
#define FFA_VERSION_BIT31_MASK U(0x1u << 31)
+#define FFA_VERSION_MASK U(0xFFFFFFFF)
#define MAKE_FFA_VERSION(major, minor) \
@@ -53,6 +56,19 @@
(((blk) & FFA_MSG_SEND_ATTRS_BLK_MASK) \
<< FFA_MSG_SEND_ATTRS_BLK_SHIFT)
+/* Defines for FF-A framework messages exchanged using direct messages. */
+#define FFA_FWK_MSG_BIT BIT(31)
+#define FFA_FWK_MSG_MASK 0xFF
+#define FFA_FWK_MSG_PSCI U(0x0)
+
+/* Defines for FF-A power management messages framework messages. */
+#define FFA_PM_MSG_WB_REQ U(0x1) /* Warm boot request. */
+#define FFA_PM_MSG_PM_RESP U(0x2) /* Response to PSCI or warmboot req. */
+
+/* FF-A warm boot types. */
+#define FFA_WB_TYPE_S2RAM 0x0
+#define FFA_WB_TYPE_NOTS2RAM 0x1
+
/* Get FFA fastcall std FID from function number */
#define FFA_FID(smc_cc, func_num) \
((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
@@ -85,6 +101,8 @@
#define FFA_FNUM_MEM_RETRIEVE_RESP U(0x75)
#define FFA_FNUM_MEM_RELINQUISH U(0x76)
#define FFA_FNUM_MEM_RECLAIM U(0x77)
+#define FFA_FNUM_MEM_FRAG_RX U(0x7A)
+#define FFA_FNUM_MEM_FRAG_TX U(0x7B)
#define FFA_FNUM_NORMAL_WORLD_RESUME U(0x7C)
/* FF-A v1.1 */
@@ -107,6 +125,7 @@
#define FFA_VERSION FFA_FID(SMC_32, FFA_FNUM_VERSION)
#define FFA_FEATURES FFA_FID(SMC_32, FFA_FNUM_FEATURES)
#define FFA_RX_RELEASE FFA_FID(SMC_32, FFA_FNUM_RX_RELEASE)
+#define FFA_RX_ACQUIRE FFA_FID(SMC_32, FFA_FNUM_RX_ACQUIRE)
#define FFA_RXTX_MAP_SMC32 FFA_FID(SMC_32, FFA_FNUM_RXTX_MAP)
#define FFA_RXTX_UNMAP FFA_FID(SMC_32, FFA_FNUM_RXTX_UNMAP)
#define FFA_PARTITION_INFO_GET FFA_FID(SMC_32, FFA_FNUM_PARTITION_INFO_GET)
@@ -139,6 +158,8 @@
#define FFA_NOTIFICATION_GET FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_GET)
#define FFA_NOTIFICATION_INFO_GET \
FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_INFO_GET)
+#define FFA_MEM_FRAG_RX FFA_FID(SMC_32, FFA_FNUM_MEM_FRAG_RX)
+#define FFA_MEM_FRAG_TX FFA_FID(SMC_32, FFA_FNUM_MEM_FRAG_TX)
#define FFA_SPM_ID_GET FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
#define FFA_NORMAL_WORLD_RESUME FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME)
@@ -161,6 +182,13 @@
FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET)
/*
+ * FF-A partition properties values.
+ */
+#define FFA_PARTITION_DIRECT_REQ_RECV U(1 << 0)
+#define FFA_PARTITION_DIRECT_REQ_SEND U(1 << 1)
+#define FFA_PARTITION_INDIRECT_MSG U(1 << 2)
+
+/*
* Reserve a special value for traffic targeted to the Hypervisor or SPM.
*/
#define FFA_TARGET_INFO_MBZ U(0x0)
@@ -176,6 +204,20 @@
#define FFA_ENDPOINT_ID_MAX U(1 << 16)
/*
+ * Reserve endpoint id for the SPMD.
+ */
+#define SPMD_DIRECT_MSG_ENDPOINT_ID U(FFA_ENDPOINT_ID_MAX - 1)
+
+/* Mask and shift to check valid secure FF-A Endpoint ID. */
+#define SPMC_SECURE_ID_MASK U(1)
+#define SPMC_SECURE_ID_SHIFT U(15)
+
+/*
+ * Partition Count Flag in FFA_PARTITION_INFO_GET.
+ */
+#define FFA_PARTITION_INFO_GET_COUNT_FLAG_MASK U(1 << 0)
+
+/*
* Mask for source and destination endpoint id in
* a direct message request/response.
*/
@@ -209,4 +251,91 @@
FFA_DIRECT_MSG_ENDPOINT_ID_MASK;
}
+/******************************************************************************
+ * FF-A helper functions to determine partition ID world.
+ *****************************************************************************/
+
+/*
+ * Determine if provided ID is in the secure world.
+ */
+static inline bool ffa_is_secure_world_id(uint16_t id)
+{
+ return ((id >> SPMC_SECURE_ID_SHIFT) & SPMC_SECURE_ID_MASK) == 1;
+}
+
+/*
+ * Determine if provided ID is in the normal world.
+ */
+static inline bool ffa_is_normal_world_id(uint16_t id)
+{
+ return !ffa_is_secure_world_id(id);
+}
+
+
+/******************************************************************************
+ * Boot information protocol as per the FF-A v1.1 spec.
+ *****************************************************************************/
+#define FFA_INIT_DESC_SIGNATURE 0x00000FFA
+
+/* Boot information type. */
+#define FFA_BOOT_INFO_TYPE_STD U(0x0)
+#define FFA_BOOT_INFO_TYPE_IMPL U(0x1)
+
+#define FFA_BOOT_INFO_TYPE_MASK U(0x1)
+#define FFA_BOOT_INFO_TYPE_SHIFT U(0x7)
+#define FFA_BOOT_INFO_TYPE(type) \
+ (((type) & FFA_BOOT_INFO_TYPE_MASK) \
+ << FFA_BOOT_INFO_TYPE_SHIFT)
+
+/* Boot information identifier. */
+#define FFA_BOOT_INFO_TYPE_ID_FDT U(0x0)
+#define FFA_BOOT_INFO_TYPE_ID_HOB U(0x1)
+
+#define FFA_BOOT_INFO_TYPE_ID_MASK U(0x3F)
+#define FFA_BOOT_INFO_TYPE_ID_SHIFT U(0x0)
+#define FFA_BOOT_INFO_TYPE_ID(type) \
+ (((type) & FFA_BOOT_INFO_TYPE_ID_MASK) \
+ << FFA_BOOT_INFO_TYPE_ID_SHIFT)
+
+/* Format of Flags Name field. */
+#define FFA_BOOT_INFO_FLAG_NAME_STRING U(0x0)
+#define FFA_BOOT_INFO_FLAG_NAME_UUID U(0x1)
+
+#define FFA_BOOT_INFO_FLAG_NAME_MASK U(0x3)
+#define FFA_BOOT_INFO_FLAG_NAME_SHIFT U(0x0)
+#define FFA_BOOT_INFO_FLAG_NAME(type) \
+ (((type) & FFA_BOOT_INFO_FLAG_NAME_MASK)\
+ << FFA_BOOT_INFO_FLAG_NAME_SHIFT)
+
+/* Format of Flags Contents field. */
+#define FFA_BOOT_INFO_FLAG_CONTENT_ADR U(0x0)
+#define FFA_BOOT_INFO_FLAG_CONTENT_VAL U(0x1)
+
+#define FFA_BOOT_INFO_FLAG_CONTENT_MASK U(0x1)
+#define FFA_BOOT_INFO_FLAG_CONTENT_SHIFT U(0x2)
+#define FFA_BOOT_INFO_FLAG_CONTENT(content) \
+ (((content) & FFA_BOOT_INFO_FLAG_CONTENT_MASK) \
+ << FFA_BOOT_INFO_FLAG_CONTENT_SHIFT)
+
+/* Boot information descriptor. */
+struct ffa_boot_info_desc {
+ uint8_t name[16];
+ uint8_t type;
+ uint8_t reserved;
+ uint16_t flags;
+ uint32_t size_boot_info;
+ uint64_t content;
+};
+
+/* Boot information header. */
+struct ffa_boot_info_header {
+ uint32_t signature; /* 0xFFA */
+ uint32_t version;
+ uint32_t size_boot_info_blob;
+ uint32_t size_boot_info_desc;
+ uint32_t count_boot_info_desc;
+ uint32_t offset_boot_info_desc;
+ uint64_t reserved;
+};
+
#endif /* FFA_SVC_H */
diff --git a/include/services/gtsi_svc.h b/include/services/gtsi_svc.h
deleted file mode 100644
index ef4289f..0000000
--- a/include/services/gtsi_svc.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef GTSI_SVC_H
-#define GTSI_SVC_H
-
-/* GTSI error codes. */
-#define GTSI_SUCCESS 0
-#define GTSI_ERROR_NOT_SUPPORTED -1
-#define GTSI_ERROR_INVALID_ADDRESS -2
-#define GTSI_ERROR_INVALID_PAS -3
-
-/* The macros below are used to identify GTSI calls from the SMC function ID */
-#define GTSI_FNUM_MIN_VALUE U(0x1B0)
-#define GTSI_FNUM_MAX_VALUE U(0x1B1)
-#define is_gtsi_fid(fid) __extension__ ({ \
- __typeof__(fid) _fid = (fid); \
- ((GET_SMC_NUM(_fid) >= GTSI_FNUM_MIN_VALUE) && \
- (GET_SMC_NUM(_fid) <= GTSI_FNUM_MAX_VALUE) && \
- (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST) && \
- (GET_SMC_CC(_fid) == SMC_64) && \
- (GET_SMC_OEN(_fid) == OEN_STD_START) && \
- ((_fid & 0x00FE0000) == 0U)); })
-
-/* Get GTSI fastcall std FID from function number */
-#define GTSI_FID(smc_cc, func_num) \
- ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
- ((smc_cc) << FUNCID_CC_SHIFT) | \
- (OEN_STD_START << FUNCID_OEN_SHIFT) | \
- ((func_num) << FUNCID_NUM_SHIFT))
-
-#define GRAN_TRANS_TO_REALM_FNUM U(0x1B0)
-#define GRAN_TRANS_TO_NS_FNUM U(0x1B1)
-
-#define SMC_ASC_MARK_REALM GTSI_FID(SMC_64, GRAN_TRANS_TO_REALM_FNUM)
-#define SMC_ASC_MARK_NONSECURE GTSI_FID(SMC_64, GRAN_TRANS_TO_NS_FNUM)
-
-#define GRAN_TRANS_RET_BAD_ADDR -2
-#define GRAN_TRANS_RET_BAD_PAS -3
-
-#endif /* GTSI_SVC_H */
diff --git a/include/services/rmi_svc.h b/include/services/rmi_svc.h
deleted file mode 100644
index 46fd510..0000000
--- a/include/services/rmi_svc.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef RMI_SVC_H
-#define RMI_SVC_H
-
-#include <lib/smccc.h>
-#include <lib/utils_def.h>
-
-/* RMI error codes. */
-#define RMI_SUCCESS 0
-#define RMI_ERROR_NOT_SUPPORTED -1
-#define RMI_ERROR_INVALID_ADDRESS -2
-#define RMI_ERROR_INVALID_PAS -3
-
-/* The macros below are used to identify RMI calls from the SMC function ID */
-#define RMI_FNUM_MIN_VALUE U(0x150)
-#define RMI_FNUM_MAX_VALUE U(0x18F)
-#define is_rmi_fid(fid) __extension__ ({ \
- __typeof__(fid) _fid = (fid); \
- ((GET_SMC_NUM(_fid) >= RMI_FNUM_MIN_VALUE) && \
- (GET_SMC_NUM(_fid) <= RMI_FNUM_MAX_VALUE) && \
- (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST) && \
- (GET_SMC_CC(_fid) == SMC_64) && \
- (GET_SMC_OEN(_fid) == OEN_STD_START) && \
- ((_fid & 0x00FE0000) == 0U)); })
-
-/* Get RMI fastcall std FID from function number */
-#define RMI_FID(smc_cc, func_num) \
- ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
- ((smc_cc) << FUNCID_CC_SHIFT) | \
- (OEN_STD_START << FUNCID_OEN_SHIFT) | \
- ((func_num) << FUNCID_NUM_SHIFT))
-
-/*
- * SMC_RMM_INIT_COMPLETE is the only function in the RMI that originates from
- * the Realm world and is handled by the RMMD. The remaining functions are
- * always invoked by the Normal world, forwarded by RMMD and handled by the
- * RMM
- */
-#define RMI_FNUM_REQ_COMPLETE U(0x18F)
-#define RMI_FNUM_VERSION_REQ U(0x150)
-
-#define RMI_FNUM_GRANULE_DELEGATE U(0x151)
-#define RMI_FNUM_GRANULE_UNDELEGATE U(0x152)
-
-/* RMI SMC64 FIDs handled by the RMMD */
-#define RMI_RMM_REQ_COMPLETE RMI_FID(SMC_64, RMI_FNUM_REQ_COMPLETE)
-#define RMI_RMM_REQ_VERSION RMI_FID(SMC_64, RMI_FNUM_VERSION_REQ)
-
-#define RMI_RMM_GRANULE_DELEGATE RMI_FID(SMC_64, \
- RMI_FNUM_GRANULE_DELEGATE)
-#define RMI_RMM_GRANULE_UNDELEGATE RMI_FID(SMC_64, \
- RMI_FNUM_GRANULE_UNDELEGATE)
-
-#define RMI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16)
-#define RMI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF)
-
-/* Reserve a special value for MBZ parameters. */
-#define RMI_PARAM_MBZ U(0x0)
-
-#endif /* RMI_SVC_H */
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
new file mode 100644
index 0000000..2f25858
--- /dev/null
+++ b/include/services/rmm_core_manifest.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RMM_CORE_MANIFEST_H
+#define RMM_CORE_MANIFEST_H
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/cassert.h>
+
+#define RMMD_MANIFEST_VERSION_MAJOR U(0)
+#define RMMD_MANIFEST_VERSION_MINOR U(1)
+
+/*
+ * Manifest version encoding:
+ * - Bit[31] RES0
+ * - Bits [30:16] Major version
+ * - Bits [15:0] Minor version
+ */
+#define _RMMD_MANIFEST_VERSION(_major, _minor) \
+ ((((_major) & 0x7FFF) << 16) | ((_minor) & 0xFFFF))
+
+#define RMMD_MANIFEST_VERSION _RMMD_MANIFEST_VERSION( \
+ RMMD_MANIFEST_VERSION_MAJOR, \
+ RMMD_MANIFEST_VERSION_MINOR)
+
+#define RMMD_GET_MANIFEST_VERSION_MAJOR(_version) \
+ ((_version >> 16) & 0x7FFF)
+
+#define RMMD_GET_MANIFEST_VERSION_MINOR(_version) \
+ (_version & 0xFFFF)
+
+/* Boot manifest core structure as per v0.1 */
+typedef struct rmm_manifest {
+ uint32_t version; /* Manifest version */
+ uintptr_t plat_data; /* Manifest platform data */
+} rmm_manifest_t;
+
+CASSERT(offsetof(rmm_manifest_t, version) == 0,
+ rmm_manifest_t_version_unaligned);
+CASSERT(offsetof(rmm_manifest_t, plat_data) == 8,
+ rmm_manifest_t_plat_data_unaligned);
+
+#endif /* RMM_CORE_MANIFEST_H */
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index 132973b..de7181c 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,161 @@
#ifndef RMMD_SVC_H
#define RMMD_SVC_H
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+
+/* STD calls FNUM Min/Max ranges */
+#define RMI_FNUM_MIN_VALUE U(0x150)
+#define RMI_FNUM_MAX_VALUE U(0x18F)
+
+/* Construct RMI fastcall std FID from offset */
+#define SMC64_RMI_FID(_offset) \
+ ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+ (SMC_64 << FUNCID_CC_SHIFT) | \
+ (OEN_STD_START << FUNCID_OEN_SHIFT) | \
+ (((RMI_FNUM_MIN_VALUE + (_offset)) & FUNCID_NUM_MASK) \
+ << FUNCID_NUM_SHIFT))
+
+#define is_rmi_fid(fid) __extension__ ({ \
+ __typeof__(fid) _fid = (fid); \
+ ((GET_SMC_NUM(_fid) >= RMI_FNUM_MIN_VALUE) && \
+ (GET_SMC_NUM(_fid) <= RMI_FNUM_MAX_VALUE) && \
+ (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST) && \
+ (GET_SMC_CC(_fid) == SMC_64) && \
+ (GET_SMC_OEN(_fid) == OEN_STD_START) && \
+ ((_fid & 0x00FE0000) == 0U)); })
+
+/*
+ * RMI_FNUM_REQ_COMPLETE is the only function in the RMI range that originates
+ * from the Realm world and is handled by the RMMD. The RMI functions are
+ * always invoked by the Normal world, forwarded by RMMD and handled by the
+ * RMM.
+ */
+ /* 0x18F */
+#define RMM_RMI_REQ_COMPLETE SMC64_RMI_FID(U(0x3F))
+
+/* RMM_BOOT_COMPLETE arg0 error codes */
+#define E_RMM_BOOT_SUCCESS (0)
+#define E_RMM_BOOT_UNKNOWN (-1)
+#define E_RMM_BOOT_VERSION_MISMATCH (-2)
+#define E_RMM_BOOT_CPUS_OUT_OF_RANGE (-3)
+#define E_RMM_BOOT_CPU_ID_OUT_OF_RANGE (-4)
+#define E_RMM_BOOT_INVALID_SHARED_BUFFER (-5)
+#define E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED (-6)
+#define E_RMM_BOOT_MANIFEST_DATA_ERROR (-7)
+
+/* The SMC in the range 0x8400 0191 - 0x8400 01AF are reserved for RSIs.*/
+
+/*
+ * EL3 - RMM SMCs used for requesting RMMD services. These SMCs originate in Realm
+ * world and return to Realm world.
+ *
+ * These are allocated from 0x8400 01B0 - 0x8400 01CF in the RMM Service range.
+ */
+#define RMMD_EL3_FNUM_MIN_VALUE U(0x1B0)
+#define RMMD_EL3_FNUM_MAX_VALUE U(0x1CF)
+
+/* Construct RMM_EL3 fastcall std FID from offset */
+#define SMC64_RMMD_EL3_FID(_offset) \
+ ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+ (SMC_64 << FUNCID_CC_SHIFT) | \
+ (OEN_STD_START << FUNCID_OEN_SHIFT) | \
+ (((RMMD_EL3_FNUM_MIN_VALUE + (_offset)) & FUNCID_NUM_MASK) \
+ << FUNCID_NUM_SHIFT))
+
+/* The macros below are used to identify GTSI calls from the SMC function ID */
+#define is_rmmd_el3_fid(fid) __extension__ ({ \
+ __typeof__(fid) _fid = (fid); \
+ ((GET_SMC_NUM(_fid) >= RMMD_EL3_FNUM_MIN_VALUE) &&\
+ (GET_SMC_NUM(_fid) <= RMMD_EL3_FNUM_MAX_VALUE) &&\
+ (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST) && \
+ (GET_SMC_CC(_fid) == SMC_64) && \
+ (GET_SMC_OEN(_fid) == OEN_STD_START) && \
+ ((_fid & 0x00FE0000) == 0U)); })
+
+ /* 0x1B0 - 0x1B1 */
+#define RMM_GTSI_DELEGATE SMC64_RMMD_EL3_FID(U(0))
+#define RMM_GTSI_UNDELEGATE SMC64_RMMD_EL3_FID(U(1))
+
+/* Return error codes from RMM-EL3 SMCs */
+#define E_RMM_OK 0
+#define E_RMM_UNK -1
+#define E_RMM_BAD_ADDR -2
+#define E_RMM_BAD_PAS -3
+#define E_RMM_NOMEM -4
+#define E_RMM_INVAL -5
+
+/* Acceptable SHA sizes for Challenge object */
+#define SHA256_DIGEST_SIZE 32U
+#define SHA384_DIGEST_SIZE 48U
+#define SHA512_DIGEST_SIZE 64U
+
+/*
+ * Retrieve Realm attestation key from EL3. Only P-384 ECC curve key is
+ * supported. The arguments to this SMC are :
+ * arg0 - Function ID.
+ * arg1 - Realm attestation key buffer Physical address.
+ * arg2 - Realm attestation key buffer size (in bytes).
+ * arg3 - The type of the elliptic curve to which the requested
+ * attestation key belongs to. The value should be one of the
+ * defined curve types.
+ * The return arguments are :
+ * ret0 - Status / error.
+ * ret1 - Size of the realm attestation key if successful.
+ */
+ /* 0x1B2 */
+#define RMM_ATTEST_GET_REALM_KEY SMC64_RMMD_EL3_FID(U(2))
+
+/*
+ * Retrieve Platform token from EL3.
+ * The arguments to this SMC are :
+ * arg0 - Function ID.
+ * arg1 - Platform attestation token buffer Physical address. (The challenge
+ * object is passed in this buffer.)
+ * arg2 - Platform attestation token buffer size (in bytes).
+ * arg3 - Challenge object size (in bytes). It has to be one of the defined
+ * SHA hash sizes.
+ * The return arguments are :
+ * ret0 - Status / error.
+ * ret1 - Size of the platform token if successful.
+ */
+ /* 0x1B3 */
+#define RMM_ATTEST_GET_PLAT_TOKEN SMC64_RMMD_EL3_FID(U(3))
+
+/* ECC Curve types for attest key generation */
+#define ATTEST_KEY_CURVE_ECC_SECP384R1 0
+
+/*
+ * RMM_BOOT_COMPLETE originates on RMM when the boot finishes (either cold
+ * or warm boot). This is handled by the RMM-EL3 interface SMC handler.
+ *
+ * RMM_BOOT_COMPLETE FID is located at the end of the available range.
+ */
+ /* 0x1CF */
+#define RMM_BOOT_COMPLETE SMC64_RMMD_EL3_FID(U(0x1F))
+
+/*
+ * The major version number of the RMM Boot Interface implementation.
+ * Increase this whenever the semantics of the boot arguments change making it
+ * backwards incompatible.
+ */
+#define RMM_EL3_IFC_VERSION_MAJOR (U(0))
+
+/*
+ * The minor version number of the RMM Boot Interface implementation.
+ * Increase this when a bug is fixed, or a feature is added without
+ * breaking compatibility.
+ */
+#define RMM_EL3_IFC_VERSION_MINOR (U(1))
+
+#define RMM_EL3_INTERFACE_VERSION \
+ (((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) | \
+ RMM_EL3_IFC_VERSION_MINOR)
+
+#define RMM_EL3_IFC_VERSION_GET_MAJOR(_version) (((_version) >> 16) \
+ & 0x7FFF)
+#define RMM_EL3_IFC_VERSION_GET_MAJOR_MINOR(_version) ((_version) & 0xFFFF)
+
#ifndef __ASSEMBLER__
#include <stdint.h>
@@ -20,7 +175,7 @@
void *handle,
uint64_t flags);
-uint64_t rmmd_gtsi_handler(uint32_t smc_fid,
+uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
@@ -30,5 +185,4 @@
uint64_t flags);
#endif /* __ASSEMBLER__ */
-
#endif /* RMMD_SVC_H */
diff --git a/include/services/spmc_svc.h b/include/services/spmc_svc.h
new file mode 100644
index 0000000..8ee61e9
--- /dev/null
+++ b/include/services/spmc_svc.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMC_SVC_H
+#define SPMC_SVC_H
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+#include <services/ffa_svc.h>
+#include <services/spm_core_manifest.h>
+
+int spmc_setup(void);
+void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs);
+void *spmc_get_config_addr(void);
+
+void spmc_set_config_addr(uintptr_t soc_fw_config);
+
+uint64_t spmc_smc_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
+
+static inline bool is_spmc_at_el3(void)
+{
+ return SPMC_AT_EL3 == 1;
+}
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPMC_SVC_H */
diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h
index 1e7e6aa..29dfdad 100644
--- a/include/services/spmd_svc.h
+++ b/include/services/spmd_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,14 @@
#include <stdint.h>
int spmd_setup(void);
+uint64_t spmd_ffa_smc_handler(uint32_t smc_fid,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
uint64_t spmd_smc_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
@@ -20,6 +28,13 @@
void *cookie,
void *handle,
uint64_t flags);
+uint64_t spmd_smc_switch_state(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *handle);
#endif /* __ASSEMBLER__ */
#endif /* SPMD_SVC_H */
diff --git a/include/services/trp/platform_trp.h b/include/services/trp/platform_trp.h
index b34da85..1c963c8 100644
--- a/include/services/trp/platform_trp.h
+++ b/include/services/trp/platform_trp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,9 +7,11 @@
#ifndef PLATFORM_TRP_H
#define PLATFORM_TRP_H
+#include <services/rmm_core_manifest.h>
+
/*******************************************************************************
* Mandatory TRP functions (only if platform contains a TRP)
******************************************************************************/
-void trp_early_platform_setup(void);
+void trp_early_platform_setup(rmm_manifest_t *manifest);
#endif /* PLATFORM_TRP_H */
diff --git a/include/services/trp/trp_helpers.h b/include/services/trp/trp_helpers.h
new file mode 100644
index 0000000..8e786e2
--- /dev/null
+++ b/include/services/trp/trp_helpers.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRP_HELPERS_H
+#define TRP_HELPERS_H
+
+/* Definitions to help the assembler access the SMC/ERET args structure */
+#define TRP_ARGS_SIZE TRP_ARGS_END
+#define TRP_ARG0 0x0
+#define TRP_ARG1 0x8
+#define TRP_ARG2 0x10
+#define TRP_ARG3 0x18
+#define TRP_ARG4 0x20
+#define TRP_ARG5 0x28
+#define TRP_ARG6 0x30
+#define TRP_ARG7 0x38
+#define TRP_ARGS_END 0x40
+
+#ifndef __ASSEMBLER__
+
+#include <platform_def.h>
+
+/* Data structure to hold SMC arguments */
+typedef struct trp_args {
+ uint64_t regs[TRP_ARGS_END >> 3];
+} __aligned(CACHE_WRITEBACK_GRANULE) trp_args_t;
+
+trp_args_t *set_smc_args(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7);
+
+__dead2 void trp_boot_abort(uint64_t err);
+
+#endif /* __ASSEMBLER __ */
+#endif /* TRP_HELPERS_H */
diff --git a/include/tools_share/cca_oid.h b/include/tools_share/cca_oid.h
new file mode 100644
index 0000000..e586b8c
--- /dev/null
+++ b/include/tools_share/cca_oid.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CCA_OID_H
+#define CCA_OID_H
+
+/* Reuse the Object IDs defined by TBBR for certificate extensions. */
+#include "tbbr_oid.h"
+
+/*
+ * Assign arbitrary Object ID values that do not conflict with any of the
+ * TBBR reserved OIDs.
+ */
+/* Platform root-of-trust public key */
+#define PROT_PK_OID "1.3.6.1.4.1.4128.2100.1102"
+/* Secure World root-of-trust public key */
+#define SWD_ROT_PK_OID "1.3.6.1.4.1.4128.2100.1103"
+/* Core Secure World public key */
+#define CORE_SWD_PK_OID "1.3.6.1.4.1.4128.2100.1104"
+/* Platform public key */
+#define PLAT_PK_OID "1.3.6.1.4.1.4128.2100.1105"
+/* Realm Monitor Manager (RMM) Hash */
+#define RMM_HASH_OID "1.3.6.1.4.1.4128.2100.1106"
+
+#endif /* CCA_OID_H */
diff --git a/include/tools_share/firmware_image_package.h b/include/tools_share/firmware_image_package.h
index bd5b14b..b73eec7 100644
--- a/include/tools_share/firmware_image_package.h
+++ b/include/tools_share/firmware_image_package.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -24,6 +24,12 @@
{{0x4f, 0x51, 0x1d, 0x11}, {0x2b, 0xe5}, {0x4e, 0x49}, 0xb4, 0xc5, {0x83, 0xc2, 0xf7, 0x15, 0x84, 0x0a} }
#define UUID_TRUSTED_FWU_CERT \
{{0x71, 0x40, 0x8a, 0xb2}, {0x18, 0xd6}, {0x87, 0x4c}, 0x8b, 0x2e, {0xc6, 0xdc, 0xcd, 0x50, 0xf0, 0x96} }
+#define UUID_CCA_CONTENT_CERT \
+ {{0x36, 0xd8, 0x3d, 0x85}, {0x76, 0x1d}, {0x4d, 0xaf}, 0x96, 0xf1, {0xcd, 0x99, 0xd6, 0x56, 0x9b, 0x00} }
+#define UUID_CORE_SWD_KEY_CERT \
+ {{0x52, 0x22, 0x2d, 0x31}, {0x82, 0x0f}, {0x49, 0x4d}, 0x8b, 0xbc, {0xea, 0x68, 0x25, 0xd3, 0xc3, 0x5a} }
+#define UUID_PLAT_KEY_CERT \
+ {{0xd4, 0x3c, 0xd9, 0x02}, {0x5b, 0x9f}, {0x41, 0x2e}, 0x8a, 0xc6, {0x92, 0xb6, 0xd1, 0x8b, 0xe6, 0x0d} }
#define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \
{{0x5f, 0xf9, 0xec, 0x0b}, {0x4d, 0x22}, {0x3e, 0x4d}, 0xa5, 0x44, {0xc3, 0x9d, 0x81, 0xc7, 0x3f, 0x0a} }
#define UUID_SCP_FIRMWARE_SCP_BL2 \
diff --git a/include/tools_share/sptool.h b/include/tools_share/sptool.h
deleted file mode 100644
index 53668e0..0000000
--- a/include/tools_share/sptool.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPTOOL_H
-#define SPTOOL_H
-
-#include <stdint.h>
-
-/* 4 Byte magic name "SPKG" */
-#define SECURE_PARTITION_MAGIC 0x474B5053
-
-/* Header for a secure partition package. */
-struct sp_pkg_header {
- uint32_t magic;
- uint32_t version;
- uint32_t pm_offset;
- uint32_t pm_size;
- uint32_t img_offset;
- uint32_t img_size;
-};
-
-#endif /* SPTOOL_H */
diff --git a/lib/cpus/aarch32/cortex_a15.S b/lib/cpus/aarch32/cortex_a15.S
index ab136ad..1143e9b 100644
--- a/lib/cpus/aarch32/cortex_a15.S
+++ b/lib/cpus/aarch32/cortex_a15.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -100,6 +100,15 @@
bx lr
endfunc check_errata_cve_2017_5715
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov r0, #ERRATA_APPLIES
+#else
+ mov r0, #ERRATA_MISSING
+#endif
+ bx lr
+endfunc check_errata_cve_2022_23960
+
#if REPORT_ERRATA
/*
* Errata printing function for Cortex A15. Must follow AAPCS.
@@ -117,6 +126,7 @@
report_errata ERRATA_A15_816470, cortex_a15, 816470
report_errata ERRATA_A15_827671, cortex_a15, 827671
report_errata WORKAROUND_CVE_2017_5715, cortex_a15, cve_2017_5715
+ report_errata WORKAROUND_CVE_2022_23960, cortex_a15, cve_2022_23960
pop {r12, lr}
bx lr
@@ -131,11 +141,11 @@
bl errata_a15_827671_wa
#endif
-#if IMAGE_BL32 && WORKAROUND_CVE_2017_5715
+#if IMAGE_BL32 && (WORKAROUND_CVE_2017_5715 || WORKAROUND_CVE_2022_23960)
ldcopr r0, ACTLR
orr r0, #CORTEX_A15_ACTLR_INV_BTB_BIT
stcopr r0, ACTLR
- ldr r0, =workaround_icache_inv_runtime_exceptions
+ ldr r0, =wa_cve_2017_5715_icache_inv_vbar
stcopr r0, VBAR
stcopr r0, MVBAR
/* isb will be applied in the course of the reset func */
diff --git a/lib/cpus/aarch32/cortex_a57.S b/lib/cpus/aarch32/cortex_a57.S
index 2e97abb..18ee1f9 100644
--- a/lib/cpus/aarch32/cortex_a57.S
+++ b/lib/cpus/aarch32/cortex_a57.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -396,6 +396,11 @@
bx lr
endfunc check_errata_cve_2018_3639
+func check_errata_cve_2022_23960
+ mov r0, #ERRATA_MISSING
+ bx lr
+endfunc check_errata_cve_2022_23960
+
/* -------------------------------------------------
* The CPU Ops reset function for Cortex-A57.
* Shall clobber: r0-r6
@@ -600,6 +605,7 @@
report_errata ERRATA_A57_859972, cortex_a57, 859972
report_errata WORKAROUND_CVE_2017_5715, cortex_a57, cve_2017_5715
report_errata WORKAROUND_CVE_2018_3639, cortex_a57, cve_2018_3639
+ report_errata WORKAROUND_CVE_2022_23960, cortex_a57, cve_2022_23960
pop {r12, lr}
bx lr
diff --git a/lib/cpus/aarch32/cortex_a72.S b/lib/cpus/aarch32/cortex_a72.S
index ff2b0e6..03914b2 100644
--- a/lib/cpus/aarch32/cortex_a72.S
+++ b/lib/cpus/aarch32/cortex_a72.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -101,6 +101,11 @@
bx lr
endfunc check_errata_cve_2018_3639
+func check_errata_cve_2022_23960
+ mov r0, #ERRATA_MISSING
+ bx lr
+endfunc check_errata_cve_2022_23960
+
/* -------------------------------------------------
* The CPU Ops reset function for Cortex-A72.
* -------------------------------------------------
@@ -260,6 +265,7 @@
report_errata ERRATA_A72_859971, cortex_a72, 859971
report_errata WORKAROUND_CVE_2017_5715, cortex_a72, cve_2017_5715
report_errata WORKAROUND_CVE_2018_3639, cortex_a72, cve_2018_3639
+ report_errata WORKAROUND_CVE_2022_23960, cortex_a72, cve_2022_23960
pop {r12, lr}
bx lr
diff --git a/lib/cpus/aarch64/a64fx.S b/lib/cpus/aarch64/a64fx.S
new file mode 100644
index 0000000..54c20c3
--- /dev/null
+++ b/lib/cpus/aarch64/a64fx.S
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022, Fujitsu Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <a64fx.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+func a64fx_core_pwr_dwn
+endfunc a64fx_core_pwr_dwn
+
+func a64fx_cluster_pwr_dwn
+endfunc a64fx_cluster_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for A64FX. Must follow AAPCS.
+ */
+func a64fx_errata_report
+ ret
+endfunc a64fx_errata_report
+#endif
+
+ /* ---------------------------------------------
+ * This function provides cpu specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ascii and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.a64fx_regs, "aS"
+a64fx_regs: /* The ascii list of register names to be reported */
+ .asciz ""
+
+func a64fx_cpu_reg_dump
+ adr x6, a64fx_regs
+ ret
+endfunc a64fx_cpu_reg_dump
+
+declare_cpu_ops a64fx, A64FX_MIDR, CPU_NO_RESET_FUNC \
+ a64fx_core_pwr_dwn, \
+ a64fx_cluster_pwr_dwn
+
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index 34e1082..81a4a78 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -265,6 +265,72 @@
endfunc check_errata_2172148
/* ----------------------------------------------------
+ * Errata Workaround for Cortex-A510 Errata #2347730.
+ * This applies to revisions r0p0 - r0p3, r1p0, r1p1.
+ * It is fixed in r1p2.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * ----------------------------------------------------
+ */
+func errata_cortex_a510_2347730_wa
+ mov x17, x30
+ bl check_errata_2347730
+ cbz x0, 1f
+
+ /*
+ * Set CPUACTLR_EL1[17] to 1'b1, which disables
+ * specific microarchitectural clock gating
+ * behaviour.
+ */
+ mrs x1, CORTEX_A510_CPUACTLR_EL1
+ orr x1, x1, CORTEX_A510_CPUACTLR_EL1_BIT_17
+ msr CORTEX_A510_CPUACTLR_EL1, x1
+1:
+ ret x17
+endfunc errata_cortex_a510_2347730_wa
+
+func check_errata_2347730
+ /* Applies to revisions r1p1 and lower. */
+ mov x1, #0x11
+ b cpu_rev_var_ls
+endfunc check_errata_2347730
+
+ /*---------------------------------------------------
+ * Errata Workaround for Cortex-A510 Errata #2371937.
+ * This applies to revisions r1p1 and lower, and is
+ * fixed in r1p2.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0, x1, x17
+ *---------------------------------------------------
+ */
+func errata_cortex_a510_2371937_wa
+ mov x17, x30
+ bl check_errata_2371937
+ cbz x0, 1f
+
+ /*
+ * Cacheable atomic operations can be forced
+ * to be executed near by setting
+ * IMP_CPUECTLR_EL1.ATOM=0b010. ATOM is found
+ * in [40:38] of CPUECTLR_EL1.
+ */
+ mrs x0, CORTEX_A510_CPUECTLR_EL1
+ mov x1, CORTEX_A510_CPUECTLR_EL1_ATOM_EXECALLINSTRNEAR
+ bfi x0, x1, CORTEX_A510_CPUECTLR_EL1_ATOM, #3
+ msr CORTEX_A510_CPUECTLR_EL1, x0
+1:
+ ret x17
+endfunc errata_cortex_a510_2371937_wa
+
+func check_errata_2371937
+ /* Applies to r1p1 and lower */
+ mov x1, #0x11
+ b cpu_rev_var_ls
+endfunc check_errata_2371937
+
+ /* ----------------------------------------------------
* HW will do the cache maintenance while powering down
* ----------------------------------------------------
*/
@@ -301,6 +367,9 @@
report_errata ERRATA_A510_2250311, cortex_a510, 2250311
report_errata ERRATA_A510_2218950, cortex_a510, 2218950
report_errata ERRATA_A510_2172148, cortex_a510, 2172148
+ report_errata ERRATA_A510_2347730, cortex_a510, 2347730
+ report_errata ERRATA_A510_2371937, cortex_a510, 2371937
+ report_errata ERRATA_DSU_2313941, cortex_a510, dsu_2313941
ldp x8, x30, [sp], #16
ret
@@ -312,12 +381,15 @@
/* Disable speculative loads */
msr SSBS, xzr
- isb
/* Get the CPU revision and stash it in x18. */
bl cpu_get_rev_var
mov x18, x0
+#if ERRATA_DSU_2313941
+ bl errata_dsu_2313941_wa
+#endif
+
#if ERRATA_A510_1922240
mov x0, x18
bl errata_cortex_a510_1922240_wa
@@ -348,11 +420,22 @@
bl errata_cortex_a510_2218950_wa
#endif
+#if ERRATA_A510_2371937
+ mov x0, x18
+ bl errata_cortex_a510_2371937_wa
+#endif
+
#if ERRATA_A510_2172148
mov x0, x18
bl errata_cortex_a510_2172148_wa
#endif
+#if ERRATA_A510_2347730
+ mov x0, x18
+ bl errata_cortex_a510_2347730_wa
+#endif
+
+ isb
ret x19
endfunc cortex_a510_reset_func
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index 7838304..0e0388b 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.S
@@ -16,6 +16,8 @@
#error "Cortex-A55 must be compiled with HW_ASSISTED_COHERENCY enabled"
#endif
+ .globl cortex_a55_reset_func
+ .globl cortex_a55_core_pwr_dwn
/* --------------------------------------------------
* Errata Workaround for Cortex A55 Errata #768277.
* This applies only to revision r0p0 of Cortex A55.
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index aea62ae..77f7a8d 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -280,6 +280,79 @@
b cpu_rev_var_ls
endfunc check_errata_2136059
+/* ----------------------------------------------------------------
+ * Errata workaround for Cortex-A710 Erratum 2147715.
+ * This applies to revision r2p0, and is fixed in r2p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0, x1, x17
+ * ----------------------------------------------------------------
+ */
+func errata_a710_2147715_wa
+ mov x17, x30
+ bl check_errata_2147715
+ cbz x0, 1f
+
+ /* Apply workaround; set CPUACTLR_EL1[22]
+ * to 1, which will cause the CFP instruction
+ * to invalidate all branch predictor resources
+ * regardless of context.
+ */
+ mrs x1, CORTEX_A710_CPUACTLR_EL1
+ orr x1, x1, CORTEX_A710_CPUACTLR_EL1_BIT_22
+ msr CORTEX_A710_CPUACTLR_EL1, x1
+1:
+ ret x17
+endfunc errata_a710_2147715_wa
+
+func check_errata_2147715
+ mov x1, #0x20
+ mov x2, #0x20
+ b cpu_rev_var_range
+endfunc check_errata_2147715
+
+/* ---------------------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2216384.
+ * This applies to revision r0p0, r1p0 and r2p0.
+ * It is fixed in r2p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ---------------------------------------------------------------
+ */
+func errata_a710_2216384_wa
+ /* Compare x0 against revision r2p0 */
+ mov x17, x30
+ bl check_errata_2216384
+ cbz x0, 1f
+
+ /* Apply workaround: set CPUACTLR5_EL1[17]
+ * to 1 and the following instruction
+ * patching sequence.
+ */
+ mrs x1, CORTEX_A710_CPUACTLR5_EL1
+ orr x1, x1, CORTEX_A710_CPUACTLR5_EL1_BIT_17
+ msr CORTEX_A710_CPUACTLR5_EL1, x1
+
+ ldr x0,=0x5
+ msr CORTEX_A710_CPUPSELR_EL3, x0
+ ldr x0,=0x10F600E000
+ msr CORTEX_A710_CPUPOR_EL3, x0
+ ldr x0,=0x10FF80E000
+ msr CORTEX_A710_CPUPMR_EL3, x0
+ ldr x0,=0x80000000003FF
+ msr CORTEX_A710_CPUPCR_EL3, x0
+ isb
+1:
+ ret x17
+endfunc errata_a710_2216384_wa
+
+func check_errata_2216384
+ /* Applies to r0p0, r1p0 and r2p0 */
+ mov x1, #0x20
+ b cpu_rev_var_ls
+endfunc check_errata_2216384
+
/* ---------------------------------------------------------------
* Errata Workaround for Cortex-A710 Erratum 2282622.
* This applies to revision r0p0, r1p0 and r2p0.
@@ -310,6 +383,77 @@
b cpu_rev_var_ls
endfunc check_errata_2282622
+/* ---------------------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2008768.
+ * This applies to revision r0p0, r1p0 and r2p0.
+ * It is fixed in r2p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0, x1, x2, x17
+ * ---------------------------------------------------------------
+ */
+func errata_a710_2008768_wa
+ mov x17, x30
+ bl check_errata_2008768
+ cbz x0, 1f
+
+ /* Stash ERRSELR_EL1 in x2 */
+ mrs x2, ERRSELR_EL1
+
+ /* Select error record 0 and clear ED bit */
+ msr ERRSELR_EL1, xzr
+ mrs x1, ERXCTLR_EL1
+ bfi x1, xzr, #ERXCTLR_ED_SHIFT, #1
+ msr ERXCTLR_EL1, x1
+
+ /* Select error record 1 and clear ED bit */
+ mov x0, #1
+ msr ERRSELR_EL1, x0
+ mrs x1, ERXCTLR_EL1
+ bfi x1, xzr, #ERXCTLR_ED_SHIFT, #1
+ msr ERXCTLR_EL1, x1
+
+ /* Restore ERRSELR_EL1 from x2 */
+ msr ERRSELR_EL1, x2
+
+1:
+ ret x17
+endfunc errata_a710_2008768_wa
+
+func check_errata_2008768
+ /* Applies to r0p0, r1p0 and r2p0 */
+ mov x1, #0x20
+ b cpu_rev_var_ls
+endfunc check_errata_2008768
+
+/* -------------------------------------------------------
+ * Errata Workaround for Cortex-A710 Erratum 2371105.
+ * This applies to revisions <= r2p0 and is fixed in r2p1.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * -------------------------------------------------------
+ */
+func errata_a710_2371105_wa
+ /* Check workaround compatibility. */
+ mov x17, x30
+ bl check_errata_2371105
+ cbz x0, 1f
+
+ /* Set bit 40 in CPUACTLR2_EL1 */
+ mrs x1, CORTEX_A710_CPUACTLR2_EL1
+ orr x1, x1, #CORTEX_A710_CPUACTLR2_EL1_BIT_40
+ msr CORTEX_A710_CPUACTLR2_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_a710_2371105_wa
+
+func check_errata_2371105
+ /* Applies to <= r2p0. */
+ mov x1, #0x20
+ b cpu_rev_var_ls
+endfunc check_errata_2371105
+
func check_errata_cve_2022_23960
#if WORKAROUND_CVE_2022_23960
mov x0, #ERRATA_APPLIES
@@ -324,6 +468,14 @@
* ----------------------------------------------------
*/
func cortex_a710_core_pwr_dwn
+
+#if ERRATA_A710_2008768
+ mov x4, x30
+ bl cpu_get_rev_var
+ bl errata_a710_2008768_wa
+ mov x30, x4
+#endif
+
/* ---------------------------------------------------
* Enable CPU power down bit in power control register
* ---------------------------------------------------
@@ -358,7 +510,12 @@
report_errata ERRATA_A710_2267065, cortex_a710, 2267065
report_errata ERRATA_A710_2136059, cortex_a710, 2136059
report_errata ERRATA_A710_2282622, cortex_a710, 2282622
+ report_errata ERRATA_A710_2008768, cortex_a710, 2008768
+ report_errata ERRATA_A710_2147715, cortex_a710, 2147715
+ report_errata ERRATA_A710_2216384, cortex_a710, 2216384
+ report_errata ERRATA_A710_2371105, cortex_a710, 2371105
report_errata WORKAROUND_CVE_2022_23960, cortex_a710, cve_2022_23960
+ report_errata ERRATA_DSU_2313941, cortex_a710, dsu_2313941
ldp x8, x30, [sp], #16
ret
@@ -374,6 +531,10 @@
bl cpu_get_rev_var
mov x18, x0
+#if ERRATA_DSU_2313941
+ bl errata_dsu_2313941_wa
+#endif
+
#if ERRATA_A710_1987031
mov x0, x18
bl errata_a710_1987031_wa
@@ -414,16 +575,31 @@
bl errata_a710_2136059_wa
#endif
+#if ERRATA_A710_2147715
+ mov x0, x18
+ bl errata_a710_2147715_wa
+#endif
+
+#if ERRATA_A710_2216384
+ mov x0, x18
+ bl errata_a710_2216384_wa
+#endif /* ERRATA_A710_2216384 */
+
#if ERRATA_A710_2282622
mov x0, x18
bl errata_a710_2282622_wa
#endif
+#if ERRATA_A710_2371105
+ mov x0, x18
+ bl errata_a710_2371105_wa
+#endif
+
#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
/*
* The Cortex-A710 generic vectors are overridden to apply errata
- * mitigation on exception entry from lower ELs.
- */
+ * mitigation on exception entry from lower ELs.
+ */
adr x0, wa_cve_vbar_cortex_a710
msr vbar_el3, x0
#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
diff --git a/lib/cpus/aarch64/cortex_makalu.S b/lib/cpus/aarch64/cortex_a715.S
similarity index 67%
rename from lib/cpus/aarch64/cortex_makalu.S
rename to lib/cpus/aarch64/cortex_a715.S
index 98c7d6d..7603210 100644
--- a/lib/cpus/aarch64/cortex_makalu.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,7 @@
#include <cortex_makalu.h>
#include <cpu_macros.S>
#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
/* Hardware handled coherency */
#if HW_ASSISTED_COHERENCY == 0
@@ -21,9 +22,32 @@
#error "Cortex Makalu supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
+#if WORKAROUND_CVE_2022_23960
+ wa_cve_2022_23960_bhb_vector_table CORTEX_MAKALU_BHB_LOOP_COUNT, cortex_makalu
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov x0, #ERRATA_APPLIES
+#else
+ mov x0, #ERRATA_MISSING
+#endif
+ ret
+endfunc check_errata_cve_2022_23960
+
func cortex_makalu_reset_func
/* Disable speculative loads */
msr SSBS, xzr
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+ /*
+ * The Cortex Makalu generic vectors are overridden to apply errata
+ * mitigation on exception entry from lower ELs.
+ */
+ adr x0, wa_cve_vbar_cortex_makalu
+ msr vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
isb
ret
endfunc cortex_makalu_reset_func
@@ -49,6 +73,18 @@
* Errata printing function for Cortex Makalu. Must follow AAPCS.
*/
func cortex_makalu_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata WORKAROUND_CVE_2022_23960, cortex_makalu, cve_2022_23960
+
+ ldp x8, x30, [sp], #16
ret
endfunc cortex_makalu_errata_report
#endif
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 50bd8cd..6d4017a 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -17,6 +17,9 @@
#if HW_ASSISTED_COHERENCY == 0
#error "Cortex-A76 must be compiled with HW_ASSISTED_COHERENCY enabled"
#endif
+ .globl cortex_a76_reset_func
+ .globl cortex_a76_core_pwr_dwn
+ .globl cortex_a76_disable_wa_cve_2018_3639
/* 64-bit only core */
#if CTX_INCLUDE_AARCH32_REGS == 1
diff --git a/lib/cpus/aarch64/cortex_a76ae.S b/lib/cpus/aarch64/cortex_a76ae.S
index 888f98b..5c19548 100644
--- a/lib/cpus/aarch64/cortex_a76ae.S
+++ b/lib/cpus/aarch64/cortex_a76ae.S
@@ -1,12 +1,15 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arch.h>
#include <asm_macros.S>
+#include <common/bl_common.h>
#include <cortex_a76ae.h>
#include <cpu_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
/* Hardware handled coherency */
#if HW_ASSISTED_COHERENCY == 0
@@ -18,14 +21,46 @@
#error "Cortex-A76AE supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
- /* ---------------------------------------------
+#if WORKAROUND_CVE_2022_23960
+ wa_cve_2022_23960_bhb_vector_table CORTEX_A76AE_BHB_LOOP_COUNT, cortex_a76ae
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov x0, #ERRATA_APPLIES
+#else
+ mov x0, #ERRATA_MISSING
+#endif /* WORKAROUND_CVE_2022_23960 */
+ ret
+endfunc check_errata_cve_2022_23960
+
+ /* --------------------------------------------
+ * The CPU Ops reset function for Cortex-A76AE.
+ * Shall clobber: x0-x19
+ * --------------------------------------------
+ */
+func cortex_a76ae_reset_func
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+ /*
+ * The Cortex-A76ae generic vectors are overridden to apply errata
+ * mitigation on exception entry from lower ELs.
+ */
+ adr x0, wa_cve_vbar_cortex_a76ae
+ msr vbar_el3, x0
+ isb
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
+ ret
+endfunc cortex_a76ae_reset_func
+
+ /* ----------------------------------------------------
* HW will do the cache maintenance while powering down
- * ---------------------------------------------
+ * ----------------------------------------------------
*/
func cortex_a76ae_core_pwr_dwn
- /* ---------------------------------------------
+ /* ---------------------------------------------------
* Enable CPU power down bit in power control register
- * ---------------------------------------------
+ * ---------------------------------------------------
*/
mrs x0, CORTEX_A76AE_CPUPWRCTLR_EL1
orr x0, x0, #CORTEX_A76AE_CORE_PWRDN_EN_MASK
@@ -39,6 +74,18 @@
* Errata printing function for Cortex-A76AE. Must follow AAPCS.
*/
func cortex_a76ae_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata WORKAROUND_CVE_2022_23960, cortex_a76ae, cve_2022_23960
+
+ ldp x8, x30, [sp], #16
ret
endfunc cortex_a76ae_errata_report
#endif /* REPORT_ERRATA */
@@ -62,5 +109,5 @@
ret
endfunc cortex_a76ae_cpu_reg_dump
-declare_cpu_ops cortex_a76ae, CORTEX_A76AE_MIDR, CPU_NO_RESET_FUNC, \
+declare_cpu_ops cortex_a76ae, CORTEX_A76AE_MIDR, cortex_a76ae_reset_func, \
cortex_a76ae_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index e7365e2..aa66e94 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -199,6 +199,34 @@
b cpu_rev_var_ls
endfunc check_errata_1791578
+ /* --------------------------------------------------
+ * Errata Workaround for Cortex A77 Errata #2356587.
+ * This applies to revisions r0p0, r1p0, and r1p1 and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a77_2356587_wa
+ /* Check workaround compatibility. */
+ mov x17, x30
+ bl check_errata_2356587
+ cbz x0, 1f
+
+ /* Set bit 0 in ACTLR2_EL1 */
+ mrs x1, CORTEX_A77_ACTLR2_EL1
+ orr x1, x1, #CORTEX_A77_ACTLR2_EL1_BIT_0
+ msr CORTEX_A77_ACTLR2_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_a77_2356587_wa
+
+func check_errata_2356587
+ /* Applies to r0p0, r1p0, and r1p1 right now */
+ mov x1, #0x11
+ b cpu_rev_var_ls
+endfunc check_errata_2356587
+
func check_errata_cve_2022_23960
#if WORKAROUND_CVE_2022_23960
mov x0, #ERRATA_APPLIES
@@ -238,6 +266,11 @@
bl errata_a77_1791578_wa
#endif
+#if ERRATA_A77_2356587
+ mov x0, x18
+ bl errata_a77_2356587_wa
+#endif
+
#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
/*
* The Cortex-A77 generic vectors are overridden to apply errata
@@ -285,6 +318,7 @@
report_errata ERRATA_A77_1925769, cortex_a77, 1925769
report_errata ERRATA_A77_1946167, cortex_a77, 1946167
report_errata ERRATA_A77_1791578, cortex_a77, 1791578
+ report_errata ERRATA_A77_2356587, cortex_a77, 2356587
report_errata WORKAROUND_CVE_2022_23960, cortex_a77, cve_2022_23960
ldp x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 1a6f848..dd3487a 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -17,6 +17,9 @@
#error "cortex_a78 must be compiled with HW_ASSISTED_COHERENCY enabled"
#endif
+.globl cortex_a78_reset_func
+.globl cortex_a78_core_pwr_dwn
+
#if WORKAROUND_CVE_2022_23960
wa_cve_2022_23960_bhb_vector_table CORTEX_A78_BHB_LOOP_COUNT, cortex_a78
#endif /* WORKAROUND_CVE_2022_23960 */
@@ -267,6 +270,62 @@
b cpu_rev_var_range
endfunc check_errata_2242635
+/* --------------------------------------------------
+ * Errata Workaround for Cortex A78 Errata 2376745.
+ * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
+ * It is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_a78_2376745_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2376745
+ cbz x0, 1f
+
+ /* Apply the workaround. */
+ mrs x1, CORTEX_A78_ACTLR2_EL1
+ orr x1, x1, #BIT(0)
+ msr CORTEX_A78_ACTLR2_EL1, x1
+1:
+ ret x17
+endfunc errata_a78_2376745_wa
+
+func check_errata_2376745
+ /* Applies to r0p0, r0p1, r1p1, and r1p2 */
+ mov x1, #CPU_REV(1, 2)
+ b cpu_rev_var_ls
+endfunc check_errata_2376745
+
+/* --------------------------------------------------
+ * Errata Workaround for Cortex A78 Errata 2395406.
+ * This applies to revisions r0p0, r1p0, r1p1, and r1p2.
+ * It is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_a78_2395406_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2395406
+ cbz x0, 1f
+
+ /* Apply the workaround. */
+ mrs x1, CORTEX_A78_ACTLR2_EL1
+ orr x1, x1, #BIT(40)
+ msr CORTEX_A78_ACTLR2_EL1, x1
+1:
+ ret x17
+endfunc errata_a78_2395406_wa
+
+func check_errata_2395406
+ /* Applies to r0p0, r0p1, r1p1, and r1p2 */
+ mov x1, #CPU_REV(1, 2)
+ b cpu_rev_var_ls
+endfunc check_errata_2395406
+
func check_errata_cve_2022_23960
#if WORKAROUND_CVE_2022_23960
mov x0, #ERRATA_APPLIES
@@ -320,6 +379,16 @@
bl errata_a78_2242635_wa
#endif
+#if ERRATA_A78_2376745
+ mov x0, x18
+ bl errata_a78_2376745_wa
+#endif
+
+#if ERRATA_A78_2395406
+ mov x0, x18
+ bl errata_a78_2395406_wa
+#endif
+
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, actlr_el3
@@ -390,6 +459,8 @@
report_errata ERRATA_A78_1952683, cortex_a78, 1952683
report_errata ERRATA_A78_2132060, cortex_a78, 2132060
report_errata ERRATA_A78_2242635, cortex_a78, 2242635
+ report_errata ERRATA_A78_2376745, cortex_a78, 2376745
+ report_errata ERRATA_A78_2395406, cortex_a78, 2395406
report_errata WORKAROUND_CVE_2022_23960, cortex_a78, cve_2022_23960
ldp x8, x30, [sp], #16
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index 421c174..27adc38 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
- * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,12 +11,17 @@
#include <cortex_a78_ae.h>
#include <cpu_macros.S>
#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
/* Hardware handled coherency */
#if HW_ASSISTED_COHERENCY == 0
#error "cortex_a78_ae must be compiled with HW_ASSISTED_COHERENCY enabled"
#endif
+#if WORKAROUND_CVE_2022_23960
+ wa_cve_2022_23960_bhb_vector_table CORTEX_A78_AE_BHB_LOOP_COUNT, cortex_a78_ae
+#endif /* WORKAROUND_CVE_2022_23960 */
+
/* --------------------------------------------------
* Errata Workaround for A78 AE Erratum 1941500.
* This applies to revisions r0p0 and r0p1 of A78 AE.
@@ -99,6 +104,87 @@
b cpu_rev_var_range
endfunc check_errata_1951502
+/* --------------------------------------------------
+ * Errata Workaround for A78 AE Erratum 2376748.
+ * This applies to revisions r0p0 and r0p1 of A78 AE.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78_ae_2376748_wa
+ /* Compare x0 against revisions r0p0 - r0p1 */
+ mov x17, x30
+ bl check_errata_2376748
+ cbz x0, 1f
+
+ /* -------------------------------------------------------
+ * Set CPUACTLR2_EL1[0] to 1 to force PLDW/PFRM ST to
+ * behave like PLD/PRFM LD and not cause invalidations to
+ * other PE caches. There might be a small performance
+ * degradation to this workaround for certain workloads
+ * that share data.
+ * -------------------------------------------------------
+ */
+ mrs x0, CORTEX_A78_AE_ACTLR2_EL1
+ orr x0, x0, #CORTEX_A78_AE_ACTLR2_EL1_BIT_0
+ msr CORTEX_A78_AE_ACTLR2_EL1, x0
+ isb
+1:
+ ret x17
+endfunc errata_a78_ae_2376748_wa
+
+func check_errata_2376748
+ /* Applies to revisions r0p0 and r0p1. */
+ mov x1, #CPU_REV(0, 0)
+ mov x2, #CPU_REV(0, 1)
+ b cpu_rev_var_range
+endfunc check_errata_2376748
+
+/* --------------------------------------------------
+ * Errata Workaround for A78 AE Erratum 2395408.
+ * This applies to revisions r0p0 and r0p1 of A78 AE.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78_ae_2395408_wa
+ /* Compare x0 against revisions r0p0 - r0p1 */
+ mov x17, x30
+ bl check_errata_2395408
+ cbz x0, 1f
+
+ /* --------------------------------------------------------
+ * Disable folding of demand requests into older prefetches
+ * with L2 miss requests outstanding by setting the
+ * CPUACTLR2_EL1[40] to 1.
+ * --------------------------------------------------------
+ */
+ mrs x0, CORTEX_A78_AE_ACTLR2_EL1
+ orr x0, x0, #CORTEX_A78_AE_ACTLR2_EL1_BIT_40
+ msr CORTEX_A78_AE_ACTLR2_EL1, x0
+ isb
+1:
+ ret x17
+endfunc errata_a78_ae_2395408_wa
+
+func check_errata_2395408
+ /* Applies to revisions r0p0 and r0p1. */
+ mov x1, #CPU_REV(0, 0)
+ mov x2, #CPU_REV(0, 1)
+ b cpu_rev_var_range
+endfunc check_errata_2395408
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov x0, #ERRATA_APPLIES
+#else
+ mov x0, #ERRATA_MISSING
+#endif
+ ret
+endfunc check_errata_cve_2022_23960
+
/* -------------------------------------------------
* The CPU Ops reset function for Cortex-A78-AE
* -------------------------------------------------
@@ -118,6 +204,16 @@
bl errata_a78_ae_1951502_wa
#endif
+#if ERRATA_A78_AE_2376748
+ mov x0, x18
+ bl errata_a78_ae_2376748_wa
+#endif
+
+#if ERRATA_A78_AE_2395408
+ mov x0, x18
+ bl errata_a78_ae_2395408_wa
+#endif
+
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, actlr_el3
@@ -138,8 +234,16 @@
msr CPUAMCNTENSET1_EL0, x0
#endif
- isb
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+ /*
+ * The Cortex-A78AE generic vectors are overridden to apply errata
+ * mitigation on exception entry from lower ELs.
+ */
+ adr x0, wa_cve_vbar_cortex_a78_ae
+ msr vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+ isb
ret x19
endfunc cortex_a78_ae_reset_func
@@ -175,6 +279,9 @@
*/
report_errata ERRATA_A78_AE_1941500, cortex_a78_ae, 1941500
report_errata ERRATA_A78_AE_1951502, cortex_a78_ae, 1951502
+ report_errata ERRATA_A78_AE_2376748, cortex_a78_ae, 2376748
+ report_errata ERRATA_A78_AE_2395408, cortex_a78_ae, 2395408
+ report_errata WORKAROUND_CVE_2022_23960, cortex_a78_ae, cve_2022_23960
ldp x8, x30, [sp], #16
ret
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 1b170fe..49cebfe 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,12 +10,199 @@
#include <cortex_a78c.h>
#include <cpu_macros.S>
#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
/* Hardware handled coherency */
#if HW_ASSISTED_COHERENCY == 0
#error "cortex_a78c must be compiled with HW_ASSISTED_COHERENCY enabled"
#endif
+/* --------------------------------------------------
+ * Errata Workaround for Cortex A78C Erratum 2376749.
+ * This applies to revision r0p1 and r0p2 of the A78C
+ * and is currently open. It is a Cat B erratum.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x4, x17
+ * --------------------------------------------------
+ */
+func errata_a78c_2376749_wa
+ /* Check revision */
+ mov x17, x30
+ bl check_errata_2376749
+ cbz x0, 1f
+ /* Set CPUACTLR2_EL1[0] to 1. */
+ mrs x1, CORTEX_A78C_CPUACTLR2_EL1
+ orr x1, x1, #CORTEX_A78C_CPUACTLR2_EL1_BIT_0
+ msr CORTEX_A78C_CPUACTLR2_EL1, x1
+1:
+ ret x17
+endfunc errata_a78c_2376749_wa
+
+func check_errata_2376749
+ /* Applies to r0p1 and r0p2*/
+ mov x1, #0x01
+ mov x2, #0x02
+ b cpu_rev_var_range
+endfunc check_errata_2376749
+
+/* --------------------------------------------------
+ * Errata Workaround for Cortex A78C Erratum 2395411.
+ * This applies to revision r0p1 and r0p2 of the A78C
+ * and is currently open. It is a Cat B erratum.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x4, x17
+ * --------------------------------------------------
+ */
+func errata_a78c_2395411_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2395411
+ cbz x0, 1f
+
+ /* Set CPUACTRL2_EL1[40] to 1. */
+ mrs x1, CORTEX_A78C_CPUACTLR2_EL1
+ orr x1, x1, #CORTEX_A78C_CPUACTLR2_EL1_BIT_40
+ msr CORTEX_A78C_CPUACTLR2_EL1, x1
+1:
+ ret x17
+endfunc errata_a78c_2395411_wa
+
+func check_errata_2395411
+ /* Applies to r0p1 and r0p2 */
+ mov x1, #0x01
+ mov x2, #0x02
+ b cpu_rev_var_range
+endfunc check_errata_2395411
+
+#if WORKAROUND_CVE_2022_23960
+ wa_cve_2022_23960_bhb_vector_table CORTEX_A78C_BHB_LOOP_COUNT, cortex_a78c
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+/* --------------------------------------------------
+ * Errata Workaround for A78C Erratum 2132064.
+ * This applies to revisions r0p1 and r0p2 of A78C
+ * and is still open.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78c_2132064_wa
+ /* Compare x0 against revisions r0p0 - r0p1 */
+ mov x17, x30
+ bl check_errata_2132064
+ cbz x0, 1f
+
+ /* --------------------------------------------------------
+ * Place the data prefetcher in the most conservative mode
+ * to reduce prefetches by writing the following bits to
+ * the value indicated: ecltr[7:6], PF_MODE = 2'b11
+ * --------------------------------------------------------
+ */
+ mrs x0, CORTEX_A78C_CPUECTLR_EL1
+ orr x0, x0, #CORTEX_A78C_CPUECTLR_EL1_BIT_6
+ orr x0, x0, #CORTEX_A78C_CPUECTLR_EL1_BIT_7
+ msr CORTEX_A78C_CPUECTLR_EL1, x0
+ isb
+1:
+ ret x17
+endfunc errata_a78c_2132064_wa
+
+func check_errata_2132064
+ /* Applies to revisions r0p1 and r0p2. */
+ mov x1, #CPU_REV(0, 1)
+ mov x2, #CPU_REV(0, 2)
+ b cpu_rev_var_range
+endfunc check_errata_2132064
+
+/* --------------------------------------------------------------------
+ * Errata Workaround for A78C Erratum 2242638.
+ * This applies to revisions r0p1 and r0p2 of the Cortex A78C
+ * processor and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------------------------
+ */
+func errata_a78c_2242638_wa
+ /* Compare x0 against revisions r0p1 - r0p2 */
+ mov x17, x30
+ bl check_errata_2242638
+ cbz x0, 1f
+
+ ldr x0, =0x5
+ msr CORTEX_A78C_IMP_CPUPSELR_EL3, x0
+ ldr x0, =0x10F600E000
+ msr CORTEX_A78C_IMP_CPUPOR_EL3, x0
+ ldr x0, =0x10FF80E000
+ msr CORTEX_A78C_IMP_CPUPMR_EL3, x0
+ ldr x0, =0x80000000003FF
+ msr CORTEX_A78C_IMP_CPUPCR_EL3, x0
+
+ isb
+1:
+ ret x17
+endfunc errata_a78c_2242638_wa
+
+func check_errata_2242638
+ /* Applies to revisions r0p1-r0p2. */
+ mov x1, #CPU_REV(0, 1)
+ mov x2, #CPU_REV(0, 2)
+ b cpu_rev_var_range
+endfunc check_errata_2242638
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov x0, #ERRATA_APPLIES
+#else
+ mov x0, #ERRATA_MISSING
+#endif
+ ret
+endfunc check_errata_cve_2022_23960
+
+ /* -------------------------------------------------
+ * The CPU Ops reset function for Cortex-A78C
+ * -------------------------------------------------
+ */
+func cortex_a78c_reset_func
+ mov x19, x30
+ bl cpu_get_rev_var
+ mov x18, x0
+
+#if ERRATA_A78C_2132064
+ mov x0, x18
+ bl errata_a78c_2132064_wa
+#endif
+
+#if ERRATA_A78C_2242638
+ mov x0, x18
+ bl errata_a78c_2242638_wa
+#endif
+
+#if ERRATA_A78C_2376749
+ mov x0, x18
+ bl errata_a78c_2376749_wa
+#endif
+
+#if ERRATA_A78C_2395411
+ mov x0, x18
+ bl errata_a78c_2395411_wa
+#endif
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+ /*
+ * The Cortex-A78c generic vectors are overridden to apply errata
+ * mitigation on exception entry from lower ELs.
+ */
+ adr x0, wa_cve_vbar_cortex_a78c
+ msr vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
+ isb
+ ret x19
+endfunc cortex_a78c_reset_func
+
/* ----------------------------------------------------
* HW will do the cache maintenance while powering down
* ----------------------------------------------------
@@ -37,6 +224,22 @@
* Errata printing function for Cortex A78C. Must follow AAPCS.
*/
func cortex_a78c_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata ERRATA_A78C_2132064, cortex_a78c, 2132064
+ report_errata ERRATA_A78C_2242638, cortex_a78c, 2242638
+ report_errata ERRATA_A78C_2376749, cortex_a78c, 2376749
+ report_errata ERRATA_A78C_2395411, cortex_a78c, 2395411
+ report_errata WORKAROUND_CVE_2022_23960, cortex_a78c, cve_2022_23960
+
+ ldp x8, x30, [sp], #16
ret
endfunc cortex_a78c_errata_report
#endif
@@ -61,5 +264,5 @@
endfunc cortex_a78c_cpu_reg_dump
declare_cpu_ops cortex_a78c, CORTEX_A78C_MIDR, \
- CPU_NO_RESET_FUNC, \
+ cortex_a78c_reset_func, \
cortex_a78c_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_hunter.S b/lib/cpus/aarch64/cortex_hunter.S
index 2ab4296..973637e 100644
--- a/lib/cpus/aarch64/cortex_hunter.S
+++ b/lib/cpus/aarch64/cortex_hunter.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,7 @@
#include <cortex_hunter.h>
#include <cpu_macros.S>
#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
/* Hardware handled coherency */
#if HW_ASSISTED_COHERENCY == 0
@@ -21,9 +22,32 @@
#error "Cortex Hunter supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
+#if WORKAROUND_CVE_2022_23960
+ wa_cve_2022_23960_bhb_vector_table CORTEX_HUNTER_BHB_LOOP_COUNT, cortex_hunter
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov x0, #ERRATA_APPLIES
+#else
+ mov x0, #ERRATA_MISSING
+#endif
+ ret
+endfunc check_errata_cve_2022_23960
+
func cortex_hunter_reset_func
/* Disable speculative loads */
msr SSBS, xzr
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+ /*
+ * The Cortex Hunter generic vectors are overridden to apply errata
+ * mitigation on exception entry from lower ELs.
+ */
+ adr x0, wa_cve_vbar_cortex_hunter
+ msr vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
isb
ret
endfunc cortex_hunter_reset_func
@@ -49,6 +73,18 @@
* Errata printing function for Cortex Hunter. Must follow AAPCS.
*/
func cortex_hunter_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata WORKAROUND_CVE_2022_23960, cortex_hunter, cve_2022_23960
+
+ ldp x8, x30, [sp], #16
ret
endfunc cortex_hunter_errata_report
#endif
diff --git a/lib/cpus/aarch64/cortex_x1.S b/lib/cpus/aarch64/cortex_x1.S
new file mode 100644
index 0000000..9a7f666
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_x1.S
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2022, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <cortex_x1.h>
+#include <cpu_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-X1 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-X1 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+#if WORKAROUND_CVE_2022_23960
+ wa_cve_2022_23960_bhb_vector_table CORTEX_X1_BHB_LOOP_COUNT, cortex_x1
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+/* --------------------------------------------------
+ * Errata Workaround for X1 Erratum 1821534.
+ * This applies to revision r0p0 and r1p0 of X1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_x1_1821534_wa
+ /* Compare x0 against revision r1p0 */
+ mov x17, x30
+ bl check_errata_1821534
+ cbz x0, 1f
+ mrs x1, CORTEX_X1_ACTLR2_EL1
+ orr x1, x1, BIT(2)
+ msr CORTEX_X1_ACTLR2_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_x1_1821534_wa
+
+func check_errata_1821534
+ /* Applies to r0p0 and r1p0 */
+ mov x1, #0x10
+ b cpu_rev_var_ls
+endfunc check_errata_1821534
+
+/* --------------------------------------------------
+ * Errata Workaround for X1 Erratum 1688305.
+ * This applies to revision r0p0 and r1p0 of X1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_x1_1688305_wa
+ /* Compare x0 against revision r1p0 */
+ mov x17, x30
+ bl check_errata_1688305
+ cbz x0, 1f
+ mrs x0, CORTEX_X1_ACTLR2_EL1
+ orr x0, x0, BIT(1)
+ msr CORTEX_X1_ACTLR2_EL1, x0
+ isb
+
+1:
+ ret x17
+endfunc errata_x1_1688305_wa
+
+func check_errata_1688305
+ /* Applies to r0p0 and r1p0 */
+ mov x1, #0x10
+ b cpu_rev_var_ls
+endfunc check_errata_1688305
+
+/* --------------------------------------------------
+ * Errata Workaround for X1 Erratum 1827429.
+ * This applies to revision r0p0 and r1p0 of X1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_x1_1827429_wa
+ /* Compare x0 against revision r1p0 */
+ mov x17, x30
+ bl check_errata_1827429
+ cbz x0, 1f
+ mrs x0, CORTEX_X1_CPUECTLR_EL1
+ orr x0, x0, BIT(53)
+ msr CORTEX_X1_CPUECTLR_EL1, x0
+ isb
+
+1:
+ ret x17
+endfunc errata_x1_1827429_wa
+
+func check_errata_1827429
+ /* Applies to r0p0 and r1p0 */
+ mov x1, #0x10
+ b cpu_rev_var_ls
+endfunc check_errata_1827429
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov x0, #ERRATA_APPLIES
+#else
+ mov x0, #ERRATA_MISSING
+#endif
+ ret
+endfunc check_errata_cve_2022_23960
+
+ /* -------------------------------------------------
+ * The CPU Ops reset function for Cortex-X1.
+ * Shall clobber: x0-x19
+ * -------------------------------------------------
+ */
+func cortex_x1_reset_func
+ mov x19, x30
+ bl cpu_get_rev_var
+ mov x18, x0
+
+#if ERRATA_X1_1821534
+ mov x0, x18
+ bl errata_x1_1821534_wa
+#endif
+
+#if ERRATA_X1_1688305
+ mov x0, x18
+ bl errata_x1_1688305_wa
+#endif
+
+#if ERRATA_X1_1827429
+ mov x0, x18
+ bl errata_x1_1827429_wa
+#endif
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+ /*
+ * The Cortex-X1 generic vectors are overridden to apply errata
+ * mitigation on exception entry from lower ELs.
+ */
+ adr x0, wa_cve_vbar_cortex_x1
+ msr vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
+ isb
+ ret x19
+endfunc cortex_x1_reset_func
+
+ /* ---------------------------------------------
+ * HW will do the cache maintenance while powering down
+ * ---------------------------------------------
+ */
+func cortex_x1_core_pwr_dwn
+ /* ---------------------------------------------
+ * Enable CPU power down bit in power control register
+ * ---------------------------------------------
+ */
+ mrs x0, CORTEX_X1_CPUPWRCTLR_EL1
+ orr x0, x0, #CORTEX_X1_CORE_PWRDN_EN_MASK
+ msr CORTEX_X1_CPUPWRCTLR_EL1, x0
+ isb
+ ret
+endfunc cortex_x1_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex X1. Must follow AAPCS.
+ */
+func cortex_x1_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata ERRATA_X1_1821534, cortex_x1, 1821534
+ report_errata ERRATA_X1_1688305, cortex_x1, 1688305
+ report_errata ERRATA_X1_1827429, cortex_x1, 1827429
+ report_errata WORKAROUND_CVE_2022_23960, cortex_x1, cve_2022_23960
+
+ ldp x8, x30, [sp], #16
+ ret
+endfunc cortex_x1_errata_report
+#endif
+
+ /* ---------------------------------------------
+ * This function provides Cortex X1 specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ascii and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.cortex_x1_regs, "aS"
+cortex_x1_regs: /* The ascii list of register names to be reported */
+ .asciz "cpuectlr_el1", ""
+
+func cortex_x1_cpu_reg_dump
+ adr x6, cortex_x1_regs
+ mrs x8, CORTEX_X1_CPUECTLR_EL1
+ ret
+endfunc cortex_x1_cpu_reg_dump
+
+declare_cpu_ops cortex_x1, CORTEX_X1_MIDR, \
+ cortex_x1_reset_func, \
+ cortex_x1_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 9586a5b..c810be6 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -237,6 +237,64 @@
ret
endfunc check_errata_cve_2022_23960
+ /* ---------------------------------------------------------
+ * Errata Workaround for Cortex-X2 Errata 2147715.
+ * This applies only to revisions r2p0 and is fixed in r2p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0, x1, x17
+ * ---------------------------------------------------------
+ */
+func errata_x2_2147715_wa
+ /* Compare x0 against revision r2p0 */
+ mov x17, x30
+ bl check_errata_2147715
+ cbz x0, 1f
+
+ /* Apply the workaround by setting bit 22 in CPUACTLR_EL1. */
+ mrs x1, CORTEX_X2_CPUACTLR_EL1
+ orr x1, x1, CORTEX_X2_CPUACTLR_EL1_BIT_22
+ msr CORTEX_X2_CPUACTLR_EL1, x1
+
+1:
+ ret x17
+endfunc errata_x2_2147715_wa
+
+func check_errata_2147715
+ /* Applies to r2p0 */
+ mov x1, #0x20
+ mov x2, #0x20
+ b cpu_rev_var_range
+endfunc check_errata_2147715
+
+/* -------------------------------------------------------
+ * Errata Workaround for Cortex-X2 Erratum 2371105.
+ * This applies to revisions <= r2p0 and is fixed in r2p1.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * -------------------------------------------------------
+ */
+func errata_x2_2371105_wa
+ /* Check workaround compatibility. */
+ mov x17, x30
+ bl check_errata_2371105
+ cbz x0, 1f
+
+ /* Set bit 40 in CPUACTLR2_EL1 */
+ mrs x1, CORTEX_X2_CPUACTLR2_EL1
+ orr x1, x1, #CORTEX_X2_CPUACTLR2_EL1_BIT_40
+ msr CORTEX_X2_CPUACTLR2_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_x2_2371105_wa
+
+func check_errata_2371105
+ /* Applies to <= r2p0. */
+ mov x1, #0x20
+ b cpu_rev_var_ls
+endfunc check_errata_2371105
+
/* ----------------------------------------------------
* HW will do the cache maintenance while powering down
* ----------------------------------------------------
@@ -268,12 +326,15 @@
* checking functions of each errata.
*/
report_errata ERRATA_X2_2002765, cortex_x2, 2002765
- report_errata ERRATA_X2_2058056, cortex_x2, 2058056
- report_errata ERRATA_X2_2083908, cortex_x2, 2083908
report_errata ERRATA_X2_2017096, cortex_x2, 2017096
+ report_errata ERRATA_X2_2058056, cortex_x2, 2058056
report_errata ERRATA_X2_2081180, cortex_x2, 2081180
+ report_errata ERRATA_X2_2083908, cortex_x2, 2083908
+ report_errata ERRATA_X2_2147715, cortex_x2, 2147715
report_errata ERRATA_X2_2216384, cortex_x2, 2216384
+ report_errata ERRATA_X2_2371105, cortex_x2, 2371105
report_errata WORKAROUND_CVE_2022_23960, cortex_x2, cve_2022_23960
+ report_errata ERRATA_DSU_2313941, cortex_x2, dsu_2313941
ldp x8, x30, [sp], #16
ret
@@ -285,12 +346,15 @@
/* Disable speculative loads */
msr SSBS, xzr
- isb
/* Get the CPU revision and stash it in x18. */
bl cpu_get_rev_var
mov x18, x0
+#if ERRATA_DSU_2313941
+ bl errata_dsu_2313941_wa
+#endif
+
#if ERRATA_X2_2002765
mov x0, x18
bl errata_cortex_x2_2002765_wa
@@ -321,6 +385,16 @@
bl errata_x2_2216384_wa
#endif
+#if ERRATA_X2_2147715
+ mov x0, x18
+ bl errata_x2_2147715_wa
+#endif
+
+#if ERRATA_X2_2371105
+ mov x0, x18
+ bl errata_x2_2371105_wa
+#endif
+
#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
/*
* The Cortex-X2 generic vectors are overridden to apply errata
@@ -331,7 +405,7 @@
#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
isb
- ret x19
+ ret x19
endfunc cortex_x2_reset_func
/* ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_makalu_elp_arm.S b/lib/cpus/aarch64/cortex_x3.S
similarity index 68%
rename from lib/cpus/aarch64/cortex_makalu_elp_arm.S
rename to lib/cpus/aarch64/cortex_x3.S
index fbbf205..f4d2df0 100644
--- a/lib/cpus/aarch64/cortex_makalu_elp_arm.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,7 @@
#include <cortex_makalu_elp_arm.h>
#include <cpu_macros.S>
#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
/* Hardware handled coherency */
#if HW_ASSISTED_COHERENCY == 0
@@ -21,6 +22,10 @@
#error "Cortex Makalu ELP supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
+#if WORKAROUND_CVE_2022_23960
+ wa_cve_2022_23960_bhb_vector_table CORTEX_MAKALU_ELP_ARM_BHB_LOOP_COUNT, cortex_makalu_elp_arm
+#endif /* WORKAROUND_CVE_2022_23960 */
+
/* ----------------------------------------------------
* HW will do the cache maintenance while powering down
* ----------------------------------------------------
@@ -37,22 +42,53 @@
ret
endfunc cortex_makalu_elp_arm_core_pwr_dwn
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex Makalu ELP. Must follow AAPCS.
- */
-func cortex_makalu_elp_arm_errata_report
- ret
-endfunc cortex_makalu_elp_arm_errata_report
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov x0, #ERRATA_APPLIES
+#else
+ mov x0, #ERRATA_MISSING
#endif
+ ret
+endfunc check_errata_cve_2022_23960
func cortex_makalu_elp_arm_reset_func
/* Disable speculative loads */
msr SSBS, xzr
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+ /*
+ * The Cortex Makalu ELP generic vectors are overridden to apply
+ * errata mitigation on exception entry from lower ELs.
+ */
+ adr x0, wa_cve_vbar_cortex_makalu_elp_arm
+ msr vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
isb
ret
endfunc cortex_makalu_elp_arm_reset_func
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex Makalu ELP. Must follow AAPCS.
+ */
+func cortex_makalu_elp_arm_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata WORKAROUND_CVE_2022_23960, cortex_makalu_elp_arm, cve_2022_23960
+
+ ldp x8, x30, [sp], #16
+ ret
+endfunc cortex_makalu_elp_arm_errata_report
+#endif
+
/* ---------------------------------------------
* This function provides Cortex Makalu ELP-
* specific register information for crash
diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S
index 224ee26..3c54a6f 100644
--- a/lib/cpus/aarch64/denver.S
+++ b/lib/cpus/aarch64/denver.S
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -369,6 +369,7 @@
denver_reset_func, \
check_errata_cve_2017_5715, \
CPU_NO_EXTRA2_FUNC, \
+ CPU_NO_EXTRA3_FUNC, \
denver_core_pwr_dwn, \
denver_cluster_pwr_dwn
.endm
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
index da052d5..419b6ea 100644
--- a/lib/cpus/aarch64/dsu_helpers.S
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -139,3 +139,57 @@
1:
ret x17
endfunc errata_dsu_936184_wa
+
+ /* -----------------------------------------------------------------------
+ * DSU erratum 2313941 check function
+ * Checks the DSU variant, revision and configuration to determine if
+ * the erratum applies. Erratum applies on all configurations of the
+ * DSU and if revision-variant is r0p0, r1p0, r2p0, r2p1, r3p0, r3p1.
+ *
+ * The erratum is still open.
+ *
+ * This function is called from both assembly and C environment. So it
+ * follows AAPCS.
+ *
+ * Clobbers: x0-x3
+ * -----------------------------------------------------------------------
+ */
+ .globl check_errata_dsu_2313941
+ .globl errata_dsu_2313941_wa
+
+func check_errata_dsu_2313941
+ mov x2, #ERRATA_APPLIES
+ mov x3, #ERRATA_NOT_APPLIES
+
+ /* Check if DSU version is less than or equal to r3p1 */
+ mrs x1, CLUSTERIDR_EL1
+
+ /* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
+ ubfx x0, x1, #CLUSTERIDR_REV_SHIFT,\
+ #(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
+ mov x1, #(0x31 << CLUSTERIDR_REV_SHIFT)
+ cmp x0, x1
+ csel x0, x2, x3, LS
+ ret
+endfunc check_errata_dsu_2313941
+
+ /* --------------------------------------------------
+ * Errata Workaround for DSU erratum #2313941.
+ *
+ * Can clobber only: x0-x17
+ * --------------------------------------------------
+ */
+func errata_dsu_2313941_wa
+ mov x17, x30
+ bl check_errata_dsu_2313941
+ cbz x0, 1f
+
+ /* If erratum applies, disable high-level clock gating */
+ mrs x0, CLUSTERACTLR_EL1
+ orr x0, x0, #CLUSTERACTLR_EL1_DISABLE_SCLK_GATING
+ msr CLUSTERACTLR_EL1, x0
+ isb
+1:
+ ret x17
+endfunc errata_dsu_2313941_wa
+
diff --git a/lib/cpus/aarch64/neoverse_demeter.S b/lib/cpus/aarch64/neoverse_demeter.S
index f43c18b..41cb4ee 100644
--- a/lib/cpus/aarch64/neoverse_demeter.S
+++ b/lib/cpus/aarch64/neoverse_demeter.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,7 @@
#include <neoverse_demeter.h>
#include <cpu_macros.S>
#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
/* Hardware handled coherency */
#if HW_ASSISTED_COHERENCY == 0
@@ -21,6 +22,10 @@
#error "Neoverse Demeter supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
+#if WORKAROUND_CVE_2022_23960
+ wa_cve_2022_23960_bhb_vector_table NEOVERSE_DEMETER_BHB_LOOP_COUNT, neoverse_demeter
+#endif /* WORKAROUND_CVE_2022_23960 */
+
/* ----------------------------------------------------
* HW will do the cache maintenance while powering down
* ----------------------------------------------------
@@ -37,22 +42,52 @@
ret
endfunc neoverse_demeter_core_pwr_dwn
-#if REPORT_ERRATA
-/*
- * Errata printing function for Neoverse Demeter. Must follow AAPCS.
- */
-func neoverse_demeter_errata_report
- ret
-endfunc neoverse_demeter_errata_report
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov x0, #ERRATA_APPLIES
+#else
+ mov x0, #ERRATA_MISSING
#endif
+ ret
+endfunc check_errata_cve_2022_23960
func neoverse_demeter_reset_func
/* Disable speculative loads */
msr SSBS, xzr
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+ /*
+ * The Neoverse Demeter vectors are overridden to apply
+ * errata mitigation on exception entry from lower ELs.
+ */
+ adr x0, wa_cve_vbar_neoverse_demeter
+ msr vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
isb
ret
endfunc neoverse_demeter_reset_func
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Neoverse Demeter. Must follow AAPCS.
+ */
+func neoverse_demeter_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata WORKAROUND_CVE_2022_23960, neoverse_demeter, cve_2022_23960
+
+ ldp x8, x30, [sp], #16
+ ret
+endfunc neoverse_demeter_errata_report
+#endif
+
/* ---------------------------------------------
* This function provides Neoverse Demeter-
* specific register information for crash
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index b93f2a6..a807b63 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -338,6 +338,68 @@
b cpu_rev_var_ls
endfunc check_errata_2280757
+
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2376738.
+ * This applies to revision r0p0 of Neoverse N2,
+ * fixed in r0p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current CPU.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2376738_wa
+ mov x17, x30
+ bl check_errata_2376738
+ cbz x0, 1f
+
+ /* Set CPUACTLR2_EL1[0] to 1 to force PLDW/PFRM
+ * ST to behave like PLD/PFRM LD and not cause
+ * invalidations to other PE caches.
+ */
+ mrs x1, NEOVERSE_N2_CPUACTLR2_EL1
+ orr x1, x1, NEOVERSE_N2_CPUACTLR2_EL1_BIT_0
+ msr NEOVERSE_N2_CPUACTLR2_EL1, x1
+1:
+ ret x17
+endfunc errata_n2_2376738_wa
+
+func check_errata_2376738
+ /* Applies to r0p0, fixed in r0p1 */
+ mov x1, 0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2376738
+
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N2 Erratum 2388450.
+ * This applies to revision r0p0 of Neoverse N2,
+ * fixed in r0p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x1, x17
+ * --------------------------------------------------
+ */
+func errata_n2_2388450_wa
+ /* Check revision. */
+ mov x17, x30
+ bl check_errata_2388450
+ cbz x0, 1f
+
+ /*Set bit 40 in ACTLR2_EL1 */
+ mrs x1, NEOVERSE_N2_CPUACTLR2_EL1
+ orr x1, x1, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_40
+ msr NEOVERSE_N2_CPUACTLR2_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_n2_2388450_wa
+
+func check_errata_2388450
+ /* Applies to r0p0, fixed in r0p1 */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_2388450
+
func check_errata_cve_2022_23960
#if WORKAROUND_CVE_2022_23960
mov x0, #ERRATA_APPLIES
@@ -367,6 +429,10 @@
orr x0, x0, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_2
msr NEOVERSE_N2_CPUACTLR2_EL1, x0
+#if ERRATA_DSU_2313941
+ bl errata_dsu_2313941_wa
+#endif
+
#if ERRATA_N2_2067956
mov x0, x18
bl errata_n2_2067956_wa
@@ -413,6 +479,16 @@
bl errata_n2_2280757_wa
#endif
+#if ERRATA_N2_2376738
+ mov x0, x18
+ bl errata_n2_2376738_wa
+#endif
+
+#if ERRATA_N2_2388450
+ mov x0, x18
+ bl errata_n2_2388450_wa
+#endif
+
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, cptr_el3
@@ -492,7 +568,10 @@
report_errata ERRATA_N2_2138958, neoverse_n2, 2138958
report_errata ERRATA_N2_2242400, neoverse_n2, 2242400
report_errata ERRATA_N2_2280757, neoverse_n2, 2280757
+ report_errata ERRATA_N2_2376738, neoverse_n2, 2376738
+ report_errata ERRATA_N2_2388450, neoverse_n2, 2388450
report_errata WORKAROUND_CVE_2022_23960, neoverse_n2, cve_2022_23960
+ report_errata ERRATA_DSU_2313941, neoverse_n2, dsu_2313941
ldp x8, x30, [sp], #16
ret
diff --git a/lib/cpus/aarch64/neoverse_poseidon.S b/lib/cpus/aarch64/neoverse_poseidon.S
index 43a93aa..030293d 100644
--- a/lib/cpus/aarch64/neoverse_poseidon.S
+++ b/lib/cpus/aarch64/neoverse_poseidon.S
@@ -10,6 +10,7 @@
#include <neoverse_poseidon.h>
#include <cpu_macros.S>
#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
/* Hardware handled coherency */
#if HW_ASSISTED_COHERENCY == 0
@@ -21,6 +22,10 @@
#error "Neoverse Poseidon supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
+#if WORKAROUND_CVE_2022_23960
+ wa_cve_2022_23960_bhb_vector_table NEOVERSE_POSEIDON_BHB_LOOP_COUNT, neoverse_poseidon
+#endif /* WORKAROUND_CVE_2022_23960 */
+
/* ---------------------------------------------
* HW will do the cache maintenance while powering down
* ---------------------------------------------
@@ -37,22 +42,53 @@
ret
endfunc neoverse_poseidon_core_pwr_dwn
-#if REPORT_ERRATA
- /*
- * Errata printing function for Neoverse Poseidon. Must follow AAPCS.
- */
-func neoverse_poseidon_errata_report
- ret
-endfunc neoverse_poseidon_errata_report
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov x0, #ERRATA_APPLIES
+#else
+ mov x0, #ERRATA_MISSING
#endif
+ ret
+endfunc check_errata_cve_2022_23960
func neoverse_poseidon_reset_func
/* Disable speculative loads */
msr SSBS, xzr
+
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+ /*
+ * The Neoverse Poseidon generic vectors are overridden to apply
+ * errata mitigation on exception entry from lower ELs.
+ */
+ adr x0, wa_cve_vbar_neoverse_poseidon
+ msr vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
isb
ret
endfunc neoverse_poseidon_reset_func
+#if REPORT_ERRATA
+ /*
+ * Errata printing function for Neoverse Poseidon. Must follow AAPCS.
+ */
+func neoverse_poseidon_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata WORKAROUND_CVE_2022_23960, neoverse_poseidon, cve_2022_23960
+
+ ldp x8, x30, [sp], #16
+ ret
+endfunc neoverse_poseidon_errata_report
+#endif
+
/* ---------------------------------------------
* This function provides Neoverse-Poseidon specific
* register information for crash reporting.
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 6adb3a8..109b725 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -27,6 +27,82 @@
#endif /* WORKAROUND_CVE_2022_23960 */
/* --------------------------------------------------
+ * Errata Workaround for Neoverse V1 Errata #1618635.
+ * This applies to revision r0p0 and is fixed in
+ * r1p0.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0, x17
+ * --------------------------------------------------
+ */
+func errata_neoverse_v1_1618635_wa
+ /* Check workaround compatibility. */
+ mov x17, x30
+ bl check_errata_1618635
+ cbz x0, 1f
+
+ /* Inserts a DMB SY before and after MRS PAR_EL1 */
+ ldr x0, =0x0
+ msr NEOVERSE_V1_CPUPSELR_EL3, x0
+ ldr x0, = 0xEE070F14
+ msr NEOVERSE_V1_CPUPOR_EL3, x0
+ ldr x0, = 0xFFFF0FFF
+ msr NEOVERSE_V1_CPUPMR_EL3, x0
+ ldr x0, =0x4005027FF
+ msr NEOVERSE_V1_CPUPCR_EL3, x0
+
+ /* Inserts a DMB SY before STREX imm offset */
+ ldr x0, =0x1
+ msr NEOVERSE_V1_CPUPSELR_EL3, x0
+ ldr x0, =0x00e8400000
+ msr NEOVERSE_V1_CPUPOR_EL3, x0
+ ldr x0, =0x00fff00000
+ msr NEOVERSE_V1_CPUPMR_EL3, x0
+ ldr x0, = 0x4001027FF
+ msr NEOVERSE_V1_CPUPCR_EL3, x0
+
+ /* Inserts a DMB SY before STREX[BHD}/STLEX* */
+ ldr x0, =0x2
+ msr NEOVERSE_V1_CPUPSELR_EL3, x0
+ ldr x0, =0x00e8c00040
+ msr NEOVERSE_V1_CPUPOR_EL3, x0
+ ldr x0, =0x00fff00040
+ msr NEOVERSE_V1_CPUPMR_EL3, x0
+ ldr x0, = 0x4001027FF
+ msr NEOVERSE_V1_CPUPCR_EL3, x0
+
+ /* Inserts a DMB SY after STREX imm offset */
+ ldr x0, =0x3
+ msr NEOVERSE_V1_CPUPSELR_EL3, x0
+ ldr x0, =0x00e8400000
+ msr NEOVERSE_V1_CPUPOR_EL3, x0
+ ldr x0, =0x00fff00000
+ msr NEOVERSE_V1_CPUPMR_EL3, x0
+ ldr x0, = 0x4004027FF
+ msr NEOVERSE_V1_CPUPCR_EL3, x0
+
+ /* Inserts a DMB SY after STREX[BHD}/STLEX* */
+ ldr x0, =0x4
+ msr NEOVERSE_V1_CPUPSELR_EL3, x0
+ ldr x0, =0x00e8c00040
+ msr NEOVERSE_V1_CPUPOR_EL3, x0
+ ldr x0, =0x00fff00040
+ msr NEOVERSE_V1_CPUPMR_EL3, x0
+ ldr x0, = 0x4004027FF
+ msr NEOVERSE_V1_CPUPCR_EL3, x0
+
+ /* Synchronize to enable patches */
+ isb
+1:
+ ret x17
+endfunc errata_neoverse_v1_1618635_wa
+
+func check_errata_1618635
+ /* Applies to revision r0p0. */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_1618635
+
+ /* --------------------------------------------------
* Errata Workaround for Neoverse V1 Errata #1774420.
* This applies to revisions r0p0 and r1p0, fixed in r1p1.
* x0: variant[4:7] and revision[0:3] of current cpu.
@@ -330,6 +406,62 @@
b cpu_rev_var_range
endfunc check_errata_2216392
+ /* -----------------------------------------------------------------
+ * Errata Workaround for Neoverse V1 Errata #2294912.
+ * This applies to revisions r0p0, r1p0, and r1p1 and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * -----------------------------------------------------------------
+ */
+func errata_neoverse_v1_2294912_wa
+ /* Check workaround compatibility. */
+ mov x17, x30
+ bl check_errata_2294912
+ cbz x0, 1f
+
+ /* Set bit 0 in ACTLR2_EL1 */
+ mrs x1, NEOVERSE_V1_ACTLR2_EL1
+ orr x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_0
+ msr NEOVERSE_V1_ACTLR2_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_neoverse_v1_2294912_wa
+
+func check_errata_2294912
+ /* Applies to r0p0, r1p0, and r1p1 right now */
+ mov x1, #0x11
+ b cpu_rev_var_ls
+endfunc check_errata_2294912
+
+ /* ---------------------------------------------------
+ * Errata Workaround for Neoverse V1 Errata #2372203.
+ * This applies to revisions <= r1p1 and is still open.
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * ----------------------------------------------------
+ */
+func errata_neoverse_v1_2372203_wa
+ /* Check workaround compatibility. */
+ mov x17, x30
+ bl check_errata_2372203
+ cbz x0, 1f
+
+ /* Set bit 40 in ACTLR2_EL1 */
+ mrs x1, NEOVERSE_V1_ACTLR2_EL1
+ orr x1, x1, #NEOVERSE_V1_ACTLR2_EL1_BIT_40
+ msr NEOVERSE_V1_ACTLR2_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_neoverse_v1_2372203_wa
+
+func check_errata_2372203
+ /* Applies to <= r1p1. */
+ mov x1, #0x11
+ b cpu_rev_var_ls
+endfunc check_errata_2372203
+
func check_errata_cve_2022_23960
#if WORKAROUND_CVE_2022_23960
mov x0, #ERRATA_APPLIES
@@ -369,6 +501,7 @@
* Report all errata. The revision-variant information is passed to
* checking functions of each errata.
*/
+ report_errata ERRATA_V1_1618635, neoverse_v1, 1618635
report_errata ERRATA_V1_1774420, neoverse_v1, 1774420
report_errata ERRATA_V1_1791573, neoverse_v1, 1791573
report_errata ERRATA_V1_1852267, neoverse_v1, 1852267
@@ -378,6 +511,8 @@
report_errata ERRATA_V1_2139242, neoverse_v1, 2139242
report_errata ERRATA_V1_2108267, neoverse_v1, 2108267
report_errata ERRATA_V1_2216392, neoverse_v1, 2216392
+ report_errata ERRATA_V1_2294912, neoverse_v1, 2294912
+ report_errata ERRATA_V1_2372203, neoverse_v1, 2372203
report_errata WORKAROUND_CVE_2022_23960, neoverse_v1, cve_2022_23960
ldp x8, x30, [sp], #16
@@ -392,6 +527,11 @@
msr SSBS, xzr
isb
+#if ERRATA_V1_1618635
+ mov x0, x18
+ bl errata_neoverse_v1_1618635_wa
+#endif
+
#if ERRATA_V1_1774420
mov x0, x18
bl errata_neoverse_v1_1774420_wa
@@ -437,6 +577,16 @@
bl errata_neoverse_v1_2216392_wa
#endif
+#if ERRATA_V1_2294912
+ mov x0, x18
+ bl errata_neoverse_v1_2294912_wa
+#endif
+
+#if ERRATA_V1_2372203
+ mov x0, x18
+ bl errata_neoverse_v1_2372203_wa
+#endif
+
#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
/*
* The Neoverse-V1 generic vectors are overridden to apply errata
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index c7630fb..08871f8 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1,6 +1,6 @@
#
-# Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
+# Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -303,6 +303,10 @@
# to revisions r0p0, r1p0, and r1p1, it is still open.
ERRATA_A77_1791578 ?=0
+# Flag to apply erratum 2356587 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, and r1p1, it is still open.
+ERRATA_A77_2356587 ?=0
+
# Flag to apply erratum 1688305 workaround during reset. This erratum applies
# to revisions r0p0 - r1p0 of the A78 cpu.
ERRATA_A78_1688305 ?=0
@@ -333,6 +337,14 @@
# present in r0p0 as well but there is no workaround for that revision.
ERRATA_A78_2242635 ?=0
+# Flag to apply erratum 2376745 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
+ERRATA_A78_2376745 ?=0
+
+# Flag to apply erratum 2395406 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
+ERRATA_A78_2395406 ?=0
+
# Flag to apply erratum 1941500 workaround during reset. This erratum applies
# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
ERRATA_A78_AE_1941500 ?=0
@@ -341,6 +353,42 @@
# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
ERRATA_A78_AE_1951502 ?=0
+# Flag to apply erratum 2376748 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
+ERRATA_A78_AE_2376748 ?=0
+
+# Flag to apply erratum 2395408 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
+ERRATA_A78_AE_2395408 ?=0
+
+# Flag to apply erratum 2132064 workaround during reset. This erratum applies
+# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
+ERRATA_A78C_2132064 ?=0
+
+# Flag to apply erratum 2242638 workaround during reset. This erratum applies
+# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
+ERRATA_A78C_2242638 ?=0
+
+# Flag to apply erratum 2376749 workaround during reset. This erratum applies
+# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
+ERRATA_A78C_2376749 ?=0
+
+# Flag to apply erratum 2395411 workaround during reset. This erratum applies
+# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
+ERRATA_A78C_2395411 ?=0
+
+# Flag to apply erratum 1821534 workaround during reset. This erratum applies
+# to revisions r0p0 - r1p0 of the X1 cpu and fixed in r1p1.
+ERRATA_X1_1821534 ?=0
+
+# Flag to apply erratum 1688305 workaround during reset. This erratum applies
+# to revisions r0p0 - r1p0 of the X1 cpu and fixed in r1p1.
+ERRATA_X1_1688305 ?=0
+
+# Flag to apply erratum 1827429 workaround during reset. This erratum applies
+# to revisions r0p0 - r1p0 of the X1 cpu and fixed in r1p1.
+ERRATA_X1_1827429 ?=0
+
# Flag to apply T32 CLREX workaround during reset. This erratum applies
# only to r0p0 and r1p0 of the Neoverse N1 cpu.
ERRATA_N1_1043202 ?=0
@@ -402,6 +450,10 @@
# to revisions r0p0 of the Neoverse-N2 cpu, it is still open.
ERRATA_N2_2002655 ?=0
+# Flag to apply erratum 1618635 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse V1 cpu and was fixed in the revision r1p0.
+ERRATA_V1_1618635 ?=0
+
# Flag to apply erratum 1774420 workaround during reset. This erratum applies
# to revisions r0p0 and r1p0 of the Neoverse V1 core, and was fixed in r1p1.
ERRATA_V1_1774420 ?=0
@@ -440,6 +492,14 @@
# issue exists in r0p0 as well but there is no workaround for that revision.
ERRATA_V1_2216392 ?=0
+# Flag to apply erratum 2294912 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
+ERRATA_V1_2294912 ?=0
+
+# Flag to apply erratum 2372203 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0 and r1p1 of the Neoverse V1 cpu and is still open.
+ERRATA_V1_2372203 ?=0
+
# Flag to apply erratum 1987031 workaround during reset. This erratum applies
# to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
ERRATA_A710_1987031 ?=0
@@ -472,10 +532,26 @@
# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
ERRATA_A710_2136059 ?=0
+# Flag to apply erratum 2147715 workaround during reset. This erratum applies
+# to revision r2p0 of the Cortex-A710 CPU and is fixed in revision r2p1.
+ERRATA_A710_2147715 ?=0
+
+# Flag to apply erratum 2216384 workaround during reset. This erratum applies
+# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
+ERRATA_A710_2216384 ?=0
+
# Flag to apply erratum 2282622 workaround during reset. This erratum applies
# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
ERRATA_A710_2282622 ?=0
+# Flag to apply erratum 2008768 workaround during reset. This erratum applies
+# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
+ERRATA_A710_2008768 ?=0
+
+# Flag to apply erratum 2371105 workaround during reset. This erratum applies
+# to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
+ERRATA_A710_2371105 ?=0
+
# Flag to apply erratum 2067956 workaround during reset. This erratum applies
# to revision r0p0 of the Neoverse N2 cpu and is still open.
ERRATA_N2_2067956 ?=0
@@ -512,6 +588,14 @@
# to revision r0p0 of the Neoverse N2 cpu and is still open.
ERRATA_N2_2280757 ?=0
+# Flag to apply erratum 2376738 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
+ERRATA_N2_2376738 ?=0
+
+# Flag to apply erratum 2388450 workaround during reset. This erratum applies
+# to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
+ERRATA_N2_2388450 ?=0
+
# Flag to apply erratum 2002765 workaround during reset. This erratum applies
# to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
ERRATA_X2_2002765 ?=0
@@ -539,6 +623,14 @@
# r2p1.
ERRATA_X2_2216384 ?=0
+# Flag to apply erratum 2147715 workaround during reset. This erratum applies
+# only to revision r2p0 of the Cortex-X2 cpu, it is fixed in r2p1.
+ERRATA_X2_2147715 ?=0
+
+# Flag to apply erratum 2371105 workaround during reset. This erratum applies
+# to revision r0p0, r1p0 and r2p0 of the Cortex-X2 cpu and is fixed in r2p1.
+ERRATA_X2_2371105 ?=0
+
# Flag to apply erratum 1922240 workaround during reset. This erratum applies
# to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
ERRATA_A510_1922240 ?=0
@@ -569,6 +661,15 @@
# to revisions r0p0, r0p1, r0p2, r0p3 and r1p0, and is fixed in r1p1.
ERRATA_A510_2172148 ?=0
+# Flag to apply erratum 2347730 workaround during reset. This erratum applies
+# to revisions r0p0, r0p1, r0p2, r0p3, r1p0 and r1p1 of the Cortex-A510 CPU,
+# and is fixed in r1p2.
+ERRATA_A510_2347730 ?=0
+
+# Flag to apply erratum 2371937 workaround during reset. This erratum applies
+# to revisions r0p0, r0p1, r0p2, r0p3, r1p0, and r1p1. It is fixed in r1p2.
+ERRATA_A510_2371937 ?=0
+
# Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
# Applying the workaround results in higher DSU power consumption on idle.
ERRATA_DSU_798953 ?=0
@@ -578,6 +679,11 @@
# higher DSU power consumption on idle.
ERRATA_DSU_936184 ?=0
+# Flag to apply DSU erratum 2313941. This erratum applies to DSUs revisions
+# r0p0, r1p0, r2p0, r2p1, r3p0, r3p1 and is still open. Applying the workaround
+# results in higher DSU power consumption on idle.
+ERRATA_DSU_2313941 ?=0
+
# Process ERRATA_A9_794073 flag
$(eval $(call assert_boolean,ERRATA_A9_794073))
$(eval $(call add_define,ERRATA_A9_794073))
@@ -802,6 +908,10 @@
$(eval $(call assert_boolean,ERRATA_A77_1791578))
$(eval $(call add_define,ERRATA_A77_1791578))
+# Process ERRATA_A77_2356587 flag
+$(eval $(call assert_boolean,ERRATA_A77_2356587))
+$(eval $(call add_define,ERRATA_A77_2356587))
+
# Process ERRATA_A78_1688305 flag
$(eval $(call assert_boolean,ERRATA_A78_1688305))
$(eval $(call add_define,ERRATA_A78_1688305))
@@ -830,6 +940,14 @@
$(eval $(call assert_boolean,ERRATA_A78_2242635))
$(eval $(call add_define,ERRATA_A78_2242635))
+# Process ERRATA_A78_2376745 flag
+$(eval $(call assert_boolean,ERRATA_A78_2376745))
+$(eval $(call add_define,ERRATA_A78_2376745))
+
+# Process ERRATA_A78_2395406 flag
+$(eval $(call assert_boolean,ERRATA_A78_2395406))
+$(eval $(call add_define,ERRATA_A78_2395406))
+
# Process ERRATA_A78_AE_1941500 flag
$(eval $(call assert_boolean,ERRATA_A78_AE_1941500))
$(eval $(call add_define,ERRATA_A78_AE_1941500))
@@ -838,6 +956,42 @@
$(eval $(call assert_boolean,ERRATA_A78_AE_1951502))
$(eval $(call add_define,ERRATA_A78_AE_1951502))
+# Process ERRATA_A78_AE_2376748 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_2376748))
+$(eval $(call add_define,ERRATA_A78_AE_2376748))
+
+# Process ERRATA_A78_AE_2395408 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_2395408))
+$(eval $(call add_define,ERRATA_A78_AE_2395408))
+
+# Process ERRATA_A78C_2132064 flag
+$(eval $(call assert_boolean,ERRATA_A78C_2132064))
+$(eval $(call add_define,ERRATA_A78C_2132064))
+
+# Process ERRATA_A78C_2242638 flag
+$(eval $(call assert_boolean,ERRATA_A78C_2242638))
+$(eval $(call add_define,ERRATA_A78C_2242638))
+
+# Process ERRATA_A78C_2376749 flag
+$(eval $(call assert_boolean,ERRATA_A78C_2376749))
+$(eval $(call add_define,ERRATA_A78C_2376749))
+
+# Process ERRATA_A78C_2395411 flag
+$(eval $(call assert_boolean,ERRATA_A78C_2395411))
+$(eval $(call add_define,ERRATA_A78C_2395411))
+
+# Process ERRATA_X1_1821534 flag
+$(eval $(call assert_boolean,ERRATA_X1_1821534))
+$(eval $(call add_define,ERRATA_X1_1821534))
+
+# Process ERRATA_X1_1688305 flag
+$(eval $(call assert_boolean,ERRATA_X1_1688305))
+$(eval $(call add_define,ERRATA_X1_1688305))
+
+# Process ERRATA_X1_1827429 flag
+$(eval $(call assert_boolean,ERRATA_X1_1827429))
+$(eval $(call add_define,ERRATA_X1_1827429))
+
# Process ERRATA_N1_1043202 flag
$(eval $(call assert_boolean,ERRATA_N1_1043202))
$(eval $(call add_define,ERRATA_N1_1043202))
@@ -898,6 +1052,10 @@
$(eval $(call assert_boolean,ERRATA_N2_2002655))
$(eval $(call add_define,ERRATA_N2_2002655))
+# Process ERRATA_V1_1618635 flag
+$(eval $(call assert_boolean,ERRATA_V1_1618635))
+$(eval $(call add_define,ERRATA_V1_1618635))
+
# Process ERRATA_V1_1774420 flag
$(eval $(call assert_boolean,ERRATA_V1_1774420))
$(eval $(call add_define,ERRATA_V1_1774420))
@@ -934,6 +1092,14 @@
$(eval $(call assert_boolean,ERRATA_V1_2216392))
$(eval $(call add_define,ERRATA_V1_2216392))
+# Process ERRATA_V1_2294912 flag
+$(eval $(call assert_boolean,ERRATA_V1_2294912))
+$(eval $(call add_define,ERRATA_V1_2294912))
+
+# Process ERRATA_V1_2372203 flag
+$(eval $(call assert_boolean,ERRATA_V1_2372203))
+$(eval $(call add_define,ERRATA_V1_2372203))
+
# Process ERRATA_A710_1987031 flag
$(eval $(call assert_boolean,ERRATA_A710_1987031))
$(eval $(call add_define,ERRATA_A710_1987031))
@@ -966,10 +1132,26 @@
$(eval $(call assert_boolean,ERRATA_A710_2136059))
$(eval $(call add_define,ERRATA_A710_2136059))
+# Process ERRATA_A710_2147715 flag
+$(eval $(call assert_boolean,ERRATA_A710_2147715))
+$(eval $(call add_define,ERRATA_A710_2147715))
+
+# Process ERRATA_A710_2216384 flag
+$(eval $(call assert_boolean,ERRATA_A710_2216384))
+$(eval $(call add_define,ERRATA_A710_2216384))
+
# Process ERRATA_A710_2282622 flag
$(eval $(call assert_boolean,ERRATA_A710_2282622))
$(eval $(call add_define,ERRATA_A710_2282622))
+# Process ERRATA_A710_2008768 flag
+$(eval $(call assert_boolean,ERRATA_A710_2008768))
+$(eval $(call add_define,ERRATA_A710_2008768))
+
+# Process ERRATA_A710_2371105 flag
+$(eval $(call assert_boolean,ERRATA_A710_2371105))
+$(eval $(call add_define,ERRATA_A710_2371105))
+
# Process ERRATA_N2_2067956 flag
$(eval $(call assert_boolean,ERRATA_N2_2067956))
$(eval $(call add_define,ERRATA_N2_2067956))
@@ -1006,6 +1188,14 @@
$(eval $(call assert_boolean,ERRATA_N2_2280757))
$(eval $(call add_define,ERRATA_N2_2280757))
+# Process ERRATA_N2_2376738 flag
+$(eval $(call assert_boolean,ERRATA_N2_2376738))
+$(eval $(call add_define,ERRATA_N2_2376738))
+
+# Process ERRATA_N2_2388450 flag
+$(eval $(call assert_boolean,ERRATA_N2_2388450))
+$(eval $(call add_define,ERRATA_N2_2388450))
+
# Process ERRATA_X2_2002765 flag
$(eval $(call assert_boolean,ERRATA_X2_2002765))
$(eval $(call add_define,ERRATA_X2_2002765))
@@ -1030,6 +1220,14 @@
$(eval $(call assert_boolean,ERRATA_X2_2216384))
$(eval $(call add_define,ERRATA_X2_2216384))
+# Process ERRATA_X2_2147715 flag
+$(eval $(call assert_boolean,ERRATA_X2_2147715))
+$(eval $(call add_define,ERRATA_X2_2147715))
+
+# Process ERRATA_X2_2371105 flag
+$(eval $(call assert_boolean,ERRATA_X2_2371105))
+$(eval $(call add_define,ERRATA_X2_2371105))
+
# Process ERRATA_A510_1922240 flag
$(eval $(call assert_boolean,ERRATA_A510_1922240))
$(eval $(call add_define,ERRATA_A510_1922240))
@@ -1058,6 +1256,14 @@
$(eval $(call assert_boolean,ERRATA_A510_2172148))
$(eval $(call add_define,ERRATA_A510_2172148))
+# Process ERRATA_A510_2347730 flag
+$(eval $(call assert_boolean,ERRATA_A510_2347730))
+$(eval $(call add_define,ERRATA_A510_2347730))
+
+# Process ERRATA_A510_2371937 flag
+$(eval $(call assert_boolean,ERRATA_A510_2371937))
+$(eval $(call add_define,ERRATA_A510_2371937))
+
# Process ERRATA_DSU_798953 flag
$(eval $(call assert_boolean,ERRATA_DSU_798953))
$(eval $(call add_define,ERRATA_DSU_798953))
@@ -1066,6 +1272,10 @@
$(eval $(call assert_boolean,ERRATA_DSU_936184))
$(eval $(call add_define,ERRATA_DSU_936184))
+# Process ERRATA_DSU_2313941 flag
+$(eval $(call assert_boolean,ERRATA_DSU_2313941))
+$(eval $(call add_define,ERRATA_DSU_2313941))
+
# Errata build flags
ifneq (${ERRATA_A53_843419},0)
TF_LDFLAGS_aarch64 += --fix-cortex-a53-843419
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 3ef378c..af8edf5 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -332,3 +332,12 @@
enable_extensions_nonsecure(el2_unused);
}
}
+
+/*******************************************************************************
+ * This function is used to exit to Non-secure world. It simply calls the
+ * cm_prepare_el3_exit function for AArch32.
+ ******************************************************************************/
+void cm_prepare_el3_exit_ns(void)
+{
+ cm_prepare_el3_exit(NON_SECURE);
+}
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index c1c0612..acfef80 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,16 +11,60 @@
#include <el3_common_macros.S>
#if CTX_INCLUDE_EL2_REGS
- .global el2_sysregs_context_save
- .global el2_sysregs_context_restore
-#endif
+ .global el2_sysregs_context_save_common
+ .global el2_sysregs_context_restore_common
+#if ENABLE_SPE_FOR_LOWER_ELS
+ .global el2_sysregs_context_save_spe
+ .global el2_sysregs_context_restore_spe
+#endif /* ENABLE_SPE_FOR_LOWER_ELS */
+#if CTX_INCLUDE_MTE_REGS
+ .global el2_sysregs_context_save_mte
+ .global el2_sysregs_context_restore_mte
+#endif /* CTX_INCLUDE_MTE_REGS */
+#if ENABLE_MPAM_FOR_LOWER_ELS
+ .global el2_sysregs_context_save_mpam
+ .global el2_sysregs_context_restore_mpam
+#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
+#if ENABLE_FEAT_FGT
+ .global el2_sysregs_context_save_fgt
+ .global el2_sysregs_context_restore_fgt
+#endif /* ENABLE_FEAT_FGT */
+#if ENABLE_FEAT_ECV
+ .global el2_sysregs_context_save_ecv
+ .global el2_sysregs_context_restore_ecv
+#endif /* ENABLE_FEAT_ECV */
+#if ENABLE_FEAT_VHE
+ .global el2_sysregs_context_save_vhe
+ .global el2_sysregs_context_restore_vhe
+#endif /* ENABLE_FEAT_VHE */
+#if RAS_EXTENSION
+ .global el2_sysregs_context_save_ras
+ .global el2_sysregs_context_restore_ras
+#endif /* RAS_EXTENSION */
+#if CTX_INCLUDE_NEVE_REGS
+ .global el2_sysregs_context_save_nv2
+ .global el2_sysregs_context_restore_nv2
+#endif /* CTX_INCLUDE_NEVE_REGS */
+#if ENABLE_TRF_FOR_NS
+ .global el2_sysregs_context_save_trf
+ .global el2_sysregs_context_restore_trf
+#endif /* ENABLE_TRF_FOR_NS */
+#if ENABLE_FEAT_CSV2_2
+ .global el2_sysregs_context_save_csv2
+ .global el2_sysregs_context_restore_csv2
+#endif /* ENABLE_FEAT_CSV2_2 */
+#if ENABLE_FEAT_HCX
+ .global el2_sysregs_context_save_hcx
+ .global el2_sysregs_context_restore_hcx
+#endif /* ENABLE_FEAT_HCX */
+#endif /* CTX_INCLUDE_EL2_REGS */
.global el1_sysregs_context_save
.global el1_sysregs_context_restore
#if CTX_INCLUDE_FPREGS
.global fpregs_context_save
.global fpregs_context_restore
-#endif
+#endif /* CTX_INCLUDE_FPREGS */
.global prepare_el3_entry
.global restore_gp_pmcr_pauth_regs
.global save_and_update_ptw_el1_sys_regs
@@ -29,11 +73,16 @@
#if CTX_INCLUDE_EL2_REGS
/* -----------------------------------------------------
- * The following function strictly follows the AArch64
+ * The following functions strictly follow the AArch64
* PCS to use x9-x16 (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.
+ * to save/restore EL2 system register context.
+ * el2_sysregs_context_save/restore_common functions
+ * save and restore registers that are common to all
+ * configurations. The rest of the functions save and
+ * restore EL2 system registers that are present when a
+ * particular feature is enabled. All functions assume
+ * that 'x0' is pointing to a 'el2_sys_regs' structure
+ * where the register context will be saved/restored.
*
* The following registers are not added.
* AMEVCNTVOFF0<n>_EL2
@@ -43,7 +92,7 @@
* ICH_LR<n>_EL2
* -----------------------------------------------------
*/
-func el2_sysregs_context_save
+func el2_sysregs_context_save_common
mrs x9, actlr_el2
mrs x10, afsr0_el2
stp x9, x10, [x0, #CTX_ACTLR_EL2]
@@ -62,7 +111,7 @@
#if CTX_INCLUDE_AARCH32_REGS
mrs x16, dbgvcr32_el2
str x16, [x0, #CTX_DBGVCR32_EL2]
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
mrs x9, elr_el2
mrs x10, esr_el2
@@ -88,10 +137,6 @@
mrs x12, mdcr_el2
stp x11, x12, [x0, #CTX_MAIR_EL2]
-#if ENABLE_SPE_FOR_LOWER_ELS
- mrs x13, PMSCR_EL2
- str x13, [x0, #CTX_PMSCR_EL2]
-#endif
mrs x14, sctlr_el2
str x14, [x0, #CTX_SCTLR_EL2]
@@ -114,115 +159,10 @@
mrs x15, vtcr_el2
mrs x16, vttbr_el2
stp x15, x16, [x0, #CTX_VTCR_EL2]
-
-#if CTX_INCLUDE_MTE_REGS
- mrs x9, TFSR_EL2
- str x9, [x0, #CTX_TFSR_EL2]
-#endif
-
-#if ENABLE_MPAM_FOR_LOWER_ELS
- mrs x10, MPAM2_EL2
- str x10, [x0, #CTX_MPAM2_EL2]
-
- mrs x11, MPAMHCR_EL2
- mrs x12, MPAMVPM0_EL2
- stp x11, x12, [x0, #CTX_MPAMHCR_EL2]
-
- mrs x13, MPAMVPM1_EL2
- mrs x14, MPAMVPM2_EL2
- stp x13, x14, [x0, #CTX_MPAMVPM1_EL2]
-
- mrs x15, MPAMVPM3_EL2
- mrs x16, MPAMVPM4_EL2
- stp x15, x16, [x0, #CTX_MPAMVPM3_EL2]
-
- mrs x9, MPAMVPM5_EL2
- mrs x10, MPAMVPM6_EL2
- stp x9, x10, [x0, #CTX_MPAMVPM5_EL2]
-
- mrs x11, MPAMVPM7_EL2
- mrs x12, MPAMVPMV_EL2
- stp x11, x12, [x0, #CTX_MPAMVPM7_EL2]
-#endif
-
-#if ENABLE_FEAT_FGT
- mrs x13, HDFGRTR_EL2
-#if ENABLE_FEAT_AMUv1
- mrs x14, HAFGRTR_EL2
- stp x13, x14, [x0, #CTX_HDFGRTR_EL2]
-#else
- str x13, [x0, #CTX_HDFGRTR_EL2]
-#endif
- mrs x15, HDFGWTR_EL2
- mrs x16, HFGITR_EL2
- stp x15, x16, [x0, #CTX_HDFGWTR_EL2]
-
- mrs x9, HFGRTR_EL2
- mrs x10, HFGWTR_EL2
- stp x9, x10, [x0, #CTX_HFGRTR_EL2]
-#endif
-
-#if ENABLE_FEAT_ECV
- mrs x11, CNTPOFF_EL2
- str x11, [x0, #CTX_CNTPOFF_EL2]
-#endif
-
-#if ARM_ARCH_AT_LEAST(8, 4)
- mrs x12, contextidr_el2
- str x12, [x0, #CTX_CONTEXTIDR_EL2]
-
-#if CTX_INCLUDE_AARCH32_REGS
- mrs x13, sder32_el2
- str x13, [x0, #CTX_SDER32_EL2]
-#endif
- mrs x14, ttbr1_el2
- mrs x15, vdisr_el2
- stp x14, x15, [x0, #CTX_TTBR1_EL2]
-
-#if CTX_INCLUDE_NEVE_REGS
- mrs x16, vncr_el2
- str x16, [x0, #CTX_VNCR_EL2]
-#endif
-
- mrs x9, vsesr_el2
- mrs x10, vstcr_el2
- stp x9, x10, [x0, #CTX_VSESR_EL2]
-
- mrs x11, vsttbr_el2
- mrs x12, TRFCR_EL2
- stp x11, x12, [x0, #CTX_VSTTBR_EL2]
-#endif
-
-#if ARM_ARCH_AT_LEAST(8, 5)
- mrs x13, scxtnum_el2
- str x13, [x0, #CTX_SCXTNUM_EL2]
-#endif
-
-#if ENABLE_FEAT_HCX
- mrs x14, hcrx_el2
- str x14, [x0, #CTX_HCRX_EL2]
-#endif
-
ret
-endfunc el2_sysregs_context_save
-
+endfunc el2_sysregs_context_save_common
-/* -----------------------------------------------------
- * The following function strictly follows the AArch64
- * PCS to use x9-x16 (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
+func el2_sysregs_context_restore_common
ldp x9, x10, [x0, #CTX_ACTLR_EL2]
msr actlr_el2, x9
msr afsr0_el2, x10
@@ -241,7 +181,7 @@
#if CTX_INCLUDE_AARCH32_REGS
ldr x16, [x0, #CTX_DBGVCR32_EL2]
msr dbgvcr32_el2, x16
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
ldp x9, x10, [x0, #CTX_ELR_EL2]
msr elr_el2, x9
@@ -267,10 +207,6 @@
msr mair_el2, x11
msr mdcr_el2, x12
-#if ENABLE_SPE_FOR_LOWER_ELS
- ldr x13, [x0, #CTX_PMSCR_EL2]
- msr PMSCR_EL2, x13
-#endif
ldr x14, [x0, #CTX_SCTLR_EL2]
msr sctlr_el2, x14
@@ -293,13 +229,65 @@
ldp x15, x16, [x0, #CTX_VTCR_EL2]
msr vtcr_el2, x15
msr vttbr_el2, x16
+ ret
+endfunc el2_sysregs_context_restore_common
+
+#if ENABLE_SPE_FOR_LOWER_ELS
+func el2_sysregs_context_save_spe
+ mrs x13, PMSCR_EL2
+ str x13, [x0, #CTX_PMSCR_EL2]
+ ret
+endfunc el2_sysregs_context_save_spe
+
+func el2_sysregs_context_restore_spe
+ ldr x13, [x0, #CTX_PMSCR_EL2]
+ msr PMSCR_EL2, x13
+ ret
+endfunc el2_sysregs_context_restore_spe
+#endif /* ENABLE_SPE_FOR_LOWER_ELS */
#if CTX_INCLUDE_MTE_REGS
+func el2_sysregs_context_save_mte
+ mrs x9, TFSR_EL2
+ str x9, [x0, #CTX_TFSR_EL2]
+ ret
+endfunc el2_sysregs_context_save_mte
+
+func el2_sysregs_context_restore_mte
ldr x9, [x0, #CTX_TFSR_EL2]
msr TFSR_EL2, x9
-#endif
+ ret
+endfunc el2_sysregs_context_restore_mte
+#endif /* CTX_INCLUDE_MTE_REGS */
#if ENABLE_MPAM_FOR_LOWER_ELS
+func el2_sysregs_context_save_mpam
+ mrs x10, MPAM2_EL2
+ str x10, [x0, #CTX_MPAM2_EL2]
+
+ mrs x11, MPAMHCR_EL2
+ mrs x12, MPAMVPM0_EL2
+ stp x11, x12, [x0, #CTX_MPAMHCR_EL2]
+
+ mrs x13, MPAMVPM1_EL2
+ mrs x14, MPAMVPM2_EL2
+ stp x13, x14, [x0, #CTX_MPAMVPM1_EL2]
+
+ mrs x15, MPAMVPM3_EL2
+ mrs x16, MPAMVPM4_EL2
+ stp x15, x16, [x0, #CTX_MPAMVPM3_EL2]
+
+ mrs x9, MPAMVPM5_EL2
+ mrs x10, MPAMVPM6_EL2
+ stp x9, x10, [x0, #CTX_MPAMVPM5_EL2]
+
+ mrs x11, MPAMVPM7_EL2
+ mrs x12, MPAMVPMV_EL2
+ stp x11, x12, [x0, #CTX_MPAMVPM7_EL2]
+ ret
+endfunc func el2_sysregs_context_save_mpam
+
+func el2_sysregs_context_restore_mpam
ldr x10, [x0, #CTX_MPAM2_EL2]
msr MPAM2_EL2, x10
@@ -322,15 +310,36 @@
ldp x11, x12, [x0, #CTX_MPAMVPM7_EL2]
msr MPAMVPM7_EL2, x11
msr MPAMVPMV_EL2, x12
-#endif
+ ret
+endfunc el2_sysregs_context_restore_mpam
+#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
#if ENABLE_FEAT_FGT
+func el2_sysregs_context_save_fgt
+ mrs x13, HDFGRTR_EL2
#if ENABLE_FEAT_AMUv1
+ mrs x14, HAFGRTR_EL2
+ stp x13, x14, [x0, #CTX_HDFGRTR_EL2]
+#else
+ str x13, [x0, #CTX_HDFGRTR_EL2]
+#endif /* ENABLE_FEAT_AMUv1 */
+ mrs x15, HDFGWTR_EL2
+ mrs x16, HFGITR_EL2
+ stp x15, x16, [x0, #CTX_HDFGWTR_EL2]
+
+ mrs x9, HFGRTR_EL2
+ mrs x10, HFGWTR_EL2
+ stp x9, x10, [x0, #CTX_HFGRTR_EL2]
+ ret
+endfunc el2_sysregs_context_save_fgt
+
+func el2_sysregs_context_restore_fgt
+ #if ENABLE_FEAT_AMUv1
ldp x13, x14, [x0, #CTX_HDFGRTR_EL2]
msr HAFGRTR_EL2, x14
#else
ldr x13, [x0, #CTX_HDFGRTR_EL2]
-#endif
+#endif /* ENABLE_FEAT_AMUv1 */
msr HDFGRTR_EL2, x13
ldp x15, x16, [x0, #CTX_HDFGWTR_EL2]
@@ -340,52 +349,145 @@
ldp x9, x10, [x0, #CTX_HFGRTR_EL2]
msr HFGRTR_EL2, x9
msr HFGWTR_EL2, x10
-#endif
+ ret
+endfunc el2_sysregs_context_restore_fgt
+#endif /* ENABLE_FEAT_FGT */
#if ENABLE_FEAT_ECV
+func el2_sysregs_context_save_ecv
+ mrs x11, CNTPOFF_EL2
+ str x11, [x0, #CTX_CNTPOFF_EL2]
+ ret
+endfunc el2_sysregs_context_save_ecv
+
+func el2_sysregs_context_restore_ecv
ldr x11, [x0, #CTX_CNTPOFF_EL2]
msr CNTPOFF_EL2, x11
-#endif
+ ret
+endfunc el2_sysregs_context_restore_ecv
+#endif /* ENABLE_FEAT_ECV */
-#if ARM_ARCH_AT_LEAST(8, 4)
- ldr x12, [x0, #CTX_CONTEXTIDR_EL2]
- msr contextidr_el2, x12
+#if ENABLE_FEAT_VHE
+func el2_sysregs_context_save_vhe
+ /*
+ * CONTEXTIDR_EL2 register is saved only when FEAT_VHE or
+ * FEAT_Debugv8p2 (currently not in TF-A) is supported.
+ */
+ mrs x9, contextidr_el2
+ mrs x10, ttbr1_el2
+ stp x9, x10, [x0, #CTX_CONTEXTIDR_EL2]
+ ret
+endfunc el2_sysregs_context_save_vhe
-#if CTX_INCLUDE_AARCH32_REGS
- ldr x13, [x0, #CTX_SDER32_EL2]
- msr sder32_el2, x13
-#endif
- ldp x14, x15, [x0, #CTX_TTBR1_EL2]
- msr ttbr1_el2, x14
- msr vdisr_el2, x15
+func el2_sysregs_context_restore_vhe
+ /*
+ * CONTEXTIDR_EL2 register is restored only when FEAT_VHE or
+ * FEAT_Debugv8p2 (currently not in TF-A) is supported.
+ */
+ ldp x9, x10, [x0, #CTX_CONTEXTIDR_EL2]
+ msr contextidr_el2, x9
+ msr ttbr1_el2, x10
+ ret
+endfunc el2_sysregs_context_restore_vhe
+#endif /* ENABLE_FEAT_VHE */
+
+#if RAS_EXTENSION
+func el2_sysregs_context_save_ras
+ /*
+ * VDISR_EL2 and VSESR_EL2 registers are saved only when
+ * FEAT_RAS is supported.
+ */
+ mrs x11, vdisr_el2
+ mrs x12, vsesr_el2
+ stp x11, x12, [x0, #CTX_VDISR_EL2]
+ ret
+endfunc el2_sysregs_context_save_ras
+
+func el2_sysregs_context_restore_ras
+ /*
+ * VDISR_EL2 and VSESR_EL2 registers are restored only when FEAT_RAS
+ * is supported.
+ */
+ ldp x11, x12, [x0, #CTX_VDISR_EL2]
+ msr vdisr_el2, x11
+ msr vsesr_el2, x12
+ ret
+endfunc el2_sysregs_context_restore_ras
+#endif /* RAS_EXTENSION */
#if CTX_INCLUDE_NEVE_REGS
+func el2_sysregs_context_save_nv2
+ /*
+ * VNCR_EL2 register is saved only when FEAT_NV2 is supported.
+ */
+ mrs x16, vncr_el2
+ str x16, [x0, #CTX_VNCR_EL2]
+ ret
+endfunc el2_sysregs_context_save_nv2
+
+func el2_sysregs_context_restore_nv2
+ /*
+ * VNCR_EL2 register is restored only when FEAT_NV2 is supported.
+ */
ldr x16, [x0, #CTX_VNCR_EL2]
msr vncr_el2, x16
-#endif
+ ret
+endfunc el2_sysregs_context_restore_nv2
+#endif /* CTX_INCLUDE_NEVE_REGS */
- ldp x9, x10, [x0, #CTX_VSESR_EL2]
- msr vsesr_el2, x9
- msr vstcr_el2, x10
+#if ENABLE_TRF_FOR_NS
+func el2_sysregs_context_save_trf
+ /*
+ * TRFCR_EL2 register is saved only when FEAT_TRF is supported.
+ */
+ mrs x12, TRFCR_EL2
+ str x12, [x0, #CTX_TRFCR_EL2]
+ ret
+endfunc el2_sysregs_context_save_trf
- ldp x11, x12, [x0, #CTX_VSTTBR_EL2]
- msr vsttbr_el2, x11
+func el2_sysregs_context_restore_trf
+ /*
+ * TRFCR_EL2 register is restored only when FEAT_TRF is supported.
+ */
+ ldr x12, [x0, #CTX_TRFCR_EL2]
msr TRFCR_EL2, x12
-#endif
+ ret
+endfunc el2_sysregs_context_restore_trf
+#endif /* ENABLE_TRF_FOR_NS */
-#if ARM_ARCH_AT_LEAST(8, 5)
+#if ENABLE_FEAT_CSV2_2
+func el2_sysregs_context_save_csv2
+ /*
+ * SCXTNUM_EL2 register is saved only when FEAT_CSV2_2 is supported.
+ */
+ mrs x13, scxtnum_el2
+ str x13, [x0, #CTX_SCXTNUM_EL2]
+ ret
+endfunc el2_sysregs_context_save_csv2
+
+func el2_sysregs_context_restore_csv2
+ /*
+ * SCXTNUM_EL2 register is restored only when FEAT_CSV2_2 is supported.
+ */
ldr x13, [x0, #CTX_SCXTNUM_EL2]
msr scxtnum_el2, x13
-#endif
+ ret
+endfunc el2_sysregs_context_restore_csv2
+#endif /* ENABLE_FEAT_CSV2_2 */
#if ENABLE_FEAT_HCX
+func el2_sysregs_context_save_hcx
+ mrs x14, hcrx_el2
+ str x14, [x0, #CTX_HCRX_EL2]
+ ret
+endfunc el2_sysregs_context_save_hcx
+
+func el2_sysregs_context_restore_hcx
ldr x14, [x0, #CTX_HCRX_EL2]
msr hcrx_el2, x14
-#endif
-
ret
-endfunc el2_sysregs_context_restore
-
+endfunc el2_sysregs_context_restore_hcx
+#endif /* ENABLE_FEAT_HCX */
#endif /* CTX_INCLUDE_EL2_REGS */
/* ------------------------------------------------------------------
@@ -405,7 +507,7 @@
mrs x15, sctlr_el1
mrs x16, tcr_el1
stp x15, x16, [x0, #CTX_SCTLR_EL1]
-#endif
+#endif /* ERRATA_SPECULATIVE_AT */
mrs x17, cpacr_el1
mrs x9, csselr_el1
@@ -456,7 +558,7 @@
mrs x15, dacr32_el2
mrs x16, ifsr32_el2
stp x15, x16, [x0, #CTX_DACR32_EL2]
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
/* Save NS timer registers if the build has instructed so */
#if NS_TIMER_SWITCH
@@ -470,7 +572,7 @@
mrs x14, cntkctl_el1
str x14, [x0, #CTX_CNTKCTL_EL1]
-#endif
+#endif /* NS_TIMER_SWITCH */
/* Save MTE system registers if the build has instructed so */
#if CTX_INCLUDE_MTE_REGS
@@ -481,7 +583,7 @@
mrs x9, RGSR_EL1
mrs x10, GCR_EL1
stp x9, x10, [x0, #CTX_RGSR_EL1]
-#endif
+#endif /* CTX_INCLUDE_MTE_REGS */
ret
endfunc el1_sysregs_context_save
@@ -504,7 +606,7 @@
ldp x15, x16, [x0, #CTX_SCTLR_EL1]
msr sctlr_el1, x15
msr tcr_el1, x16
-#endif
+#endif /* ERRATA_SPECULATIVE_AT */
ldp x17, x9, [x0, #CTX_CPACR_EL1]
msr cpacr_el1, x17
@@ -555,7 +657,8 @@
ldp x15, x16, [x0, #CTX_DACR32_EL2]
msr dacr32_el2, x15
msr ifsr32_el2, x16
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
+
/* Restore NS timer registers if the build has instructed so */
#if NS_TIMER_SWITCH
ldp x10, x11, [x0, #CTX_CNTP_CTL_EL0]
@@ -568,7 +671,8 @@
ldr x14, [x0, #CTX_CNTKCTL_EL1]
msr cntkctl_el1, x14
-#endif
+#endif /* NS_TIMER_SWITCH */
+
/* Restore MTE system registers if the build has instructed so */
#if CTX_INCLUDE_MTE_REGS
ldp x11, x12, [x0, #CTX_TFSRE0_EL1]
@@ -578,7 +682,7 @@
ldp x13, x14, [x0, #CTX_RGSR_EL1]
msr RGSR_EL1, x13
msr GCR_EL1, x14
-#endif
+#endif /* CTX_INCLUDE_MTE_REGS */
/* No explict ISB required here as ERET covers it */
ret
@@ -626,7 +730,7 @@
#if CTX_INCLUDE_AARCH32_REGS
mrs x11, fpexc32_el2
str x11, [x0, #CTX_FP_FPEXC32_EL2]
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
ret
endfunc fpregs_context_save
@@ -671,7 +775,8 @@
#if CTX_INCLUDE_AARCH32_REGS
ldr x11, [x0, #CTX_FP_FPEXC32_EL2]
msr fpexc32_el2, x11
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
+
/*
* No explict ISB required here as ERET to
* switch to secure EL1 or non-secure world
@@ -688,13 +793,13 @@
* in ARM DDI 0487F.c page J1-7635 to a default value.
*/
.macro set_unset_pstate_bits
- /*
- * If Data Independent Timing (DIT) functionality is implemented,
- * always enable DIT in EL3
- */
+ /*
+ * If Data Independent Timing (DIT) functionality is implemented,
+ * always enable DIT in EL3
+ */
#if ENABLE_FEAT_DIT
- mov x8, #DIT_BIT
- msr DIT, x8
+ mov x8, #DIT_BIT
+ msr DIT, x8
#endif /* ENABLE_FEAT_DIT */
.endm /* set_unset_pstate_bits */
@@ -933,7 +1038,7 @@
mrs x17, spsel
cmp x17, #MODE_SP_EL0
ASM_ASSERT(eq)
-#endif
+#endif /* ENABLE_ASSERTIONS */
/* ----------------------------------------------------------
* Save the current SP_EL0 i.e. the EL3 runtime stack which
@@ -971,7 +1076,7 @@
isb
msr S3_6_C1_C2_0, x20 /* zcr_el3 */
sve_not_enabled:
-#endif
+#endif /* IMAGE_BL31 */
#if IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639
/* ----------------------------------------------------------
@@ -982,7 +1087,8 @@
cbz x17, 1f
blr x17
1:
-#endif
+#endif /* IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 */
+
restore_ptw_el1_sys_regs
/* ----------------------------------------------------------
@@ -1005,10 +1111,12 @@
esb
#else
dsb sy
-#endif
+#endif /* IMAGE_BL31 && RAS_EXTENSION */
+
#ifdef IMAGE_BL31
str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
-#endif
+#endif /* IMAGE_BL31 */
+
exception_return
endfunc el3_exit
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index c69dc95..68aacc1 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,9 +16,11 @@
#include <bl31/interrupt_mgmt.h>
#include <common/bl_common.h>
#include <context.h>
+#include <drivers/arm/gicv3.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/el3_runtime/pubsub_events.h>
#include <lib/extensions/amu.h>
+#include <lib/extensions/brbe.h>
#include <lib/extensions/mpam.h>
#include <lib/extensions/sme.h>
#include <lib/extensions/spe.h>
@@ -26,58 +28,233 @@
#include <lib/extensions/sys_reg_trace.h>
#include <lib/extensions/trbe.h>
#include <lib/extensions/trf.h>
-#include <lib/extensions/twed.h>
#include <lib/utils.h>
+#if ENABLE_FEAT_TWED
+/* Make sure delay value fits within the range(0-15) */
+CASSERT(((TWED_DELAY & ~SCR_TWEDEL_MASK) == 0U), assert_twed_delay_value_check);
+#endif /* ENABLE_FEAT_TWED */
+
static void manage_extensions_secure(cpu_context_t *ctx);
-/*******************************************************************************
- * Context management library initialisation routine. This library is used by
- * runtime services to share pointers to 'cpu_context' structures for the secure
- * and non-secure states. Management of the structures and their associated
- * memory is not done by the context management library e.g. the PSCI service
- * manages the cpu context used for entry from and exit to the non-secure state.
- * The Secure payload dispatcher service manages the context(s) corresponding to
- * the secure state. It also uses this library to get access to the non-secure
- * state cpu context pointers.
- * Lastly, this library provides the api to make SP_EL3 point to the cpu context
- * which will used for programming an entry into a lower EL. The same context
- * will used to save state upon exception entry from that EL.
- ******************************************************************************/
-void __init cm_init(void)
+static void setup_el1_context(cpu_context_t *ctx, const struct entry_point_info *ep)
{
+ u_register_t sctlr_elx, actlr_elx;
+
/*
- * The context management library has only global data to intialize, but
- * that will be done when the BSS is zeroed out
+ * Initialise SCTLR_EL1 to the reset value corresponding to the target
+ * execution state setting all fields rather than relying on the hw.
+ * Some fields have architecturally UNKNOWN reset values and these are
+ * set to zero.
+ *
+ * SCTLR.EE: Endianness is taken from the entrypoint attributes.
+ *
+ * SCTLR.M, SCTLR.C and SCTLR.I: These fields must be zero (as
+ * required by PSCI specification)
+ */
+ sctlr_elx = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0UL;
+ if (GET_RW(ep->spsr) == MODE_RW_64) {
+ sctlr_elx |= SCTLR_EL1_RES1;
+ } else {
+ /*
+ * If the target execution state is AArch32 then the following
+ * fields need to be set.
+ *
+ * SCTRL_EL1.nTWE: Set to one so that EL0 execution of WFE
+ * instructions are not trapped to EL1.
+ *
+ * SCTLR_EL1.nTWI: Set to one so that EL0 execution of WFI
+ * instructions are not trapped to EL1.
+ *
+ * SCTLR_EL1.CP15BEN: Set to one to enable EL0 execution of the
+ * CP15DMB, CP15DSB, and CP15ISB instructions.
+ */
+ sctlr_elx |= SCTLR_AARCH32_EL1_RES1 | SCTLR_CP15BEN_BIT
+ | SCTLR_NTWI_BIT | SCTLR_NTWE_BIT;
+ }
+
+#if ERRATA_A75_764081
+ /*
+ * If workaround of errata 764081 for Cortex-A75 is used then set
+ * SCTLR_EL1.IESB to enable Implicit Error Synchronization Barrier.
+ */
+ sctlr_elx |= SCTLR_IESB_BIT;
+#endif
+ /* Store the initialised SCTLR_EL1 value in the cpu_context */
+ 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
+ * implementation defined. The context restore process will write
+ * the value from the context to the actual register and can cause
+ * problems for processor cores that don't expect certain bits to
+ * be zero.
+ */
+ actlr_elx = read_actlr_el1();
+ write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
+}
+
+/******************************************************************************
+ * This function performs initializations that are specific to SECURE state
+ * and updates the cpu context specified by 'ctx'.
+ *****************************************************************************/
+static void setup_secure_context(cpu_context_t *ctx, const struct entry_point_info *ep)
+{
+ u_register_t scr_el3;
+ el3_state_t *state;
+
+ state = get_el3state_ctx(ctx);
+ scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
+
+#if defined(IMAGE_BL31) && !defined(SPD_spmd)
+ /*
+ * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
+ * indicated by the interrupt routing model for BL31.
+ */
+ scr_el3 |= get_scr_el3_from_routing_model(SECURE);
+#endif
+
+#if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS
+ /* Get Memory Tagging Extension support level */
+ unsigned int mte = get_armv8_5_mte_support();
+#endif
+ /*
+ * Allow access to Allocation Tags when CTX_INCLUDE_MTE_REGS
+ * is set, or when MTE is only implemented at EL0.
+ */
+#if CTX_INCLUDE_MTE_REGS
+ assert((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY));
+ scr_el3 |= SCR_ATA_BIT;
+#else
+ if (mte == MTE_IMPLEMENTED_EL0) {
+ scr_el3 |= SCR_ATA_BIT;
+ }
+#endif /* CTX_INCLUDE_MTE_REGS */
+
+ /* Enable S-EL2 if the next EL is EL2 and S-EL2 is present */
+ if ((GET_EL(ep->spsr) == MODE_EL2) && is_armv8_4_sel2_present()) {
+ if (GET_RW(ep->spsr) != MODE_RW_64) {
+ ERROR("S-EL2 can not be used in AArch32\n.");
+ panic();
+ }
+
+ scr_el3 |= SCR_EEL2_BIT;
+ }
+
+ write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
+
+ /*
+ * Initialize EL1 context registers unless SPMC is running
+ * at S-EL2.
+ */
+#if !SPMD_SPM_AT_SEL2
+ setup_el1_context(ctx, ep);
+#endif
+
+ manage_extensions_secure(ctx);
+}
+
+#if ENABLE_RME
+/******************************************************************************
+ * This function performs initializations that are specific to REALM state
+ * and updates the cpu context specified by 'ctx'.
+ *****************************************************************************/
+static void setup_realm_context(cpu_context_t *ctx, const struct entry_point_info *ep)
+{
+ u_register_t scr_el3;
+ el3_state_t *state;
+
+ state = get_el3state_ctx(ctx);
+ scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
+
+ scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT | SCR_EnSCXT_BIT;
+
+ write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
+}
+#endif /* ENABLE_RME */
+
+/******************************************************************************
+ * This function performs initializations that are specific to NON-SECURE state
+ * and updates the cpu context specified by 'ctx'.
+ *****************************************************************************/
+static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *ep)
+{
+ u_register_t scr_el3;
+ el3_state_t *state;
+
+ state = get_el3state_ctx(ctx);
+ scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
+
+ /* SCR_NS: Set the NS bit */
+ scr_el3 |= SCR_NS_BIT;
+
+#if !CTX_INCLUDE_PAUTH_REGS
+ /*
+ * If the pointer authentication registers aren't saved during world
+ * switches the value of the registers can be leaked from the Secure to
+ * the Non-secure world. To prevent this, rather than enabling pointer
+ * authentication everywhere, we only enable it in the Non-secure world.
+ *
+ * If the Secure world wants to use pointer authentication,
+ * CTX_INCLUDE_PAUTH_REGS must be set to 1.
+ */
+ scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
+#endif /* !CTX_INCLUDE_PAUTH_REGS */
+
+ /* Allow access to Allocation Tags when MTE is implemented. */
+ scr_el3 |= SCR_ATA_BIT;
+
+#ifdef IMAGE_BL31
+ /*
+ * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
+ * indicated by the interrupt routing model for BL31.
+ */
+ scr_el3 |= get_scr_el3_from_routing_model(NON_SECURE);
+#endif
+ write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
+
+ /* Initialize EL1 context registers */
+ setup_el1_context(ctx, ep);
+
+ /* Initialize EL2 context registers */
+#if CTX_INCLUDE_EL2_REGS
+
+ /*
+ * Initialize SCTLR_EL2 context register using Endianness value
+ * taken from the entrypoint attribute.
*/
+ u_register_t sctlr_el2 = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0UL;
+ sctlr_el2 |= SCTLR_EL2_RES1;
+ write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_SCTLR_EL2,
+ sctlr_el2);
+
+ /*
+ * The GICv3 driver initializes the ICC_SRE_EL2 register during
+ * platform setup. Use the same setting for the corresponding
+ * context register to make sure the correct bits are set when
+ * restoring NS context.
+ */
+ u_register_t icc_sre_el2 = read_icc_sre_el2();
+ icc_sre_el2 |= (ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT);
+ icc_sre_el2 |= (ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT);
+ write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_ICC_SRE_EL2,
+ icc_sre_el2);
+#endif /* CTX_INCLUDE_EL2_REGS */
}
/*******************************************************************************
- * The following function initializes the cpu_context 'ctx' for
- * first use, and sets the initial entrypoint state as specified by the
- * entry_point_info structure.
- *
- * The security state to initialize is determined by the SECURE attribute
- * of the entry_point_info.
+ * The following function performs initialization of the cpu_context 'ctx'
+ * for first use that is common to all security states, and sets the
+ * initial entrypoint state as specified by the entry_point_info structure.
*
* The EE and ST attributes are used to configure the endianness and secure
* timer availability for the new execution context.
- *
- * To prepare the register state for entry call cm_prepare_el3_exit() and
- * el3_exit(). For Secure-EL1 cm_prepare_el3_exit() is equivalent to
- * cm_el1_sysregs_context_restore().
******************************************************************************/
-void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
+static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *ep)
{
- unsigned int security_state;
u_register_t scr_el3;
el3_state_t *state;
gp_regs_t *gp_regs;
- u_register_t sctlr_elx, actlr_elx;
-
- assert(ctx != NULL);
-
- security_state = GET_SECURITY_STATE(ep->h.attr);
/* Clear any residual register values from the context */
zeromem(ctx, sizeof(*ctx));
@@ -93,38 +270,22 @@
*/
scr_el3 = read_scr();
scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT |
- SCR_ST_BIT | SCR_HCE_BIT);
-
-#if ENABLE_RME
- /* When RME support is enabled, clear the NSE bit as well. */
- scr_el3 &= ~SCR_NSE_BIT;
-#endif /* ENABLE_RME */
+ SCR_ST_BIT | SCR_HCE_BIT | SCR_NSE_BIT);
/*
- * SCR_NS: Set the security state of the next EL.
- */
- if (security_state == NON_SECURE) {
- scr_el3 |= SCR_NS_BIT;
- }
-
-#if ENABLE_RME
- /* Check for realm state if RME support enabled. */
- if (security_state == REALM) {
- scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT | SCR_EnSCXT_BIT;
- }
-#endif /* ENABLE_RME */
-
- /*
* SCR_EL3.RW: Set the execution state, AArch32 or AArch64, for next
* Exception level as specified by SPSR.
*/
if (GET_RW(ep->spsr) == MODE_RW_64) {
scr_el3 |= SCR_RW_BIT;
}
+
/*
* SCR_EL3.ST: Traps Secure EL1 accesses to the Counter-timer Physical
- * Secure timer registers to EL3, from AArch64 state only, if specified
- * by the entrypoint attributes.
+ * Secure timer registers to EL3, from AArch64 state only, if specified
+ * by the entrypoint attributes. If SEL2 is present and enabled, the ST
+ * bit always behaves as 1 (i.e. secure physical timer register access
+ * is not trapped)
*/
if (EP_GET_ST(ep->h.attr) != 0U) {
scr_el3 |= SCR_ST_BIT;
@@ -138,6 +299,14 @@
scr_el3 |= SCR_HXEn_BIT;
#endif
+ /*
+ * If FEAT_RNG_TRAP is enabled, all reads of the RNDR and RNDRRS
+ * registers are trapped to EL3.
+ */
+#if ENABLE_FEAT_RNG_TRAP
+ scr_el3 |= SCR_TRNDR_BIT;
+#endif
+
#if RAS_TRAP_LOWER_EL_ERR_ACCESS
/*
* SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR
@@ -149,8 +318,8 @@
#if !HANDLE_EA_EL3_FIRST
/*
* SCR_EL3.EA: Do not route External Abort and SError Interrupt External
- * to EL3 when executing at a lower EL. When executing at EL3, External
- * Aborts are taken to EL3.
+ * to EL3 when executing at a lower EL. When executing at EL3, External
+ * Aborts are taken to EL3.
*/
scr_el3 &= ~SCR_EA_BIT;
#endif
@@ -159,69 +328,12 @@
/* Enable fault injection from lower ELs */
scr_el3 |= SCR_FIEN_BIT;
#endif
-
-#if !CTX_INCLUDE_PAUTH_REGS
- /*
- * If the pointer authentication registers aren't saved during world
- * switches the value of the registers can be leaked from the Secure to
- * the Non-secure world. To prevent this, rather than enabling pointer
- * authentication everywhere, we only enable it in the Non-secure world.
- *
- * If the Secure world wants to use pointer authentication,
- * CTX_INCLUDE_PAUTH_REGS must be set to 1.
- */
- if (security_state == NON_SECURE) {
- scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
- }
-#endif /* !CTX_INCLUDE_PAUTH_REGS */
-
-#if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS
- /* Get Memory Tagging Extension support level */
- unsigned int mte = get_armv8_5_mte_support();
-#endif
- /*
- * Enable MTE support. Support is enabled unilaterally for the normal
- * world, and only for the secure world when CTX_INCLUDE_MTE_REGS is
- * set.
- */
-#if CTX_INCLUDE_MTE_REGS
- assert((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY));
- scr_el3 |= SCR_ATA_BIT;
-#else
- /*
- * When MTE is only implemented at EL0, it can be enabled
- * across both worlds as no MTE registers are used.
- */
- if ((mte == MTE_IMPLEMENTED_EL0) ||
- /*
- * When MTE is implemented at all ELs, it can be only enabled
- * in Non-Secure world without register saving.
- */
- (((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY)) &&
- (security_state == NON_SECURE))) {
- scr_el3 |= SCR_ATA_BIT;
- }
-#endif /* CTX_INCLUDE_MTE_REGS */
-#ifdef IMAGE_BL31
/*
- * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
- * indicated by the interrupt routing model for BL31.
- *
- * TODO: The interrupt routing model code is not updated for REALM
- * state. Use the default values of IRQ = FIQ = 0 for REALM security
- * state for now.
+ * CPTR_EL3 was initialized out of reset, copy that value to the
+ * context register.
*/
- if (security_state != REALM) {
- scr_el3 |= get_scr_el3_from_routing_model(security_state);
- }
-#endif
-
- /* Save the initialized value of CPTR_EL3 register */
write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, read_cptr_el3());
- if (security_state == SECURE) {
- manage_extensions_secure(ctx);
- }
/*
* SCR_EL3.HCE: Enable HVC instructions if next execution state is
@@ -247,102 +359,18 @@
== ID_AA64MMFR0_EL1_ECV_SELF_SYNCH) {
scr_el3 |= SCR_ECVEN_BIT;
}
- }
-
- /* Enable S-EL2 if the next EL is EL2 and security state is secure */
- if ((security_state == SECURE) && (GET_EL(ep->spsr) == MODE_EL2)) {
- if (GET_RW(ep->spsr) != MODE_RW_64) {
- ERROR("S-EL2 can not be used in AArch32.");
- panic();
- }
-
- scr_el3 |= SCR_EEL2_BIT;
- }
-
- /*
- * FEAT_AMUv1p1 virtual offset registers are only accessible from EL3
- * and EL2, when clear, this bit traps accesses from EL2 so we set it
- * to 1 when EL2 is present.
- */
- if (is_armv8_6_feat_amuv1p1_present() &&
- (el_implemented(2) != EL_IMPL_NONE)) {
- scr_el3 |= SCR_AMVOFFEN_BIT;
- }
-
- /*
- * Initialise SCTLR_EL1 to the reset value corresponding to the target
- * execution state setting all fields rather than relying of the hw.
- * Some fields have architecturally UNKNOWN reset values and these are
- * set to zero.
- *
- * SCTLR.EE: Endianness is taken from the entrypoint attributes.
- *
- * SCTLR.M, SCTLR.C and SCTLR.I: These fields must be zero (as
- * required by PSCI specification)
- */
- sctlr_elx = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0U;
- if (GET_RW(ep->spsr) == MODE_RW_64) {
- sctlr_elx |= SCTLR_EL1_RES1;
- } else {
- /*
- * If the target execution state is AArch32 then the following
- * fields need to be set.
- *
- * SCTRL_EL1.nTWE: Set to one so that EL0 execution of WFE
- * instructions are not trapped to EL1.
- *
- * SCTLR_EL1.nTWI: Set to one so that EL0 execution of WFI
- * instructions are not trapped to EL1.
- *
- * SCTLR_EL1.CP15BEN: Set to one to enable EL0 execution of the
- * CP15DMB, CP15DSB, and CP15ISB instructions.
- */
- sctlr_elx |= SCTLR_AARCH32_EL1_RES1 | SCTLR_CP15BEN_BIT
- | SCTLR_NTWI_BIT | SCTLR_NTWE_BIT;
}
-#if ERRATA_A75_764081
- /*
- * If workaround of errata 764081 for Cortex-A75 is used then set
- * SCTLR_EL1.IESB to enable Implicit Error Synchronization Barrier.
- */
- sctlr_elx |= SCTLR_IESB_BIT;
-#endif
-
+#if ENABLE_FEAT_TWED
/* Enable WFE trap delay in SCR_EL3 if supported and configured */
- if (is_armv8_6_twed_present()) {
- uint32_t delay = plat_arm_set_twedel_scr_el3();
+ /* Set delay in SCR_EL3 */
+ scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
+ scr_el3 |= ((TWED_DELAY & SCR_TWEDEL_MASK)
+ << SCR_TWEDEL_SHIFT);
- if (delay != TWED_DISABLED) {
- /* Make sure delay value fits */
- assert((delay & ~SCR_TWEDEL_MASK) == 0U);
-
- /* Set delay in SCR_EL3 */
- scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
- scr_el3 |= ((delay & SCR_TWEDEL_MASK)
- << SCR_TWEDEL_SHIFT);
-
- /* Enable WFE delay */
- scr_el3 |= SCR_TWEDEn_BIT;
- }
- }
-
- /*
- * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
- * and other EL2 registers are set up by cm_prepare_el3_exit() as they
- * are not part of the stored cpu_context.
- */
- 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
- * implementation defined. The context restore process will write
- * the value from the context to the actual register and can cause
- * problems for processor cores that don't expect certain bits to
- * be zero.
- */
- actlr_elx = read_actlr_el1();
- write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
+ /* Enable WFE delay */
+ scr_el3 |= SCR_TWEDEn_BIT;
+#endif /* ENABLE_FEAT_TWED */
/*
* Populate EL3 state so that we've the right context
@@ -362,6 +390,66 @@
}
/*******************************************************************************
+ * Context management library initialization routine. This library is used by
+ * runtime services to share pointers to 'cpu_context' structures for secure
+ * non-secure and realm states. Management of the structures and their associated
+ * memory is not done by the context management library e.g. the PSCI service
+ * manages the cpu context used for entry from and exit to the non-secure state.
+ * The Secure payload dispatcher service manages the context(s) corresponding to
+ * the secure state. It also uses this library to get access to the non-secure
+ * state cpu context pointers.
+ * Lastly, this library provides the API to make SP_EL3 point to the cpu context
+ * which will be used for programming an entry into a lower EL. The same context
+ * will be used to save state upon exception entry from that EL.
+ ******************************************************************************/
+void __init cm_init(void)
+{
+ /*
+ * The context management library has only global data to intialize, but
+ * that will be done when the BSS is zeroed out.
+ */
+}
+
+/*******************************************************************************
+ * This is the high-level function used to initialize the cpu_context 'ctx' for
+ * first use. It performs initializations that are common to all security states
+ * and initializations specific to the security state specified in 'ep'
+ ******************************************************************************/
+void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
+{
+ unsigned int security_state;
+
+ assert(ctx != NULL);
+
+ /*
+ * Perform initializations that are common
+ * to all security states
+ */
+ setup_context_common(ctx, ep);
+
+ security_state = GET_SECURITY_STATE(ep->h.attr);
+
+ /* Perform security state specific initializations */
+ switch (security_state) {
+ case SECURE:
+ setup_secure_context(ctx, ep);
+ break;
+#if ENABLE_RME
+ case REALM:
+ setup_realm_context(ctx, ep);
+ break;
+#endif
+ case NON_SECURE:
+ setup_ns_context(ctx, ep);
+ break;
+ default:
+ ERROR("Invalid security state\n");
+ panic();
+ break;
+ }
+}
+
+/*******************************************************************************
* Enable architecture extensions on first entry to Non-secure world.
* When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
* it is zero.
@@ -393,6 +481,10 @@
trbe_enable();
#endif /* ENABLE_TRBE_FOR_NS */
+#if ENABLE_BRBE_FOR_NS
+ brbe_enable();
+#endif /* ENABLE_BRBE_FOR_NS */
+
#if ENABLE_SYS_REG_TRACE_FOR_NS
sys_reg_trace_enable(ctx);
#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */
@@ -706,11 +798,47 @@
if ((security_state != SECURE) ||
((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
cpu_context_t *ctx;
+ el2_sysregs_t *el2_sysregs_ctx;
ctx = cm_get_context(security_state);
assert(ctx != NULL);
+ el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
+
- el2_sysregs_context_save(get_el2_sysregs_ctx(ctx));
+ el2_sysregs_context_save_common(el2_sysregs_ctx);
+#if ENABLE_SPE_FOR_LOWER_ELS
+ el2_sysregs_context_save_spe(el2_sysregs_ctx);
+#endif
+#if CTX_INCLUDE_MTE_REGS
+ el2_sysregs_context_save_mte(el2_sysregs_ctx);
+#endif
+#if ENABLE_MPAM_FOR_LOWER_ELS
+ el2_sysregs_context_save_mpam(el2_sysregs_ctx);
+#endif
+#if ENABLE_FEAT_FGT
+ el2_sysregs_context_save_fgt(el2_sysregs_ctx);
+#endif
+#if ENABLE_FEAT_ECV
+ el2_sysregs_context_save_ecv(el2_sysregs_ctx);
+#endif
+#if ENABLE_FEAT_VHE
+ el2_sysregs_context_save_vhe(el2_sysregs_ctx);
+#endif
+#if RAS_EXTENSION
+ el2_sysregs_context_save_ras(el2_sysregs_ctx);
+#endif
+#if CTX_INCLUDE_NEVE_REGS
+ el2_sysregs_context_save_nv2(el2_sysregs_ctx);
+#endif
+#if ENABLE_TRF_FOR_NS
+ el2_sysregs_context_save_trf(el2_sysregs_ctx);
+#endif
+#if ENABLE_FEAT_CSV2_2
+ el2_sysregs_context_save_csv2(el2_sysregs_ctx);
+#endif
+#if ENABLE_FEAT_HCX
+ el2_sysregs_context_save_hcx(el2_sysregs_ctx);
+#endif
}
}
@@ -728,16 +856,100 @@
if ((security_state != SECURE) ||
((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
cpu_context_t *ctx;
+ el2_sysregs_t *el2_sysregs_ctx;
ctx = cm_get_context(security_state);
assert(ctx != NULL);
+ el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
+
- el2_sysregs_context_restore(get_el2_sysregs_ctx(ctx));
+ el2_sysregs_context_restore_common(el2_sysregs_ctx);
+#if ENABLE_SPE_FOR_LOWER_ELS
+ el2_sysregs_context_restore_spe(el2_sysregs_ctx);
+#endif
+#if CTX_INCLUDE_MTE_REGS
+ el2_sysregs_context_restore_mte(el2_sysregs_ctx);
+#endif
+#if ENABLE_MPAM_FOR_LOWER_ELS
+ el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
+#endif
+#if ENABLE_FEAT_FGT
+ el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
+#endif
+#if ENABLE_FEAT_ECV
+ el2_sysregs_context_restore_ecv(el2_sysregs_ctx);
+#endif
+#if ENABLE_FEAT_VHE
+ el2_sysregs_context_restore_vhe(el2_sysregs_ctx);
+#endif
+#if RAS_EXTENSION
+ el2_sysregs_context_restore_ras(el2_sysregs_ctx);
+#endif
+#if CTX_INCLUDE_NEVE_REGS
+ el2_sysregs_context_restore_nv2(el2_sysregs_ctx);
+#endif
+#if ENABLE_TRF_FOR_NS
+ el2_sysregs_context_restore_trf(el2_sysregs_ctx);
+#endif
+#if ENABLE_FEAT_CSV2_2
+ el2_sysregs_context_restore_csv2(el2_sysregs_ctx);
+#endif
+#if ENABLE_FEAT_HCX
+ el2_sysregs_context_restore_hcx(el2_sysregs_ctx);
+#endif
}
}
#endif /* CTX_INCLUDE_EL2_REGS */
/*******************************************************************************
+ * This function is used to exit to Non-secure world. If CTX_INCLUDE_EL2_REGS
+ * is enabled, it restores EL1 and EL2 sysreg contexts instead of directly
+ * updating EL1 and EL2 registers. Otherwise, it calls the generic
+ * cm_prepare_el3_exit function.
+ ******************************************************************************/
+void cm_prepare_el3_exit_ns(void)
+{
+#if CTX_INCLUDE_EL2_REGS
+ cpu_context_t *ctx = cm_get_context(NON_SECURE);
+ assert(ctx != NULL);
+
+ /* Assert that EL2 is used. */
+#if ENABLE_ASSERTIONS
+ el3_state_t *state = get_el3state_ctx(ctx);
+ u_register_t scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
+#endif
+ assert(((scr_el3 & SCR_HCE_BIT) != 0UL) &&
+ (el_implemented(2U) != EL_IMPL_NONE));
+
+ /*
+ * Currently some extensions are configured using
+ * direct register updates. Therefore, do this here
+ * instead of when setting up context.
+ */
+ manage_extensions_nonsecure(0, ctx);
+
+ /*
+ * Set the NS bit to be able to access the ICC_SRE_EL2
+ * register when restoring context.
+ */
+ write_scr_el3(read_scr_el3() | SCR_NS_BIT);
+
+ /*
+ * Ensure the NS bit change is committed before the EL2/EL1
+ * state restoration.
+ */
+ isb();
+
+ /* Restore EL2 and EL1 sysreg contexts */
+ cm_el2_sysregs_context_restore(NON_SECURE);
+ cm_el1_sysregs_context_restore(NON_SECURE);
+ cm_set_next_eret_context(NON_SECURE);
+#else
+ cm_prepare_el3_exit(NON_SECURE);
+#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
* state.
diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c
index d329c3d..72566fd 100644
--- a/lib/extensions/amu/aarch64/amu.c
+++ b/lib/extensions/amu/aarch64/amu.c
@@ -75,7 +75,7 @@
((value << CPTR_EL2_TAM_SHIFT) & CPTR_EL2_TAM_BIT));
}
-static inline __unused void write_cptr_el3_tam(cpu_context_t *ctx, uint64_t tam)
+static inline __unused void ctx_write_cptr_el3_tam(cpu_context_t *ctx, uint64_t tam)
{
uint64_t value = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3);
@@ -85,6 +85,16 @@
write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, value);
}
+static inline __unused void ctx_write_scr_el3_amvoffen(cpu_context_t *ctx, uint64_t amvoffen)
+{
+ uint64_t value = read_ctx_reg(get_el3state_ctx(ctx), CTX_SCR_EL3);
+
+ value &= ~SCR_AMVOFFEN_BIT;
+ value |= (amvoffen << SCR_AMVOFFEN_SHIFT) & SCR_AMVOFFEN_BIT;
+
+ write_ctx_reg(get_el3state_ctx(ctx), CTX_SCR_EL3, value);
+}
+
static inline __unused void write_hcr_el2_amvoffen(uint64_t value)
{
write_hcr_el2((read_hcr_el2() & ~HCR_AMVOFFEN_BIT) |
@@ -226,7 +236,7 @@
* in 'ctx'. Set CPTR_EL3.TAM to zero so that any accesses to
* the Activity Monitor registers do not trap to EL3.
*/
- write_cptr_el3_tam(ctx, 0U);
+ ctx_write_cptr_el3_tam(ctx, 0U);
/*
* Retrieve the number of architected counters. All of these counters
@@ -285,6 +295,13 @@
* used.
*/
write_hcr_el2_amvoffen(0U);
+ } else {
+ /*
+ * Virtual offset registers are only accessible from EL3
+ * and EL2, when clear, this bit traps accesses from EL2
+ * so we set it to 1 when EL2 is present.
+ */
+ ctx_write_scr_el3_amvoffen(ctx, 1U);
}
#if AMU_RESTRICT_COUNTERS
diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c
new file mode 100644
index 0000000..1982619
--- /dev/null
+++ b/lib/extensions/brbe/brbe.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+
+void brbe_enable(void)
+{
+ uint64_t val;
+
+ if (is_feat_brbe_present()) {
+ /*
+ * MDCR_EL3.SBRBE = 0b01
+ *
+ * Allows BRBE usage in non-secure world and prohibited in
+ * secure world.
+ */
+ val = read_mdcr_el3();
+ val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
+ val |= (0x1UL << MDCR_SBRBE_SHIFT);
+ write_mdcr_el3(val);
+ }
+}
diff --git a/lib/extensions/mpam/mpam.c b/lib/extensions/mpam/mpam.c
index 65601dd..884d480 100644
--- a/lib/extensions/mpam/mpam.c
+++ b/lib/extensions/mpam/mpam.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,7 +27,6 @@
/*
* If EL2 is implemented but unused, disable trapping to EL2 when lower
* ELs access their own MPAM registers.
- * If EL2 is implemented and used, enable trapping to EL2.
*/
if (el2_unused) {
write_mpam2_el2(0ULL);
@@ -35,12 +34,5 @@
if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U) {
write_mpamhcr_el2(0ULL);
}
- } else {
- write_mpam2_el2(MPAM2_EL2_TRAPMPAM0EL1 |
- MPAM2_EL2_TRAPMPAM1EL1);
-
- if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U) {
- write_mpamhcr_el2(MPAMHCR_EL2_TRAP_MPAMIDR_EL1);
- }
}
}
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index 1c2b984..958b623 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -37,6 +37,8 @@
/* Make sure SME is implemented in hardware before continuing. */
if (!feat_sme_supported()) {
+ /* Perhaps the hardware supports SVE only */
+ sve_enable(context);
return;
}
@@ -83,6 +85,8 @@
/* Make sure SME is implemented in hardware before continuing. */
if (!feat_sme_supported()) {
+ /* Perhaps the hardware supports SVE only */
+ sve_disable(context);
return;
}
diff --git a/lib/extensions/sve/sve.c b/lib/extensions/sve/sve.c
index aa8904b..f7dcc76 100644
--- a/lib/extensions/sve/sve.c
+++ b/lib/extensions/sve/sve.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,9 +8,14 @@
#include <arch.h>
#include <arch_helpers.h>
+#include <lib/cassert.h>
#include <lib/el3_runtime/pubsub.h>
#include <lib/extensions/sve.h>
+CASSERT(SVE_VECTOR_LEN <= 2048, assert_sve_vl_too_long);
+CASSERT(SVE_VECTOR_LEN >= 128, assert_sve_vl_too_short);
+CASSERT((SVE_VECTOR_LEN % 128) == 0, assert_sve_vl_granule);
+
/*
* Converts SVE vector size restriction in bytes to LEN according to ZCR_EL3 documentation.
* VECTOR_SIZE = (LEN+1) * 128
@@ -39,9 +44,9 @@
cptr_el3 = (cptr_el3 | CPTR_EZ_BIT) & ~(TFP_BIT);
write_ctx_reg(get_el3state_ctx(context), CTX_CPTR_EL3, cptr_el3);
- /* Restrict maximum SVE vector length (SVE_VECTOR_LENGTH+1) * 128. */
+ /* Restrict maximum SVE vector length (SVE_VECTOR_LEN+1) * 128. */
write_ctx_reg(get_el3state_ctx(context), CTX_ZCR_EL3,
- (ZCR_EL3_LEN_MASK & CONVERT_SVE_LENGTH(512)));
+ (ZCR_EL3_LEN_MASK & CONVERT_SVE_LENGTH(SVE_VECTOR_LEN)));
}
void sve_disable(cpu_context_t *context)
diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
index 9f754d5..b346387 100644
--- a/lib/extensions/trbe/trbe.c
+++ b/lib/extensions/trbe/trbe.c
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
+#include <arch_features.h>
#include <arch_helpers.h>
#include <lib/el3_runtime/pubsub.h>
#include <lib/extensions/trbe.h>
@@ -18,20 +19,11 @@
__asm__ volatile("hint #18");
}
-static bool trbe_supported(void)
-{
- uint64_t features;
-
- features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEBUFFER_SHIFT;
- return ((features & ID_AA64DFR0_TRACEBUFFER_MASK) ==
- ID_AA64DFR0_TRACEBUFFER_SUPPORTED);
-}
-
void trbe_enable(void)
{
uint64_t val;
- if (trbe_supported()) {
+ if (is_feat_trbe_present()) {
/*
* MDCR_EL3.NSTB = 0b11
* Allow access of trace buffer control registers from NS-EL1
@@ -46,7 +38,7 @@
static void *trbe_drain_trace_buffers_hook(const void *arg __unused)
{
- if (trbe_supported()) {
+ if (is_feat_trbe_present()) {
/*
* Before switching from normal world to secure world
* the trace buffers need to be drained out to memory. This is
diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c
index 34623fb..3038c09 100644
--- a/lib/fconf/fconf_dyn_cfg_getter.c
+++ b/lib/fconf/fconf_dyn_cfg_getter.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,13 +29,15 @@
* This function is used to alloc memory for config information from
* global pool and set the configuration information.
*/
-void set_config_info(uintptr_t config_addr, uint32_t config_max_size,
- unsigned int config_id)
+void set_config_info(uintptr_t config_addr, uintptr_t ns_config_addr,
+ uint32_t config_max_size,
+ unsigned int config_id)
{
struct dyn_cfg_dtb_info_t *dtb_info;
dtb_info = pool_alloc(&dtb_info_pool);
dtb_info->config_addr = config_addr;
+ dtb_info->ns_config_addr = ns_config_addr;
dtb_info->config_max_size = config_max_size;
dtb_info->config_id = config_id;
}
@@ -88,7 +90,7 @@
*/
if (dtb_infos[0].config_id == 0U) {
uint32_t config_max_size = fdt_totalsize(dtb);
- set_config_info(config, config_max_size, FW_CONFIG_ID);
+ set_config_info(config, ~0UL, config_max_size, FW_CONFIG_ID);
}
/* Find the node offset point to "fconf,dyn_cfg-dtb_registry" compatible property */
@@ -102,6 +104,7 @@
fdt_for_each_subnode(child, dtb, node) {
uint32_t config_max_size, config_id;
uintptr_t config_addr;
+ uintptr_t ns_config_addr = ~0UL;
uint64_t val64;
/* Read configuration dtb information */
@@ -129,7 +132,14 @@
VERBOSE("\tmax-size = 0x%x\n", config_max_size);
VERBOSE("\tconfig-id = %u\n", config_id);
- set_config_info(config_addr, config_max_size, config_id);
+ rc = fdt_read_uint64(dtb, child, "ns-load-address", &val64);
+ if (rc == 0) {
+ ns_config_addr = (uintptr_t)val64;
+ VERBOSE("\tns-load-address = %lx\n", ns_config_addr);
+ }
+
+ set_config_info(config_addr, ns_config_addr, config_max_size,
+ config_id);
}
if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c
index d6fbc04..a6e17a3 100644
--- a/lib/gpt_rme/gpt_rme.c
+++ b/lib/gpt_rme/gpt_rme.c
@@ -693,10 +693,6 @@
return -EPERM;
}
- /* Invalidate any stale TLB entries */
- tlbipaallos();
- dsb();
-
/* Write the base address of the L0 tables into GPTBR */
write_gptbr_el3(((gpt_config.plat_gpt_l0_base >> GPTBR_BADDR_VAL_SHIFT)
>> GPTBR_BADDR_SHIFT) & GPTBR_BADDR_MASK);
@@ -718,6 +714,15 @@
gpccr_el3 |= SET_GPCCR_ORGN(GPCCR_ORGN_WB_RA_WA);
gpccr_el3 |= SET_GPCCR_IRGN(GPCCR_IRGN_WB_RA_WA);
+ /* Prepopulate GPCCR_EL3 but don't enable GPC yet */
+ write_gpccr_el3(gpccr_el3);
+ isb();
+
+ /* Invalidate any stale TLB entries and any cached register fields */
+ tlbipaallos();
+ dsb();
+ isb();
+
/* Enable GPT */
gpccr_el3 |= GPCCR_GPC_BIT;
@@ -1076,7 +1081,7 @@
VERBOSE(" Caller: %u, Current GPI: %u\n", src_sec_state,
gpi_info.gpi);
spin_unlock(&gpt_lock);
- return -EINVAL;
+ return -EPERM;
}
if (src_sec_state == SMC_FROM_SECURE) {
@@ -1197,7 +1202,7 @@
VERBOSE(" Caller: %u, Current GPI: %u\n", src_sec_state,
gpi_info.gpi);
spin_unlock(&gpt_lock);
- return -EINVAL;
+ return -EPERM;
}
diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c
index 675d243..12f51c0 100644
--- a/lib/libc/snprintf.c
+++ b/lib/libc/snprintf.c
@@ -11,6 +11,16 @@
#include <common/debug.h>
#include <plat/common/platform.h>
+#define get_num_va_args(_args, _lcount) \
+ (((_lcount) > 1) ? va_arg(_args, long long int) : \
+ (((_lcount) == 1) ? va_arg(_args, long int) : \
+ va_arg(_args, int)))
+
+#define get_unum_va_args(_args, _lcount) \
+ (((_lcount) > 1) ? va_arg(_args, unsigned long long int) : \
+ (((_lcount) == 1) ? va_arg(_args, unsigned long int) : \
+ va_arg(_args, unsigned int)))
+
#define CHECK_AND_PUT_CHAR(buf, size, chars_printed, ch) \
do { \
if ((chars_printed) < (size)) { \
@@ -80,6 +90,11 @@
* %u - unsigned decimal format
* %p - pointer format
*
+ * The following length specifiers are supported by this print
+ * %l - long int
+ * %ll - long long int
+ * %z - size_t sized integer formats
+ *
* The following padding specifiers are supported by this print
* %0NN - Left-pad the number with 0s (NN is a decimal number)
* %NN - Left-pad the number or string with spaces (NN is a decimal number)
@@ -101,6 +116,7 @@
bool left;
bool capitalise;
size_t chars_printed = 0U;
+ unsigned int l_count;
if (n == 0U) {
/* There isn't space for anything. */
@@ -118,6 +134,7 @@
padc ='\0';
padn = 0;
capitalise = false;
+ l_count = 0;
if (*fmt == '%') {
fmt++;
@@ -152,7 +169,7 @@
case 'i':
case 'd':
- num = va_arg(args, int);
+ num = get_num_va_args(args, l_count);
if (num < 0) {
CHECK_AND_PUT_CHAR(s, n, chars_printed,
@@ -170,10 +187,18 @@
string_print(&s, n, &chars_printed, str);
break;
case 'u':
- unum = va_arg(args, unsigned int);
+ unum = get_unum_va_args(args, l_count);
unsigned_num_print(&s, n, &chars_printed,
unum, 10, padc, padn, false);
break;
+ case 'z':
+ l_count = 1;
+ fmt++;
+ goto loop;
+ case 'l':
+ l_count++;
+ fmt++;
+ goto loop;
case 'p':
unum = (uintptr_t)va_arg(args, void *);
if (unum > 0U) {
@@ -186,7 +211,7 @@
case 'X':
capitalise = true;
case 'x':
- unum = va_arg(args, unsigned int);
+ unum = get_unum_va_args(args, l_count);
unsigned_num_print(&s, n, &chars_printed,
unum, 16, padc, padn,
capitalise);
diff --git a/lib/locks/bakery/bakery_lock_normal.c b/lib/locks/bakery/bakery_lock_normal.c
index 7d35dea..faea6c5 100644
--- a/lib/locks/bakery/bakery_lock_normal.c
+++ b/lib/locks/bakery/bakery_lock_normal.c
@@ -83,7 +83,7 @@
}
/* Helper function to check if the lock is acquired */
-static inline bool is_lock_acquired(const bakery_info_t *my_bakery_info,
+static inline __unused bool is_lock_acquired(const bakery_info_t *my_bakery_info,
bool is_cached)
{
/*
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index 72979cd..d30248f 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -192,8 +192,17 @@
&header->optee_image_list[num]);
} else if (header->optee_image_list[num].image_id ==
OPTEE_PAGED_IMAGE_ID) {
- ret = parse_optee_image(paged_image_info,
- &header->optee_image_list[num]);
+ if (paged_image_info == NULL) {
+ if (header->optee_image_list[num].size != 0U) {
+ ERROR("Paged image is not supported\n");
+ return -1;
+ }
+
+ continue;
+ } else {
+ ret = parse_optee_image(paged_image_info,
+ &header->optee_image_list[num]);
+ }
} else {
ERROR("Parse optee image failed.\n");
return -1;
@@ -215,8 +224,10 @@
* header image arguments so that can be read by the
* BL32 SPD.
*/
- header_ep->args.arg1 = paged_image_info->image_base;
- header_ep->args.arg2 = paged_image_info->image_size;
+ if (paged_image_info != NULL) {
+ header_ep->args.arg1 = paged_image_info->image_base;
+ header_ep->args.arg2 = paged_image_info->image_size;
+ }
/* Set OPTEE runtime arch - aarch32/aarch64 */
if (header->arch == 0) {
diff --git a/lib/psa/initial_attestation.c b/lib/psa/initial_attestation.c
new file mode 100644
index 0000000..44498a8
--- /dev/null
+++ b/lib/psa/initial_attestation.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <initial_attestation.h>
+#include <psa/client.h>
+#include <psa_manifest/sid.h>
+
+#if !PLAT_RSS_NOT_SUPPORTED
+psa_status_t
+psa_initial_attest_get_token(const uint8_t *auth_challenge,
+ size_t challenge_size,
+ uint8_t *token_buf,
+ size_t token_buf_size,
+ size_t *token_size)
+{
+ psa_status_t status;
+ psa_invec in_vec[] = {
+ {auth_challenge, challenge_size}
+ };
+ psa_outvec out_vec[] = {
+ {token_buf, token_buf_size},
+ };
+
+ status = psa_call(RSS_ATTESTATION_SERVICE_HANDLE, RSS_ATTEST_GET_TOKEN,
+ in_vec, IOVEC_LEN(in_vec),
+ out_vec, IOVEC_LEN(out_vec));
+
+ if (status == PSA_SUCCESS) {
+ *token_size = out_vec[0].len;
+ }
+
+ return status;
+}
+
+#else /* !PLAT_RSS_NOT_SUPPORTED */
+
+#include <string.h>
+
+static const uint8_t platform_token[] = {
+ 0xD2, 0x84, 0x43, 0xA1, 0x01, 0x26, 0xA0, 0x59,
+ 0x02, 0xBE, 0xAA, 0x3A, 0x00, 0x01, 0x24, 0xFF,
+ 0x58, 0x20, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
+ 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
+ 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
+ 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
+ 0xAB, 0xAB, 0x3A, 0x00, 0x01, 0x24, 0xFB, 0x58,
+ 0x20, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE,
+ 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
+ 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
+ 0xBF, 0x3A, 0x00, 0x01, 0x25, 0x00, 0x58, 0x21,
+ 0x01, 0xFA, 0x58, 0x75, 0x5F, 0x65, 0x86, 0x27,
+ 0xCE, 0x54, 0x60, 0xF2, 0x9B, 0x75, 0x29, 0x67,
+ 0x13, 0x24, 0x8C, 0xAE, 0x7A, 0xD9, 0xE2, 0x98,
+ 0x4B, 0x90, 0x28, 0x0E, 0xFC, 0xBC, 0xB5, 0x02,
+ 0x48, 0x3A, 0x00, 0x01, 0x24, 0xFA, 0x58, 0x20,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0x3A, 0x00, 0x01, 0x24, 0xF8, 0x20, 0x3A, 0x00,
+ 0x01, 0x24, 0xF9, 0x00, 0x3A, 0x00, 0x01, 0x24,
+ 0xFD, 0x85, 0xA5, 0x05, 0x58, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x60,
+ 0x01, 0x65, 0x42, 0x4C, 0x31, 0x5F, 0x32, 0x06,
+ 0x66, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x02,
+ 0x58, 0x20, 0xF8, 0xB7, 0xCE, 0xAD, 0x9B, 0xE4,
+ 0x5A, 0x8F, 0x5C, 0x52, 0x6F, 0x0C, 0x05, 0x25,
+ 0x8F, 0xF3, 0xE9, 0x81, 0xDC, 0xBC, 0xF2, 0x05,
+ 0x7F, 0x33, 0xF6, 0xBB, 0xDC, 0xD9, 0x4D, 0xA2,
+ 0x34, 0x3A, 0xA5, 0x05, 0x58, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x67,
+ 0x31, 0x2E, 0x37, 0x2E, 0x32, 0x2B, 0x30, 0x01,
+ 0x63, 0x42, 0x4C, 0x32, 0x06, 0x66, 0x53, 0x48,
+ 0x41, 0x32, 0x35, 0x36, 0x02, 0x58, 0x20, 0x3A,
+ 0xE5, 0x9E, 0x40, 0xA9, 0x6B, 0xD5, 0x29, 0x1C,
+ 0xAB, 0x7A, 0x5F, 0xBD, 0x1F, 0x9A, 0xA6, 0x52,
+ 0xFB, 0x77, 0x7D, 0xA3, 0xEC, 0x9C, 0x29, 0xBC,
+ 0xE6, 0x5B, 0x3B, 0x43, 0xFC, 0x9D, 0x26, 0xA5,
+ 0x05, 0x58, 0x20, 0xBF, 0xE6, 0xD8, 0x6F, 0x88,
+ 0x26, 0xF4, 0xFF, 0x97, 0xFB, 0x96, 0xC4, 0xE6,
+ 0xFB, 0xC4, 0x99, 0x3E, 0x46, 0x19, 0xFC, 0x56,
+ 0x5D, 0xA2, 0x6A, 0xDF, 0x34, 0xC3, 0x29, 0x48,
+ 0x9A, 0xDC, 0x38, 0x04, 0x67, 0x31, 0x2E, 0x35,
+ 0x2E, 0x30, 0x2B, 0x30, 0x01, 0x64, 0x52, 0x54,
+ 0x5F, 0x30, 0x06, 0x66, 0x53, 0x48, 0x41, 0x32,
+ 0x35, 0x36, 0x02, 0x58, 0x20, 0x47, 0x94, 0x9D,
+ 0x27, 0x33, 0x82, 0x45, 0x1A, 0xDD, 0x25, 0xF4,
+ 0x9A, 0x89, 0x6F, 0x5F, 0xD9, 0xB0, 0xE8, 0x14,
+ 0xD3, 0xA4, 0x9B, 0x53, 0xB0, 0x44, 0x0B, 0xCF,
+ 0x32, 0x1A, 0xC4, 0xD2, 0x65, 0xA5, 0x05, 0x58,
+ 0x20, 0xB3, 0x60, 0xCA, 0xF5, 0xC9, 0x8C, 0x6B,
+ 0x94, 0x2A, 0x48, 0x82, 0xFA, 0x9D, 0x48, 0x23,
+ 0xEF, 0xB1, 0x66, 0xA9, 0xEF, 0x6A, 0x6E, 0x4A,
+ 0xA3, 0x7C, 0x19, 0x19, 0xED, 0x1F, 0xCC, 0xC0,
+ 0x49, 0x04, 0x67, 0x30, 0x2E, 0x30, 0x2E, 0x37,
+ 0x2B, 0x30, 0x01, 0x64, 0x52, 0x54, 0x5F, 0x31,
+ 0x06, 0x66, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
+ 0x02, 0x58, 0x20, 0xCD, 0x38, 0xBE, 0xC8, 0xB7,
+ 0xC0, 0x9E, 0xD5, 0x24, 0x30, 0xFE, 0xC8, 0xD0,
+ 0x19, 0x12, 0x56, 0xB2, 0x7A, 0xA5, 0x53, 0x6F,
+ 0xBC, 0x7D, 0x09, 0xCA, 0x11, 0xDD, 0x90, 0xD7,
+ 0xD6, 0x70, 0xFD, 0xA5, 0x05, 0x58, 0x20, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x04,
+ 0x60, 0x01, 0x60, 0x06, 0x66, 0x53, 0x48, 0x41,
+ 0x32, 0x35, 0x36, 0x02, 0x58, 0x20, 0x28, 0x3D,
+ 0x0C, 0x25, 0x22, 0x0C, 0x87, 0x46, 0xA0, 0x58,
+ 0x64, 0x6C, 0x0B, 0x14, 0x37, 0x39, 0x40, 0x9D,
+ 0x2D, 0x11, 0xD1, 0xCC, 0x54, 0x51, 0xB4, 0x29,
+ 0x22, 0xCD, 0x70, 0x92, 0x71, 0xC3, 0x3A, 0x00,
+ 0x01, 0x25, 0x01, 0x77, 0x77, 0x77, 0x77, 0x2E,
+ 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x66,
+ 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x2E,
+ 0x6F, 0x72, 0x67, 0x3A, 0x00, 0x01, 0x24, 0xF7,
+ 0x71, 0x50, 0x53, 0x41, 0x5F, 0x49, 0x4F, 0x54,
+ 0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45,
+ 0x5F, 0x31, 0x3A, 0x00, 0x01, 0x24, 0xFC, 0x70,
+ 0x30, 0x36, 0x30, 0x34, 0x35, 0x36, 0x35, 0x32,
+ 0x37, 0x32, 0x38, 0x32, 0x39, 0x31, 0x30, 0x30,
+ 0x58, 0x40, 0x1E, 0x0D, 0x2B, 0xD8, 0x7A, 0xC9,
+ 0x2D, 0xCB, 0x73, 0xD1, 0x42, 0x2F, 0xBF, 0xDA,
+ 0x24, 0x71, 0xE2, 0xAF, 0xEA, 0x48, 0x60, 0x17,
+ 0x23, 0x75, 0x64, 0xAC, 0xCC, 0x23, 0xA2, 0x67,
+ 0xC4, 0xE7, 0x8F, 0x1C, 0x7C, 0x68, 0x49, 0x42,
+ 0x4D, 0xDA, 0xC6, 0xD6, 0x21, 0x1C, 0xAA, 0x00,
+ 0xDA, 0x1E, 0x68, 0x56, 0xA3, 0x48, 0xEE, 0xA7,
+ 0x92, 0xA9, 0x09, 0x83, 0x42, 0x04, 0x06, 0x9E,
+ 0x62, 0xBB
+};
+
+psa_status_t
+psa_initial_attest_get_token(const uint8_t *auth_challenge,
+ size_t challenge_size,
+ uint8_t *token_buf,
+ size_t token_buf_size,
+ size_t *token_size)
+{
+ (void)auth_challenge;
+ (void)challenge_size;
+
+ if (token_buf_size < sizeof(platform_token)) {
+ return PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+
+ (void)memcpy(token_buf, platform_token, sizeof(platform_token));
+ *token_size = sizeof(platform_token);
+
+ return PSA_SUCCESS;
+}
+#endif /* !PLAT_RSS_NOT_SUPPORTED */
diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c
new file mode 100644
index 0000000..90e4ef3
--- /dev/null
+++ b/lib/psa/measured_boot.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <string.h>
+
+#include <common/debug.h>
+#include <measured_boot.h>
+#include <psa/client.h>
+#include <psa_manifest/sid.h>
+
+#include "measured_boot_private.h"
+
+static void print_byte_array(const uint8_t *array __unused, size_t len __unused)
+{
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+ size_t i;
+
+ if (array == NULL || len == 0U) {
+ (void)printf("\n");
+ } else {
+ for (i = 0U; i < len; ++i) {
+ (void)printf(" %02x", array[i]);
+ if ((i & U(0xF)) == U(0xF)) {
+ (void)printf("\n");
+ if (i < (len - 1U)) {
+ INFO("\t\t:");
+ }
+ }
+ }
+ }
+#endif
+}
+
+static void log_measurement(uint8_t index,
+ const uint8_t *signer_id,
+ size_t signer_id_size,
+ const uint8_t *version, /* string */
+ uint32_t measurement_algo,
+ const uint8_t *sw_type, /* string */
+ const uint8_t *measurement_value,
+ size_t measurement_value_size,
+ bool lock_measurement)
+{
+ INFO("Measured boot extend measurement:\n");
+ INFO(" - slot : %u\n", index);
+ INFO(" - signer_id :");
+ print_byte_array(signer_id, signer_id_size);
+ INFO(" - version : %s\n", version);
+ INFO(" - algorithm : %x\n", measurement_algo);
+ INFO(" - sw_type : %s\n", sw_type);
+ INFO(" - measurement :");
+ print_byte_array(measurement_value, measurement_value_size);
+ INFO(" - locking : %s\n", lock_measurement ? "true" : "false");
+}
+
+#if !PLAT_RSS_NOT_SUPPORTED
+psa_status_t
+rss_measured_boot_extend_measurement(uint8_t index,
+ const uint8_t *signer_id,
+ size_t signer_id_size,
+ const uint8_t *version,
+ size_t version_size,
+ uint32_t measurement_algo,
+ const uint8_t *sw_type,
+ size_t sw_type_size,
+ const uint8_t *measurement_value,
+ size_t measurement_value_size,
+ bool lock_measurement)
+{
+ struct measured_boot_extend_iovec_t extend_iov = {
+ .index = index,
+ .lock_measurement = lock_measurement,
+ .measurement_algo = measurement_algo,
+ .sw_type = {0},
+ .sw_type_size = sw_type_size,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &extend_iov,
+ .len = sizeof(struct measured_boot_extend_iovec_t)},
+ {.base = signer_id, .len = signer_id_size},
+ {.base = version, .len = version_size},
+ {.base = measurement_value, .len = measurement_value_size}
+ };
+
+ uint32_t sw_type_size_limited;
+
+ if (sw_type != NULL) {
+ sw_type_size_limited = (sw_type_size < SW_TYPE_MAX_SIZE) ?
+ sw_type_size : SW_TYPE_MAX_SIZE;
+ memcpy(extend_iov.sw_type, sw_type, sw_type_size_limited);
+ }
+
+ log_measurement(index, signer_id, signer_id_size,
+ version, measurement_algo, sw_type,
+ measurement_value, measurement_value_size,
+ lock_measurement);
+
+ return psa_call(RSS_MEASURED_BOOT_HANDLE,
+ RSS_MEASURED_BOOT_EXTEND,
+ in_vec, IOVEC_LEN(in_vec),
+ NULL, 0);
+}
+
+#else /* !PLAT_RSS_NOT_SUPPORTED */
+
+psa_status_t
+rss_measured_boot_extend_measurement(uint8_t index,
+ const uint8_t *signer_id,
+ size_t signer_id_size,
+ const uint8_t *version,
+ size_t version_size,
+ uint32_t measurement_algo,
+ const uint8_t *sw_type,
+ size_t sw_type_size,
+ const uint8_t *measurement_value,
+ size_t measurement_value_size,
+ bool lock_measurement)
+{
+ log_measurement(index, signer_id, signer_id_size,
+ version, measurement_algo, sw_type,
+ measurement_value, measurement_value_size,
+ lock_measurement);
+
+ return PSA_SUCCESS;
+}
+#endif /* !PLAT_RSS_NOT_SUPPORTED */
diff --git a/lib/psa/measured_boot_private.h b/lib/psa/measured_boot_private.h
new file mode 100644
index 0000000..649c3f6
--- /dev/null
+++ b/lib/psa/measured_boot_private.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_MEASURED_BOOT_PRIVATE_H
+#define PSA_MEASURED_BOOT_PRIVATE_H
+
+#include <stdint.h>
+
+/* Measured boot message types that distinguish its services */
+#define RSS_MEASURED_BOOT_EXTEND 1002U
+
+struct measured_boot_extend_iovec_t {
+ uint8_t index;
+ uint8_t lock_measurement;
+ uint32_t measurement_algo;
+ uint8_t sw_type[SW_TYPE_MAX_SIZE];
+ uint8_t sw_type_size;
+};
+
+#endif /* PSA_MEASURED_BOOT_PRIVATE_H */
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 170777f..b60ddbb 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1022,3 +1022,56 @@
return PSCI_E_SUCCESS;
}
+
+/*******************************************************************************
+ * This function verifies that all the other cores in the system have been
+ * turned OFF and the current CPU is the last running CPU in the system.
+ * Returns true if the current CPU is the last ON CPU or false otherwise.
+ *
+ * This API has following differences with psci_is_last_on_cpu
+ * 1. PSCI states are locked
+ * 2. It caters for "forest" topology instead of just "tree"
+ * TODO : Revisit both API's and unify them
+ ******************************************************************************/
+bool psci_is_last_on_cpu_safe(void)
+{
+ unsigned int this_core = plat_my_core_pos();
+ unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
+ unsigned int i = 0;
+
+ /*
+ * Traverse the forest of PSCI nodes, nodes with no parents
+ * (invalid-nodes) are the root nodes.
+ */
+ while ((i < PSCI_NUM_NON_CPU_PWR_DOMAINS) &&
+ (psci_non_cpu_pd_nodes[i].parent_node ==
+ PSCI_PARENT_NODE_INVALID)) {
+ psci_get_parent_pwr_domain_nodes(
+ psci_non_cpu_pd_nodes[i].cpu_start_idx,
+ PLAT_MAX_PWR_LVL, parent_nodes);
+
+ psci_acquire_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+
+ for (unsigned int core = 0U;
+ core < psci_non_cpu_pd_nodes[i].ncpus; core++) {
+ if (core == this_core) {
+ continue;
+ }
+
+ if (psci_get_aff_info_state_by_idx(core) !=
+ AFF_STATE_OFF) {
+ psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL,
+ parent_nodes);
+ VERBOSE("core=%u other than boot core=%u %s\n",
+ core, this_core, "running in the system");
+
+ return false;
+ }
+ }
+
+ psci_release_pwr_domain_locks(PLAT_MAX_PWR_LVL, parent_nodes);
+ i++;
+ }
+
+ return true;
+}
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index dd48e10..c70b377 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -229,5 +229,5 @@
* information that we had stashed away during the cpu_on
* call to set this cpu on its way.
*/
- cm_prepare_el3_exit(NON_SECURE);
+ cm_prepare_el3_exit_ns();
}
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 72bd6bd..61bd966 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -47,6 +47,9 @@
*/
#define PSCI_MAX_CPUS_INDEX 0xFFFFU
+/* Invalid parent */
+#define PSCI_PARENT_NODE_INVALID 0xFFFFFFFFU
+
/*
* Helper functions to get/set the fields of PSCI per-cpu data.
*/
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index da9f328..ffe3a91 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -331,5 +331,5 @@
* information that we had stashed away during the suspend
* call to set this cpu on its way.
*/
- cm_prepare_el3_exit(NON_SECURE);
+ cm_prepare_el3_exit_ns();
}
diff --git a/lib/xlat_tables_v2/ro_xlat_tables.mk b/lib/xlat_tables_v2/ro_xlat_tables.mk
index 7991e1a..fb8a426 100644
--- a/lib/xlat_tables_v2/ro_xlat_tables.mk
+++ b/lib/xlat_tables_v2/ro_xlat_tables.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020, ARM Limited. All rights reserved.
+# Copyright (c) 2020-2022, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -34,4 +34,8 @@
attributes, which is not possible once the translation tables \
have been made read-only.")
endif
+ ifeq (${SPMC_AT_EL3},1)
+ $(error "EL3 SPMC requires functionality from the dynamic translation \
+ library and is incompatible with ALLOW_RO_XLAT_TABLES.")
+ endif
endif
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
new file mode 100644
index 0000000..01e3e09
--- /dev/null
+++ b/make_helpers/arch_features.mk
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# This file lists all the checks related to the Architectural Feature
+# Enablement flags, based on the Architectural version.
+
+# Enable the features which are mandatory from ARCH version 8.1 and upwards.
+ifeq "8.1" "$(word 1, $(sort 8.1 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_PAN = 1
+ENABLE_FEAT_VHE = 1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.4 and upwards.
+ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_DIT = 1
+ENABLE_FEAT_SEL2 = 1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.5 and upwards.
+ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_SB = 1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.6 and upwards.
+ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_FGT = 1
+ENABLE_FEAT_ECV = 1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.7 and upwards.
+ifeq "8.7" "$(word 1, $(sort 8.7 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_HCX = 1
+endif
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 12aaee6..abdd4d0 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -489,13 +489,18 @@
$(ELF): romlib.bin
endif
+# MODULE_OBJS can be assigned by vendors with different compiled
+# object file path, and prebuilt object file path.
+$(eval OBJS += $(MODULE_OBJS))
+
$(ELF): $(OBJS) $(LINKERFILE) | $(1)_dirs libraries $(BL_LIBS)
$$(ECHO) " LD $$@"
ifdef MAKE_BUILD_STRINGS
$(call MAKE_BUILD_STRINGS, $(BUILD_DIR)/build_message.o)
else
@echo 'const char build_message[] = "Built : "$(BUILD_MESSAGE_TIMESTAMP); \
- const char version_string[] = "${VERSION_STRING}";' | \
+ const char version_string[] = "${VERSION_STRING}"; \
+ const char version[] = "${VERSION}";' | \
$$(CC) $$(TF_CFLAGS) $$(CFLAGS) -xc -c - -o $(BUILD_DIR)/build_message.o
endif
ifneq ($(findstring armlink,$(notdir $(LD))),)
@@ -507,7 +512,7 @@
$(BUILD_DIR)/build_message.o $(OBJS)
else ifneq ($(findstring gcc,$(notdir $(LD))),)
$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \
- -Wl,-T$(LINKERFILE) $(BUILD_DIR)/build_message.o \
+ -Wl,-dT $(LINKERFILE) $(EXTRA_LINKERFILE) $(BUILD_DIR)/build_message.o \
$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
else
$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index b39dcf4..5e73120 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -133,12 +133,18 @@
# Use BRANCH_PROTECTION to enable PAUTH.
ENABLE_PAUTH := 0
-# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
-ENABLE_FEAT_HCX := 0
-
# Flag to enable access to the HAFGRTR_EL2 register
ENABLE_FEAT_AMUv1 := 0
+# Flag to enable AMUv1p1 extension.
+ENABLE_FEAT_AMUv1p1 := 0
+
+# Flag to enable CSV2_2 extension.
+ENABLE_FEAT_CSV2_2 := 0
+
+# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
+ENABLE_FEAT_HCX := 0
+
# Flag to enable access to the HDFGRTR_EL2 register
ENABLE_FEAT_FGT := 0
@@ -148,6 +154,28 @@
# Flag to enable use of the DIT feature.
ENABLE_FEAT_DIT := 0
+# Flag to enable access to Privileged Access Never bit of PSTATE.
+ENABLE_FEAT_PAN := 0
+
+# Flag to enable access to the Random Number Generator registers
+ENABLE_FEAT_RNG := 0
+
+# Flag to enable support for EL3 trapping of reads of the RNDR and RNDRRS
+# registers, by setting SCR_EL3.TRNDR.
+ENABLE_FEAT_RNG_TRAP := 0
+
+# Flag to enable Speculation Barrier Instruction
+ENABLE_FEAT_SB := 0
+
+# Flag to enable Secure EL-2 feature.
+ENABLE_FEAT_SEL2 := 0
+
+# Flag to enable Virtualization Host Extensions
+ENABLE_FEAT_VHE := 0
+
+# Flag to enable delayed trapping of WFE instruction (FEAT_TWED)
+ENABLE_FEAT_TWED := 0
+
# By default BL31 encryption disabled
ENCRYPT_BL31 := 0
@@ -166,6 +194,9 @@
# Fault injection support
FAULT_INJECTION_SUPPORT := 0
+# Flag to enable architectural features detection mechanism
+FEATURE_DETECTION := 0
+
# Byte alignment that each component in FIP is aligned to
FIP_ALIGN := 0
@@ -230,6 +261,9 @@
# By default, BL1 acts as the reset handler, not BL31
RESET_TO_BL31 := 0
+# By default, clear the input registers when RESET_TO_BL31 is enabled
+RESET_TO_BL31_WITH_PARAMS := 0
+
# For Chain of Trust
SAVE_KEYS := 0
@@ -250,6 +284,10 @@
# separate memory region, which may be discontiguous from the rest of BL31.
SEPARATE_NOBITS_REGION := 0
+# Put BL2 NOLOAD sections (.bss, stacks, page tables) in a separate memory
+# region, platform Makefile is free to override this value.
+SEPARATE_BL2_NOLOAD_REGION := 0
+
# If the BL31 image initialisation code is recalimed after use for the secondary
# cores stack
RECLAIM_INIT_CODE := 0
@@ -260,6 +298,9 @@
# Enable the Management Mode (MM)-based Secure Partition Manager implementation
SPM_MM := 0
+# Use the FF-A SPMC implementation in EL3.
+SPMC_AT_EL3 := 0
+
# Use SPM at S-EL2 as a default config for SPMD
SPMD_SPM_AT_SEL2 := 1
@@ -336,6 +377,9 @@
endif
ENABLE_SVE_FOR_SWD := 0
+# Default SVE vector length to maximum architected value
+SVE_VECTOR_LEN := 2048
+
# SME defaults to disabled
ENABLE_SME_FOR_NS := 0
ENABLE_SME_FOR_SWD := 0
@@ -378,6 +422,13 @@
# Build option to provide openssl directory path
OPENSSL_DIR := /usr
+# Select the openssl binary provided in OPENSSL_DIR variable
+ifeq ("$(wildcard ${OPENSSL_DIR}/bin)", "")
+ OPENSSL_BIN_PATH = ${OPENSSL_DIR}/apps
+else
+ OPENSSL_BIN_PATH = ${OPENSSL_DIR}/bin
+endif
+
# Build option to use the SP804 timer instead of the generic one
USE_SP804_TIMER := 0
@@ -403,6 +454,11 @@
override ENABLE_TRBE_FOR_NS := 0
endif
+# By default, disable access to branch record buffer control registers from NS
+# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
+# if FEAT_BRBE is implemented.
+ENABLE_BRBE_FOR_NS := 0
+
# By default, disable access of trace system registers from NS lower
# ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
# system register trace is implemented.
@@ -412,3 +468,15 @@
# lower ELs, i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused
# if FEAT_TRF is implemented.
ENABLE_TRF_FOR_NS := 0
+
+# In v8.6+ platforms with delayed trapping of WFE being supported
+# via FEAT_TWED, this flag takes the delay value to be set in the
+# SCR_EL3.TWEDEL(4bit) field, when FEAT_TWED is implemented.
+# By default it takes 0, and need to be updated by the platforms.
+TWED_DELAY := 0
+
+# By default, disable the mocking of RSS provided services
+PLAT_RSS_NOT_SUPPORTED := 0
+
+# Dynamic Root of Trust for Measurement support
+DRTM_SUPPORT := 0
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index 0a280b4..5ef2d85 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -25,6 +25,9 @@
# KEY_SIZE
# ROT_KEY
# PROT_KEY
+# PLAT_KEY
+# SWD_ROT_KEY
+# CORE_SWD_KEY
# TRUSTED_WORLD_KEY
# NON_TRUSTED_WORLD_KEY
# SCP_BL2_KEY
@@ -46,10 +49,18 @@
$(eval $(call CERT_ADD_CMD_OPT,${NTFW_NVCTR_VAL},--ntfw-nvctr))
# Add Trusted Key certificate to the fiptool and cert_create command line options
+ifneq (${COT},cca)
$(eval $(call TOOL_ADD_PAYLOAD,${TRUSTED_KEY_CERT},--trusted-key-cert))
+else
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/cca.crt,--cca-cert))
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/core-swd.crt,--core-swd-cert))
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat-key.crt,--plat-key-cert))
+endif
# Add fwu certificate to the fiptool and cert_create command line options
+ifneq (${COT},cca)
$(eval $(call TOOL_ADD_PAYLOAD,${FWU_CERT},--fwu-cert,,FWU_))
+endif
# Add the keys to the cert_create command line options (private keys are NOT
# packed in the FIP). Developers can use their own keys by specifying the proper
@@ -63,6 +74,9 @@
$(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key)))
$(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,FWU_)))
$(if ${PROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PROT_KEY},--prot-key)))
+$(if ${PLAT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PLAT_KEY},--plat-key)))
+$(if ${SWD_ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${SWD_ROT_KEY},--swd-rot-key)))
+$(if ${CORE_SWD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${CORE_SWD_KEY},--core-swd-key)))
$(if ${TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_WORLD_KEY},--trusted-world-key)))
$(if ${NON_TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${NON_TRUSTED_WORLD_KEY},--non-trusted-world-key)))
@@ -70,25 +84,31 @@
# Add the BL2 CoT (image cert)
ifeq (${NEED_BL2},yes)
ifeq (${BL2_AT_EL3}, 0)
+ifneq (${COT},cca)
$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
endif
endif
+endif
# Add the SCP_BL2 CoT (key cert + img cert)
ifneq (${SCP_BL2},)
+ifneq (${COT},cca)
$(if ${SCP_BL2_KEY},$(eval $(call CERT_ADD_CMD_OPT,${SCP_BL2_KEY},--scp-fw-key)))
$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/scp_fw_content.crt,--scp-fw-cert))
$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/scp_fw_key.crt,--scp-fw-key-cert))
endif
+endif
ifeq (${ARCH},aarch64)
ifeq (${NEED_BL31},yes)
# Add the BL31 CoT (key cert + img cert)
$(if ${BL31_KEY},$(eval $(call CERT_ADD_CMD_OPT,${BL31_KEY},--soc-fw-key)))
+ifneq (${COT},cca)
$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_content.crt,--soc-fw-cert))
$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_key.crt,--soc-fw-key-cert))
endif
endif
+endif
# Add the BL32 CoT (key cert + img cert)
ifeq (${NEED_BL32},yes)
@@ -102,7 +122,9 @@
$(if ${BL33_KEY},$(eval $(call CERT_ADD_CMD_OPT,${BL33_KEY},--nt-fw-key)))
$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_content.crt,--nt-fw-cert))
ifneq (${COT},dualroot)
- $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_key.crt,--nt-fw-key-cert))
+ ifneq (${COT},cca)
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_key.crt,--nt-fw-key-cert))
+ endif
endif
endif
@@ -112,4 +134,7 @@
ifeq (${COT},dualroot)
$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat_sp_content.crt,--plat-sp-cert))
endif
+ifeq (${COT},cca)
+ $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/plat_sp_content.crt,--plat-sp-cert))
+endif
endif
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
index 26ea88e..b6d6f0b 100644
--- a/make_helpers/windows.mk
+++ b/make_helpers/windows.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -81,8 +81,9 @@
# by defining the MAKE_BUILD_STRINGS macro.
BUILT_TIME_DATE_STRING = const char build_message[] = "Built : "${BUILD_MESSAGE_TIMESTAMP};
VERSION_STRING_MESSAGE = const char version_string[] = "${VERSION_STRING}";
+VERSION_MESSAGE = const char version[] = "${VERSION}";
define MAKE_BUILD_STRINGS
- @echo $$(BUILT_TIME_DATE_STRING) $$(VERSION_STRING_MESSAGE) | \
+ @echo $$(BUILT_TIME_DATE_STRING) $$(VERSION_STRING_MESSAGE) $$(VERSION_MESSAGE) | \
$$(CC) $$(TF_CFLAGS) $$(CFLAGS) -x c -c - -o $1
endef
diff --git a/package-lock.json b/package-lock.json
index 469c5f5..34e7dbd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "trusted-firmware-a",
- "version": "2.6.0",
+ "version": "2.7.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "trusted-firmware-a",
- "version": "2.6.0",
+ "version": "2.7.0",
"hasInstallScript": true,
"license": "BSD-3-Clause",
"devDependencies": {
@@ -843,9 +843,9 @@
}
},
"node_modules/commitizen/node_modules/ansi-regex": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
- "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
"dev": true,
"engines": {
"node": ">=6"
@@ -1073,9 +1073,9 @@
}
},
"node_modules/commitizen/node_modules/string-width/node_modules/ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
+ "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
"dev": true,
"engines": {
"node": ">=4"
@@ -4792,9 +4792,9 @@
"dev": true
},
"ansi-regex": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
- "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+ "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
"dev": true
},
"ansi-styles": {
@@ -4975,9 +4975,9 @@
},
"dependencies": {
"ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
+ "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
"dev": true
},
"strip-ansi": {
diff --git a/package.json b/package.json
index e5cd924..0284e6f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "trusted-firmware-a",
- "version": "2.6.0",
+ "version": "2.7.0",
"license": "BSD-3-Clause",
"private": true,
"scripts": {
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 34fdaf6..61c1dbe 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -27,6 +27,7 @@
plat/common/plat_gicv2.c \
plat/common/plat_psci_common.c \
${AW_PLAT}/common/sunxi_bl31_setup.c \
+ ${AW_PLAT}/${PLAT}/sunxi_idle_states.c \
${AW_PLAT}/common/sunxi_pm.c \
${AW_PLAT}/${PLAT}/sunxi_power.c \
${AW_PLAT}/common/sunxi_security.c \
@@ -65,6 +66,23 @@
$(eval $(call assert_boolean,SUNXI_SETUP_REGULATORS))
$(eval $(call add_define,SUNXI_SETUP_REGULATORS))
+SUNXI_BL31_IN_DRAM ?= 0
+$(eval $(call assert_boolean,SUNXI_BL31_IN_DRAM))
+
+ifeq (${SUNXI_BL31_IN_DRAM},1)
+SUNXI_AMEND_DTB := 1
+$(eval $(call add_define,SUNXI_BL31_IN_DRAM))
+endif
+
+SUNXI_AMEND_DTB ?= 0
+$(eval $(call assert_boolean,SUNXI_AMEND_DTB))
+$(eval $(call add_define,SUNXI_AMEND_DTB))
+
+ifeq (${SUNXI_AMEND_DTB},1)
+BL31_SOURCES += common/fdt_fixup.c \
+ ${AW_PLAT}/common/sunxi_prepare_dtb.c
+endif
+
# The bootloader is guaranteed to only run on CPU 0 by the boot ROM.
COLD_BOOT_SINGLE_CPU := 1
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index 49951e0..c9d075a 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -57,9 +57,10 @@
#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE \
(SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE - 0x200)
-#define PLAT_MAX_PWR_LVL_STATES U(2)
+/* These states are used directly for SCPI communication. */
+#define PLAT_MAX_PWR_LVL_STATES U(3)
#define PLAT_MAX_RET_STATE U(1)
-#define PLAT_MAX_OFF_STATE U(2)
+#define PLAT_MAX_OFF_STATE U(3)
#define PLAT_MAX_PWR_LVL U(2)
#define PLAT_NUM_PWR_DOMAINS (U(1) + \
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index ec50887..c17ef95 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -20,4 +20,7 @@
#define SUNXI_SOC_H616 0x1823
#define SUNXI_SOC_R329 0x1851
+#define JEDEC_ALLWINNER_BKID 9U
+#define JEDEC_ALLWINNER_MFID 0x9eU
+
#endif /* SUNXI_DEF_H */
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 6cf4670..6a38657 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -7,8 +7,12 @@
#ifndef SUNXI_PRIVATE_H
#define SUNXI_PRIVATE_H
+#include <common/fdt_fixup.h>
+
#include <lib/psci/psci.h>
+extern const struct psci_cpu_idle_state sunxi_idle_states[];
+
void sunxi_configure_mmu_el3(int flags);
void sunxi_cpu_on(u_register_t mpidr);
@@ -24,8 +28,13 @@
}
#endif
#if SUNXI_PSCI_USE_SCPI
+bool sunxi_psci_is_scpi(void);
int sunxi_set_scpi_psci_ops(const plat_psci_ops_t **psci_ops);
#else
+static inline bool sunxi_psci_is_scpi(void)
+{
+ return false;
+}
static inline int sunxi_set_scpi_psci_ops(const plat_psci_ops_t **psci_ops)
{
return -1;
@@ -41,7 +50,7 @@
int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb);
void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param);
-#ifdef SUNXI_BL31_IN_DRAM
+#if SUNXI_AMEND_DTB
void sunxi_prepare_dtb(void *fdt);
#else
static inline void sunxi_prepare_dtb(void *fdt)
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 14049e8..a32124a 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,6 +32,8 @@
static console_t console;
+static void *fdt;
+
static const gicv2_driver_data_t sunxi_gic_data = {
.gicd_base = SUNXI_GICD_BASE,
.gicc_base = SUNXI_GICC_BASE,
@@ -49,7 +51,7 @@
* entry point to find the load address, which should be followed by the
* size. Adding those together gives us the address of the DTB.
*/
-static void *sunxi_find_dtb(void)
+static void sunxi_find_dtb(void)
{
uint64_t *u_boot_base;
int i;
@@ -57,7 +59,7 @@
u_boot_base = (void *)SUNXI_BL33_VIRT_BASE;
for (i = 0; i < 2048 / sizeof(uint64_t); i++) {
- uint32_t *dtb_base;
+ void *dtb_base;
if (u_boot_base[i] != PRELOADED_BL33_BASE)
continue;
@@ -67,15 +69,13 @@
continue;
/* end of the image: base address + size */
- dtb_base = (void *)((char *)u_boot_base + u_boot_base[i + 1]);
-
- if (fdt_check_header(dtb_base) != 0)
- continue;
+ dtb_base = (char *)u_boot_base + u_boot_base[i + 1];
- return dtb_base;
+ if (fdt_check_header(dtb_base) == 0) {
+ fdt = dtb_base;
+ return;
+ }
}
-
- return NULL;
}
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
@@ -113,7 +113,6 @@
{
const char *soc_name;
uint16_t soc_id = sunxi_read_soc_id();
- void *fdt;
switch (soc_id) {
case SUNXI_SOC_A64:
@@ -139,7 +138,7 @@
generic_delay_timer_init();
- fdt = sunxi_find_dtb();
+ sunxi_find_dtb();
if (fdt) {
const char *model;
int length;
@@ -180,9 +179,15 @@
sunxi_pmic_setup(soc_id, fdt);
+ INFO("BL31: Platform setup done\n");
+}
+
+void bl31_plat_runtime_setup(void)
+{
+ /* Change the DTB if the configuration requires so. */
sunxi_prepare_dtb(fdt);
- INFO("BL31: Platform setup done\n");
+ console_switch_state(CONSOLE_FLAG_RUNTIME);
}
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 82410b1..092659c 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -8,7 +8,9 @@
#include <common/debug.h>
#include <lib/mmio.h>
+#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <services/arm_arch_svc.h>
#include <sunxi_def.h>
#include <sunxi_mmap.h>
@@ -157,3 +159,29 @@
return 0;
}
+
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ return SMC_ARCH_CALL_SUCCESS;
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
+
+int32_t plat_get_soc_version(void)
+{
+ int32_t ret;
+
+ ret = SOC_ID_SET_JEP_106(JEDEC_ALLWINNER_BKID, JEDEC_ALLWINNER_MFID);
+
+ return ret | (sunxi_read_soc_id() & SOC_ID_IMPL_DEF_MASK);
+}
+
+int32_t plat_get_soc_revision(void)
+{
+ uint32_t reg = mmio_read_32(SRAM_VER_REG);
+
+ return reg & GENMASK_32(7, 0);
+}
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index eb1b7e7..3772b4a 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -9,12 +9,22 @@
#include <platform_def.h>
#include <common/debug.h>
+#include <common/fdt_fixup.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
#include <sunxi_cpucfg.h>
#include <sunxi_private.h>
+static bool psci_is_scpi;
+
+#if SUNXI_PSCI_USE_SCPI
+bool sunxi_psci_is_scpi(void)
+{
+ return psci_is_scpi;
+}
+#endif
+
int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
{
/* The non-secure entry point must be in DRAM */
@@ -40,6 +50,7 @@
if (sunxi_set_scpi_psci_ops(psci_ops) == 0) {
INFO("PSCI: Suspend is available via SCPI\n");
+ psci_is_scpi = true;
} else {
INFO("PSCI: Suspend is unavailable\n");
sunxi_set_native_psci_ops(psci_ops);
diff --git a/plat/allwinner/sun50i_h616/prepare_dtb.c b/plat/allwinner/common/sunxi_prepare_dtb.c
similarity index 69%
rename from plat/allwinner/sun50i_h616/prepare_dtb.c
rename to plat/allwinner/common/sunxi_prepare_dtb.c
index e94b0b4..66af35a 100644
--- a/plat/allwinner/sun50i_h616/prepare_dtb.c
+++ b/plat/allwinner/common/sunxi_prepare_dtb.c
@@ -19,25 +19,34 @@
if (fdt == NULL || fdt_check_header(fdt) != 0) {
return;
}
- ret = fdt_open_into(fdt, fdt, 0x100000);
+
+ ret = fdt_open_into(fdt, fdt, 0x10000);
if (ret < 0) {
ERROR("Preparing devicetree at %p: error %d\n", fdt, ret);
return;
}
+#ifdef SUNXI_BL31_IN_DRAM
/* Reserve memory used by Trusted Firmware. */
if (fdt_add_reserved_memory(fdt, "tf-a@40000000", BL31_BASE,
BL31_LIMIT - BL31_BASE)) {
WARN("Failed to add reserved memory nodes to DT.\n");
- return;
}
+#endif
+
+ if (sunxi_psci_is_scpi()) {
+ ret = fdt_add_cpu_idle_states(fdt, sunxi_idle_states);
+ if (ret < 0) {
+ WARN("Failed to add idle states to DT: %d\n", ret);
+ }
+ }
ret = fdt_pack(fdt);
if (ret < 0) {
ERROR("Failed to pack devicetree at %p: error %d\n",
fdt, ret);
- } else {
- clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt));
- INFO("Changed devicetree to reserve BL31 memory.\n");
}
+
+ clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt));
+ INFO("Changed devicetree.\n");
}
diff --git a/plat/allwinner/common/sunxi_scpi_pm.c b/plat/allwinner/common/sunxi_scpi_pm.c
index eb37daa..41dc563 100644
--- a/plat/allwinner/common/sunxi_scpi_pm.c
+++ b/plat/allwinner/common/sunxi_scpi_pm.c
@@ -33,6 +33,9 @@
*/
#define SCP_FIRMWARE_MAGIC 0xb4400012
+#define PLAT_LOCAL_PSTATE_WIDTH U(4)
+#define PLAT_LOCAL_PSTATE_MASK ((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
#define CPU_PWR_LVL MPIDR_AFFLVL0
#define CLUSTER_PWR_LVL MPIDR_AFFLVL1
#define SYSTEM_PWR_LVL MPIDR_AFFLVL2
@@ -44,17 +47,6 @@
#define SYSTEM_PWR_STATE(state) \
((state)->pwr_domain_state[SYSTEM_PWR_LVL])
-static inline scpi_power_state_t scpi_map_state(plat_local_state_t psci_state)
-{
- if (is_local_state_run(psci_state)) {
- return scpi_power_on;
- }
- if (is_local_state_retn(psci_state)) {
- return scpi_power_retention;
- }
- return scpi_power_off;
-}
-
static void sunxi_cpu_standby(plat_local_state_t cpu_state)
{
u_register_t scr = read_scr_el3();
@@ -87,9 +79,9 @@
}
scpi_set_css_power_state(read_mpidr(),
- scpi_map_state(cpu_pwr_state),
- scpi_map_state(cluster_pwr_state),
- scpi_map_state(system_pwr_state));
+ cpu_pwr_state,
+ cluster_pwr_state,
+ system_pwr_state);
}
static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
@@ -137,7 +129,9 @@
psci_power_state_t *req_state)
{
unsigned int power_level = psci_get_pstate_pwrlvl(power_state);
+ unsigned int state_id = psci_get_pstate_id(power_state);
unsigned int type = psci_get_pstate_type(power_state);
+ unsigned int i;
assert(req_state != NULL);
@@ -146,28 +140,19 @@
}
if (type == PSTATE_TYPE_STANDBY) {
- /* Only one retention power state is supported. */
- if (psci_get_pstate_id(power_state) > 0) {
- return PSCI_E_INVALID_PARAMS;
- }
- /* The SoC cannot be suspended without losing state */
- if (power_level == SYSTEM_PWR_LVL) {
- return PSCI_E_INVALID_PARAMS;
- }
- for (unsigned int i = 0; i <= power_level; ++i) {
- req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE;
- }
- } else {
- /* Only one off power state is supported. */
- if (psci_get_pstate_id(power_state) > 0) {
- return PSCI_E_INVALID_PARAMS;
- }
- for (unsigned int i = 0; i <= power_level; ++i) {
- req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
- }
+ return PSCI_E_INVALID_PARAMS;
}
+
+ /* Pass through the requested PSCI state as-is. */
+ for (i = 0; i <= power_level; ++i) {
+ unsigned int local_pstate = state_id & PLAT_LOCAL_PSTATE_MASK;
+
+ req_state->pwr_domain_state[i] = local_pstate;
+ state_id >>= PLAT_LOCAL_PSTATE_WIDTH;
+ }
+
/* Higher power domain levels should all remain running */
- for (unsigned int i = power_level + 1; i <= PLAT_MAX_PWR_LVL; ++i) {
+ for (; i <= PLAT_MAX_PWR_LVL; ++i) {
req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN;
}
diff --git a/plat/allwinner/sun50i_a64/sunxi_idle_states.c b/plat/allwinner/sun50i_a64/sunxi_idle_states.c
new file mode 100644
index 0000000..2918bb7
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/sunxi_idle_states.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+ {
+ .name = "cpu-sleep",
+ .power_state = 0x00010003,
+ .local_timer_stop = true,
+ .entry_latency_us = 800,
+ .exit_latency_us = 1500,
+ .min_residency_us = 25000
+ },
+ {
+ .name = "cluster-sleep",
+ .power_state = 0x01010013,
+ .local_timer_stop = true,
+ .entry_latency_us = 850,
+ .exit_latency_us = 1500,
+ .min_residency_us = 50000
+ },
+ {}
+};
diff --git a/plat/allwinner/sun50i_h6/sunxi_idle_states.c b/plat/allwinner/sun50i_h6/sunxi_idle_states.c
new file mode 100644
index 0000000..4339bcd
--- /dev/null
+++ b/plat/allwinner/sun50i_h6/sunxi_idle_states.c
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+ {}
+};
diff --git a/plat/allwinner/sun50i_h616/platform.mk b/plat/allwinner/sun50i_h616/platform.mk
index fc09af7..de494a2 100644
--- a/plat/allwinner/sun50i_h616/platform.mk
+++ b/plat/allwinner/sun50i_h616/platform.mk
@@ -4,6 +4,8 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+SUNXI_BL31_IN_DRAM := 1
+
# Without a management processor there is no SCPI support.
SUNXI_PSCI_USE_SCPI := 0
SUNXI_PSCI_USE_NATIVE := 1
@@ -18,7 +20,3 @@
BL31_SOURCES += drivers/allwinner/axp/axp805.c \
drivers/allwinner/sunxi_rsb.c \
- common/fdt_fixup.c \
- ${AW_PLAT}/${PLAT}/prepare_dtb.c
-
-$(eval $(call add_define,SUNXI_BL31_IN_DRAM))
diff --git a/plat/allwinner/sun50i_h616/sunxi_idle_states.c b/plat/allwinner/sun50i_h616/sunxi_idle_states.c
new file mode 100644
index 0000000..4339bcd
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/sunxi_idle_states.c
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+ {}
+};
diff --git a/plat/allwinner/sun50i_r329/sunxi_idle_states.c b/plat/allwinner/sun50i_r329/sunxi_idle_states.c
new file mode 100644
index 0000000..4339bcd
--- /dev/null
+++ b/plat/allwinner/sun50i_r329/sunxi_idle_states.c
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sunxi_private.h>
+
+const struct psci_cpu_idle_state sunxi_idle_states[] = {
+ {}
+};
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index 084532c..a14a0d8 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -71,9 +71,9 @@
lib/cpus/aarch64/cortex_a65.S \
lib/cpus/aarch64/cortex_a65ae.S \
lib/cpus/aarch64/cortex_a510.S \
- lib/cpus/aarch64/cortex_a710.S \
- lib/cpus/aarch64/cortex_makalu.S \
- lib/cpus/aarch64/cortex_makalu_elp_arm.S \
+ lib/cpus/aarch64/cortex_a710.S \
+ lib/cpus/aarch64/cortex_a715.S \
+ lib/cpus/aarch64/cortex_x3.S \
lib/cpus/aarch64/cortex_a78c.S
# AArch64/AArch32 cores
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 66cc3e9..714c444 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,18 +13,20 @@
#include <drivers/delay_timer.h>
#include <lib/cassert.h>
#include <lib/fconf/fconf.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/arm/common/fconf_nv_cntr_getter.h>
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
-#include <platform_def.h>
-
-#if defined(ARM_COT_tbbr)
-#include <tools_share/tbbr_oid.h>
+#if defined(ARM_COT_cca)
+#include <tools_share/cca_oid.h>
#elif defined(ARM_COT_dualroot)
#include <tools_share/dualroot_oid.h>
+#elif defined(ARM_COT_tbbr)
+#include <tools_share/tbbr_oid.h>
#endif
+#include <plat/arm/common/fconf_nv_cntr_getter.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
#if !ARM_CRYPTOCELL_INTEG
#if !ARM_ROTPK_LOCATION_ID
#error "ARM_ROTPK_LOCATION_ID not defined"
@@ -181,6 +183,40 @@
return 1;
}
}
+
+#elif defined(ARM_COT_cca)
+
+int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ /*
+ * Return the right root of trust key hash based on the cookie value:
+ * - NULL means the primary ROTPK.
+ * - Otherwise, interpret cookie as the OID of the certificate
+ * extension containing the key.
+ */
+ if (cookie == NULL) {
+ return get_rotpk_info(key_ptr, key_len, flags);
+ } else if (strcmp(cookie, PROT_PK_OID) == 0) {
+ extern unsigned char arm_protpk_hash[];
+ extern unsigned char arm_protpk_hash_end[];
+ *key_ptr = arm_protpk_hash;
+ *key_len = arm_protpk_hash_end - arm_protpk_hash;
+ *flags = ROTPK_IS_HASH;
+ return 0;
+ } else if (strcmp(cookie, SWD_ROT_PK_OID) == 0) {
+ extern unsigned char arm_swd_rotpk_hash[];
+ extern unsigned char arm_swd_rotpk_hash_end[];
+ *key_ptr = arm_swd_rotpk_hash;
+ *key_len = arm_swd_rotpk_hash_end - arm_swd_rotpk_hash;
+ *flags = ROTPK_IS_HASH;
+ return 0;
+ } else {
+ /* Invalid key ID. */
+ return 1;
+ }
+}
+
#endif
/*
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 5cdf1bf..1d0eb13 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -38,6 +38,10 @@
$(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
+ifeq (${ENABLE_RME}, 1)
+COT := cca
+endif
+
# Force generation of the new hash if ROT_KEY is specified
ifdef ROT_KEY
HASH_PREREQUISITES = $(ROT_KEY) FORCE
@@ -49,8 +53,8 @@
ifndef ROT_KEY
$(error Cannot generate hash: no ROT_KEY defined)
endif
- openssl ${CRYPTO_ALG} -in $< -pubout -outform DER | openssl dgst \
- -sha256 -binary > $@
+ ${OPENSSL_BIN_PATH}/openssl ${CRYPTO_ALG} -in $< -pubout -outform DER | \
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@
# Certificate NV-Counters. Use values corresponding to tied off values in
# ARM development platforms
@@ -85,7 +89,32 @@
BL2_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S
$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+endif
+
+ifeq (${COT},cca)
+# Platform and Secure World Root of Trust key files.
+ARM_PROT_KEY := plat/arm/board/common/protpk/arm_protprivk_rsa.pem
+ARM_PROTPK_HASH := plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
+ARM_SWD_ROT_KEY := plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem
+ARM_SWD_ROTPK_HASH := plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
+
+# Provide the private keys to cert_create tool. It needs them to sign the images.
+PROT_KEY := ${ARM_PROT_KEY}
+SWD_ROT_KEY := ${ARM_SWD_ROT_KEY}
+
+$(eval $(call add_define_val,ARM_PROTPK_HASH,'"$(ARM_PROTPK_HASH)"'))
+$(eval $(call add_define_val,ARM_SWD_ROTPK_HASH,'"$(ARM_SWD_ROTPK_HASH)"'))
+
+BL1_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S \
+ plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
+BL2_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S \
+ plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
+
+$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+$(BUILD_PLAT)/bl1/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK_HASH)
$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+$(BUILD_PLAT)/bl2/arm_dev_swd_rotpk.o: $(ARM_SWD_ROTPK_HASH)
endif
endif
diff --git a/plat/arm/board/common/swd_rotpk/README b/plat/arm/board/common/swd_rotpk/README
new file mode 100644
index 0000000..b628a5f
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/README
@@ -0,0 +1,14 @@
+This directory contains some development keys to be used as the secure world
+root-of-trust key used in the CCA chain of trust.
+
+* swd_rotprivk_rsa.pem is a 2K RSA private key in PEM format. It has been
+ generated using the openssl command line tool:
+
+ openssl genrsa 2048 > arm_swd_rotprivk_rsa.pem
+
+* swd_rotpk_rsa_sha256.bin is the SHA-256 hash of the DER-encoded public key
+ associated with the above private key. It has been generated using the openssl
+ command line tool:
+
+ openssl rsa -in arm_swd_rotprivk_rsa.pem -pubout -outform DER | \
+ openssl dgst -sha256 -binary > arm_swd_rotpk_rsa_sha256.bin
diff --git a/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S b/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
new file mode 100644
index 0000000..ae4f9d2
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .global arm_swd_rotpk_hash
+ .global arm_swd_rotpk_hash_end
+
+ .section .rodata.arm_swd_rotpk_hash, "a"
+
+arm_swd_rotpk_hash:
+ /* DER header. */
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ /* Key hash. */
+ .incbin ARM_SWD_ROTPK_HASH
+arm_swd_rotpk_hash_end:
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin b/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
new file mode 100644
index 0000000..b2f3e60
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
@@ -0,0 +1 @@
+0¾âÃæÈË(ì¨0wIÓÕéã¡gk
\ No newline at end of file
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem
new file mode 100644
index 0000000..0de655d
--- /dev/null
+++ b/plat/arm/board/common/swd_rotpk/arm_swd_rotprivk_rsa.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA8igTd5QdZd181kz9vINr7Au34Rr/pQ1jpesfLlc1ZXCNAI9y
+/rhQlpw00y8rwOfgZsf18gPwGWWGhDJMsXI7OPem7BEUr8xKumuJuCiOdJh1STcR
+/JoFvz8wJPyycj/DOERRGsz+RvFBs6cLjSZHNQdzKDW+DE5vVJpmNWBVkoK7MCRD
+Wh/PMZVSoq9PeJOzayYcsipKvifT1+Wo9y2MG5zTDxi28rLr/FBm0CpTepBcRe8L
+pmgS7XJKhCQYxdDSzxi/0t/qXAwWuME4jv2HbNxsUZjahiBYpA0BafXanSuxVHly
+qpD0BmKAu7PpgKrEnUcPuHpZ2W+a05lNk6zjewIDAQABAoIBAG3twYCcTYgrtvs1
+8k38vyZl33CiKAGOhXkRtpL75fKJ2IizljmKBJOKj/R6ynsFCHrANadLIFj3HMyw
+ZN59A+OFkVJDIsf3jsj3/ooKZzkI6N120YSBizBZiAqSaJOy3HWTldn7y0b7SJ88
+quLFyLeLDTzowMCnbqTSfqmmdNJQAn+Q+7RX5sZGyBQUF2pRAA67cOYzc3a5MZ5E
+zBOs2u8VboC3ulEq876XWQbcXpRh/ap3eplQ1kAdyy64IPp2WbxqyXW0IQAQqaqh
+6oj19ME6mVD5wtELcYscJCDb7pA6WJtPp6nz/og2ifCJE/75T5RJ6fc6eBFMcofQ
+STIClGECgYEA/ZC0GX1HTKEKK3c1TiS3Zy0DS5ZoN5KFK7Sp1ZAjPE63iAr1a3z9
+Kepb+L8TBSw50tVD74MF5ChEid/ghF5BrVC3/YJkiiNpM1F51SMLGFeiDPRzJcx5
+KJkSflX7Q36BAXqj85Yz5AjgTPKcBqQRVZ6pNZN1HY99MloMg22WPRECgYEA9HtU
+FXmnTplXaNnihdq+vL5Z4/KDM+1f1E95y1PB8vkLI+o1szVNFP+BYz+w42lKtHW+
+c+z40AhFBGZQ0QCx83NOyObCReFjEbP8Nz71BsHe6GyMk9tSPIpzu9XB49Rs+9EO
+DAvFM5y2j5bH+lXE0pSyS3oBf51L9ZCPhp/vB8sCgYEAydwB1Gzsbu+hFfs/v2bx
+brzh67HgY6VMSP/5WF/3/RG5gB8hQ6HsNQsyjrMmZC7SFarb+3e2H+2CqrREm3wi
+EuS4pKPCgEoyfL03HVtZgNZ61o9gf83pAk3h8Bto/VFfSBsnHEsOIlKCph9Z4NuK
+RTwa/uDWEmNhyszvO03pldECgYEA2zB7GWnhc1mNgabfLY0JtuSeaPzzXqnyYcID
+eyUT3QglUcTY8lvWSP4ufdILgEfVP2fVIdAS30iawDAPQuLxqEf4Gayx/r7s+GE6
+vjlGqxFEDXPMsX9QApFK49voop/AOiCbDHe9DOHy11ei4TDmbrn8BClVkJlxEa/S
+ziszvfMCgYEA2V0zXziooI0toaOJEWZlAYhEONS5SG2z28HMLNgbdMcueGNhseaR
+NBGgPcu3EQhbL/hD0tBs09u6gjy1WD1i0HYnm1K1YQ1flzfbjUa3BqZETMbNhugd
+CM9yv0GEL/udZyOmO401aYl+QGXZX/WwlLQOe7WqQXOXJvW73oSqy7M=
+-----END RSA PRIVATE KEY-----
diff --git a/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c b/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c
index 3ee396c..fe521a9 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c
@@ -57,8 +57,8 @@
{
.image_id = TOS_FW_CONFIG_ID,
.image_info.image_base = CORSTONE1000_TOS_FW_CONFIG_BASE,
- .image_info.image_max_size = CORSTONE1000_TOS_FW_CONFIG_LIMIT - \
- CORSTONE1000_TOS_FW_CONFIG_BASE,
+ .image_info.image_max_size = (CORSTONE1000_TOS_FW_CONFIG_LIMIT -
+ CORSTONE1000_TOS_FW_CONFIG_BASE),
SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
diff --git a/plat/arm/board/corstone1000/common/corstone1000_plat.c b/plat/arm/board/corstone1000/common/corstone1000_plat.c
index a96baae..0235f8b 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_plat.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_plat.c
@@ -34,12 +34,13 @@
{
const struct plat_io_policy *policy;
/*
- * metadata for firmware update is written at 0x0000 offset of the flash.
- * PLAT_ARM_BOOT_BANK_FLAG contains the boot bank that TF-M is booted.
- * As per firmware update spec, at a given point of time, only one bank is active.
- * This means, TF-A should boot from the same bank as TF-M.
- */
+ * metadata for firmware update is written at 0x0000 offset of the flash.
+ * PLAT_ARM_BOOT_BANK_FLAG contains the boot bank that TF-M is booted.
+ * As per firmware update spec, at a given point of time, only one bank
+ * is active. This means, TF-A should boot from the same bank as TF-M.
+ */
volatile uint32_t *boot_bank_flag = (uint32_t *)(PLAT_ARM_BOOT_BANK_FLAG);
+
if (*boot_bank_flag > 1) {
VERBOSE("Boot_bank is set higher than possible values");
}
diff --git a/plat/arm/board/corstone1000/common/corstone1000_pm.c b/plat/arm/board/corstone1000/common/corstone1000_pm.c
index 98dea79..4b0a791 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_pm.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_pm.c
@@ -21,8 +21,8 @@
*(watchdog_val_reg) = SECURE_WATCHDOG_COUNTDOWN_VAL;
*watchdog_ctrl_reg = SECURE_WATCHDOG_MASK_ENABLE;
while (1) {
- wfi();
- }
+ wfi();
+ }
}
plat_psci_ops_t plat_arm_psci_pm_ops = {
diff --git a/plat/arm/board/corstone1000/common/corstone1000_trusted_boot.c b/plat/arm/board/corstone1000/common/corstone1000_trusted_boot.c
index cec7332..7e8fbb2 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_trusted_boot.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_trusted_boot.c
@@ -38,8 +38,8 @@
*/
int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
{
- *nv_ctr = CORSTONE1000_FW_NVCTR_VAL;
- return 0;
+ *nv_ctr = CORSTONE1000_FW_NVCTR_VAL;
+ return 0;
}
/*
@@ -49,5 +49,5 @@
*/
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
{
- return 0;
+ return 0;
}
diff --git a/plat/arm/board/corstone1000/common/include/platform_def.h b/plat/arm/board/corstone1000/common/include/platform_def.h
index 2523d72..584d485 100644
--- a/plat/arm/board/corstone1000/common/include/platform_def.h
+++ b/plat/arm/board/corstone1000/common/include/platform_def.h
@@ -16,11 +16,11 @@
#include <plat/common/common_def.h>
#include <plat/arm/soc/common/soc_css_def.h>
-#define ARM_ROTPK_HEADER_LEN 19
-#define ARM_ROTPK_HASH_LEN 32
+#define ARM_ROTPK_HEADER_LEN 19
+#define ARM_ROTPK_HASH_LEN 32
/* Special value used to verify platform parameters from BL2 to BL31 */
-#define ARM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978)
+#define ARM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978)
/* PL011 UART related constants */
#ifdef V2M_IOFPGA_UART0_CLK_IN_HZ
@@ -31,368 +31,324 @@
#undef V2M_IOFPGA_UART1_CLK_IN_HZ
#endif
-#define V2M_IOFPGA_UART0_CLK_IN_HZ 50000000
-#define V2M_IOFPGA_UART1_CLK_IN_HZ 50000000
+#define V2M_IOFPGA_UART0_CLK_IN_HZ 50000000
+#define V2M_IOFPGA_UART1_CLK_IN_HZ 50000000
/* Core/Cluster/Thread counts for corstone1000 */
-#define CORSTONE1000_CLUSTER_COUNT U(1)
-#define CORSTONE1000_MAX_CPUS_PER_CLUSTER U(4)
-#define CORSTONE1000_MAX_PE_PER_CPU U(1)
-#define CORSTONE1000_PRIMARY_CPU U(0)
+#define CORSTONE1000_CLUSTER_COUNT U(1)
+#define CORSTONE1000_MAX_CPUS_PER_CLUSTER U(4)
+#define CORSTONE1000_MAX_PE_PER_CPU U(1)
+#define CORSTONE1000_PRIMARY_CPU U(0)
-#define PLAT_ARM_CLUSTER_COUNT CORSTONE1000_CLUSTER_COUNT
+#define PLAT_ARM_CLUSTER_COUNT CORSTONE1000_CLUSTER_COUNT
-#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
- CORSTONE1000_MAX_CPUS_PER_CLUSTER * \
- CORSTONE1000_MAX_PE_PER_CPU)
+#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
+ CORSTONE1000_MAX_CPUS_PER_CLUSTER * \
+ CORSTONE1000_MAX_PE_PER_CPU)
/* UART related constants */
-#define PLAT_ARM_BOOT_UART_BASE 0x1a510000
-#define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ
-#define PLAT_ARM_RUN_UART_BASE 0x1a520000
-#define PLAT_ARM_RUN_UART_CLK_IN_HZ V2M_IOFPGA_UART1_CLK_IN_HZ
-#define ARM_CONSOLE_BAUDRATE 115200
-#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE
-#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ
+#define PLAT_ARM_BOOT_UART_BASE 0x1a510000
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ
+#define PLAT_ARM_RUN_UART_BASE 0x1a520000
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ V2M_IOFPGA_UART1_CLK_IN_HZ
+#define ARM_CONSOLE_BAUDRATE 115200
+#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ
/* Memory related constants */
/* SRAM (CVM) memory layout
*
* <ARM_TRUSTED_SRAM_BASE>
- *
- * partition size: sizeof(meminfo_t) = 16 bytes
- *
- * content: memory info area used by the next BL
+ * partition size: sizeof(meminfo_t) = 16 bytes
+ * content: memory info area used by the next BL
*
* <ARM_FW_CONFIG_BASE>
- *
- * partition size: 4080 bytes
+ * partition size: 4080 bytes
*
* <ARM_BL2_MEM_DESC_BASE>
- *
- * partition size: 4 KB
- *
- * content:
- *
- * Area where BL2 copies the images descriptors
+ * partition size: 4 KB
+ * content: Area where BL2 copies the images descriptors
*
* <ARM_BL_RAM_BASE> = <BL32_BASE>
- *
- * partition size: 688 KB
- *
- * content:
- *
- * BL32 (optee-os)
+ * partition size: 688 KB
+ * content: BL32 (optee-os)
*
* <CORSTONE1000_TOS_FW_CONFIG_BASE> = 0x20ae000
- *
- * partition size: 8 KB
- *
- * content:
- *
- * BL32 config (TOS_FW_CONFIG)
+ * partition size: 8 KB
+ * content: BL32 config (TOS_FW_CONFIG)
*
* <BL31_BASE>
- *
- * partition size: 140 KB
- *
- * content:
- *
- * BL31
+ * partition size: 140 KB
+ * content: BL31
*
* <BL2_SIGNATURE_BASE>
- *
- * partition size: 4 KB
- *
- * content:
- *
- * MCUBOOT data needed to verify TF-A BL2
+ * partition size: 4 KB
+ * content: MCUBOOT data needed to verify TF-A BL2
*
* <BL2_BASE>
- *
- * partition size: 176 KB
- *
- * content:
- *
- * BL2
+ * partition size: 176 KB
+ * content: BL2
*
* <ARM_NS_SHARED_RAM_BASE> = <ARM_TRUSTED_SRAM_BASE> + 1 MB
- *
- * partition size: 512 KB
- *
- * content:
- *
- * BL33 (u-boot)
+ * partition size: 512 KB
+ * content: BL33 (u-boot)
*/
/* DDR memory */
-#define ARM_DRAM1_BASE UL(0x80000000)
-#define ARM_DRAM1_SIZE (SZ_2G) /* 2GB*/
-#define ARM_DRAM1_END (ARM_DRAM1_BASE + \
- ARM_DRAM1_SIZE - 1)
+#define ARM_DRAM1_BASE UL(0x80000000)
+#define ARM_DRAM1_SIZE (SZ_2G) /* 2GB*/
+#define ARM_DRAM1_END (ARM_DRAM1_BASE + ARM_DRAM1_SIZE - 1)
/* DRAM1 and DRAM2 are the same for corstone1000 */
-#define ARM_DRAM2_BASE ARM_DRAM1_BASE
-#define ARM_DRAM2_SIZE ARM_DRAM1_SIZE
-#define ARM_DRAM2_END ARM_DRAM1_END
+#define ARM_DRAM2_BASE ARM_DRAM1_BASE
+#define ARM_DRAM2_SIZE ARM_DRAM1_SIZE
+#define ARM_DRAM2_END ARM_DRAM1_END
-#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE
-#define ARM_NS_DRAM1_SIZE ARM_DRAM1_SIZE
-#define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE +\
- ARM_NS_DRAM1_SIZE - 1)
+#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE
+#define ARM_NS_DRAM1_SIZE ARM_DRAM1_SIZE
+#define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE - 1)
/* The first 8 KB of Trusted SRAM are used as shared memory */
-#define ARM_TRUSTED_SRAM_BASE UL(0x02000000)
-#define ARM_SHARED_RAM_SIZE (SZ_8K) /* 8 KB */
-#define ARM_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE
+#define ARM_TRUSTED_SRAM_BASE UL(0x02000000)
+#define ARM_SHARED_RAM_SIZE (SZ_8K) /* 8 KB */
+#define ARM_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE
/* The remaining Trusted SRAM is used to load the BL images */
-#define TOTAL_SRAM_SIZE (SZ_4M) /* 4 MB */
+#define TOTAL_SRAM_SIZE (SZ_4M) /* 4 MB */
-/* Last 512KB of CVM is allocated for shared RAM
- * as an example openAMP */
-#define ARM_NS_SHARED_RAM_SIZE (512 * SZ_1K)
+/* Last 512KB of CVM is allocated for shared RAM as an example openAMP */
+#define ARM_NS_SHARED_RAM_SIZE (512 * SZ_1K)
-#define PLAT_ARM_TRUSTED_SRAM_SIZE (TOTAL_SRAM_SIZE - \
- ARM_NS_SHARED_RAM_SIZE - \
- ARM_SHARED_RAM_SIZE)
+#define PLAT_ARM_TRUSTED_SRAM_SIZE (TOTAL_SRAM_SIZE - \
+ ARM_NS_SHARED_RAM_SIZE - \
+ ARM_SHARED_RAM_SIZE)
-#define PLAT_ARM_MAX_BL2_SIZE (180 * SZ_1K) /* 180 KB */
+#define PLAT_ARM_MAX_BL2_SIZE (180 * SZ_1K) /* 180 KB */
-#define PLAT_ARM_MAX_BL31_SIZE (140 * SZ_1K) /* 140 KB */
+#define PLAT_ARM_MAX_BL31_SIZE (140 * SZ_1K) /* 140 KB */
-#define ARM_BL_RAM_BASE (ARM_SHARED_RAM_BASE + \
- ARM_SHARED_RAM_SIZE)
-#define ARM_BL_RAM_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \
- ARM_SHARED_RAM_SIZE)
+#define ARM_BL_RAM_BASE (ARM_SHARED_RAM_BASE + ARM_SHARED_RAM_SIZE)
+#define ARM_BL_RAM_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \
+ ARM_SHARED_RAM_SIZE)
-#define BL2_SIGNATURE_SIZE (SZ_4K) /* 4 KB */
+#define BL2_SIGNATURE_SIZE (SZ_4K) /* 4 KB */
-#define BL2_SIGNATURE_BASE (BL2_LIMIT - \
- PLAT_ARM_MAX_BL2_SIZE)
-#define BL2_BASE (BL2_LIMIT - \
- PLAT_ARM_MAX_BL2_SIZE + \
- BL2_SIGNATURE_SIZE)
-#define BL2_LIMIT (ARM_BL_RAM_BASE + \
- ARM_BL_RAM_SIZE)
+#define BL2_SIGNATURE_BASE (BL2_LIMIT - PLAT_ARM_MAX_BL2_SIZE)
+#define BL2_BASE (BL2_LIMIT - \
+ PLAT_ARM_MAX_BL2_SIZE + \
+ BL2_SIGNATURE_SIZE)
+#define BL2_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
-#define BL31_BASE (BL2_SIGNATURE_BASE - \
- PLAT_ARM_MAX_BL31_SIZE)
-#define BL31_LIMIT BL2_SIGNATURE_BASE
+#define BL31_BASE (BL2_SIGNATURE_BASE - PLAT_ARM_MAX_BL31_SIZE)
+#define BL31_LIMIT BL2_SIGNATURE_BASE
-#define CORSTONE1000_TOS_FW_CONFIG_BASE (BL31_BASE - \
- CORSTONE1000_TOS_FW_CONFIG_SIZE)
-#define CORSTONE1000_TOS_FW_CONFIG_SIZE (SZ_8K) /* 8 KB */
-#define CORSTONE1000_TOS_FW_CONFIG_LIMIT BL31_BASE
+#define CORSTONE1000_TOS_FW_CONFIG_BASE (BL31_BASE - \
+ CORSTONE1000_TOS_FW_CONFIG_SIZE)
+#define CORSTONE1000_TOS_FW_CONFIG_SIZE (SZ_8K) /* 8 KB */
+#define CORSTONE1000_TOS_FW_CONFIG_LIMIT BL31_BASE
-#define BL32_BASE ARM_BL_RAM_BASE
-#define PLAT_ARM_MAX_BL32_SIZE (CORSTONE1000_TOS_FW_CONFIG_BASE - \
- BL32_BASE)
+#define BL32_BASE ARM_BL_RAM_BASE
+#define PLAT_ARM_MAX_BL32_SIZE (CORSTONE1000_TOS_FW_CONFIG_BASE - BL32_BASE)
-#define BL32_LIMIT (BL32_BASE + \
- PLAT_ARM_MAX_BL32_SIZE)
+#define BL32_LIMIT (BL32_BASE + PLAT_ARM_MAX_BL32_SIZE)
/* SPD_spmd settings */
-#define PLAT_ARM_SPMC_BASE BL32_BASE
-#define PLAT_ARM_SPMC_SIZE PLAT_ARM_MAX_BL32_SIZE
+#define PLAT_ARM_SPMC_BASE BL32_BASE
+#define PLAT_ARM_SPMC_SIZE PLAT_ARM_MAX_BL32_SIZE
/* NS memory */
/* The last 512KB of the SRAM is allocated as shared memory */
-#define ARM_NS_SHARED_RAM_BASE (ARM_TRUSTED_SRAM_BASE + TOTAL_SRAM_SIZE - \
- (PLAT_ARM_MAX_BL31_SIZE + \
- PLAT_ARM_MAX_BL32_SIZE))
+#define ARM_NS_SHARED_RAM_BASE (ARM_TRUSTED_SRAM_BASE + TOTAL_SRAM_SIZE - \
+ (PLAT_ARM_MAX_BL31_SIZE + \
+ PLAT_ARM_MAX_BL32_SIZE))
-#define BL33_BASE ARM_DRAM1_BASE
-#define PLAT_ARM_MAX_BL33_SIZE (12 * SZ_1M) /* 12 MB*/
-#define BL33_LIMIT (ARM_DRAM1_BASE + PLAT_ARM_MAX_BL33_SIZE)
+#define BL33_BASE ARM_DRAM1_BASE
+#define PLAT_ARM_MAX_BL33_SIZE (12 * SZ_1M) /* 12 MB*/
+#define BL33_LIMIT (ARM_DRAM1_BASE + PLAT_ARM_MAX_BL33_SIZE)
/* end of the definition of SRAM memory layout */
/* NOR Flash */
-#define PLAT_ARM_BOOT_BANK_FLAG UL(0x08002000)
-#define PLAT_ARM_FIP_BASE_BANK0 UL(0x081EF000)
-#define PLAT_ARM_FIP_BASE_BANK1 UL(0x0916F000)
-#define PLAT_ARM_FIP_MAX_SIZE UL(0x1ff000) /* 1.996 MB */
+#define PLAT_ARM_BOOT_BANK_FLAG UL(0x08002000)
+#define PLAT_ARM_FIP_BASE_BANK0 UL(0x081EF000)
+#define PLAT_ARM_FIP_BASE_BANK1 UL(0x0916F000)
+#define PLAT_ARM_FIP_MAX_SIZE UL(0x1ff000) /* 1.996 MB */
-#define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE
-#define PLAT_ARM_NVM_SIZE (SZ_32M) /* 32 MB */
+#define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE (SZ_32M) /* 32 MB */
-#define PLAT_ARM_FLASH_IMAGE_BASE PLAT_ARM_FIP_BASE_BANK0
-#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE PLAT_ARM_FIP_MAX_SIZE
+#define PLAT_ARM_FLASH_IMAGE_BASE PLAT_ARM_FIP_BASE_BANK0
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE PLAT_ARM_FIP_MAX_SIZE
/*
* Some data must be aligned on the biggest cache line size in the platform.
* This is known only to the platform as it might have a combination of
* integrated and external caches.
*/
-#define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT)
-#define ARM_CACHE_WRITEBACK_SHIFT 6
+#define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT)
+#define ARM_CACHE_WRITEBACK_SHIFT 6
/*
* Define FW_CONFIG area base and limit. Leave enough space for BL2 meminfo.
* FW_CONFIG is intended to host the device tree. Currently, This area is not
* used because corstone1000 platform doesn't use a device tree at TF-A level.
*/
-#define ARM_FW_CONFIG_BASE (ARM_SHARED_RAM_BASE \
- + sizeof(meminfo_t))
-#define ARM_FW_CONFIG_LIMIT (ARM_SHARED_RAM_BASE \
- + (ARM_SHARED_RAM_SIZE >> 1))
+#define ARM_FW_CONFIG_BASE (ARM_SHARED_RAM_BASE + sizeof(meminfo_t))
+#define ARM_FW_CONFIG_LIMIT (ARM_SHARED_RAM_BASE + \
+ (ARM_SHARED_RAM_SIZE >> 1))
/*
* Boot parameters passed from BL2 to BL31/BL32 are stored here
*/
-#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT
-#define ARM_BL2_MEM_DESC_LIMIT ARM_BL_RAM_BASE
+#define ARM_BL2_MEM_DESC_BASE ARM_FW_CONFIG_LIMIT
+#define ARM_BL2_MEM_DESC_LIMIT ARM_BL_RAM_BASE
/*
* The max number of regions like RO(code), coherent and data required by
* different BL stages which need to be mapped in the MMU.
*/
-#define ARM_BL_REGIONS 3
-#define PLAT_ARM_MMAP_ENTRIES 8
-#define MAX_XLAT_TABLES 5
-#define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \
- ARM_BL_REGIONS)
-#define MAX_IO_DEVICES 2
-#define MAX_IO_HANDLES 3
-#define MAX_IO_BLOCK_DEVICES 1
+#define ARM_BL_REGIONS 3
+#define PLAT_ARM_MMAP_ENTRIES 8
+#define MAX_XLAT_TABLES 5
+#define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + ARM_BL_REGIONS)
+#define MAX_IO_DEVICES 2
+#define MAX_IO_HANDLES 3
+#define MAX_IO_BLOCK_DEVICES 1
/* GIC related constants */
-#define PLAT_ARM_GICD_BASE 0x1C010000
-#define PLAT_ARM_GICC_BASE 0x1C02F000
+#define PLAT_ARM_GICD_BASE 0x1C010000
+#define PLAT_ARM_GICC_BASE 0x1C02F000
/* MHUv2 Secure Channel receiver and sender */
-#define PLAT_SDK700_MHU0_SEND 0x1B800000
-#define PLAT_SDK700_MHU0_RECV 0x1B810000
+#define PLAT_SDK700_MHU0_SEND 0x1B800000
+#define PLAT_SDK700_MHU0_RECV 0x1B810000
/* Timer/watchdog related constants */
-#define ARM_SYS_CNTCTL_BASE UL(0x1a200000)
-#define ARM_SYS_CNTREAD_BASE UL(0x1a210000)
-#define ARM_SYS_TIMCTL_BASE UL(0x1a220000)
+#define ARM_SYS_CNTCTL_BASE UL(0x1a200000)
+#define ARM_SYS_CNTREAD_BASE UL(0x1a210000)
+#define ARM_SYS_TIMCTL_BASE UL(0x1a220000)
-#define SECURE_WATCHDOG_ADDR_CTRL_REG 0x1A320000
-#define SECURE_WATCHDOG_ADDR_VAL_REG 0x1A320008
-#define SECURE_WATCHDOG_MASK_ENABLE 0x01
-#define SECURE_WATCHDOG_COUNTDOWN_VAL 0x1000
+#define SECURE_WATCHDOG_ADDR_CTRL_REG 0x1A320000
+#define SECURE_WATCHDOG_ADDR_VAL_REG 0x1A320008
+#define SECURE_WATCHDOG_MASK_ENABLE 0x01
+#define SECURE_WATCHDOG_COUNTDOWN_VAL 0x1000
-#define SYS_COUNTER_FREQ_IN_TICKS UL(50000000) /* 50MHz */
+#define SYS_COUNTER_FREQ_IN_TICKS UL(50000000) /* 50MHz */
-#define CORSTONE1000_IRQ_TZ_WDOG 32
-#define CORSTONE1000_IRQ_SEC_SYS_TIMER 34
+#define CORSTONE1000_IRQ_TZ_WDOG 32
+#define CORSTONE1000_IRQ_SEC_SYS_TIMER 34
-#define PLAT_MAX_PWR_LVL 2
+#define PLAT_MAX_PWR_LVL 2
/*
* Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The
* power levels have a 1:1 mapping with the MPIDR affinity levels.
*/
-#define ARM_PWR_LVL0 MPIDR_AFFLVL0
-#define ARM_PWR_LVL1 MPIDR_AFFLVL1
-#define ARM_PWR_LVL2 MPIDR_AFFLVL2
+#define ARM_PWR_LVL0 MPIDR_AFFLVL0
+#define ARM_PWR_LVL1 MPIDR_AFFLVL1
+#define ARM_PWR_LVL2 MPIDR_AFFLVL2
/*
* Macros for local power states in ARM platforms encoded by State-ID field
* within the power-state parameter.
*/
/* Local power state for power domains in Run state. */
-#define ARM_LOCAL_STATE_RUN U(0)
+#define ARM_LOCAL_STATE_RUN U(0)
/* Local power state for retention. Valid only for CPU power domains */
-#define ARM_LOCAL_STATE_RET U(1)
+#define ARM_LOCAL_STATE_RET U(1)
/* Local power state for OFF/power-down. Valid for CPU and cluster
* power domains
*/
-#define ARM_LOCAL_STATE_OFF U(2)
+#define ARM_LOCAL_STATE_OFF U(2)
-#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
-#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
+#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
+#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
-#define PLAT_ARM_NS_IMAGE_BASE (ARM_NS_SHARED_RAM_BASE)
+#define PLAT_ARM_NS_IMAGE_BASE (ARM_NS_SHARED_RAM_BASE)
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
/*
* This macro defines the deepest retention state possible. A higher state
* ID will represent an invalid or a power down state.
*/
-#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_RET_STATE 1
/*
* This macro defines the deepest power down states possible. Any state ID
* higher than this is invalid.
*/
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_OFF_STATE 2
-#define PLATFORM_STACK_SIZE UL(0x440)
+#define PLATFORM_STACK_SIZE UL(0x440)
-#define CORSTONE1000_EXTERNAL_FLASH MAP_REGION_FLAT( \
- PLAT_ARM_NVM_BASE, \
- PLAT_ARM_NVM_SIZE, \
- MT_DEVICE | MT_RO | MT_SECURE)
+#define CORSTONE1000_EXTERNAL_FLASH MAP_REGION_FLAT( \
+ PLAT_ARM_NVM_BASE, \
+ PLAT_ARM_NVM_SIZE, \
+ MT_DEVICE | MT_RO | MT_SECURE)
-#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \
- ARM_SHARED_RAM_BASE, \
- ARM_SHARED_RAM_SIZE, \
- MT_MEMORY | MT_RW | MT_SECURE)
+#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \
+ ARM_SHARED_RAM_BASE, \
+ ARM_SHARED_RAM_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
-#define ARM_MAP_NS_SHARED_RAM MAP_REGION_FLAT( \
- ARM_NS_SHARED_RAM_BASE, \
- ARM_NS_SHARED_RAM_SIZE, \
- MT_MEMORY | MT_RW | MT_NS)
+#define ARM_MAP_NS_SHARED_RAM MAP_REGION_FLAT( \
+ ARM_NS_SHARED_RAM_BASE, \
+ ARM_NS_SHARED_RAM_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
-#define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \
- ARM_NS_DRAM1_BASE, \
- ARM_NS_DRAM1_SIZE, \
- MT_MEMORY | MT_RW | MT_NS)
+#define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \
+ ARM_NS_DRAM1_BASE, \
+ ARM_NS_DRAM1_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
-#define ARM_MAP_BL_RO MAP_REGION_FLAT( \
- BL_CODE_BASE, \
- BL_CODE_END \
- - BL_CODE_BASE, \
- MT_CODE | MT_SECURE), \
- MAP_REGION_FLAT( \
- BL_RO_DATA_BASE, \
- BL_RO_DATA_END \
- - BL_RO_DATA_BASE, \
- MT_RO_DATA | MT_SECURE)
+#define ARM_MAP_BL_RO MAP_REGION_FLAT( \
+ BL_CODE_BASE, \
+ (BL_CODE_END - BL_CODE_BASE), \
+ MT_CODE | MT_SECURE), \
+ MAP_REGION_FLAT( \
+ BL_RO_DATA_BASE, \
+ (BL_RO_DATA_END - BL_RO_DATA_BASE), \
+ MT_RO_DATA | MT_SECURE)
#if USE_COHERENT_MEM
-#define ARM_MAP_BL_COHERENT_RAM MAP_REGION_FLAT( \
- BL_COHERENT_RAM_BASE, \
- BL_COHERENT_RAM_END \
- - BL_COHERENT_RAM_BASE, \
- MT_DEVICE | MT_RW | MT_SECURE)
+#define ARM_MAP_BL_COHERENT_RAM MAP_REGION_FLAT( \
+ BL_COHERENT_RAM_BASE, \
+ (BL_COHERENT_RAM_END \
+ - BL_COHERENT_RAM_BASE), \
+ MT_DEVICE | MT_RW | MT_SECURE)
#endif
/*
* Map the region for the optional device tree configuration with read and
* write permissions
*/
-#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT( \
- ARM_FW_CONFIG_BASE, \
- (ARM_FW_CONFIG_LIMIT- \
- ARM_FW_CONFIG_BASE), \
- MT_MEMORY | MT_RW | MT_SECURE)
+#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT( \
+ ARM_FW_CONFIG_BASE, \
+ (ARM_FW_CONFIG_LIMIT \
+ - ARM_FW_CONFIG_BASE), \
+ MT_MEMORY | MT_RW | MT_SECURE)
-#define CORSTONE1000_DEVICE_BASE (0x1A000000)
-#define CORSTONE1000_DEVICE_SIZE (0x26000000)
-#define CORSTONE1000_MAP_DEVICE MAP_REGION_FLAT( \
- CORSTONE1000_DEVICE_BASE, \
- CORSTONE1000_DEVICE_SIZE, \
- MT_DEVICE | MT_RW | MT_SECURE)
+#define CORSTONE1000_DEVICE_BASE (0x1A000000)
+#define CORSTONE1000_DEVICE_SIZE (0x26000000)
+#define CORSTONE1000_MAP_DEVICE MAP_REGION_FLAT( \
+ CORSTONE1000_DEVICE_BASE, \
+ CORSTONE1000_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
-#define ARM_IRQ_SEC_PHY_TIMER 29
+#define ARM_IRQ_SEC_PHY_TIMER 29
-#define ARM_IRQ_SEC_SGI_0 8
-#define ARM_IRQ_SEC_SGI_1 9
-#define ARM_IRQ_SEC_SGI_2 10
-#define ARM_IRQ_SEC_SGI_3 11
-#define ARM_IRQ_SEC_SGI_4 12
-#define ARM_IRQ_SEC_SGI_5 13
-#define ARM_IRQ_SEC_SGI_6 14
-#define ARM_IRQ_SEC_SGI_7 15
+#define ARM_IRQ_SEC_SGI_0 8
+#define ARM_IRQ_SEC_SGI_1 9
+#define ARM_IRQ_SEC_SGI_2 10
+#define ARM_IRQ_SEC_SGI_3 11
+#define ARM_IRQ_SEC_SGI_4 12
+#define ARM_IRQ_SEC_SGI_5 13
+#define ARM_IRQ_SEC_SGI_6 14
+#define ARM_IRQ_SEC_SGI_7 15
/*
* Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3
@@ -424,12 +380,14 @@
* terminology. On a GICv2 system or mode, the lists will be merged and treated
* as Group 0 interrupts.
*/
-#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
- ARM_G1S_IRQ_PROPS(grp), \
- INTR_PROP_DESC(CORSTONE1000_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, \
- (grp), GIC_INTR_CFG_LEVEL), \
- INTR_PROP_DESC(CORSTONE1000_IRQ_SEC_SYS_TIMER, \
- GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL)
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+ ARM_G1S_IRQ_PROPS(grp), \
+ INTR_PROP_DESC(CORSTONE1000_IRQ_TZ_WDOG, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(CORSTONE1000_IRQ_SEC_SYS_TIMER, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ (grp), GIC_INTR_CFG_LEVEL)
#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
diff --git a/plat/arm/board/corstone700/common/corstone700_plat.c b/plat/arm/board/corstone700/common/corstone700_plat.c
index 629f076..dd7531d 100644
--- a/plat/arm/board/corstone700/common/corstone700_plat.c
+++ b/plat/arm/board/corstone700/common/corstone700_plat.c
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/bl_common.h>
-#include <mhu.h>
+#include <corstone700_mhu.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
diff --git a/plat/arm/board/corstone700/common/drivers/mhu/mhu.c b/plat/arm/board/corstone700/common/drivers/mhu/corstone700_mhu.c
similarity index 96%
rename from plat/arm/board/corstone700/common/drivers/mhu/mhu.c
rename to plat/arm/board/corstone700/common/drivers/mhu/corstone700_mhu.c
index 2231d11..832cfb7 100644
--- a/plat/arm/board/corstone700/common/drivers/mhu/mhu.c
+++ b/plat/arm/board/corstone700/common/drivers/mhu/corstone700_mhu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +12,7 @@
#include <lib/bakery_lock.h>
#include <lib/mmio.h>
-#include "mhu.h"
+#include "corstone700_mhu.h"
#include <plat_arm.h>
#include <platform_def.h>
diff --git a/plat/arm/board/corstone700/common/drivers/mhu/mhu.h b/plat/arm/board/corstone700/common/drivers/mhu/corstone700_mhu.h
similarity index 86%
rename from plat/arm/board/corstone700/common/drivers/mhu/mhu.h
rename to plat/arm/board/corstone700/common/drivers/mhu/corstone700_mhu.h
index 3808746..7f14ca5 100644
--- a/plat/arm/board/corstone700/common/drivers/mhu/mhu.h
+++ b/plat/arm/board/corstone700/common/drivers/mhu/corstone700_mhu.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef MHU_H
-#define MHU_H
+#ifndef CORSTONE700_MHU_H
+#define CORSTONE700_MHU_H
#define MHU_POLL_INTR_STAT_TIMEOUT 50000 /*timeout value in us*/
@@ -34,4 +34,4 @@
void mhu_secure_message_end(uintptr_t address, unsigned int slot_id);
void mhu_secure_init(void);
-#endif /* MHU_H */
+#endif /* CORSTONE700_MHU_H */
diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk
index 9a8d38c..75833f6 100644
--- a/plat/arm/board/corstone700/platform.mk
+++ b/plat/arm/board/corstone700/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -17,7 +17,7 @@
lib/xlat_tables/aarch32/xlat_tables.c \
lib/xlat_tables/xlat_tables_common.c \
${CORSTONE700_CPU_LIBS} \
- plat/arm/board/corstone700/common/drivers/mhu/mhu.c
+ plat/arm/board/corstone700/common/drivers/mhu/corstone700_mhu.c
PLAT_INCLUDES := -Iplat/arm/board/corstone700/common/include \
-Iinclude/plat/arm/common \
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index c26b519..577ac74 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,9 +19,10 @@
};
hw-config {
- load-address = <0x0 0x82000000>;
- max-size = <0x01000000>;
+ load-address = <0x0 0x07f00000>;
+ max-size = <0x00100000>;
id = <HW_CONFIG_ID>;
+ ns-load-address = <0x0 0x82000000>;
};
/*
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index 21a6073..4543671 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -82,4 +82,8 @@
device_type = "memory";
reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
};
+
+#if MEASURED_BOOT
+#include "event_log.dtsi"
+#endif
};
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index cf4ef2d..6fd334d 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -47,6 +47,9 @@
soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0";
tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
+ cca_cert_uuid = "36d83d85-761d-4daf-96f1-cd99d6569b00";
+ core_swd_cert_uuid = "52222d31-820f-494d-8bbc-ea6825d3c35a";
+ plat_cert_uuid = "d43cd902-5b9f-412e-8ac6-92b6d18be60d";
t_key_cert_uuid = "827ee890-f860-e411-a1b4-777a21b4f94c";
scp_fw_key_uuid = "024221a1-f860-e411-8d9b-f33c0e15a014";
soc_fw_key_uuid = "8ab8becc-f960-e411-9ad0-eb4822d8dcf8";
diff --git a/plat/arm/board/fvp/fdts/fvp_tsp_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_tsp_sp_manifest.dts
new file mode 100644
index 0000000..1587c72
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_tsp_sp_manifest.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+#define AFF 00
+
+#include "fvp-defs.dtsi"
+#undef POST
+#define POST \
+ };
+
+#define S_EL0 (0x1)
+#define S_EL1 (0x2)
+
+/* For consumption by EL3 SPMC. */
+/ {
+ compatible = "arm,ffa-manifest-1.0";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
+ id = <0x8001>;
+ uuid = <0x6b43b460 0x74a24b78 0xade24502 0x40682886>;
+ messaging-method = <0x3>; /* Direct Messaging Only */
+ exception-level = <S_EL1>;
+ execution-state = <0>;
+ execution-ctx-count = <8>;
+ gp-register-num = <0>;
+ /* Subscribe to CPU_OFF, CPU_SUSPEND and CPU_SUSPEND_RESUME PM Msgs */
+ power-management-messages = <0x7>;
+};
diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
index b803340..27f4724 100644
--- a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -22,7 +22,7 @@
exception-level = <2>; /* S-EL1 */
execution-state = <0>; /* AARCH64 */
load-address = <0x6280000>;
- entrypoint-offset = <0x1000>;
+ entrypoint-offset = <0x4000>;
xlat-granule = <0>; /* 4KiB */
boot-order = <0>;
messaging-method = <0x3>; /* Direct request/response supported. */
diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
index 5468555..76cd918 100644
--- a/plat/arm/board/fvp/fvp_bl1_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/rss/rss_measured_boot.h>
#include <plat/arm/common/plat_arm.h>
/* Event Log data */
@@ -21,10 +22,39 @@
{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
};
+/* FVP table with platform specific image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rss_mboot_metadata fvp_rss_mboot_metadata[] = {
+ {
+ .id = FW_CONFIG_ID,
+ .slot = U(6),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_FW_CONFIG_STRING,
+ .lock_measurement = true },
+ {
+ .id = TB_FW_CONFIG_ID,
+ .slot = U(7),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_TB_FW_CONFIG_STRING,
+ .lock_measurement = true },
+ {
+ .id = BL2_IMAGE_ID,
+ .slot = U(8),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_BL2_STRING,
+ .lock_measurement = true },
+
+ {
+ .id = RSS_MBOOT_INVALID_ID }
+};
+
void bl1_plat_mboot_init(void)
{
event_log_init(event_log, event_log + sizeof(event_log));
event_log_write_header();
+
+ rss_measured_boot_init();
}
void bl1_plat_mboot_finish(void)
diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
index 1f38278..e938e24 100644
--- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
@@ -6,7 +6,9 @@
#include <stdint.h>
+#include <common/tbbr/tbbr_img_def.h>
#include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/rss/rss_measured_boot.h>
#include <tools_share/tbbr_oid.h>
#include <fvp_critical_data.h>
@@ -30,11 +32,54 @@
{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
{ RMM_IMAGE_ID, EVLOG_RMM_STRING, PCR_0},
+#if defined(SPD_spmd)
+ { SP_PKG1_ID, EVLOG_SP1_STRING, PCR_0 },
+ { SP_PKG2_ID, EVLOG_SP2_STRING, PCR_0 },
+ { SP_PKG3_ID, EVLOG_SP3_STRING, PCR_0 },
+ { SP_PKG4_ID, EVLOG_SP4_STRING, PCR_0 },
+ { SP_PKG5_ID, EVLOG_SP5_STRING, PCR_0 },
+ { SP_PKG6_ID, EVLOG_SP6_STRING, PCR_0 },
+ { SP_PKG7_ID, EVLOG_SP7_STRING, PCR_0 },
+ { SP_PKG8_ID, EVLOG_SP8_STRING, PCR_0 },
+#endif
+
{ CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 },
{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
};
+/* FVP table with platform specific image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rss_mboot_metadata fvp_rss_mboot_metadata[] = {
+ {
+ .id = BL31_IMAGE_ID,
+ .slot = U(9),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_BL31_STRING,
+ .lock_measurement = true },
+ {
+ .id = HW_CONFIG_ID,
+ .slot = U(10),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_HW_CONFIG_STRING,
+ .lock_measurement = true },
+ {
+ .id = SOC_FW_CONFIG_ID,
+ .slot = U(11),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_SOC_FW_CONFIG_STRING,
+ .lock_measurement = true },
+ {
+ .id = RMM_IMAGE_ID,
+ .slot = U(12),
+ .signer_id_size = SIGNER_ID_MIN_SIZE,
+ .sw_type = RSS_MBOOT_RMM_STRING,
+ .lock_measurement = true },
+ {
+ .id = RSS_MBOOT_INVALID_ID }
+};
+
void bl2_plat_mboot_init(void)
{
uint8_t *event_log_start;
@@ -64,6 +109,8 @@
PLAT_ARM_EVENT_LOG_MAX_SIZE);
event_log_init((uint8_t *)event_log_start, event_log_finish);
+
+ rss_measured_boot_init();
}
int plat_mboot_measure_critical_data(unsigned int critical_data_id,
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 5a17a0d..74e5d72 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -40,17 +40,23 @@
struct bl_params *plat_get_next_bl_params(void)
{
struct bl_params *arm_bl_params;
+ const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+ bl_mem_params_node_t *param_node __unused;
arm_bl_params = arm_get_next_bl_params();
-#if __aarch64__ && !BL2_AT_EL3
+#if !BL2_AT_EL3 && !EL3_PAYLOAD_BASE
const struct dyn_cfg_dtb_info_t *fw_config_info;
- bl_mem_params_node_t *param_node;
- uintptr_t fw_config_base = 0U;
+ uintptr_t fw_config_base = 0UL;
entry_point_info_t *ep_info;
+#if __aarch64__
/* Get BL31 image node */
param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
+#else /* aarch32 */
+ /* Get SP_MIN image node */
+ param_node = get_bl_mem_params_node(BL32_IMAGE_ID);
+#endif /* __aarch64__ */
assert(param_node != NULL);
/* get fw_config load address */
@@ -58,15 +64,42 @@
assert(fw_config_info != NULL);
fw_config_base = fw_config_info->config_addr;
- assert(fw_config_base != 0U);
+ assert(fw_config_base != 0UL);
/*
- * Get the entry point info of BL31 image and override
+ * Get the entry point info of next executable image and override
* arg1 of entry point info with fw_config base address
*/
ep_info = ¶m_node->ep_info;
ep_info->args.arg1 = (uint32_t)fw_config_base;
-#endif /* __aarch64__ && !BL2_AT_EL3 */
+
+ /* grab NS HW config address */
+ hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+ assert(hw_config_info != NULL);
+
+ /* To retrieve actual size of the HW_CONFIG */
+ param_node = get_bl_mem_params_node(HW_CONFIG_ID);
+ assert(param_node != NULL);
+
+ /* Copy HW config from Secure address to NS address */
+ memcpy((void *)hw_config_info->ns_config_addr,
+ (void *)hw_config_info->config_addr,
+ (size_t)param_node->image_info.image_size);
+
+ /*
+ * Ensure HW-config device tree committed to memory, as there is
+ * a possibility to use HW-config without cache and MMU enabled
+ * at BL33
+ */
+ flush_dcache_range(hw_config_info->ns_config_addr,
+ param_node->image_info.image_size);
+
+ param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
+ assert(param_node != NULL);
+
+ /* Update BL33's ep info with NS HW config address */
+ param_node->ep_info.args.arg1 = hw_config_info->ns_config_addr;
+#endif /* !BL2_AT_EL3 && !EL3_PAYLOAD_BASE */
return arm_bl_params;
}
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index a94a4f4..dd90965 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -17,6 +17,8 @@
#include "fvp_private.h"
+static const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+
void __init bl31_early_platform_setup2(u_register_t arg0,
u_register_t arg1, u_register_t arg2, u_register_t arg3)
{
@@ -34,6 +36,17 @@
if (soc_fw_config_info != NULL) {
arg1 = soc_fw_config_info->config_addr;
}
+
+ /*
+ * arg2 is currently holding the 'secure' address of HW_CONFIG.
+ * But arm_bl31_early_platform_setup() below expects the 'non-secure'
+ * address of HW_CONFIG (which it will pass to BL33).
+ * This why we need to override arg2 here.
+ */
+ hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+ assert(hw_config_info != NULL);
+ assert(hw_config_info->ns_config_addr != 0UL);
+ arg2 = hw_config_info->ns_config_addr;
#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 */
arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
@@ -66,22 +79,57 @@
void __init bl31_plat_arch_setup(void)
{
+ int rc __unused;
+ uintptr_t hw_config_base_align __unused;
+ size_t mapped_size_align __unused;
+
arm_bl31_plat_arch_setup();
/*
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run.
* So there is no BL2 to load the HW_CONFIG dtb into memory before
- * control is passed to BL31.
+ * control is passed to BL31. The code below relies on dynamic mapping
+ * capability, which is not supported by xlat tables lib V1.
+ * TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
+ * gets deprecated.
*/
-#if !RESET_TO_BL31 && !BL2_AT_EL3
- /* HW_CONFIG was also loaded by BL2 */
- const struct dyn_cfg_dtb_info_t *hw_config_info;
-
- hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+#if !RESET_TO_BL31 && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1
assert(hw_config_info != NULL);
+ assert(hw_config_info->config_addr != 0UL);
+ /* Page aligned address and size if necessary */
+ hw_config_base_align = page_align(hw_config_info->config_addr, DOWN);
+ mapped_size_align = page_align(hw_config_info->config_max_size, UP);
+
+ if ((hw_config_info->config_addr != hw_config_base_align) &&
+ (hw_config_info->config_max_size == mapped_size_align)) {
+ mapped_size_align += PAGE_SIZE;
+ }
+
+ /*
+ * map dynamically HW config region with its aligned base address and
+ * size
+ */
+ rc = mmap_add_dynamic_region((unsigned long long)hw_config_base_align,
+ hw_config_base_align,
+ mapped_size_align,
+ MT_RO_DATA);
+ if (rc != 0) {
+ ERROR("Error while mapping HW_CONFIG device tree (%d).\n", rc);
+ panic();
+ }
+
+ /* Populate HW_CONFIG device tree with the mapped address */
fconf_populate("HW_CONFIG", hw_config_info->config_addr);
-#endif
+
+ /* unmap the HW_CONFIG memory region */
+ rc = mmap_remove_dynamic_region(hw_config_base_align, mapped_size_align);
+ if (rc != 0) {
+ ERROR("Error while unmapping HW_CONFIG device tree (%d).\n",
+ rc);
+ panic();
+ }
+#endif /* !RESET_TO_BL31 && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1 */
}
unsigned int plat_get_syscnt_freq2(void)
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index d8d19de..f8463f1 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -17,6 +17,9 @@
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <platform_def.h>
#include <services/arm_arch_svc.h>
+#if ENABLE_RME
+#include <services/rmm_core_manifest.h>
+#endif
#if SPM_MM
#include <services/spm_mm_partition.h>
#endif
@@ -104,9 +107,10 @@
#ifdef __aarch64__
ARM_MAP_DRAM2,
#endif
-#if defined(SPD_spmd)
+ /*
+ * Required to load HW_CONFIG, SPMC and SPs to trusted DRAM.
+ */
ARM_MAP_TRUSTED_DRAM,
-#endif
#if ENABLE_RME
ARM_MAP_RMM_DRAM,
ARM_MAP_GPT_L1_DRAM,
@@ -126,7 +130,7 @@
*/
ARM_MAP_BL1_RW,
#endif /* CRYPTO_SUPPORT && !BL2_AT_EL3 */
-#if SPM_MM
+#if SPM_MM || SPMC_AT_EL3
ARM_SP_IMAGE_MMAP,
#endif
#if ARM_BL31_IN_DRAM
@@ -166,10 +170,9 @@
#if SPM_MM
ARM_SPM_BUF_EL3_MMAP,
#endif
- /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
- ARM_DTB_DRAM_NS,
#if ENABLE_RME
ARM_MAP_GPT_L1_DRAM,
+ ARM_MAP_EL3_RMM_SHARED_MEM,
#endif
{0}
};
@@ -197,8 +200,6 @@
V2M_MAP_IOFPGA,
MAP_DEVICE0,
MAP_DEVICE1,
- /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
- ARM_DTB_DRAM_NS,
{0}
};
#endif
@@ -515,3 +516,29 @@
return (int32_t)(((sys_id >> V2M_SYS_ID_REV_SHIFT) &
V2M_SYS_ID_REV_MASK) & SOC_ID_REV_MASK);
}
+
+#if ENABLE_RME
+/*
+ * Get a pointer to the RMM-EL3 Shared buffer and return it
+ * through the pointer passed as parameter.
+ *
+ * This function returns the size of the shared buffer.
+ */
+size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
+{
+ *shared = (uintptr_t)RMM_SHARED_BASE;
+
+ return (size_t)RMM_SHARED_SIZE;
+}
+
+int plat_rmmd_load_manifest(rmm_manifest_t *manifest)
+{
+ assert(manifest != NULL);
+
+ manifest->version = RMMD_MANIFEST_VERSION;
+ manifest->plat_data = (uintptr_t)NULL;
+
+ return 0;
+}
+
+#endif
diff --git a/plat/arm/board/fvp/fvp_common_measured_boot.c b/plat/arm/board/fvp/fvp_common_measured_boot.c
index 6a403d9..93aa055 100644
--- a/plat/arm/board/fvp/fvp_common_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_common_measured_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,27 +9,47 @@
#include <common/desc_image_load.h>
#include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/rss/rss_measured_boot.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
extern event_log_metadata_t fvp_event_log_metadata[];
+extern struct rss_mboot_metadata fvp_rss_mboot_metadata[];
const event_log_metadata_t *plat_event_log_get_metadata(void)
{
return fvp_event_log_metadata;
}
+struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void)
+{
+ return fvp_rss_mboot_metadata;
+}
+
int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
{
+ int err;
+ int rc = 0;
+
/* Calculate image hash and record data in Event Log */
- int err = event_log_measure_and_record(image_data->image_base,
- image_data->image_size,
- image_id);
+ err = event_log_measure_and_record(image_data->image_base,
+ image_data->image_size,
+ image_id);
if (err != 0) {
ERROR("%s%s image id %u (%i)\n",
- "Failed to ", "record", image_id, err);
- return err;
+ "Failed to ", "record in event log", image_id, err);
+ rc = err;
}
- return 0;
+ /* Calculate image hash and record data in RSS */
+ err = rss_mboot_measure_and_record(image_data->image_base,
+ image_data->image_size,
+ image_id);
+ if (err != 0) {
+ ERROR("%s%s image id %u (%i)\n",
+ "Failed to ", "record in RSS", image_id, err);
+ rc = (rc == 0) ? err : -1;
+ }
+
+ return rc;
}
diff --git a/plat/arm/board/fvp/fvp_el3_spmc.c b/plat/arm/board/fvp/fvp_el3_spmc.c
new file mode 100644
index 0000000..2b347ed
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_el3_spmc.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <services/el3_spmc_ffa_memory.h>
+
+#include <platform_def.h>
+
+/*
+ * On the FVP platform when using the EL3 SPMC implementation allocate the
+ * datastore for tracking shared memory descriptors in the TZC DRAM section
+ * to ensure sufficient storage can be allocated.
+ * Provide an implementation of the accessor method to allow the datastore
+ * details to be retrieved by the SPMC.
+ * The SPMC will take care of initializing the memory region.
+ */
+
+#define PLAT_SPMC_SHMEM_DATASTORE_SIZE 512 * 1024
+
+__section("arm_el3_tzc_dram") static uint8_t
+plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE];
+
+int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
+{
+ *datastore = plat_spmc_shmem_datastore;
+ *size = PLAT_SPMC_SHMEM_DATASTORE_SIZE;
+ return 0;
+}
+
+/*
+ * Add dummy implementations of memory management related platform hooks.
+ * These can be used to implement platform specific functionality to support
+ * a memory sharing/lending operation.
+ *
+ * Note: The hooks must be located as part of the initial share request and
+ * final reclaim to prevent order dependencies with operations that may take
+ * place in the normal world without visibility of the SPMC.
+ */
+int plat_spmc_shmem_begin(struct ffa_mtd *desc)
+{
+ return 0;
+}
+int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
+{
+ return 0;
+}
diff --git a/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
new file mode 100644
index 0000000..b9e4f86
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <services/el3_spmc_logical_sp.h>
+#include <services/ffa_svc.h>
+#include <smccc_helpers.h>
+
+#define LP_PARTITION_ID 0xC001
+#define LP_UUID {0x47a3bf57, 0xe98e43ad, 0xb7db524f, 0x1588f4e3}
+
+/* Our Logical SP currently only supports receipt of direct messaging. */
+#define PARTITION_PROPERTIES FFA_PARTITION_DIRECT_REQ_RECV
+
+static int32_t sp_init(void)
+{
+ INFO("LSP: Init function called.\n");
+ return 0;
+}
+
+static uint64_t handle_ffa_direct_request(uint32_t smc_fid, bool secure_origin,
+ uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, void *cookie,
+ void *handle, uint64_t flags)
+{
+ uint64_t ret;
+
+ /* Determine if we have a 64 or 32 direct request. */
+ if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC32) {
+ ret = FFA_MSG_SEND_DIRECT_RESP_SMC32;
+ } else if (smc_fid == FFA_MSG_SEND_DIRECT_REQ_SMC64) {
+ ret = FFA_MSG_SEND_DIRECT_RESP_SMC64;
+ } else {
+ panic(); /* Unknown SMC. */
+ }
+ /*
+ * Handle the incoming request. For testing purposes we echo the
+ * incoming message.
+ */
+ INFO("Logical Partition: Received Direct Request from %s world!\n",
+ secure_origin ? "Secure" : "Normal");
+
+ /*
+ * Logical SP's must always send a direct response so we can populate
+ * our response directly.
+ */
+ SMC_RET8(handle, ret, 0, 0, x4, 0, 0, 0, 0);
+}
+
+/* Register logical partition */
+DECLARE_LOGICAL_PARTITION(
+ my_logical_partition,
+ sp_init, /* Init Function */
+ LP_PARTITION_ID, /* FF-A Partition ID */
+ LP_UUID, /* UUID */
+ PARTITION_PROPERTIES, /* Partition Properties. */
+ handle_ffa_direct_request /* Callback for direct requests. */
+);
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
new file mode 100644
index 0000000..1b0854b
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+
+/* Using hardcoded token values for AEM FVP */
+static uint8_t platform_token[] = {
+ 0xD2, 0x84, 0x40, 0xA0, 0x59, 0x08, 0xB1, 0xD9,
+ 0x61, 0xA8, 0xA9, 0x0A, 0x58, 0x40, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x3A, 0x00,
+ 0x01, 0x24, 0xFA, 0x58, 0x40, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x3A, 0x00, 0x01,
+ 0x25, 0x00, 0x58, 0x41, 0x01, 0x0B, 0xBB, 0xBB,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x12, 0x78, 0x1C,
+ 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x61,
+ 0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x43,
+ 0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F, 0x31,
+ 0x2E, 0x30, 0x2E, 0x30, 0x0B, 0x58, 0x19, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0x3A, 0x00, 0x01, 0x24, 0xF7, 0x78, 0x1C, 0x68,
+ 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x61, 0x72,
+ 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x43, 0x43,
+ 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F, 0x31, 0x2E,
+ 0x30, 0x2E, 0x30, 0x3A, 0x00, 0x01, 0x25, 0x01,
+ 0x78, 0x18, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A,
+ 0x2F, 0x2F, 0x63, 0x63, 0x61, 0x5F, 0x76, 0x65,
+ 0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x2E, 0x6F,
+ 0x72, 0x67, 0x3A, 0x00, 0x01, 0x24, 0xF9, 0x19,
+ 0x30, 0x00, 0x3A, 0x00, 0x01, 0x24, 0xFD, 0x8D,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+ 0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+ 0x58, 0x40, 0xD3, 0x8A, 0x41, 0xA6, 0xC1, 0x29,
+ 0x98, 0x18, 0xB5, 0x16, 0x9C, 0x21, 0x78, 0xB7,
+ 0x92, 0xF8, 0x26, 0x82, 0x76, 0x2F, 0x26, 0x45,
+ 0x21, 0x6D, 0x0C, 0x21, 0x06, 0xF4, 0xB5, 0xE3,
+ 0xA8, 0x07, 0xD1, 0xD6, 0x8C, 0x73, 0xA5, 0xC8,
+ 0x16, 0xD8, 0x30, 0x68, 0xC0, 0xA4, 0x77, 0xE2,
+ 0x1E, 0xD2, 0x17, 0x86, 0xC3, 0x68, 0x82, 0xDD,
+ 0x21, 0x1B, 0xA3, 0xE2, 0xC7, 0xF7, 0x06, 0x33,
+ 0xB0, 0x3A
+};
+
+int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
+ uintptr_t hash, size_t hash_size)
+{
+ (void)hash;
+ (void)hash_size;
+
+ if (*len < sizeof(platform_token)) {
+ return -EINVAL;
+ }
+
+ (void)memcpy((void *)buf, platform_token, sizeof(platform_token));
+ *len = sizeof(platform_token);
+
+ return 0;
+}
diff --git a/plat/arm/board/fvp/fvp_realm_attest_key.c b/plat/arm/board/fvp/fvp_realm_attest_key.c
new file mode 100644
index 0000000..1af1f0d
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_realm_attest_key.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <services/rmmd_svc.h>
+
+static uint8_t sample_attest_priv_key[] = {
+ 0x20, 0x11, 0xC7, 0xF0, 0x3C, 0xEE, 0x43, 0x25, 0x17, 0x6E,
+ 0x52, 0x4F, 0x03, 0x3C, 0x0C, 0xE1, 0xE2, 0x1A, 0x76, 0xE6,
+ 0xC1, 0xA4, 0xF0, 0xB8, 0x39, 0xAA, 0x1D, 0xF6, 0x1E, 0x0E,
+ 0x8A, 0x5C, 0x8A, 0x05, 0x74, 0x0F, 0x9B, 0x69, 0xEF, 0xA7,
+ 0xEB, 0x1A, 0x41, 0x85, 0xBD, 0x11, 0x7F, 0x68
+};
+
+int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
+ unsigned int type)
+{
+ assert(type == ATTEST_KEY_CURVE_ECC_SECP384R1);
+
+ if (*len < sizeof(sample_attest_priv_key)) {
+ return -EINVAL;
+ }
+
+ (void)memcpy((void *)buf, sample_attest_priv_key,
+ sizeof(sample_attest_priv_key));
+ *len = sizeof(sample_attest_priv_key);
+
+ return 0;
+}
diff --git a/plat/arm/board/fvp/include/fvp_critical_data.h b/plat/arm/board/fvp/include/fvp_critical_data.h
index 3010d21..04bd5b2 100644
--- a/plat/arm/board/fvp/include/fvp_critical_data.h
+++ b/plat/arm/board/fvp/include/fvp_critical_data.h
@@ -1,8 +1,10 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#ifndef FVP_CRITICAL_DATA_H
+#define FVP_CRITICAL_DATA_H
#include <common/nv_cntr_ids.h>
#include <lib/utils_def.h>
@@ -17,3 +19,5 @@
/* platform NV counters */
unsigned int nv_ctr[MAX_NV_CTR_IDS];
};
+
+#endif /* FVP_CRITICAL_DATA_H */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 77df610..e1bf46d 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -90,6 +90,31 @@
FVP_DTB_DRAM_MAP_START, \
FVP_DTB_DRAM_MAP_SIZE, \
MT_MEMORY | MT_RO | MT_NS)
+
+#if SPMC_AT_EL3
+/*
+ * Number of Secure Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * secure partitions.
+ */
+#define SECURE_PARTITION_COUNT 1
+
+/*
+ * Number of Normal World Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * NWd partitions.
+ */
+#define NS_PARTITION_COUNT 1
+
+/*
+ * Number of Logical Partitions supported.
+ * SPMC at EL3, uses this count to configure the maximum number of supported
+ * logical partitions.
+ */
+#define MAX_EL3_LP_DESCS_COUNT 1
+
+#endif /* SPMC_AT_EL3 */
+
/*
* Load address of BL33 for this platform port
*/
@@ -102,13 +127,12 @@
#if defined(IMAGE_BL31)
# if SPM_MM
# define PLAT_ARM_MMAP_ENTRIES 10
-# if ENABLE_RME
-# define MAX_XLAT_TABLES 10
-# else
-# define MAX_XLAT_TABLES 9
-# endif
+# define MAX_XLAT_TABLES 9
# define PLAT_SP_IMAGE_MMAP_REGIONS 30
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
+# elif SPMC_AT_EL3
+# define PLAT_ARM_MMAP_ENTRIES 13
+# define MAX_XLAT_TABLES 11
# else
# define PLAT_ARM_MMAP_ENTRIES 9
# if USE_DEBUGFS
@@ -126,8 +150,13 @@
# endif
# endif
#elif defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES 9
-# define MAX_XLAT_TABLES 6
+# if SPMC_AT_EL3
+# define PLAT_ARM_MMAP_ENTRIES 270
+# define MAX_XLAT_TABLES 10
+# else
+# define PLAT_ARM_MMAP_ENTRIES 9
+# define MAX_XLAT_TABLES 6
+# endif
#elif !USE_ROMLIB
# define PLAT_ARM_MMAP_ENTRIES 11
# define MAX_XLAT_TABLES 5
@@ -164,6 +193,9 @@
# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1E000) - FVP_BL2_ROMLIB_OPTIMIZATION)
#elif CRYPTO_SUPPORT
# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+#elif ARM_BL31_IN_DRAM
+/* When ARM_BL31_IN_DRAM is set, BL2 can use almost all of Trusted SRAM. */
+# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1F000) - FVP_BL2_ROMLIB_OPTIMIZATION)
#else
# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - FVP_BL2_ROMLIB_OPTIMIZATION)
#endif
@@ -217,7 +249,11 @@
#elif defined(IMAGE_BL31)
# define PLATFORM_STACK_SIZE UL(0x800)
#elif defined(IMAGE_BL32)
-# define PLATFORM_STACK_SIZE UL(0x440)
+# if SPMC_AT_EL3
+# define PLATFORM_STACK_SIZE UL(0x1000)
+# else
+# define PLATFORM_STACK_SIZE UL(0x440)
+# endif /* SPMC_AT_EL3 */
#elif defined(IMAGE_RMM)
# define PLATFORM_STACK_SIZE UL(0x440)
#endif
@@ -261,6 +297,7 @@
#define PLAT_ARM_TRP_UART_CLK_IN_HZ V2M_IOFPGA_UART3_CLK_IN_HZ
#define PLAT_FVP_SMMUV3_BASE UL(0x2b400000)
+#define PLAT_ARM_SMMUV3_ROOT_REG_OFFSET UL(0x20000)
/* CCI related constants */
#define PLAT_FVP_CCI400_BASE UL(0x2c090000)
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index b72bdab..85e6e3a 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -35,6 +35,8 @@
fdt fdt_get_name
fdt fdt_get_alias
fdt fdt_node_offset_by_phandle
+fdt fdt_subnode_offset
+fdt fdt_add_subnode
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index acac886..2539712 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -135,9 +135,9 @@
lib/cpus/aarch64/neoverse_demeter.S \
lib/cpus/aarch64/cortex_a78_ae.S \
lib/cpus/aarch64/cortex_a510.S \
- lib/cpus/aarch64/cortex_a710.S \
- lib/cpus/aarch64/cortex_makalu.S \
- lib/cpus/aarch64/cortex_makalu_elp_arm.S \
+ lib/cpus/aarch64/cortex_a710.S \
+ lib/cpus/aarch64/cortex_a715.S \
+ lib/cpus/aarch64/cortex_x3.S \
lib/cpus/aarch64/cortex_a65.S \
lib/cpus/aarch64/cortex_a65ae.S \
lib/cpus/aarch64/cortex_a78c.S \
@@ -193,6 +193,8 @@
ifeq (${ENABLE_RME},1)
BL2_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S
+BL31_SOURCES += plat/arm/board/fvp/fvp_plat_attest_token.c \
+ plat/arm/board/fvp/fvp_realm_attest_key.c
endif
ifeq (${BL2_AT_EL3},1)
@@ -331,15 +333,10 @@
endif
# Enable the dynamic translation tables library.
-ifeq (${ARCH},aarch32)
- ifeq (${RESET_TO_SP_MIN},1)
+ifeq ($(filter 1,${BL2_AT_EL3} ${ARM_XLAT_TABLES_LIB_V1}),)
+ ifeq (${ARCH},aarch32)
BL32_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
- endif
-else # AArch64
- ifeq (${RESET_TO_BL31},1)
- BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
- endif
- ifeq (${SPD},trusty)
+ else # AArch64
BL31_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
endif
endif
@@ -366,14 +363,40 @@
override BL1_SOURCES =
endif
+# Include Measured Boot makefile before any Crypto library makefile.
+# Crypto library makefile may need default definitions of Measured Boot build
+# flags present in Measured Boot makefile.
+ifeq (${MEASURED_BOOT},1)
+ RSS_MEASURED_BOOT_MK := drivers/measured_boot/rss/rss_measured_boot.mk
+ $(info Including ${RSS_MEASURED_BOOT_MK})
+ include ${RSS_MEASURED_BOOT_MK}
+
+ ifneq (${MBOOT_RSS_HASH_ALG}, sha256)
+ $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
+ endif
+
+ BL1_SOURCES += ${MEASURED_BOOT_SOURCES}
+ BL2_SOURCES += ${MEASURED_BOOT_SOURCES}
+endif
+
include plat/arm/board/common/board_common.mk
include plat/arm/common/arm_common.mk
ifeq (${MEASURED_BOOT},1)
BL1_SOURCES += plat/arm/board/fvp/fvp_common_measured_boot.c \
- plat/arm/board/fvp/fvp_bl1_measured_boot.c
+ plat/arm/board/fvp/fvp_bl1_measured_boot.c \
+ lib/psa/measured_boot.c
+
BL2_SOURCES += plat/arm/board/fvp/fvp_common_measured_boot.c \
- plat/arm/board/fvp/fvp_bl2_measured_boot.c
+ plat/arm/board/fvp/fvp_bl2_measured_boot.c \
+ lib/psa/measured_boot.c
+
+PLAT_INCLUDES += -Iinclude/lib/psa
+
+# RSS is not supported on FVP right now. Thus, we use the mocked version
+# of PSA Measured Boot APIs. They return with success and hard-coded data.
+PLAT_RSS_NOT_SUPPORTED := 1
+
endif
ifeq (${TRUSTED_BOARD_BOOT}, 1)
@@ -388,8 +411,21 @@
# enable trace buffer control registers access to NS by default
ENABLE_TRBE_FOR_NS := 1
+# enable branch record buffer control registers access in NS by default
+# only enable for aarch64
+# do not enable when ENABLE_RME=1
+ifeq (${ARCH}, aarch64)
+ifeq (${ENABLE_RME},0)
+ ENABLE_BRBE_FOR_NS := 1
+endif
+endif
+
# enable trace system registers access to NS by default
ENABLE_SYS_REG_TRACE_FOR_NS := 1
# enable trace filter control registers access to NS by default
ENABLE_TRF_FOR_NS := 1
+
+ifeq (${SPMC_AT_EL3}, 1)
+PLAT_BL_COMMON_SOURCES += plat/arm/board/fvp/fvp_el3_spmc.c
+endif
diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
index 763b42a..9ab36a6 100644
--- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
+++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,15 +9,31 @@
#include <bl32/sp_min/platform_sp_min.h>
#include <common/debug.h>
#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <plat/arm/common/plat_arm.h>
#include "../fvp_private.h"
-uintptr_t hw_config_dtb;
-
void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
+ const struct dyn_cfg_dtb_info_t *tos_fw_config_info __unused;
+
+ /* Initialize the console to provide early debug support */
+ arm_console_boot_init();
+
+#if !RESET_TO_SP_MIN && !BL2_AT_EL3
+
+ INFO("SP_MIN FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
+ /* Fill the properties struct with the info from the config dtb */
+ fconf_populate("FW_CONFIG", arg1);
+
+ tos_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TOS_FW_CONFIG_ID);
+ if (tos_fw_config_info != NULL) {
+ arg1 = tos_fw_config_info->config_addr;
+ }
+#endif /* !RESET_TO_SP_MIN && !BL2_AT_EL3 */
+
arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
/* Initialize the platform config for future decision making */
@@ -37,12 +53,15 @@
* FVP PSCI code will enable coherency for other clusters.
*/
fvp_interconnect_enable();
-
- hw_config_dtb = arg2;
}
void sp_min_plat_arch_setup(void)
{
+ int rc __unused;
+ const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+ uintptr_t hw_config_base_align __unused;
+ size_t mapped_size_align __unused;
+
arm_sp_min_plat_arch_setup();
/*
@@ -50,11 +69,53 @@
* to run. So there is no BL2 to load the HW_CONFIG dtb into memory
* before control is passed to SP_MIN.
* Also, BL2 skips loading HW_CONFIG dtb for BL2_AT_EL3 builds.
+ * The code below relies on dynamic mapping capability, which is not
+ * supported by xlat tables lib V1.
+ * TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
+ * gets deprecated.
*/
-#if !RESET_TO_SP_MIN && !BL2_AT_EL3
- assert(hw_config_dtb != 0U);
+#if !RESET_TO_SP_MIN && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1
+ hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
+ assert(hw_config_info != NULL);
+ assert(hw_config_info->config_addr != 0UL);
+
+ INFO("SP_MIN FCONF: HW_CONFIG address = %p\n",
+ (void *)hw_config_info->config_addr);
+
+ /*
+ * Preferrably we expect this address and size are page aligned,
+ * but if they are not then align it.
+ */
+ hw_config_base_align = page_align(hw_config_info->config_addr, DOWN);
+ mapped_size_align = page_align(hw_config_info->config_max_size, UP);
+
+ if ((hw_config_info->config_addr != hw_config_base_align) &&
+ (hw_config_info->config_max_size == mapped_size_align)) {
+ mapped_size_align += PAGE_SIZE;
+ }
+
+ /*
+ * map dynamically HW config region with its aligned base address and
+ * size
+ */
+ rc = mmap_add_dynamic_region((unsigned long long)hw_config_base_align,
+ hw_config_base_align,
+ mapped_size_align,
+ MT_RO_DATA);
+ if (rc != 0) {
+ ERROR("Error while mapping HW_CONFIG device tree (%d).\n", rc);
+ panic();
+ }
+
+ /* Populate HW_CONFIG device tree with the mapped address */
+ fconf_populate("HW_CONFIG", hw_config_info->config_addr);
- INFO("SP_MIN FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb);
- fconf_populate("HW_CONFIG", hw_config_dtb);
-#endif
+ /* unmap the HW_CONFIG memory region */
+ rc = mmap_remove_dynamic_region(hw_config_base_align, mapped_size_align);
+ if (rc != 0) {
+ ERROR("Error while unmapping HW_CONFIG device tree (%d).\n",
+ rc);
+ panic();
+ }
+#endif /* !RESET_TO_SP_MIN && !BL2_AT_EL3 && !ARM_XLAT_TABLES_LIB_V1 */
}
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 0d8cca5..183d802 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -25,7 +25,8 @@
# Added separately from the above list for better readability
ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_SP_MIN}),)
BL32_SOURCES += lib/fconf/fconf.c \
- plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+ lib/fconf/fconf_dyn_cfg_getter.c \
+ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c \
BL32_SOURCES += ${FDT_WRAPPERS_SOURCES}
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
index 68872c1..1ac0a9c 100644
--- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
@@ -154,7 +154,8 @@
/* Set global DTB info for fixed fw_config information */
fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
- set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID);
+ set_config_info(ARM_FW_CONFIG_BASE, ~0UL, fw_config_max_size,
+ FW_CONFIG_ID);
assert(bl1_plat_get_image_desc(BL33_IMAGE_ID) != NULL);
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index d61ba5d..3265b0b 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -9,7 +9,7 @@
#include <drivers/arm/tzc400.h>
#if TRUSTED_BOARD_BOOT
-#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include MBEDTLS_CONFIG_FILE
#endif
#include <plat/arm/board/common/board_css_def.h>
#include <plat/arm/board/common/v2m_def.h>
diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i
index 393a648..8932aa0 100644
--- a/plat/arm/board/juno/jmptbl.i
+++ b/plat/arm/board/juno/jmptbl.i
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -34,6 +34,8 @@
fdt fdt_get_name
fdt fdt_get_alias
fdt fdt_node_offset_by_phandle
+fdt fdt_subnode_offset
+fdt fdt_add_subnode
mbedtls mbedtls_asn1_get_alg
mbedtls mbedtls_asn1_get_alg_null
mbedtls mbedtls_asn1_get_bitstring_null
diff --git a/plat/arm/board/morello/morello_bl2_setup.c b/plat/arm/board/morello/morello_bl2_setup.c
index 0d4b6d0..da1f7ae 100644
--- a/plat/arm/board/morello/morello_bl2_setup.c
+++ b/plat/arm/board/morello/morello_bl2_setup.c
@@ -1,27 +1,226 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
+#include <drivers/arm/css/sds.h>
+#include <lib/mmio.h>
#include <lib/utils.h>
#include <plat/arm/common/plat_arm.h>
-void bl2_platform_setup(void)
-{
+#include "morello_def.h"
+#include <platform_def.h>
+
+#ifdef TARGET_PLATFORM_FVP
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size
+ * - Local DDR size in bytes, DDR memory in main board
+ */
+struct morello_plat_info {
+ uint64_t local_ddr_size;
+} __packed;
+#else
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size which is an information about multichip setup
+ * - Local DDR size in bytes, DDR memory in main board
+ * - Remote DDR size in bytes, DDR memory in remote board
+ * - remote_chip_count
+ * - multichip mode
+ * - scc configuration
+ */
+struct morello_plat_info {
+ uint64_t local_ddr_size;
+ uint64_t remote_ddr_size;
+ uint8_t remote_chip_count;
+ bool multichip_mode;
+ uint32_t scc_config;
+} __packed;
+#endif
+
+/* Compile time assertion to ensure the size of structure is 18 bytes */
+CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
+ assert_invalid_plat_info_size);
+
#ifdef TARGET_PLATFORM_SOC
- /*
- * Morello platform supports RDIMMs with ECC capability. To use the ECC
- * capability, the entire DDR memory space has to be zeroed out before
- * enabling the ECC bits in DMC-Bing.
- * Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF during BL2 stage,
- * as BL33 binary cannot be copied to DDR memory before enabling ECC.
- * Rest of the DDR memory space is zeroed out during BL31 stage.
- */
+/*
+ * Morello platform supports RDIMMs with ECC capability. To use the ECC
+ * capability, the entire DDR memory space has to be zeroed out before
+ * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
+ * memory from SCP is quite time consuming so the following function
+ * is added to zero out the DDR memory from application processor which is
+ * much faster compared to SCP.
+ */
+
+static void dmc_ecc_setup(struct morello_plat_info *plat_info)
+{
+ uint64_t dram2_size;
+ uint32_t val;
+ uint64_t tag_mem_base;
+ uint64_t usable_mem_size;
+
+ INFO("Total DIMM size: %uGB\n",
+ (uint32_t)(plat_info->local_ddr_size / 0x40000000));
+
+ assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
+ dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
+
INFO("Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF\n");
zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
+
+ INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
+ ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
+ zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
+ flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
+
+ /* Clear previous ECC errors while zeroing out the memory */
+ val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
+ mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
+
+ val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
+ mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
+
+ /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
+ mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
+ mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
+
+ while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
+ MORELLO_DMC_MEMC_STATUS_MASK) !=
+ MORELLO_DMC_MEMC_CMD_CONFIG) {
+ continue;
+ }
+
+ while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
+ MORELLO_DMC_MEMC_STATUS_MASK) !=
+ MORELLO_DMC_MEMC_CMD_CONFIG) {
+ continue;
+ }
+
+ /* Configure Bing client/server mode based on SCC configuration */
+ if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
+ INFO("Configuring DMC Bing in client mode\n");
+ usable_mem_size = plat_info->local_ddr_size -
+ (plat_info->local_ddr_size / 128ULL);
+
+ /* Linear DDR address */
+ tag_mem_base = usable_mem_size;
+ tag_mem_base = tag_mem_base / 4;
+
+ /* Reverse translation */
+ if (tag_mem_base < ARM_DRAM1_BASE) {
+ tag_mem_base += ARM_DRAM1_BASE;
+ } else {
+ tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
+ ARM_DRAM2_BASE;
+ }
+
+ mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
+ mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
+ mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
+ mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
+
+ if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
+ mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
+ mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
+ INFO("C1 Tag Cache Enabled\n");
+ }
+
+ if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
+ mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
+ mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
+ INFO("C2 Tag Cache Enabled\n");
+ }
+
+ mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
+ (uint32_t)tag_mem_base);
+ mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
+ (uint32_t)tag_mem_base);
+ mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
+ (uint32_t)(tag_mem_base >> 32));
+ mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
+ (uint32_t)(tag_mem_base >> 32));
+
+ mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
+ MORELLO_DMC_MEM_ACCESS_DIS);
+ mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
+ MORELLO_DMC_MEM_ACCESS_DIS);
+
+ INFO("Tag base set to 0x%lx\n", tag_mem_base);
+ plat_info->local_ddr_size = usable_mem_size;
+ } else {
+ INFO("Configuring DMC Bing in server mode\n");
+ mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
+ mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
+ }
+
+ INFO("Enabling ECC on DMCs\n");
+ /* Enable ECC in DMCs */
+ mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
+ MORELLO_DMC_ERR0CTLR0_ECC_EN);
+ mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
+ MORELLO_DMC_ERR0CTLR0_ECC_EN);
+
+ /* Set DMCs to READY state */
+ mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
+ mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
+
+ while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
+ MORELLO_DMC_MEMC_STATUS_MASK) !=
+ MORELLO_DMC_MEMC_CMD_READY) {
+ continue;
+ }
+
+ while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
+ MORELLO_DMC_MEMC_STATUS_MASK) !=
+ MORELLO_DMC_MEMC_CMD_READY) {
+ continue;
+ }
+}
+#endif
+
+void bl2_platform_setup(void)
+{
+ int ret;
+ struct morello_plat_info plat_info;
+
+ ret = sds_init();
+ if (ret != SDS_OK) {
+ ERROR("SDS initialization failed. ret:%d\n", ret);
+ panic();
+ }
+
+ ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
+ MORELLO_SDS_PLATFORM_INFO_OFFSET,
+ &plat_info,
+ MORELLO_SDS_PLATFORM_INFO_SIZE,
+ SDS_ACCESS_MODE_NON_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("Error getting platform info from SDS. ret:%d\n", ret);
+ panic();
+ }
+
+ /* Validate plat_info SDS */
+#ifdef TARGET_PLATFORM_FVP
+ if (plat_info.local_ddr_size == 0U) {
+#else
+ if ((plat_info.local_ddr_size == 0U)
+ || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
+ || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
+ || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
+ ) {
+#endif
+ ERROR("platform info SDS is corrupted\n");
+ panic();
+ }
+
+#ifdef TARGET_PLATFORM_SOC
+ dmc_ecc_setup(&plat_info);
#endif
arm_bl2_platform_setup();
}
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
index e418518..a044212 100644
--- a/plat/arm/board/morello/morello_bl31_setup.c
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -1,54 +1,16 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <common/debug.h>
#include <drivers/arm/css/css_mhu_doorbell.h>
#include <drivers/arm/css/scmi.h>
-#include <drivers/arm/css/sds.h>
-#include <lib/cassert.h>
-#include <lib/utils.h>
#include <plat/arm/common/plat_arm.h>
#include "morello_def.h"
#include <platform_def.h>
-#ifdef TARGET_PLATFORM_FVP
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size
- * - Local DDR size in bytes, DDR memory in main board
- */
-struct morello_plat_info {
- uint64_t local_ddr_size;
-} __packed;
-#else
-/*
- * Platform information structure stored in SDS.
- * This structure holds information about platform's DDR
- * size which is an information about multichip setup
- * - Local DDR size in bytes, DDR memory in main board
- * - Remote DDR size in bytes, DDR memory in remote board
- * - remote_chip_count
- * - multichip mode
- * - scc configuration
- */
-struct morello_plat_info {
- uint64_t local_ddr_size;
- uint64_t remote_ddr_size;
- uint8_t remote_chip_count;
- bool multichip_mode;
- uint32_t scc_config;
-} __packed;
-#endif
-
-/* Compile time assertion to ensure the size of structure is 18 bytes */
-CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
- assert_invalid_plat_info_size);
-
static scmi_channel_plat_info_t morello_scmi_plat_info = {
.scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE,
.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
@@ -67,177 +29,7 @@
return css_scmi_override_pm_ops(ops);
}
-#ifdef TARGET_PLATFORM_SOC
-/*
- * Morello platform supports RDIMMs with ECC capability. To use the ECC
- * capability, the entire DDR memory space has to be zeroed out before
- * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
- * memory from SCP is quite time consuming so the following function
- * is added to zero out the DDR memory from application processor which is
- * much faster compared to SCP.
- */
-
-static void dmc_ecc_setup(struct morello_plat_info *plat_info)
-{
- uint64_t dram2_size;
- uint32_t val;
- uint64_t tag_mem_base;
- uint64_t usable_mem_size;
-
- INFO("Total DIMM size: %uGB\n",
- (uint32_t)(plat_info->local_ddr_size / 0x40000000));
-
- assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
- dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
-
- INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
- ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
- zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
- flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
-
- /* Clear previous ECC errors while zeroing out the memory */
- val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
- mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
-
- val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
- mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
-
- /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
- mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
- mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
-
- while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_CONFIG) {
- continue;
- }
-
- while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_CONFIG) {
- continue;
- }
-
- /* Configure Bing client/server mode based on SCC configuration */
- if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
- INFO("Configuring DMC Bing in client mode\n");
- usable_mem_size = plat_info->local_ddr_size -
- (plat_info->local_ddr_size / 128ULL);
-
- /* Linear DDR address */
- tag_mem_base = usable_mem_size;
- tag_mem_base = tag_mem_base / 4;
-
- /* Reverse translation */
- if (tag_mem_base < ARM_DRAM1_BASE) {
- tag_mem_base += ARM_DRAM1_BASE;
- } else {
- tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
- ARM_DRAM2_BASE;
- }
-
- mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
- mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
- mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
- mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
-
- if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
- mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
- mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
- INFO("C1 Tag Cache Enabled\n");
- }
-
- if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
- mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
- mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
- INFO("C2 Tag Cache Enabled\n");
- }
-
- mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
- (uint32_t)tag_mem_base);
- mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
- (uint32_t)tag_mem_base);
- mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
- (uint32_t)(tag_mem_base >> 32));
- mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
- (uint32_t)(tag_mem_base >> 32));
-
- mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
- MORELLO_DMC_MEM_ACCESS_DIS);
- mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
- MORELLO_DMC_MEM_ACCESS_DIS);
-
- INFO("Tag base set to 0x%lx\n", tag_mem_base);
- plat_info->local_ddr_size = usable_mem_size;
- } else {
- INFO("Configuring DMC Bing in server mode\n");
- mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
- mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
- }
-
- INFO("Enabling ECC on DMCs\n");
- /* Enable ECC in DMCs */
- mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
- MORELLO_DMC_ERR0CTLR0_ECC_EN);
- mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
- MORELLO_DMC_ERR0CTLR0_ECC_EN);
-
- /* Set DMCs to READY state */
- mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
- mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
-
- while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_READY) {
- continue;
- }
-
- while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
- MORELLO_DMC_MEMC_STATUS_MASK) !=
- MORELLO_DMC_MEMC_CMD_READY) {
- continue;
- }
-}
-#endif
-
void bl31_platform_setup(void)
{
- int ret;
- struct morello_plat_info plat_info;
-
- ret = sds_init();
- if (ret != SDS_OK) {
- ERROR("SDS initialization failed. ret:%d\n", ret);
- panic();
- }
-
- ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
- MORELLO_SDS_PLATFORM_INFO_OFFSET,
- &plat_info,
- MORELLO_SDS_PLATFORM_INFO_SIZE,
- SDS_ACCESS_MODE_NON_CACHED);
- if (ret != SDS_OK) {
- ERROR("Error getting platform info from SDS. ret:%d\n", ret);
- panic();
- }
-
- /* Validate plat_info SDS */
-#ifdef TARGET_PLATFORM_FVP
- if (plat_info.local_ddr_size == 0U) {
-#else
- if ((plat_info.local_ddr_size == 0U)
- || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
- || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
- || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
- ) {
-#endif
- ERROR("platform info SDS is corrupted\n");
- panic();
- }
-
arm_bl31_platform_setup();
-
-#ifdef TARGET_PLATFORM_SOC
- dmc_ecc_setup(&plat_info);
-#endif
}
diff --git a/plat/arm/board/morello/morello_plat.c b/plat/arm/board/morello/morello_plat.c
index 42e5171..1da0ff9 100644
--- a/plat/arm/board/morello/morello_plat.c
+++ b/plat/arm/board/morello/morello_plat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,7 +15,7 @@
* Table of regions to map using the MMU.
* Replace or extend the below regions as required
*/
-#if IMAGE_BL1 || IMAGE_BL31
+#if IMAGE_BL1
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
MORELLO_MAP_DEVICE,
@@ -25,12 +25,23 @@
{0}
};
#endif
+
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ MORELLO_MAP_DEVICE,
+ MORELLO_MAP_NS_SRAM,
+ {0}
+};
+#endif
+
#if IMAGE_BL2
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
MORELLO_MAP_DEVICE,
MORELLO_MAP_NS_SRAM,
ARM_MAP_DRAM1,
+ ARM_MAP_DRAM2,
#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
ARM_MAP_BL1_RW,
#endif
diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk
index 86047e3..156b7ea 100644
--- a/plat/arm/board/morello/platform.mk
+++ b/plat/arm/board/morello/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -83,6 +83,8 @@
override ARM_PLAT_MT := 1
+override ARM_BL31_IN_DRAM := 1
+
# Errata workarounds:
ERRATA_N1_1868343 := 1
diff --git a/plat/arm/board/n1sdp/fdts/n1sdp_fw_config.dts b/plat/arm/board/n1sdp/fdts/n1sdp_fw_config.dts
new file mode 100644
index 0000000..700b900
--- /dev/null
+++ b/plat/arm/board/n1sdp/fdts/n1sdp_fw_config.dts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+/ {
+ dtb-registry {
+ compatible = "fconf,dyn_cfg-dtb_registry";
+ tb_fw-config {
+ load-address = <0x0 0x4001300>;
+ max-size = <0x200>;
+ id = <TB_FW_CONFIG_ID>;
+ };
+ tos_fw-config {
+ load-address = <0x0 0x4001600>;
+ max-size = <0x1000>;
+ id = <TOS_FW_CONFIG_ID>;
+ };
+ nt_fw-config {
+ load-address = <0x0 0xFEF00000>;
+ max-size = <0x0100000>;
+ id = <NT_FW_CONFIG_ID>;
+ };
+ };
+};
diff --git a/plat/arm/board/n1sdp/fdts/n1sdp_nt_fw_config.dts b/plat/arm/board/n1sdp/fdts/n1sdp_nt_fw_config.dts
new file mode 100644
index 0000000..da5e04d
--- /dev/null
+++ b/plat/arm/board/n1sdp/fdts/n1sdp_nt_fw_config.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+ /* compatible string */
+ compatible = "arm,n1sdp";
+
+ /*
+ * Place holder for platform-info node with default values.
+ * The values will be set to the correct values during
+ * the BL2 stage of boot.
+ */
+ platform-info {
+ multichip-mode = <0x0>;
+ secondary-chip-count = <0x0>;
+ local-ddr-size = <0x0>;
+ remote-ddr-size = <0x0>;
+ };
+};
\ No newline at end of file
diff --git a/plat/arm/board/n1sdp/fdts/n1sdp_optee_spmc_manifest.dts b/plat/arm/board/n1sdp/fdts/n1sdp_optee_spmc_manifest.dts
new file mode 100644
index 0000000..ed87080
--- /dev/null
+++ b/plat/arm/board/n1sdp/fdts/n1sdp_optee_spmc_manifest.dts
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+/ {
+ compatible = "arm,ffa-core-manifest-1.0";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ /*
+ * BL32 image details needed by SPMC
+ *
+ * Note:
+ * binary_size: size of BL32 + TOS_FW_CONFIG
+ */
+
+ attribute {
+ spmc_id = <0x8000>;
+ maj_ver = <0x1>;
+ min_ver = <0x0>;
+ exec_state = <0x0>;
+ load_address = <0x0 0x08000000>;
+ entrypoint = <0x0 0x08000000>;
+ binary_size = <0x2000000>;
+ };
+
+};
diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/n1sdp/fdts/n1sdp_tb_fw_config.dts
similarity index 89%
rename from plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
rename to plat/arm/board/n1sdp/fdts/n1sdp_tb_fw_config.dts
index 49eda27..e5ffba3 100644
--- a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
+++ b/plat/arm/board/n1sdp/fdts/n1sdp_tb_fw_config.dts
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/dts-v1/;
-
/ {
tb_fw-config {
compatible = "arm,tb_fw";
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index cc07852..b3799a7 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,8 +15,9 @@
#define PLAT_ARM_BOOT_UART_BASE 0x2A400000
#define PLAT_ARM_BOOT_UART_CLK_IN_HZ 50000000
-#define PLAT_ARM_RUN_UART_BASE 0x2A410000
-#define PLAT_ARM_RUN_UART_CLK_IN_HZ 50000000
+/* IOFPGA UART0 */
+#define PLAT_ARM_RUN_UART_BASE 0x1C090000
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ 24000000
#define PLAT_ARM_SP_MIN_RUN_UART_BASE 0x2A410000
#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ 50000000
@@ -27,6 +28,27 @@
#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000)
#define PLAT_ARM_DRAM2_SIZE ULL(0xF80000000)
+#define MAX_IO_DEVICES U(3)
+#define MAX_IO_HANDLES U(4)
+
+#define PLAT_ARM_FLASH_IMAGE_BASE 0x18200000
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE 0x00800000
+
+#define PLAT_ARM_NVM_BASE 0x18200000
+#define PLAT_ARM_NVM_SIZE 0x00800000
+
+#if defined NS_BL1U_BASE
+# undef NS_BL1U_BASE
+# define NS_BL1U_BASE (PLAT_ARM_NVM_BASE + UL(0x00800000))
+#endif
+
+/* Non-volatile counters */
+#define SOC_TRUSTED_NVCTR_BASE 0x7fe70000
+#define TFW_NVCTR_BASE (SOC_TRUSTED_NVCTR_BASE)
+#define TFW_NVCTR_SIZE U(4)
+#define NTFW_CTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0004)
+#define NTFW_CTR_SIZE U(4)
+
/* N1SDP remote chip at 4 TB offset */
#define PLAT_ARM_REMOTE_CHIP_OFFSET (ULL(1) << 42)
@@ -59,8 +81,46 @@
#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE 0x45400000
#endif
+/*
+ * Trusted SRAM in N1SDP is 512 KB but only the bottom 384 KB
+ * is used for trusted board boot flow. The top 128 KB is used
+ * to load AP-BL1 image.
+ */
+#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00060000 /* 384 KB */
+
-#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00080000 /* 512 KB */
-#define PLAT_ARM_MAX_BL31_SIZE 0X20000
+/*
+ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
+ * plus a little space for growth.
+ */
+#define PLAT_ARM_MAX_BL1_RW_SIZE 0xC000
+
+/*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+
+#if USE_ROMLIB
+# define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0x1000
+# define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0xe000
+#else
+# define PLAT_ARM_MAX_ROMLIB_RW_SIZE U(0)
+# define PLAT_ARM_MAX_ROMLIB_RO_SIZE U(0)
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+# define PLAT_ARM_MAX_BL2_SIZE 0x22000
+#else
+# define PLAT_ARM_MAX_BL2_SIZE 0x14000
+#endif
+
+#define PLAT_ARM_MAX_BL31_SIZE UL(0x40000)
+
+#define PLAT_ARM_SPMC_BASE U(0x08000000)
+#define PLAT_ARM_SPMC_SIZE UL(0x02000000) /* 32 MB */
+
/*******************************************************************************
* N1SDP topology related constants
@@ -83,10 +143,48 @@
* PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
* plat_arm_mmap array defined for each BL stage.
*/
-#define PLAT_ARM_MMAP_ENTRIES 9
-#define MAX_XLAT_TABLES 10
-#define PLATFORM_STACK_SIZE 0x400
+#ifdef IMAGE_BL1
+# define PLAT_ARM_MMAP_ENTRIES U(6)
+# define MAX_XLAT_TABLES U(5)
+#endif
+
+#ifdef IMAGE_BL2
+# define PLAT_ARM_MMAP_ENTRIES U(11)
+# define MAX_XLAT_TABLES U(10)
+#endif
+
+#ifdef IMAGE_BL31
+# define PLAT_ARM_MMAP_ENTRIES U(12)
+# define MAX_XLAT_TABLES U(12)
+#endif
+
+/*
+ * Size of cacheable stacks
+ */
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE 0x1000
+# else
+# define PLATFORM_STACK_SIZE 0x440
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE 0x1000
+# else
+# define PLATFORM_STACK_SIZE 0x400
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE 0x400
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+# define PLATFORM_STACK_SIZE 0x500
+# else
+# define PLATFORM_STACK_SIZE 0x400
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE 0x440
+#endif
#define PLAT_ARM_NSTIMER_FRAME_ID 0
#define PLAT_CSS_MHU_BASE 0x45000000
@@ -106,6 +204,10 @@
PLAT_ARM_REMOTE_CHIP_OFFSET
#define N1SDP_REMOTE_DEVICE_SIZE N1SDP_DEVICE_SIZE
+/* Real base is 0x0. Changed to load BL1 at this address */
+# define PLAT_ARM_TRUSTED_ROM_BASE 0x04060000
+# define PLAT_ARM_TRUSTED_ROM_SIZE 0x00020000 /* 128KB */
+
#define N1SDP_MAP_DEVICE MAP_REGION_FLAT( \
N1SDP_DEVICE_BASE, \
N1SDP_DEVICE_SIZE, \
diff --git a/plat/arm/board/n1sdp/n1sdp_bl1_setup.c b/plat/arm/board/n1sdp/n1sdp_bl1_setup.c
new file mode 100644
index 0000000..ed93222
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_bl1_setup.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+
+void soc_css_init_nic400(void)
+{
+}
+
+void soc_css_init_pcie(void)
+{
+}
diff --git a/plat/arm/board/n1sdp/n1sdp_bl2_setup.c b/plat/arm/board/n1sdp/n1sdp_bl2_setup.c
new file mode 100644
index 0000000..5f8af9f
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_bl2_setup.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/css/sds.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+
+#include "n1sdp_def.h"
+#include <plat/arm/common/plat_arm.h>
+
+struct n1sdp_plat_info {
+ bool multichip_mode;
+ uint8_t secondary_count;
+ uint8_t local_ddr_size;
+ uint8_t remote_ddr_size;
+} __packed;
+
+/*
+ * N1SDP platform supports RDIMMs with ECC capability. To use the ECC
+ * capability, the entire DDR memory space has to be zeroed out before
+ * enabling the ECC bits in DMC620. Zeroing out several gigabytes of
+ * memory from SCP is quite time consuming so the following function
+ * is added to zero out the DDR memory from application processor which is
+ * much faster compared to SCP.
+ */
+
+void dmc_ecc_setup(uint8_t ddr_size_gb)
+{
+ uint64_t dram2_size;
+
+ dram2_size = (ddr_size_gb * 1024UL * 1024UL * 1024UL) -
+ ARM_DRAM1_SIZE;
+
+ INFO("Zeroing DDR memories\n");
+ zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
+ flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
+ zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
+ flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
+
+ INFO("Enabling ECC on DMCs\n");
+ /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
+ mmio_write_32(N1SDP_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_CONFIG);
+ mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_CONFIG);
+
+ /* Enable ECC in DMCs */
+ mmio_setbits_32(N1SDP_DMC0_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN);
+ mmio_setbits_32(N1SDP_DMC1_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN);
+
+ /* Set DMCs to READY state */
+ mmio_write_32(N1SDP_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
+ mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
+}
+
+void bl2_platform_setup(void)
+{
+ int ret;
+ struct n1sdp_plat_info plat_info;
+
+ ret = sds_init();
+ if (ret != SDS_OK) {
+ ERROR("SDS initialization failed\n");
+ panic();
+ }
+
+ ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
+ N1SDP_SDS_PLATFORM_INFO_OFFSET,
+ &plat_info,
+ N1SDP_SDS_PLATFORM_INFO_SIZE,
+ SDS_ACCESS_MODE_NON_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("Error getting platform info from SDS\n");
+ panic();
+ }
+ /* Validate plat_info SDS */
+ if ((plat_info.local_ddr_size == 0)
+ || (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
+ || (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
+ || (plat_info.secondary_count > N1SDP_MAX_SECONDARY_COUNT)) {
+ ERROR("platform info SDS is corrupted\n");
+ panic();
+ }
+
+ dmc_ecc_setup(plat_info.local_ddr_size);
+ arm_bl2_platform_setup();
+}
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index d7003e9..5e897fe 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -1,11 +1,9 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <platform_def.h>
-
#include <common/debug.h>
#include <drivers/arm/css/css_mhu_doorbell.h>
#include <drivers/arm/css/scmi.h>
@@ -16,6 +14,7 @@
#include <plat/arm/common/plat_arm.h>
#include "n1sdp_def.h"
+#include <platform_def.h>
/*
* Platform information structure stored in SDS.
@@ -24,28 +23,17 @@
* enabling the ECC capability as well as information
* about multichip setup
* - multichip mode
- * - slave_count
+ * - secondary_count
* - Local DDR size in GB, DDR memory in master board
- * - Remote DDR size in GB, DDR memory in slave board
+ * - Remote DDR size in GB, DDR memory in secondary board
*/
struct n1sdp_plat_info {
bool multichip_mode;
- uint8_t slave_count;
+ uint8_t secondary_count;
uint8_t local_ddr_size;
uint8_t remote_ddr_size;
} __packed;
-/*
- * BL33 image information structure stored in SDS.
- * This structure holds the source & destination addresses and
- * the size of the BL33 image which will be loaded by BL31.
- */
-struct n1sdp_bl33_info {
- uint32_t bl33_src_addr;
- uint32_t bl33_dst_addr;
- uint32_t bl33_size;
-};
-
static scmi_channel_plat_info_t n1sdp_scmi_plat_info = {
.scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE,
.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
@@ -90,38 +78,10 @@
* enabling the ECC bits in DMC620. Zeroing out several gigabytes of
* memory from SCP is quite time consuming so the following function
* is added to zero out the DDR memory from application processor which is
- * much faster compared to SCP. BL33 binary cannot be copied to DDR memory
- * before enabling ECC so copy_bl33 function is added to copy BL33 binary
- * from IOFPGA-DDR3 memory to main DDR4 memory.
+ * much faster compared to SCP. Local DDR memory is zeroed out during BL2
+ * stage. If remote chip is connected, it's DDR memory is zeroed out here.
*/
-void dmc_ecc_setup(uint8_t ddr_size_gb)
-{
- uint64_t dram2_size;
-
- dram2_size = (ddr_size_gb * 1024UL * 1024UL * 1024UL) -
- ARM_DRAM1_SIZE;
-
- INFO("Zeroing DDR memories\n");
- zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
- flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
- zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
- flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
-
- INFO("Enabling ECC on DMCs\n");
- /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
- mmio_write_32(N1SDP_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_CONFIG);
- mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_CONFIG);
-
- /* Enable ECC in DMCs */
- mmio_setbits_32(N1SDP_DMC0_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN);
- mmio_setbits_32(N1SDP_DMC1_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN);
-
- /* Set DMCs to READY state */
- mmio_write_32(N1SDP_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
- mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
-}
-
void remote_dmc_ecc_setup(uint8_t remote_ddr_size)
{
uint64_t remote_dram2_size;
@@ -154,22 +114,6 @@
mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
}
-void copy_bl33(uint32_t src, uint32_t dst, uint32_t size)
-{
- uint32_t i;
-
- INFO("Copying BL33 to DDR memory\n");
- for (i = 0; i < size; i = i + 8)
- mmio_write_64((dst + i), mmio_read_64(src + i));
-
- for (i = 0; i < size; i = i + 8) {
- if (mmio_read_64(src + i) != mmio_read_64(dst + i)) {
- ERROR("Copy failed!\n");
- panic();
- }
- }
-}
-
void n1sdp_bl31_multichip_setup(void)
{
plat_arm_override_gicr_frames(n1sdp_multichip_gicr_frames);
@@ -180,7 +124,6 @@
{
int ret;
struct n1sdp_plat_info plat_info;
- struct n1sdp_bl33_info bl33_info;
ret = sds_init();
if (ret != SDS_OK) {
@@ -201,41 +144,18 @@
if ((plat_info.local_ddr_size == 0)
|| (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
|| (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
- || (plat_info.slave_count > N1SDP_MAX_SLAVE_COUNT)) {
+ || (plat_info.secondary_count > N1SDP_MAX_SECONDARY_COUNT)) {
ERROR("platform info SDS is corrupted\n");
panic();
}
if (plat_info.multichip_mode) {
- n1sdp_multichip_data.chip_count = plat_info.slave_count + 1;
+ n1sdp_multichip_data.chip_count = plat_info.secondary_count + 1;
n1sdp_bl31_multichip_setup();
}
arm_bl31_platform_setup();
- dmc_ecc_setup(plat_info.local_ddr_size);
-
/* Check if remote memory is present */
if ((plat_info.multichip_mode) && (plat_info.remote_ddr_size != 0))
remote_dmc_ecc_setup(plat_info.remote_ddr_size);
-
- ret = sds_struct_read(N1SDP_SDS_BL33_INFO_STRUCT_ID,
- N1SDP_SDS_BL33_INFO_OFFSET,
- &bl33_info,
- N1SDP_SDS_BL33_INFO_SIZE,
- SDS_ACCESS_MODE_NON_CACHED);
- if (ret != SDS_OK) {
- ERROR("Error getting BL33 info from SDS\n");
- panic();
- }
- copy_bl33(bl33_info.bl33_src_addr,
- bl33_info.bl33_dst_addr,
- bl33_info.bl33_size);
- /*
- * Pass platform information to BL33. This method is followed as
- * currently there is no BL1/BL2 involved in boot flow of N1SDP.
- * When TBBR is implemented for N1SDP, this method should be removed
- * and platform information should be passed to BL33 using NT_FW_CONFIG
- * passing mechanism.
- */
- mmio_write_32(N1SDP_PLATFORM_INFO_BASE, *(uint32_t *)&plat_info);
}
diff --git a/plat/arm/board/n1sdp/n1sdp_def.h b/plat/arm/board/n1sdp/n1sdp_def.h
index 30e29a7..ffa6a03 100644
--- a/plat/arm/board/n1sdp/n1sdp_def.h
+++ b/plat/arm/board/n1sdp/n1sdp_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,12 +20,7 @@
#define N1SDP_SDS_PLATFORM_INFO_OFFSET 0
#define N1SDP_SDS_PLATFORM_INFO_SIZE 4
#define N1SDP_MAX_DDR_CAPACITY_GB 64
-#define N1SDP_MAX_SLAVE_COUNT 16
-
-/* SDS BL33 image information defines */
-#define N1SDP_SDS_BL33_INFO_STRUCT_ID 9
-#define N1SDP_SDS_BL33_INFO_OFFSET 0
-#define N1SDP_SDS_BL33_INFO_SIZE 12
+#define N1SDP_MAX_SECONDARY_COUNT 16
/* DMC memory command registers */
#define N1SDP_DMC0_MEMC_CMD_REG 0x4E000008
@@ -54,7 +49,4 @@
/* DMC ECC enable bit in ERR0CTLR0 register */
#define N1SDP_DMC_ERR0CTLR0_ECC_EN 0x1
-/* Base address of non-secure SRAM where Platform information will be filled */
-#define N1SDP_PLATFORM_INFO_BASE 0x06008000
-
#endif /* N1SDP_DEF_H */
diff --git a/plat/arm/board/sgm775/sgm775_err.c b/plat/arm/board/n1sdp/n1sdp_err.c
similarity index 66%
rename from plat/arm/board/sgm775/sgm775_err.c
rename to plat/arm/board/n1sdp/n1sdp_err.c
index dc114f0..629e76a 100644
--- a/plat/arm/board/sgm775/sgm775_err.c
+++ b/plat/arm/board/n1sdp/n1sdp_err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,7 +7,7 @@
#include <plat/arm/common/plat_arm.h>
/*
- * sgm775 error handler
+ * n1sdp error handler
*/
void __dead2 plat_arm_error_handler(int err)
{
diff --git a/plat/arm/board/n1sdp/n1sdp_image_load.c b/plat/arm/board/n1sdp/n1sdp_image_load.c
new file mode 100644
index 0000000..6c3528c
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_image_load.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/arm/css/sds.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+
+#include "n1sdp_def.h"
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size which will be used to zero out the memory before
+ * enabling the ECC capability as well as information
+ * about multichip setup
+ * - multichip mode
+ * - secondary_count
+ * - Local DDR size in GB, DDR memory in master board
+ * - Remote DDR size in GB, DDR memory in secondary board
+ */
+struct n1sdp_plat_info {
+ bool multichip_mode;
+ uint8_t secondary_count;
+ uint8_t local_ddr_size;
+ uint8_t remote_ddr_size;
+} __packed;
+
+/*******************************************************************************
+ * This function inserts Platform information via device tree nodes as,
+ * platform-info {
+ * multichip-mode = <0x0>;
+ * secondary-chip-count = <0x0>;
+ * local-ddr-size = <0x0>;
+ * remote-ddr-size = <0x0>;
+ * };
+ ******************************************************************************/
+static int plat_n1sdp_append_config_node(struct n1sdp_plat_info *plat_info)
+{
+ bl_mem_params_node_t *mem_params;
+ void *fdt;
+ int nodeoffset, err;
+
+ mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
+ if (mem_params == NULL) {
+ ERROR("NT_FW CONFIG base address is NULL\n");
+ return -1;
+ }
+
+ fdt = (void *)(mem_params->image_info.image_base);
+
+ /* Check the validity of the fdt */
+ if (fdt_check_header(fdt) != 0) {
+ ERROR("Invalid NT_FW_CONFIG DTB passed\n");
+ return -1;
+ }
+
+ nodeoffset = fdt_subnode_offset(fdt, 0, "platform-info");
+ if (nodeoffset < 0) {
+ ERROR("NT_FW_CONFIG: Failed to get platform-info node offset\n");
+ return -1;
+ }
+
+ err = fdt_setprop_u32(fdt, nodeoffset, "multichip-mode",
+ plat_info->multichip_mode);
+ if (err < 0) {
+ ERROR("NT_FW_CONFIG: Failed to set multichip-mode\n");
+ return -1;
+ }
+
+ err = fdt_setprop_u32(fdt, nodeoffset, "secondary-chip-count",
+ plat_info->secondary_count);
+ if (err < 0) {
+ ERROR("NT_FW_CONFIG: Failed to set secondary-chip-count\n");
+ return -1;
+ }
+
+ err = fdt_setprop_u32(fdt, nodeoffset, "local-ddr-size",
+ plat_info->local_ddr_size);
+ if (err < 0) {
+ ERROR("NT_FW_CONFIG: Failed to set local-ddr-size\n");
+ return -1;
+ }
+
+ err = fdt_setprop_u32(fdt, nodeoffset, "remote-ddr-size",
+ plat_info->remote_ddr_size);
+ if (err < 0) {
+ ERROR("NT_FW_CONFIG: Failed to set remote-ddr-size\n");
+ return -1;
+ }
+
+ flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function returns the list of executable images.
+ ******************************************************************************/
+bl_params_t *plat_get_next_bl_params(void)
+{
+ int ret;
+ struct n1sdp_plat_info plat_info;
+
+ ret = sds_init();
+ if (ret != SDS_OK) {
+ ERROR("SDS initialization failed. ret:%d\n", ret);
+ panic();
+ }
+
+ ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
+ N1SDP_SDS_PLATFORM_INFO_OFFSET,
+ &plat_info,
+ N1SDP_SDS_PLATFORM_INFO_SIZE,
+ SDS_ACCESS_MODE_NON_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("Error getting platform info from SDS. ret:%d\n", ret);
+ panic();
+ }
+
+ /* Validate plat_info SDS */
+ if ((plat_info.local_ddr_size == 0U)
+ || (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
+ || (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
+ || (plat_info.secondary_count > N1SDP_MAX_SECONDARY_COUNT)
+ ){
+ ERROR("platform info SDS is corrupted\n");
+ panic();
+ }
+
+ ret = plat_n1sdp_append_config_node(&plat_info);
+ if (ret != 0) {
+ panic();
+ }
+
+ return arm_get_next_bl_params();
+}
diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c
index 951a562..502268c 100644
--- a/plat/arm/board/n1sdp/n1sdp_plat.c
+++ b/plat/arm/board/n1sdp/n1sdp_plat.c
@@ -1,16 +1,13 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <platform_def.h>
+#include <assert.h>
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/common/platform.h>
#include <drivers/arm/sbsa.h>
+#include <plat/arm/common/plat_arm.h>
#include "n1sdp_def.h"
@@ -19,17 +16,51 @@
* Replace or extend the below regions as required
*/
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ N1SDP_MAP_DEVICE,
+ N1SDP_MAP_NS_SRAM,
+ ARM_MAP_DRAM1,
+ {0}
+};
+#endif
+
+#if IMAGE_BL2
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
N1SDP_MAP_DEVICE,
N1SDP_MAP_NS_SRAM,
ARM_MAP_DRAM1,
ARM_MAP_DRAM2,
+#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
+ ARM_MAP_BL1_RW,
+#endif
+ {0}
+};
+#endif
+
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ N1SDP_MAP_DEVICE,
+ N1SDP_MAP_NS_SRAM,
N1SDP_MAP_REMOTE_DEVICE,
N1SDP_MAP_REMOTE_DRAM1,
N1SDP_MAP_REMOTE_DRAM2,
{0}
};
+#endif
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ assert(heap_addr != NULL);
+ assert(heap_size != NULL);
+
+ return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
void plat_arm_secure_wdt_start(void)
{
diff --git a/plat/arm/board/n1sdp/n1sdp_trusted_boot.c b/plat/arm/board/n1sdp/n1sdp_trusted_boot.c
new file mode 100644
index 0000000..c7dc47f
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_trusted_boot.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * Return the non-volatile counter value stored in the platform. The cookie
+ * will contain the OID of the counter in the certificate.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ *nv_ctr = N1SDP_FW_NVCTR_VAL;
+ return 0;
+}
+
+/*
+ * Store a new non-volatile counter value. By default on ARM development
+ * platforms, the non-volatile counters are RO and cannot be modified. We expect
+ * the values in the certificates to always match the RO values so that this
+ * function is never called.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ return 1;
+}
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
+
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index f20397a..9c0cc02 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -28,30 +28,66 @@
PLAT_BL_COMMON_SOURCES := ${N1SDP_BASE}/n1sdp_plat.c \
${N1SDP_BASE}/aarch64/n1sdp_helper.S
-BL1_SOURCES += drivers/arm/sbsa/sbsa.c
+BL1_SOURCES := ${N1SDP_CPU_SOURCES} \
+ ${INTERCONNECT_SOURCES} \
+ ${N1SDP_BASE}/n1sdp_err.c \
+ ${N1SDP_BASE}/n1sdp_trusted_boot.c \
+ ${N1SDP_BASE}/n1sdp_bl1_setup.c \
+ drivers/arm/sbsa/sbsa.c
+
+BL2_SOURCES := ${N1SDP_BASE}/n1sdp_security.c \
+ ${N1SDP_BASE}/n1sdp_err.c \
+ ${N1SDP_BASE}/n1sdp_trusted_boot.c \
+ lib/utils/mem_region.c \
+ ${N1SDP_BASE}/n1sdp_bl2_setup.c \
+ ${N1SDP_BASE}/n1sdp_image_load.c \
+ drivers/arm/css/sds/sds.c
BL31_SOURCES := ${N1SDP_CPU_SOURCES} \
${INTERCONNECT_SOURCES} \
${N1SDP_GIC_SOURCES} \
- ${N1SDP_BASE}/n1sdp_bl31_setup.c \
+ ${N1SDP_BASE}/n1sdp_bl31_setup.c \
${N1SDP_BASE}/n1sdp_topology.c \
${N1SDP_BASE}/n1sdp_security.c \
drivers/arm/css/sds/sds.c
FDT_SOURCES += fdts/${PLAT}-single-chip.dts \
- fdts/${PLAT}-multi-chip.dts
+ fdts/${PLAT}-multi-chip.dts \
+ ${N1SDP_BASE}/fdts/n1sdp_fw_config.dts \
+ ${N1SDP_BASE}/fdts/n1sdp_tb_fw_config.dts \
+ ${N1SDP_BASE}/fdts/n1sdp_nt_fw_config.dts
+
+FW_CONFIG := ${BUILD_PLAT}/fdts/n1sdp_fw_config.dtb
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/n1sdp_tb_fw_config.dtb
+NT_FW_CONFIG := ${BUILD_PLAT}/fdts/n1sdp_nt_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
+
+N1SDP_SPMC_MANIFEST_DTS := ${N1SDP_BASE}/fdts/${PLAT}_optee_spmc_manifest.dts
+FDT_SOURCES += ${N1SDP_SPMC_MANIFEST_DTS}
+N1SDP_TOS_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_optee_spmc_manifest.dtb
+
+# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${N1SDP_TOS_FW_CONFIG},--tos-fw-config,${N1SDP_TOS_FW_CONFIG}))
+
+# Setting to 0 as no NVCTR in N1SDP
+N1SDP_FW_NVCTR_VAL := 0
+TFW_NVCTR_VAL := ${N1SDP_FW_NVCTR_VAL}
+NTFW_NVCTR_VAL := ${N1SDP_FW_NVCTR_VAL}
+
+# Add N1SDP_FW_NVCTR_VAL
+$(eval $(call add_define,N1SDP_FW_NVCTR_VAL))
# TF-A not required to load the SCP Images
override CSS_LOAD_SCP_IMAGES := 0
-# BL1/BL2 Image not a part of the capsule Image for n1sdp
-override NEED_BL1 := no
-override NEED_BL2 := no
override NEED_BL2U := no
-#TFA for n1sdp starts from BL31
-override RESET_TO_BL31 := 1
-
# 32 bit mode not supported
override CTX_INCLUDE_AARCH32_REGS := 0
@@ -73,4 +109,3 @@
include plat/arm/common/arm_common.mk
include plat/arm/css/common/css_common.mk
include plat/arm/board/common/board_common.mk
-
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
index a9b30a4..69bfd7b 100644
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ b/plat/arm/board/rde1edge/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,12 +26,15 @@
#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL3
+/* Maximum number of address bits used per chip */
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(36)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
index a61b0d5..de01902 100644
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ b/plat/arm/board/rdn1edge/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,12 +30,17 @@
/* Virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
+/* Maximum number of address bits used per chip */
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(42)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43)
+#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
+ CSS_SGI_CHIP_COUNT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
+ CSS_SGI_CHIP_COUNT)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
diff --git a/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts b/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
index bbc36fc..dd70141 100644
--- a/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
+++ b/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020 - 2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,5 +18,26 @@
platform-id = <0x0>;
config-id = <0x0>;
multi-chip-mode = <0x0>;
+ /*
+ * First cell pair: Count of isolated CPUs in the list.
+ * Rest of the cells: MPID list of the isolated CPUs.
+ */
+ isolated-cpu-list = <0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0
+ 0x0 0x0>;
};
};
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index e4015f7..464a157 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -69,15 +69,16 @@
*/
#ifdef __aarch64__
#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(46) /* 64TB */
+#else
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(42) /* 4TB */
+#endif
+
#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
CSS_SGI_CHIP_COUNT)
#define PLAT_VIRT_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
CSS_SGI_CHIP_COUNT)
#else
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42)
-#endif
-#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
#endif
diff --git a/plat/arm/board/rdv1/include/platform_def.h b/plat/arm/board/rdv1/include/platform_def.h
index 5b98b4e..620fa3e 100644
--- a/plat/arm/board/rdv1/include/platform_def.h
+++ b/plat/arm/board/rdv1/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -46,12 +46,15 @@
(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \
(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
+/* Maximum number of address bits used per chip */
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(42)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 42)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 42)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
diff --git a/plat/arm/board/rdv1mc/include/platform_def.h b/plat/arm/board/rdv1mc/include/platform_def.h
index 12ce806..3670904 100644
--- a/plat/arm/board/rdv1mc/include/platform_def.h
+++ b/plat/arm/board/rdv1mc/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -46,6 +46,9 @@
/* Virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xC0000000)
+/* Remote chip address offset (4TB per chip) */
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(42)
+
/* Physical and virtual address space limits for MMU in AARCH64 mode */
#define PLAT_PHY_ADDR_SPACE_SIZE CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
CSS_SGI_CHIP_COUNT)
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index 72d5f7c..82a38c5 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,12 +27,15 @@
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
+/* Maximum number of address bits used per chip */
+#define CSS_SGI_ADDR_BITS_PER_CHIP U(36)
+
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
deleted file mode 100644
index 5d478e9..0000000
--- a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/tbbr/tbbr_img_def.h>
-
-/dts-v1/;
-
-/ {
- dtb-registry {
- compatible = "fconf,dyn_cfg-dtb_registry";
-
- tb_fw-config {
- load-address = <0x0 0x4001300>;
- max-size = <0x200>;
- id = <TB_FW_CONFIG_ID>;
- };
- };
-};
diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h
deleted file mode 100644
index e83cd57..0000000
--- a/plat/arm/board/sgm775/include/platform_def.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <sgm_base_platform_def.h>
-
-#define PLAT_MAX_CPUS_PER_CLUSTER U(8)
-#define PLAT_MAX_PE_PER_CPU U(1)
-
-#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
-#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
-#endif
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
deleted file mode 100644
index f8df1a7..0000000
--- a/plat/arm/board/sgm775/platform.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-$(warning Platform ${PLAT} is deprecated. Some of the features might not work as expected)
-
-include plat/arm/css/sgm/sgm-common.mk
-
-SGM775_BASE= plat/arm/board/sgm775
-
-# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += ${SGM775_BASE}/fdts/${PLAT}_fw_config.dts \
- ${SGM775_BASE}/fdts/${PLAT}_tb_fw_config.dts
-FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
-TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
-
-# Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
-# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
-
-PLAT_INCLUDES +=-I${SGM775_BASE}/include/
-
-BL1_SOURCES += ${SGM775_BASE}/sgm775_err.c
-
-BL2_SOURCES += lib/utils/mem_region.c \
- ${SGM775_BASE}/sgm775_err.c \
- plat/arm/common/arm_nor_psci_mem_protect.c
-
-BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \
- lib/utils/mem_region.c \
- plat/arm/common/arm_nor_psci_mem_protect.c
-
-ifeq (${TRUSTED_BOARD_BOOT}, 1)
-BL1_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c
-BL2_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c
-endif
diff --git a/plat/arm/board/sgm775/sgm775_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c
deleted file mode 100644
index 4592b8f..0000000
--- a/plat/arm/board/sgm775/sgm775_trusted_boot.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm AlgorithmIdentifier,
- * digest OCTET STRING
- * }
- */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
- unsigned int *flags)
-{
- return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
-}
diff --git a/plat/arm/board/sgm775/tsp/tsp-sgm775.mk b/plat/arm/board/sgm775/tsp/tsp-sgm775.mk
deleted file mode 100644
index 129b586..0000000
--- a/plat/arm/board/sgm775/tsp/tsp-sgm775.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-include plat/arm/css/sgm/tsp/tsp-sgm.mk
\ No newline at end of file
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 745d91c..11762d4 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -177,8 +177,14 @@
#define PLAT_ARM_NSTIMER_FRAME_ID 0
+#if (TARGET_PLATFORM >= 2)
+#define PLAT_ARM_TRUSTED_ROM_BASE 0x1000
+#else
#define PLAT_ARM_TRUSTED_ROM_BASE 0x0
-#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000 /* 512KB */
+#endif
+
+/* PLAT_ARM_TRUSTED_ROM_SIZE 512KB minus ROM base. */
+#define PLAT_ARM_TRUSTED_ROM_SIZE (0x00080000 - PLAT_ARM_TRUSTED_ROM_BASE)
#define PLAT_ARM_NSRAM_BASE 0x06000000
#define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 3acd88e..1a1bc56 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -1,14 +1,16 @@
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
include common/fdt_wrappers.mk
-ifeq ($(filter ${TARGET_PLATFORM}, 0 1),)
- $(error TARGET_PLATFORM must be 0 or 1)
+ifeq ($(shell expr $(TARGET_PLATFORM) \<= 2), 0)
+ $(error TARGET_PLATFORM must be less than or equal to 2)
endif
+$(eval $(call add_define,TARGET_PLATFORM))
+
CSS_LOAD_SCP_IMAGES := 1
CSS_USE_SCMI_SDS_DRIVER := 1
@@ -61,19 +63,24 @@
PLAT_INCLUDES += -I${TC_BASE}/include/
-# Common CPU libraries
-TC_CPU_SOURCES := lib/cpus/aarch64/cortex_a510.S
-
# CPU libraries for TARGET_PLATFORM=0
ifeq (${TARGET_PLATFORM}, 0)
-TC_CPU_SOURCES += lib/cpus/aarch64/cortex_a710.S \
+TC_CPU_SOURCES += lib/cpus/aarch64/cortex_a510.S \
+ lib/cpus/aarch64/cortex_a710.S \
lib/cpus/aarch64/cortex_x2.S
endif
# CPU libraries for TARGET_PLATFORM=1
ifeq (${TARGET_PLATFORM}, 1)
-TC_CPU_SOURCES += lib/cpus/aarch64/cortex_makalu.S \
- lib/cpus/aarch64/cortex_makalu_elp_arm.S
+TC_CPU_SOURCES += lib/cpus/aarch64/cortex_a510.S \
+ lib/cpus/aarch64/cortex_a715.S \
+ lib/cpus/aarch64/cortex_x3.S
+endif
+
+# CPU libraries for TARGET_PLATFORM=2
+ifeq (${TARGET_PLATFORM}, 2)
+TC_CPU_SOURCES += lib/cpus/aarch64/cortex_hayes.S \
+ lib/cpus/aarch64/cortex_hunter.S
endif
INTERCONNECT_SOURCES := ${TC_BASE}/tc_interconnect.c
diff --git a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
index 78360b0..18f1a37 100644
--- a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
@@ -20,71 +20,72 @@
static bl_mem_params_node_t bl2_mem_params_descs[] = {
#ifdef SCP_BL2_BASE
/* Fill SCP_BL2 related information if it exists */
- {
- .image_id = SCP_BL2_IMAGE_ID,
+ {
+ .image_id = SCP_BL2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = SCP_BL2_BASE,
- .image_info.image_max_size = PLAT_CSS_MAX_SCP_BL2_SIZE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = SCP_BL2_BASE,
+ .image_info.image_max_size = PLAT_CSS_MAX_SCP_BL2_SIZE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
#endif /* SCP_BL2_BASE */
/* Fill BL32 related information */
- {
- .image_id = BL32_IMAGE_ID,
+ {
+ .image_id = BL32_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = BL32_BASE,
- .ep_info.spsr = SPSR_MODE32(MODE32_mon, SPSR_T_ARM,
- SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL32_BASE,
+ .ep_info.spsr = SPSR_MODE32(MODE32_mon, SPSR_T_ARM,
+ SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = BL33_IMAGE_ID,
- },
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
/* Fill HW_CONFIG related information if it exists */
- {
- .image_id = HW_CONFIG_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, NON_SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ {
+ .image_id = HW_CONFIG_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t,
+ NON_SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
/* Fill BL33 related information */
- {
- .image_id = BL33_IMAGE_ID,
+ {
+ .image_id = BL33_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
#ifdef PRELOADED_BL33_BASE
- .ep_info.pc = PRELOADED_BL33_BASE,
+ .ep_info.pc = PRELOADED_BL33_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
#else
- .ep_info.pc = PLAT_ARM_NS_IMAGE_BASE,
+ .ep_info.pc = PLAT_ARM_NS_IMAGE_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = PLAT_ARM_NS_IMAGE_BASE,
- .image_info.image_max_size = ARM_DRAM1_BASE + ARM_DRAM1_SIZE
- - PLAT_ARM_NS_IMAGE_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = PLAT_ARM_NS_IMAGE_BASE,
+ .image_info.image_max_size = ARM_DRAM1_BASE + ARM_DRAM1_SIZE
+ - PLAT_ARM_NS_IMAGE_BASE,
#endif /* PRELOADED_BL33_BASE */
- .next_handoff_image_id = INVALID_IMAGE_ID,
- }
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
};
REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
index 0666e57..3d7b361 100644
--- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
@@ -20,203 +20,207 @@
static bl_mem_params_node_t bl2_mem_params_descs[] = {
#ifdef SCP_BL2_BASE
/* Fill SCP_BL2 related information if it exists */
- {
- .image_id = SCP_BL2_IMAGE_ID,
+ {
+ .image_id = SCP_BL2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = SCP_BL2_BASE,
- .image_info.image_max_size = PLAT_CSS_MAX_SCP_BL2_SIZE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = SCP_BL2_BASE,
+ .image_info.image_max_size = PLAT_CSS_MAX_SCP_BL2_SIZE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
#endif /* SCP_BL2_BASE */
#ifdef EL3_PAYLOAD_BASE
/* Fill EL3 payload related information (BL31 is EL3 payload)*/
- {
- .image_id = BL31_IMAGE_ID,
+ {
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = EL3_PAYLOAD_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = EL3_PAYLOAD_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t,
- IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
#else /* EL3_PAYLOAD_BASE */
/* Fill BL31 related information */
- {
- .image_id = BL31_IMAGE_ID,
+ {
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = BL31_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
#if DEBUG
- .ep_info.args.arg3 = ARM_BL31_PLAT_PARAM_VAL,
+ .ep_info.args.arg3 = ARM_BL31_PLAT_PARAM_VAL,
#endif
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
- .image_info.image_base = BL31_BASE,
- .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
# if defined(BL32_BASE)
- .next_handoff_image_id = BL32_IMAGE_ID,
+ .next_handoff_image_id = BL32_IMAGE_ID,
# elif ENABLE_RME
- .next_handoff_image_id = RMM_IMAGE_ID,
+ .next_handoff_image_id = RMM_IMAGE_ID,
# else
- .next_handoff_image_id = BL33_IMAGE_ID,
+ .next_handoff_image_id = BL33_IMAGE_ID,
# endif
- },
+ },
/* Fill HW_CONFIG related information */
- {
- .image_id = HW_CONFIG_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, NON_SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ {
+ .image_id = HW_CONFIG_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t,
+ NON_SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
/* Fill SOC_FW_CONFIG related information */
- {
- .image_id = SOC_FW_CONFIG_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ {
+ .image_id = SOC_FW_CONFIG_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
# if ENABLE_RME
/* Fill RMM related information */
- {
- .image_id = RMM_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, EP_REALM | EXECUTABLE),
- .ep_info.pc = RMM_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = RMM_BASE,
- .image_info.image_max_size = RMM_LIMIT - RMM_BASE,
- .next_handoff_image_id = BL33_IMAGE_ID,
- },
+ {
+ .image_id = RMM_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, EP_REALM | EXECUTABLE),
+ .ep_info.pc = RMM_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = RMM_BASE,
+ .image_info.image_max_size = RMM_LIMIT - RMM_BASE,
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
# endif
# ifdef BL32_BASE
/* Fill BL32 related information */
- {
- .image_id = BL32_IMAGE_ID,
+ {
+ .image_id = BL32_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
- .ep_info.pc = BL32_BASE,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
+ .ep_info.pc = BL32_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
# if ENABLE_RME
- .next_handoff_image_id = RMM_IMAGE_ID,
+ .next_handoff_image_id = RMM_IMAGE_ID,
# else
- .next_handoff_image_id = BL33_IMAGE_ID,
+ .next_handoff_image_id = BL33_IMAGE_ID,
# endif
- },
+ },
/*
* Fill BL32 external 1 related information.
- * A typical use for extra1 image is with OP-TEE where it is the pager image.
+ * A typical use for extra1 image is with OP-TEE where it is the pager
+ * image.
*/
- {
- .image_id = BL32_EXTRA1_IMAGE_ID,
+ {
+ .image_id = BL32_EXTRA1_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
/*
* Fill BL32 external 2 related information.
- * A typical use for extra2 image is with OP-TEE where it is the paged image.
+ * A typical use for extra2 image is with OP-TEE where it is the paged
+ * image.
*/
- {
- .image_id = BL32_EXTRA2_IMAGE_ID,
+ {
+ .image_id = BL32_EXTRA2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
#ifdef SPD_opteed
- .image_info.image_base = ARM_OPTEE_PAGEABLE_LOAD_BASE,
- .image_info.image_max_size = ARM_OPTEE_PAGEABLE_LOAD_SIZE,
+ .image_info.image_base = ARM_OPTEE_PAGEABLE_LOAD_BASE,
+ .image_info.image_max_size = ARM_OPTEE_PAGEABLE_LOAD_SIZE,
#endif
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
/* Fill TOS_FW_CONFIG related information */
- {
- .image_id = TOS_FW_CONFIG_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ {
+ .image_id = TOS_FW_CONFIG_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
# endif /* BL32_BASE */
/* Fill BL33 related information */
- {
- .image_id = BL33_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+ {
+ .image_id = BL33_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
# ifdef PRELOADED_BL33_BASE
- .ep_info.pc = PRELOADED_BL33_BASE,
+ .ep_info.pc = PRELOADED_BL33_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
# else
- .ep_info.pc = PLAT_ARM_NS_IMAGE_BASE,
+ .ep_info.pc = PLAT_ARM_NS_IMAGE_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = PLAT_ARM_NS_IMAGE_BASE,
- .image_info.image_max_size = ARM_DRAM1_BASE + ARM_DRAM1_SIZE
- - PLAT_ARM_NS_IMAGE_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = PLAT_ARM_NS_IMAGE_BASE,
+ .image_info.image_max_size = ARM_DRAM1_BASE + ARM_DRAM1_SIZE
+ - PLAT_ARM_NS_IMAGE_BASE,
# endif /* PRELOADED_BL33_BASE */
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
/* Fill NT_FW_CONFIG related information */
- {
- .image_id = NT_FW_CONFIG_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, NON_SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
- }
+ {
+ .image_id = NT_FW_CONFIG_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t,
+ NON_SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
#endif /* EL3_PAYLOAD_BASE */
};
diff --git a/plat/arm/common/aarch64/execution_state_switch.c b/plat/arm/common/aarch64/execution_state_switch.c
index bed929a..2353e6a 100644
--- a/plat/arm/common/aarch64/execution_state_switch.c
+++ b/plat/arm/common/aarch64/execution_state_switch.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -162,7 +162,7 @@
* calling EL.
*/
cm_init_my_context(&ep);
- cm_prepare_el3_exit(NON_SECURE);
+ cm_prepare_el3_exit_ns();
/*
* State switch success. The caller of SMC wouldn't see the SMC
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 73338cb..7a9e04d 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -166,7 +166,7 @@
/* Set global DTB info for fixed fw_config information */
fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
- set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID);
+ set_config_info(ARM_FW_CONFIG_BASE, ~0UL, fw_config_max_size, FW_CONFIG_ID);
/* Fill the device tree information struct with the info from the config dtb */
err = fconf_load_config(FW_CONFIG_ID);
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index a6f7df5..cf403b1 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -164,6 +164,14 @@
bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+#if ENABLE_RME
+ /*
+ * Populate entry point information for RMM.
+ * Only PC needs to be set as other fields are determined by RMMD.
+ */
+ rmm_image_ep_info.pc = RMM_BASE;
+#endif /* ENABLE_RME */
+
#else /* RESET_TO_BL31 */
/*
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 6d7aa2d..bd59ec0 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -73,6 +73,14 @@
$(eval $(call assert_boolean,ARM_BL31_IN_DRAM))
$(eval $(call add_define,ARM_BL31_IN_DRAM))
+# As per CCA security model, all root firmware must execute from on-chip secure
+# memory. This means we must not run BL31 from TZC-protected DRAM.
+ifeq (${ARM_BL31_IN_DRAM},1)
+ ifeq (${ENABLE_RME},1)
+ $(error "BL31 must not run from DRAM on RME-systems. Please set ARM_BL31_IN_DRAM to 0")
+ endif
+endif
+
# Process ARM_PLAT_MT flag
ARM_PLAT_MT := 0
$(eval $(call assert_boolean,ARM_PLAT_MT))
@@ -373,6 +381,8 @@
endif
else ifeq (${COT},dualroot)
AUTH_SOURCES += drivers/auth/dualroot/cot.c
+ else ifeq (${COT},cca)
+ AUTH_SOURCES += drivers/auth/cca/cot.c
else
$(error Unknown chain of trust ${COT})
endif
@@ -401,6 +411,10 @@
$(info Including ${MEASURED_BOOT_MK})
include ${MEASURED_BOOT_MK}
+ ifneq (${MBOOT_EL_HASH_ALG}, sha256)
+ $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
+ endif
+
BL1_SOURCES += ${EVENT_LOG_SOURCES}
BL2_SOURCES += ${EVENT_LOG_SOURCES}
endif
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 7abd1cd..a62693c 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -14,7 +14,7 @@
#include <common/desc_image_load.h>
#include <common/tbbr/tbbr_img_def.h>
#if CRYPTO_SUPPORT
-#include <drivers/auth/mbedtls/mbedtls_config.h>
+#include MBEDTLS_CONFIG_FILE
#endif /* CRYPTO_SUPPORT */
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
@@ -131,6 +131,7 @@
bl_mem_params_node_t *cfg_mem_params = NULL;
uintptr_t image_base;
uint32_t image_size;
+ unsigned int error_config_id = MAX_IMAGE_IDS;
const unsigned int config_ids[] = {
HW_CONFIG_ID,
SOC_FW_CONFIG_ID,
@@ -142,17 +143,17 @@
/* Iterate through all the fw config IDs */
for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
- /* Get the config load address and size from TB_FW_CONFIG */
+ /* Get the config load address and size */
cfg_mem_params = get_bl_mem_params_node(config_ids[i]);
if (cfg_mem_params == NULL) {
- VERBOSE("%sHW_CONFIG in bl_mem_params_node\n",
- "Couldn't find ");
+ VERBOSE("%sconfig_id = %d in bl_mem_params_node\n",
+ "Couldn't find ", config_ids[i]);
continue;
}
dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]);
if (dtb_info == NULL) {
- VERBOSE("%sconfig_id %d load info in TB_FW_CONFIG\n",
+ VERBOSE("%sconfig_id %d load info in FW_CONFIG\n",
"Couldn't find ", config_ids[i]);
continue;
}
@@ -168,17 +169,32 @@
if (config_ids[i] != HW_CONFIG_ID) {
if (check_uptr_overflow(image_base, image_size)) {
+ VERBOSE("%s=%d as its %s is overflowing uptr\n",
+ "skip loading of firmware config",
+ config_ids[i],
+ "load-address");
+ error_config_id = config_ids[i];
continue;
}
#ifdef BL31_BASE
/* Ensure the configs don't overlap with BL31 */
if ((image_base >= BL31_BASE) &&
(image_base <= BL31_LIMIT)) {
+ VERBOSE("%s=%d as its %s is overlapping BL31\n",
+ "skip loading of firmware config",
+ config_ids[i],
+ "load-address");
+ error_config_id = config_ids[i];
continue;
}
#endif
/* Ensure the configs are loaded in a valid address */
if (image_base < ARM_BL_RAM_BASE) {
+ VERBOSE("%s=%d as its %s is invalid\n",
+ "skip loading of firmware config",
+ config_ids[i],
+ "load-address");
+ error_config_id = config_ids[i];
continue;
}
#ifdef BL32_BASE
@@ -188,6 +204,11 @@
*/
if ((image_base >= BL32_BASE) &&
(image_base <= BL32_LIMIT)) {
+ VERBOSE("%s=%d as its %s is overlapping BL32\n",
+ "skip loading of firmware config",
+ config_ids[i],
+ "load-address");
+ error_config_id = config_ids[i];
continue;
}
#endif
@@ -202,4 +223,9 @@
*/
cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
}
+
+ if (error_config_id != MAX_IMAGE_IDS) {
+ ERROR("Invalid config file %u\n", error_config_id);
+ panic();
+ }
}
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index aea2f38..6c32331 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -72,6 +72,9 @@
#if TRUSTED_BOARD_BOOT
[TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT},
#if !ARM_IO_IN_DTB
+ [CCA_CONTENT_CERT_ID] = {UUID_CCA_CONTENT_CERT},
+ [CORE_SWD_KEY_CERT_ID] = {UUID_CORE_SWD_KEY_CERT},
+ [PLAT_KEY_CERT_ID] = {UUID_PLAT_KEY_CERT},
[TRUSTED_KEY_CERT_ID] = {UUID_TRUSTED_KEY_CERT},
[SCP_FW_KEY_CERT_ID] = {UUID_SCP_FW_KEY_CERT},
[SOC_FW_KEY_CERT_ID] = {UUID_SOC_FW_KEY_CERT},
@@ -196,6 +199,21 @@
open_fip
},
#if !ARM_IO_IN_DTB
+ [CCA_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[CCA_CONTENT_CERT_ID],
+ open_fip
+ },
+ [CORE_SWD_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[CORE_SWD_KEY_CERT_ID],
+ open_fip
+ },
+ [PLAT_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&arm_uuid_spec[PLAT_KEY_CERT_ID],
+ open_fip
+ },
[TRUSTED_KEY_CERT_ID] = {
&fip_dev_handle,
(uintptr_t)&arm_uuid_spec[TRUSTED_KEY_CERT_ID],
@@ -260,7 +278,7 @@
#ifdef IMAGE_BL2
#if TRUSTED_BOARD_BOOT
-#define FCONF_ARM_IO_UUID_NUMBER U(21)
+#define FCONF_ARM_IO_UUID_NUMBER U(24)
#else
#define FCONF_ARM_IO_UUID_NUMBER U(10)
#endif
@@ -286,6 +304,9 @@
{TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"},
{NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"},
#if TRUSTED_BOARD_BOOT
+ {CCA_CONTENT_CERT_ID, "cca_cert_uuid"},
+ {CORE_SWD_KEY_CERT_ID, "core_swd_cert_uuid"},
+ {PLAT_KEY_CERT_ID, "plat_cert_uuid"},
{TRUSTED_KEY_CERT_ID, "t_key_cert_uuid"},
{SCP_FW_KEY_CERT_ID, "scp_fw_key_uuid"},
{SOC_FW_KEY_CERT_ID, "soc_fw_key_uuid"},
diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c
index 95e0873..18c83c7 100644
--- a/plat/arm/common/fconf/arm_fconf_sp.c
+++ b/plat/arm/common/fconf/arm_fconf_sp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,13 +30,16 @@
union uuid_helper_t uuid_helper;
unsigned int index = 0;
uint32_t val32;
- bool is_plat_owned = false;
const unsigned int sip_start = SP_PKG1_ID;
unsigned int sip_index = sip_start;
+#if defined(ARM_COT_dualroot)
const unsigned int sip_end = sip_start + MAX_SP_IDS / 2;
+ /* Allocating index range for platform SPs */
const unsigned int plat_start = SP_PKG5_ID;
unsigned int plat_index = plat_start;
const unsigned int plat_end = plat_start + MAX_SP_IDS / 2;
+ bool is_plat_owned = false;
+#endif /* ARM_COT_dualroot */
/* As libfdt use void *, we can't avoid this cast */
const void *dtb = (void *)config;
@@ -51,12 +54,18 @@
}
fdt_for_each_subnode(sp_node, dtb, node) {
- if ((index == MAX_SP_IDS) || (sip_index == sip_end)
- || (plat_index == plat_end)) {
+ if (index == MAX_SP_IDS) {
ERROR("FCONF: Reached max number of SPs\n");
return -1;
}
+#if defined(ARM_COT_dualroot)
+ if ((sip_index == sip_end) || (plat_index == plat_end)) {
+ ERROR("FCONF: Reached max number of plat/SiP SPs\n");
+ return -1;
+ }
+#endif /* ARM_COT_dualroot */
+
/* Read UUID */
err = fdtw_read_uuid(dtb, sp_node, "uuid", 16,
(uint8_t *)&uuid_helper);
@@ -96,7 +105,7 @@
/* Owner is an optional field, no need to catch error */
fdtw_read_string(dtb, sp_node, "owner",
arm_sp.owner[index], ARM_SP_OWNER_NAME_LEN);
-#endif
+
/* If owner is empty mark it as SiP owned */
if ((strncmp(arm_sp.owner[index], "SiP",
ARM_SP_OWNER_NAME_LEN) == 0) ||
@@ -121,7 +130,9 @@
policies[plat_index].dev_handle = &fip_dev_handle;
policies[plat_index].check = open_fip;
plat_index++;
- } else {
+ } else
+#endif /* ARM_COT_dualroot */
+ {
sp_mem_params_descs[index].image_id = sip_index;
policies[sip_index].image_spec =
(uintptr_t)&arm_sp.uuids[index];
diff --git a/plat/arm/common/trp/arm_trp.mk b/plat/arm/common/trp/arm_trp.mk
index 997111f..204c14a 100644
--- a/plat/arm/common/trp/arm_trp.mk
+++ b/plat/arm/common/trp/arm_trp.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,3 +8,5 @@
RMM_SOURCES += plat/arm/common/trp/arm_trp_setup.c \
plat/arm/common/arm_topology.c \
plat/common/aarch64/platform_mp_stack.S
+
+INCLUDES += -Iinclude/services/trp
diff --git a/plat/arm/common/trp/arm_trp_setup.c b/plat/arm/common/trp/arm_trp_setup.c
index 8e48293..59b4c06 100644
--- a/plat/arm/common/trp/arm_trp_setup.c
+++ b/plat/arm/common/trp/arm_trp_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,33 +8,65 @@
#include <common/debug.h>
#include <drivers/arm/pl011.h>
#include <drivers/console.h>
+#include <services/rmm_core_manifest.h>
+#include <services/rmmd_svc.h>
+#include <services/trp/platform_trp.h>
+#include <trp_helpers.h>
+
#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>
/*******************************************************************************
+ * Received from boot manifest and populated here
+ ******************************************************************************/
+extern uint32_t trp_boot_manifest_version;
+
+/*******************************************************************************
* Initialize the UART
******************************************************************************/
static console_t arm_trp_runtime_console;
+static int arm_trp_process_manifest(rmm_manifest_t *manifest)
+{
+ /* Verify the Boot Manifest Version. Only the Major is considered */
+ if (RMMD_MANIFEST_VERSION_MAJOR !=
+ RMMD_GET_MANIFEST_VERSION_MAJOR(manifest->version)) {
+ return E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED;
+ }
+
-void arm_trp_early_platform_setup(void)
+ trp_boot_manifest_version = manifest->version;
+ flush_dcache_range((uintptr_t)manifest, sizeof(rmm_manifest_t));
+
+ return 0;
+}
+
+void arm_trp_early_platform_setup(rmm_manifest_t *manifest)
{
+ int rc;
+
+ rc = arm_trp_process_manifest(manifest);
+ if (rc != 0) {
+ trp_boot_abort(rc);
+ }
+
/*
* Initialize a different console than already in use to display
* messages from trp
*/
- int rc = console_pl011_register(PLAT_ARM_TRP_UART_BASE,
- PLAT_ARM_TRP_UART_CLK_IN_HZ,
- ARM_CONSOLE_BAUDRATE,
- &arm_trp_runtime_console);
+ rc = console_pl011_register(PLAT_ARM_TRP_UART_BASE,
+ PLAT_ARM_TRP_UART_CLK_IN_HZ,
+ ARM_CONSOLE_BAUDRATE,
+ &arm_trp_runtime_console);
if (rc == 0) {
panic();
}
console_set_scope(&arm_trp_runtime_console,
CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+
}
-void trp_early_platform_setup(void)
+void trp_early_platform_setup(rmm_manifest_t *manifest)
{
- arm_trp_early_platform_setup();
+ arm_trp_early_platform_setup(manifest);
}
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 c9c8c04..22870c4 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,8 +21,9 @@
#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */
-/* Remote chip address offset (4TB per chip) */
-#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) ((ULL(1) << 42) * (n))
+/* Remote chip address offset */
+#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) \
+ ((ULL(1) << CSS_SGI_ADDR_BITS_PER_CHIP) * (n))
/*
* PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
@@ -35,8 +36,8 @@
# if SPM_MM
# define PLAT_ARM_MMAP_ENTRIES (9 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
# define MAX_XLAT_TABLES (7 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-# define PLAT_SP_IMAGE_MMAP_REGIONS 9
-# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 11
+# define PLAT_SP_IMAGE_MMAP_REGIONS 10
+# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 12
# else
# define PLAT_ARM_MMAP_ENTRIES (5 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
# define MAX_XLAT_TABLES (6 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
@@ -67,7 +68,7 @@
* PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
* plus a little space for growth.
*/
-#define PLAT_ARM_MAX_BL1_RW_SIZE 0xC000
+#define PLAT_ARM_MAX_BL1_RW_SIZE (64 * 1024) /* 64 KB */
/*
* PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
@@ -101,7 +102,7 @@
* calculated using the current BL31 PROGBITS debug size plus the sizes of
* BL2 and BL1-RW
*/
-#define PLAT_ARM_MAX_BL31_SIZE 0x3B000
+#define PLAT_ARM_MAX_BL31_SIZE 0x48000
/*
* Size of cacheable stacks
@@ -130,6 +131,21 @@
# define PLATFORM_STACK_SIZE 0x440
#endif
+/* PL011 UART related constants */
+#define SOC_CSS_SEC_UART_BASE UL(0x2A410000)
+#define SOC_CSS_NSEC_UART_BASE UL(0x2A400000)
+#define SOC_CSS_UART_SIZE UL(0x10000)
+#define SOC_CSS_UART_CLK_IN_HZ UL(7372800)
+
+/* UART related constants */
+#define PLAT_ARM_BOOT_UART_BASE SOC_CSS_SEC_UART_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ SOC_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE SOC_CSS_SEC_UART_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ SOC_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE SOC_CSS_SEC_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ SOC_CSS_UART_CLK_IN_HZ
#define PLAT_ARM_NSTIMER_FRAME_ID 0
@@ -258,4 +274,21 @@
CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_END, \
ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
+#if SPM_MM
+
+/*
+ * Stand-alone MM logs would be routed via secure UART. Define page table
+ * entry for secure UART which would be common to all platforms.
+ */
+#define SOC_PLATFORM_SECURE_UART MAP_REGION_FLAT( \
+ SOC_CSS_SEC_UART_BASE, \
+ SOC_CSS_UART_SIZE, \
+ MT_DEVICE | MT_RW | \
+ MT_SECURE | MT_USER)
+
+#endif
+
+/* SDS ID for unusable CPU MPID list structure */
+#define SDS_ISOLATED_CPU_LIST_ID U(128)
+
#endif /* SGI_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def.h b/plat/arm/css/sgi/include/sgi_soc_css_def.h
new file mode 100644
index 0000000..f78b45a
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_soc_css_def.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SGI_SOC_CSS_DEF_H
+#define SGI_SOC_CSS_DEF_H
+
+#include <lib/utils_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
+#include <plat/common/common_def.h>
+
+/*
+ * Definitions common to all ARM CSSv1-based development platforms
+ */
+
+/* Platform ID address */
+#define BOARD_CSS_PLAT_ID_REG_ADDR UL(0x7ffe00e0)
+
+/* Platform ID related accessors */
+#define BOARD_CSS_PLAT_ID_REG_ID_MASK 0x0f
+#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT 0x0
+#define BOARD_CSS_PLAT_TYPE_EMULATOR 0x02
+
+#ifndef __ASSEMBLER__
+
+#include <lib/mmio.h>
+
+#define BOARD_CSS_GET_PLAT_TYPE(addr) \
+ ((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK) \
+ >> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
+
+#endif /* __ASSEMBLER__ */
+
+#define MAX_IO_DEVICES 3
+#define MAX_IO_HANDLES 4
+
+/* Reserve the last block of flash for PSCI MEM PROTECT flag */
+#define PLAT_ARM_FLASH_IMAGE_BASE V2M_FLASH0_BASE
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#endif /* SGI_SOC_CSS_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
index 639b687..acf31eb 100644
--- a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
+++ b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -24,17 +24,10 @@
#define SOC_CSS_PCIE_CONTROL_BASE UL(0x0ef20000)
-/* PL011 UART related constants */
-#define SOC_CSS_UART1_BASE UL(0x0ef80000)
-#define SOC_CSS_UART0_BASE UL(0x0ef70000)
-
/* Memory controller */
#define SOC_MEMCNTRL_BASE UL(0x10000000)
#define SOC_MEMCNTRL_SIZE UL(0x10000000)
-#define SOC_CSS_UART0_CLK_IN_HZ UL(7372800)
-#define SOC_CSS_UART1_CLK_IN_HZ UL(7372800)
-
/* SoC NIC-400 Global Programmers View (GPV) */
#define SOC_CSS_NIC400_BASE UL(0x0ED00000)
@@ -206,17 +199,4 @@
#define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE
#define PLAT_ARM_NVM_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-/* 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
-
-#define PLAT_ARM_RUN_UART_BASE SOC_CSS_UART1_BASE
-#define PLAT_ARM_RUN_UART_CLK_IN_HZ SOC_CSS_UART1_CLK_IN_HZ
-
-#define PLAT_ARM_SP_MIN_RUN_UART_BASE SOC_CSS_UART1_BASE
-#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ SOC_CSS_UART1_CLK_IN_HZ
-
-#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE
-#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ
-
#endif /* SGI_SOC_CSS_DEF_V2_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def.h b/plat/arm/css/sgi/include/sgi_soc_platform_def.h
index 405d62f..3b8d9c6 100644
--- a/plat/arm/css/sgi/include/sgi_soc_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_soc_platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,10 +7,10 @@
#ifndef SGI_SOC_PLATFORM_DEF_H
#define SGI_SOC_PLATFORM_DEF_H
-#include <sgi_base_platform_def.h>
-#include <plat/arm/board/common/board_css_def.h>
#include <plat/arm/board/common/v2m_def.h>
#include <plat/arm/soc/common/soc_css_def.h>
+#include <sgi_base_platform_def.h>
+#include <sgi_soc_css_def.h>
/* Map the System registers to access from S-EL0 */
#define CSS_SYSTEMREG_DEVICE_BASE (0x1C010000)
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index f56fe35..4af579e 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -23,6 +23,8 @@
# Do not enable SVE
ENABLE_SVE_FOR_NS := 0
+CTX_INCLUDE_FPREGS := 1
+
INTERCONNECT_SOURCES := ${CSS_ENT_BASE}/sgi_interconnect.c
PLAT_INCLUDES += -I${CSS_ENT_BASE}/include
@@ -42,7 +44,8 @@
BL1_SOURCES += ${INTERCONNECT_SOURCES} \
drivers/arm/sbsa/sbsa.c
-BL2_SOURCES += ${CSS_ENT_BASE}/sgi_image_load.c
+BL2_SOURCES += ${CSS_ENT_BASE}/sgi_image_load.c \
+ drivers/arm/css/sds/sds.c
BL31_SOURCES += ${INTERCONNECT_SOURCES} \
${ENT_GIC_SOURCES} \
diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c
index 09f3b72..ac4bfd2 100644
--- a/plat/arm/css/sgi/sgi_image_load.c
+++ b/plat/arm/css/sgi/sgi_image_load.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,16 +9,68 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <common/desc_image_load.h>
+#include <drivers/arm/css/sds.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <sgi_base_platform_def.h>
#include <sgi_variant.h>
+/*
+ * Information about the isolated CPUs obtained from SDS.
+ */
+struct isolated_cpu_mpid_list {
+ uint64_t num_entries; /* Number of entries in the list */
+ uint64_t mpid_list[PLATFORM_CORE_COUNT]; /* List of isolated CPU MPIDs */
+};
+
+/* Function to read isolated CPU MPID list from SDS. */
+void plat_arm_sgi_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list)
+{
+ int ret;
+
+ ret = sds_init();
+ if (ret != SDS_OK) {
+ ERROR("SDS initialization failed, error: %d\n", ret);
+ panic();
+ }
+
+ ret = sds_struct_read(SDS_ISOLATED_CPU_LIST_ID, 0, &list->num_entries,
+ sizeof(list->num_entries), SDS_ACCESS_MODE_CACHED);
+ if (ret != SDS_OK) {
+ INFO("SDS CPU num elements read failed, error: %d\n", ret);
+ list->num_entries = 0;
+ return;
+ }
+
+ if (list->num_entries > PLATFORM_CORE_COUNT) {
+ ERROR("Isolated CPU list count %ld greater than max"
+ " number supported %d\n",
+ list->num_entries, PLATFORM_CORE_COUNT);
+ panic();
+ } else if (list->num_entries == 0) {
+ INFO("SDS isolated CPU list is empty\n");
+ return;
+ }
+
+ ret = sds_struct_read(SDS_ISOLATED_CPU_LIST_ID,
+ sizeof(list->num_entries),
+ &list->mpid_list,
+ sizeof(list->mpid_list[0]) * list->num_entries,
+ SDS_ACCESS_MODE_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("SDS CPU list read failed. error: %d\n", ret);
+ panic();
+ }
+}
+
/*******************************************************************************
* This function inserts Platform information via device tree nodes as,
* system-id {
* platform-id = <0>;
* config-id = <0>;
+ * isolated-cpu-list = <0>
* }
******************************************************************************/
static int plat_sgi_append_config_node(void)
@@ -27,6 +79,7 @@
void *fdt;
int nodeoffset, err;
unsigned int platid = 0, platcfg = 0;
+ struct isolated_cpu_mpid_list cpu_mpid_list = {0};
mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
if (mem_params == NULL) {
@@ -69,6 +122,18 @@
return -1;
}
+ plat_arm_sgi_get_isolated_cpu_list(&cpu_mpid_list);
+ if (cpu_mpid_list.num_entries > 0) {
+ err = fdt_setprop(fdt, nodeoffset, "isolated-cpu-list",
+ &cpu_mpid_list,
+ (sizeof(cpu_mpid_list.num_entries) *
+ (cpu_mpid_list.num_entries + 1)));
+ if (err < 0) {
+ ERROR("Failed to set isolated-cpu-list, error: %d\n",
+ err);
+ }
+ }
+
flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
return 0;
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 20c52e9..a0199c3 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -89,6 +89,7 @@
const mmap_region_t plat_arm_secure_partition_mmap[] = {
PLAT_ARM_SECURE_MAP_SYSTEMREG,
PLAT_ARM_SECURE_MAP_NOR2,
+ SOC_PLATFORM_SECURE_UART,
PLAT_ARM_SECURE_MAP_DEVICE,
ARM_SP_IMAGE_MMAP,
ARM_SP_IMAGE_NS_BUF_MMAP,
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
index 1a2a966..cef5345 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/css/sgi/sgi_plat_v2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -83,6 +83,7 @@
const mmap_region_t plat_arm_secure_partition_mmap[] = {
PLAT_ARM_SECURE_MAP_SYSTEMREG,
PLAT_ARM_SECURE_MAP_NOR2,
+ SOC_PLATFORM_SECURE_UART,
SOC_PLATFORM_PERIPH_MAP_DEVICE_USER,
ARM_SP_IMAGE_MMAP,
ARM_SP_IMAGE_NS_BUF_MMAP,
diff --git a/plat/arm/css/sgm/aarch64/css_sgm_helpers.S b/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
deleted file mode 100644
index 32ca1bb..0000000
--- a/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <platform_def.h>
-#include <cortex_a75.h>
-#include <cortex_a55.h>
-#include <cpu_macros.S>
-
- .globl plat_arm_calc_core_pos
- .globl plat_reset_handler
-
- /* ---------------------------------------------------------------------
- * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
- *
- * Function to calculate the core position on FVP.
- *
- * (ClusterId * MAX_CPUS_PER_CLUSTER * MAX_PE_PER_CPU) +
- * (CPUId * MAX_PE_PER_CPU) +
- * ThreadId
- *
- * which can be simplified as:
- *
- * ((ClusterId * MAX_CPUS_PER_CLUSTER + CPUId) * MAX_PE_PER_CPU)
- * + ThreadId
- * ---------------------------------------------------------------------
- */
-func plat_arm_calc_core_pos
- /*
- * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
- * look as if in a multi-threaded implementation.
- */
- tst x0, #MPIDR_MT_MASK
- lsr x3, x0, #MPIDR_AFFINITY_BITS
- csel x3, x3, x0, eq
-
- /* Extract individual affinity fields from MPIDR */
- ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
- ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
- ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
-
- /* Compute linear position */
- mov x4, #PLAT_MAX_CPUS_PER_CLUSTER
- madd x1, x2, x4, x1
- mov x5, #PLAT_MAX_PE_PER_CPU
- madd x0, x1, x5, x0
- ret
-endfunc plat_arm_calc_core_pos
-
- /* -----------------------------------------------------
- * void plat_reset_handler(void);
- *
- * Determine the CPU MIDR and disable power down bit for
- * that CPU.
- * -----------------------------------------------------
- */
-func plat_reset_handler
- jump_if_cpu_midr CORTEX_A75_MIDR, A75
- jump_if_cpu_midr CORTEX_A55_MIDR, A55
- ret
-
- /* -----------------------------------------------------
- * Disable CPU power down bit in power control register
- * -----------------------------------------------------
- */
-A75:
- mrs x0, CORTEX_A75_CPUPWRCTLR_EL1
- bic x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
- msr CORTEX_A75_CPUPWRCTLR_EL1, x0
- isb
- ret
-A55:
- mrs x0, CORTEX_A55_CPUPWRCTLR_EL1
- bic x0, x0, #CORTEX_A55_CORE_PWRDN_EN_MASK
- msr CORTEX_A55_CPUPWRCTLR_EL1, x0
- isb
- ret
-endfunc plat_reset_handler
diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
deleted file mode 100644
index 54b2423..0000000
--- a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
- /* Platform Config */
- tb_fw-config {
- compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x83000000>;
- hw_config_max_size = <0x01000000>;
- /*
- * The following two entries are placeholders for Mbed TLS
- * heap information. The default values don't matter since
- * they will be overwritten by BL1.
- * In case of having shared Mbed TLS heap between BL1 and BL2,
- * BL1 will populate these two properties with the respective
- * info about the shared heap. This info will be available for
- * BL2 in order to locate and re-use the heap.
- */
- mbedtls_heap_addr = <0x0 0x0>;
- mbedtls_heap_size = <0x0>;
- };
-};
diff --git a/plat/arm/css/sgm/include/plat_macros.S b/plat/arm/css/sgm/include/plat_macros.S
deleted file mode 100644
index 715ded2..0000000
--- a/plat/arm/css/sgm/include/plat_macros.S
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef PLAT_MACROS_S
-#define PLAT_MACROS_S
-
-#include <cci_macros.S>
-#include <css_macros.S>
-
-/* ---------------------------------------------
- * The below required platform porting macro
- * prints out relevant platform registers
- * whenever an unhandled exception is taken in
- * BL31.
- * ---------------------------------------------
- */
-.macro plat_crash_print_regs
-css_print_gic_regs
-print_cci_regs
-.endm
-
-#endif /* PLAT_MACROS_S */
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
deleted file mode 100644
index 2d8e677..0000000
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGM_BASE_PLATFORM_DEF_H
-#define SGM_BASE_PLATFORM_DEF_H
-
-#include <drivers/arm/tzc400.h>
-#include <drivers/arm/tzc_common.h>
-#include <plat/arm/board/common/board_css_def.h>
-#include <plat/arm/board/common/v2m_def.h>
-#include <plat/arm/common/arm_def.h>
-#include <plat/arm/css/common/css_def.h>
-#include <plat/arm/soc/common/soc_css_def.h>
-#include <plat/common/common_def.h>
-
-/* CPU topology */
-#define PLAT_ARM_CLUSTER_COUNT U(1)
-#define PLAT_ARM_CLUSTER_CORE_COUNT U(8)
-#define PLATFORM_CORE_COUNT PLAT_ARM_CLUSTER_CORE_COUNT
-
-#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
-#define PLAT_NUM_PWR_DOMAINS (ARM_SYSTEM_COUNT + \
- PLAT_ARM_CLUSTER_COUNT + \
- PLATFORM_CORE_COUNT)
-
-/*
- * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
- * terminology. On a GICv2 system or mode, the lists will be merged and treated
- * as Group 0 interrupts.
- */
-#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
- CSS_G1S_IRQ_PROPS(grp), \
- ARM_G1S_IRQ_PROPS(grp)
-
-#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE 0x30000000
-#define PLAT_ARM_GICR_BASE 0x300C0000
-#define PLAT_ARM_GICC_BASE 0x2c000000
-
-#define CSS_GIC_SIZE 0x00200000
-
-#define CSS_MAP_GIC_DEVICE MAP_REGION_FLAT( \
- PLAT_ARM_GICD_BASE, \
- CSS_GIC_SIZE, \
- MT_DEVICE | MT_RW | MT_SECURE)
-
-/* Platform ID address */
-#define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET)
-#ifndef __ASSEMBLER__
-/* SSC_VERSION related accessors */
-/* Returns the part number of the platform */
-#define GET_PLAT_PART_NUM \
- GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
-/* Returns the configuration number of the platform */
-#define GET_PLAT_CONFIG_NUM \
- GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
-#endif /* __ASSEMBLER__ */
-
-
-/*************************************************************************
- * Definitions common to all SGM CSS based platforms
- *************************************************************************/
-
-/* TZC-400 related constants */
-#define PLAT_ARM_TZC_BASE 0x2a500000
-#define TZC_NSAID_ALL_AP 0 /* Note: Same as default NSAID!! */
-#define TZC_NSAID_HDLCD0 2
-#define TZC_NSAID_HDLCD1 3
-#define TZC_NSAID_GPU 9
-#define TZC_NSAID_VIDEO 10
-#define TZC_NSAID_DISP0 11
-#define TZC_NSAID_DISP1 12
-
-
-/*************************************************************************
- * Required platform porting definitions common to all SGM CSS based
- * platforms
- *************************************************************************/
-
-#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */
-
-/* MHU related constants */
-#define PLAT_CSS_MHU_BASE 0x2b1f0000
-
-#define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000
-#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000
-
-#define PLAT_ARM_CCI_BASE 0x2a000000
-
-/* Cluster to CCI slave mapping */
-#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 6
-#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 5
-
-/* System timer related constants */
-#define PLAT_ARM_NSTIMER_FRAME_ID 0
-
-/* TZC related constants */
-#define PLAT_ARM_TZC_NS_DEV_ACCESS ( \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD1) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_GPU) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIDEO) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP0) | \
- TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP1))
-
-/* Display Processor register definitions to setup the NSAIDs */
-#define MALI_DP_BASE 0x2cc00000
-#define DP_NPROT_NSAID_OFFSET 0x1000c
-#define W_NPROT_NSAID_SHIFT 24
-#define LS_NPORT_NSAID_SHIFT 12
-
-/*
- * Base address of the first memory region used for communication between AP
- * and SCP. Used by the BootOverMHU and SCPI protocols.
- */
-#if !CSS_USE_SCMI_SDS_DRIVER
-/*
- * Note that this is located at the same address as SCP_BOOT_CFG_ADDR, which
- * means the SCP/AP configuration data gets overwritten when the AP initiates
- * communication with the SCP. The configuration data is expected to be a
- * 32-bit word on all CSS platforms. Part of this configuration is
- * which CPU is the primary, according to the shift and mask definitions below.
- */
-#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE (ARM_TRUSTED_SRAM_BASE + 0x80)
-#define PLAT_CSS_PRIMARY_CPU_SHIFT 8
-#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH 4
-#endif
-
-/*
- * SCP_BL2 uses up whatever remaining space is available as it is loaded before
- * anything else in this memory region and is handed over to the SCP before
- * BL31 is loaded over the top.
- */
-#define PLAT_CSS_MAX_SCP_BL2_SIZE \
- ((SCP_BL2_LIMIT - ARM_FW_CONFIG_LIMIT) & ~PAGE_SIZE_MASK)
-
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE
-
-/*
- * Most platform porting definitions provided by included headers
- */
-
-/*
- * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
- * plat_arm_mmap array defined for each BL stage.
- */
-#if defined(IMAGE_BL31)
-# define PLAT_ARM_MMAP_ENTRIES 8
-# define MAX_XLAT_TABLES 5
-#elif defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES 8
-# define MAX_XLAT_TABLES 5
-#elif !USE_ROMLIB
-# define PLAT_ARM_MMAP_ENTRIES 11
-# define MAX_XLAT_TABLES 5
-#else
-# define PLAT_ARM_MMAP_ENTRIES 12
-# define MAX_XLAT_TABLES 6
-#endif
-
-/*
- * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
- * plus a little space for growth.
- */
-#define PLAT_ARM_MAX_BL1_RW_SIZE 0xB000
-
-/*
- * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
- */
-
-#if USE_ROMLIB
-#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0x1000
-#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0xe000
-#else
-#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0
-#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0
-#endif
-
-/*
- * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
- * little space for growth.
- */
-#if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE 0x1D000
-#else
-# define PLAT_ARM_MAX_BL2_SIZE 0x12000
-#endif
-
-/*
- * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
- * calculated using the current BL31 PROGBITS debug size plus the sizes of
- * BL2 and BL1-RW
- */
-#define PLAT_ARM_MAX_BL31_SIZE 0x3B000
-
-/*
- * Size of cacheable stacks
- */
-#if defined(IMAGE_BL1)
-# if TRUSTED_BOARD_BOOT
-# define PLATFORM_STACK_SIZE 0x1000
-# else
-# define PLATFORM_STACK_SIZE 0x440
-# endif
-#elif defined(IMAGE_BL2)
-# if TRUSTED_BOARD_BOOT
-# define PLATFORM_STACK_SIZE 0x1000
-# else
-# define PLATFORM_STACK_SIZE 0x400
-# endif
-#elif defined(IMAGE_BL2U)
-# define PLATFORM_STACK_SIZE 0x400
-#elif defined(IMAGE_BL31)
-# define PLATFORM_STACK_SIZE 0x400
-#elif defined(IMAGE_BL32)
-# define PLATFORM_STACK_SIZE 0x440
-#endif
-
-/*******************************************************************************
- * Memprotect definitions
- ******************************************************************************/
-/* PSCI memory protect definitions:
- * This variable is stored in a non-secure flash because some ARM reference
- * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
- * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
- */
-#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \
- V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-/* System power domain level */
-#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
-
-/* Number of SCMI channels on the platform */
-#define PLAT_ARM_SCMI_CHANNEL_COUNT U(1)
-
-#endif /* SGM_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgm/include/sgm_plat_config.h b/plat/arm/css/sgm/include/sgm_plat_config.h
deleted file mode 100644
index 29b98d4..0000000
--- a/plat/arm/css/sgm/include/sgm_plat_config.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGM_PLAT_CONFIG_H
-#define SGM_PLAT_CONFIG_H
-
-#include <drivers/arm/ccn.h>
-#include <drivers/arm/gicv3.h>
-
-/* The type of interconnect */
-typedef enum {
- ARM_CCI = 0,
- ARM_CCN,
- ARM_CMN
-} css_inteconn_type_t;
-
-typedef ccn_desc_t inteconn_desc_t;
-
-/* Interconnect configurations */
-typedef struct css_inteconn_config {
- css_inteconn_type_t ip_type;
- const inteconn_desc_t *plat_inteconn_desc;
-} css_inteconn_config_t;
-
-/* Topology configurations */
-typedef struct css_topology {
- const unsigned char *power_tree;
- unsigned int plat_cluster_core_count;
-} css_topology_t;
-
-typedef struct css_plat_config {
- const gicv3_driver_data_t *gic_data;
- const css_inteconn_config_t *inteconn;
- const css_topology_t *topology;
-} css_plat_config_t;
-
-void plat_config_init(void);
-css_plat_config_t *get_plat_config(void);
-
-#endif /* SGM_PLAT_CONFIG_H */
diff --git a/plat/arm/css/sgm/include/sgm_variant.h b/plat/arm/css/sgm/include/sgm_variant.h
deleted file mode 100644
index 859ddb5..0000000
--- a/plat/arm/css/sgm/include/sgm_variant.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGM_VARIANT_H
-#define SGM_VARIANT_H
-
-/* SSC_VERSION values for sgm */
-#define SGM775_SSC_VER_PART_NUM 0x0790
-
-/* DMC configuration for sgm */
-#define SGM_DMC_SIZE 0x40000
-#define SGM775_DMC_COUNT 4
-
-#endif /* SGM_VARIANT_H */
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
deleted file mode 100644
index 5b954f8..0000000
--- a/plat/arm/css/sgm/sgm-common.mk
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-CSS_USE_SCMI_SDS_DRIVER := 1
-
-CSS_SGM_BASE := plat/arm/css/sgm
-
-PLAT_INCLUDES := -I${CSS_SGM_BASE}/include
-
-PLAT_BL_COMMON_SOURCES := ${CSS_SGM_BASE}/sgm_mmap_config.c \
- ${CSS_SGM_BASE}/aarch64/css_sgm_helpers.S
-
-SECURITY_SOURCES := drivers/arm/tzc/tzc_dmc500.c \
- plat/arm/common/arm_tzc_dmc500.c \
- ${CSS_SGM_BASE}/sgm_security.c
-
-SGM_CPU_SOURCES := lib/cpus/aarch64/cortex_a55.S \
- lib/cpus/aarch64/cortex_a75.S
-
-INTERCONNECT_SOURCES := ${CSS_SGM_BASE}/sgm_interconnect.c
-
-# GIC-600 configuration
-GICV3_SUPPORT_GIC600 := 1
-
-# Include GICv3 driver files
-include drivers/arm/gic/v3/gicv3.mk
-
-SGM_GIC_SOURCES := ${GICV3_SOURCES} \
- plat/common/plat_gicv3.c \
- plat/arm/common/arm_gicv3.c
-
-BL1_SOURCES += $(SGM_CPU_SOURCES) \
- ${INTERCONNECT_SOURCES} \
- ${CSS_SGM_BASE}/sgm_bl1_setup.c \
- ${CSS_SGM_BASE}/sgm_plat_config.c \
- drivers/arm/sp805/sp805.c
-
-BL2_SOURCES += ${SECURITY_SOURCES} \
- ${CSS_SGM_BASE}/sgm_plat_config.c
-
-BL2U_SOURCES += ${SECURITY_SOURCES}
-
-BL31_SOURCES += $(SGM_CPU_SOURCES) \
- ${INTERCONNECT_SOURCES} \
- ${SECURITY_SOURCES} \
- ${SGM_GIC_SOURCES} \
- ${CSS_SGM_BASE}/sgm_topology.c \
- ${CSS_SGM_BASE}/sgm_bl31_setup.c \
- ${CSS_SGM_BASE}/sgm_plat_config.c
-
-ifneq (${RESET_TO_BL31},0)
- $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
- Please set RESET_TO_BL31 to 0.")
-endif
-
-# sgm uses CCI-500 as Cache Coherent Interconnect
-ARM_CCI_PRODUCT_ID := 500
-
-# System coherency is managed in hardware
-HW_ASSISTED_COHERENCY := 1
-
-# When building for systems with hardware-assisted coherency, there's no need to
-# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
-USE_COHERENT_MEM := 0
-
-override ARM_PLAT_MT := 1
-
-$(eval $(call add_define,SGM_PLAT))
-
-include plat/arm/common/arm_common.mk
-include plat/arm/board/common/board_common.mk
-include plat/arm/css/common/css_common.mk
-include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c
deleted file mode 100644
index 5fd9655..0000000
--- a/plat/arm/css/sgm/sgm_bl1_setup.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/arm/soc/common/soc_css.h>
-#include <plat/arm/common/arm_def.h>
-#include <drivers/arm/sp805.h>
-#include <sgm_plat_config.h>
-
-void bl1_early_platform_setup(void)
-{
-
- /* Initialize the console before anything else */
- arm_bl1_early_platform_setup();
-
- /* Initialize the platform configuration structure */
- plat_config_init();
-
-#if !HW_ASSISTED_COHERENCY
- /*
- * Initialize Interconnect for this cluster during cold boot.
- * No need for locks as no other CPU is active.
- */
- plat_arm_interconnect_init();
- /*
- * Enable Interconnect coherency for the primary CPU's cluster.
- */
- plat_arm_interconnect_enter_coherency();
-#endif
-}
-
-void plat_arm_secure_wdt_start(void)
-{
- sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
-}
-
-void plat_arm_secure_wdt_stop(void)
-{
- sp805_stop(ARM_SP805_TWDG_BASE);
-}
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
deleted file mode 100644
index 907e9fd..0000000
--- a/plat/arm/css/sgm/sgm_bl31_setup.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <drivers/arm/css/css_mhu_doorbell.h>
-#include <drivers/arm/css/scmi.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-
-static scmi_channel_plat_info_t sgm775_scmi_plat_info = {
- .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
- .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
- .db_preserve_mask = 0xfffffffe,
- .db_modify_mask = 0x1,
- .ring_doorbell = &mhu_ring_doorbell,
-};
-
-scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
-{
- return &sgm775_scmi_plat_info;
-}
-
-void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
- u_register_t arg2, u_register_t arg3)
-{
- uint32_t plat_version;
- bl_params_node_t *bl_params;
-
- bl_params = ((bl_params_t *)arg0)->head;
-
- /* Initialize the platform configuration structure */
- plat_config_init();
-
- while (bl_params) {
- if (bl_params->image_id == BL33_IMAGE_ID) {
- plat_version = mmio_read_32(SSC_VERSION);
- bl_params->ep_info->args.arg2 = plat_version;
- break;
- }
-
- bl_params = bl_params->next_params_info;
- }
-
- arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
-}
-
-const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
-{
- return css_scmi_override_pm_ops(ops);
-}
diff --git a/plat/arm/css/sgm/sgm_interconnect.c b/plat/arm/css/sgm/sgm_interconnect.c
deleted file mode 100644
index 5b45341..0000000
--- a/plat/arm/css/sgm/sgm_interconnect.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <cdefs.h>
-
-/*
- * As the SGM platform supports FCM (with automatic interconnect
- * enter/exit), we should not do anything in these interface functions.
- * They are used to override the weak functions in cci drivers.
- */
-
-/******************************************************************************
- * Helper function to initialize ARM interconnect driver.
- *****************************************************************************/
-void __init plat_arm_interconnect_init(void)
-{
-}
-
-/******************************************************************************
- * Helper function to place current master into coherency
- *****************************************************************************/
-void plat_arm_interconnect_enter_coherency(void)
-{
-}
-
-/******************************************************************************
- * Helper function to remove current master from coherency
- *****************************************************************************/
-void plat_arm_interconnect_exit_coherency(void)
-{
-}
diff --git a/plat/arm/css/sgm/sgm_mmap_config.c b/plat/arm/css/sgm/sgm_mmap_config.c
deleted file mode 100644
index e5b4b03..0000000
--- a/plat/arm/css/sgm/sgm_mmap_config.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_variant.h>
-
-/*
- * Table of regions for different BL stages to map using the MMU.
- * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
- * arm_configure_mmu_elx() will give the available subset of that.
- */
-#if IMAGE_BL1
-const mmap_region_t plat_arm_mmap[] = {
- ARM_MAP_SHARED_RAM,
- V2M_MAP_FLASH0_RO,
- V2M_MAP_IOFPGA,
- CSS_MAP_DEVICE,
- CSS_MAP_GIC_DEVICE,
- SOC_CSS_MAP_DEVICE,
-#if TRUSTED_BOARD_BOOT
- ARM_MAP_NS_DRAM1,
-#endif
- {0}
-};
-#endif
-#if IMAGE_BL2
-const mmap_region_t plat_arm_mmap[] = {
- ARM_MAP_SHARED_RAM,
- V2M_MAP_FLASH0_RO,
- V2M_MAP_IOFPGA,
- CSS_MAP_DEVICE,
- CSS_MAP_GIC_DEVICE,
- SOC_CSS_MAP_DEVICE,
- ARM_MAP_NS_DRAM1,
-#ifdef SPD_tspd
- ARM_MAP_TSP_SEC_MEM,
-#endif
-#ifdef SPD_opteed
- ARM_OPTEE_PAGEABLE_LOAD_MEM,
-#endif
-#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
- ARM_MAP_BL1_RW,
-#endif
- {0}
-};
-#endif
-#if IMAGE_BL2U
-const mmap_region_t plat_arm_mmap[] = {
- ARM_MAP_SHARED_RAM,
- CSS_MAP_DEVICE,
- CSS_MAP_GIC_DEVICE,
- SOC_CSS_MAP_DEVICE,
- {0}
-};
-#endif
-#if IMAGE_BL31
-const mmap_region_t plat_arm_mmap[] = {
- ARM_MAP_SHARED_RAM,
- V2M_MAP_IOFPGA,
- CSS_MAP_DEVICE,
- CSS_MAP_GIC_DEVICE,
- SOC_CSS_MAP_DEVICE,
- {0}
-};
-#endif
-#if IMAGE_BL32
-const mmap_region_t plat_arm_mmap[] = {
- V2M_MAP_IOFPGA,
- CSS_MAP_DEVICE,
- CSS_MAP_GIC_DEVICE,
- SOC_CSS_MAP_DEVICE,
- {0}
-};
-#endif
-
-ARM_CASSERT_MMAP
-
-const mmap_region_t *plat_arm_get_mmap(void)
-{
- return plat_arm_mmap;
-}
diff --git a/plat/arm/css/sgm/sgm_plat_config.c b/plat/arm/css/sgm/sgm_plat_config.c
deleted file mode 100644
index eed3631..0000000
--- a/plat/arm/css/sgm/sgm_plat_config.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <plat/common/platform.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-#include <sgm_variant.h>
-
-static css_plat_config_t *css_plat_info;
-
-/* Interconnect */
-const css_inteconn_config_t sgm_inteconn = {
- .ip_type = ARM_CCI,
- .plat_inteconn_desc = NULL
-};
-
-/* Special definition for SGM775 */
-/* Topology configuration for SGM775 */
-const unsigned char sgm775_power_domain_tree_desc[] = {
- /* No of root nodes */
- ARM_SYSTEM_COUNT,
- /* No of children for the root node */
- PLAT_ARM_CLUSTER_COUNT,
- /* No of children for the first cluster node */
- PLAT_ARM_CLUSTER_CORE_COUNT,
-};
-
-const css_topology_t sgm775_topology = {
- .power_tree = sgm775_power_domain_tree_desc,
- .plat_cluster_core_count = PLAT_ARM_CLUSTER_CORE_COUNT
-};
-
-/* Configuration structure for SGM775 */
-css_plat_config_t sgm775_config = {
- .inteconn = &sgm_inteconn,
- .topology = &sgm775_topology
-};
-
-/*******************************************************************************
- * This function initializes the platform structure.
- ******************************************************************************/
-void plat_config_init(void)
-{
- /* Get the platform configurations */
- switch (GET_PLAT_PART_NUM) {
- case SGM775_SSC_VER_PART_NUM:
- css_plat_info = &sgm775_config;
-
- break;
- default:
- ERROR("Not a valid sgm variant!\n");
- panic();
- }
-}
-
-/*******************************************************************************
- * This function returns the platform structure pointer.
- ******************************************************************************/
-css_plat_config_t *get_plat_config(void)
-{
- assert(css_plat_info != NULL);
- return css_plat_info;
-}
-
-#if TRUSTED_BOARD_BOOT
-int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
-{
- return get_mbedtls_heap_helper(heap_addr, heap_size);
-}
-#endif
diff --git a/plat/arm/css/sgm/sgm_security.c b/plat/arm/css/sgm/sgm_security.c
deleted file mode 100644
index 21d5306..0000000
--- a/plat/arm/css/sgm/sgm_security.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/debug.h>
-#include <drivers/arm/tzc_dmc500.h>
-#include <plat/arm/common/plat_arm.h>
-#include <plat/arm/soc/common/soc_css.h>
-
-#include <sgm_variant.h>
-
-/* Is populated with the DMC-500 controllers base addresses */
-static tzc_dmc500_driver_data_t plat_driver_data;
-
-void plat_sgm_dp_security_setup(void)
-{
- unsigned int nprot_nsaid;
-
- /*
- * At reset the Mali display processors start with NSAIDs set to zero
- * so the firmware must set them up to the expected values for ARM sgm
- * platforms.
- */
-
- nprot_nsaid = mmio_read_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET);
- nprot_nsaid &= ~((0xF << W_NPROT_NSAID_SHIFT) |
- (0xF << LS_NPORT_NSAID_SHIFT));
- nprot_nsaid |= ((TZC_NSAID_DISP1 << W_NPROT_NSAID_SHIFT) |
- (TZC_NSAID_DISP0 << LS_NPORT_NSAID_SHIFT));
- mmio_write_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET, nprot_nsaid);
-}
-
-void plat_arm_security_setup(void)
-{
- unsigned int i;
- unsigned int part_num = GET_PLAT_PART_NUM;
-
- INFO("part_num: 0x%x\n", part_num);
-
- /*
- * Initialise plat_driver_data with platform specific DMC_BASE
- * addresses
- */
- switch (part_num) {
- case SGM775_SSC_VER_PART_NUM:
- for (i = 0; i < SGM775_DMC_COUNT; i++)
- plat_driver_data.dmc_base[i] = PLAT_ARM_TZC_BASE
- + SGM_DMC_SIZE * i;
- plat_driver_data.dmc_count = SGM775_DMC_COUNT;
- break;
- default:
- /* Unexpected platform */
- ERROR("Unexpected platform\n");
- panic();
- }
- /* Initialize the TrustZone Controller in DMC-500 */
- arm_tzc_dmc500_setup(&plat_driver_data, NULL);
-
- /* Do DP NSAID setup */
- plat_sgm_dp_security_setup();
- /* Do ARM CSS SoC security setup */
- soc_css_security_setup();
-}
diff --git a/plat/arm/css/sgm/sgm_topology.c b/plat/arm/css/sgm/sgm_topology.c
deleted file mode 100644
index 2d9552d..0000000
--- a/plat/arm/css/sgm/sgm_topology.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-
-/*******************************************************************************
- * This function returns the topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
- return get_plat_config()->topology->power_tree;
-}
-
-/*******************************************************************************
- * This function returns the core count within the cluster corresponding to
- * `mpidr`.
- ******************************************************************************/
-unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
-{
- return get_plat_config()->topology->plat_cluster_core_count;
-}
-
-/*
- * The array mapping platform core position (implemented by plat_my_core_pos())
- * to the SCMI power domain ID implemented by SCP.
- */
-const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
- 0, 1, 2, 3, 4, 5, 6, 7 };
diff --git a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
deleted file mode 100644
index 5f40c4c..0000000
--- a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-#include <sgm_plat_config.h>
-
-void tsp_early_platform_setup(void)
-{
- /* Initialize the platform configuration structure */
- plat_config_init();
-
- arm_tsp_early_platform_setup();
-}
diff --git a/plat/arm/css/sgm/tsp/tsp-sgm.mk b/plat/arm/css/sgm/tsp/tsp-sgm.mk
deleted file mode 100644
index de5e5b7..0000000
--- a/plat/arm/css/sgm/tsp/tsp-sgm.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-BL32_SOURCES += ${SGM_GIC_SOURCES} \
- ${CSS_SGM_BASE}/sgm_plat_config.c \
- plat/arm/css/sgm/tsp/sgm_tsp_setup.c
-
-include plat/arm/common/tsp/arm_tsp.mk
diff --git a/plat/brcm/common/brcm_bl2_mem_params_desc.c b/plat/brcm/common/brcm_bl2_mem_params_desc.c
index f711354..aed99d9 100644
--- a/plat/brcm/common/brcm_bl2_mem_params_desc.c
+++ b/plat/brcm/common/brcm_bl2_mem_params_desc.c
@@ -22,84 +22,84 @@
#ifdef SCP_BL2_BASE
/* Fill SCP_BL2 related information if it exists */
{
- .image_id = SCP_BL2_IMAGE_ID,
+ .image_id = SCP_BL2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = SCP_BL2_BASE,
- .image_info.image_max_size = PLAT_MAX_SCP_BL2_SIZE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = SCP_BL2_BASE,
+ .image_info.image_max_size = PLAT_MAX_SCP_BL2_SIZE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
},
#endif /* SCP_BL2_BASE */
/* Fill BL31 related information */
{
- .image_id = BL31_IMAGE_ID,
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = BL31_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
#if DEBUG
- .ep_info.args.arg3 = BRCM_BL31_PLAT_PARAM_VAL,
+ .ep_info.args.arg3 = BRCM_BL31_PLAT_PARAM_VAL,
#endif
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
- .image_info.image_base = BL31_BASE,
- .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
#ifdef BL32_BASE
- .next_handoff_image_id = BL32_IMAGE_ID,
+ .next_handoff_image_id = BL32_IMAGE_ID,
#else
- .next_handoff_image_id = BL33_IMAGE_ID,
+ .next_handoff_image_id = BL33_IMAGE_ID,
#endif
},
#ifdef BL32_BASE
/* Fill BL32 related information */
{
- .image_id = BL32_IMAGE_ID,
+ .image_id = BL32_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
- .ep_info.pc = BL32_BASE,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
+ .ep_info.pc = BL32_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = BL33_IMAGE_ID,
+ .next_handoff_image_id = BL33_IMAGE_ID,
},
#endif /* BL32_BASE */
/* Fill BL33 related information */
{
- .image_id = BL33_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+ .image_id = BL33_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
#ifdef PRELOADED_BL33_BASE
- .ep_info.pc = PRELOADED_BL33_BASE,
+ .ep_info.pc = PRELOADED_BL33_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
#else
- .ep_info.pc = PLAT_BRCM_NS_IMAGE_OFFSET,
+ .ep_info.pc = PLAT_BRCM_NS_IMAGE_OFFSET,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = PLAT_BRCM_NS_IMAGE_OFFSET,
- .image_info.image_max_size = BRCM_DRAM1_SIZE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = PLAT_BRCM_NS_IMAGE_OFFSET,
+ .image_info.image_max_size = BRCM_DRAM1_SIZE,
#endif /* PRELOADED_BL33_BASE */
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
}
};
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 38a5786..e807660 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,7 +13,6 @@
#if RAS_EXTENSION
#include <lib/extensions/ras.h>
#endif
-#include <lib/extensions/twed.h>
#include <lib/xlat_tables/xlat_mmu_helpers.h>
#include <plat/common/platform.h>
@@ -23,7 +22,6 @@
* platforms but may also be overridden by a platform if required.
*/
#pragma weak bl31_plat_runtime_setup
-#pragma weak plat_arm_set_twedel_scr_el3
#if SDEI_SUPPORT
#pragma weak plat_sdei_handle_masked_trigger
@@ -105,16 +103,3 @@
#endif
panic();
}
-
-/*******************************************************************************
- * In v8.6+ platforms with delayed trapping of WFE this hook sets the delay. It
- * is a weak function definition so can be overridden depending on the
- * requirements of a platform. The only hook provided is for the TWED fields
- * in SCR_EL3, the TWED fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 should be
- * configured as needed in lower exception levels.
- ******************************************************************************/
-
-uint32_t plat_arm_set_twedel_scr_el3(void)
-{
- return TWED_DISABLED;
-}
diff --git a/plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c b/plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c
index 4e013a0..d029703 100644
--- a/plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c
+++ b/plat/hisilicon/hikey/hikey_bl2_mem_params_desc.c
@@ -21,144 +21,146 @@
static bl_mem_params_node_t bl2_mem_params_descs[] = {
#ifdef SCP_BL2_BASE
/* Fill SCP_BL2 related information if it exists */
- {
- .image_id = SCP_BL2_IMAGE_ID,
+ {
+ .image_id = SCP_BL2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
- .image_info.image_base = SCP_BL2_BASE,
- .image_info.image_max_size = SCP_BL2_SIZE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = SCP_BL2_BASE,
+ .image_info.image_max_size = SCP_BL2_SIZE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
#endif /* SCP_BL2_BASE */
#ifdef EL3_PAYLOAD_BASE
/* Fill EL3 payload related information (BL31 is EL3 payload)*/
- {
- .image_id = BL31_IMAGE_ID,
+ {
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = EL3_PAYLOAD_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = EL3_PAYLOAD_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t,
- IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
#else /* EL3_PAYLOAD_BASE */
/* Fill BL31 related information */
- {
- .image_id = BL31_IMAGE_ID,
+ {
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = BL31_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
#if DEBUG
- .ep_info.args.arg1 = HIKEY_BL31_PLAT_PARAM_VAL,
+ .ep_info.args.arg1 = HIKEY_BL31_PLAT_PARAM_VAL,
#endif
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
- .image_info.image_base = BL31_BASE,
- .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
# ifdef BL32_BASE
- .next_handoff_image_id = BL32_IMAGE_ID,
+ .next_handoff_image_id = BL32_IMAGE_ID,
# else
- .next_handoff_image_id = BL33_IMAGE_ID,
+ .next_handoff_image_id = BL33_IMAGE_ID,
# endif
- },
+ },
# ifdef BL32_BASE
/* Fill BL32 related information */
- {
- .image_id = BL32_IMAGE_ID,
+ {
+ .image_id = BL32_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
- .ep_info.pc = BL32_BASE,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
+ .ep_info.pc = BL32_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = BL33_IMAGE_ID,
- },
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
/*
* Fill BL32 external 1 related information.
- * A typical use for extra1 image is with OP-TEE where it is the pager image.
+ * A typical use for extra1 image is with OP-TEE where it is the pager
+ * image.
*/
- {
- .image_id = BL32_EXTRA1_IMAGE_ID,
+ {
+ .image_id = BL32_EXTRA1_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
/*
* Fill BL32 external 2 related information.
- * A typical use for extra2 image is with OP-TEE where it is the paged image.
+ * A typical use for extra2 image is with OP-TEE where it is the paged
+ * image.
*/
- {
- .image_id = BL32_EXTRA2_IMAGE_ID,
+ {
+ .image_id = BL32_EXTRA2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
#ifdef SPD_opteed
- .image_info.image_base = HIKEY_OPTEE_PAGEABLE_LOAD_BASE,
- .image_info.image_max_size = HIKEY_OPTEE_PAGEABLE_LOAD_SIZE,
+ .image_info.image_base = HIKEY_OPTEE_PAGEABLE_LOAD_BASE,
+ .image_info.image_max_size = HIKEY_OPTEE_PAGEABLE_LOAD_SIZE,
#endif
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
# endif /* BL32_BASE */
/* Fill BL33 related information */
- {
- .image_id = BL33_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+ {
+ .image_id = BL33_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
# ifdef PRELOADED_BL33_BASE
- .ep_info.pc = PRELOADED_BL33_BASE,
+ .ep_info.pc = PRELOADED_BL33_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
# else
- .ep_info.pc = HIKEY_NS_IMAGE_OFFSET,
+ .ep_info.pc = HIKEY_NS_IMAGE_OFFSET,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = HIKEY_NS_IMAGE_OFFSET,
- .image_info.image_max_size = 0x200000 /* 2MB */,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = HIKEY_NS_IMAGE_OFFSET,
+ .image_info.image_max_size = 0x200000 /* 2MB */,
# endif /* PRELOADED_BL33_BASE */
- .next_handoff_image_id = INVALID_IMAGE_ID,
- }
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
#endif /* EL3_PAYLOAD_BASE */
};
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
index 18197cf..2bfc582 100644
--- a/plat/hisilicon/hikey/platform.mk
+++ b/plat/hisilicon/hikey/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -95,6 +95,10 @@
BL2_SOURCES += lib/optee/optee_utils.c
endif
+include lib/zlib/zlib.mk
+PLAT_INCLUDES += -Ilib/zlib
+BL2_SOURCES += $(ZLIB_SOURCES)
+
HIKEY_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v2/gicv2_main.c \
drivers/arm/gic/v2/gicv2_helpers.c \
@@ -150,12 +154,12 @@
certificates: $(ROT_KEY)
$(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
- $(Q)openssl genrsa 2048 > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
$(ROTPK_HASH): $(ROT_KEY)
@echo " OPENSSL $@"
- $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
- openssl dgst -sha256 -binary > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
endif
# Enable workarounds for selected Cortex-A53 errata.
diff --git a/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c b/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c
index ba236d2..39a54cb 100644
--- a/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c
+++ b/plat/hisilicon/hikey960/hikey960_bl2_mem_params_desc.c
@@ -21,144 +21,146 @@
static bl_mem_params_node_t bl2_mem_params_descs[] = {
#ifdef SCP_BL2_BASE
/* Fill SCP_BL2 related information if it exists */
- {
- .image_id = SCP_BL2_IMAGE_ID,
+ {
+ .image_id = SCP_BL2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
- .image_info.image_base = SCP_BL2_BASE,
- .image_info.image_max_size = SCP_BL2_SIZE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = SCP_BL2_BASE,
+ .image_info.image_max_size = SCP_BL2_SIZE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
#endif /* SCP_BL2_BASE */
#ifdef EL3_PAYLOAD_BASE
/* Fill EL3 payload related information (BL31 is EL3 payload)*/
- {
- .image_id = BL31_IMAGE_ID,
+ {
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = EL3_PAYLOAD_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = EL3_PAYLOAD_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t,
- IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
#else /* EL3_PAYLOAD_BASE */
/* Fill BL31 related information */
- {
- .image_id = BL31_IMAGE_ID,
+ {
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = BL31_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
#if DEBUG
- .ep_info.args.arg1 = HIKEY960_BL31_PLAT_PARAM_VAL,
+ .ep_info.args.arg1 = HIKEY960_BL31_PLAT_PARAM_VAL,
#endif
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
- .image_info.image_base = BL31_BASE,
- .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
# ifdef BL32_BASE
- .next_handoff_image_id = BL32_IMAGE_ID,
+ .next_handoff_image_id = BL32_IMAGE_ID,
# else
- .next_handoff_image_id = BL33_IMAGE_ID,
+ .next_handoff_image_id = BL33_IMAGE_ID,
# endif
- },
+ },
# ifdef BL32_BASE
/* Fill BL32 related information */
- {
- .image_id = BL32_IMAGE_ID,
+ {
+ .image_id = BL32_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
- .ep_info.pc = BL32_BASE,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
+ .ep_info.pc = BL32_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = BL33_IMAGE_ID,
- },
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
/*
* Fill BL32 external 1 related information.
- * A typical use for extra1 image is with OP-TEE where it is the pager image.
+ * A typical use for extra1 image is with OP-TEE where it is the pager
+ * image.
*/
- {
- .image_id = BL32_EXTRA1_IMAGE_ID,
+ {
+ .image_id = BL32_EXTRA1_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
/*
* Fill BL32 external 2 related information.
- * A typical use for extra2 image is with OP-TEE where it is the paged image.
+ * A typical use for extra2 image is with OP-TEE where it is the paged
+ * image.
*/
- {
- .image_id = BL32_EXTRA2_IMAGE_ID,
+ {
+ .image_id = BL32_EXTRA2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
#ifdef SPD_opteed
- .image_info.image_base = HIKEY960_OPTEE_PAGEABLE_LOAD_BASE,
- .image_info.image_max_size = HIKEY960_OPTEE_PAGEABLE_LOAD_SIZE,
+ .image_info.image_base = HIKEY960_OPTEE_PAGEABLE_LOAD_BASE,
+ .image_info.image_max_size = HIKEY960_OPTEE_PAGEABLE_LOAD_SIZE,
#endif
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
# endif /* BL32_BASE */
/* Fill BL33 related information */
- {
- .image_id = BL33_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+ {
+ .image_id = BL33_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
# ifdef PRELOADED_BL33_BASE
- .ep_info.pc = PRELOADED_BL33_BASE,
+ .ep_info.pc = PRELOADED_BL33_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
# else
- .ep_info.pc = NS_BL1U_BASE,
+ .ep_info.pc = NS_BL1U_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = NS_BL1U_BASE,
- .image_info.image_max_size = 0x200000 /* 2MB */,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = NS_BL1U_BASE,
+ .image_info.image_max_size = 0x200000 /* 2MB */,
# endif /* PRELOADED_BL33_BASE */
- .next_handoff_image_id = INVALID_IMAGE_ID,
- }
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
#endif /* EL3_PAYLOAD_BASE */
};
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index fc2c209..c8ad66c 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -94,6 +94,10 @@
BL2_SOURCES += lib/optee/optee_utils.c
endif
+include lib/zlib/zlib.mk
+PLAT_INCLUDES += -Ilib/zlib
+BL2_SOURCES += $(ZLIB_SOURCES)
+
BL31_SOURCES += drivers/arm/cci/cci.c \
drivers/arm/pl061/pl061_gpio.c \
drivers/gpio/gpio.c \
@@ -142,12 +146,12 @@
certificates: $(ROT_KEY)
$(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
- $(Q)openssl genrsa 2048 > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
$(ROTPK_HASH): $(ROT_KEY)
@echo " OPENSSL $@"
- $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
- openssl dgst -sha256 -binary > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
endif
# Enable workarounds for selected Cortex-A53 errata.
diff --git a/plat/hisilicon/poplar/bl2_plat_mem_params_desc.c b/plat/hisilicon/poplar/bl2_plat_mem_params_desc.c
index f683d75..9bda02e 100644
--- a/plat/hisilicon/poplar/bl2_plat_mem_params_desc.c
+++ b/plat/hisilicon/poplar/bl2_plat_mem_params_desc.c
@@ -22,143 +22,145 @@
#ifdef SCP_BL2_BASE
/* Fill SCP_BL2 related information if it exists */
{
- .image_id = SCP_BL2_IMAGE_ID,
+ .image_id = SCP_BL2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = SCP_BL2_BASE,
- .image_info.image_max_size = SCP_BL2_SIZE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = SCP_BL2_BASE,
+ .image_info.image_max_size = SCP_BL2_SIZE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
},
#endif /* SCP_BL2_BASE */
#ifdef EL3_PAYLOAD_BASE
/* Fill EL3 payload related information (BL31 is EL3 payload)*/
{
- .image_id = BL31_IMAGE_ID,
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = EL3_PAYLOAD_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = EL3_PAYLOAD_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t,
- IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
},
#else /* EL3_PAYLOAD_BASE */
/* Fill BL31 related information */
{
- .image_id = BL31_IMAGE_ID,
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = BL31_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
#if DEBUG
- .ep_info.args.arg1 = POPLAR_BL31_PLAT_PARAM_VAL,
+ .ep_info.args.arg1 = POPLAR_BL31_PLAT_PARAM_VAL,
#endif
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
- .image_info.image_base = BL31_BASE,
- .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
# ifdef BL32_BASE
- .next_handoff_image_id = BL32_IMAGE_ID,
+ .next_handoff_image_id = BL32_IMAGE_ID,
# else
- .next_handoff_image_id = BL33_IMAGE_ID,
+ .next_handoff_image_id = BL33_IMAGE_ID,
# endif
},
# ifdef BL32_BASE
/* Fill BL32 related information */
{
- .image_id = BL32_IMAGE_ID,
+ .image_id = BL32_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
- .ep_info.pc = BL32_BASE,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
+ .ep_info.pc = BL32_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = BL33_IMAGE_ID,
+ .next_handoff_image_id = BL33_IMAGE_ID,
},
/*
* Fill BL32 external 1 related information.
- * A typical use for extra1 image is with OP-TEE where it is the pager image.
+ * A typical use for extra1 image is with OP-TEE where it is the pager
+ * image.
*/
{
- .image_id = BL32_EXTRA1_IMAGE_ID,
+ .image_id = BL32_EXTRA1_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
},
/*
* Fill BL32 external 2 related information.
- * A typical use for extra2 image is with OP-TEE where it is the paged image.
+ * A typical use for extra2 image is with OP-TEE where it is the paged
+ * image.
*/
{
- .image_id = BL32_EXTRA2_IMAGE_ID,
+ .image_id = BL32_EXTRA2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
#ifdef SPD_opteed
- .image_info.image_base = POPLAR_OPTEE_PAGEABLE_LOAD_BASE,
- .image_info.image_max_size = POPLAR_OPTEE_PAGEABLE_LOAD_SIZE,
+ .image_info.image_base = POPLAR_OPTEE_PAGEABLE_LOAD_BASE,
+ .image_info.image_max_size = POPLAR_OPTEE_PAGEABLE_LOAD_SIZE,
#endif
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
},
# endif /* BL32_BASE */
/* Fill BL33 related information */
{
- .image_id = BL33_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+ .image_id = BL33_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
# ifdef PRELOADED_BL33_BASE
- .ep_info.pc = PRELOADED_BL33_BASE,
+ .ep_info.pc = PRELOADED_BL33_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
# else
- .ep_info.pc = PLAT_POPLAR_NS_IMAGE_OFFSET,
+ .ep_info.pc = PLAT_POPLAR_NS_IMAGE_OFFSET,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = PLAT_POPLAR_NS_IMAGE_OFFSET,
- .image_info.image_max_size = DDR_BASE + DDR_SIZE -
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = PLAT_POPLAR_NS_IMAGE_OFFSET,
+ .image_info.image_max_size = DDR_BASE + DDR_SIZE -
PLAT_POPLAR_NS_IMAGE_OFFSET,
# endif /* PRELOADED_BL33_BASE */
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
}
#endif /* EL3_PAYLOAD_BASE */
};
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index fd54820..fae9750 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -34,6 +34,13 @@
SMC_RET1(handle, imx_soc_info_handler(smc_fid, x1, x2, x3));
break;
#endif
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+ case IMX_SIP_DDR_DVFS:
+ return dram_dvfs_handler(smc_fid, handle, x1, x2, x3);
+ case IMX_SIP_GPC:
+ SMC_RET1(handle, imx_gpc_handler(smc_fid, x1, x2, x3));
+ break;
+#endif
#if (defined(PLAT_imx8qm) || defined(PLAT_imx8qx))
case IMX_SIP_SRTC:
return imx_srtc_handler(smc_fid, handle, x1, x2, x3, x4);
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 6c7a760..c6e9879 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,8 @@
#define __IMX_SIP_SVC_H__
/* SMC function IDs for SiP Service queries */
+#define IMX_SIP_GPC 0xC2000000
+
#define IMX_SIP_CPUFREQ 0xC2000001
#define IMX_SIP_SET_CPUFREQ 0x00
@@ -17,6 +19,8 @@
#define IMX_SIP_BUILDINFO 0xC2000003
#define IMX_SIP_BUILDINFO_GET_COMMITHASH 0x00
+#define IMX_SIP_DDR_DVFS 0xc2000004
+
#define IMX_SIP_SRC 0xC2000005
#define IMX_SIP_SRC_SET_SECONDARY_BOOT 0x10
#define IMX_SIP_SRC_IS_SECONDARY_BOOT 0x11
@@ -41,6 +45,13 @@
int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1,
u_register_t x2, u_register_t x3);
#endif
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+ u_register_t x1, u_register_t x2, u_register_t x3);
+
+int imx_gpc_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3);
+#endif
#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
int imx_src_handler(uint32_t smc_fid, u_register_t x1,
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
index fdde9a9..f4f5bfc 100644
--- a/plat/imx/imx7/common/imx7.mk
+++ b/plat/imx/imx7/common/imx7.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -80,13 +80,13 @@
$(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
@if [ ! -f $(ROT_KEY) ]; then \
- openssl genrsa 2048 > $@ 2>/dev/null; \
+ ${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
fi
$(ROTPK_HASH): $(ROT_KEY)
@echo " OPENSSL $@"
- $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
- openssl dgst -sha256 -binary > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
endif
# Add the build options to pack BLx images and kernel device tree
diff --git a/plat/imx/imx8m/ddr/clock.c b/plat/imx/imx8m/ddr/clock.c
new file mode 100644
index 0000000..7fb5730
--- /dev/null
+++ b/plat/imx/imx8m/ddr/clock.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#define IMX_CCM_IP_BASE (IMX_CCM_BASE + 0xa000)
+#define DRAM_SEL_CFG (IMX_CCM_BASE + 0x9800)
+#define CCM_IP_CLK_ROOT_GEN_TAGET(i) (IMX_CCM_IP_BASE + 0x80 * (i) + 0x00)
+#define CCM_IP_CLK_ROOT_GEN_TAGET_SET(i) (IMX_CCM_IP_BASE + 0x80 * (i) + 0x04)
+#define CCM_IP_CLK_ROOT_GEN_TAGET_CLR(i) (IMX_CCM_IP_BASE + 0x80 * (i) + 0x08)
+#define PLL_FREQ_800M U(0x00ece580)
+#define PLL_FREQ_400M U(0x00ec6984)
+#define PLL_FREQ_167M U(0x00f5a406)
+
+void ddr_pll_bypass_100mts(void)
+{
+ /* change the clock source of dram_alt_clk_root to source 2 --100MHz */
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(0), (0x7 << 24) | (0x7 << 16));
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(0), (0x2 << 24));
+
+ /* change the clock source of dram_apb_clk_root to source 2 --40MHz/2 */
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x2 << 24) | (0x1 << 16));
+
+ /* configure pll bypass mode */
+ mmio_write_32(DRAM_SEL_CFG + 0x4, BIT(24));
+}
+
+void ddr_pll_bypass_400mts(void)
+{
+ /* change the clock source of dram_alt_clk_root to source 1 --400MHz */
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(0), (0x7 << 24) | (0x7 << 16));
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(0), (0x1 << 24) | (0x1 << 16));
+
+ /* change the clock source of dram_apb_clk_root to source 3 --160MHz/2 */
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x3 << 24) | (0x1 << 16));
+
+ /* configure pll bypass mode */
+ mmio_write_32(DRAM_SEL_CFG + 0x4, BIT(24));
+}
+
+void ddr_pll_unbypass(void)
+{
+ mmio_write_32(DRAM_SEL_CFG + 0x8, BIT(24));
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1), (0x7 << 24) | (0x7 << 16));
+ /* to source 4 --800MHz/5 */
+ mmio_write_32(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1), (0x4 << 24) | (0x4 << 16));
+}
+
+#if defined(PLAT_imx8mq)
+void dram_pll_init(unsigned int drate)
+{
+ /* bypass the PLL */
+ mmio_setbits_32(HW_DRAM_PLL_CFG0, 0x30);
+
+ switch (drate) {
+ case 3200:
+ mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_800M);
+ break;
+ case 1600:
+ mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_400M);
+ break;
+ case 667:
+ mmio_write_32(HW_DRAM_PLL_CFG2, PLL_FREQ_167M);
+ break;
+ default:
+ break;
+ }
+
+ /* unbypass the PLL */
+ mmio_clrbits_32(HW_DRAM_PLL_CFG0, 0x30);
+ while (!(mmio_read_32(HW_DRAM_PLL_CFG0) & (1 << 31))) {
+ ;
+ }
+}
+#else
+void dram_pll_init(unsigned int drate)
+{
+ /* bypass the PLL */
+ mmio_setbits_32(DRAM_PLL_CTRL, (1 << 16));
+ mmio_clrbits_32(DRAM_PLL_CTRL, (1 << 9));
+
+ switch (drate) {
+ case 2400:
+ mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (3 << 4) | 2);
+ break;
+ case 1600:
+ mmio_write_32(DRAM_PLL_CTRL + 0x4, (400 << 12) | (3 << 4) | 3);
+ break;
+ case 1066:
+ mmio_write_32(DRAM_PLL_CTRL + 0x4, (266 << 12) | (3 << 4) | 3);
+ break;
+ case 667:
+ mmio_write_32(DRAM_PLL_CTRL + 0x4, (334 << 12) | (3 << 4) | 4);
+ break;
+ default:
+ break;
+ }
+
+ mmio_setbits_32(DRAM_PLL_CTRL, BIT(9));
+ /* wait for PLL locked */
+ while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) {
+ ;
+ }
+
+ /* unbypass the PLL */
+ mmio_clrbits_32(DRAM_PLL_CTRL, BIT(16));
+}
+#endif
+
+/* change the dram clock frequency */
+void dram_clock_switch(unsigned int target_drate, bool bypass_mode)
+{
+ if (bypass_mode) {
+ switch (target_drate) {
+ case 400:
+ ddr_pll_bypass_400mts();
+ break;
+ case 100:
+ ddr_pll_bypass_100mts();
+ break;
+ default:
+ ddr_pll_unbypass();
+ break;
+ }
+ } else {
+ dram_pll_init(target_drate);
+ }
+}
diff --git a/plat/imx/imx8m/ddr/ddr4_dvfs.c b/plat/imx/imx8m/ddr/ddr4_dvfs.c
new file mode 100644
index 0000000..cdc7dc2
--- /dev/null
+++ b/plat/imx/imx8m/ddr/ddr4_dvfs.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <dram.h>
+
+void ddr4_mr_write(uint32_t mr, uint32_t data, uint32_t mr_type, uint32_t rank)
+{
+ uint32_t val, mr_mirror, data_mirror;
+
+ /*
+ * 1. Poll MRSTAT.mr_wr_busy until it is 0 to make sure
+ * that there is no outstanding MR transAction.
+ */
+ while (mmio_read_32(DDRC_MRSTAT(0)) & 0x1) {
+ ;
+ }
+
+ /*
+ * 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr, MRCTRL0.mr_rank
+ * and (for MRWs) MRCTRL1.mr_data to define the MR transaction.
+ */
+ val = mmio_read_32(DDRC_DIMMCTL(0));
+ if ((val & 0x2) && (rank == 0x2)) {
+ mr_mirror = (mr & 0x4) | ((mr & 0x1) << 1) | ((mr & 0x2) >> 1); /* BA0, BA1 swap */
+ data_mirror = (data & 0x1607) | ((data & 0x8) << 1) | ((data & 0x10) >> 1) |
+ ((data & 0x20) << 1) | ((data & 0x40) >> 1) | ((data & 0x80) << 1) |
+ ((data & 0x100) >> 1) | ((data & 0x800) << 2) | ((data & 0x2000) >> 2) ;
+ } else {
+ mr_mirror = mr;
+ data_mirror = data;
+ }
+
+ mmio_write_32(DDRC_MRCTRL0(0), mr_type | (mr_mirror << 12) | (rank << 4));
+ mmio_write_32(DDRC_MRCTRL1(0), data_mirror);
+
+ /*
+ * 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1.
+ * This bit is self-clearing, and triggers the MR transaction.
+ * The uMCTL2 then asserts the MRSTAT.mr_wr_busy while it performs
+ * the MR transaction to SDRAM, and no further accesses can be
+ * initiated until it is deasserted.
+ */
+ mmio_setbits_32(DDRC_MRCTRL0(0), BIT(31));
+
+ while (mmio_read_32(DDRC_MRSTAT(0))) {
+ ;
+ }
+}
+
+void dram_cfg_all_mr(struct dram_info *info, uint32_t pstate)
+{
+ uint32_t num_rank = info->num_rank;
+ /*
+ * 15. Perform MRS commands as required to re-program
+ * timing registers in the SDRAM for the new frequency
+ * (in particular, CL, CWL and WR may need to be changed).
+ */
+
+ for (int i = 1; i <= num_rank; i++) {
+ for (int j = 0; j < 6; j++) {
+ ddr4_mr_write(j, info->mr_table[pstate][j], 0, i);
+ }
+ ddr4_mr_write(6, info->mr_table[pstate][7], 0, i);
+ }
+}
+
+void sw_pstate(uint32_t pstate, uint32_t drate)
+{
+ uint32_t val;
+
+ mmio_write_32(DDRC_SWCTL(0), 0x0);
+
+ /*
+ * Update any registers which may be required to
+ * change for the new frequency.
+ */
+ mmio_write_32(DDRC_MSTR2(0), pstate);
+ mmio_setbits_32(DDRC_MSTR(0), (0x1 << 29));
+
+ /*
+ * Toggle RFSHCTL3.refresh_update_level to allow the
+ * new refresh-related register values to propagate
+ * to the refresh logic.
+ */
+ val = mmio_read_32(DDRC_RFSHCTL3(0));
+ if (val & 0x2) {
+ mmio_write_32(DDRC_RFSHCTL3(0), val & 0xFFFFFFFD);
+ } else {
+ mmio_write_32(DDRC_RFSHCTL3(0), val | 0x2);
+ }
+
+ /*
+ * 19. If required, trigger the initialization in the PHY.
+ * If using the gen2 multiPHY, PLL initialization should
+ * be triggered at this point. See the PHY databook for
+ * details about the frequency change procedure.
+ */
+ mmio_write_32(DDRC_DFIMISC(0), 0x00000000 | (pstate << 8));
+ mmio_write_32(DDRC_DFIMISC(0), 0x00000020 | (pstate << 8));
+
+ /* wait DFISTAT.dfi_init_complete to 0 */
+ while (mmio_read_32(DDRC_DFISTAT(0)) & 0x1) {
+ ;
+ }
+
+ /* change the clock to the target frequency */
+ dram_clock_switch(drate, false);
+
+ mmio_write_32(DDRC_DFIMISC(0), 0x00000000 | (pstate << 8));
+
+ /* wait DFISTAT.dfi_init_complete to 1 */
+ while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
+ ;
+ }
+
+ /*
+ * When changing frequencies the controller may violate the JEDEC
+ * requirement that no more than 16 refreshes should be issued within
+ * 2*tREFI. These extra refreshes are not expected to cause a problem
+ * in the SDRAM. This issue can be avoided by waiting for at least 2*tREFI
+ * before exiting self-refresh in step 19.
+ */
+ udelay(14);
+
+ /* 14. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
+ mmio_clrbits_32(DDRC_PWRCTL(0), (1 << 5));
+
+ while ((mmio_read_32(DDRC_STAT(0)) & 0x3f) == 0x23) {
+ ;
+ }
+}
+
+void ddr4_swffc(struct dram_info *info, unsigned int pstate)
+{
+ uint32_t drate = info->timing_info->fsp_table[pstate];
+
+ /*
+ * 1. set SWCTL.sw_done to disable quasi-dynamic register
+ * programming outside reset.
+ */
+ mmio_write_32(DDRC_SWCTL(0), 0x0);
+
+ /*
+ * 2. Write 0 to PCTRL_n.port_en. This blocks AXI port(s)
+ * from taking any transaction (blocks traffic on AXI ports).
+ */
+ mmio_write_32(DDRC_PCTRL_0(0), 0x0);
+
+ /*
+ * 3. Poll PSTAT.rd_port_busy_n=0 and PSTAT.wr_port_busy_n=0.
+ * Wait until all AXI ports are idle (the uMCTL2 core has to
+ * be idle).
+ */
+ while (mmio_read_32(DDRC_PSTAT(0)) & 0x10001) {
+ ;
+ }
+
+ /*
+ * 4. Write 0 to SBRCTL.scrub_en. Disable SBR, required only if
+ * SBR instantiated.
+ * 5. Poll SBRSTAT.scrub_busy=0.
+ * 6. Set DERATEEN.derate_enable = 0, if DERATEEN.derate_eanble = 1
+ * and the read latency (RL) value needs to change after the frequency
+ * change (LPDDR2/3/4 only).
+ * 7. Set DBG1.dis_hif=1 so that no new commands will be accepted by the uMCTL2.
+ */
+ mmio_setbits_32(DDRC_DBG1(0), (0x1 << 1));
+
+ /*
+ * 8. Poll DBGCAM.dbg_wr_q_empty and DBGCAM.dbg_rd_q_empty to ensure
+ * that write and read data buffers are empty.
+ */
+ while ((mmio_read_32(DDRC_DBGCAM(0)) & 0x06000000) != 0x06000000) {
+ ;
+ }
+
+ /*
+ * 9. For DDR4, update MR6 with the new tDLLK value via the Mode
+ * Register Write signals
+ * 10. Set DFILPCFG0.dfi_lp_en_sr = 0, if DFILPCFG0.dfi_lp_en_sr = 1,
+ * and wait until DFISTAT.dfi_lp_ack
+ * 11. If DFI PHY Master interface is active in uMCTL2, then disable it
+ * 12. Wait until STAT.operating_mode[1:0]!=11 indicating that the
+ * controller is not in self-refresh mode.
+ */
+ while ((mmio_read_32(DDRC_STAT(0)) & 0x3) == 0x3) {
+ ;
+ }
+
+ /*
+ * 13. Assert PWRCTL.selfref_sw for the DWC_ddr_umctl2 core to enter
+ * the self-refresh mode.
+ */
+ mmio_setbits_32(DDRC_PWRCTL(0), (1 << 5));
+
+ /*
+ * 14. Wait until STAT.operating_mode[1:0]==11 indicating that the
+ * controller core is in self-refresh mode.
+ */
+ while ((mmio_read_32(DDRC_STAT(0)) & 0x3f) != 0x23) {
+ ;
+ }
+
+ sw_pstate(pstate, drate);
+ dram_cfg_all_mr(info, pstate);
+
+ /* 23. Enable HIF commands by setting DBG1.dis_hif=0. */
+ mmio_clrbits_32(DDRC_DBG1(0), (0x1 << 1));
+
+ /*
+ * 24. Reset DERATEEN.derate_enable = 1 if DERATEEN.derate_enable
+ * has been set to 0 in step 6.
+ * 25. If DFI PHY Master interface was active before step 11 then
+ * enable it back by programming DFIPHYMSTR.phymstr_en = 1'b1.
+ * 26. Write 1 to PCTRL_n.port_en. AXI port(s) are no longer blocked
+ * from taking transactions (Re-enable traffic on AXI ports)
+ */
+ mmio_write_32(DDRC_PCTRL_0(0), 0x1);
+
+ /*
+ * 27. Write 1 to SBRCTL.scrub_en. Enable SBR if desired, only
+ * required if SBR instantiated.
+ */
+
+ /*
+ * set SWCTL.sw_done to enable quasi-dynamic register programming
+ * outside reset.
+ */
+ mmio_write_32(DDRC_SWCTL(0), 0x1);
+
+ /* wait SWSTAT.sw_done_ack to 1 */
+ while (!(mmio_read_32(DDRC_SWSTAT(0)) & 0x1)) {
+ ;
+ }
+}
diff --git a/plat/imx/imx8m/ddr/dram.c b/plat/imx/imx8m/ddr/dram.c
new file mode 100644
index 0000000..6ccd6fd
--- /dev/null
+++ b/plat/imx/imx8m/ddr/dram.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2019-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl31/interrupt_mgmt.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+
+#include <dram.h>
+
+#define IMX_SIP_DDR_DVFS_GET_FREQ_COUNT 0x10
+#define IMX_SIP_DDR_DVFS_GET_FREQ_INFO 0x11
+
+struct dram_info dram_info;
+
+/* lock used for DDR DVFS */
+spinlock_t dfs_lock;
+
+static volatile uint32_t wfe_done;
+static volatile bool wait_ddrc_hwffc_done = true;
+static unsigned int dev_fsp = 0x1;
+
+static uint32_t fsp_init_reg[3][4] = {
+ { DDRC_INIT3(0), DDRC_INIT4(0), DDRC_INIT6(0), DDRC_INIT7(0) },
+ { DDRC_FREQ1_INIT3(0), DDRC_FREQ1_INIT4(0), DDRC_FREQ1_INIT6(0), DDRC_FREQ1_INIT7(0) },
+ { DDRC_FREQ2_INIT3(0), DDRC_FREQ2_INIT4(0), DDRC_FREQ2_INIT6(0), DDRC_FREQ2_INIT7(0) },
+};
+
+static void get_mr_values(uint32_t (*mr_value)[8])
+{
+ uint32_t init_val;
+ unsigned int i, fsp_index;
+
+ for (fsp_index = 0U; fsp_index < 3U; fsp_index++) {
+ for (i = 0U; i < 4U; i++) {
+ init_val = mmio_read_32(fsp_init_reg[fsp_index][i]);
+ mr_value[fsp_index][2*i] = init_val >> 16;
+ mr_value[fsp_index][2*i + 1] = init_val & 0xFFFF;
+ }
+ }
+}
+
+/* Restore the ddrc configs */
+void dram_umctl2_init(struct dram_timing_info *timing)
+{
+ struct dram_cfg_param *ddrc_cfg = timing->ddrc_cfg;
+ unsigned int i;
+
+ for (i = 0U; i < timing->ddrc_cfg_num; i++) {
+ mmio_write_32(ddrc_cfg->reg, ddrc_cfg->val);
+ ddrc_cfg++;
+ }
+
+ /* set the default fsp to P0 */
+ mmio_write_32(DDRC_MSTR2(0), 0x0);
+}
+
+/* Restore the dram PHY config */
+void dram_phy_init(struct dram_timing_info *timing)
+{
+ struct dram_cfg_param *cfg = timing->ddrphy_cfg;
+ unsigned int i;
+
+ /* Restore the PHY init config */
+ cfg = timing->ddrphy_cfg;
+ for (i = 0U; i < timing->ddrphy_cfg_num; i++) {
+ dwc_ddrphy_apb_wr(cfg->reg, cfg->val);
+ cfg++;
+ }
+
+ /* Restore the DDR PHY CSRs */
+ cfg = timing->ddrphy_trained_csr;
+ for (i = 0U; i < timing->ddrphy_trained_csr_num; i++) {
+ dwc_ddrphy_apb_wr(cfg->reg, cfg->val);
+ cfg++;
+ }
+
+ /* Load the PIE image */
+ cfg = timing->ddrphy_pie;
+ for (i = 0U; i < timing->ddrphy_pie_num; i++) {
+ dwc_ddrphy_apb_wr(cfg->reg, cfg->val);
+ cfg++;
+ }
+}
+
+/* EL3 SGI-8 IPI handler for DDR Dynamic frequency scaling */
+static uint64_t waiting_dvfs(uint32_t id, uint32_t flags,
+ void *handle, void *cookie)
+{
+ uint64_t mpidr = read_mpidr_el1();
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+ uint32_t irq;
+
+ irq = plat_ic_acknowledge_interrupt();
+ if (irq < 1022U) {
+ plat_ic_end_of_interrupt(irq);
+ }
+
+ /* set the WFE done status */
+ spin_lock(&dfs_lock);
+ wfe_done |= (1 << cpu_id * 8);
+ dsb();
+ spin_unlock(&dfs_lock);
+
+ while (1) {
+ /* ddr frequency change done */
+ if (!wait_ddrc_hwffc_done)
+ break;
+
+ wfe();
+ }
+
+ return 0;
+}
+
+void dram_info_init(unsigned long dram_timing_base)
+{
+ uint32_t ddrc_mstr, current_fsp;
+ uint32_t flags = 0;
+ uint32_t rc;
+ unsigned int i;
+
+ /* Get the dram type & rank */
+ ddrc_mstr = mmio_read_32(DDRC_MSTR(0));
+
+ dram_info.dram_type = ddrc_mstr & DDR_TYPE_MASK;
+ dram_info.num_rank = (ddrc_mstr >> 24) & ACTIVE_RANK_MASK;
+
+ /* Get current fsp info */
+ current_fsp = mmio_read_32(DDRC_DFIMISC(0)) & 0xf;
+ dram_info.boot_fsp = current_fsp;
+ dram_info.current_fsp = current_fsp;
+
+ get_mr_values(dram_info.mr_table);
+
+ dram_info.timing_info = (struct dram_timing_info *)dram_timing_base;
+
+ /* get the num of supported fsp */
+ for (i = 0U; i < 4U; ++i) {
+ if (!dram_info.timing_info->fsp_table[i]) {
+ break;
+ }
+ }
+ dram_info.num_fsp = i;
+
+ /* check if has bypass mode support */
+ if (dram_info.timing_info->fsp_table[i-1] < 666) {
+ dram_info.bypass_mode = true;
+ } else {
+ dram_info.bypass_mode = false;
+ }
+
+ /* Register the EL3 handler for DDR DVFS */
+ set_interrupt_rm_flag(flags, NON_SECURE);
+ rc = register_interrupt_type_handler(INTR_TYPE_EL3, waiting_dvfs, flags);
+ if (rc != 0) {
+ panic();
+ }
+}
+
+
+/*
+ * For each freq return the following info:
+ *
+ * r1: data rate
+ * r2: 1 + dram_core parent
+ * r3: 1 + dram_alt parent index
+ * r4: 1 + dram_apb parent index
+ *
+ * The parent indices can be used by an OS who manages source clocks to enabled
+ * them ahead of the switch.
+ *
+ * A parent value of "0" means "don't care".
+ *
+ * Current implementation of freq switch is hardcoded in
+ * plat/imx/common/imx8m/clock.c but in theory this can be enhanced to support
+ * a wide variety of rates.
+ */
+int dram_dvfs_get_freq_info(void *handle, u_register_t index)
+{
+ switch (index) {
+ case 0:
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[0],
+ 1, 0, 5);
+ case 1:
+ if (!dram_info.bypass_mode) {
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[1],
+ 1, 0, 0);
+ }
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[1],
+ 2, 2, 4);
+ case 2:
+ if (!dram_info.bypass_mode) {
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[2],
+ 1, 0, 0);
+ }
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[2],
+ 2, 3, 3);
+ case 3:
+ SMC_RET4(handle, dram_info.timing_info->fsp_table[3],
+ 1, 0, 0);
+ default:
+ SMC_RET1(handle, -3);
+ }
+}
+
+int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+ u_register_t x1, u_register_t x2, u_register_t x3)
+{
+ uint64_t mpidr = read_mpidr_el1();
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+ unsigned int fsp_index = x1;
+ uint32_t online_cores = x2;
+
+ if (x1 == IMX_SIP_DDR_DVFS_GET_FREQ_COUNT) {
+ SMC_RET1(handle, dram_info.num_fsp);
+ } else if (x1 == IMX_SIP_DDR_DVFS_GET_FREQ_INFO) {
+ return dram_dvfs_get_freq_info(handle, x2);
+ } else if (x1 < 4) {
+ wait_ddrc_hwffc_done = true;
+ dsb();
+
+ /* trigger the SGI IPI to info other cores */
+ for (int i = 0; i < PLATFORM_CORE_COUNT; i++) {
+ if (cpu_id != i && (online_cores & (0x1 << (i * 8)))) {
+ plat_ic_raise_el3_sgi(0x8, i);
+ }
+ }
+
+ /* make sure all the core in WFE */
+ online_cores &= ~(0x1 << (cpu_id * 8));
+ while (1) {
+ if (online_cores == wfe_done) {
+ break;
+ }
+ }
+
+ /* flush the L1/L2 cache */
+ dcsw_op_all(DCCSW);
+
+ if (dram_info.dram_type == DDRC_LPDDR4) {
+ lpddr4_swffc(&dram_info, dev_fsp, fsp_index);
+ dev_fsp = (~dev_fsp) & 0x1;
+ } else if (dram_info.dram_type == DDRC_DDR4) {
+ ddr4_swffc(&dram_info, fsp_index);
+ }
+
+ dram_info.current_fsp = fsp_index;
+ wait_ddrc_hwffc_done = false;
+ wfe_done = 0;
+ dsb();
+ sev();
+ isb();
+ }
+
+ SMC_RET1(handle, 0);
+}
diff --git a/plat/imx/imx8m/ddr/dram_retention.c b/plat/imx/imx8m/ddr/dram_retention.c
new file mode 100644
index 0000000..7d4f823
--- /dev/null
+++ b/plat/imx/imx8m/ddr/dram_retention.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <lib/mmio.h>
+
+#include <dram.h>
+#include <platform_def.h>
+
+#define SRC_DDR1_RCR (IMX_SRC_BASE + 0x1000)
+#define SRC_DDR2_RCR (IMX_SRC_BASE + 0x1004)
+
+#define PU_PGC_UP_TRG 0xf8
+#define PU_PGC_DN_TRG 0x104
+#define GPC_PU_PWRHSK (IMX_GPC_BASE + 0x01FC)
+#define CCM_SRC_CTRL_OFFSET (IMX_CCM_BASE + 0x800)
+#define CCM_CCGR_OFFSET (IMX_CCM_BASE + 0x4000)
+#define CCM_SRC_CTRL(n) (CCM_SRC_CTRL_OFFSET + 0x10 * (n))
+#define CCM_CCGR(n) (CCM_CCGR_OFFSET + 0x10 * (n))
+
+#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50)
+
+#define DBGCAM_EMPTY 0x36000000
+
+void dram_enter_retention(void)
+{
+ /* Wait DBGCAM to be empty */
+ while (mmio_read_32(DDRC_DBGCAM(0)) != DBGCAM_EMPTY) {
+ ;
+ }
+
+ /* Block AXI ports from taking anymore transactions */
+ mmio_write_32(DDRC_PCTRL_0(0), 0x0);
+ /* Wait until all AXI ports are idle */
+ while (mmio_read_32(DDRC_PSTAT(0)) & 0x10001) {
+ ;
+ }
+
+ /* Enter self refresh */
+ mmio_write_32(DDRC_PWRCTL(0), 0xaa);
+
+ /* LPDDR4 & DDR4/DDR3L need to check different status */
+ if (dram_info.dram_type == DDRC_LPDDR4) {
+ while (0x223 != (mmio_read_32(DDRC_STAT(0)) & 0x33f)) {
+ ;
+ }
+ } else {
+ while (0x23 != (mmio_read_32(DDRC_STAT(0)) & 0x3f)) {
+ ;
+ }
+ }
+
+ mmio_write_32(DDRC_DFIMISC(0), 0x0);
+ mmio_write_32(DDRC_SWCTL(0), 0x0);
+ mmio_write_32(DDRC_DFIMISC(0), 0x1f00);
+ mmio_write_32(DDRC_DFIMISC(0), 0x1f20);
+
+ while (mmio_read_32(DDRC_DFISTAT(0)) & 0x1) {
+ ;
+ }
+
+ mmio_write_32(DDRC_DFIMISC(0), 0x1f00);
+ /* wait DFISTAT.dfi_init_complete to 1 */
+ while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
+ ;
+ }
+
+ mmio_write_32(DDRC_SWCTL(0), 0x1);
+
+ /* should check PhyInLP3 pub reg */
+ dwc_ddrphy_apb_wr(0xd0000, 0x0);
+ if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) {
+ INFO("PhyInLP3 = 1\n");
+ }
+ dwc_ddrphy_apb_wr(0xd0000, 0x1);
+
+#if defined(PLAT_imx8mq)
+ /* pwrdnreqn_async adbm/adbs of ddr */
+ mmio_clrbits_32(GPC_PU_PWRHSK, BIT(1));
+ while (mmio_read_32(GPC_PU_PWRHSK) & BIT(18)) {
+ ;
+ }
+ mmio_setbits_32(GPC_PU_PWRHSK, BIT(1));
+#else
+ /* pwrdnreqn_async adbm/adbs of ddr */
+ mmio_clrbits_32(GPC_PU_PWRHSK, BIT(2));
+ while (mmio_read_32(GPC_PU_PWRHSK) & BIT(20)) {
+ ;
+ }
+ mmio_setbits_32(GPC_PU_PWRHSK, BIT(2));
+#endif
+ /* remove PowerOk */
+ mmio_write_32(SRC_DDR1_RCR, 0x8F000008);
+
+ mmio_write_32(CCM_CCGR(5), 0);
+ mmio_write_32(CCM_SRC_CTRL(15), 2);
+
+ /* enable the phy iso */
+ mmio_setbits_32(IMX_GPC_BASE + 0xd40, 1);
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, BIT(5));
+
+ VERBOSE("dram enter retention\n");
+}
+
+void dram_exit_retention(void)
+{
+ VERBOSE("dram exit retention\n");
+ /* assert all reset */
+#if defined(PLAT_imx8mq)
+ mmio_write_32(SRC_DDR2_RCR, 0x8F000003);
+ mmio_write_32(SRC_DDR1_RCR, 0x8F00000F);
+ mmio_write_32(SRC_DDR2_RCR, 0x8F000000);
+#else
+ mmio_write_32(SRC_DDR1_RCR, 0x8F00001F);
+ mmio_write_32(SRC_DDR1_RCR, 0x8F00000F);
+#endif
+ mmio_write_32(CCM_CCGR(5), 2);
+ mmio_write_32(CCM_SRC_CTRL(15), 2);
+
+ /* disable iso */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, BIT(5));
+ mmio_write_32(SRC_DDR1_RCR, 0x8F000006);
+
+ /* wait dram pll locked */
+ while (!(mmio_read_32(DRAM_PLL_CTRL) & BIT(31))) {
+ ;
+ }
+
+ /* ddrc re-init */
+ dram_umctl2_init(dram_info.timing_info);
+
+ /*
+ * Skips the DRAM init routine and starts up in selfrefresh mode
+ * Program INIT0.skip_dram_init = 2'b11
+ */
+ mmio_setbits_32(DDRC_INIT0(0), 0xc0000000);
+ /* Keeps the controller in self-refresh mode */
+ mmio_write_32(DDRC_PWRCTL(0), 0xaa);
+ mmio_write_32(DDRC_DBG1(0), 0x0);
+ mmio_write_32(SRC_DDR1_RCR, 0x8F000004);
+ mmio_write_32(SRC_DDR1_RCR, 0x8F000000);
+
+ /* before write Dynamic reg, sw_done should be 0 */
+ mmio_write_32(DDRC_SWCTL(0), 0x0);
+
+#if !PLAT_imx8mn
+ if (dram_info.dram_type == DDRC_LPDDR4) {
+ mmio_write_32(DDRC_DDR_SS_GPR0, 0x01); /*LPDDR4 mode */
+ }
+#endif /* !PLAT_imx8mn */
+
+ mmio_write_32(DDRC_DFIMISC(0), 0x0);
+
+ /* dram phy re-init */
+ dram_phy_init(dram_info.timing_info);
+
+ /* DWC_DDRPHYA_APBONLY0_MicroContMuxSel */
+ dwc_ddrphy_apb_wr(0xd0000, 0x0);
+ while (dwc_ddrphy_apb_rd(0x20097)) {
+ ;
+ }
+ dwc_ddrphy_apb_wr(0xd0000, 0x1);
+
+ /* before write Dynamic reg, sw_done should be 0 */
+ mmio_write_32(DDRC_SWCTL(0), 0x0);
+ mmio_write_32(DDRC_DFIMISC(0), 0x20);
+ /* wait DFISTAT.dfi_init_complete to 1 */
+ while (!(mmio_read_32(DDRC_DFISTAT(0)) & 0x1)) {
+ ;
+ }
+
+ /* clear DFIMISC.dfi_init_start */
+ mmio_write_32(DDRC_DFIMISC(0), 0x0);
+ /* set DFIMISC.dfi_init_complete_en */
+ mmio_write_32(DDRC_DFIMISC(0), 0x1);
+
+ /* set SWCTL.sw_done to enable quasi-dynamic register programming */
+ mmio_write_32(DDRC_SWCTL(0), 0x1);
+ /* wait SWSTAT.sw_done_ack to 1 */
+ while (!(mmio_read_32(DDRC_SWSTAT(0)) & 0x1)) {
+ ;
+ }
+
+ mmio_write_32(DDRC_PWRCTL(0), 0x88);
+ /* wait STAT to normal state */
+ while (0x1 != (mmio_read_32(DDRC_STAT(0)) & 0x7)) {
+ ;
+ }
+
+ mmio_write_32(DDRC_PCTRL_0(0), 0x1);
+ /* dis_auto-refresh is set to 0 */
+ mmio_write_32(DDRC_RFSHCTL3(0), 0x0);
+
+ /* should check PhyInLP3 pub reg */
+ dwc_ddrphy_apb_wr(0xd0000, 0x0);
+ if (!(dwc_ddrphy_apb_rd(0x90028) & 0x1)) {
+ VERBOSE("PHYInLP3 = 0\n");
+ }
+ dwc_ddrphy_apb_wr(0xd0000, 0x1);
+}
diff --git a/plat/imx/imx8m/ddr/lpddr4_dvfs.c b/plat/imx/imx8m/ddr/lpddr4_dvfs.c
new file mode 100644
index 0000000..2b4f300
--- /dev/null
+++ b/plat/imx/imx8m/ddr/lpddr4_dvfs.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+
+#include <dram.h>
+
+static void lpddr4_mr_write(uint32_t mr_rank, uint32_t mr_addr, uint32_t mr_data)
+{
+ /*
+ * 1. Poll MRSTAT.mr_wr_busy until it is 0. This checks that there
+ * is no outstanding MR transaction. No
+ * writes should be performed to MRCTRL0 and MRCTRL1 if MRSTAT.mr_wr_busy = 1.
+ */
+ while (mmio_read_32(DDRC_MRSTAT(0)) & 0x1)
+ ;
+
+ /*
+ * 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr,
+ * MRCTRL0.mr_rank and (for MRWs)
+ * MRCTRL1.mr_data to define the MR transaction.
+ */
+ mmio_write_32(DDRC_MRCTRL0(0), (mr_rank << 4));
+ mmio_write_32(DDRC_MRCTRL1(0), (mr_addr << 8) | mr_data);
+ mmio_setbits_32(DDRC_MRCTRL0(0), BIT(31));
+}
+
+void lpddr4_swffc(struct dram_info *info, unsigned int init_fsp,
+ unsigned int fsp_index)
+
+{
+ uint32_t mr, emr, emr2, emr3;
+ uint32_t mr11, mr12, mr22, mr14;
+ uint32_t val;
+ uint32_t derate_backup[3];
+ uint32_t (*mr_data)[8];
+
+ /* 1. program targetd UMCTL2_REGS_FREQ1/2/3,already done, skip it. */
+
+ /* 2. MR13.FSP-WR=1, MRW to update MR registers */
+ mr_data = info->mr_table;
+ mr = mr_data[fsp_index][0];
+ emr = mr_data[fsp_index][1];
+ emr2 = mr_data[fsp_index][2];
+ emr3 = mr_data[fsp_index][3];
+ mr11 = mr_data[fsp_index][4];
+ mr12 = mr_data[fsp_index][5];
+ mr22 = mr_data[fsp_index][6];
+ mr14 = mr_data[fsp_index][7];
+
+ val = (init_fsp == 1) ? 0x2 << 6 : 0x1 << 6;
+ emr3 = (emr3 & 0x003f) | val | 0x0d00;
+
+ /* 12. set PWRCTL.selfref_en=0 */
+ mmio_clrbits_32(DDRC_PWRCTL(0), 0xf);
+
+ /* It is more safe to config it here */
+ mmio_clrbits_32(DDRC_DFIPHYMSTR(0), 0x1);
+
+ lpddr4_mr_write(3, 13, emr3);
+ lpddr4_mr_write(3, 1, mr);
+ lpddr4_mr_write(3, 2, emr);
+ lpddr4_mr_write(3, 3, emr2);
+ lpddr4_mr_write(3, 11, mr11);
+ lpddr4_mr_write(3, 12, mr12);
+ lpddr4_mr_write(3, 14, mr14);
+ lpddr4_mr_write(3, 22, mr22);
+
+ do {
+ val = mmio_read_32(DDRC_MRSTAT(0));
+ } while (val & 0x1);
+
+ /* 3. disable AXI ports */
+ mmio_write_32(DDRC_PCTRL_0(0), 0x0);
+
+ /* 4.Poll PSTAT.rd_port_busy_n=0 and PSTAT.wr_port_busy_n=0. */
+ do {
+ val = mmio_read_32(DDRC_PSTAT(0));
+ } while (val != 0);
+
+ /* 6.disable SBRCTL.scrub_en, skip if never enable it */
+ /* 7.poll SBRSTAT.scrub_busy Q2: should skip phy master if never enable it */
+ /* Disable phy master */
+#ifdef DFILP_SPT
+ /* 8. disable DFI LP */
+ /* DFILPCFG0.dfi_lp_en_sr */
+ val = mmio_read_32(DDRC_DFILPCFG0(0));
+ if (val & 0x100) {
+ mmio_write_32(DDRC_DFILPCFG0(0), 0x0);
+ do {
+ val = mmio_read_32(DDRC_DFISTAT(0)); // dfi_lp_ack
+ val2 = mmio_read_32(DDRC_STAT(0)); // operating_mode
+ } while (((val & 0x2) == 0x2) && ((val2 & 0x7) == 3));
+ }
+#endif
+ /* 9. wait until in normal or power down states */
+ do {
+ /* operating_mode */
+ val = mmio_read_32(DDRC_STAT(0));
+ } while (((val & 0x7) != 1) && ((val & 0x7) != 2));
+
+ /* 10. Disable automatic derating: derate_enable */
+ val = mmio_read_32(DDRC_DERATEEN(0));
+ derate_backup[0] = val;
+ mmio_clrbits_32(DDRC_DERATEEN(0), 0x1);
+
+ val = mmio_read_32(DDRC_FREQ1_DERATEEN(0));
+ derate_backup[1] = val;
+ mmio_clrbits_32(DDRC_FREQ1_DERATEEN(0), 0x1);
+
+ val = mmio_read_32(DDRC_FREQ2_DERATEEN(0));
+ derate_backup[2] = val;
+ mmio_clrbits_32(DDRC_FREQ2_DERATEEN(0), 0x1);
+
+ /* 11. disable automatic ZQ calibration */
+ mmio_setbits_32(DDRC_ZQCTL0(0), BIT(31));
+ mmio_setbits_32(DDRC_FREQ1_ZQCTL0(0), BIT(31));
+ mmio_setbits_32(DDRC_FREQ2_ZQCTL0(0), BIT(31));
+
+ /* 12. set PWRCTL.selfref_en=0 */
+ mmio_clrbits_32(DDRC_PWRCTL(0), 0x1);
+
+ /* 13.Poll STAT.operating_mode is in "Normal" (001) or "Power-down" (010) */
+ do {
+ val = mmio_read_32(DDRC_STAT(0));
+ } while (((val & 0x7) != 1) && ((val & 0x7) != 2));
+
+ /* 14-15. trigger SW SR */
+ /* bit 5: selfref_sw, bit 6: stay_in_selfref */
+ mmio_setbits_32(DDRC_PWRCTL(0), 0x60);
+
+ /* 16. Poll STAT.selfref_state in "Self Refresh 1" */
+ do {
+ val = mmio_read_32(DDRC_STAT(0));
+ } while ((val & 0x300) != 0x100);
+
+ /* 17. disable dq */
+ mmio_setbits_32(DDRC_DBG1(0), 0x1);
+
+ /* 18. Poll DBGCAM.wr_data_pipeline_empty and DBGCAM.rd_data_pipeline_empty */
+ do {
+ val = mmio_read_32(DDRC_DBGCAM(0));
+ val &= 0x30000000;
+ } while (val != 0x30000000);
+
+ /* 19. change MR13.FSP-OP to new FSP and MR13.VRCG to high current */
+ emr3 = (((~init_fsp) & 0x1) << 7) | (0x1 << 3) | (emr3 & 0x0077) | 0x0d00;
+ lpddr4_mr_write(3, 13, emr3);
+
+ /* 20. enter SR Power Down */
+ mmio_clrsetbits_32(DDRC_PWRCTL(0), 0x60, 0x20);
+
+ /* 21. Poll STAT.selfref_state is in "SR Power down" */
+ do {
+ val = mmio_read_32(DDRC_STAT(0));
+ } while ((val & 0x300) != 0x200);
+
+ /* 22. set dfi_init_complete_en = 0 */
+
+ /* 23. switch clock */
+ /* set SWCTL.dw_done to 0 */
+ mmio_write_32(DDRC_SWCTL(0), 0x0000);
+
+ /* 24. program frequency mode=1(bit 29), target_frequency=target_freq (bit 29) */
+ mmio_write_32(DDRC_MSTR2(0), fsp_index);
+
+ /* 25. DBICTL for FSP-OP[1], skip it if never enable it */
+
+ /* 26.trigger initialization in the PHY */
+
+ /* Q3: if refresh level is updated, then should program */
+ /* as updating refresh, need to toggle refresh_update_level signal */
+ val = mmio_read_32(DDRC_RFSHCTL3(0));
+ val = val ^ 0x2;
+ mmio_write_32(DDRC_RFSHCTL3(0), val);
+
+ /* Q4: only for legacy PHY, so here can skipped */
+
+ /* dfi_frequency -> 0x1x */
+ val = mmio_read_32(DDRC_DFIMISC(0));
+ val &= 0xFE;
+ val |= (fsp_index << 8);
+ mmio_write_32(DDRC_DFIMISC(0), val);
+ /* dfi_init_start */
+ val |= 0x20;
+ mmio_write_32(DDRC_DFIMISC(0), val);
+
+ /* polling dfi_init_complete de-assert */
+ do {
+ val = mmio_read_32(DDRC_DFISTAT(0));
+ } while ((val & 0x1) == 0x1);
+
+ /* change the clock frequency */
+ dram_clock_switch(info->timing_info->fsp_table[fsp_index], info->bypass_mode);
+
+ /* dfi_init_start de-assert */
+ mmio_clrbits_32(DDRC_DFIMISC(0), 0x20);
+
+ /* polling dfi_init_complete re-assert */
+ do {
+ val = mmio_read_32(DDRC_DFISTAT(0));
+ } while ((val & 0x1) == 0x0);
+
+ /* 27. set ZQCTL0.dis_srx_zqcl = 1 */
+ if (fsp_index == 0) {
+ mmio_setbits_32(DDRC_ZQCTL0(0), BIT(30));
+ } else if (fsp_index == 1) {
+ mmio_setbits_32(DDRC_FREQ1_ZQCTL0(0), BIT(30));
+ } else {
+ mmio_setbits_32(DDRC_FREQ2_ZQCTL0(0), BIT(30));
+ }
+
+ /* 28,29. exit "self refresh power down" to stay "self refresh 2" */
+ /* exit SR power down */
+ mmio_clrsetbits_32(DDRC_PWRCTL(0), 0x60, 0x40);
+ /* 30. Poll STAT.selfref_state in "Self refresh 2" */
+ do {
+ val = mmio_read_32(DDRC_STAT(0));
+ } while ((val & 0x300) != 0x300);
+
+ /* 31. change MR13.VRCG to normal */
+ emr3 = (emr3 & 0x00f7) | 0x0d00;
+ lpddr4_mr_write(3, 13, emr3);
+
+ /* enable PHY master */
+ mmio_write_32(DDRC_DFIPHYMSTR(0), 0x1);
+
+ /* 32. issue ZQ if required: zq_calib_short, bit 4 */
+ /* polling zq_calib_short_busy */
+ mmio_setbits_32(DDRC_DBGCMD(0), 0x10);
+
+ do {
+ val = mmio_read_32(DDRC_DBGSTAT(0));
+ } while ((val & 0x10) != 0x0);
+
+ /* 33. Reset ZQCTL0.dis_srx_zqcl=0 */
+ if (fsp_index == 1)
+ mmio_clrbits_32(DDRC_FREQ1_ZQCTL0(0), BIT(30));
+ else if (fsp_index == 2)
+ mmio_clrbits_32(DDRC_FREQ2_ZQCTL0(0), BIT(30));
+ else
+ mmio_clrbits_32(DDRC_ZQCTL0(0), BIT(30));
+
+ /* set SWCTL.dw_done to 1 and poll SWSTAT.sw_done_ack=1 */
+ mmio_write_32(DDRC_SWCTL(0), 0x1);
+
+ /* wait SWSTAT.sw_done_ack to 1 */
+ do {
+ val = mmio_read_32(DDRC_SWSTAT(0));
+ } while ((val & 0x1) == 0x0);
+
+ /* 34. set PWRCTL.stay_in_selfreh=0, exit SR */
+ mmio_clrbits_32(DDRC_PWRCTL(0), 0x40);
+ /* wait tXSR */
+
+ /* 35. Poll STAT.selfref_state in "Idle" */
+ do {
+ val = mmio_read_32(DDRC_STAT(0));
+ } while ((val & 0x300) != 0x0);
+
+#ifdef DFILP_SPT
+ /* 36. restore dfi_lp.dfi_lp_en_sr */
+ mmio_setbits_32(DDRC_DFILPCFG0(0), BIT(8));
+#endif
+
+ /* 37. re-enable CAM: dis_dq */
+ mmio_clrbits_32(DDRC_DBG1(0), 0x1);
+
+ /* 38. re-enable automatic SR: selfref_en */
+ mmio_setbits_32(DDRC_PWRCTL(0), 0x1);
+
+ /* 39. re-enable automatic ZQ: dis_auto_zq=0 */
+ /* disable automatic ZQ calibration */
+ if (fsp_index == 1)
+ mmio_clrbits_32(DDRC_FREQ1_ZQCTL0(0), BIT(31));
+ else if (fsp_index == 2)
+ mmio_clrbits_32(DDRC_FREQ2_ZQCTL0(0), BIT(31));
+ else
+ mmio_clrbits_32(DDRC_ZQCTL0(0), BIT(31));
+ /* 40. re-emable automatic derating: derate_enable */
+ mmio_write_32(DDRC_DERATEEN(0), derate_backup[0]);
+ mmio_write_32(DDRC_FREQ1_DERATEEN(0), derate_backup[1]);
+ mmio_write_32(DDRC_FREQ2_DERATEEN(0), derate_backup[2]);
+
+ /* 41. write 1 to PCTRL.port_en */
+ mmio_write_32(DDRC_PCTRL_0(0), 0x1);
+
+ /* 42. enable SBRCTL.scrub_en, skip if never enable it */
+}
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c
index 1e55f05..e674d7a 100644
--- a/plat/imx/imx8m/gpc_common.c
+++ b/plat/imx/imx8m/gpc_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
+#include <common/runtime_svc.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
@@ -16,10 +17,14 @@
#include <imx8m_psci.h>
#include <plat_imx8.h>
+#define MAX_PLL_NUM U(10)
+
static uint32_t gpc_imr_offset[] = { IMR1_CORE0_A53, IMR1_CORE1_A53, IMR1_CORE2_A53, IMR1_CORE3_A53, };
DEFINE_BAKERY_LOCK(gpc_lock);
+#define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03
+
#pragma weak imx_set_cpu_pwr_off
#pragma weak imx_set_cpu_pwr_on
#pragma weak imx_set_cpu_lpm
@@ -250,3 +255,54 @@
mmio_clrbits_32(IMX_GPC_BASE + SLPCR, SLPCR_RBC_EN |
(0x3f << SLPCR_RBC_COUNT_SHIFT));
}
+
+struct pll_override {
+ uint32_t reg;
+ uint32_t override_mask;
+};
+
+struct pll_override pll[MAX_PLL_NUM] = {
+ {.reg = 0x0, .override_mask = (1 << 12) | (1 << 8), },
+ {.reg = 0x14, .override_mask = (1 << 12) | (1 << 8), },
+ {.reg = 0x28, .override_mask = (1 << 12) | (1 << 8), },
+ {.reg = 0x50, .override_mask = (1 << 12) | (1 << 8), },
+ {.reg = 0x64, .override_mask = (1 << 10) | (1 << 8), },
+ {.reg = 0x74, .override_mask = (1 << 10) | (1 << 8), },
+ {.reg = 0x84, .override_mask = (1 << 10) | (1 << 8), },
+ {.reg = 0x94, .override_mask = 0x5555500, },
+ {.reg = 0x104, .override_mask = 0x5555500, },
+ {.reg = 0x114, .override_mask = 0x500, },
+};
+
+#define PLL_BYPASS BIT(4)
+void imx_anamix_override(bool enter)
+{
+ unsigned int i;
+
+ /*
+ * bypass all the plls & enable the override bit before
+ * entering DSM mode.
+ */
+ for (i = 0U; i < MAX_PLL_NUM; i++) {
+ if (enter) {
+ mmio_setbits_32(IMX_ANAMIX_BASE + pll[i].reg, PLL_BYPASS);
+ mmio_setbits_32(IMX_ANAMIX_BASE + pll[i].reg, pll[i].override_mask);
+ } else {
+ mmio_clrbits_32(IMX_ANAMIX_BASE + pll[i].reg, PLL_BYPASS);
+ mmio_clrbits_32(IMX_ANAMIX_BASE + pll[i].reg, pll[i].override_mask);
+ }
+ }
+}
+
+int imx_gpc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3)
+{
+ switch (x1) {
+ case FSL_SIP_CONFIG_GPC_PM_DOMAIN:
+ imx_gpc_pm_domain_enable(x2, x3);
+ break;
+ default:
+ return SMC_UNK;
+ }
+
+ return 0;
+}
diff --git a/plat/imx/imx8m/imx8m_caam.c b/plat/imx/imx8m/imx8m_caam.c
index 478005e..644572c 100644
--- a/plat/imx/imx8m/imx8m_caam.c
+++ b/plat/imx/imx8m/imx8m_caam.c
@@ -1,13 +1,16 @@
/*
- * Copyright (c) 2019, NXP. All rights reserved.
+ * Copyright (c) 2019-2022 NXP. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <common/debug.h>
#include <lib/mmio.h>
#include <imx8m_caam.h>
+#define HAB_JR0_DID U(0x8011)
+
void imx8m_caam_init(void)
{
uint32_t sm_cmd;
@@ -20,7 +23,12 @@
mmio_write_32(SM_CMD, sm_cmd);
/* config CAAM JRaMID set MID to Cortex A */
- mmio_write_32(CAAM_JR0MID, CAAM_NS_MID);
+ if (mmio_read_32(CAAM_JR0MID) == HAB_JR0_DID) {
+ NOTICE("Do not release JR0 to NS as it can be used by HAB");
+ } else {
+ mmio_write_32(CAAM_JR0MID, CAAM_NS_MID);
+ }
+
mmio_write_32(CAAM_JR1MID, CAAM_NS_MID);
mmio_write_32(CAAM_JR2MID, CAAM_NS_MID);
diff --git a/plat/imx/imx8m/imx8m_csu.c b/plat/imx/imx8m/imx8m_csu.c
new file mode 100644
index 0000000..2b3a7d9
--- /dev/null
+++ b/plat/imx/imx8m/imx8m_csu.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+
+#include <imx8m_csu.h>
+
+void imx_csu_init(const struct imx_csu_cfg *csu_cfg)
+{
+ const struct imx_csu_cfg *csu = csu_cfg;
+ uint32_t val;
+
+ while (csu->type != CSU_INVALID) {
+ switch (csu->type) {
+ case CSU_CSL:
+ val = mmio_read_32(CSLx_REG(csu->idx));
+ if (val & CSLx_LOCK(csu->idx)) {
+ break;
+ }
+ mmio_clrsetbits_32(CSLx_REG(csu->idx), CSLx_CFG(0xff, csu->idx),
+ CSLx_CFG(csu->csl_level | (csu->lock << 8), csu->idx));
+ break;
+ case CSU_HP:
+ val = mmio_read_32(CSU_HP_REG(csu->idx));
+ if (val & CSU_HP_LOCK(csu->idx)) {
+ break;
+ }
+ mmio_clrsetbits_32(CSU_HP_REG(csu->idx), CSU_HP_CFG(0x1, csu->idx),
+ CSU_HP_CFG(csu->hp | (csu->lock << 0x1), csu->idx));
+ break;
+ case CSU_SA:
+ val = mmio_read_32(CSU_SA_REG(csu->idx));
+ if (val & CSU_SA_LOCK(csu->idx)) {
+ break;
+ }
+ mmio_clrsetbits_32(CSU_SA_REG(csu->idx), CSU_SA_CFG(0x1, csu->idx),
+ CSU_SA_CFG(csu->sa | (csu->lock << 0x1), csu->idx));
+ break;
+ case CSU_HPCONTROL:
+ val = mmio_read_32(CSU_HPCONTROL_REG(csu->idx));
+ if (val & CSU_HPCONTROL_LOCK(csu->idx)) {
+ break;
+ }
+ mmio_clrsetbits_32(CSU_HPCONTROL_REG(csu->idx), CSU_HPCONTROL_CFG(0x1, csu->idx),
+ CSU_HPCONTROL_CFG(csu->hpctrl | (csu->lock << 0x1), csu->idx));
+ break;
+ default:
+ break;
+ }
+
+ csu++;
+ }
+}
diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c
index 9dfd311..4df4f8e 100644
--- a/plat/imx/imx8m/imx8m_psci_common.c
+++ b/plat/imx/imx8m/imx8m_psci_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,7 @@
#include <lib/mmio.h>
#include <lib/psci/psci.h>
+#include <dram.h>
#include <gpc.h>
#include <imx8m_psci.h>
#include <plat_imx8.h>
@@ -118,8 +119,11 @@
if (!is_local_state_run(CLUSTER_PWR_STATE(target_state)))
imx_set_cluster_powerdown(core_id, CLUSTER_PWR_STATE(target_state));
- if (is_local_state_off(SYSTEM_PWR_STATE(target_state)))
+ if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
imx_set_sys_lpm(core_id, true);
+ dram_enter_retention();
+ imx_anamix_override(true);
+ }
}
void imx_domain_suspend_finish(const psci_power_state_t *target_state)
@@ -127,8 +131,11 @@
uint64_t mpidr = read_mpidr_el1();
unsigned int core_id = MPIDR_AFFLVL0_VAL(mpidr);
- if (is_local_state_off(SYSTEM_PWR_STATE(target_state)))
+ if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
+ imx_anamix_override(false);
+ dram_exit_retention();
imx_set_sys_lpm(core_id, false);
+ }
if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) {
imx_clear_rbc_count();
diff --git a/plat/imx/imx8m/imx8mm/gpc.c b/plat/imx/imx8m/imx8mm/gpc.c
index ab59292..cc1cb10 100644
--- a/plat/imx/imx8m/imx8mm/gpc.c
+++ b/plat/imx/imx8m/imx8mm/gpc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,6 +19,332 @@
#include <gpc.h>
#include <imx_sip_svc.h>
+#define MIPI_PWR_REQ BIT(0)
+#define PCIE_PWR_REQ BIT(1)
+#define OTG1_PWR_REQ BIT(2)
+#define OTG2_PWR_REQ BIT(3)
+#define HSIOMIX_PWR_REQ BIT(4)
+#define GPU2D_PWR_REQ BIT(6)
+#define GPUMIX_PWR_REQ BIT(7)
+#define VPUMIX_PWR_REQ BIT(8)
+#define GPU3D_PWR_REQ BIT(9)
+#define DISPMIX_PWR_REQ BIT(10)
+#define VPU_G1_PWR_REQ BIT(11)
+#define VPU_G2_PWR_REQ BIT(12)
+#define VPU_H1_PWR_REQ BIT(13)
+
+#define HSIOMIX_ADB400_SYNC (0x3 << 5)
+#define DISPMIX_ADB400_SYNC BIT(7)
+#define VPUMIX_ADB400_SYNC BIT(8)
+#define GPU3D_ADB400_SYNC BIT(9)
+#define GPU2D_ADB400_SYNC BIT(10)
+#define GPUMIX_ADB400_SYNC BIT(11)
+#define HSIOMIX_ADB400_ACK (0x3 << 23)
+#define DISPMIX_ADB400_ACK BIT(25)
+#define VPUMIX_ADB400_ACK BIT(26)
+#define GPU3D_ADB400_ACK BIT(27)
+#define GPU2D_ADB400_ACK BIT(28)
+#define GPUMIX_ADB400_ACK BIT(29)
+
+#define MIPI_PGC 0xc00
+#define PCIE_PGC 0xc40
+#define OTG1_PGC 0xc80
+#define OTG2_PGC 0xcc0
+#define HSIOMIX_PGC 0xd00
+#define GPU2D_PGC 0xd80
+#define GPUMIX_PGC 0xdc0
+#define VPUMIX_PGC 0xe00
+#define GPU3D_PGC 0xe40
+#define DISPMIX_PGC 0xe80
+#define VPU_G1_PGC 0xec0
+#define VPU_G2_PGC 0xf00
+#define VPU_H1_PGC 0xf40
+
+enum pu_domain_id {
+ HSIOMIX,
+ PCIE,
+ OTG1,
+ OTG2,
+ GPUMIX,
+ VPUMIX,
+ VPU_G1,
+ VPU_G2,
+ VPU_H1,
+ DISPMIX,
+ MIPI,
+ /* below two domain only for ATF internal use */
+ GPU2D,
+ GPU3D,
+ MAX_DOMAINS,
+};
+
+/* PU domain */
+static struct imx_pwr_domain pu_domains[] = {
+ IMX_MIX_DOMAIN(HSIOMIX, false),
+ IMX_PD_DOMAIN(PCIE, false),
+ IMX_PD_DOMAIN(OTG1, true),
+ IMX_PD_DOMAIN(OTG2, true),
+ IMX_MIX_DOMAIN(GPUMIX, false),
+ IMX_MIX_DOMAIN(VPUMIX, false),
+ IMX_PD_DOMAIN(VPU_G1, false),
+ IMX_PD_DOMAIN(VPU_G2, false),
+ IMX_PD_DOMAIN(VPU_H1, false),
+ IMX_MIX_DOMAIN(DISPMIX, false),
+ IMX_PD_DOMAIN(MIPI, false),
+ /* below two domain only for ATF internal use */
+ IMX_MIX_DOMAIN(GPU2D, false),
+ IMX_MIX_DOMAIN(GPU3D, false),
+};
+
+static unsigned int pu_domain_status;
+
+#define GPU_RCR 0x40
+#define VPU_RCR 0x44
+
+#define VPU_CTL_BASE 0x38330000
+#define BLK_SFT_RSTN_CSR 0x0
+#define H1_SFT_RSTN BIT(2)
+#define G1_SFT_RSTN BIT(1)
+#define G2_SFT_RSTN BIT(0)
+
+#define DISP_CTL_BASE 0x32e28000
+
+void vpu_sft_reset_assert(uint32_t domain_id)
+{
+ uint32_t val;
+
+ val = mmio_read_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR);
+
+ switch (domain_id) {
+ case VPU_G1:
+ val &= ~G1_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ case VPU_G2:
+ val &= ~G2_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ case VPU_H1:
+ val &= ~H1_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ default:
+ break;
+ }
+}
+
+void vpu_sft_reset_deassert(uint32_t domain_id)
+{
+ uint32_t val;
+
+ val = mmio_read_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR);
+
+ switch (domain_id) {
+ case VPU_G1:
+ val |= G1_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ case VPU_G2:
+ val |= G2_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ case VPU_H1:
+ val |= H1_SFT_RSTN;
+ mmio_write_32(VPU_CTL_BASE + BLK_SFT_RSTN_CSR, val);
+ break;
+ default:
+ break;
+ }
+}
+
+void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
+{
+ if (domain_id >= MAX_DOMAINS) {
+ return;
+ }
+
+ struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id];
+
+ if (on) {
+ pu_domain_status |= (1 << domain_id);
+
+ if (domain_id == VPU_G1 || domain_id == VPU_G2 ||
+ domain_id == VPU_H1) {
+ vpu_sft_reset_assert(domain_id);
+ }
+
+ /* HSIOMIX has no PU bit, so skip for it */
+ if (domain_id != HSIOMIX) {
+ /* clear the PGC bit */
+ mmio_clrbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
+
+ /* power up the domain */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, pwr_domain->pwr_req);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & pwr_domain->pwr_req) {
+ ;
+ }
+ }
+
+ if (domain_id == VPU_G1 || domain_id == VPU_G2 ||
+ domain_id == VPU_H1) {
+ vpu_sft_reset_deassert(domain_id);
+ /* dealy for a while to make sure reset done */
+ udelay(100);
+ }
+
+ if (domain_id == GPUMIX) {
+ /* assert reset */
+ mmio_write_32(IMX_SRC_BASE + GPU_RCR, 0x1);
+
+ /* power up GPU2D */
+ mmio_clrbits_32(IMX_GPC_BASE + GPU2D_PGC, 0x1);
+
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, GPU2D_PWR_REQ);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & GPU2D_PWR_REQ) {
+ ;
+ }
+
+ udelay(1);
+
+ /* power up GPU3D */
+ mmio_clrbits_32(IMX_GPC_BASE + GPU3D_PGC, 0x1);
+
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, GPU3D_PWR_REQ);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & GPU3D_PWR_REQ) {
+ ;
+ }
+
+ udelay(10);
+ /* release the gpumix reset */
+ mmio_write_32(IMX_SRC_BASE + GPU_RCR, 0x0);
+ udelay(10);
+ }
+
+ /* vpu sft clock enable */
+ if (domain_id == VPUMIX) {
+ mmio_write_32(IMX_SRC_BASE + VPU_RCR, 0x1);
+ udelay(5);
+ mmio_write_32(IMX_SRC_BASE + VPU_RCR, 0x0);
+ udelay(5);
+
+ /* enable all clock */
+ mmio_write_32(VPU_CTL_BASE + 0x4, 0x7);
+ }
+
+ if (domain_id == DISPMIX) {
+ /* special setting for DISPMIX */
+ mmio_write_32(DISP_CTL_BASE + 0x4, 0x1fff);
+ mmio_write_32(DISP_CTL_BASE, 0x7f);
+ mmio_write_32(DISP_CTL_BASE + 0x8, 0x30000);
+ }
+
+ /* handle the ADB400 sync */
+ if (pwr_domain->need_sync) {
+ /* clear adb power down request */
+ mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
+
+ /* wait for adb power request ack */
+ while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
+ ;
+ }
+ }
+
+ if (domain_id == GPUMIX) {
+ /* power up GPU2D ADB */
+ mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU2D_ADB400_SYNC);
+
+ /* wait for adb power request ack */
+ while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU2D_ADB400_ACK)) {
+ ;
+ }
+
+ /* power up GPU3D ADB */
+ mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU3D_ADB400_SYNC);
+
+ /* wait for adb power request ack */
+ while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU3D_ADB400_ACK)) {
+ ;
+ }
+ }
+ } else {
+ pu_domain_status &= ~(1 << domain_id);
+
+ if (domain_id == OTG1 || domain_id == OTG2) {
+ return;
+ }
+
+ /* GPU2D & GPU3D ADB power down */
+ if (domain_id == GPUMIX) {
+ mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU2D_ADB400_SYNC);
+
+ /* wait for adb power request ack */
+ while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU2D_ADB400_ACK)) {
+ ;
+ }
+
+ mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, GPU3D_ADB400_SYNC);
+
+ /* wait for adb power request ack */
+ while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & GPU3D_ADB400_ACK)) {
+ ;
+ }
+ }
+
+ /* handle the ADB400 sync */
+ if (pwr_domain->need_sync) {
+ /* set adb power down request */
+ mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
+
+ /* wait for adb power request ack */
+ while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
+ ;
+ }
+ }
+
+ if (domain_id == GPUMIX) {
+ /* power down GPU2D */
+ mmio_setbits_32(IMX_GPC_BASE + GPU2D_PGC, 0x1);
+
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, GPU2D_PWR_REQ);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & GPU2D_PWR_REQ) {
+ ;
+ }
+
+ /* power down GPU3D */
+ mmio_setbits_32(IMX_GPC_BASE + GPU3D_PGC, 0x1);
+
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, GPU3D_PWR_REQ);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & GPU3D_PWR_REQ) {
+ ;
+ }
+ }
+
+ /* HSIOMIX has no PU bit, so skip for it */
+ if (domain_id != HSIOMIX) {
+ /* set the PGC bit */
+ mmio_setbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
+
+ /* power down the domain */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, pwr_domain->pwr_req);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & pwr_domain->pwr_req) {
+ ;
+ }
+ }
+ }
+}
+
void imx_gpc_init(void)
{
unsigned int val;
@@ -85,7 +411,4 @@
*/
mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1);
-
- /* enable all the power domain by default */
- mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x3fcf);
}
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index 40110d7..ba0db0c 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022 ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,19 +18,26 @@
#include <drivers/generic_delay_timer.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
+#include <dram.h>
#include <gpc.h>
#include <imx_aipstz.h>
#include <imx_uart.h>
#include <imx_rdc.h>
#include <imx8m_caam.h>
+#include <imx8m_csu.h>
#include <plat_imx8.h>
+#define TRUSTY_PARAMS_LEN_BYTES (4096*2)
+
static const mmap_region_t imx_mmap[] = {
MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW),
MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW), /* AIPS map */
+ MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_DEVICE | MT_RW), /* OCRAM_S */
+ MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW), /* DDRMIX */
+ MAP_REGION_FLAT(IMX_VPUMIX_BASE, IMX_VPUMIX_SIZE, MT_DEVICE | MT_RW), /* VPUMIX */
{0},
};
@@ -44,9 +51,11 @@
static const struct imx_rdc_cfg rdc[] = {
/* Master domain assignment */
- RDC_MDAn(0x1, DID1),
+ RDC_MDAn(RDC_MDA_M4, DID1),
/* peripherals domain permission */
+ RDC_PDAPn(RDC_PDAP_UART4, D1R | D1W),
+ RDC_PDAPn(RDC_PDAP_UART2, D0R | D0W),
/* memory region */
@@ -54,6 +63,20 @@
{0},
};
+static const struct imx_csu_cfg csu_cfg[] = {
+ /* peripherals csl setting */
+ CSU_CSLx(0x1, CSU_SEC_LEVEL_0, UNLOCKED),
+
+ /* master HP0~1 */
+
+ /* SA setting */
+
+ /* HP control setting */
+
+ /* Sentinel */
+ {0}
+};
+
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
@@ -109,6 +132,8 @@
imx_rdc_init(rdc);
+ imx_csu_init(csu_cfg);
+
imx8m_caam_init();
console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
@@ -124,7 +149,7 @@
bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-#ifdef SPD_opteed
+#if defined(SPD_opteed) || defined(SPD_trusty)
/* Populate entry point information for BL32 */
SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
@@ -134,6 +159,16 @@
/* Pass TEE base and size to bl33 */
bl33_image_ep_info.args.arg1 = BL32_BASE;
bl33_image_ep_info.args.arg2 = BL32_SIZE;
+
+#ifdef SPD_trusty
+ bl32_image_ep_info.args.arg0 = BL32_SIZE;
+ bl32_image_ep_info.args.arg1 = BL32_BASE;
+#else
+ /* Make sure memory is clean */
+ mmio_write_32(BL32_FDT_OVERLAY_ADDR, 0);
+ bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+ bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+#endif
#endif
bl31_tzc380_setup();
@@ -150,6 +185,9 @@
(BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE),
MT_DEVICE | MT_RW | MT_SECURE);
#endif
+ /* Map TEE memory */
+ mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW);
+
mmap_add(imx_mmap);
init_xlat_tables();
@@ -164,6 +202,9 @@
/* select the CKIL source to 32K OSC */
mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
+ /* Init the dram info */
+ dram_info_init(SAVED_DRAM_TIMING_BASE);
+
plat_gic_driver_init();
plat_gic_init();
@@ -184,3 +225,12 @@
{
return COUNTER_FREQUENCY;
}
+
+#ifdef SPD_trusty
+void plat_trusty_set_boot_args(aapcs64_params_t *args)
+{
+ args->arg0 = BL32_SIZE;
+ args->arg1 = BL32_BASE;
+ args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+}
+#endif
diff --git a/plat/imx/imx8m/imx8mm/include/imx_sec_def.h b/plat/imx/imx8m/imx8mm/include/imx_sec_def.h
new file mode 100644
index 0000000..6215983
--- /dev/null
+++ b/plat/imx/imx8m/imx8mm/include/imx_sec_def.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_SEC_DEF_H
+#define IMX_SEC_DEF_H
+
+/* RDC MDA index */
+enum rdc_mda_idx {
+ RDC_MDA_A53 = 0,
+ RDC_MDA_M4 = 1,
+ RDC_MDA_PCIE_CTRL1 = 2,
+ RDC_MDA_SDMA3p = 3,
+ RDC_MDA_VPU_Decoders = 4,
+ RDC_MDA_LCDIF = 5,
+ RDC_MDA_CSI1 = 6,
+ RDC_MDA_SDMA3b = 7,
+ RDC_MDA_Coresight = 8,
+ RDC_MDA_DAP = 9,
+ RDC_MDA_CAAM = 10,
+ RDC_MDA_SDMA1p = 11,
+ RDC_MDA_SDMA1b = 12,
+ RDC_MDA_APBHDMA = 13,
+ RDC_MDA_NAND = 14,
+ RDC_MDA_uSDHC1 = 15,
+ RDC_MDA_uSDHC2 = 16,
+ RDC_MDA_uSDHC3 = 17,
+ RDC_MDA_GPU = 18,
+ RDC_MDA_USB1 = 19,
+ RDC_MDA_USB2 = 20,
+ RDC_MDA_TESTPORT = 21,
+ RDC_MDA_ENET1_TX = 22,
+ RDC_MDA_ENET1_RX = 23,
+ RDC_MDA_SDMA2p = 24,
+ RDC_MDA_SDMA2b = 24,
+ RDC_MDA_SDMA2_to_SPBA2 = 24,
+ RDC_MDA_SDMA3_to_SPBA2 = 25,
+ RDC_MDA_SDMA1_to_SPBA1 = 26,
+};
+
+/* RDC Peripherals index */
+enum rdc_pdap_idx {
+ RDC_PDAP_GPIO2 = 1,
+ RDC_PDAP_GPIO3 = 2,
+ RDC_PDAP_GPIO4 = 3,
+ RDC_PDAP_GPIO5 = 4,
+ RDC_PDAP_ANA_TSENSOR = 6,
+ RDC_PDAP_ANA_OSC = 7,
+ RDC_PDAP_WDOG1 = 8,
+ RDC_PDAP_WDOG2 = 9,
+ RDC_PDAP_WDOG3 = 10,
+ RDC_PDAP_SDMA3 = 11,
+ RDC_PDAP_SDMA2 = 12,
+ RDC_PDAP_GPT1 = 13,
+ RDC_PDAP_GPT2 = 14,
+ RDC_PDAP_GPT3 = 15,
+ RDC_PDAP_ROMCP = 17,
+ RDC_PDAP_IOMUXC = 19,
+ RDC_PDAP_IOMUXC_GPR = 20,
+ RDC_PDAP_OCOTP_CTRL = 21,
+ RDC_PDAP_ANA_PLL = 22,
+ RDC_PDAP_SNVS_HP = 23,
+ RDC_PDAP_CCM = 24,
+ RDC_PDAP_SRC = 25,
+ RDC_PDAP_GPC = 26,
+ RDC_PDAP_SEMAPHORE1 = 27,
+ RDC_PDAP_SEMAPHORE2 = 28,
+ RDC_PDAP_RDC = 29,
+ RDC_PDAP_CSU = 30,
+ RDC_PDAP_LCDIF = 32,
+ RDC_PDAP_MIPI_DSI = 33,
+ RDC_PDAP_CSI = 34,
+ RDC_PDAP_MIPI_CSI = 35,
+ RDC_PDAP_USB1 = 36,
+ RDC_PDAP_PWM1 = 38,
+ RDC_PDAP_PWM2 = 39,
+ RDC_PDAP_PWM3 = 40,
+ RDC_PDAP_PWM4 = 41,
+ RDC_PDAP_System_Counter_RD = 42,
+ RDC_PDAP_System_Counter_CMP = 43,
+ RDC_PDAP_System_Counter_CTRL = 44,
+ RDC_PDAP_GPT6 = 46,
+ RDC_PDAP_GPT5 = 47,
+ RDC_PDAP_GPT4 = 48,
+ RDC_PDAP_TZASC = 56,
+ RDC_PDAP_USB2 = 59,
+ RDC_PDAP_PERFMON1 = 60,
+ RDC_PDAP_PERFMON2 = 61,
+ RDC_PDAP_PLATFORM_CTRL = 62,
+ RDC_PDAP_QoSC = 63,
+ RDC_PDAP_I2C1 = 66,
+ RDC_PDAP_I2C2 = 67,
+ RDC_PDAP_I2C3 = 68,
+ RDC_PDAP_I2C4 = 69,
+ RDC_PDAP_UART4 = 70,
+ RDC_PDAP_MU_A = 74,
+ RDC_PDAP_MU_B = 75,
+ RDC_PDAP_SEMAPHORE_HS = 76,
+ RDC_PDAP_SAI1 = 78,
+ RDC_PDAP_SAI2 = 79,
+ RDC_PDAP_SAI3 = 80,
+ RDC_PDAP_SAI5 = 82,
+ RDC_PDAP_SAI6 = 83,
+ RDC_PDAP_uSDHC1 = 84,
+ RDC_PDAP_uSDHC2 = 85,
+ RDC_PDAP_uSDHC3 = 86,
+ RDC_PDAP_PCIE_PHY1 = 88,
+ RDC_PDAP_SPBA2 = 90,
+ RDC_PDAP_QSPI = 91,
+ RDC_PDAP_SDMA1 = 93,
+ RDC_PDAP_ENET1 = 94,
+ RDC_PDAP_SPDIF1 = 97,
+ RDC_PDAP_eCSPI1 = 98,
+ RDC_PDAP_eCSPI2 = 99,
+ RDC_PDAP_eCSPI3 = 100,
+ RDC_PDAP_MICFIL = 101,
+ RDC_PDAP_UART1 = 102,
+ RDC_PDAP_UART3 = 104,
+ RDC_PDAP_UART2 = 105,
+ RDC_PDAP_SPDIF2 = 106,
+ RDC_PDAP_SPBA1 = 111,
+ RDC_PDAP_CAAM = 114,
+};
+
+enum csu_csl_idx {
+ CSU_CSL_GPIO1 = 0,
+ CSU_CSL_GPIO2 = 1,
+ CSU_CSL_GPIO3 = 2,
+ CSU_CSL_GPIO4 = 3,
+ CSU_CSL_GPIO5 = 4,
+ CSU_CSL_ANA_TSENSOR = 6,
+ CSU_CSL_ANA_OSC = 7,
+ CSU_CSL_WDOG1 = 8,
+ CSU_CSL_WDOG2 = 9,
+ CSU_CSL_WDOG3 = 10,
+ CSU_CSL_SDMA2 = 12,
+ CSU_CSL_GPT1 = 13,
+ CSU_CSL_GPT2 = 14,
+ CSU_CSL_GPT3 = 15,
+ CSU_CSL_ROMCP = 17,
+ CSU_CSL_LCDIF = 18,
+ CSU_CSL_IOMUXC = 19,
+ CSU_CSL_IOMUXC_GPR = 20,
+ CSU_CSL_OCOTP_CTRL = 21,
+ CSU_CSL_ANA_PLL = 22,
+ CSU_CSL_SNVS_HP = 23,
+ CSU_CSL_CCM = 24,
+ CSU_CSL_SRC = 25,
+ CSU_CSL_GPC = 26,
+ CSU_CSL_SEMAPHORE1 = 27,
+ CSU_CSL_SEMAPHORE2 = 28,
+ CSU_CSL_RDC = 29,
+ CSU_CSL_CSU = 30,
+ CSU_CSL_DC_MST0 = 32,
+ CSU_CSL_DC_MST1 = 33,
+ CSU_CSL_DC_MST2 = 34,
+ CSU_CSL_DC_MST3 = 35,
+ CSU_CSL_PWM1 = 38,
+ CSU_CSL_PWM2 = 39,
+ CSU_CSL_PWM3 = 40,
+ CSU_CSL_PWM4 = 41,
+ CSU_CSL_System_Counter_RD = 42,
+ CSU_CSL_System_Counter_CMP = 43,
+ CSU_CSL_System_Counter_CTRL = 44,
+ CSU_CSL_GPT6 = 46,
+ CSU_CSL_GPT5 = 47,
+ CSU_CSL_GPT4 = 48,
+ CSU_CSL_TZASC = 56,
+ CSU_CSL_MTR = 59,
+ CSU_CSL_PERFMON1 = 60,
+ CSU_CSL_PERFMON2 = 61,
+ CSU_CSL_PLATFORM_CTRL = 62,
+ CSU_CSL_QoSC = 63,
+ CSU_CSL_MIPI_PHY = 64,
+ CSU_CSL_MIPI_DSI = 65,
+ CSU_CSL_I2C1 = 66,
+ CSU_CSL_I2C2 = 67,
+ CSU_CSL_I2C3 = 68,
+ CSU_CSL_I2C4 = 69,
+ CSU_CSL_UART4 = 70,
+ CSU_CSL_MIPI_CSI1 = 71,
+ CSU_CSL_MIPI_CSI_PHY1 = 72,
+ CSU_CSL_CSI1 = 73,
+ CSU_CSL_MU_A = 74,
+ CSU_CSL_MU_B = 75,
+ CSU_CSL_SEMAPHORE_HS = 76,
+ CSU_CSL_SAI1 = 78,
+ CSU_CSL_SAI6 = 80,
+ CSU_CSL_SAI5 = 81,
+ CSU_CSL_SAI4 = 82,
+ CSU_CSL_uSDHC1 = 84,
+ CSU_CSL_uSDHC2 = 85,
+ CSU_CSL_MIPI_CSI2 = 86,
+ CSU_CSL_MIPI_CSI_PHY2 = 87,
+ CSU_CSL_CSI2 = 88,
+ CSU_CSL_SPBA2 = 90,
+ CSU_CSL_QSPI = 91,
+ CSU_CSL_SDMA1 = 93,
+ CSU_CSL_ENET1 = 94,
+ CSU_CSL_SPDIF1 = 97,
+ CSU_CSL_eCSPI1 = 98,
+ CSU_CSL_eCSPI2 = 99,
+ CSU_CSL_eCSPI3 = 100,
+ CSU_CSL_UART1 = 102,
+ CSU_CSL_UART3 = 104,
+ CSU_CSL_UART2 = 105,
+ CSU_CSL_SPDIF2 = 106,
+ CSU_CSL_SAI2 = 107,
+ CSU_CSL_SAI3 = 108,
+ CSU_CSL_SPBA1 = 111,
+ CSU_CSL_CAAM = 114,
+};
+
+#endif /* IMX_SEC_DEF_H */
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 300ef9e..84d86b9 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -1,11 +1,12 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <common/tbbr/tbbr_img_def.h>
+#include <lib/utils_def.h>
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
@@ -59,6 +60,8 @@
#define PLAT_NS_IMAGE_OFFSET U(0x40200000)
#define PLAT_NS_IMAGE_SIZE U(0x00200000)
+#define BL32_FDT_OVERLAY_ADDR (PLAT_NS_IMAGE_OFFSET + 0x3000000)
+
/* GICv3 base address */
#define PLAT_GICD_BASE U(0x38800000)
#define PLAT_GICR_BASE U(0x38880000)
@@ -83,7 +86,7 @@
#define IMX_AIPSTZ4 U(0x32df0000)
#define IMX_AIPS_BASE U(0x30000000)
-#define IMX_AIPS_SIZE U(0xC00000)
+#define IMX_AIPS_SIZE U(0x3000000)
#define IMX_GPV_BASE U(0x32000000)
#define IMX_GPV_SIZE U(0x800000)
#define IMX_AIPS1_BASE U(0x30200000)
@@ -103,7 +106,10 @@
#define IMX_DDRC_BASE U(0x3d400000)
#define IMX_DDRPHY_BASE U(0x3c000000)
#define IMX_DDR_IPS_BASE U(0x3d000000)
+#define IMX_DDR_IPS_SIZE U(0x1800000)
#define IMX_ROM_BASE U(0x0)
+#define IMX_VPUMIX_BASE U(0x38330000)
+#define IMX_VPUMIX_SIZE U(0x100000)
#define GPV_BASE U(0x32000000)
#define GPV_SIZE U(0x800000)
@@ -138,12 +144,14 @@
#define GPR_TZASC_EN_LOCK BIT(16)
#define ANAMIX_MISC_CTL U(0x124)
+#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50)
#define MAX_CSU_NUM U(64)
#define OCRAM_S_BASE U(0x00180000)
#define OCRAM_S_SIZE U(0x8000)
#define OCRAM_S_LIMIT (OCRAM_S_BASE + OCRAM_S_SIZE)
+#define SAVED_DRAM_TIMING_BASE OCRAM_S_BASE
#define COUNTER_FREQUENCY 8000000 /* 8MHz */
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index cd8de89..e3e5c0c 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -1,8 +1,11 @@
#
-# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
+#
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
PLAT_INCLUDES := -Iplat/imx/common/include \
-Iplat/imx/imx8m/include \
@@ -16,6 +19,12 @@
include lib/libfdt/libfdt.mk
+IMX_DRAM_SOURCES := plat/imx/imx8m/ddr/dram.c \
+ plat/imx/imx8m/ddr/clock.c \
+ plat/imx/imx8m/ddr/dram_retention.c \
+ plat/imx/imx8m/ddr/ddr4_dvfs.c \
+ plat/imx/imx8m/ddr/lpddr4_dvfs.c
+
IMX_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
@@ -25,6 +34,7 @@
plat/imx/imx8m/gpc_common.c \
plat/imx/imx8m/imx_aipstz.c \
plat/imx/imx8m/imx_rdc.c \
+ plat/imx/imx8m/imx8m_csu.c \
plat/imx/imx8m/imx8m_caam.c \
plat/imx/imx8m/imx8m_psci_common.c \
plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c \
@@ -34,14 +44,12 @@
plat/imx/common/imx_sip_handler.c \
plat/imx/common/imx_sip_svc.c \
plat/imx/common/imx_uart_console.S \
- plat/imx/common/imx_ehf.c \
- plat/imx/common/imx_sdei.c \
- lib/xlat_tables/aarch64/xlat_tables.c \
- lib/xlat_tables/xlat_tables_common.c \
lib/cpus/aarch64/cortex_a53.S \
drivers/arm/tzc/tzc380.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ ${XLAT_TABLES_LIB_SRCS} \
+ ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES}
ifeq (${NEED_BL2},yes)
@@ -124,13 +132,13 @@
$(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
@if [ ! -f $(ROT_KEY) ]; then \
- openssl genrsa 2048 > $@ 2>/dev/null; \
+ ${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
fi
$(ROTPK_HASH): $(ROT_KEY)
@echo " OPENSSL $@"
- $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
- openssl dgst -sha256 -binary > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
endif
USE_COHERENT_MEM := 1
@@ -150,16 +158,26 @@
IMX_BOOT_UART_BASE ?= 0x30890000
$(eval $(call add_define,IMX_BOOT_UART_BASE))
-EL3_EXCEPTION_HANDLING := 1
-SDEI_SUPPORT := 1
+EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
+ifeq (${SDEI_SUPPORT}, 1)
+BL31_SOURCES += plat/imx/common/imx_ehf.c \
+ plat/imx/common/imx_sdei.c
+endif
ifeq (${MEASURED_BOOT},1)
MEASURED_BOOT_MK := drivers/measured_boot/event_log/event_log.mk
$(info Including ${MEASURED_BOOT_MK})
include ${MEASURED_BOOT_MK}
+ifneq (${MBOOT_EL_HASH_ALG}, sha256)
+ $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
+endif
+
BL2_SOURCES += plat/imx/imx8m/imx8m_measured_boot.c \
plat/imx/imx8m/imx8m_dyn_cfg_helpers.c \
${EVENT_LOG_SOURCES}
+endif
+ifeq (${SPD},trusty)
+ BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
endif
diff --git a/plat/imx/imx8m/imx8mn/gpc.c b/plat/imx/imx8m/imx8mn/gpc.c
index 37d4226..4e05297 100644
--- a/plat/imx/imx8m/imx8mn/gpc.c
+++ b/plat/imx/imx8m/imx8mn/gpc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 NXP
+ * Copyright 2019-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,6 +21,124 @@
#define CCGR(x) (0x4000 + (x) * 0x10)
+#define MIPI_PWR_REQ BIT(0)
+#define OTG1_PWR_REQ BIT(2)
+#define HSIOMIX_PWR_REQ BIT(4)
+#define GPUMIX_PWR_REQ BIT(7)
+#define DISPMIX_PWR_REQ BIT(10)
+
+#define HSIOMIX_ADB400_SYNC BIT(5)
+#define DISPMIX_ADB400_SYNC BIT(7)
+#define GPUMIX_ADB400_SYNC (0x5 << 9)
+#define HSIOMIX_ADB400_ACK BIT(23)
+#define DISPMIX_ADB400_ACK BIT(25)
+#define GPUMIX_ADB400_ACK (0x5 << 27)
+
+#define MIPI_PGC 0xc00
+#define OTG1_PGC 0xc80
+#define HSIOMIX_PGC 0xd00
+#define GPUMIX_PGC 0xdc0
+#define DISPMIX_PGC 0xe80
+
+enum pu_domain_id {
+ HSIOMIX,
+ OTG1 = 2,
+ GPUMIX = 4,
+ DISPMIX = 9,
+ MIPI,
+};
+
+/* PU domain, add some hole to minimize the uboot change */
+static struct imx_pwr_domain pu_domains[11] = {
+ [HSIOMIX] = IMX_MIX_DOMAIN(HSIOMIX, false),
+ [OTG1] = IMX_PD_DOMAIN(OTG1, true),
+ [GPUMIX] = IMX_MIX_DOMAIN(GPUMIX, false),
+ [DISPMIX] = IMX_MIX_DOMAIN(DISPMIX, false),
+ [MIPI] = IMX_PD_DOMAIN(MIPI, true),
+};
+
+static unsigned int pu_domain_status;
+
+void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
+{
+ if (domain_id > MIPI) {
+ return;
+ }
+
+ struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id];
+
+ if (on) {
+ if (pwr_domain->need_sync) {
+ pu_domain_status |= (1 << domain_id);
+ }
+
+ /* HSIOMIX has no PU bit, so skip for it */
+ if (domain_id != HSIOMIX) {
+ /* clear the PGC bit */
+ mmio_clrbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
+
+ /* power up the domain */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_UP_TRG, pwr_domain->pwr_req);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_UP_TRG) & pwr_domain->pwr_req) {
+ ;
+ }
+ }
+
+ if (domain_id == DISPMIX) {
+ /* de-reset bus_blk clk and
+ * enable bus_blk clk
+ */
+ mmio_write_32(0x32e28000, 0x100);
+ mmio_write_32(0x32e28004, 0x100);
+ }
+
+ /* handle the ADB400 sync */
+ if (pwr_domain->need_sync) {
+ /* clear adb power down request */
+ mmio_setbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
+
+ /* wait for adb power request ack */
+ while (!(mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
+ ;
+ }
+ }
+ } else {
+ pu_domain_status &= ~(1 << domain_id);
+
+ if (domain_id == OTG1) {
+ return;
+ }
+
+ /* handle the ADB400 sync */
+ if (pwr_domain->need_sync) {
+
+ /* set adb power down request */
+ mmio_clrbits_32(IMX_GPC_BASE + GPC_PU_PWRHSK, pwr_domain->adb400_sync);
+
+ /* wait for adb power request ack */
+ while ((mmio_read_32(IMX_GPC_BASE + GPC_PU_PWRHSK) & pwr_domain->adb400_ack)) {
+ ;
+ }
+ }
+
+ /* HSIOMIX has no PU bit, so skip for it */
+ if (domain_id != HSIOMIX) {
+ /* set the PGC bit */
+ mmio_setbits_32(IMX_GPC_BASE + pwr_domain->pgc_offset, 0x1);
+
+ /* power down the domain */
+ mmio_setbits_32(IMX_GPC_BASE + PU_PGC_DN_TRG, pwr_domain->pwr_req);
+
+ /* wait for power request done */
+ while (mmio_read_32(IMX_GPC_BASE + PU_PGC_DN_TRG) & pwr_domain->pwr_req) {
+ ;
+ }
+ }
+ }
+}
+
void imx_gpc_init(void)
{
unsigned int val;
@@ -86,9 +204,4 @@
* only need to do it once.
*/
mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
-
- /* enable all the power domain by default */
- for (i = 0; i < 103; i++)
- mmio_write_32(IMX_CCM_BASE + CCGR(i), 0x3);
- mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x485);
}
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index d4705ee..5d2a64e 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 NXP
+ * Copyright 2019-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,14 +19,18 @@
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
+#include <dram.h>
#include <gpc.h>
#include <imx_aipstz.h>
#include <imx_uart.h>
#include <imx_rdc.h>
#include <imx8m_caam.h>
+#include <imx8m_csu.h>
#include <platform_def.h>
#include <plat_imx8.h>
+#define TRUSTY_PARAMS_LEN_BYTES (4096*2)
+
static const mmap_region_t imx_mmap[] = {
GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP, {0},
};
@@ -41,9 +45,11 @@
static const struct imx_rdc_cfg rdc[] = {
/* Master domain assignment */
- RDC_MDAn(0x1, DID1),
+ RDC_MDAn(RDC_MDA_M7, DID1),
/* peripherals domain permission */
+ RDC_PDAPn(RDC_PDAP_UART4, D1R | D1W),
+ RDC_PDAPn(RDC_PDAP_UART2, D0R | D0W),
/* memory region */
RDC_MEM_REGIONn(16, 0x0, 0x0, 0xff),
@@ -54,6 +60,22 @@
{0},
};
+static const struct imx_csu_cfg csu_cfg[] = {
+ /* peripherals csl setting */
+ CSU_CSLx(CSU_CSL_OCRAM, CSU_SEC_LEVEL_2, UNLOCKED),
+ CSU_CSLx(CSU_CSL_OCRAM_S, CSU_SEC_LEVEL_2, UNLOCKED),
+
+ /* master HP0~1 */
+
+ /* SA setting */
+
+ /* HP control setting */
+
+ /* Sentinel */
+ {0}
+};
+
+
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
@@ -98,6 +120,7 @@
u_register_t arg2, u_register_t arg3)
{
static console_t console;
+ unsigned int val;
int i;
/* Enable CSU NS access permission */
@@ -109,6 +132,13 @@
imx_rdc_init(rdc);
+ imx_csu_init(csu_cfg);
+
+ /* config the ocram memory range for secure access */
+ mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, 0x4c1);
+ val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
+ mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
+
imx8m_caam_init();
console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
@@ -124,7 +154,7 @@
bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-#ifdef SPD_opteed
+#if defined(SPD_opteed) || defined(SPD_trusty)
/* Populate entry point information for BL32 */
SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
@@ -134,6 +164,16 @@
/* Pass TEE base and size to bl33 */
bl33_image_ep_info.args.arg1 = BL32_BASE;
bl33_image_ep_info.args.arg2 = BL32_SIZE;
+
+#ifdef SPD_trusty
+ bl32_image_ep_info.args.arg0 = BL32_SIZE;
+ bl32_image_ep_info.args.arg1 = BL32_BASE;
+#else
+ /* Make sure memory is clean */
+ mmio_write_32(BL32_FDT_OVERLAY_ADDR, 0);
+ bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+ bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+#endif
#endif
bl31_tzc380_setup();
@@ -150,6 +190,10 @@
(BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE),
MT_DEVICE | MT_RW | MT_SECURE);
#endif
+
+ /* Map TEE memory */
+ mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW);
+
mmap_add(imx_mmap);
init_xlat_tables();
@@ -164,6 +208,9 @@
/* select the CKIL source to 32K OSC */
mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
+ /* Init the dram info */
+ dram_info_init(SAVED_DRAM_TIMING_BASE);
+
plat_gic_driver_init();
plat_gic_init();
@@ -184,3 +231,12 @@
{
return COUNTER_FREQUENCY;
}
+
+#ifdef SPD_trusty
+void plat_trusty_set_boot_args(aapcs64_params_t *args)
+{
+ args->arg0 = BL32_SIZE;
+ args->arg1 = BL32_BASE;
+ args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+}
+#endif
diff --git a/plat/imx/imx8m/imx8mn/include/imx_sec_def.h b/plat/imx/imx8m/imx8mn/include/imx_sec_def.h
new file mode 100644
index 0000000..0ef14a9
--- /dev/null
+++ b/plat/imx/imx8m/imx8mn/include/imx_sec_def.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_SEC_DEF_H
+#define IMX_SEC_DEF_H
+
+/* RDC MDA index */
+enum rdc_mda_idx {
+ RDC_MDA_A53 = 0,
+ RDC_MDA_M7 = 1,
+ RDC_MDA_SDMA3p = 3,
+ RDC_MDA_LCDIF = 5,
+ RDC_MDA_ISI = 6,
+ RDC_MDA_SDMA3b = 7,
+ RDC_MDA_Coresight = 8,
+ RDC_MDA_DAP = 9,
+ RDC_MDA_CAAM = 10,
+ RDC_MDA_SDMA1p = 11,
+ RDC_MDA_SDMA1b = 12,
+ RDC_MDA_APBHDMA = 13,
+ RDC_MDA_RAWNAND = 14,
+ RDC_MDA_uSDHC1 = 15,
+ RDC_MDA_uSDHC2 = 16,
+ RDC_MDA_uSDHC3 = 17,
+ RDC_MDA_GPU = 18,
+ RDC_MDA_USB1 = 19,
+ RDC_MDA_TESTPORT = 21,
+ RDC_MDA_ENET1_TX = 22,
+ RDC_MDA_ENET1_RX = 23,
+ RDC_MDA_SDMA2 = 24,
+};
+
+/* RDC Peripherals index */
+enum rdc_pdap_idx {
+ RDC_PDAP_GPIO1 = 0,
+ RDC_PDAP_GPIO2 = 1,
+ RDC_PDAP_GPIO3 = 2,
+ RDC_PDAP_GPIO4 = 3,
+ RDC_PDAP_GPIO5 = 4,
+ RDC_PDAP_ANA_TSENSOR = 6,
+ RDC_PDAP_ANA_OSC = 7,
+ RDC_PDAP_WDOG1 = 8,
+ RDC_PDAP_WDOG2 = 9,
+ RDC_PDAP_WDOG3 = 10,
+ RDC_PDAP_SDMA3 = 11,
+ RDC_PDAP_SDMA2 = 12,
+ RDC_PDAP_GPT1 = 13,
+ RDC_PDAP_GPT2 = 14,
+ RDC_PDAP_GPT3 = 15,
+ RDC_PDAP_ROMCP = 17,
+ RDC_PDAP_IOMUXC = 19,
+ RDC_PDAP_IOMUXC_GPR = 20,
+ RDC_PDAP_OCOTP_CTRL = 21,
+ RDC_PDAP_ANA_PLL = 22,
+ RDC_PDAP_SNVS_HP = 23,
+ RDC_PDAP_CCM = 24,
+ RDC_PDAP_SRC = 25,
+ RDC_PDAP_GPC = 26,
+ RDC_PDAP_SEMAPHORE1 = 27,
+ RDC_PDAP_SEMAPHORE2 = 28,
+ RDC_PDAP_RDC = 29,
+ RDC_PDAP_CSU = 30,
+ RDC_PDAP_LCDIF = 32,
+ RDC_PDAP_MIPI_DSI = 33,
+ RDC_PDAP_ISI = 34,
+ RDC_PDAP_MIPI_CSI = 35,
+ RDC_PDAP_USB1 = 36,
+ RDC_PDAP_PWM1 = 38,
+ RDC_PDAP_PWM2 = 39,
+ RDC_PDAP_PWM3 = 40,
+ RDC_PDAP_PWM4 = 41,
+ RDC_PDAP_System_Counter_RD = 42,
+ RDC_PDAP_System_Counter_CMP = 43,
+ RDC_PDAP_System_Counter_CTRL = 44,
+ RDC_PDAP_GPT6 = 46,
+ RDC_PDAP_GPT5 = 47,
+ RDC_PDAP_GPT4 = 48,
+ RDC_PDAP_TZASC = 56,
+ RDC_PDAP_PERFMON1 = 60,
+ RDC_PDAP_PERFMON2 = 61,
+ RDC_PDAP_PLATFORM_CTRL = 62,
+ RDC_PDAP_QoSC = 63,
+ RDC_PDAP_I2C1 = 66,
+ RDC_PDAP_I2C2 = 67,
+ RDC_PDAP_I2C3 = 68,
+ RDC_PDAP_I2C4 = 69,
+ RDC_PDAP_UART4 = 70,
+ RDC_PDAP_MU_A = 74,
+ RDC_PDAP_MU_B = 75,
+ RDC_PDAP_SEMAPHORE_HS = 76,
+ RDC_PDAP_SAI2 = 79,
+ RDC_PDAP_SAI3 = 80,
+ RDC_PDAP_SAI5 = 82,
+ RDC_PDAP_SAI6 = 83,
+ RDC_PDAP_uSDHC1 = 84,
+ RDC_PDAP_uSDHC2 = 85,
+ RDC_PDAP_uSDHC3 = 86,
+ RDC_PDAP_SAI7 = 87,
+ RDC_PDAP_SPBA2 = 90,
+ RDC_PDAP_QSPI = 91,
+ RDC_PDAP_SDMA1 = 93,
+ RDC_PDAP_ENET1 = 94,
+ RDC_PDAP_SPDIF1 = 97,
+ RDC_PDAP_eCSPI1 = 98,
+ RDC_PDAP_eCSPI2 = 99,
+ RDC_PDAP_eCSPI3 = 100,
+ RDC_PDAP_MICFIL = 101,
+ RDC_PDAP_UART1 = 102,
+ RDC_PDAP_UART3 = 104,
+ RDC_PDAP_UART2 = 105,
+ RDC_PDAP_ASRC = 107,
+ RDC_PDAP_SPBA1 = 111,
+ RDC_PDAP_CAAM = 114,
+};
+
+enum csu_csl_idx {
+ CSU_CSL_GPIO1 = 0,
+ CSU_CSL_GPIO2 = 1,
+ CSU_CSL_GPIO3 = 2,
+ CSU_CSL_GPIO4 = 3,
+ CSU_CSL_GPIO5 = 4,
+ CSU_CSL_ANA_TSENSOR = 6,
+ CSU_CSL_ANA_OSC = 7,
+ CSU_CSL_WDOG1 = 8,
+ CSU_CSL_WDOG2 = 9,
+ CSU_CSL_WDOG3 = 10,
+ CSU_CSL_SDMA2 = 12,
+ CSU_CSL_GPT1 = 13,
+ CSU_CSL_GPT2 = 14,
+ CSU_CSL_GPT3 = 15,
+ CSU_CSL_ROMCP = 17,
+ CSU_CSL_LCDIF = 18,
+ CSU_CSL_IOMUXC = 19,
+ CSU_CSL_IOMUXC_GPR = 20,
+ CSU_CSL_OCOTP_CTRL = 21,
+ CSU_CSL_ANA_PLL = 22,
+ CSU_CSL_SNVS_HP = 23,
+ CSU_CSL_CCM = 24,
+ CSU_CSL_SRC = 25,
+ CSU_CSL_GPC = 26,
+ CSU_CSL_SEMAPHORE1 = 27,
+ CSU_CSL_SEMAPHORE2 = 28,
+ CSU_CSL_RDC = 29,
+ CSU_CSL_CSU = 30,
+ CSU_CSL_DC_MST0 = 32,
+ CSU_CSL_DC_MST1 = 33,
+ CSU_CSL_DC_MST2 = 34,
+ CSU_CSL_DC_MST3 = 35,
+ CSU_CSL_PWM1 = 38,
+ CSU_CSL_PWM2 = 39,
+ CSU_CSL_PWM3 = 40,
+ CSU_CSL_PWM4 = 41,
+ CSU_CSL_System_Counter_RD = 42,
+ CSU_CSL_System_Counter_CMP = 43,
+ CSU_CSL_System_Counter_CTRL = 44,
+ CSU_CSL_GPT6 = 46,
+ CSU_CSL_GPT5 = 47,
+ CSU_CSL_GPT4 = 48,
+ CSU_CSL_TZASC = 56,
+ CSU_CSL_MTR = 59,
+ CSU_CSL_PERFMON1 = 60,
+ CSU_CSL_PERFMON2 = 61,
+ CSU_CSL_PLATFORM_CTRL = 62,
+ CSU_CSL_QoSC = 63,
+ CSU_CSL_MIPI_PHY = 64,
+ CSU_CSL_MIPI_DSI = 65,
+ CSU_CSL_I2C1 = 66,
+ CSU_CSL_I2C2 = 67,
+ CSU_CSL_I2C3 = 68,
+ CSU_CSL_I2C4 = 69,
+ CSU_CSL_UART4 = 70,
+ CSU_CSL_MIPI_CSI1 = 71,
+ CSU_CSL_MIPI_CSI_PHY1 = 72,
+ CSU_CSL_CSI1 = 73,
+ CSU_CSL_MU_A = 74,
+ CSU_CSL_MU_B = 75,
+ CSU_CSL_SEMAPHORE_HS = 76,
+ CSU_CSL_SAI1 = 78,
+ CSU_CSL_SAI6 = 80,
+ CSU_CSL_SAI5 = 81,
+ CSU_CSL_SAI4 = 82,
+ CSU_CSL_uSDHC1 = 84,
+ CSU_CSL_uSDHC2 = 85,
+ CSU_CSL_MIPI_CSI2 = 86,
+ CSU_CSL_MIPI_CSI_PHY2 = 87,
+ CSU_CSL_CSI2 = 88,
+ CSU_CSL_SPBA2 = 90,
+ CSU_CSL_QSPI = 91,
+ CSU_CSL_SDMA1 = 93,
+ CSU_CSL_ENET1 = 94,
+ CSU_CSL_SPDIF1 = 97,
+ CSU_CSL_eCSPI1 = 98,
+ CSU_CSL_eCSPI2 = 99,
+ CSU_CSL_eCSPI3 = 100,
+ CSU_CSL_UART1 = 102,
+ CSU_CSL_UART3 = 104,
+ CSU_CSL_UART2 = 105,
+ CSU_CSL_SPDIF2 = 106,
+ CSU_CSL_SAI2 = 107,
+ CSU_CSL_SAI3 = 108,
+ CSU_CSL_SPBA1 = 111,
+ CSU_CSL_CAAM = 114,
+ CSU_CSL_OCRAM = 118,
+ CSU_CSL_OCRAM_S = 119,
+};
+
+#endif /* IMX_SEC_DEF_H */
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index 9c46d8d..dbb4416 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 NXP
+ * Copyright 2020-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,8 @@
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <lib/utils_def.h>
+
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
@@ -45,6 +47,8 @@
/* non-secure uboot base */
#define PLAT_NS_IMAGE_OFFSET U(0x40200000)
+#define BL32_FDT_OVERLAY_ADDR (PLAT_NS_IMAGE_OFFSET + 0x3000000)
+
/* GICv3 base address */
#define PLAT_GICD_BASE U(0x38800000)
#define PLAT_GICR_BASE U(0x38880000)
@@ -68,7 +72,7 @@
#define IMX_AIPSTZ4 U(0x32df0000)
#define IMX_AIPS_BASE U(0x30000000)
-#define IMX_AIPS_SIZE U(0xC00000)
+#define IMX_AIPS_SIZE U(0x3000000)
#define IMX_GPV_BASE U(0x32000000)
#define IMX_GPV_SIZE U(0x800000)
#define IMX_AIPS1_BASE U(0x30200000)
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
index 2087089..0f3ad1a 100644
--- a/plat/imx/imx8m/imx8mn/platform.mk
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright 2019-2020 NXP
+# Copyright 2019-2022 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -13,6 +13,13 @@
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
+IMX_DRAM_SOURCES := plat/imx/imx8m/ddr/dram.c \
+ plat/imx/imx8m/ddr/clock.c \
+ plat/imx/imx8m/ddr/dram_retention.c \
+ plat/imx/imx8m/ddr/ddr4_dvfs.c \
+ plat/imx/imx8m/ddr/lpddr4_dvfs.c
+
+
IMX_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
@@ -23,6 +30,7 @@
plat/imx/imx8m/imx_aipstz.c \
plat/imx/imx8m/imx_rdc.c \
plat/imx/imx8m/imx8m_caam.c \
+ plat/imx/imx8m/imx8m_csu.c \
plat/imx/imx8m/imx8m_psci_common.c \
plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c \
plat/imx/imx8m/imx8mn/imx8mn_psci.c \
@@ -31,12 +39,11 @@
plat/imx/common/imx_sip_handler.c \
plat/imx/common/imx_sip_svc.c \
plat/imx/common/imx_uart_console.S \
- plat/imx/common/imx_ehf.c \
- plat/imx/common/imx_sdei.c \
lib/cpus/aarch64/cortex_a53.S \
drivers/arm/tzc/tzc380.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES} \
${XLAT_TABLES_LIB_SRCS}
@@ -57,5 +64,12 @@
IMX_BOOT_UART_BASE ?= 0x30890000
$(eval $(call add_define,IMX_BOOT_UART_BASE))
-EL3_EXCEPTION_HANDLING := 1
-SDEI_SUPPORT := 1
+EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
+ifeq (${SDEI_SUPPORT}, 1)
+BL31_SOURCES += plat/imx/common/imx_ehf.c \
+ plat/imx/common/imx_sdei.c
+endif
+
+ifeq (${SPD},trusty)
+ BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+endif
diff --git a/plat/imx/imx8m/imx8mp/gpc.c b/plat/imx/imx8m/imx8mp/gpc.c
index d660e3d..452e788 100644
--- a/plat/imx/imx8m/imx8mp/gpc.c
+++ b/plat/imx/imx8m/imx8mp/gpc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 NXP
+ * Copyright 2019-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -69,10 +69,11 @@
HDMIMIX,
HDMI_PHY,
DDRMIX,
+ MAX_DOMAINS,
};
/* PU domain, add some hole to minimize the uboot change */
-static struct imx_pwr_domain pu_domains[20] = {
+static struct imx_pwr_domain pu_domains[MAX_DOMAINS] = {
[MIPI_PHY1] = IMX_PD_DOMAIN(MIPI_PHY1, false),
[PCIE_PHY] = IMX_PD_DOMAIN(PCIE_PHY, false),
[USB1_PHY] = IMX_PD_DOMAIN(USB1_PHY, true),
@@ -169,11 +170,16 @@
}
}
-static void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
+void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on)
{
struct imx_pwr_domain *pwr_domain = &pu_domains[domain_id];
unsigned int i;
+ /* validate the domain id */
+ if (domain_id >= MAX_DOMAINS) {
+ return;
+ }
+
if (domain_id == HSIOMIX) {
for (i = 0; i < ARRAY_SIZE(hsiomix_clk); i++) {
hsiomix_clk[i].val = mmio_read_32(IMX_CCM_BASE + hsiomix_clk[i].offset);
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index 22fbd5e..d443c3d 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 NXP
+ * Copyright 2020-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,14 +19,18 @@
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
+#include <dram.h>
#include <gpc.h>
#include <imx_aipstz.h>
#include <imx_uart.h>
#include <imx_rdc.h>
#include <imx8m_caam.h>
+#include <imx8m_csu.h>
#include <platform_def.h>
#include <plat_imx8.h>
+#define TRUSTY_PARAMS_LEN_BYTES (4096*2)
+
static const mmap_region_t imx_mmap[] = {
GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP,
NOC_MAP, {0},
@@ -42,9 +46,10 @@
static const struct imx_rdc_cfg rdc[] = {
/* Master domain assignment */
- RDC_MDAn(0x1, DID1),
+ RDC_MDAn(RDC_MDA_M7, DID1),
/* peripherals domain permission */
+ RDC_PDAPn(RDC_PDAP_UART2, D0R | D0W),
/* memory region */
@@ -52,6 +57,21 @@
{0},
};
+static const struct imx_csu_cfg csu_cfg[] = {
+ /* peripherals csl setting */
+ CSU_CSLx(CSU_CSL_OCRAM, CSU_SEC_LEVEL_2, UNLOCKED),
+ CSU_CSLx(CSU_CSL_OCRAM_S, CSU_SEC_LEVEL_2, UNLOCKED),
+
+ /* master HP0~1 */
+
+ /* SA setting */
+
+ /* HP control setting */
+
+ /* Sentinel */
+ {0}
+};
+
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
@@ -96,6 +116,7 @@
u_register_t arg2, u_register_t arg3)
{
static console_t console;
+ unsigned int val;
unsigned int i;
/* Enable CSU NS access permission */
@@ -107,6 +128,13 @@
imx_rdc_init(rdc);
+ imx_csu_init(csu_cfg);
+
+ /* config the ocram memory range for secure access */
+ mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, 0x4E1);
+ val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
+ mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
+
imx8m_caam_init();
console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
@@ -122,7 +150,7 @@
bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-#ifdef SPD_opteed
+#if defined(SPD_opteed) || defined(SPD_trusty)
/* Populate entry point information for BL32 */
SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
@@ -132,6 +160,16 @@
/* Pass TEE base and size to bl33 */
bl33_image_ep_info.args.arg1 = BL32_BASE;
bl33_image_ep_info.args.arg2 = BL32_SIZE;
+
+#ifdef SPD_trusty
+ bl32_image_ep_info.args.arg0 = BL32_SIZE;
+ bl32_image_ep_info.args.arg1 = BL32_BASE;
+#else
+ /* Make sure memory is clean */
+ mmio_write_32(BL32_FDT_OVERLAY_ADDR, 0);
+ bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+ bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+#endif
#endif
bl31_tzc380_setup();
@@ -148,6 +186,10 @@
(BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE),
MT_DEVICE | MT_RW | MT_SECURE);
#endif
+
+ /* Map TEE memory */
+ mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW);
+
mmap_add(imx_mmap);
init_xlat_tables();
@@ -162,6 +204,9 @@
/* select the CKIL source to 32K OSC */
mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1);
+ /* Init the dram info */
+ dram_info_init(SAVED_DRAM_TIMING_BASE);
+
plat_gic_driver_init();
plat_gic_init();
@@ -185,3 +230,12 @@
{
return COUNTER_FREQUENCY;
}
+
+#ifdef SPD_trusty
+void plat_trusty_set_boot_args(aapcs64_params_t *args)
+{
+ args->arg0 = BL32_SIZE;
+ args->arg1 = BL32_BASE;
+ args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+}
+#endif
diff --git a/plat/imx/imx8m/imx8mp/include/imx_sec_def.h b/plat/imx/imx8m/imx8mp/include/imx_sec_def.h
new file mode 100644
index 0000000..ba248b5
--- /dev/null
+++ b/plat/imx/imx8m/imx8mp/include/imx_sec_def.h
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_SEC_DEF_H
+#define IMX_SEC_DEF_H
+
+/* RDC MDA index */
+enum rdc_mda_idx {
+ RDC_MDA_A53 = 0,
+ RDC_MDA_M7 = 1,
+ RDC_MDA_PCIE_CTRL1 = 2,
+ RDC_MDA_SDMA3p = 3,
+ RDC_MDA_SDMA3b = 4,
+ RDC_MDA_LCDIF = 5,
+ RDC_MDA_ISI = 6,
+ RDC_MDA_NPU = 7,
+ RDC_MDA_Coresight = 8,
+ RDC_MDA_DAP = 9,
+ RDC_MDA_CAAM = 10,
+ RDC_MDA_SDMA1p = 11,
+ RDC_MDA_SDMA1b = 12,
+ RDC_MDA_APBHDMA = 13,
+ RDC_MDA_RAWNAND = 14,
+ RDC_MDA_uSDHC1 = 15,
+ RDC_MDA_uSDHC2 = 16,
+ RDC_MDA_uSDHC3 = 17,
+ RDC_MDA_AUDIO_PROCESSOR = 18,
+ RDC_MDA_USB1 = 19,
+ RDC_MDA_USB2 = 20,
+ RDC_MDA_TESTPORT = 21,
+ RDC_MDA_ENET1_TX = 22,
+ RDC_MDA_ENET1_RX = 23,
+ RDC_MDA_SDMA2 = 24,
+ RDC_MDA_SDMA3_to_SPBA2 = 25,
+ RDC_MDA_SDMA1_to_SPBA1 = 26,
+ RDC_MDA_LCDIF2 = 27,
+ RDC_MDA_HDMI_TX = 28,
+ RDC_MDA_ENET2 = 29,
+ RDC_MDA_GPU3D = 30,
+ RDC_MDA_GPU2D = 31,
+ RDC_MDA_VPU_G1 = 32,
+ RDC_MDA_VPU_G2 = 33,
+ RDC_MDA_VPU_VC8000E = 34,
+ RDC_MDA_AUDIO_EDMA = 35,
+ RDC_MDA_ISP1 = 36,
+ RDC_MDA_ISP2 = 37,
+ RDC_MDA_DEWARP = 38,
+ RDC_MDA_GIC500 = 39,
+};
+
+/* RDC Peripherals index */
+enum rdc_pdap_idx {
+ RDC_PDAP_GPIO1 = 0,
+ RDC_PDAP_GPIO2 = 1,
+ RDC_PDAP_GPIO3 = 2,
+ RDC_PDAP_GPIO4 = 3,
+ RDC_PDAP_GPIO5 = 4,
+ RDC_PDAP_MU_2_A = 5,
+ RDC_PDAP_ANA_TSENSOR = 6,
+ RDC_PDAP_ANA_OSC = 7,
+ RDC_PDAP_WDOG1 = 8,
+ RDC_PDAP_WDOG2 = 9,
+ RDC_PDAP_WDOG3 = 10,
+ RDC_PDAP_GPT1 = 13,
+ RDC_PDAP_GPT2 = 14,
+ RDC_PDAP_GPT3 = 15,
+ RDC_PDAP_MU_2_B = 16,
+ RDC_PDAP_ROMCP = 17,
+ RDC_PDAP_MU_3_A = 18,
+ RDC_PDAP_IOMUXC = 19,
+ RDC_PDAP_IOMUXC_GPR = 20,
+ RDC_PDAP_OCOTP_CTRL = 21,
+ RDC_PDAP_ANA_PLL = 22,
+ RDC_PDAP_SNVS_HP = 23,
+ RDC_PDAP_CCM = 24,
+ RDC_PDAP_SRC = 25,
+ RDC_PDAP_GPC = 26,
+ RDC_PDAP_SEMAPHORE1 = 27,
+ RDC_PDAP_SEMAPHORE2 = 28,
+ RDC_PDAP_RDC = 29,
+ RDC_PDAP_CSU = 30,
+ RDC_PDAP_MU_3_B = 31,
+ RDC_PDAP_ISI = 32,
+ RDC_PDAP_ISP0 = 33,
+ RDC_PDAP_ISP1 = 34,
+ RDC_PDAP_IPS_Dewarp = 35,
+ RDC_PDAP_MIPI_CSI0 = 36,
+ RDC_PDAP_HSIOMIX_BLK_CTL = 37,
+ RDC_PDAP_PWM1 = 38,
+ RDC_PDAP_PWM2 = 39,
+ RDC_PDAP_PWM3 = 40,
+ RDC_PDAP_PWM4 = 41,
+ RDC_PDAP_System_Counter_RD = 42,
+ RDC_PDAP_System_Counter_CMP = 43,
+ RDC_PDAP_System_Counter_CTRL = 44,
+ RDC_PDAP_I2C5 = 45,
+ RDC_PDAP_GPT6 = 46,
+ RDC_PDAP_GPT5 = 47,
+ RDC_PDAP_GPT4 = 48,
+ RDC_PDAP_MIPI_CSI1 = 49,
+ RDC_PDAP_MIPI_DSI0 = 50,
+ RDC_PDAP_MEDIAMIX_BLK_CTL = 51,
+ RDC_PDAP_LCDIF1 = 52,
+ RDC_PDAP_eDMA_Management_Page = 53,
+ RDC_PDAP_eDMA_Channels_15_0 = 54,
+ RDC_PDAP_eDMA_Channels_31_16 = 55,
+ RDC_PDAP_TZASC = 56,
+ RDC_PDAP_I2C6 = 57,
+ RDC_PDAP_CAAM = 58,
+ RDC_PDAP_LCDIF2 = 59,
+ RDC_PDAP_PERFMON1 = 60,
+ RDC_PDAP_PERFMON2 = 61,
+ RDC_PDAP_NOC_BLK_CTL = 62,
+ RDC_PDAP_QoSC = 63,
+ RDC_PDAP_LVDS0 = 64,
+ RDC_PDAP_LVDS1 = 65,
+ RDC_PDAP_I2C1 = 66,
+ RDC_PDAP_I2C2 = 67,
+ RDC_PDAP_I2C3 = 68,
+ RDC_PDAP_I2C4 = 69,
+ RDC_PDAP_UART4 = 70,
+ RDC_PDAP_HDMI_TX = 71,
+ RDC_PDAP_IRQ_STEER_Audio_Processor = 72,
+ RDC_PDAP_SDMA2 = 73,
+ RDC_PDAP_MU_1_A = 74,
+ RDC_PDAP_MU_1_B = 75,
+ RDC_PDAP_SEMAPHORE_HS = 76,
+ RDC_PDAP_SAI1 = 78,
+ RDC_PDAP_SAI2 = 79,
+ RDC_PDAP_SAI3 = 80,
+ RDC_PDAP_CAN_FD1 = 81,
+ RDC_PDAP_SAI5 = 82,
+ RDC_PDAP_SAI6 = 83,
+ RDC_PDAP_uSDHC1 = 84,
+ RDC_PDAP_uSDHC2 = 85,
+ RDC_PDAP_uSDHC3 = 86,
+ RDC_PDAP_PCIE_PHY1 = 87,
+ RDC_PDAP_HDMI_TX_AUDLNK_MSTR = 88,
+ RDC_PDAP_CAN_FD2 = 89,
+ RDC_PDAP_SPBA2 = 90,
+ RDC_PDAP_QSPI = 91,
+ RDC_PDAP_AUDIO_BLK_CTRL = 92,
+ RDC_PDAP_SDMA1 = 93,
+ RDC_PDAP_ENET1 = 94,
+ RDC_PDAP_ENET2_TSN = 95,
+ RDC_PDAP_ASRC = 97,
+ RDC_PDAP_eCSPI1 = 98,
+ RDC_PDAP_eCSPI2 = 99,
+ RDC_PDAP_eCSPI3 = 100,
+ RDC_PDAP_SAI7 = 101,
+ RDC_PDAP_UART1 = 102,
+ RDC_PDAP_UART3 = 104,
+ RDC_PDAP_UART2 = 105,
+ RDC_PDAP_PDM_MICFIL = 106,
+ RDC_PDAP_AUDIO_XCVR_RX_eARC = 107,
+ RDC_PDAP_SDMA3 = 109,
+ RDC_PDAP_SPBA1 = 111,
+};
+
+enum csu_csl_idx {
+ CSU_CSL_GPIO1 = 0,
+ CSU_CSL_GPIO2 = 1,
+ CSU_CSL_GPIO3 = 2,
+ CSU_CSL_GPIO4 = 3,
+ CSU_CSL_GPIO5 = 4,
+ CSU_CSL_MU_2_A = 5,
+ CSU_CSL_ANA_TSENSOR = 6,
+ CSU_CSL_ANA_OSC = 7,
+ CSU_CSL_WDOG1 = 8,
+ CSU_CSL_WDOG2 = 9,
+ CSU_CSL_WDOG3 = 10,
+ CSU_CSL_GPT1 = 13,
+ CSU_CSL_GPT2 = 14,
+ CSU_CSL_GPT3 = 15,
+ CSU_CSL_MU_2_B = 16,
+ CSU_CSL_ROMCP = 17,
+ CSU_CSL_MU_3_A = 18,
+ CSU_CSL_IOMUXC = 19,
+ CSU_CSL_IOMUXC_GPR = 20,
+ CSU_CSL_OCOTP_CTRL = 21,
+ CSU_CSL_ANA_PLL = 22,
+ CSU_CSL_SNVS_HP = 23,
+ CSU_CSL_CCM = 24,
+ CSU_CSL_SRC = 25,
+ CSU_CSL_GPC = 26,
+ CSU_CSL_SEMAPHORE1 = 27,
+ CSU_CSL_SEMAPHORE2 = 28,
+ CSU_CSL_RDC = 29,
+ CSU_CSL_CSU = 30,
+ CSU_CSL_MU_3_B = 31,
+ CSU_CSL_ISI = 32,
+ CSU_CSL_ISP0 = 33,
+ CSU_CSL_ISP1 = 34,
+ CSU_CSL_IPS_Dewarp = 35,
+ CSU_CSL_MIPI_CSI0 = 36,
+ CSU_CSL_HSIOMIX_BLK_CTL = 37,
+ CSU_CSL_PWM1 = 38,
+ CSU_CSL_PWM2 = 39,
+ CSU_CSL_PWM3 = 40,
+ CSU_CSL_PWM4 = 41,
+ CSU_CSL_System_Counter_RD = 42,
+ CSU_CSL_System_Counter_CMP = 43,
+ CSU_CSL_System_Counter_CTRL = 44,
+ CSU_CSL_I2C5 = 45,
+ CSU_CSL_GPT6 = 46,
+ CSU_CSL_GPT5 = 47,
+ CSU_CSL_GPT4 = 48,
+ CSU_CSL_MIPI_CSI1 = 49,
+ CSU_CSL_MIPI_DSI0 = 50,
+ CSU_CSL_MEDIAMIX_BLK_CTL = 51,
+ CSU_CSL_LCDIF1 = 52,
+ CSU_CSL_eDMA_Management_Page = 53,
+ CSU_CSL_eDMA_Channels_15_0 = 54,
+ CSU_CSL_eDMA_Channels_31_16 = 55,
+ CSU_CSL_TZASC = 56,
+ CSU_CSL_I2C6 = 57,
+ CSU_CSL_CAAM = 58,
+ CSU_CSL_LCDIF2 = 59,
+ CSU_CSL_PERFMON1 = 60,
+ CSU_CSL_PERFMON2 = 61,
+ CSU_CSL_NOC_BLK_CTL = 62,
+ CSU_CSL_QoSC = 63,
+ CSU_CSL_LVDS0 = 64,
+ CSU_CSL_LVDS1 = 65,
+ CSU_CSL_I2C1 = 66,
+ CSU_CSL_I2C2 = 67,
+ CSU_CSL_I2C3 = 68,
+ CSU_CSL_I2C4 = 69,
+ CSU_CSL_UART4 = 70,
+ CSU_CSL_HDMI_TX = 71,
+ CSU_CSL_IRQ_STEER_Audio_Processor = 72,
+ CSU_CSL_SDMA2 = 73,
+ CSU_CSL_MU_1_A = 74,
+ CSU_CSL_MU_1_B = 75,
+ CSU_CSL_SEMAPHORE_HS = 76,
+ CSU_CSL_SAI1 = 78,
+ CSU_CSL_SAI2 = 79,
+ CSU_CSL_SAI3 = 80,
+ CSU_CSL_CAN_FD1 = 81,
+ CSU_CSL_SAI5 = 82,
+ CSU_CSL_SAI6 = 83,
+ CSU_CSL_uSDHC1 = 84,
+ CSU_CSL_uSDHC2 = 85,
+ CSU_CSL_uSDHC3 = 86,
+ CSU_CSL_PCIE_PHY1 = 87,
+ CSU_CSL_HDMI_TX_AUDLNK_MSTR = 88,
+ CSU_CSL_CAN_FD2 = 89,
+ CSU_CSL_SPBA2 = 90,
+ CSU_CSL_QSPI = 91,
+ CSU_CSL_AUDIO_BLK_CTRL = 92,
+ CSU_CSL_SDMA1 = 93,
+ CSU_CSL_ENET1 = 94,
+ CSU_CSL_ENET2_TSN = 95,
+ CSU_CSL_ASRC = 97,
+ CSU_CSL_eCSPI1 = 98,
+ CSU_CSL_eCSPI2 = 99,
+ CSU_CSL_eCSPI3 = 100,
+ CSU_CSL_SAI7 = 101,
+ CSU_CSL_UART1 = 102,
+ CSU_CSL_UART3 = 104,
+ CSU_CSL_UART2 = 105,
+ CSU_CSL_PDM_MICFIL = 106,
+ CSU_CSL_AUDIO_XCVR_RX_eARC = 107,
+ CSU_CSL_SDMA3 = 109,
+ CSU_CSL_SPBA1 = 111,
+ CSU_CSL_OCRAM_A = 113,
+ CSU_CSL_OCRAM = 118,
+ CSU_CSL_OCRAM_S = 119,
+};
+
+#endif /* IMX_SEC_DEF_H */
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index 486c1ee..8807f5d 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 NXP
+ * Copyright 2020-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -62,6 +62,8 @@
#define PLAT_NS_IMAGE_OFFSET U(0x40200000)
#define PLAT_NS_IMAGE_SIZE U(0x00200000)
+#define BL32_FDT_OVERLAY_ADDR (PLAT_NS_IMAGE_OFFSET + 0x3000000)
+
/* GICv3 base address */
#define PLAT_GICD_BASE U(0x38800000)
#define PLAT_GICR_BASE U(0x38880000)
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 823b5d6..e8669e5 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright 2019-2020 NXP
+# Copyright 2019-2022 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -15,6 +15,12 @@
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
+IMX_DRAM_SOURCES := plat/imx/imx8m/ddr/dram.c \
+ plat/imx/imx8m/ddr/clock.c \
+ plat/imx/imx8m/ddr/dram_retention.c \
+ plat/imx/imx8m/ddr/ddr4_dvfs.c \
+ plat/imx/imx8m/ddr/lpddr4_dvfs.c
+
IMX_GIC_SOURCES := ${GICV3_SOURCES} \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
@@ -25,13 +31,12 @@
plat/imx/imx8m/imx_aipstz.c \
plat/imx/imx8m/imx_rdc.c \
plat/imx/imx8m/imx8m_caam.c \
+ plat/imx/imx8m/imx8m_csu.c \
plat/imx/imx8m/imx8m_psci_common.c \
plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c \
plat/imx/imx8m/imx8mp/imx8mp_psci.c \
plat/imx/imx8m/imx8mp/gpc.c \
plat/imx/common/imx8_topology.c \
- plat/imx/common/imx_ehf.c \
- plat/imx/common/imx_sdei.c \
plat/imx/common/imx_sip_handler.c \
plat/imx/common/imx_sip_svc.c \
plat/imx/common/imx_uart_console.S \
@@ -39,6 +44,7 @@
drivers/arm/tzc/tzc380.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES} \
${XLAT_TABLES_LIB_SRCS}
@@ -123,13 +129,13 @@
$(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
@if [ ! -f $(ROT_KEY) ]; then \
- openssl genrsa 2048 > $@ 2>/dev/null; \
+ ${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
fi
$(ROTPK_HASH): $(ROT_KEY)
@echo " OPENSSL $@"
- $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
- openssl dgst -sha256 -binary > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
endif
USE_COHERENT_MEM := 1
@@ -149,5 +155,12 @@
IMX_BOOT_UART_BASE ?= 0x30890000
$(eval $(call add_define,IMX_BOOT_UART_BASE))
+EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
+ifeq (${SDEI_SUPPORT}, 1)
+BL31_SOURCES += plat/imx/common/imx_ehf.c \
+ plat/imx/common/imx_sdei.c
+endif
+
-EL3_EXCEPTION_HANDLING := 1
-SDEI_SUPPORT := 1
+ifeq (${SPD},trusty)
+ BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+endif
diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c
index 367c941..fa83324 100644
--- a/plat/imx/imx8m/imx8mq/gpc.c
+++ b/plat/imx/imx8m/imx8mq/gpc.c
@@ -9,6 +9,7 @@
#include <stdbool.h>
#include <common/debug.h>
+#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
#include <platform_def.h>
@@ -176,6 +177,13 @@
mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1);
- /* enable all the power domain by default */
- mmio_write_32(IMX_GPC_BASE + PU_PGC_UP_TRG, 0x3fcf);
+ /*
+ * for USB OTG, the limitation are:
+ * 1. before system clock config, the IPG clock run at 12.5MHz, delay time
+ * should be longer than 82us.
+ * 2. after system clock config, ipg clock run at 66.5MHz, delay time
+ * be longer that 15.3 us.
+ * Add 100us to make sure the USB OTG SRC is clear safely.
+ */
+ udelay(100);
}
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index 05b5970..e998a16 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,7 +18,7 @@
#include <drivers/generic_delay_timer.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <gpc.h>
@@ -27,6 +27,8 @@
#include <imx8m_caam.h>
#include <plat_imx8.h>
+#define TRUSTY_PARAMS_LEN_BYTES (4096*2)
+
static const mmap_region_t imx_mmap[] = {
MAP_REGION_FLAT(GPV_BASE, GPV_SIZE, MT_DEVICE | MT_RW), /* GPV map */
MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO), /* ROM map */
@@ -146,7 +148,7 @@
bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-#ifdef SPD_opteed
+#if defined(SPD_opteed) || defined(SPD_trusty)
/* Populate entry point information for BL32 */
SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
@@ -156,6 +158,16 @@
/* Pass TEE base and size to bl33 */
bl33_image_ep_info.args.arg1 = BL32_BASE;
bl33_image_ep_info.args.arg2 = BL32_SIZE;
+
+#ifdef SPD_trusty
+ bl32_image_ep_info.args.arg0 = BL32_SIZE;
+ bl32_image_ep_info.args.arg1 = BL32_BASE;
+#else
+ /* Make sure memory is clean */
+ mmio_write_32(BL32_FDT_OVERLAY_ADDR, 0);
+ bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+ bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+#endif
#endif
bl31_tz380_setup();
@@ -168,6 +180,9 @@
mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, (BL_CODE_END - BL_CODE_BASE),
MT_MEMORY | MT_RO | MT_SECURE);
+ /* Map TEE memory */
+ mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW);
+
mmap_add(imx_mmap);
#if USE_COHERENT_MEM
@@ -215,3 +230,12 @@
{
return;
}
+
+#ifdef SPD_trusty
+void plat_trusty_set_boot_args(aapcs64_params_t *args)
+{
+ args->arg0 = BL32_SIZE;
+ args->arg1 = BL32_BASE;
+ args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+}
+#endif
diff --git a/plat/imx/imx8m/imx8mq/include/imx_sec_def.h b/plat/imx/imx8m/imx8mq/include/imx_sec_def.h
new file mode 100644
index 0000000..0f77141
--- /dev/null
+++ b/plat/imx/imx8m/imx8mq/include/imx_sec_def.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_SEC_DEF_H
+#define IMX_SEC_DEF_H
+
+/* RDC MDA index */
+enum rdc_mda_idx {
+ RDC_MDA_A53 = 0,
+ RDC_MDA_M4 = 1,
+ RDC_MDA_PCIE_CTRL1 = 2,
+ RDC_MDA_PCIE_CTRL2 = 3,
+ RDC_MDA_VPU_DEC = 4,
+ RDC_MDA_LCDIF = 5,
+ RDC_MDA_CSI1 = 6,
+ RDC_MDA_CSI2 = 7,
+ RDC_MDA_Coresight = 8,
+ RDC_MDA_DAP = 9,
+ RDC_MDA_CAAM = 10,
+ RDC_MDA_SDMAp = 11,
+ RDC_MDA_SDMAb = 12,
+ RDC_MDA_APBHDMA = 13,
+ RDC_MDA_RAWNAND = 14,
+ RDC_MDA_uSDHC1 = 15,
+ RDC_MDA_uSDHC2 = 16,
+ RDC_MDA_DCSS = 17,
+ RDC_MDA_GPU = 18,
+ RDC_MDA_USB1 = 19,
+ RDC_MDA_USB2 = 20,
+ RDC_MDA_TESTPORT = 21,
+ RDC_MDA_ENET1_TX = 22,
+ RDC_MDA_ENET1_RX = 23,
+ RDC_MDA_SDMA2 = 24,
+ RDC_MDA_SDMA1 = 26,
+};
+
+/* RDC Peripherals index */
+enum rdc_pdap_idx {
+ RDC_PDAP_GPIO1 = 0,
+ RDC_PDAP_GPIO2 = 1,
+ RDC_PDAP_GPIO3 = 2,
+ RDC_PDAP_GPIO4 = 3,
+ RDC_PDAP_GPIO5 = 4,
+ RDC_PDAP_ANA_TSENSOR = 6,
+ RDC_PDAP_ANA_OSC = 7,
+ RDC_PDAP_WDOG1 = 8,
+ RDC_PDAP_WDOG2 = 9,
+ RDC_PDAP_WDOG3 = 10,
+ RDC_PDAP_SDMA2 = 12,
+ RDC_PDAP_GPT1 = 13,
+ RDC_PDAP_GPT2 = 14,
+ RDC_PDAP_GPT3 = 15,
+ RDC_PDAP_ROMCP = 17,
+ RDC_PDAP_LCDIF = 18,
+ RDC_PDAP_IOMUXC = 19,
+ RDC_PDAP_IOMUXC_GPR = 20,
+ RDC_PDAP_OCOTP_CTRL = 21,
+ RDC_PDAP_ANATOP_PLL = 22,
+ RDC_PDAP_SNVS_HP = 23,
+ RDC_PDAP_CCM = 24,
+ RDC_PDAP_SRC = 25,
+ RDC_PDAP_GPC = 26,
+ RDC_PDAP_SEMAPHORE1 = 27,
+ RDC_PDAP_SEMAPHORE2 = 28,
+ RDC_PDAP_RDC = 29,
+ RDC_PDAP_CSU = 30,
+ RDC_PDAP_MST0 = 32,
+ RDC_PDAP_MST1 = 33,
+ RDC_PDAP_MST2 = 34,
+ RDC_PDAP_MST3 = 35,
+ RDC_PDAP_HDMI_SEC = 36,
+ RDC_PDAP_PWM1 = 38,
+ RDC_PDAP_PWM2 = 39,
+ RDC_PDAP_PWM3 = 40,
+ RDC_PDAP_PWM4 = 41,
+ RDC_PDAP_SysCounter_RD = 42,
+ RDC_PDAP_SysCounter_CMP = 43,
+ RDC_PDAP_SysCounter_CTRL = 44,
+ RDC_PDAP_HDMI_CTRL = 45,
+ RDC_PDAP_GPT6 = 46,
+ RDC_PDAP_GPT5 = 47,
+ RDC_PDAP_GPT4 = 48,
+ RDC_PDAP_TZASC = 56,
+ RDC_PDAP_MTR = 59,
+ RDC_PDAP_PERFMON1 = 60,
+ RDC_PDAP_PERFMON2 = 61,
+ RDC_PDAP_PLATFORM_CTRL = 62,
+ RDC_PDAP_QoSC = 63,
+ RDC_PDAP_MIPI_PHY = 64,
+ RDC_PDAP_MIPI_DSI = 65,
+ RDC_PDAP_I2C1 = 66,
+ RDC_PDAP_I2C2 = 67,
+ RDC_PDAP_I2C3 = 68,
+ RDC_PDAP_I2C4 = 69,
+ RDC_PDAP_UART4 = 70,
+ RDC_PDAP_MIPI_CSI1 = 71,
+ RDC_PDAP_MIPI_CSI_PHY1 = 72,
+ RDC_PDAP_CSI1 = 73,
+ RDC_PDAP_MU_A = 74,
+ RDC_PDAP_MU_B = 75,
+ RDC_PDAP_SEMAPHORE_HS = 76,
+ RDC_PDAP_SAI1 = 78,
+ RDC_PDAP_SAI6 = 80,
+ RDC_PDAP_SAI5 = 81,
+ RDC_PDAP_SAI4 = 82,
+ RDC_PDAP_USDHC1 = 84,
+ RDC_PDAP_USDHC2 = 85,
+ RDC_PDAP_MIPI_CSI2 = 86,
+ RDC_PDAP_MIPI_CSI_PHY2 = 87,
+ RDC_PDAP_CSI2 = 88,
+ RDC_PDAP_QSPI = 91,
+ RDC_PDAP_SDMA1 = 93,
+ RDC_PDAP_ENET1 = 94,
+ RDC_PDAP_SPDIF1 = 97,
+ RDC_PDAP_ECSPI1 = 98,
+ RDC_PDAP_ECSPI2 = 99,
+ RDC_PDAP_ECSPI3 = 100,
+ RDC_PDAP_UART1 = 102,
+ RDC_PDAP_UART3 = 104,
+ RDC_PDAP_UART2 = 105,
+ RDC_PDAP_SPDIF2 = 106,
+ RDC_PDAP_SAI2 = 107,
+ RDC_PDAP_SAI3 = 108,
+ RDC_PDAP_SPBA1 = 111,
+ RDC_PDAP_CAAM = 114,
+ RDC_PDAP_DDRC_SEC = 115,
+ RDC_PDAP_GIC_EXSC = 116,
+ RDC_PDAP_USB_EXSC = 117,
+ RDC_PDAP_OCRAM_TZ = 118,
+ RDC_PDAP_OCRAM_S_TZ = 119,
+ RDC_PDAP_VPU_SEC = 120,
+ RDC_PDAP_DAP_EXSC = 121,
+ RDC_PDAP_ROMCP_SEC = 122,
+ RDC_PDAP_APBHDMA_SEC = 123,
+ RDC_PDAP_M4_SEC = 124,
+ RDC_PDAP_QSPI_SEC = 125,
+ RDC_PDAP_GPU_EXSC = 126,
+ RDC_PDAP_PCIE = 127,
+};
+
+enum csu_csl_idx {
+ CSU_CSL_GPIO1 = 0,
+ CSU_CSL_GPIO2 = 1,
+ CSU_CSL_GPIO3 = 2,
+ CSU_CSL_GPIO4 = 3,
+ CSU_CSL_GPIO5 = 4,
+ CSU_CSL_ANA_TSENSOR = 6,
+ CSU_CSL_ANA_OSC = 7,
+ CSU_CSL_WDOG1 = 8,
+ CSU_CSL_WDOG2 = 9,
+ CSU_CSL_WDOG3 = 10,
+ CSU_CSL_SDMA2 = 12,
+ CSU_CSL_GPT1 = 13,
+ CSU_CSL_GPT2 = 14,
+ CSU_CSL_GPT3 = 15,
+ CSU_CSL_ROMCP = 17,
+ CSU_CSL_LCDIF = 18,
+ CSU_CSL_IOMUXC = 19,
+ CSU_CSL_IOMUXC_GPR = 20,
+ CSU_CSL_OCOTP_CTRL = 21,
+ CSU_CSL_ANATOP_PLL = 22,
+ CSU_CSL_SNVS_HP = 23,
+ CSU_CSL_CCM = 24,
+ CSU_CSL_SRC = 25,
+ CSU_CSL_GPC = 26,
+ CSU_CSL_SEMAPHORE1 = 27,
+ CSU_CSL_SEMAPHORE2 = 28,
+ CSU_CSL_RDC = 29,
+ CSU_CSL_CSU = 30,
+ CSU_CSL_MST0 = 32,
+ CSU_CSL_MST1 = 33,
+ CSU_CSL_MST2 = 34,
+ CSU_CSL_MST3 = 35,
+ CSU_CSL_HDMI_SEC = 36,
+ CSU_CSL_PWM1 = 38,
+ CSU_CSL_PWM2 = 39,
+ CSU_CSL_PWM3 = 40,
+ CSU_CSL_PWM4 = 41,
+ CSU_CSL_SysCounter_RD = 42,
+ CSU_CSL_SysCounter_CMP = 43,
+ CSU_CSL_SysCounter_CTRL = 44,
+ CSU_CSL_HDMI_CTRL = 45,
+ CSU_CSL_GPT6 = 46,
+ CSU_CSL_GPT5 = 47,
+ CSU_CSL_GPT4 = 48,
+ CSU_CSL_TZASC = 56,
+ CSU_CSL_MTR = 59,
+ CSU_CSL_PERFMON1 = 60,
+ CSU_CSL_PERFMON2 = 61,
+ CSU_CSL_PLATFORM_CTRL = 62,
+ CSU_CSL_QoSC = 63,
+ CSU_CSL_MIPI_PHY = 64,
+ CSU_CSL_MIPI_DSI = 65,
+ CSU_CSL_I2C1 = 66,
+ CSU_CSL_I2C2 = 67,
+ CSU_CSL_I2C3 = 68,
+ CSU_CSL_I2C4 = 69,
+ CSU_CSL_UART4 = 70,
+ CSU_CSL_MIPI_CSI1 = 71,
+ CSU_CSL_MIPI_CSI_PHY1 = 72,
+ CSU_CSL_CSI1 = 73,
+ CSU_CSL_MU_A = 74,
+ CSU_CSL_MU_B = 75,
+ CSU_CSL_SEMAPHORE_HS = 76,
+ CSU_CSL_SAI1 = 78,
+ CSU_CSL_SAI6 = 80,
+ CSU_CSL_SAI5 = 81,
+ CSU_CSL_SAI4 = 82,
+ CSU_CSL_USDHC1 = 84,
+ CSU_CSL_USDHC2 = 85,
+ CSU_CSL_MIPI_CSI2 = 86,
+ CSU_CSL_MIPI_CSI_PHY2 = 87,
+ CSU_CSL_CSI2 = 88,
+ CSU_CSL_QSPI = 91,
+ CSU_CSL_SDMA1 = 93,
+ CSU_CSL_ENET1 = 94,
+ CSU_CSL_SPDIF1 = 97,
+ CSU_CSL_ECSPI1 = 98,
+ CSU_CSL_ECSPI2 = 99,
+ CSU_CSL_ECSPI3 = 100,
+ CSU_CSL_UART1 = 102,
+ CSU_CSL_UART3 = 104,
+ CSU_CSL_UART2 = 105,
+ CSU_CSL_SPDIF2 = 106,
+ CSU_CSL_SAI2 = 107,
+ CSU_CSL_SAI3 = 108,
+ CSU_CSL_SPBA1 = 111,
+ CSU_CSL_MOD_EN3 = 112,
+ CSU_CSL_MOD_EN0 = 113,
+ CSU_CSL_CAAM = 114,
+ CSU_CSL_DDRC_SEC = 115,
+ CSU_CSL_GIC_EXSC = 116,
+ CSU_CSL_USB_EXSC = 117,
+ CSU_CSL_OCRAM_TZ = 118,
+ CSU_CSL_OCRAM_S_TZ = 119,
+ CSU_CSL_VPU_SEC = 120,
+ CSU_CSL_DAP_EXSC = 121,
+ CSU_CSL_ROMCP_SEC = 122,
+ CSU_CSL_APBHDMA_SEC = 123,
+ CSU_CSL_M4_SEC = 124,
+ CSU_CSL_QSPI_SEC = 125,
+ CSU_CSL_GPU_EXSC = 126,
+ CSU_CSL_PCIE = 127,
+};
+
+#endif /* IMX_SEC_DEF_H */
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index 6d6a865..1dd22d9 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -35,6 +35,7 @@
/* non-secure uboot base */
#define PLAT_NS_IMAGE_OFFSET U(0x40200000)
+#define BL32_FDT_OVERLAY_ADDR (PLAT_NS_IMAGE_OFFSET + 0x3000000)
/* GICv3 base address */
#define PLAT_GICD_BASE U(0x38800000)
@@ -43,8 +44,13 @@
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
+#ifdef SPD_trusty
+#define MAX_XLAT_TABLES 5
+#define MAX_MMAP_REGIONS 15
+#else
#define MAX_XLAT_TABLES 4
#define MAX_MMAP_REGIONS 14
+#endif
#define HAB_RVT_BASE U(0x00000880) /* HAB_RVT for i.MX8MQ */
@@ -120,7 +126,7 @@
#define OCRAM_S_SIZE U(0x8000)
#define OCRAM_S_LIMIT (OCRAM_S_BASE + OCRAM_S_SIZE)
-#define COUNTER_FREQUENCY 8000000 /* 8MHz */
+#define COUNTER_FREQUENCY 8333333 /* 25MHz / 3 */
#define DEBUG_CONSOLE 0
#define IMX_WDOG_B_RESET
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 5461010..7b6df92 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -1,9 +1,12 @@
#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
PLAT_INCLUDES := -Iplat/imx/common/include \
-Iplat/imx/imx8m/include \
-Iplat/imx/imx8m/imx8mq/include
@@ -28,12 +31,11 @@
plat/imx/common/imx_sip_handler.c \
plat/imx/common/imx_sip_svc.c \
plat/imx/common/imx_uart_console.S \
- lib/xlat_tables/aarch64/xlat_tables.c \
- lib/xlat_tables/xlat_tables_common.c \
lib/cpus/aarch64/cortex_a53.S \
drivers/arm/tzc/tzc380.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ ${XLAT_TABLES_LIB_SRCS} \
${IMX_GIC_SOURCES}
USE_COHERENT_MEM := 1
@@ -49,3 +51,7 @@
BL32_SIZE ?= 0x2000000
$(eval $(call add_define,BL32_SIZE))
+
+ifeq (${SPD},trusty)
+ BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+endif
diff --git a/plat/imx/imx8m/include/ddrc.h b/plat/imx/imx8m/include/ddrc.h
new file mode 100644
index 0000000..55af3ff
--- /dev/null
+++ b/plat/imx/imx8m/include/ddrc.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2019-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_DDRC_H
+#define IMX_DDRC_H
+
+#define DDRC_IPS_BASE_ADDR(X) (0x3d400000 + ((X) * 0x2000000))
+#define DDRC_DDR_SS_GPR0 0x3d000000
+
+/* DWC ddr umctl2 REGs offset*/
+/**********************/
+#define DDRC_MSTR(X) (DDRC_IPS_BASE_ADDR(X) + 0x00)
+#define DDRC_STAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x04)
+#define DDRC_MSTR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x08)
+#define DDRC_MRCTRL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x10)
+#define DDRC_MRCTRL1(X) (DDRC_IPS_BASE_ADDR(X) + 0x14)
+#define DDRC_MRSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x18)
+#define DDRC_MRCTRL2(X) (DDRC_IPS_BASE_ADDR(X) + 0x1c)
+#define DDRC_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x20)
+#define DDRC_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x24)
+#define DDRC_MSTR2(X) (DDRC_IPS_BASE_ADDR(X) + 0x28)
+#define DDRC_PWRCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x30)
+#define DDRC_PWRTMG(X) (DDRC_IPS_BASE_ADDR(X) + 0x34)
+#define DDRC_HWLPCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x38)
+#define DDRC_HWFFCCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x3c)
+#define DDRC_HWFFCSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x40)
+#define DDRC_RFSHCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x50)
+#define DDRC_RFSHCTL1(X) (DDRC_IPS_BASE_ADDR(X) + 0x54)
+#define DDRC_RFSHCTL2(X) (DDRC_IPS_BASE_ADDR(X) + 0x58)
+#define DDRC_RFSHCTL3(X) (DDRC_IPS_BASE_ADDR(X) + 0x60)
+#define DDRC_RFSHTMG(X) (DDRC_IPS_BASE_ADDR(X) + 0x64)
+#define DDRC_ECCCFG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x70)
+#define DDRC_ECCCFG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x74)
+#define DDRC_ECCSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x78)
+#define DDRC_ECCCLR(X) (DDRC_IPS_BASE_ADDR(X) + 0x7c)
+#define DDRC_ECCERRCNT(X) (DDRC_IPS_BASE_ADDR(X) + 0x80)
+#define DDRC_ECCCADDR0(X) (DDRC_IPS_BASE_ADDR(X) + 0x84)
+#define DDRC_ECCCADDR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x88)
+#define DDRC_ECCCSYN0(X) (DDRC_IPS_BASE_ADDR(X) + 0x8c)
+#define DDRC_ECCCSYN1(X) (DDRC_IPS_BASE_ADDR(X) + 0x90)
+#define DDRC_ECCCSYN2(X) (DDRC_IPS_BASE_ADDR(X) + 0x94)
+#define DDRC_ECCBITMASK0(X) (DDRC_IPS_BASE_ADDR(X) + 0x98)
+#define DDRC_ECCBITMASK1(X) (DDRC_IPS_BASE_ADDR(X) + 0x9c)
+#define DDRC_ECCBITMASK2(X) (DDRC_IPS_BASE_ADDR(X) + 0xa0)
+#define DDRC_ECCUADDR0(X) (DDRC_IPS_BASE_ADDR(X) + 0xa4)
+#define DDRC_ECCUADDR1(X) (DDRC_IPS_BASE_ADDR(X) + 0xa8)
+#define DDRC_ECCUSYN0(X) (DDRC_IPS_BASE_ADDR(X) + 0xac)
+#define DDRC_ECCUSYN1(X) (DDRC_IPS_BASE_ADDR(X) + 0xb0)
+#define DDRC_ECCUSYN2(X) (DDRC_IPS_BASE_ADDR(X) + 0xb4)
+#define DDRC_ECCPOISONADDR0(X) (DDRC_IPS_BASE_ADDR(X) + 0xb8)
+#define DDRC_ECCPOISONADDR1(X) (DDRC_IPS_BASE_ADDR(X) + 0xbc)
+#define DDRC_CRCPARCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0xc0)
+#define DDRC_CRCPARCTL1(X) (DDRC_IPS_BASE_ADDR(X) + 0xc4)
+#define DDRC_CRCPARCTL2(X) (DDRC_IPS_BASE_ADDR(X) + 0xc8)
+#define DDRC_CRCPARSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0xcc)
+#define DDRC_INIT0(X) (DDRC_IPS_BASE_ADDR(X) + 0xd0)
+#define DDRC_INIT1(X) (DDRC_IPS_BASE_ADDR(X) + 0xd4)
+#define DDRC_INIT2(X) (DDRC_IPS_BASE_ADDR(X) + 0xd8)
+#define DDRC_INIT3(X) (DDRC_IPS_BASE_ADDR(X) + 0xdc)
+#define DDRC_INIT4(X) (DDRC_IPS_BASE_ADDR(X) + 0xe0)
+#define DDRC_INIT5(X) (DDRC_IPS_BASE_ADDR(X) + 0xe4)
+#define DDRC_INIT6(X) (DDRC_IPS_BASE_ADDR(X) + 0xe8)
+#define DDRC_INIT7(X) (DDRC_IPS_BASE_ADDR(X) + 0xec)
+#define DDRC_DIMMCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0xf0)
+#define DDRC_RANKCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0xf4)
+#define DDRC_DRAMTMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x100)
+#define DDRC_DRAMTMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x104)
+#define DDRC_DRAMTMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x108)
+#define DDRC_DRAMTMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x10c)
+#define DDRC_DRAMTMG4(X) (DDRC_IPS_BASE_ADDR(X) + 0x110)
+#define DDRC_DRAMTMG5(X) (DDRC_IPS_BASE_ADDR(X) + 0x114)
+#define DDRC_DRAMTMG6(X) (DDRC_IPS_BASE_ADDR(X) + 0x118)
+#define DDRC_DRAMTMG7(X) (DDRC_IPS_BASE_ADDR(X) + 0x11c)
+#define DDRC_DRAMTMG8(X) (DDRC_IPS_BASE_ADDR(X) + 0x120)
+#define DDRC_DRAMTMG9(X) (DDRC_IPS_BASE_ADDR(X) + 0x124)
+#define DDRC_DRAMTMG10(X) (DDRC_IPS_BASE_ADDR(X) + 0x128)
+#define DDRC_DRAMTMG11(X) (DDRC_IPS_BASE_ADDR(X) + 0x12c)
+#define DDRC_DRAMTMG12(X) (DDRC_IPS_BASE_ADDR(X) + 0x130)
+#define DDRC_DRAMTMG13(X) (DDRC_IPS_BASE_ADDR(X) + 0x134)
+#define DDRC_DRAMTMG14(X) (DDRC_IPS_BASE_ADDR(X) + 0x138)
+#define DDRC_DRAMTMG15(X) (DDRC_IPS_BASE_ADDR(X) + 0x13C)
+#define DDRC_DRAMTMG16(X) (DDRC_IPS_BASE_ADDR(X) + 0x140)
+#define DDRC_DRAMTMG17(X) (DDRC_IPS_BASE_ADDR(X) + 0x144)
+
+#define DDRC_ZQCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x180)
+#define DDRC_ZQCTL1(X) (DDRC_IPS_BASE_ADDR(X) + 0x184)
+#define DDRC_ZQCTL2(X) (DDRC_IPS_BASE_ADDR(X) + 0x188)
+#define DDRC_ZQSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x18c)
+#define DDRC_DFITMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x190)
+#define DDRC_DFITMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x194)
+#define DDRC_DFILPCFG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x198)
+#define DDRC_DFILPCFG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x19c)
+#define DDRC_DFIUPD0(X) (DDRC_IPS_BASE_ADDR(X) + 0x1a0)
+#define DDRC_DFIUPD1(X) (DDRC_IPS_BASE_ADDR(X) + 0x1a4)
+#define DDRC_DFIUPD2(X) (DDRC_IPS_BASE_ADDR(X) + 0x1a8)
+#define DDRC_DFIMISC(X) (DDRC_IPS_BASE_ADDR(X) + 0x1b0)
+#define DDRC_DFITMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x1b4)
+#define DDRC_DFITMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x1b8)
+#define DDRC_DFISTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x1bc)
+
+#define DDRC_DBICTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x1c0)
+#define DDRC_DFIPHYMSTR(X) (DDRC_IPS_BASE_ADDR(X) + 0x1c4)
+#define DDRC_TRAINCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x1d0)
+#define DDRC_TRAINCTL1(X) (DDRC_IPS_BASE_ADDR(X) + 0x1d4)
+#define DDRC_TRAINCTL2(X) (DDRC_IPS_BASE_ADDR(X) + 0x1d8)
+#define DDRC_TRAINSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x1dc)
+#define DDRC_ADDRMAP0(X) (DDRC_IPS_BASE_ADDR(X) + 0x200)
+#define DDRC_ADDRMAP1(X) (DDRC_IPS_BASE_ADDR(X) + 0x204)
+#define DDRC_ADDRMAP2(X) (DDRC_IPS_BASE_ADDR(X) + 0x208)
+#define DDRC_ADDRMAP3(X) (DDRC_IPS_BASE_ADDR(X) + 0x20c)
+#define DDRC_ADDRMAP4(X) (DDRC_IPS_BASE_ADDR(X) + 0x210)
+#define DDRC_ADDRMAP5(X) (DDRC_IPS_BASE_ADDR(X) + 0x214)
+#define DDRC_ADDRMAP6(X) (DDRC_IPS_BASE_ADDR(X) + 0x218)
+#define DDRC_ADDRMAP7(X) (DDRC_IPS_BASE_ADDR(X) + 0x21c)
+#define DDRC_ADDRMAP8(X) (DDRC_IPS_BASE_ADDR(X) + 0x220)
+#define DDRC_ADDRMAP9(X) (DDRC_IPS_BASE_ADDR(X) + 0x224)
+#define DDRC_ADDRMAP10(X) (DDRC_IPS_BASE_ADDR(X) + 0x228)
+#define DDRC_ADDRMAP11(X) (DDRC_IPS_BASE_ADDR(X) + 0x22c)
+
+#define DDRC_ODTCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x240)
+#define DDRC_ODTMAP(X) (DDRC_IPS_BASE_ADDR(X) + 0x244)
+#define DDRC_SCHED(X) (DDRC_IPS_BASE_ADDR(X) + 0x250)
+#define DDRC_SCHED1(X) (DDRC_IPS_BASE_ADDR(X) + 0x254)
+#define DDRC_PERFHPR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x25c)
+#define DDRC_PERFLPR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x264)
+#define DDRC_PERFWR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x26c)
+#define DDRC_PERFVPR1(X) (DDRC_IPS_BASE_ADDR(X) + 0x274)
+
+#define DDRC_PERFVPW1(X) (DDRC_IPS_BASE_ADDR(X) + 0x278)
+
+#define DDRC_DQMAP0(X) (DDRC_IPS_BASE_ADDR(X) + 0x280)
+#define DDRC_DQMAP1(X) (DDRC_IPS_BASE_ADDR(X) + 0x284)
+#define DDRC_DQMAP2(X) (DDRC_IPS_BASE_ADDR(X) + 0x288)
+#define DDRC_DQMAP3(X) (DDRC_IPS_BASE_ADDR(X) + 0x28c)
+#define DDRC_DQMAP4(X) (DDRC_IPS_BASE_ADDR(X) + 0x290)
+#define DDRC_DQMAP5(X) (DDRC_IPS_BASE_ADDR(X) + 0x294)
+#define DDRC_DBG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x300)
+#define DDRC_DBG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x304)
+#define DDRC_DBGCAM(X) (DDRC_IPS_BASE_ADDR(X) + 0x308)
+#define DDRC_DBGCMD(X) (DDRC_IPS_BASE_ADDR(X) + 0x30c)
+#define DDRC_DBGSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x310)
+
+#define DDRC_SWCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x320)
+#define DDRC_SWSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x324)
+#define DDRC_OCPARCFG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x330)
+#define DDRC_OCPARCFG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x334)
+#define DDRC_OCPARCFG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x338)
+#define DDRC_OCPARCFG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x33c)
+#define DDRC_OCPARSTAT0(X) (DDRC_IPS_BASE_ADDR(X) + 0x340)
+#define DDRC_OCPARSTAT1(X) (DDRC_IPS_BASE_ADDR(X) + 0x344)
+#define DDRC_OCPARWLOG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x348)
+#define DDRC_OCPARWLOG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x34c)
+#define DDRC_OCPARWLOG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x350)
+#define DDRC_OCPARAWLOG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x354)
+#define DDRC_OCPARAWLOG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x358)
+#define DDRC_OCPARRLOG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x35c)
+#define DDRC_OCPARRLOG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x360)
+#define DDRC_OCPARARLOG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x364)
+#define DDRC_OCPARARLOG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x368)
+#define DDRC_POISONCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x36C)
+#define DDRC_POISONSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x370)
+#define DDRC_ADVECCINDEX(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ADVECCSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ECCPOISONPAT0(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ECCPOISONPAT1(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_ECCPOISONPAT2(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+#define DDRC_HIFCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0x3)
+
+#define DDRC_PSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0x3fc)
+#define DDRC_PCCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x400)
+#define DDRC_PCFGR_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x404)
+#define DDRC_PCFGR_1(X) (DDRC_IPS_BASE_ADDR(X) + 1 * 0xb0 + 0x404)
+#define DDRC_PCFGR_2(X) (DDRC_IPS_BASE_ADDR(X) + 2 * 0xb0 + 0x404)
+#define DDRC_PCFGR_3(X) (DDRC_IPS_BASE_ADDR(X) + 3 * 0xb0 + 0x404)
+#define DDRC_PCFGW_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x408)
+#define DDRC_PCFGW_1(X) (DDRC_IPS_BASE_ADDR(X) + 1 * 0xb0 + 0x408)
+#define DDRC_PCFGW_2(X) (DDRC_IPS_BASE_ADDR(X) + 2 * 0xb0 + 0x408)
+#define DDRC_PCFGW_3(X) (DDRC_IPS_BASE_ADDR(X) + 3 * 0xb0 + 0x408)
+#define DDRC_PCFGC_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x40c)
+#define DDRC_PCFGIDMASKCH(X) (DDRC_IPS_BASE_ADDR(X) + 0x410)
+#define DDRC_PCFGIDVALUECH(X) (DDRC_IPS_BASE_ADDR(X) + 0x414)
+#define DDRC_PCTRL_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x490)
+#define DDRC_PCTRL_1(X) (DDRC_IPS_BASE_ADDR(X) + 0x490 + 1 * 0xb0)
+#define DDRC_PCTRL_2(X) (DDRC_IPS_BASE_ADDR(X) + 0x490 + 2 * 0xb0)
+#define DDRC_PCTRL_3(X) (DDRC_IPS_BASE_ADDR(X) + 0x490 + 3 * 0xb0)
+#define DDRC_PCFGQOS0_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x494)
+#define DDRC_PCFGQOS1_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x498)
+#define DDRC_PCFGWQOS0_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x49c)
+#define DDRC_PCFGWQOS1_0(X) (DDRC_IPS_BASE_ADDR(X) + 0x4a0)
+#define DDRC_SARBASE0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf04)
+#define DDRC_SARSIZE0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf08)
+#define DDRC_SBRCTL(X) (DDRC_IPS_BASE_ADDR(X) + 0xf24)
+#define DDRC_SBRSTAT(X) (DDRC_IPS_BASE_ADDR(X) + 0xf28)
+#define DDRC_SBRWDATA0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf2c)
+#define DDRC_SBRWDATA1(X) (DDRC_IPS_BASE_ADDR(X) + 0xf30)
+#define DDRC_PDCH(X) (DDRC_IPS_BASE_ADDR(X) + 0xf34)
+
+/* SHADOW registers */
+#define DDRC_FREQ1_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x2020)
+#define DDRC_FREQ1_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x2024)
+#define DDRC_FREQ1_RFSHCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x2050)
+#define DDRC_FREQ1_RFSHTMG(X) (DDRC_IPS_BASE_ADDR(X) + 0x2064)
+#define DDRC_FREQ1_INIT3(X) (DDRC_IPS_BASE_ADDR(X) + 0x20dc)
+#define DDRC_FREQ1_INIT4(X) (DDRC_IPS_BASE_ADDR(X) + 0x20e0)
+#define DDRC_FREQ1_INIT6(X) (DDRC_IPS_BASE_ADDR(X) + 0x20e8)
+#define DDRC_FREQ1_INIT7(X) (DDRC_IPS_BASE_ADDR(X) + 0x20ec)
+#define DDRC_FREQ1_DRAMTMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x2100)
+#define DDRC_FREQ1_DRAMTMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x2104)
+#define DDRC_FREQ1_DRAMTMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x2108)
+#define DDRC_FREQ1_DRAMTMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x210c)
+#define DDRC_FREQ1_DRAMTMG4(X) (DDRC_IPS_BASE_ADDR(X) + 0x2110)
+#define DDRC_FREQ1_DRAMTMG5(X) (DDRC_IPS_BASE_ADDR(X) + 0x2114)
+#define DDRC_FREQ1_DRAMTMG6(X) (DDRC_IPS_BASE_ADDR(X) + 0x2118)
+#define DDRC_FREQ1_DRAMTMG7(X) (DDRC_IPS_BASE_ADDR(X) + 0x211c)
+#define DDRC_FREQ1_DRAMTMG8(X) (DDRC_IPS_BASE_ADDR(X) + 0x2120)
+#define DDRC_FREQ1_DRAMTMG9(X) (DDRC_IPS_BASE_ADDR(X) + 0x2124)
+#define DDRC_FREQ1_DRAMTMG10(X) (DDRC_IPS_BASE_ADDR(X) + 0x2128)
+#define DDRC_FREQ1_DRAMTMG11(X) (DDRC_IPS_BASE_ADDR(X) + 0x212c)
+#define DDRC_FREQ1_DRAMTMG12(X) (DDRC_IPS_BASE_ADDR(X) + 0x2130)
+#define DDRC_FREQ1_DRAMTMG13(X) (DDRC_IPS_BASE_ADDR(X) + 0x2134)
+#define DDRC_FREQ1_DRAMTMG14(X) (DDRC_IPS_BASE_ADDR(X) + 0x2138)
+#define DDRC_FREQ1_DRAMTMG15(X) (DDRC_IPS_BASE_ADDR(X) + 0x213C)
+#define DDRC_FREQ1_DRAMTMG16(X) (DDRC_IPS_BASE_ADDR(X) + 0x2140)
+#define DDRC_FREQ1_DRAMTMG17(X) (DDRC_IPS_BASE_ADDR(X) + 0x2144)
+#define DDRC_FREQ1_ZQCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x2180)
+#define DDRC_FREQ1_DFITMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x2190)
+#define DDRC_FREQ1_DFITMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x2194)
+#define DDRC_FREQ1_DFITMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x21b4)
+#define DDRC_FREQ1_DFITMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x21b8)
+#define DDRC_FREQ1_ODTCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x2240)
+
+#define DDRC_FREQ2_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x3020)
+#define DDRC_FREQ2_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x3024)
+#define DDRC_FREQ2_RFSHCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x3050)
+#define DDRC_FREQ2_RFSHTMG(X) (DDRC_IPS_BASE_ADDR(X) + 0x3064)
+#define DDRC_FREQ2_INIT3(X) (DDRC_IPS_BASE_ADDR(X) + 0x30dc)
+#define DDRC_FREQ2_INIT4(X) (DDRC_IPS_BASE_ADDR(X) + 0x30e0)
+#define DDRC_FREQ2_INIT6(X) (DDRC_IPS_BASE_ADDR(X) + 0x30e8)
+#define DDRC_FREQ2_INIT7(X) (DDRC_IPS_BASE_ADDR(X) + 0x30ec)
+#define DDRC_FREQ2_DRAMTMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x3100)
+#define DDRC_FREQ2_DRAMTMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x3104)
+#define DDRC_FREQ2_DRAMTMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x3108)
+#define DDRC_FREQ2_DRAMTMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x310c)
+#define DDRC_FREQ2_DRAMTMG4(X) (DDRC_IPS_BASE_ADDR(X) + 0x3110)
+#define DDRC_FREQ2_DRAMTMG5(X) (DDRC_IPS_BASE_ADDR(X) + 0x3114)
+#define DDRC_FREQ2_DRAMTMG6(X) (DDRC_IPS_BASE_ADDR(X) + 0x3118)
+#define DDRC_FREQ2_DRAMTMG7(X) (DDRC_IPS_BASE_ADDR(X) + 0x311c)
+#define DDRC_FREQ2_DRAMTMG8(X) (DDRC_IPS_BASE_ADDR(X) + 0x3120)
+#define DDRC_FREQ2_DRAMTMG9(X) (DDRC_IPS_BASE_ADDR(X) + 0x3124)
+#define DDRC_FREQ2_DRAMTMG10(X) (DDRC_IPS_BASE_ADDR(X) + 0x3128)
+#define DDRC_FREQ2_DRAMTMG11(X) (DDRC_IPS_BASE_ADDR(X) + 0x312c)
+#define DDRC_FREQ2_DRAMTMG12(X) (DDRC_IPS_BASE_ADDR(X) + 0x3130)
+#define DDRC_FREQ2_DRAMTMG13(X) (DDRC_IPS_BASE_ADDR(X) + 0x3134)
+#define DDRC_FREQ2_DRAMTMG14(X) (DDRC_IPS_BASE_ADDR(X) + 0x3138)
+#define DDRC_FREQ2_DRAMTMG15(X) (DDRC_IPS_BASE_ADDR(X) + 0x313C)
+#define DDRC_FREQ2_DRAMTMG16(X) (DDRC_IPS_BASE_ADDR(X) + 0x3140)
+#define DDRC_FREQ2_DRAMTMG17(X) (DDRC_IPS_BASE_ADDR(X) + 0x3144)
+#define DDRC_FREQ2_ZQCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x3180)
+#define DDRC_FREQ2_DFITMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x3190)
+#define DDRC_FREQ2_DFITMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x3194)
+#define DDRC_FREQ2_DFITMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x31b4)
+#define DDRC_FREQ2_DFITMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x31b8)
+#define DDRC_FREQ2_ODTCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x3240)
+
+#define DDRC_FREQ3_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x4020)
+#define DDRC_FREQ3_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x4024)
+#define DDRC_FREQ3_RFSHCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x4050)
+#define DDRC_FREQ3_RFSHTMG(X) (DDRC_IPS_BASE_ADDR(X) + 0x4064)
+#define DDRC_FREQ3_INIT3(X) (DDRC_IPS_BASE_ADDR(X) + 0x40dc)
+#define DDRC_FREQ3_INIT4(X) (DDRC_IPS_BASE_ADDR(X) + 0x40e0)
+#define DDRC_FREQ3_INIT6(X) (DDRC_IPS_BASE_ADDR(X) + 0x40e8)
+#define DDRC_FREQ3_INIT7(X) (DDRC_IPS_BASE_ADDR(X) + 0x40ec)
+#define DDRC_FREQ3_DRAMTMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x4100)
+#define DDRC_FREQ3_DRAMTMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x4104)
+#define DDRC_FREQ3_DRAMTMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x4108)
+#define DDRC_FREQ3_DRAMTMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x410c)
+#define DDRC_FREQ3_DRAMTMG4(X) (DDRC_IPS_BASE_ADDR(X) + 0x4110)
+#define DDRC_FREQ3_DRAMTMG5(X) (DDRC_IPS_BASE_ADDR(X) + 0x4114)
+#define DDRC_FREQ3_DRAMTMG6(X) (DDRC_IPS_BASE_ADDR(X) + 0x4118)
+#define DDRC_FREQ3_DRAMTMG7(X) (DDRC_IPS_BASE_ADDR(X) + 0x411c)
+#define DDRC_FREQ3_DRAMTMG8(X) (DDRC_IPS_BASE_ADDR(X) + 0x4120)
+#define DDRC_FREQ3_DRAMTMG9(X) (DDRC_IPS_BASE_ADDR(X) + 0x4124)
+#define DDRC_FREQ3_DRAMTMG10(X) (DDRC_IPS_BASE_ADDR(X) + 0x4128)
+#define DDRC_FREQ3_DRAMTMG11(X) (DDRC_IPS_BASE_ADDR(X) + 0x412c)
+#define DDRC_FREQ3_DRAMTMG12(X) (DDRC_IPS_BASE_ADDR(X) + 0x4130)
+#define DDRC_FREQ3_DRAMTMG13(X) (DDRC_IPS_BASE_ADDR(X) + 0x4134)
+#define DDRC_FREQ3_DRAMTMG14(X) (DDRC_IPS_BASE_ADDR(X) + 0x4138)
+#define DDRC_FREQ3_DRAMTMG15(X) (DDRC_IPS_BASE_ADDR(X) + 0x413C)
+#define DDRC_FREQ3_DRAMTMG16(X) (DDRC_IPS_BASE_ADDR(X) + 0x4140)
+
+#define DDRC_FREQ3_ZQCTL0(X) (DDRC_IPS_BASE_ADDR(X) + 0x4180)
+#define DDRC_FREQ3_DFITMG0(X) (DDRC_IPS_BASE_ADDR(X) + 0x4190)
+#define DDRC_FREQ3_DFITMG1(X) (DDRC_IPS_BASE_ADDR(X) + 0x4194)
+#define DDRC_FREQ3_DFITMG2(X) (DDRC_IPS_BASE_ADDR(X) + 0x41b4)
+#define DDRC_FREQ3_DFITMG3(X) (DDRC_IPS_BASE_ADDR(X) + 0x41b8)
+#define DDRC_FREQ3_ODTCFG(X) (DDRC_IPS_BASE_ADDR(X) + 0x4240)
+#define DDRC_DFITMG0_SHADOW(X) (DDRC_IPS_BASE_ADDR(X) + 0x2190)
+#define DDRC_DFITMG1_SHADOW(X) (DDRC_IPS_BASE_ADDR(X) + 0x2194)
+#define DDRC_DFITMG2_SHADOW(X) (DDRC_IPS_BASE_ADDR(X) + 0x21b4)
+#define DDRC_DFITMG3_SHADOW(X) (DDRC_IPS_BASE_ADDR(X) + 0x21b8)
+#define DDRC_ODTCFG_SHADOW(X) (DDRC_IPS_BASE_ADDR(X) + 0x2240)
+
+#define DRC_PERF_MON_BASE_ADDR(X) (0x3d800000 + ((X) * 0x2000000))
+#define DRC_PERF_MON_CNT0_CTL(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x0)
+#define DRC_PERF_MON_CNT1_CTL(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x4)
+#define DRC_PERF_MON_CNT2_CTL(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x8)
+#define DRC_PERF_MON_CNT3_CTL(X) (DRC_PERF_MON_BASE_ADDR(X) + 0xC)
+#define DRC_PERF_MON_CNT0_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x20)
+#define DRC_PERF_MON_CNT1_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x24)
+#define DRC_PERF_MON_CNT2_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x28)
+#define DRC_PERF_MON_CNT3_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x2C)
+#define DRC_PERF_MON_DPCR_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x30)
+#define DRC_PERF_MON_MRR0_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x40)
+#define DRC_PERF_MON_MRR1_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x44)
+#define DRC_PERF_MON_MRR2_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x48)
+#define DRC_PERF_MON_MRR3_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x4C)
+#define DRC_PERF_MON_MRR4_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x50)
+#define DRC_PERF_MON_MRR5_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x54)
+#define DRC_PERF_MON_MRR6_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x58)
+#define DRC_PERF_MON_MRR7_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x5C)
+#define DRC_PERF_MON_MRR8_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x60)
+#define DRC_PERF_MON_MRR9_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x64)
+#define DRC_PERF_MON_MRR10_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x68)
+#define DRC_PERF_MON_MRR11_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x6C)
+#define DRC_PERF_MON_MRR12_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x70)
+#define DRC_PERF_MON_MRR13_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x74)
+#define DRC_PERF_MON_MRR14_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x78)
+#define DRC_PERF_MON_MRR15_DAT(X) (DRC_PERF_MON_BASE_ADDR(X) + 0x7C)
+
+#define dwc_ddrphy_apb_rd(addr) mmio_read_32(IMX_DDRPHY_BASE + 4 * (addr))
+#define dwc_ddrphy_apb_wr(addr, val) mmio_write_32(IMX_DDRPHY_BASE + 4 * (addr), val)
+
+#endif /*IMX_DDRC_H */
diff --git a/plat/imx/imx8m/include/dram.h b/plat/imx/imx8m/include/dram.h
new file mode 100644
index 0000000..ad11a27
--- /dev/null
+++ b/plat/imx/imx8m/include/dram.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRAM_H
+#define DRAM_H
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <lib/utils_def.h>
+
+#include <ddrc.h>
+#include <platform_def.h>
+
+#define DDRC_LPDDR4 BIT(5)
+#define DDRC_DDR4 BIT(4)
+#define DDRC_DDR3L BIT(0)
+#define DDR_TYPE_MASK U(0x3f)
+#define ACTIVE_RANK_MASK U(0x3)
+
+/* reg & config param */
+struct dram_cfg_param {
+ unsigned int reg;
+ unsigned int val;
+};
+
+struct dram_timing_info {
+ /* umctl2 config */
+ struct dram_cfg_param *ddrc_cfg;
+ unsigned int ddrc_cfg_num;
+ /* ddrphy config */
+ struct dram_cfg_param *ddrphy_cfg;
+ unsigned int ddrphy_cfg_num;
+ /* ddr fsp train info */
+ struct dram_fsp_msg *fsp_msg;
+ unsigned int fsp_msg_num;
+ /* ddr phy trained CSR */
+ struct dram_cfg_param *ddrphy_trained_csr;
+ unsigned int ddrphy_trained_csr_num;
+ /* ddr phy PIE */
+ struct dram_cfg_param *ddrphy_pie;
+ unsigned int ddrphy_pie_num;
+ /* initialized fsp table */
+ unsigned int fsp_table[4];
+};
+
+struct dram_info {
+ int dram_type;
+ unsigned int num_rank;
+ uint32_t num_fsp;
+ int current_fsp;
+ int boot_fsp;
+ bool bypass_mode;
+ struct dram_timing_info *timing_info;
+ /* mr, emr, emr2, emr3, mr11, mr12, mr22, mr14 */
+ uint32_t mr_table[3][8];
+};
+
+extern struct dram_info dram_info;
+
+void dram_info_init(unsigned long dram_timing_base);
+void dram_umctl2_init(struct dram_timing_info *timing);
+void dram_phy_init(struct dram_timing_info *timing);
+
+/* dram retention */
+void dram_enter_retention(void);
+void dram_exit_retention(void);
+
+void dram_clock_switch(unsigned int target_drate, bool bypass_mode);
+
+/* dram frequency change */
+void lpddr4_swffc(struct dram_info *info, unsigned int init_fsp, unsigned int fsp_index);
+void ddr4_swffc(struct dram_info *dram_info, unsigned int pstate);
+
+#endif /* DRAM_H */
diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h
index 29b8ecf..a41030e 100644
--- a/plat/imx/imx8m/include/gpc.h
+++ b/plat/imx/imx8m/include/gpc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -69,5 +69,7 @@
void imx_set_sys_lpm(unsigned last_core, bool retention);
void imx_set_rbc_count(void);
void imx_clear_rbc_count(void);
+void imx_anamix_override(bool enter);
+void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on);
#endif /*IMX8M_GPC_H */
diff --git a/plat/imx/imx8m/include/imx8m_csu.h b/plat/imx/imx8m/include/imx8m_csu.h
new file mode 100644
index 0000000..dc634ed
--- /dev/null
+++ b/plat/imx/imx8m/include/imx8m_csu.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_CSU_H
+#define IMX_CSU_H
+
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+
+#define CSU_SEC_LEVEL_0 0xff
+#define CSU_SEC_LEVEL_1 0xbb
+#define CSU_SEC_LEVEL_2 0x3f
+#define CSU_SEC_LEVEL_3 0x3b
+#define CSU_SEC_LEVEL_4 0x33
+#define CSU_SEC_LEVEL_5 0x22
+#define CSU_SEC_LEVEL_6 0x03
+#define CSU_SEC_LEVEL_7 0x0
+
+#define LOCKED 0x1
+#define UNLOCKED 0x0
+
+#define CSLx_REG(x) (IMX_CSU_BASE + ((x) / 2) * 4)
+#define CSLx_LOCK(x) ((0x1 << (((x) % 2) * 16 + 8)))
+#define CSLx_CFG(x, n) ((x) << (((n) % 2) * 16))
+
+#define CSU_HP_REG(x) (IMX_CSU_BASE + ((x) / 16) * 4 + 0x200)
+#define CSU_HP_LOCK(x) ((0x1 << (((x) % 16) * 2 + 1)))
+#define CSU_HP_CFG(x, n) ((x) << (((n) % 16) * 2))
+
+#define CSU_SA_REG(x) (IMX_CSU_BASE + 0x218)
+#define CSU_SA_LOCK(x) ((0x1 << (((x) % 16) * 2 + 1)))
+#define CSU_SA_CFG(x, n) ((x) << (((n) % 16) * 2))
+
+#define CSU_HPCONTROL_REG(x) (IMX_CSU_BASE + (((x) / 16) * 4) + 0x358)
+#define CSU_HPCONTROL_LOCK(x) ((0x1 << (((x) % 16) * 2 + 1)))
+#define CSU_HPCONTROL_CFG(x, n) ((x) << (((n) % 16) * 2))
+
+enum csu_cfg_type {
+ CSU_INVALID,
+ CSU_CSL,
+ CSU_HP,
+ CSU_SA,
+ CSU_HPCONTROL,
+};
+
+struct imx_csu_cfg {
+ enum csu_cfg_type type;
+ uint16_t idx;
+ uint16_t lock : 1;
+ uint16_t csl_level : 8;
+ uint16_t hp : 1;
+ uint16_t sa : 1;
+ uint16_t hpctrl : 1;
+};
+
+#define CSU_CSLx(i, level, lk) \
+ {CSU_CSL, .idx = (i), .csl_level = (level), .lock = (lk),}
+
+#define CSU_HPx(i, val, lk) \
+ {CSU_HP, .idx = (i), .hp = (val), .lock = (lk), }
+
+#define CSU_SA(i, val, lk) \
+ {CSU_SA, .idx = (i), .sa = (val), .lock = (lk), }
+
+#define CSU_HPCTRL(i, val, lk) \
+ {CSU_HPCONTROL, .idx = (i), .hpctrl = (val), .lock = (lk), }
+
+void imx_csu_init(const struct imx_csu_cfg *csu_cfg);
+
+#endif /* IMX_CSU_H */
diff --git a/plat/imx/imx8m/include/imx_rdc.h b/plat/imx/imx8m/include/imx_rdc.h
index e25b0e6..a6e10a7 100644
--- a/plat/imx/imx8m/include/imx_rdc.h
+++ b/plat/imx/imx8m/include/imx_rdc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, NXP. All rights reserved.
+ * Copyright (c) 2019-2022 NXP. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <lib/utils_def.h>
+#include <imx_sec_def.h>
#include <platform_def.h>
#define MDAn(x) (IMX_RDC_BASE + 0x200 + (x) * 4)
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index d9c9110..68eb534 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,7 +19,7 @@
#include <drivers/console.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <imx8qm_pads.h>
diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk
index f35fa00..c57edbe 100644
--- a/plat/imx/imx8qm/platform.mk
+++ b/plat/imx/imx8qm/platform.mk
@@ -1,9 +1,12 @@
#
-# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
PLAT_INCLUDES := -Iplat/imx/imx8qm/include \
-Iplat/imx/common/include \
@@ -23,11 +26,10 @@
plat/imx/common/imx8_psci.c \
plat/imx/common/imx_sip_svc.c \
plat/imx/common/imx_sip_handler.c \
- lib/xlat_tables/aarch64/xlat_tables.c \
- lib/xlat_tables/xlat_tables_common.c \
lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a72.S \
drivers/arm/cci/cci.c \
+ ${XLAT_TABLES_LIB_SRCS} \
${IMX_GIC_SOURCES} \
include plat/imx/common/sci/sci_api.mk
diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c
index 3739cd6..1da8d29 100644
--- a/plat/imx/imx8qx/imx8qx_bl31_setup.c
+++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,7 +19,7 @@
#include <drivers/console.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/mmio.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <imx8qx_pads.h>
diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk
index b25be07..85b5f3d 100644
--- a/plat/imx/imx8qx/platform.mk
+++ b/plat/imx/imx8qx/platform.mk
@@ -1,9 +1,12 @@
#
-# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
PLAT_INCLUDES := -Iplat/imx/imx8qx/include \
-Iplat/imx/common/include \
@@ -23,9 +26,8 @@
plat/imx/common/imx_sip_svc.c \
plat/imx/common/imx_sip_handler.c \
plat/common/plat_psci_common.c \
- lib/xlat_tables/xlat_tables_common.c \
- lib/xlat_tables/aarch64/xlat_tables.c \
lib/cpus/aarch64/cortex_a35.S \
+ ${XLAT_TABLES_LIB_SRCS} \
${IMX_GIC_SOURCES} \
include plat/imx/common/sci/sci_api.mk
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 6e67502..211a7b7 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-2021, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2021, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,6 +23,7 @@
#include "ccu/ncore_ccu.h"
#include "qspi/cadence_qspi.h"
#include "socfpga_emac.h"
+#include "socfpga_f2sdram_manager.h"
#include "socfpga_handoff.h"
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
@@ -71,8 +72,8 @@
watchdog_init(get_wdt_clk());
- console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE,
- &console);
+ console_16550_register(PLAT_INTEL_UART_BASE, get_uart_clk(),
+ PLAT_BAUDRATE, &console);
socfpga_delay_timer_init();
init_ncore_ccu();
@@ -81,8 +82,10 @@
mailbox_init();
agx_mmc_init();
- if (!intel_mailbox_is_fpga_not_ready())
- socfpga_bridges_enable();
+ if (!intel_mailbox_is_fpga_not_ready()) {
+ socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK |
+ FPGA2SOC_MASK);
+ }
}
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 168236b..b1b9514 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +14,7 @@
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables.h>
+#include "ccu/ncore_ccu.h"
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
@@ -41,8 +42,8 @@
mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
- console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
- &console);
+ console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+ PLAT_BAUDRATE, &console);
/*
* Check params passed from BL31 should not be NULL,
*/
@@ -114,6 +115,8 @@
(uint64_t)plat_secondary_cpus_bl31_entry);
mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
+
+ ncore_enable_ocram_firewall();
}
const mmap_region_t plat_agilex_mmap[] = {
diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h
index 20667f0..f39d475 100644
--- a/plat/intel/soc/agilex/include/agilex_clock_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/intel/soc/agilex/include/agilex_noc.h b/plat/intel/soc/agilex/include/agilex_noc.h
deleted file mode 100644
index 22db3e2..0000000
--- a/plat/intel/soc/agilex/include/agilex_noc.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef AGX_NOC_H
-#define AGX_NOC_H
-
-
-#define AXI_AP (1<<0)
-#define FPGA2SOC (1<<16)
-#define MPU (1<<24)
-#define AGX_NOC_PER_SCR_NAND 0xffd21000
-#define AGX_NOC_PER_SCR_NAND_DATA 0xffd21004
-#define AGX_NOC_PER_SCR_USB0 0xffd2100c
-#define AGX_NOC_PER_SCR_USB1 0xffd21010
-#define AGX_NOC_PER_SCR_SPI_M0 0xffd2101c
-#define AGX_NOC_PER_SCR_SPI_M1 0xffd21020
-#define AGX_NOC_PER_SCR_SPI_S0 0xffd21024
-#define AGX_NOC_PER_SCR_SPI_S1 0xffd21028
-#define AGX_NOC_PER_SCR_EMAC0 0xffd2102c
-#define AGX_NOC_PER_SCR_EMAC1 0xffd21030
-#define AGX_NOC_PER_SCR_EMAC2 0xffd21034
-#define AGX_NOC_PER_SCR_SDMMC 0xffd21040
-#define AGX_NOC_PER_SCR_GPIO0 0xffd21044
-#define AGX_NOC_PER_SCR_GPIO1 0xffd21048
-#define AGX_NOC_PER_SCR_I2C0 0xffd21050
-#define AGX_NOC_PER_SCR_I2C1 0xffd21058
-#define AGX_NOC_PER_SCR_I2C2 0xffd2105c
-#define AGX_NOC_PER_SCR_I2C3 0xffd21060
-#define AGX_NOC_PER_SCR_SP_TIMER0 0xffd21064
-#define AGX_NOC_PER_SCR_SP_TIMER1 0xffd21068
-#define AGX_NOC_PER_SCR_UART0 0xffd2106c
-#define AGX_NOC_PER_SCR_UART1 0xffd21070
-
-
-#define AGX_NOC_SYS_SCR_DMA_ECC 0xffd21108
-#define AGX_NOC_SYS_SCR_EMAC0RX_ECC 0xffd2110c
-#define AGX_NOC_SYS_SCR_EMAC0TX_ECC 0xffd21110
-#define AGX_NOC_SYS_SCR_EMAC1RX_ECC 0xffd21114
-#define AGX_NOC_SYS_SCR_EMAC1TX_ECC 0xffd21118
-#define AGX_NOC_SYS_SCR_EMAC2RX_ECC 0xffd2111c
-#define AGX_NOC_SYS_SCR_EMAC2TX_ECC 0xffd21120
-#define AGX_NOC_SYS_SCR_NAND_ECC 0xffd2112c
-#define AGX_NOC_SYS_SCR_NAND_READ_ECC 0xffd21130
-#define AGX_NOC_SYS_SCR_NAND_WRITE_ECC 0xffd21134
-#define AGX_NOC_SYS_SCR_OCRAM_ECC 0xffd21138
-#define AGX_NOC_SYS_SCR_SDMMC_ECC 0xffd21140
-#define AGX_NOC_SYS_SCR_USB0_ECC 0xffd21144
-#define AGX_NOC_SYS_SCR_USB1_ECC 0xffd21148
-#define AGX_NOC_SYS_SCR_CLK_MGR 0xffd2114c
-#define AGX_NOC_SYS_SCR_IO_MGR 0xffd21154
-#define AGX_NOC_SYS_SCR_RST_MGR 0xffd21158
-#define AGX_NOC_SYS_SCR_SYS_MGR 0xffd2115c
-#define AGX_NOC_SYS_SCR_OSC0_TIMER 0xffd21160
-#define AGX_NOC_SYS_SCR_OSC1_TIMER 0xffd21164
-#define AGX_NOC_SYS_SCR_WATCHDOG0 0xffd21168
-#define AGX_NOC_SYS_SCR_WATCHDOG1 0xffd2116c
-#define AGX_NOC_SYS_SCR_WATCHDOG2 0xffd21170
-#define AGX_NOC_SYS_SCR_WATCHDOG3 0xffd21174
-#define AGX_NOC_SYS_SCR_DAP 0xffd21178
-#define AGX_NOC_SYS_SCR_L4_NOC_PROBES 0xffd21190
-#define AGX_NOC_SYS_SCR_L4_NOC_QOS 0xffd21194
-
-#define AGX_CCU_NOC_BRIDGE_CPU0_RAM 0xf7004688
-#define AGX_CCU_NOC_BRIDGE_IOM_RAM 0xf7004688
-
-#endif
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index 9c87e45..b216ab1 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -19,6 +19,9 @@
#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x2000000
/* Register Mapping */
+#define SOCFPGA_CCU_NOC_REG_BASE 0xf7000000
+#define SOCFPGA_F2SDRAMMGR_REG_BASE U(0xf8024000)
+
#define SOCFPGA_MMC_REG_BASE 0xff808000
#define SOCFPGA_RSTMGR_REG_BASE 0xffd11000
@@ -29,5 +32,9 @@
#define SOCFPGA_SOC2FPGA_SCR_REG_BASE 0xffd21200
#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE 0xffd21300
-#endif /* PLAT_SOCFPGA_DEF_H */
+/* Platform specific system counter */
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ get_cpu_clk()
+uint32_t get_cpu_clk(void);
+
+#endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 10a3eec..ccb4e07 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -26,6 +26,7 @@
lib/xlat_tables/xlat_tables_common.c \
plat/intel/soc/common/aarch64/platform_common.c \
plat/intel/soc/common/aarch64/plat_helpers.S \
+ plat/intel/soc/common/drivers/ccu/ncore_ccu.c \
plat/intel/soc/common/socfpga_delay_timer.c
BL2_SOURCES += \
@@ -44,17 +45,20 @@
plat/intel/soc/agilex/soc/agilex_memory_controller.c \
plat/intel/soc/agilex/soc/agilex_mmc.c \
plat/intel/soc/agilex/soc/agilex_pinmux.c \
- plat/intel/soc/common/bl2_plat_mem_params_desc.c \
+ plat/intel/soc/common/bl2_plat_mem_params_desc.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_firewall.c \
plat/intel/soc/common/soc/socfpga_handoff.c \
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c \
- plat/intel/soc/common/soc/socfpga_system_manager.c \
plat/intel/soc/common/drivers/qspi/cadence_qspi.c \
- plat/intel/soc/common/drivers/wdt/watchdog.c \
- plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+ plat/intel/soc/common/drivers/wdt/watchdog.c
+
+include lib/zlib/zlib.mk
+PLAT_INCLUDES += -Ilib/zlib
+BL2_SOURCES += $(ZLIB_SOURCES)
BL31_SOURCES += \
drivers/arm/cci/cci.c \
@@ -62,8 +66,10 @@
lib/cpus/aarch64/cortex_a53.S \
plat/common/plat_psci_common.c \
plat/intel/soc/agilex/bl31_plat_setup.c \
+ plat/intel/soc/agilex/soc/agilex_clock_manager.c \
plat/intel/soc/common/socfpga_psci.c \
plat/intel/soc/common/socfpga_sip_svc.c \
+ plat/intel/soc/common/socfpga_sip_svc_v2.c \
plat/intel/soc/common/socfpga_topology.c \
plat/intel/soc/common/sip/socfpga_sip_ecc.c \
plat/intel/soc/common/sip/socfpga_sip_fcs.c \
diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
index 4efd713..76b9937 100644
--- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c
+++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -387,3 +387,13 @@
return mmc_clk;
}
+
+/* Get cpu freq clock */
+uint32_t get_cpu_clk(void)
+{
+ uint32_t cpu_clk;
+
+ cpu_clk = get_l3_clk()/PLAT_SYS_COUNTER_CONVERT_TO_MHZ;
+
+ return cpu_clk;
+}
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index 5cb9b69..213fd3c 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -102,7 +102,7 @@
* ---------------------------------------------
*/
func plat_crash_console_init
- mov_imm x0, PLAT_UART0_BASE
+ mov_imm x0, CRASH_CONSOLE_BASE
mov_imm x1, PLAT_UART_CLOCK
mov_imm x2, PLAT_BAUDRATE
b console_16550_core_init
@@ -116,7 +116,7 @@
* ---------------------------------------------
*/
func plat_crash_console_putc
- mov_imm x1, PLAT_UART0_BASE
+ mov_imm x1, CRASH_CONSOLE_BASE
b console_16550_core_putc
endfunc plat_crash_console_putc
diff --git a/plat/intel/soc/common/bl2_plat_mem_params_desc.c b/plat/intel/soc/common/bl2_plat_mem_params_desc.c
index 4f75665..187c53a 100644
--- a/plat/intel/soc/common/bl2_plat_mem_params_desc.c
+++ b/plat/intel/soc/common/bl2_plat_mem_params_desc.c
@@ -22,58 +22,58 @@
#ifdef SCP_BL2_BASE
/* Fill SCP_BL2 related information if it exists */
{
- .image_id = SCP_BL2_IMAGE_ID,
+ .image_id = SCP_BL2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = SCP_BL2_BASE,
- .image_info.image_max_size = SCP_BL2_SIZE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = SCP_BL2_BASE,
+ .image_info.image_max_size = SCP_BL2_SIZE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
},
#endif /* SCP_BL2_BASE */
#ifdef EL3_PAYLOAD_BASE
/* Fill EL3 payload related information (BL31 is EL3 payload)*/
{
- .image_id = BL31_IMAGE_ID,
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = EL3_PAYLOAD_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = EL3_PAYLOAD_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t,
- IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
},
#else /* EL3_PAYLOAD_BASE */
/* Fill BL31 related information */
{
- .image_id = BL31_IMAGE_ID,
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = BL31_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
- .image_info.image_base = BL31_BASE,
- .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
- .next_handoff_image_id = BL33_IMAGE_ID,
+ .next_handoff_image_id = BL33_IMAGE_ID,
},
#endif /* EL3_PAYLOAD_BASE */
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index d4716cf..d9a238e 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -118,6 +118,7 @@
mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
}
+
uint32_t init_ncore_ccu(void)
{
uint32_t status;
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 7859493..a31adf7 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -168,6 +168,7 @@
#define PLAT_UART1_BASE (0xFFC02100)
#define CRASH_CONSOLE_BASE PLAT_UART0_BASE
+#define PLAT_INTEL_UART_BASE PLAT_UART0_BASE
#ifndef SIMICS_BUILD
#define PLAT_BAUDRATE (115200)
@@ -191,7 +192,7 @@
* System counter frequency related constants
******************************************************************************/
#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000)
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ (400)
+#define PLAT_SYS_COUNTER_CONVERT_TO_MHZ (1000000)
#define PLAT_INTEL_SOCFPGA_GICD_BASE PLAT_GICD_BASE
#define PLAT_INTEL_SOCFPGA_GICC_BASE PLAT_GICC_BASE
diff --git a/plat/intel/soc/common/include/socfpga_f2sdram_manager.h b/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
new file mode 100644
index 0000000..82bb6cb
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_f2sdram_manager.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_F2SDRAMMANAGER_H
+#define SOCFPGA_F2SDRAMMANAGER_H
+
+#include "socfpga_plat_def.h"
+
+/* FPGA2SDRAM Register Map */
+#define SOCFPGA_F2SDRAMMGR_SIDEBANDMGR_FLAGINSTATUS0 0x14
+#define SOCFPGA_F2SDRAMMGR_SIDEBANDMGR_FLAGOUTCLR0 0x54
+#define SOCFPGA_F2SDRAMMGR_SIDEBANDMGR_FLAGOUTSET0 0x50
+
+#define FLAGOUTSETCLR_F2SDRAM0_ENABLE (BIT(1))
+#define FLAGOUTSETCLR_F2SDRAM1_ENABLE (BIT(4))
+#define FLAGOUTSETCLR_F2SDRAM2_ENABLE (BIT(7))
+
+#define FLAGOUTSETCLR_F2SDRAM0_IDLEREQ (BIT(0))
+#define FLAGOUTSETCLR_F2SDRAM1_IDLEREQ (BIT(3))
+#define FLAGOUTSETCLR_F2SDRAM2_IDLEREQ (BIT(6))
+#define FLAGINTSTATUS_F2SDRAM0_IDLEACK (BIT(1))
+#define FLAGINTSTATUS_F2SDRAM1_IDLEACK (BIT(5))
+#define FLAGINTSTATUS_F2SDRAM2_IDLEACK (BIT(9))
+#define FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN (BIT(2))
+#define FLAGOUTSETCLR_F2SDRAM1_FORCE_DRAIN (BIT(5))
+#define FLAGOUTSETCLR_F2SDRAM2_FORCE_DRAIN (BIT(8))
+
+#define FLAGINTSTATUS_F2SOC_RESPEMPTY (BIT(3))
+#define FLAGINTSTATUS_F2SDRAM0_RESPEMPTY (BIT(3))
+#define FLAGINTSTATUS_F2SDRAM1_RESPEMPTY (BIT(7))
+#define FLAGINTSTATUS_F2SDRAM2_RESPEMPTY (BIT(11))
+
+#define SOCFPGA_F2SDRAMMGR(_reg) (SOCFPGA_F2SDRAMMGR_REG_BASE \
+ + (SOCFPGA_F2SDRAMMGR_##_reg))
+
+#endif /* SOCFPGA_F2SDRAMMGR_H */
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
index ff10d36..893551d 100644
--- a/plat/intel/soc/common/include/socfpga_fcs.h
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -9,33 +9,300 @@
/* FCS Definitions */
-#define FCS_RANDOM_WORD_SIZE 8U
-#define FCS_PROV_DATA_WORD_SIZE 44U
+#define FCS_RANDOM_WORD_SIZE 8U
+#define FCS_PROV_DATA_WORD_SIZE 44U
+#define FCS_SHA384_WORD_SIZE 12U
-#define FCS_RANDOM_BYTE_SIZE (FCS_RANDOM_WORD_SIZE * 4U)
-#define FCS_PROV_DATA_BYTE_SIZE (FCS_PROV_DATA_WORD_SIZE * 4U)
+#define FCS_RANDOM_BYTE_SIZE (FCS_RANDOM_WORD_SIZE * 4U)
+#define FCS_RANDOM_EXT_MAX_WORD_SIZE 1020U
+#define FCS_PROV_DATA_BYTE_SIZE (FCS_PROV_DATA_WORD_SIZE * 4U)
+#define FCS_SHA384_BYTE_SIZE (FCS_SHA384_WORD_SIZE * 4U)
-#define FCS_CRYPTION_DATA_0 0x10100
+#define FCS_RANDOM_EXT_OFFSET 3
+#define FCS_MODE_DECRYPT 0x0
+#define FCS_MODE_ENCRYPT 0x1
+#define FCS_ENCRYPTION_DATA_0 0x10100
+#define FCS_DECRYPTION_DATA_0 0x10102
+#define FCS_OWNER_ID_OFFSET 0xC
+#define FCS_CRYPTION_CRYPTO_HEADER 0x07000000
+#define FCS_CRYPTION_RESP_WORD_SIZE 4U
+#define FCS_CRYPTION_RESP_SIZE_OFFSET 3U
+
+#define PSGSIGMA_TEARDOWN_MAGIC 0xB852E2A4
+#define PSGSIGMA_SESSION_ID_ONE 0x1
+#define PSGSIGMA_UNKNOWN_SESSION 0xFFFFFFFF
+
+#define RESERVED_AS_ZERO 0x0
+/* FCS Single cert */
+
+#define FCS_BIG_CNTR_SEL 0x1
+
+#define FCS_SVN_CNTR_0_SEL 0x2
+#define FCS_SVN_CNTR_1_SEL 0x3
+#define FCS_SVN_CNTR_2_SEL 0x4
+#define FCS_SVN_CNTR_3_SEL 0x5
+
+#define FCS_BIG_CNTR_VAL_MAX 495U
+#define FCS_SVN_CNTR_VAL_MAX 64U
+
+/* FCS Attestation Cert Request Parameter */
+
+#define FCS_ATTEST_FIRMWARE_CERT 0x01
+#define FCS_ATTEST_DEV_ID_SELF_SIGN_CERT 0x02
+#define FCS_ATTEST_DEV_ID_ENROLL_CERT 0x04
+#define FCS_ATTEST_ENROLL_SELF_SIGN_CERT 0x08
+#define FCS_ATTEST_ALIAS_CERT 0x10
+#define FCS_ATTEST_CERT_MAX_REQ_PARAM 0xFF
+
+/* FCS Crypto Service */
+
+#define FCS_CS_KEY_OBJ_MAX_WORD_SIZE 88U
+#define FCS_CS_KEY_INFO_MAX_WORD_SIZE 36U
+#define FCS_CS_KEY_RESP_STATUS_MASK 0xFF
+#define FCS_CS_KEY_RESP_STATUS_OFFSET 16U
+
+#define FCS_CS_FIELD_SIZE_MASK 0xFFFF
+#define FCS_CS_FIELD_FLAG_OFFSET 24
+#define FCS_CS_FIELD_FLAG_INIT BIT(0)
+#define FCS_CS_FIELD_FLAG_UPDATE BIT(1)
+#define FCS_CS_FIELD_FLAG_FINALIZE BIT(2)
+
+#define FCS_AES_MAX_DATA_SIZE 0x10000000 /* 256 MB */
+#define FCS_AES_MIN_DATA_SIZE 0x20 /* 32 Byte */
+#define FCS_AES_CMD_MAX_WORD_SIZE 15U
+
+#define FCS_GET_DIGEST_CMD_MAX_WORD_SIZE 7U
+#define FCS_GET_DIGEST_RESP_MAX_WORD_SIZE 19U
+#define FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE 23U
+#define FCS_MAC_VERIFY_RESP_MAX_WORD_SIZE 4U
+#define FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET 8U
+
+#define FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE 5U
+#define FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE 7U
+#define FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE 43U
+#define FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE 17U
+#define FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE 52U
+#define FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE 29U
/* FCS Payload Structure */
+typedef struct fcs_rng_payload_t {
+ uint32_t session_id;
+ uint32_t context_id;
+ uint32_t crypto_header;
+ uint32_t size;
+} fcs_rng_payload;
+
+typedef struct fcs_encrypt_payload_t {
+ uint32_t first_word;
+ uint32_t src_addr;
+ uint32_t src_size;
+ uint32_t dst_addr;
+ uint32_t dst_size;
+} fcs_encrypt_payload;
-typedef struct fcs_crypt_payload_t {
+typedef struct fcs_decrypt_payload_t {
uint32_t first_word;
+ uint32_t owner_id[2];
uint32_t src_addr;
uint32_t src_size;
uint32_t dst_addr;
uint32_t dst_size;
-} fcs_crypt_payload;
+} fcs_decrypt_payload;
+
+typedef struct fcs_encrypt_ext_payload_t {
+ uint32_t session_id;
+ uint32_t context_id;
+ uint32_t crypto_header;
+ uint32_t src_addr;
+ uint32_t src_size;
+ uint32_t dst_addr;
+ uint32_t dst_size;
+} fcs_encrypt_ext_payload;
+
+typedef struct fcs_decrypt_ext_payload_t {
+ uint32_t session_id;
+ uint32_t context_id;
+ uint32_t crypto_header;
+ uint32_t owner_id[2];
+ uint32_t src_addr;
+ uint32_t src_size;
+ uint32_t dst_addr;
+ uint32_t dst_size;
+} fcs_decrypt_ext_payload;
+
+typedef struct psgsigma_teardown_msg_t {
+ uint32_t reserved_word;
+ uint32_t magic_word;
+ uint32_t session_id;
+} psgsigma_teardown_msg;
+
+typedef struct fcs_cntr_set_preauth_payload_t {
+ uint32_t first_word;
+ uint32_t counter_value;
+} fcs_cntr_set_preauth_payload;
+
+typedef struct fcs_cs_key_payload_t {
+ uint32_t session_id;
+ uint32_t reserved0;
+ uint32_t reserved1;
+ uint32_t key_id;
+} fcs_cs_key_payload;
+
+typedef struct fcs_crypto_service_data_t {
+ uint32_t session_id;
+ uint32_t context_id;
+ uint32_t key_id;
+ uint32_t crypto_param_size;
+ uint64_t crypto_param;
+ uint8_t is_updated;
+} fcs_crypto_service_data;
+
+typedef struct fcs_crypto_service_aes_data_t {
+ uint32_t session_id;
+ uint32_t context_id;
+ uint32_t param_size;
+ uint32_t key_id;
+ uint32_t crypto_param[7];
+ uint8_t is_updated;
+} fcs_crypto_service_aes_data;
/* Functions Definitions */
uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
uint32_t *mbox_error);
+int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
+ uint32_t size, uint32_t *send_id);
uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
uint32_t *send_id);
uint32_t intel_fcs_get_provision_data(uint32_t *send_id);
-uint32_t intel_fcs_cryption(uint32_t mode, uint32_t src_addr,
- uint32_t src_size, uint32_t dst_addr,
- uint32_t dst_size, uint32_t *send_id);
+uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type,
+ int32_t counter_value,
+ uint32_t test_bit,
+ uint32_t *mbox_error);
+uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t dst_size,
+ uint32_t *send_id);
+
+uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t dst_size,
+ uint32_t *send_id);
+
+int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+int intel_fcs_decryption_ext(uint32_t sesion_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error);
+int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error);
+int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
+ uint32_t *mbox_error);
+
+int intel_fcs_create_cert_on_reload(uint32_t cert_request,
+ uint32_t *mbox_error);
+int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
+ uint32_t *dst_size, uint32_t *mbox_error);
+
+int intel_fcs_open_crypto_service_session(uint32_t *session_id,
+ uint32_t *mbox_error);
+int intel_fcs_close_crypto_service_session(uint32_t session_id,
+ uint32_t *mbox_error);
+
+int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
+ uint32_t *mbox_error);
+int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
+ uint32_t *mbox_error);
+int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error);
+int intel_fcs_get_digest_update_finalize(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint8_t is_finalised, uint32_t *mbox_error);
+
+int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error);
+int intel_fcs_mac_verify_update_finalize(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t data_size, uint8_t is_finalised,
+ uint32_t *mbox_error);
+
+int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error);
+int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error);
+int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
+ uint32_t context_id, uint32_t key_id,
+ uint32_t param_size, uint64_t param_data,
+ uint32_t *mbox_error);
+int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id,
+ uint32_t context_id, uint32_t src_addr,
+ uint32_t src_size, uint64_t dst_addr,
+ uint32_t *dst_size, uint8_t is_finalised,
+ uint32_t *mbox_error);
+
+int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
+ uint32_t context_id, uint32_t key_id,
+ uint32_t param_size, uint64_t param_data,
+ uint32_t *mbox_error);
+int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
+ uint32_t context_id, uint32_t src_addr,
+ uint32_t src_size, uint64_t dst_addr,
+ uint32_t *dst_size, uint32_t data_size,
+ uint8_t is_finalised, uint32_t *mbox_error);
+
+int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error);
+int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error);
+int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint64_t param_addr,
+ uint32_t param_size, uint32_t *mbox_error);
+int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
+ uint32_t context_id, uint64_t src_addr,
+ uint32_t src_size, uint64_t dst_addr,
+ uint32_t dst_size, uint8_t is_finalised,
+ uint32_t *send_id);
#endif /* SOCFPGA_FCS_H */
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 6b7e0fc..1f4b2a4 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -10,87 +10,124 @@
#include <lib/utils_def.h>
-#define MBOX_OFFSET 0xffa30000
+#define MBOX_OFFSET 0xffa30000
-#define MBOX_ATF_CLIENT_ID 0x1U
-#define MBOX_MAX_JOB_ID 0xFU
-#define MBOX_MAX_IND_JOB_ID (MBOX_MAX_JOB_ID - 1U)
-#define MBOX_JOB_ID MBOX_MAX_JOB_ID
-
+#define MBOX_ATF_CLIENT_ID 0x1U
+#define MBOX_MAX_JOB_ID 0xFU
+#define MBOX_MAX_IND_JOB_ID (MBOX_MAX_JOB_ID - 1U)
+#define MBOX_JOB_ID MBOX_MAX_JOB_ID
+#define MBOX_TEST_BIT BIT(31)
/* Mailbox Shared Memory Register Map */
-#define MBOX_CIN 0x00
-#define MBOX_ROUT 0x04
-#define MBOX_URG 0x08
-#define MBOX_INT 0x0C
-#define MBOX_COUT 0x20
-#define MBOX_RIN 0x24
-#define MBOX_STATUS 0x2C
-#define MBOX_CMD_BUFFER 0x40
-#define MBOX_RESP_BUFFER 0xC0
+#define MBOX_CIN 0x00
+#define MBOX_ROUT 0x04
+#define MBOX_URG 0x08
+#define MBOX_INT 0x0C
+#define MBOX_COUT 0x20
+#define MBOX_RIN 0x24
+#define MBOX_STATUS 0x2C
+#define MBOX_CMD_BUFFER 0x40
+#define MBOX_RESP_BUFFER 0xC0
/* Mailbox SDM doorbell */
-#define MBOX_DOORBELL_TO_SDM 0x400
-#define MBOX_DOORBELL_FROM_SDM 0x480
+#define MBOX_DOORBELL_TO_SDM 0x400
+#define MBOX_DOORBELL_FROM_SDM 0x480
/* Mailbox commands */
-#define MBOX_CMD_NOOP 0x00
-#define MBOX_CMD_SYNC 0x01
-#define MBOX_CMD_RESTART 0x02
-#define MBOX_CMD_CANCEL 0x03
-#define MBOX_CMD_VAB_SRC_CERT 0x0B
-#define MBOX_CMD_GET_IDCODE 0x10
-#define MBOX_CMD_REBOOT_HPS 0x47
+#define MBOX_CMD_NOOP 0x00
+#define MBOX_CMD_SYNC 0x01
+#define MBOX_CMD_RESTART 0x02
+#define MBOX_CMD_CANCEL 0x03
+#define MBOX_CMD_VAB_SRC_CERT 0x0B
+#define MBOX_CMD_GET_IDCODE 0x10
+#define MBOX_CMD_GET_USERCODE 0x13
+#define MBOX_CMD_GET_CHIPID 0x12
+#define MBOX_CMD_REBOOT_HPS 0x47
/* Reconfiguration Commands */
-#define MBOX_CONFIG_STATUS 0x04
-#define MBOX_RECONFIG 0x06
-#define MBOX_RECONFIG_DATA 0x08
-#define MBOX_RECONFIG_STATUS 0x09
+#define MBOX_CONFIG_STATUS 0x04
+#define MBOX_RECONFIG 0x06
+#define MBOX_RECONFIG_DATA 0x08
+#define MBOX_RECONFIG_STATUS 0x09
+
+/* HWMON Commands */
+#define MBOX_HWMON_READVOLT 0x18
+#define MBOX_HWMON_READTEMP 0x19
+
/* QSPI Commands */
-#define MBOX_CMD_QSPI_OPEN 0x32
-#define MBOX_CMD_QSPI_CLOSE 0x33
-#define MBOX_CMD_QSPI_SET_CS 0x34
-#define MBOX_CMD_QSPI_DIRECT 0x3B
+#define MBOX_CMD_QSPI_OPEN 0x32
+#define MBOX_CMD_QSPI_CLOSE 0x33
+#define MBOX_CMD_QSPI_SET_CS 0x34
+#define MBOX_CMD_QSPI_DIRECT 0x3B
/* RSU Commands */
-#define MBOX_GET_SUBPARTITION_TABLE 0x5A
-#define MBOX_RSU_STATUS 0x5B
-#define MBOX_RSU_UPDATE 0x5C
-#define MBOX_HPS_STAGE_NOTIFY 0x5D
+#define MBOX_GET_SUBPARTITION_TABLE 0x5A
+#define MBOX_RSU_STATUS 0x5B
+#define MBOX_RSU_UPDATE 0x5C
+#define MBOX_HPS_STAGE_NOTIFY 0x5D
/* FCS Command */
-#define MBOX_FCS_GET_PROVISION 0x7B
-#define MBOX_FCS_ENCRYPT_REQ 0x7E
-#define MBOX_FCS_DECRYPT_REQ 0x7F
-#define MBOX_FCS_RANDOM_GEN 0x80
+#define MBOX_FCS_GET_PROVISION 0x7B
+#define MBOX_FCS_CNTR_SET_PREAUTH 0x7C
+#define MBOX_FCS_ENCRYPT_REQ 0x7E
+#define MBOX_FCS_DECRYPT_REQ 0x7F
+#define MBOX_FCS_RANDOM_GEN 0x80
+#define MBOX_FCS_AES_CRYPT_REQ 0x81
+#define MBOX_FCS_GET_DIGEST_REQ 0x82
+#define MBOX_FCS_MAC_VERIFY_REQ 0x83
+#define MBOX_FCS_ECDSA_HASH_SIGN_REQ 0x84
+#define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ 0x85
+#define MBOX_FCS_ECDSA_HASH_SIG_VERIFY 0x86
+#define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY 0x87
+#define MBOX_FCS_ECDSA_GET_PUBKEY 0x88
+#define MBOX_FCS_ECDH_REQUEST 0x89
+#define MBOX_FCS_OPEN_CS_SESSION 0xA0
+#define MBOX_FCS_CLOSE_CS_SESSION 0xA1
+#define MBOX_FCS_IMPORT_CS_KEY 0xA5
+#define MBOX_FCS_EXPORT_CS_KEY 0xA6
+#define MBOX_FCS_REMOVE_CS_KEY 0xA7
+#define MBOX_FCS_GET_CS_KEY_INFO 0xA8
+
+/* PSG SIGMA Commands */
+#define MBOX_PSG_SIGMA_TEARDOWN 0xD5
+
+/* Attestation Commands */
+#define MBOX_CREATE_CERT_ON_RELOAD 0x180
+#define MBOX_GET_ATTESTATION_CERT 0x181
+#define MBOX_ATTESTATION_SUBKEY 0x182
+#define MBOX_GET_MEASUREMENT 0x183
+
+/* Miscellaneous commands */
+#define MBOX_GET_ROM_PATCH_SHA384 0x1B0
/* Mailbox Definitions */
-#define CMD_DIRECT 0
-#define CMD_INDIRECT 1
-#define CMD_CASUAL 0
-#define CMD_URGENT 1
+#define CMD_DIRECT 0
+#define CMD_INDIRECT 1
+#define CMD_CASUAL 0
+#define CMD_URGENT 1
-#define MBOX_WORD_BYTE 4U
-#define MBOX_RESP_BUFFER_SIZE 16
-#define MBOX_CMD_BUFFER_SIZE 32
+#define MBOX_WORD_BYTE 4U
+#define MBOX_RESP_BUFFER_SIZE 16
+#define MBOX_CMD_BUFFER_SIZE 32
+#define MBOX_INC_HEADER_MAX_WORD_SIZE 1024U
/* Execution states for HPS_STAGE_NOTIFY */
-#define HPS_EXECUTION_STATE_FSBL 0
-#define HPS_EXECUTION_STATE_SSBL 1
-#define HPS_EXECUTION_STATE_OS 2
+#define HPS_EXECUTION_STATE_FSBL 0
+#define HPS_EXECUTION_STATE_SSBL 1
+#define HPS_EXECUTION_STATE_OS 2
/* Status Response */
-#define MBOX_RET_OK 0
-#define MBOX_RET_ERROR -1
-#define MBOX_NO_RESPONSE -2
-#define MBOX_WRONG_ID -3
-#define MBOX_BUFFER_FULL -4
-#define MBOX_TIMEOUT -2047
+#define MBOX_RET_OK 0
+#define MBOX_RET_ERROR -1
+#define MBOX_NO_RESPONSE -2
+#define MBOX_WRONG_ID -3
+#define MBOX_BUFFER_FULL -4
+#define MBOX_BUSY -5
+#define MBOX_TIMEOUT -2047
/* Reconfig Status Response */
#define RECONFIG_STATUS_STATE 0
@@ -115,34 +152,55 @@
/* Mailbox Macros */
-#define MBOX_ENTRY_TO_ADDR(_buf, ptr) (MBOX_OFFSET + (MBOX_##_buf##_BUFFER) \
- + MBOX_WORD_BYTE * (ptr))
+#define MBOX_ENTRY_TO_ADDR(_buf, ptr) (MBOX_OFFSET + (MBOX_##_buf##_BUFFER) \
+ + MBOX_WORD_BYTE * (ptr))
/* Mailbox interrupt flags and masks */
-#define MBOX_INT_FLAG_COE 0x1
-#define MBOX_INT_FLAG_RIE 0x2
-#define MBOX_INT_FLAG_UAE 0x100
-#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3)
-#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8)))
+#define MBOX_INT_FLAG_COE 0x1
+#define MBOX_INT_FLAG_RIE 0x2
+#define MBOX_INT_FLAG_UAE 0x100
+#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3)
+#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8)))
/* Mailbox response and status */
-#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff)
-#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12)
-#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28)
-#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24)
-#define MBOX_STATUS_UA_MASK (1<<8)
+#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x000007ff)
+#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12)
+#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28)
+#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24)
+#define MBOX_STATUS_UA_MASK (1<<8)
/* Mailbox command and response */
-#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28)
-#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24)
-#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12)
-#define MBOX_INDIRECT(val) ((val) << 11)
-#define MBOX_CMD_MASK(header) ((header) & 0x7ff)
+#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28)
+#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24)
+#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12)
+#define MBOX_INDIRECT(val) ((val) << 11)
+#define MBOX_CMD_MASK(header) ((header) & 0x7ff)
+
+/* Mailbox payload */
+#define MBOX_DATA_MAX_LEN 0x3ff
+#define MBOX_PAYLOAD_FLAG_BUSY BIT(0)
/* RSU Macros */
-#define RSU_VERSION_ACMF BIT(8)
-#define RSU_VERSION_ACMF_MASK 0xff00
+#define RSU_VERSION_ACMF BIT(8)
+#define RSU_VERSION_ACMF_MASK 0xff00
+
+/* Config Status Macros */
+#define CONFIG_STATUS_WORD_SIZE 16U
+#define CONFIG_STATUS_FW_VER_OFFSET 1
+#define CONFIG_STATUS_FW_VER_MASK 0x00FFFFFF
+/* Data structure */
+
+typedef struct mailbox_payload {
+ uint32_t header;
+ uint32_t data[MBOX_DATA_MAX_LEN];
+} mailbox_payload_t;
+
+typedef struct mailbox_container {
+ uint32_t flag;
+ uint32_t index;
+ mailbox_payload_t *payload;
+} mailbox_container_t;
/* Mailbox Function Definitions */
@@ -156,8 +214,13 @@
unsigned int *resp_len);
int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
unsigned int len, unsigned int indirect);
+int mailbox_send_cmd_async_ext(uint32_t header_cmd, uint32_t *args,
+ unsigned int len);
int mailbox_read_response(uint32_t *job_id, uint32_t *response,
unsigned int *resp_len);
+int mailbox_read_response_async(uint32_t *job_id, uint32_t *header,
+ uint32_t *response, unsigned int *resp_len,
+ uint8_t ignore_client_id);
int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
unsigned int *resp_len);
@@ -171,5 +234,7 @@
int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len);
int mailbox_rsu_update(uint32_t *flash_offset);
int mailbox_hps_stage_notify(uint32_t execution_stage);
+int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf);
+int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf);
#endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_noc.h b/plat/intel/soc/common/include/socfpga_noc.h
new file mode 100644
index 0000000..e3c0f73
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_noc.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_NOC_H
+#define SOCFPGA_NOC_H
+
+/* Macros */
+#define SCR_AXI_AP_MASK BIT(24)
+#define SCR_FPGA2SOC_MASK BIT(16)
+#define SCR_MPU_MASK BIT(0)
+#define DISABLE_L4_FIREWALL (SCR_AXI_AP_MASK | SCR_FPGA2SOC_MASK \
+ | SCR_MPU_MASK)
+#define DISABLE_BRIDGE_FIREWALL 0x0ffe0101
+
+#define SOCFPGA_CCU_NOC(_ctrl, _dev) (SOCFPGA_CCU_NOC_REG_BASE \
+ + (SOCFPGA_CCU_NOC_##_ctrl##_##_dev))
+
+#define SOCFPGA_L4_PER_SCR(_reg) (SOCFPGA_L4_PER_SCR_REG_BASE \
+ + (SOCFPGA_NOC_FW_L4_PER_SCR_##_reg))
+
+#define SOCFPGA_L4_SYS_SCR(_reg) (SOCFPGA_L4_SYS_SCR_REG_BASE \
+ + (SOCFPGA_NOC_FW_L4_SYS_SCR_##_reg))
+
+/* L3 Interconnect Register Map */
+#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_REGISTER 0x0000
+#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_DATA 0x0004
+#define SOCFPGA_NOC_FW_L4_PER_SCR_USB0_REGISTER 0x000c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_USB1_REGISTER 0x0010
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER0 0x001c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER1 0x0020
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE0 0x0024
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE1 0x0028
+#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC0 0x002c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC1 0x0030
+#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC2 0x0034
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SDMMC 0x0040
+#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO0 0x0044
+#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO1 0x0048
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C0 0x0050
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C1 0x0054
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C2 0x0058
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C3 0x005c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C4 0x0060
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER0 0x0064
+#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER1 0x0068
+#define SOCFPGA_NOC_FW_L4_PER_SCR_UART0 0x006c
+#define SOCFPGA_NOC_FW_L4_PER_SCR_UART1 0x0070
+
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_DMA_ECC 0x0008
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC 0x000c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC 0x0010
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC 0x0014
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC 0x0018
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC 0x001c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC 0x0020
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_ECC 0x002c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_READ_ECC 0x0030
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC 0x0034
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_OCRAM_ECC 0x0038
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_SDMMC_ECC 0x0040
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB0_ECC 0x0044
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_ECC 0x0048
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_CLK_MGR 0x004c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_IO_MGR 0x0054
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_RST_MGR 0x0058
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_SYS_MGR 0x005c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC0_TIMER 0x0060
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC1_TIMER 0x0064
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG0 0x0068
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG1 0x006c
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG2 0x0070
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG3 0x0074
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_DAP 0x0078
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES 0x0090
+#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_QOS 0x0094
+
+/* CCU NOC Register Map */
+
+#define SOCFPGA_CCU_NOC_CPU0_RAM0 0x04688
+#define SOCFPGA_CCU_NOC_IOM_RAM0 0x18628
+
+#define SOCFPGA_CCU_NOC_ADMASK_P_MASK BIT(0)
+#define SOCFPGA_CCU_NOC_ADMASK_NS_MASK BIT(1)
+
+/* Function Definitions */
+
+void enable_ns_peripheral_access(void);
+void enable_ns_bridge_access(void);
+void enable_ns_ocram_access(void);
+void enable_ocram_firewall(void);
+
+#endif
diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h
index ca38f62..9d389e3 100644
--- a/plat/intel/soc/common/include/socfpga_private.h
+++ b/plat/intel/soc/common/include/socfpga_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -55,6 +55,8 @@
void socfpga_gic_driver_init(void);
+void socfpga_delay_timer_init_args(void);
+
uint32_t socfpga_get_spsr_for_bl32_entry(void);
uint32_t socfpga_get_spsr_for_bl33_entry(void);
diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h
index a976df7..cce16ab 100644
--- a/plat/intel/soc/common/include/socfpga_reset_manager.h
+++ b/plat/intel/soc/common/include/socfpga_reset_manager.h
@@ -9,11 +9,22 @@
#include "socfpga_plat_def.h"
+#define SOCFPGA_BRIDGE_ENABLE BIT(0)
+#define SOCFPGA_BRIDGE_HAS_MASK BIT(1)
+
+#define SOC2FPGA_MASK (1<<0)
+#define LWHPS2FPGA_MASK (1<<1)
+#define FPGA2SOC_MASK (1<<2)
+#define F2SDRAM0_MASK (1<<3)
+#define F2SDRAM1_MASK (1<<4)
+#define F2SDRAM2_MASK (1<<5)
/* Register Mapping */
#define SOCFPGA_RSTMGR_STAT 0x000
#define SOCFPGA_RSTMGR_HDSKEN 0x010
+#define SOCFPGA_RSTMGR_HDSKREQ 0x014
+#define SOCFPGA_RSTMGR_HDSKACK 0x018
#define SOCFPGA_RSTMGR_MPUMODRST 0x020
#define SOCFPGA_RSTMGR_PER0MODRST 0x024
#define SOCFPGA_RSTMGR_PER1MODRST 0x028
@@ -78,14 +89,20 @@
#define RSTMGR_HDSKEN_DEBUG_L3NOC 0x00020000
#define RSTMGR_HDSKEN_SDRSELFREFEN 0x00000001
+#define RSTMGR_HDSKEQ_FPGAHSREQ 0x4
+
#define RSTMGR_BRGMODRST_SOC2FPGA 0x1
#define RSTMGR_BRGMODRST_LWHPS2FPGA 0x2
#define RSTMGR_BRGMODRST_FPGA2SOC 0x4
+#define RSTMGR_BRGMODRST_F2SSDRAM0 0x8
#define RSTMGR_BRGMODRST_F2SSDRAM1 0x10
#define RSTMGR_BRGMODRST_F2SSDRAM2 0x20
#define RSTMGR_BRGMODRST_MPFE 0x40
#define RSTMGR_BRGMODRST_DDRSCH 0x40
+#define RSTMGR_HDSKREQ_FPGAHSREQ (BIT(2))
+#define RSTMGR_HDSKACK_FPGAHSACK_MASK (BIT(2))
+
/* Definitions */
#define RSTMGR_L2_MODRST 0x0100
@@ -94,7 +111,7 @@
/* Macros */
#define SOCFPGA_RSTMGR(_reg) (SOCFPGA_RSTMGR_REG_BASE \
- + (SOCFPGA_RSTMGR_##_reg))
+ + (SOCFPGA_RSTMGR_##_reg))
#define RSTMGR_FIELD(_reg, _field) (RSTMGR_##_reg##MODRST_##_field)
/* Function Declarations */
@@ -102,7 +119,7 @@
void deassert_peripheral_reset(void);
void config_hps_hs_before_warm_reset(void);
-int socfpga_bridges_enable(void);
-int socfpga_bridges_disable(void);
+int socfpga_bridges_enable(uint32_t mask);
+int socfpga_bridges_disable(uint32_t mask);
#endif /* SOCFPGA_RESETMANAGER_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 0db71e2..0803eb5 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -9,23 +9,43 @@
/* SiP status response */
-#define INTEL_SIP_SMC_STATUS_OK 0
-#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
+#define INTEL_SIP_SMC_STATUS_OK 0
+#define INTEL_SIP_SMC_STATUS_BUSY 0x1
+#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
+#define INTEL_SIP_SMC_STATUS_NO_RESPONSE 0x3
+#define INTEL_SIP_SMC_STATUS_ERROR 0x4
+#define INTEL_SIP_SMC_RSU_ERROR 0x7
/* SiP mailbox error code */
-#define GENERIC_RESPONSE_ERROR 0x3FF
+#define GENERIC_RESPONSE_ERROR 0x3FF
-/* SMC SiP service function identifier */
+/* SiP V2 command code range */
+#define INTEL_SIP_SMC_CMD_MASK 0xFFFF
+#define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN 0x400
+#define INTEL_SIP_SMC_CMD_V2_RANGE_END 0x4FF
+
+/* SiP V2 protocol header */
+#define INTEL_SIP_SMC_HEADER_JOB_ID_MASK 0xF
+#define INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET 0U
+#define INTEL_SIP_SMC_HEADER_CID_MASK 0xF
+#define INTEL_SIP_SMC_HEADER_CID_OFFSET 4U
+#define INTEL_SIP_SMC_HEADER_VERSION_MASK 0xF
+#define INTEL_SIP_SMC_HEADER_VERSION_OFFSET 60U
+
+/* SMC SiP service function identifier for version 1 */
/* FPGA Reconfig */
-#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001
-#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002
-#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003
-#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004
-#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005
+#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001
+#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002
+#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003
+#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004
+#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005
+
+/* FPGA Bitstream Flag */
+#define FLAG_PARTIAL_CONFIG BIT(0)
+#define FLAG_AUTHENTICATION BIT(1)
+#define CONFIG_TEST_FLAG(_flag, _type) (((flag) & FLAG_##_type) \
+ == FLAG_##_type)
/* Secure Register Access */
#define INTEL_SIP_SMC_REG_READ 0xC2000007
@@ -33,37 +53,121 @@
#define INTEL_SIP_SMC_REG_UPDATE 0xC2000009
/* Remote System Update */
-#define INTEL_SIP_SMC_RSU_STATUS 0xC200000B
-#define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C
-#define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E
-#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F
-#define INTEL_SIP_SMC_RSU_DCMF_VERSION 0xC2000010
-#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION 0xC2000011
+#define INTEL_SIP_SMC_RSU_STATUS 0xC200000B
+#define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C
+#define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E
+#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F
+#define INTEL_SIP_SMC_RSU_DCMF_VERSION 0xC2000010
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION 0xC2000011
+#define INTEL_SIP_SMC_RSU_MAX_RETRY 0xC2000012
+#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY 0xC2000013
+#define INTEL_SIP_SMC_RSU_DCMF_STATUS 0xC2000014
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS 0xC2000015
+/* Hardware monitor */
+#define INTEL_SIP_SMC_HWMON_READTEMP 0xC2000020
+#define INTEL_SIP_SMC_HWMON_READVOLT 0xC2000021
+#define TEMP_CHANNEL_MAX (1 << 15)
+#define VOLT_CHANNEL_MAX (1 << 15)
/* ECC */
-#define INTEL_SIP_SMC_ECC_DBE 0xC200000D
+#define INTEL_SIP_SMC_ECC_DBE 0xC200000D
-/* Send Mailbox Command */
-#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E
+/* Generic Command */
+#define INTEL_SIP_SMC_SERVICE_COMPLETED 0xC200001E
+#define INTEL_SIP_SMC_FIRMWARE_VERSION 0xC200001F
+#define INTEL_SIP_SMC_HPS_SET_BRIDGES 0xC2000032
+#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384 0xC2000040
+#define SERVICE_COMPLETED_MODE_ASYNC 0x00004F4E
-/* SiP Definitions */
+/* Mailbox Command */
+#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200003C
+#define INTEL_SIP_SMC_GET_USERCODE 0xC200003D
+
+/* FPGA Crypto Services */
+#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER 0xC200005A
+#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER_EXT 0x4200008F
+#define INTEL_SIP_SMC_FCS_CRYPTION 0x4200005B
+#define INTEL_SIP_SMC_FCS_CRYPTION_EXT 0xC2000090
+#define INTEL_SIP_SMC_FCS_SERVICE_REQUEST 0x4200005C
+#define INTEL_SIP_SMC_FCS_SEND_CERTIFICATE 0x4200005D
+#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA 0x4200005E
+#define INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH 0xC200005F
+#define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN 0xC2000064
+#define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065
+#define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY 0xC2000066
+#define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS 0xC2000067
+#define INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT 0xC2000068
+#define INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD 0xC2000069
+#define INTEL_SIP_SMC_FCS_OPEN_CS_SESSION 0xC200006E
+#define INTEL_SIP_SMC_FCS_CLOSE_CS_SESSION 0xC200006F
+#define INTEL_SIP_SMC_FCS_IMPORT_CS_KEY 0x42000070
+#define INTEL_SIP_SMC_FCS_EXPORT_CS_KEY 0xC2000071
+#define INTEL_SIP_SMC_FCS_REMOVE_CS_KEY 0xC2000072
+#define INTEL_SIP_SMC_FCS_GET_CS_KEY_INFO 0xC2000073
+#define INTEL_SIP_SMC_FCS_AES_CRYPT_INIT 0xC2000074
+#define INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE 0x42000075
+#define INTEL_SIP_SMC_FCS_AES_CRYPT_FINALIZE 0x42000076
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_INIT 0xC2000077
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_UPDATE 0xC2000078
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE 0xC2000079
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT 0xC200007A
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_UPDATE 0xC200007B
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE 0xC200007C
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT 0xC200007D
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_FINALIZE 0xC200007F
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT 0xC2000080
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE 0xC2000081
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE 0xC2000082
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_INIT 0xC2000083
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE 0xC2000085
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT 0xC2000086
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE 0xC2000087
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE 0xC2000088
+#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT 0xC2000089
+#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE 0xC200008B
+#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT 0xC200008C
+#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE 0xC200008E
+
+#define INTEL_SIP_SMC_FCS_SHA_MODE_MASK 0xF
+#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK 0xF
+#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET 4U
+#define INTEL_SIP_SMC_FCS_ECC_ALGO_MASK 0xF
/* ECC DBE */
-#define WARM_RESET_WFI_FLAG BIT(31)
-#define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\
- SYSMGR_ECC_DDR0_MASK |\
- SYSMGR_ECC_DDR1_MASK)
+#define WARM_RESET_WFI_FLAG BIT(31)
+#define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\
+ SYSMGR_ECC_DDR0_MASK |\
+ SYSMGR_ECC_DDR1_MASK)
+
+/* Non-mailbox SMC Call */
+#define INTEL_SIP_SMC_SVC_VERSION 0xC2000200
+
+/**
+ * SMC SiP service function identifier for version 2
+ * Command code from 0x400 ~ 0x4FF
+ */
+
+/* V2: Non-mailbox function identifier */
+#define INTEL_SIP_SMC_V2_GET_SVC_VERSION 0xC2000400
+#define INTEL_SIP_SMC_V2_REG_READ 0xC2000401
+#define INTEL_SIP_SMC_V2_REG_WRITE 0xC2000402
+#define INTEL_SIP_SMC_V2_REG_UPDATE 0xC2000403
+#define INTEL_SIP_SMC_V2_HPS_SET_BRIDGES 0xC2000404
+
+/* V2: Mailbox function identifier */
+#define INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND 0xC2000420
+#define INTEL_SIP_SMC_V2_MAILBOX_POLL_RESPONSE 0xC2000421
/* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT 0x8200ff00
-#define SIP_SVC_UID 0x8200ff01
-#define SIP_SVC_VERSION 0x8200ff03
+#define SIP_SVC_CALL_COUNT 0x8200ff00
+#define SIP_SVC_UID 0x8200ff01
+#define SIP_SVC_VERSION 0x8200ff03
/* SiP Service Calls version numbers */
-#define SIP_SVC_VERSION_MAJOR 0
-#define SIP_SVC_VERSION_MINOR 1
+#define SIP_SVC_VERSION_MAJOR 1
+#define SIP_SVC_VERSION_MINOR 0
/* Structure Definitions */
@@ -76,12 +180,38 @@
int block_number;
};
-/* Function Definitions */
+typedef enum {
+ NO_REQUEST = 0,
+ RECONFIGURATION,
+ BITSTREAM_AUTH
+} config_type;
+/* Function Definitions */
+bool is_size_4_bytes_aligned(uint32_t size);
bool is_address_in_ddr_range(uint64_t addr, uint64_t size);
/* ECC DBE */
bool cold_reset_for_ecc_dbe(void);
uint32_t intel_ecc_dbe_notification(uint64_t dbe_value);
+/* Secure register access */
+uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval);
+uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val,
+ uint32_t *retval);
+uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask,
+ uint32_t val, uint32_t *retval);
+
+/* Miscellaneous HPS services */
+uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask);
+
+/* SiP Service handler for version 2 */
+uintptr_t sip_smc_handler_v2(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags);
+
#endif /* SOCFPGA_SIP_SVC_H */
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 2b13f1f..7f67313 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -38,17 +38,10 @@
#define SYSMGR_SDMMC_DRVSEL(x) (((x) & 0x7) << 0)
#define SYSMGR_SDMMC_SMPLSEL(x) (((x) & 0x7) << 4)
-#define IDLE_DATA_LWSOC2FPGA BIT(0)
-#define IDLE_DATA_SOC2FPGA BIT(4)
+#define IDLE_DATA_LWSOC2FPGA BIT(4)
+#define IDLE_DATA_SOC2FPGA BIT(0)
#define IDLE_DATA_MASK (IDLE_DATA_LWSOC2FPGA | IDLE_DATA_SOC2FPGA)
-#define SCR_AXI_AP_MASK BIT(24)
-#define SCR_FPGA2SOC_MASK BIT(16)
-#define SCR_MPU_MASK BIT(0)
-#define DISABLE_L4_FIREWALL (SCR_AXI_AP_MASK | SCR_FPGA2SOC_MASK \
- | SCR_MPU_MASK)
-#define DISABLE_BRIDGE_FIREWALL 0x0ffe0101
-
#define SYSMGR_ECC_OCRAM_MASK BIT(1)
#define SYSMGR_ECC_DDR0_MASK BIT(16)
#define SYSMGR_ECC_DDR1_MASK BIT(17)
@@ -58,69 +51,4 @@
#define SOCFPGA_SYSMGR(_reg) (SOCFPGA_SYSMGR_REG_BASE \
+ (SOCFPGA_SYSMGR_##_reg))
-#define SOCFPGA_L4_PER_SCR(_reg) (SOCFPGA_L4_PER_SCR_REG_BASE \
- + (SOCFPGA_NOC_FW_L4_PER_SCR_##_reg))
-
-#define SOCFPGA_L4_SYS_SCR(_reg) (SOCFPGA_L4_SYS_SCR_REG_BASE \
- + (SOCFPGA_NOC_FW_L4_SYS_SCR_##_reg))
-
-/* L3 Interconnect Register Map */
-#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_REGISTER 0x0000
-#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_DATA 0x0004
-#define SOCFPGA_NOC_FW_L4_PER_SCR_USB0_REGISTER 0x000c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_USB1_REGISTER 0x0010
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER0 0x001c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER1 0x0020
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE0 0x0024
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE1 0x0028
-#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC0 0x002c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC1 0x0030
-#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC2 0x0034
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SDMMC 0x0040
-#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO0 0x0044
-#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO1 0x0048
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C0 0x0050
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C1 0x0054
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C2 0x0058
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C3 0x005c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C4 0x0060
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER0 0x0064
-#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER1 0x0068
-#define SOCFPGA_NOC_FW_L4_PER_SCR_UART0 0x006c
-#define SOCFPGA_NOC_FW_L4_PER_SCR_UART1 0x0070
-
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_DMA_ECC 0x0008
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC 0x000c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC 0x0010
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC 0x0014
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC 0x0018
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC 0x001c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC 0x0020
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_ECC 0x002c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_READ_ECC 0x0030
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC 0x0034
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_OCRAM_ECC 0x0038
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_SDMMC_ECC 0x0040
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB0_ECC 0x0044
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_ECC 0x0048
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_CLK_MGR 0x004c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_IO_MGR 0x0054
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_RST_MGR 0x0058
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_SYS_MGR 0x005c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC0_TIMER 0x0060
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC1_TIMER 0x0064
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG0 0x0068
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG1 0x006c
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG2 0x0070
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG3 0x0074
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_DAP 0x0078
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES 0x0090
-#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_QOS 0x0094
-
-#define SOCFPGA_CCU_NOC_CPU0_RAMSPACE0_0 0xf7004688
-#define SOCFPGA_CCU_NOC_IOM_RAMSPACE0_0 0xf7018628
-
-void enable_ns_peripheral_access(void);
-void enable_ns_bridge_access(void);
-
#endif /* SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index fe5461b..eacc4dd 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -11,6 +11,73 @@
#include "socfpga_mailbox.h"
#include "socfpga_sip_svc.h"
+/* FCS static variables */
+static fcs_crypto_service_aes_data fcs_aes_init_payload;
+static fcs_crypto_service_data fcs_sha_get_digest_param;
+static fcs_crypto_service_data fcs_sha_mac_verify_param;
+static fcs_crypto_service_data fcs_ecdsa_hash_sign_param;
+static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param;
+static fcs_crypto_service_data fcs_sha2_data_sign_param;
+static fcs_crypto_service_data fcs_sha2_data_sig_verify_param;
+static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
+static fcs_crypto_service_data fcs_ecdh_request_param;
+
+bool is_size_4_bytes_aligned(uint32_t size)
+{
+ if ((size % MBOX_WORD_BYTE) != 0U) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+static bool is_8_bytes_aligned(uint32_t data)
+{
+ if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+static bool is_32_bytes_aligned(uint32_t data)
+{
+ if ((data % (8U * MBOX_WORD_BYTE)) != 0U) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+static int intel_fcs_crypto_service_init(uint32_t session_id,
+ uint32_t context_id, uint32_t key_id,
+ uint32_t param_size, uint64_t param_data,
+ fcs_crypto_service_data *data_addr,
+ uint32_t *mbox_error)
+{
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (param_size != 4) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ memset(data_addr, 0, sizeof(fcs_crypto_service_data));
+
+ data_addr->session_id = session_id;
+ data_addr->context_id = context_id;
+ data_addr->key_id = key_id;
+ data_addr->crypto_param_size = param_size;
+ data_addr->crypto_param = param_data;
+
+ data_addr->is_updated = 0;
+
+ *mbox_error = 0;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
uint32_t *mbox_error)
{
@@ -48,6 +115,45 @@
return INTEL_SIP_SMC_STATUS_OK;
}
+int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
+ uint32_t size, uint32_t *send_id)
+{
+ int status;
+ uint32_t payload_size;
+ uint32_t crypto_header;
+
+ if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
+ MBOX_WORD_BYTE) || size == 0U) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
+ FCS_CS_FIELD_FLAG_OFFSET;
+
+ fcs_rng_payload payload = {
+ session_id,
+ context_id,
+ crypto_header,
+ size
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
+ (uint32_t *) &payload, payload_size,
+ CMD_INDIRECT);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
uint32_t *send_id)
{
@@ -57,10 +163,16 @@
return INTEL_SIP_SMC_STATUS_REJECTED;
}
+ if (!is_size_4_bytes_aligned(size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
status = mailbox_send_cmd_async(send_id, MBOX_CMD_VAB_SRC_CERT,
(uint32_t *)addr, size / MBOX_WORD_BYTE,
CMD_DIRECT);
+ flush_dcache_range(addr, size);
+
if (status < 0) {
return INTEL_SIP_SMC_STATUS_ERROR;
}
@@ -76,45 +188,1552 @@
NULL, 0U, CMD_DIRECT);
if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
+ uint32_t test_bit, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t first_word;
+ uint32_t payload_size;
+
+ if ((test_bit != MBOX_TEST_BIT) &&
+ (test_bit != 0)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((counter_type < FCS_BIG_CNTR_SEL) ||
+ (counter_type > FCS_SVN_CNTR_3_SEL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((counter_type == FCS_BIG_CNTR_SEL) &&
+ (counter_value > FCS_BIG_CNTR_VAL_MAX)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
+ (counter_type <= FCS_SVN_CNTR_3_SEL) &&
+ (counter_value > FCS_SVN_CNTR_VAL_MAX)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ first_word = test_bit | counter_type;
+ fcs_cntr_set_preauth_payload payload = {
+ first_word,
+ counter_value
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, NULL, NULL);
+
+ if (status < 0) {
+ *mbox_error = -status;
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
-uint32_t intel_fcs_cryption(uint32_t mode, uint32_t src_addr,
- uint32_t src_size, uint32_t dst_addr,
- uint32_t dst_size, uint32_t *send_id)
+uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
{
int status;
- uint32_t cmd;
+ uint32_t load_size;
+
+ fcs_encrypt_payload payload = {
+ FCS_ENCRYPTION_DATA_0,
+ src_addr,
+ src_size,
+ dst_addr,
+ dst_size };
+ load_size = sizeof(payload) / MBOX_WORD_BYTE;
if (!is_address_in_ddr_range(src_addr, src_size) ||
!is_address_in_ddr_range(dst_addr, dst_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
+ if (!is_size_4_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
+ (uint32_t *) &payload, load_size,
+ CMD_INDIRECT);
+ inv_dcache_range(dst_addr, dst_size);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
+{
+ int status;
+ uint32_t load_size;
+ uintptr_t id_offset;
+
- fcs_crypt_payload payload = {
- FCS_CRYPTION_DATA_0,
+ id_offset = src_addr + FCS_OWNER_ID_OFFSET;
+ fcs_decrypt_payload payload = {
+ FCS_DECRYPTION_DATA_0,
+ {mmio_read_32(id_offset),
+ mmio_read_32(id_offset + MBOX_WORD_BYTE)},
src_addr,
src_size,
dst_addr,
dst_size };
+ load_size = sizeof(payload) / MBOX_WORD_BYTE;
- if (mode != 0U) {
- cmd = MBOX_FCS_ENCRYPT_REQ;
- } else {
- cmd = MBOX_FCS_DECRYPT_REQ;
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
}
- status = mailbox_send_cmd_async(send_id, cmd, (uint32_t *) &payload,
- sizeof(fcs_crypt_payload) / MBOX_WORD_BYTE,
+ if (!is_size_4_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
+ (uint32_t *) &payload, load_size,
CMD_INDIRECT);
inv_dcache_range(dst_addr, dst_size);
if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t payload_size;
+ uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
+ uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ fcs_encrypt_ext_payload payload = {
+ session_id,
+ context_id,
+ FCS_CRYPTION_CRYPTO_HEADER,
+ src_addr,
+ src_size,
+ dst_addr,
+ *dst_size
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, resp_data, &resp_len);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
+ *mbox_error = MBOX_RET_ERROR;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
+ inv_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_decryption_ext(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
+{
+ int status;
+ uintptr_t id_offset;
+ uint32_t payload_size;
+ uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
+ uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ id_offset = src_addr + FCS_OWNER_ID_OFFSET;
+ fcs_decrypt_ext_payload payload = {
+ session_id,
+ context_id,
+ FCS_CRYPTION_CRYPTO_HEADER,
+ {mmio_read_32(id_offset),
+ mmio_read_32(id_offset + MBOX_WORD_BYTE)},
+ src_addr,
+ src_size,
+ dst_addr,
+ *dst_size
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, resp_data, &resp_len);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
+ *mbox_error = MBOX_RET_ERROR;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
+ inv_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
+{
+ int status;
+
+ if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
+ (session_id != PSGSIGMA_UNKNOWN_SESSION)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ psgsigma_teardown_msg message = {
+ RESERVED_AS_ZERO,
+ PSGSIGMA_TEARDOWN_MAGIC,
+ session_id
+ };
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
+ (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
+ CMD_CASUAL, NULL, NULL);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t load_size;
+ uint32_t chip_id[2];
+
+ load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
+ 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *id_low = chip_id[0];
+ *id_high = chip_id[1];
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t send_size = src_size / MBOX_WORD_BYTE;
+ uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
+
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
+ (uint32_t *) src_addr, send_size, CMD_CASUAL,
+ (uint32_t *) dst_addr, &ret_size);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = ret_size * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t send_size = src_size / MBOX_WORD_BYTE;
+ uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
+ (uint32_t *) src_addr, send_size, CMD_CASUAL,
+ (uint32_t *) dst_addr, &ret_size);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = ret_size * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ unsigned int resp_len = FCS_SHA384_WORD_SIZE;
+
+ if (!is_address_in_ddr_range(addr, FCS_SHA384_BYTE_SIZE)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ROM_PATCH_SHA384, NULL, 0U,
+ CMD_CASUAL, (uint32_t *) addr, &resp_len);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (resp_len != FCS_SHA384_WORD_SIZE) {
+ *mbox_error = GENERIC_RESPONSE_ERROR;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *ret_size = FCS_SHA384_BYTE_SIZE;
+
+ flush_dcache_range(addr, *ret_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
+ uint32_t *dst_size, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
+
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
+ cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
+ (uint32_t *) &cert_request, 1U, CMD_CASUAL,
+ (uint32_t *) dst_addr, &ret_size);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = ret_size * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_create_cert_on_reload(uint32_t cert_request,
+ uint32_t *mbox_error)
+{
+ int status;
+
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
+ cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
+ (uint32_t *) &cert_request, 1U, CMD_CASUAL,
+ NULL, NULL);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_open_crypto_service_session(uint32_t *session_id,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t resp_len = 1U;
+
+ if ((session_id == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
+ NULL, 0U, CMD_CASUAL, session_id, &resp_len);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_close_crypto_service_session(uint32_t session_id,
+ uint32_t *mbox_error)
+{
+ int status;
+
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
+ &session_id, 1U, CMD_CASUAL, NULL, NULL);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
+ uint32_t *send_id)
+{
+ int status;
+
+ if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
+ MBOX_WORD_BYTE)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
+ (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
+ CMD_INDIRECT);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t i;
+ uint32_t payload_size;
+ uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
+ uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
+ uint32_t op_status = 0U;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ fcs_cs_key_payload payload = {
+ session_id,
+ RESERVED_AS_ZERO,
+ RESERVED_AS_ZERO,
+ key_id
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, resp_data, &resp_len);
+
+ if (resp_len > 0) {
+ op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
+ }
+
+ if (status < 0) {
+ *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (resp_len > 1) {
+
+ /* Export key object is start at second response data */
+ *dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
+
+ for (i = 1U; i < resp_len; i++) {
+ mmio_write_32(dst_addr, resp_data[i]);
+ dst_addr += MBOX_WORD_BYTE;
+ }
+
+ flush_dcache_range(dst_addr - *dst_size, *dst_size);
+
+ } else {
+
+ /* Unexpected response, missing key object in response */
+ *mbox_error = MBOX_RET_ERROR;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t payload_size;
+ uint32_t resp_len = 1U;
+ uint32_t resp_data = 0U;
+ uint32_t op_status = 0U;
+
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ fcs_cs_key_payload payload = {
+ session_id,
+ RESERVED_AS_ZERO,
+ RESERVED_AS_ZERO,
+ key_id
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, &resp_data, &resp_len);
+
+ if (resp_len > 0) {
+ op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
+ }
+
+ if (status < 0) {
+ *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t payload_size;
+ uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
+ uint32_t op_status = 0U;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ fcs_cs_key_payload payload = {
+ session_id,
+ RESERVED_AS_ZERO,
+ RESERVED_AS_ZERO,
+ key_id
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
+
+ if (resp_len > 0) {
+ op_status = mmio_read_32(dst_addr) &
+ FCS_CS_KEY_RESP_STATUS_MASK;
+ }
+
+ if (status < 0) {
+ *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_sha_get_digest_param,
+ mbox_error);
+}
+
+int intel_fcs_get_digest_update_finalize(uint32_t session_id,
+ uint32_t context_id, uint32_t src_addr,
+ uint32_t src_size, uint64_t dst_addr,
+ uint32_t *dst_size, uint8_t is_finalised,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t i;
+ uint32_t flag;
+ uint32_t crypto_header;
+ uint32_t resp_len;
+ uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
+
+ if (dst_size == NULL || mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_sha_get_digest_param.session_id != session_id ||
+ fcs_sha_get_digest_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /* Source data must be 8 bytes aligned */
+ if (!is_8_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare crypto header */
+ flag = 0;
+
+ if (fcs_sha_get_digest_param.is_updated) {
+ fcs_sha_get_digest_param.crypto_param_size = 0;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_INIT;
+ }
+
+ if (is_finalised != 0U) {
+ flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_UPDATE;
+ fcs_sha_get_digest_param.is_updated = 1;
+ }
+
+ crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
+ (fcs_sha_get_digest_param.crypto_param_size &
+ FCS_CS_FIELD_SIZE_MASK));
+
+ /* Prepare command payload */
+ i = 0;
+ payload[i] = fcs_sha_get_digest_param.session_id;
+ i++;
+ payload[i] = fcs_sha_get_digest_param.context_id;
+ i++;
+ payload[i] = crypto_header;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_INIT) {
+ payload[i] = fcs_sha_get_digest_param.key_id;
+ i++;
+ /* Crypto parameters */
+ payload[i] = fcs_sha_get_digest_param.crypto_param
+ & INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
+ payload[i] |= ((fcs_sha_get_digest_param.crypto_param
+ >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
+ & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
+ << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
+ i++;
+ }
+ /* Data source address and size */
+ payload[i] = src_addr;
+ i++;
+ payload[i] = src_size;
+ i++;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
+ payload, i, CMD_CASUAL,
+ (uint32_t *) dst_addr, &resp_len);
+
+ if (is_finalised != 0U) {
+ memset((void *)&fcs_sha_get_digest_param, 0,
+ sizeof(fcs_crypto_service_data));
+ }
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_sha_mac_verify_param,
+ mbox_error);
+}
+
+int intel_fcs_mac_verify_update_finalize(uint32_t session_id,
+ uint32_t context_id, uint32_t src_addr,
+ uint32_t src_size, uint64_t dst_addr,
+ uint32_t *dst_size, uint32_t data_size,
+ uint8_t is_finalised, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t i;
+ uint32_t flag;
+ uint32_t crypto_header;
+ uint32_t resp_len;
+ uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
+ uintptr_t mac_offset;
+
+ if (dst_size == NULL || mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_sha_mac_verify_param.session_id != session_id ||
+ fcs_sha_mac_verify_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (data_size >= src_size) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(src_size) ||
+ !is_8_bytes_aligned(data_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare crypto header */
+ flag = 0;
+
+ if (fcs_sha_mac_verify_param.is_updated) {
+ fcs_sha_mac_verify_param.crypto_param_size = 0;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_INIT;
+ }
+
+ if (is_finalised) {
+ flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_UPDATE;
+ fcs_sha_mac_verify_param.is_updated = 1;
+ }
+
+ crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
+ (fcs_sha_mac_verify_param.crypto_param_size &
+ FCS_CS_FIELD_SIZE_MASK));
+
+ /* Prepare command payload */
+ i = 0;
+ payload[i] = fcs_sha_mac_verify_param.session_id;
+ i++;
+ payload[i] = fcs_sha_mac_verify_param.context_id;
+ i++;
+ payload[i] = crypto_header;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_INIT) {
+ payload[i] = fcs_sha_mac_verify_param.key_id;
+ i++;
+ /* Crypto parameters */
+ payload[i] = ((fcs_sha_mac_verify_param.crypto_param
+ >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
+ & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
+ << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
+ i++;
+ }
+ /* Data source address and size */
+ payload[i] = src_addr;
+ i++;
+ payload[i] = data_size;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_FINALIZE) {
+ /* Copy mac data to command */
+ mac_offset = src_addr + data_size;
+ memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
+ src_size - data_size);
+
+ i += (src_size - data_size) / MBOX_WORD_BYTE;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
+ payload, i, CMD_CASUAL,
+ (uint32_t *) dst_addr, &resp_len);
+
+ if (is_finalised) {
+ memset((void *)&fcs_sha_mac_verify_param, 0,
+ sizeof(fcs_crypto_service_data));
+ }
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_ecdsa_hash_sign_param,
+ mbox_error);
+}
+
+int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t i;
+ uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
+ uint32_t resp_len;
+ uintptr_t hash_data_addr;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
+ fcs_ecdsa_hash_sign_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare command payload */
+ /* Crypto header */
+ i = 0;
+ payload[i] = fcs_ecdsa_hash_sign_param.session_id;
+ i++;
+ payload[i] = fcs_ecdsa_hash_sign_param.context_id;
+
+ i++;
+ payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
+ & FCS_CS_FIELD_SIZE_MASK;
+ payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
+ | FCS_CS_FIELD_FLAG_FINALIZE)
+ << FCS_CS_FIELD_FLAG_OFFSET;
+ i++;
+ payload[i] = fcs_ecdsa_hash_sign_param.key_id;
+
+ /* Crypto parameters */
+ i++;
+ payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
+ & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+
+ /* Hash Data */
+ i++;
+ hash_data_addr = src_addr;
+ memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
+ src_size);
+
+ i += src_size / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
+ payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
+ &resp_len);
+
+ memset((void *) &fcs_ecdsa_hash_sign_param,
+ 0, sizeof(fcs_crypto_service_data));
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_ecdsa_hash_sig_verify_param,
+ mbox_error);
+}
+
+int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t i = 0;
+ uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
+ uint32_t resp_len;
+ uintptr_t hash_sig_pubkey_addr;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
+ fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare command payload */
+ /* Crypto header */
+ i = 0;
+ payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
+
+ i++;
+ payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
+
+ i++;
+ payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
+ & FCS_CS_FIELD_SIZE_MASK;
+ payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
+ | FCS_CS_FIELD_FLAG_FINALIZE)
+ << FCS_CS_FIELD_FLAG_OFFSET;
+
+ i++;
+ payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
+
+ /* Crypto parameters */
+ i++;
+ payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
+ & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+
+ /* Hash Data Word, Signature Data Word and Public Key Data word */
+ i++;
+ hash_sig_pubkey_addr = src_addr;
+ memcpy((uint8_t *) &payload[i],
+ (uint8_t *) hash_sig_pubkey_addr, src_size);
+
+ i += (src_size / MBOX_WORD_BYTE);
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
+ payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
+ &resp_len);
+
+ memset((void *)&fcs_ecdsa_hash_sig_verify_param,
+ 0, sizeof(fcs_crypto_service_data));
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
+ uint32_t context_id, uint32_t key_id,
+ uint32_t param_size, uint64_t param_data,
+ uint32_t *mbox_error)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_sha2_data_sign_param,
+ mbox_error);
+}
+
+int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id,
+ uint32_t context_id, uint32_t src_addr,
+ uint32_t src_size, uint64_t dst_addr,
+ uint32_t *dst_size, uint8_t is_finalised,
+ uint32_t *mbox_error)
+{
+ int status;
+ int i;
+ uint32_t flag;
+ uint32_t crypto_header;
+ uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
+ uint32_t resp_len;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_sha2_data_sign_param.session_id != session_id ||
+ fcs_sha2_data_sign_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /* Source data must be 8 bytes aligned */
+ if (!is_8_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare crypto header */
+ flag = 0;
+ if (fcs_sha2_data_sign_param.is_updated) {
+ fcs_sha2_data_sign_param.crypto_param_size = 0;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_INIT;
+ }
+
+ if (is_finalised != 0U) {
+ flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_UPDATE;
+ fcs_sha2_data_sign_param.is_updated = 1;
+ }
+ crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
+ fcs_sha2_data_sign_param.crypto_param_size;
+
+ /* Prepare command payload */
+ i = 0;
+ payload[i] = fcs_sha2_data_sign_param.session_id;
+ i++;
+ payload[i] = fcs_sha2_data_sign_param.context_id;
+ i++;
+ payload[i] = crypto_header;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_INIT) {
+ payload[i] = fcs_sha2_data_sign_param.key_id;
+ /* Crypto parameters */
+ i++;
+ payload[i] = fcs_sha2_data_sign_param.crypto_param
+ & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+ i++;
+ }
+
+ /* Data source address and size */
+ payload[i] = src_addr;
+ i++;
+ payload[i] = src_size;
+ i++;
+ status = mailbox_send_cmd(MBOX_JOB_ID,
+ MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
+ i, CMD_CASUAL, (uint32_t *) dst_addr,
+ &resp_len);
+
+ if (is_finalised != 0U) {
+ memset((void *)&fcs_sha2_data_sign_param, 0,
+ sizeof(fcs_crypto_service_data));
+ }
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
+ uint32_t context_id, uint32_t key_id,
+ uint32_t param_size, uint64_t param_data,
+ uint32_t *mbox_error)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_sha2_data_sig_verify_param,
+ mbox_error);
+}
+
+int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
+ uint32_t context_id, uint32_t src_addr,
+ uint32_t src_size, uint64_t dst_addr,
+ uint32_t *dst_size, uint32_t data_size,
+ uint8_t is_finalised, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t i;
+ uint32_t flag;
+ uint32_t crypto_header;
+ uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
+ uint32_t resp_len;
+ uintptr_t sig_pubkey_offset;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
+ fcs_sha2_data_sig_verify_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_8_bytes_aligned(data_size) ||
+ !is_8_bytes_aligned(src_addr)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare crypto header */
+ flag = 0;
+ if (fcs_sha2_data_sig_verify_param.is_updated)
+ fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
+ else
+ flag |= FCS_CS_FIELD_FLAG_INIT;
+
+ if (is_finalised != 0U)
+ flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+ else {
+ flag |= FCS_CS_FIELD_FLAG_UPDATE;
+ fcs_sha2_data_sig_verify_param.is_updated = 1;
+ }
+ crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
+ fcs_sha2_data_sig_verify_param.crypto_param_size;
+
+ /* Prepare command payload */
+ i = 0;
+ payload[i] = fcs_sha2_data_sig_verify_param.session_id;
+ i++;
+ payload[i] = fcs_sha2_data_sig_verify_param.context_id;
+ i++;
+ payload[i] = crypto_header;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_INIT) {
+ payload[i] = fcs_sha2_data_sig_verify_param.key_id;
+ i++;
+ /* Crypto parameters */
+ payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
+ & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+ i++;
+ }
+
+ /* Data source address and size */
+ payload[i] = src_addr;
+ i++;
+ payload[i] = data_size;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_FINALIZE) {
+ /* Signature + Public Key Data */
+ sig_pubkey_offset = src_addr + data_size;
+ memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
+ src_size - data_size);
+
+ i += (src_size - data_size) / MBOX_WORD_BYTE;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID,
+ MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
+ CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
+
+ if (is_finalised != 0U) {
+ memset((void *) &fcs_sha2_data_sig_verify_param, 0,
+ sizeof(fcs_crypto_service_data));
+ }
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_ecdsa_get_pubkey_param,
+ mbox_error);
+}
+
+int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ int i;
+ uint32_t crypto_header;
+ uint32_t ret_size;
+ uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
+ fcs_ecdsa_get_pubkey_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ ret_size = *dst_size / MBOX_WORD_BYTE;
+
+ crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
+ FCS_CS_FIELD_FLAG_UPDATE |
+ FCS_CS_FIELD_FLAG_FINALIZE) <<
+ FCS_CS_FIELD_FLAG_OFFSET) |
+ fcs_ecdsa_get_pubkey_param.crypto_param_size;
+ i = 0;
+ /* Prepare command payload */
+ payload[i] = session_id;
+ i++;
+ payload[i] = context_id;
+ i++;
+ payload[i] = crypto_header;
+ i++;
+ payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
+ i++;
+ payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
+ INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+ i++;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
+ payload, i, CMD_CASUAL,
+ (uint32_t *) dst_addr, &ret_size);
+
+ memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
+ sizeof(fcs_crypto_service_data));
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = ret_size * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint32_t param_size,
+ uint64_t param_data, uint32_t *mbox_error)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_ecdh_request_param,
+ mbox_error);
+}
+
+int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t i;
+ uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
+ uint32_t resp_len;
+ uintptr_t pubkey;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_ecdh_request_param.session_id != session_id ||
+ fcs_ecdh_request_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare command payload */
+ i = 0;
+ /* Crypto header */
+ payload[i] = fcs_ecdh_request_param.session_id;
+ i++;
+ payload[i] = fcs_ecdh_request_param.context_id;
+ i++;
+ payload[i] = fcs_ecdh_request_param.crypto_param_size
+ & FCS_CS_FIELD_SIZE_MASK;
+ payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
+ | FCS_CS_FIELD_FLAG_FINALIZE)
+ << FCS_CS_FIELD_FLAG_OFFSET;
+ i++;
+ payload[i] = fcs_ecdh_request_param.key_id;
+ i++;
+ /* Crypto parameters */
+ payload[i] = fcs_ecdh_request_param.crypto_param
+ & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+ i++;
+ /* Public key data */
+ pubkey = src_addr;
+ memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
+ i += src_size / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
+ payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
+ &resp_len);
+
+ memset((void *)&fcs_ecdh_request_param, 0,
+ sizeof(fcs_crypto_service_data));
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
+ uint32_t key_id, uint64_t param_addr,
+ uint32_t param_size, uint32_t *mbox_error)
+{
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
+
+ fcs_aes_init_payload.session_id = session_id;
+ fcs_aes_init_payload.context_id = context_id;
+ fcs_aes_init_payload.param_size = param_size;
+ fcs_aes_init_payload.key_id = key_id;
+
+ memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
+ (uint8_t *) param_addr, param_size);
+
+ fcs_aes_init_payload.is_updated = 0;
+
+ *mbox_error = 0;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
+ uint32_t context_id, uint64_t src_addr,
+ uint32_t src_size, uint64_t dst_addr,
+ uint32_t dst_size, uint8_t is_finalised,
+ uint32_t *send_id)
+{
+ int status;
+ int i;
+ uint32_t flag;
+ uint32_t crypto_header;
+ uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
+
+ if (fcs_aes_init_payload.session_id != session_id ||
+ fcs_aes_init_payload.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((!is_8_bytes_aligned(src_addr)) ||
+ (!is_32_bytes_aligned(src_size)) ||
+ (!is_address_in_ddr_range(src_addr, src_size))) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((!is_8_bytes_aligned(dst_addr)) ||
+ (!is_32_bytes_aligned(dst_size))) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
+ dst_size < FCS_AES_MIN_DATA_SIZE) ||
+ (src_size > FCS_AES_MAX_DATA_SIZE ||
+ src_size < FCS_AES_MIN_DATA_SIZE)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /* Prepare crypto header*/
+ flag = 0;
+ if (fcs_aes_init_payload.is_updated) {
+ fcs_aes_init_payload.param_size = 0;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_INIT;
+ }
+
+ if (is_finalised != 0U) {
+ flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_UPDATE;
+ fcs_aes_init_payload.is_updated = 1;
+ }
+ crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
+ fcs_aes_init_payload.param_size;
+
+ i = 0U;
+ fcs_aes_crypt_payload[i] = session_id;
+ i++;
+ fcs_aes_crypt_payload[i] = context_id;
+ i++;
+ fcs_aes_crypt_payload[i] = crypto_header;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_INIT) {
+ fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
+ i++;
+
+ memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
+ (uint8_t *) fcs_aes_init_payload.crypto_param,
+ fcs_aes_init_payload.param_size);
+
+ i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
+ }
+
+ fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
+ i++;
+ fcs_aes_crypt_payload[i] = src_size;
+ i++;
+ fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
+ i++;
+ fcs_aes_crypt_payload[i] = dst_size;
+ i++;
+
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
+ fcs_aes_crypt_payload, i,
+ CMD_INDIRECT);
+
+ if (is_finalised != 0U) {
+ memset((void *)&fcs_aes_init_payload, 0,
+ sizeof(fcs_aes_init_payload));
+ }
+
+ if (status < 0U) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
return INTEL_SIP_SMC_STATUS_OK;
}
diff --git a/plat/intel/soc/common/soc/socfpga_system_manager.c b/plat/intel/soc/common/soc/socfpga_firewall.c
similarity index 84%
rename from plat/intel/soc/common/soc/socfpga_system_manager.c
rename to plat/intel/soc/common/soc/socfpga_firewall.c
index a64053c..515784b 100644
--- a/plat/intel/soc/common/soc/socfpga_system_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_firewall.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,8 @@
#include <lib/mmio.h>
#include <lib/utils_def.h>
+#include "socfpga_noc.h"
+#include "socfpga_plat_def.h"
#include "socfpga_system_manager.h"
void enable_nonsecure_access(void)
@@ -92,12 +94,18 @@
mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_QOS), DISABLE_L4_FIREWALL);
#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
- mmio_clrbits_32(SOCFPGA_CCU_NOC_CPU0_RAMSPACE0_0, 0x03);
- mmio_clrbits_32(SOCFPGA_CCU_NOC_IOM_RAMSPACE0_0, 0x03);
-
+ enable_ns_ocram_access();
mmio_write_32(SOCFPGA_SYSMGR(SDMMC), SYSMGR_SDMMC_DRVSEL(3));
#endif
+}
+
+void enable_ns_ocram_access(void)
+{
+ mmio_clrbits_32(SOCFPGA_CCU_NOC(CPU0, RAM0),
+ SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
+ mmio_clrbits_32(SOCFPGA_CCU_NOC(IOM, RAM0),
+ SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
}
void enable_ns_bridge_access(void)
@@ -105,3 +113,11 @@
mmio_write_32(SOCFPGA_SOC2FPGA_SCR_REG_BASE, DISABLE_BRIDGE_FIREWALL);
mmio_write_32(SOCFPGA_LWSOC2FPGA_SCR_REG_BASE, DISABLE_BRIDGE_FIREWALL);
}
+
+void enable_ocram_firewall(void)
+{
+ mmio_setbits_32(SOCFPGA_CCU_NOC(CPU0, RAM0),
+ SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
+ mmio_setbits_32(SOCFPGA_CCU_NOC(IOM, RAM0),
+ SOCFPGA_CCU_NOC_ADMASK_P_MASK | SOCFPGA_CCU_NOC_ADMASK_NS_MASK);
+}
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index be900c9..778d4af 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -11,6 +11,8 @@
#include "socfpga_mailbox.h"
#include "socfpga_sip_svc.h"
+static mailbox_payload_t mailbox_resp_payload;
+static mailbox_container_t mailbox_resp_ctr = {0, 0, &mailbox_resp_payload};
static bool is_mailbox_cmdbuf_full(uint32_t cin)
{
@@ -171,6 +173,95 @@
return MBOX_NO_RESPONSE;
}
+int mailbox_read_response_async(unsigned int *job_id, uint32_t *header,
+ uint32_t *response, unsigned int *resp_len,
+ uint8_t ignore_client_id)
+{
+ uint32_t rin;
+ uint32_t rout;
+ uint32_t resp_data;
+ uint32_t ret_resp_len = 0;
+ uint8_t is_done = 0;
+
+ if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
+ ret_resp_len = MBOX_RESP_LEN(
+ mailbox_resp_ctr.payload->header) -
+ mailbox_resp_ctr.index;
+ }
+
+ if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
+ mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
+ }
+
+ rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
+ rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
+
+ while (rout != rin && !is_done) {
+
+ resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
+
+ rout %= MBOX_RESP_BUFFER_SIZE;
+ mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
+ rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
+
+ if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
+ mailbox_resp_ctr.payload->data[mailbox_resp_ctr.index] = resp_data;
+ mailbox_resp_ctr.index++;
+ ret_resp_len--;
+ } else {
+ if (!ignore_client_id) {
+ if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) {
+ *resp_len = 0;
+ return MBOX_WRONG_ID;
+ }
+ }
+
+ *job_id = MBOX_RESP_JOB_ID(resp_data);
+ ret_resp_len = MBOX_RESP_LEN(resp_data);
+ mailbox_resp_ctr.payload->header = resp_data;
+ mailbox_resp_ctr.flag |= MBOX_PAYLOAD_FLAG_BUSY;
+ }
+
+ if (ret_resp_len == 0) {
+ is_done = 1;
+ }
+ }
+
+ if (is_done != 0) {
+
+ /* copy header data to input address if applicable */
+ if (header != 0) {
+ *header = mailbox_resp_ctr.payload->header;
+ }
+
+ /* copy response data to input buffer if applicable */
+ ret_resp_len = MBOX_RESP_LEN(mailbox_resp_ctr.payload->header);
+ if ((ret_resp_len > 0) && (response == NULL) && resp_len) {
+ if (*resp_len > ret_resp_len) {
+ *resp_len = ret_resp_len;
+ }
+
+ memcpy((uint8_t *) response,
+ (uint8_t *) mailbox_resp_ctr.payload->data,
+ *resp_len * MBOX_WORD_BYTE);
+ }
+
+ /* reset async response param */
+ mailbox_resp_ctr.index = 0;
+ mailbox_resp_ctr.flag = 0;
+
+ if (MBOX_RESP_ERR(mailbox_resp_ctr.payload->header) > 0U) {
+ INFO("Error in async response: %x\n",
+ mailbox_resp_ctr.payload->header);
+ return -MBOX_RESP_ERR(mailbox_resp_ctr.payload->header);
+ }
+
+ return MBOX_RET_OK;
+ }
+
+ *resp_len = 0;
+ return (mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) ? MBOX_BUSY : MBOX_NO_RESPONSE;
+}
int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
unsigned int *resp_len)
@@ -294,6 +385,12 @@
return MBOX_RET_OK;
}
+int mailbox_send_cmd_async_ext(uint32_t header_cmd, uint32_t *args,
+ unsigned int len)
+{
+ return fill_mailbox_circular_buffer(header_cmd, args, len);
+}
+
int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
unsigned int len, unsigned int indirect)
{
@@ -507,11 +604,13 @@
return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
}
- if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U)
+ if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
return MBOX_CFGSTAT_STATE_CONFIG;
+ }
- if (init_done && (res & SOFTFUNC_STATUS_INIT_DONE) == 0U)
+ if (init_done && (res & SOFTFUNC_STATUS_INIT_DONE) == 0U) {
return MBOX_CFGSTAT_STATE_CONFIG;
+ }
return MBOX_RET_OK;
}
@@ -527,3 +626,22 @@
return ret;
}
+
+int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf)
+{
+ unsigned int resp_len = sizeof(resp_buf);
+
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READTEMP, &chan, 1U,
+ CMD_CASUAL, resp_buf,
+ &resp_len);
+
+}
+
+int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf)
+{
+ unsigned int resp_len = sizeof(resp_buf);
+
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READVOLT, &chan, 1U,
+ CMD_CASUAL, resp_buf,
+ &resp_len);
+}
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index b0de60e..bb4efab 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -4,10 +4,12 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <common/debug.h>
#include <errno.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
#include <lib/mmio.h>
+#include "socfpga_f2sdram_manager.h"
#include "socfpga_mailbox.h"
#include "socfpga_reset_manager.h"
#include "socfpga_system_manager.h"
@@ -89,58 +91,241 @@
static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match)
{
- int time_out = 1000;
+ int time_out = 300;
while (time_out--) {
if ((mmio_read_32(addr) & mask) == match) {
return 0;
}
+ udelay(1000);
}
return -ETIMEDOUT;
}
+static void socfpga_s2f_bridge_mask(uint32_t mask,
+ uint32_t *brg_mask,
+ uint32_t *noc_mask)
+{
+ *brg_mask = 0;
+ *noc_mask = 0;
+
+ if ((mask & SOC2FPGA_MASK) != 0U) {
+ *brg_mask |= RSTMGR_FIELD(BRG, SOC2FPGA);
+ *noc_mask |= IDLE_DATA_SOC2FPGA;
+ }
+
+ if ((mask & LWHPS2FPGA_MASK) != 0U) {
+ *brg_mask |= RSTMGR_FIELD(BRG, LWHPS2FPGA);
+ *noc_mask |= IDLE_DATA_LWSOC2FPGA;
+ }
+}
+
-int socfpga_bridges_enable(void)
+static void socfpga_f2s_bridge_mask(uint32_t mask,
+ uint32_t *brg_mask,
+ uint32_t *f2s_idlereq,
+ uint32_t *f2s_force_drain,
+ uint32_t *f2s_en,
+ uint32_t *f2s_idleack,
+ uint32_t *f2s_respempty)
{
- /* Clear idle request */
- mmio_setbits_32(SOCFPGA_SYSMGR(NOC_IDLEREQ_CLR), ~0);
+ *brg_mask = 0;
+ *f2s_idlereq = 0;
+ *f2s_force_drain = 0;
+ *f2s_en = 0;
+ *f2s_idleack = 0;
+ *f2s_respempty = 0;
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
+ if ((mask & FPGA2SOC_MASK) != 0U) {
+ *brg_mask |= RSTMGR_FIELD(BRG, FPGA2SOC);
+ }
+ if ((mask & F2SDRAM0_MASK) != 0U) {
+ *brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM0);
+ *f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
+ *f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
+ *f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
+ *f2s_idleack |= FLAGINTSTATUS_F2SDRAM0_IDLEACK;
+ *f2s_respempty |= FLAGINTSTATUS_F2SDRAM0_RESPEMPTY;
+ }
+ if ((mask & F2SDRAM1_MASK) != 0U) {
+ *brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM1);
+ *f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM1_IDLEREQ;
+ *f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM1_FORCE_DRAIN;
+ *f2s_en |= FLAGOUTSETCLR_F2SDRAM1_ENABLE;
+ *f2s_idleack |= FLAGINTSTATUS_F2SDRAM1_IDLEACK;
+ *f2s_respempty |= FLAGINTSTATUS_F2SDRAM1_RESPEMPTY;
+ }
+ if ((mask & F2SDRAM2_MASK) != 0U) {
+ *brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM2);
+ *f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM2_IDLEREQ;
+ *f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM2_FORCE_DRAIN;
+ *f2s_en |= FLAGOUTSETCLR_F2SDRAM2_ENABLE;
+ *f2s_idleack |= FLAGINTSTATUS_F2SDRAM2_IDLEACK;
+ *f2s_respempty |= FLAGINTSTATUS_F2SDRAM2_RESPEMPTY;
+ }
+#else
+ if ((mask & FPGA2SOC_MASK) != 0U) {
+ *brg_mask |= RSTMGR_FIELD(BRG, FPGA2SOC);
+ *f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
+ *f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
+ *f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
+ *f2s_idleack |= FLAGINTSTATUS_F2SDRAM0_IDLEACK;
+ *f2s_respempty |= FLAGINTSTATUS_F2SDRAM0_RESPEMPTY;
+ }
+#endif
+}
+
+int socfpga_bridges_enable(uint32_t mask)
+{
+ int ret = 0;
+ uint32_t brg_mask = 0;
+ uint32_t noc_mask = 0;
+ uint32_t f2s_idlereq = 0;
+ uint32_t f2s_force_drain = 0;
+ uint32_t f2s_en = 0;
+ uint32_t f2s_idleack = 0;
+ uint32_t f2s_respempty = 0;
+
+ /* Enable s2f bridge */
+ socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
+ if (brg_mask != 0U) {
+ /* Clear idle request */
+ mmio_setbits_32(SOCFPGA_SYSMGR(NOC_IDLEREQ_CLR),
+ noc_mask);
+
+ /* De-assert all bridges */
+ mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
- /* De-assert all bridges */
- mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), ~0);
+ /* Wait until idle ack becomes 0 */
+ ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
+ noc_mask, 0);
+ if (ret < 0) {
+ ERROR("S2F bridge enable: "
+ "Timeout waiting for idle ack\n");
+ }
+ }
+
+ /* Enable f2s bridge */
+ socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
+ &f2s_force_drain, &f2s_en,
+ &f2s_idleack, &f2s_respempty);
+ if (brg_mask != 0U) {
+ mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
+
+ mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+ f2s_idlereq);
+
+ ret = poll_idle_status(SOCFPGA_F2SDRAMMGR(
+ SIDEBANDMGR_FLAGINSTATUS0), f2s_idleack, 0);
+ if (ret < 0) {
+ ERROR("F2S bridge enable: "
+ "Timeout waiting for idle ack");
+ }
- /* Wait until idle ack becomes 0 */
- return poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
- IDLE_DATA_MASK, 0);
+ mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+ f2s_force_drain);
+ udelay(5);
+
+ mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+ f2s_en);
+ udelay(5);
+ }
+
+ return ret;
}
-int socfpga_bridges_disable(void)
+int socfpga_bridges_disable(uint32_t mask)
{
- /* Set idle request */
- mmio_write_32(SOCFPGA_SYSMGR(NOC_IDLEREQ_SET), ~0);
+ int ret = 0;
+ int timeout = 300;
+ uint32_t brg_mask = 0;
+ uint32_t noc_mask = 0;
+ uint32_t f2s_idlereq = 0;
+ uint32_t f2s_force_drain = 0;
+ uint32_t f2s_en = 0;
+ uint32_t f2s_idleack = 0;
+ uint32_t f2s_respempty = 0;
- /* Enable NOC timeout */
- mmio_setbits_32(SOCFPGA_SYSMGR(NOC_TIMEOUT), 1);
+ /* Disable s2f bridge */
+ socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
+ if (brg_mask != 0U) {
+ mmio_setbits_32(SOCFPGA_SYSMGR(NOC_IDLEREQ_SET),
+ noc_mask);
- /* Wait until each idle ack bit toggle to 1 */
- if (poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
- IDLE_DATA_MASK, IDLE_DATA_MASK))
- return -ETIMEDOUT;
+ mmio_write_32(SOCFPGA_SYSMGR(NOC_TIMEOUT), 1);
- /* Wait until each idle status bit toggle to 1 */
- if (poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLESTATUS),
- IDLE_DATA_MASK, IDLE_DATA_MASK))
- return -ETIMEDOUT;
+ ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
+ noc_mask, noc_mask);
+ if (ret < 0) {
+ ERROR("S2F Bridge disable: "
+ "Timeout waiting for idle ack\n");
+ }
+
+ ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLESTATUS),
+ noc_mask, noc_mask);
+ if (ret < 0) {
+ ERROR("S2F Bridge disable: "
+ "Timeout waiting for idle status\n");
+ }
- /* Assert all bridges */
+ mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
+
+ mmio_write_32(SOCFPGA_SYSMGR(NOC_TIMEOUT), 0);
+ }
+
+ /* Disable f2s bridge */
+ socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
+ &f2s_force_drain, &f2s_en,
+ &f2s_idleack, &f2s_respempty);
+ if (brg_mask != 0U) {
+ mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN),
+ RSTMGR_HDSKEN_FPGAHSEN);
+
+ mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+ RSTMGR_HDSKREQ_FPGAHSREQ);
+
+ poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+ RSTMGR_HDSKACK_FPGAHSACK_MASK,
+ RSTMGR_HDSKACK_FPGAHSACK_MASK);
+
+ mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+ f2s_en);
+ udelay(5);
+
+ mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+ f2s_force_drain);
+ udelay(5);
+
+ do {
+ /* Read response queue status to ensure it is empty */
+ uint32_t idle_status;
+
+ idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
+ SIDEBANDMGR_FLAGINSTATUS0));
+ if ((idle_status & f2s_respempty) != 0U) {
+ idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
+ SIDEBANDMGR_FLAGINSTATUS0));
+ if ((idle_status & f2s_respempty) != 0U) {
+ break;
+ }
+ }
+ udelay(1000);
+ } while (timeout-- > 0);
+
#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
- mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
- ~(RSTMGR_FIELD(BRG, DDRSCH) | RSTMGR_FIELD(BRG, FPGA2SOC)));
+ /* Software must never write a 0x1 to FPGA2SOC_MASK bit */
+ mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+ brg_mask & ~RSTMGR_FIELD(BRG, FPGA2SOC));
#else
- mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
- ~(RSTMGR_FIELD(BRG, MPFE) | RSTMGR_FIELD(BRG, FPGA2SOC)));
+ mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+ brg_mask);
#endif
+ mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+ RSTMGR_HDSKEQ_FPGAHSREQ);
- /* Disable NOC timeout */
- mmio_clrbits_32(SOCFPGA_SYSMGR(NOC_TIMEOUT), 1);
+ mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+ f2s_idlereq);
+ }
- return 0;
+ return ret;
}
diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c
index c55cc9d..dcd51e2 100644
--- a/plat/intel/soc/common/socfpga_delay_timer.c
+++ b/plat/intel/soc/common/socfpga_delay_timer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,10 +8,12 @@
#include <arch_helpers.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
+#include "socfpga_plat_def.h"
#define SOCFPGA_GLOBAL_TIMER 0xffd01000
#define SOCFPGA_GLOBAL_TIMER_EN 0x3
+static timer_ops_t plat_timer_ops;
/********************************************************************
* The timer delay function
********************************************************************/
@@ -26,15 +28,19 @@
return (uint32_t)(~read_cntpct_el0());
}
-static const timer_ops_t plat_timer_ops = {
- .get_timer_value = socfpga_get_timer_value,
- .clk_mult = 1,
- .clk_div = PLAT_SYS_COUNTER_FREQ_IN_MHZ,
-};
+void socfpga_delay_timer_init_args(void)
+{
+ plat_timer_ops.get_timer_value = socfpga_get_timer_value;
+ plat_timer_ops.clk_mult = 1;
+ plat_timer_ops.clk_div = PLAT_SYS_COUNTER_FREQ_IN_MHZ;
+
+ timer_init(&plat_timer_ops);
+
+}
void socfpga_delay_timer_init(void)
{
- timer_init(&plat_timer_ops);
+ socfpga_delay_timer_init_args();
mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN);
asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN));
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 14cd9e0..f079349 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -19,11 +19,17 @@
/* Total buffer the driver can hold */
#define FPGA_CONFIG_BUFFER_SIZE 4
+static config_type request_type = NO_REQUEST;
static int current_block, current_buffer;
-static int read_block, max_blocks, is_partial_reconfig;
+static int read_block, max_blocks;
static uint32_t send_id, rcv_id;
static uint32_t bytes_per_block, blocks_submitted;
+static bool bridge_disable;
+/* RSU static variables */
+static uint32_t rsu_dcmf_ver[4] = {0};
+static uint16_t rsu_dcmf_stat[4] = {0};
+static uint32_t rsu_max_retry;
/* SiP Service UUID */
DEFINE_SVC_UUID2(intl_svc_uid,
@@ -56,8 +62,9 @@
args[2] = buffer->size - buffer->size_written;
current_buffer++;
current_buffer %= FPGA_CONFIG_BUFFER_SIZE;
- } else
+ } else {
args[2] = bytes_per_block;
+ }
buffer->size_written += args[2];
mailbox_send_cmd_async(&send_id, MBOX_RECONFIG_DATA, args,
@@ -72,34 +79,48 @@
static int intel_fpga_sdm_write_all(void)
{
- for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
+ for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
if (intel_fpga_sdm_write_buffer(
- &fpga_config_buffers[current_buffer]))
+ &fpga_config_buffers[current_buffer])) {
break;
+ }
+ }
return 0;
}
-static uint32_t intel_mailbox_fpga_config_isdone(uint32_t query_type)
+static uint32_t intel_mailbox_fpga_config_isdone(void)
{
uint32_t ret;
- if (query_type == 1)
- ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS, false);
- else
- ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true);
+ switch (request_type) {
+ case RECONFIGURATION:
+ ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS,
+ true);
+ break;
+ case BITSTREAM_AUTH:
+ ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS,
+ false);
+ break;
+ default:
+ ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS,
+ false);
+ break;
+ }
- if (ret) {
- if (ret == MBOX_CFGSTAT_STATE_CONFIG)
+ if (ret != 0U) {
+ if (ret == MBOX_CFGSTAT_STATE_CONFIG) {
return INTEL_SIP_SMC_STATUS_BUSY;
- else
+ } else {
+ request_type = NO_REQUEST;
return INTEL_SIP_SMC_STATUS_ERROR;
+ }
}
- if (query_type != 1) {
- /* full reconfiguration */
- if (!is_partial_reconfig)
- socfpga_bridges_enable(); /* Enable bridge */
+ if (bridge_disable != 0U) {
+ socfpga_bridges_enable(~0); /* Enable bridge */
+ bridge_disable = false;
}
+ request_type = NO_REQUEST;
return INTEL_SIP_SMC_STATUS_OK;
}
@@ -158,6 +179,7 @@
if (status != MBOX_NO_RESPONSE &&
status != MBOX_TIMEOUT && resp_len != 0) {
mailbox_clear_response();
+ request_type = NO_REQUEST;
return INTEL_SIP_SMC_STATUS_ERROR;
}
@@ -166,10 +188,11 @@
intel_fpga_sdm_write_all();
- if (*count > 0)
+ if (*count > 0) {
status = INTEL_SIP_SMC_STATUS_OK;
- else if (*count == 0)
+ } else if (*count == 0) {
status = INTEL_SIP_SMC_STATUS_BUSY;
+ }
for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
if (fpga_config_buffers[i].write_requested != 0) {
@@ -178,13 +201,14 @@
}
}
- if (all_completed == 1)
+ if (all_completed == 1) {
return INTEL_SIP_SMC_STATUS_OK;
+ }
return status;
}
-static int intel_fpga_config_start(uint32_t config_type)
+static int intel_fpga_config_start(uint32_t flag)
{
uint32_t argument = 0x1;
uint32_t response[3];
@@ -192,7 +216,17 @@
unsigned int size = 0;
unsigned int resp_len = ARRAY_SIZE(response);
+ request_type = RECONFIGURATION;
+
+ if (!CONFIG_TEST_FLAG(flag, PARTIAL_CONFIG)) {
+ bridge_disable = true;
+ }
+
- is_partial_reconfig = config_type;
+ if (CONFIG_TEST_FLAG(flag, AUTHENTICATION)) {
+ size = 1;
+ bridge_disable = false;
+ request_type = BITSTREAM_AUTH;
+ }
mailbox_clear_response();
@@ -202,8 +236,11 @@
status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RECONFIG, &argument, size,
CMD_CASUAL, response, &resp_len);
- if (status < 0)
- return status;
+ if (status < 0) {
+ bridge_disable = false;
+ request_type = NO_REQUEST;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
max_blocks = response[0];
bytes_per_block = response[1];
@@ -222,20 +259,21 @@
read_block = 0;
current_buffer = 0;
- /* full reconfiguration */
- if (!is_partial_reconfig) {
- /* Disable bridge */
- socfpga_bridges_disable();
+ /* Disable bridge on full reconfiguration */
+ if (bridge_disable) {
+ socfpga_bridges_disable(~0);
}
- return 0;
+ return INTEL_SIP_SMC_STATUS_OK;
}
static bool is_fpga_config_buffer_full(void)
{
- for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
- if (!fpga_config_buffers[i].write_requested)
+ for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
+ if (!fpga_config_buffers[i].write_requested) {
return false;
+ }
+ }
return true;
}
@@ -244,12 +282,15 @@
if (!addr && !size) {
return true;
}
- if (size > (UINT64_MAX - addr))
+ if (size > (UINT64_MAX - addr)) {
return false;
- if (addr < BL31_LIMIT)
+ }
+ if (addr < BL31_LIMIT) {
return false;
- if (addr + size > DRAM_BASE + DRAM_SIZE)
+ }
+ if (addr + size > DRAM_BASE + DRAM_SIZE) {
return false;
+ }
return true;
}
@@ -261,8 +302,9 @@
intel_fpga_sdm_write_all();
if (!is_address_in_ddr_range(mem, size) ||
- is_fpga_config_buffer_full())
+ is_fpga_config_buffer_full()) {
return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
int j = (i + current_buffer) % FPGA_CONFIG_BUFFER_SIZE;
@@ -279,14 +321,19 @@
}
}
- if (is_fpga_config_buffer_full())
+ if (is_fpga_config_buffer_full()) {
return INTEL_SIP_SMC_STATUS_BUSY;
+ }
return INTEL_SIP_SMC_STATUS_OK;
}
static int is_out_of_sec_range(uint64_t reg_addr)
{
+#if DEBUG
+ return 0;
+#endif
+
switch (reg_addr) {
case(0xF8011100): /* ECCCTRL1 */
case(0xF8011104): /* ECCCTRL2 */
@@ -327,8 +374,9 @@
/* Secure register access */
uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval)
{
- if (is_out_of_sec_range(reg_addr))
+ if (is_out_of_sec_range(reg_addr)) {
return INTEL_SIP_SMC_STATUS_ERROR;
+ }
*retval = mmio_read_32(reg_addr);
@@ -338,8 +386,9 @@
uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val,
uint32_t *retval)
{
- if (is_out_of_sec_range(reg_addr))
+ if (is_out_of_sec_range(reg_addr)) {
return INTEL_SIP_SMC_STATUS_ERROR;
+ }
mmio_write_32(reg_addr, val);
@@ -363,8 +412,9 @@
static uint32_t intel_rsu_status(uint64_t *respbuf, unsigned int respbuf_sz)
{
- if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0)
+ if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) {
return INTEL_SIP_SMC_RSU_ERROR;
+ }
return INTEL_SIP_SMC_STATUS_OK;
}
@@ -377,8 +427,9 @@
static uint32_t intel_rsu_notify(uint32_t execution_stage)
{
- if (mailbox_hps_stage_notify(execution_stage) < 0)
+ if (mailbox_hps_stage_notify(execution_stage) < 0) {
return INTEL_SIP_SMC_RSU_ERROR;
+ }
return INTEL_SIP_SMC_STATUS_OK;
}
@@ -386,28 +437,99 @@
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)
+ if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) {
return INTEL_SIP_SMC_RSU_ERROR;
+ }
*ret_stat = respbuf[8];
return INTEL_SIP_SMC_STATUS_OK;
}
+static uint32_t intel_rsu_copy_dcmf_version(uint64_t dcmf_ver_1_0,
+ uint64_t dcmf_ver_3_2)
+{
+ rsu_dcmf_ver[0] = dcmf_ver_1_0;
+ rsu_dcmf_ver[1] = dcmf_ver_1_0 >> 32;
+ rsu_dcmf_ver[2] = dcmf_ver_3_2;
+ rsu_dcmf_ver[3] = dcmf_ver_3_2 >> 32;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_rsu_copy_dcmf_status(uint64_t dcmf_stat)
+{
+ rsu_dcmf_stat[0] = 0xFFFF & (dcmf_stat >> (0 * 16));
+ rsu_dcmf_stat[1] = 0xFFFF & (dcmf_stat >> (1 * 16));
+ rsu_dcmf_stat[2] = 0xFFFF & (dcmf_stat >> (2 * 16));
+ rsu_dcmf_stat[3] = 0xFFFF & (dcmf_stat >> (3 * 16));
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+/* Intel HWMON services */
+static uint32_t intel_hwmon_readtemp(uint32_t chan, uint32_t *retval)
+{
+ if (chan > TEMP_CHANNEL_MAX) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (mailbox_hwmon_readtemp(chan, retval) < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static uint32_t intel_hwmon_readvolt(uint32_t chan, uint32_t *retval)
+{
+ if (chan > VOLT_CHANNEL_MAX) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (mailbox_hwmon_readvolt(chan, retval) < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
/* Mailbox services */
+static uint32_t intel_smc_fw_version(uint32_t *fw_version)
+{
+ int status;
+ unsigned int resp_len = CONFIG_STATUS_WORD_SIZE;
+ uint32_t resp_data[CONFIG_STATUS_WORD_SIZE] = {0U};
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CONFIG_STATUS, NULL, 0U,
+ CMD_CASUAL, resp_data, &resp_len);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (resp_len <= CONFIG_STATUS_FW_VER_OFFSET) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *fw_version = resp_data[CONFIG_STATUS_FW_VER_OFFSET] & CONFIG_STATUS_FW_VER_MASK;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args,
- unsigned int len,
- uint32_t urgent, uint32_t *response,
+ unsigned int len, uint32_t urgent, uint64_t response,
unsigned int resp_len, int *mbox_status,
unsigned int *len_in_resp)
{
*len_in_resp = 0;
- *mbox_status = 0;
+ *mbox_status = GENERIC_RESPONSE_ERROR;
- if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len))
+ if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent,
- response, &resp_len);
+ (uint32_t *) response, &resp_len);
if (status < 0) {
*mbox_status = -status;
@@ -416,14 +538,104 @@
*mbox_status = 0;
*len_in_resp = resp_len;
+
+ flush_dcache_range(response, resp_len * MBOX_WORD_BYTE);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static int intel_smc_get_usercode(uint32_t *user_code)
+{
+ int status;
+ unsigned int resp_len = sizeof(user_code) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_USERCODE, NULL,
+ 0U, CMD_CASUAL, user_code, &resp_len);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_smc_service_completed(uint64_t addr, uint32_t size,
+ uint32_t mode, uint32_t *job_id,
+ uint32_t *ret_size, uint32_t *mbox_error)
+{
+ int status = 0;
+ uint32_t resp_len = size / MBOX_WORD_BYTE;
+
+ if (resp_len > MBOX_DATA_MAX_LEN) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(addr, size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (mode == SERVICE_COMPLETED_MODE_ASYNC) {
+ status = mailbox_read_response_async(job_id,
+ NULL, (uint32_t *) addr, &resp_len, 0);
+ } else {
+ status = mailbox_read_response(job_id,
+ (uint32_t *) addr, &resp_len);
+
+ if (status == MBOX_NO_RESPONSE) {
+ status = MBOX_BUSY;
+ }
+ }
+
+ if (status == MBOX_NO_RESPONSE) {
+ return INTEL_SIP_SMC_STATUS_NO_RESPONSE;
+ }
+
+ if (status == MBOX_BUSY) {
+ return INTEL_SIP_SMC_STATUS_BUSY;
+ }
+
+ *ret_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(addr, *ret_size);
+
+ if (status != MBOX_RET_OK) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
return INTEL_SIP_SMC_STATUS_OK;
}
+/* Miscellaneous HPS services */
+uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask)
+{
+ int status = 0;
+
+ if ((enable & SOCFPGA_BRIDGE_ENABLE) != 0U) {
+ if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0U) {
+ status = socfpga_bridges_enable((uint32_t)mask);
+ } else {
+ status = socfpga_bridges_enable(~0);
+ }
+ } else {
+ if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0U) {
+ status = socfpga_bridges_disable((uint32_t)mask);
+ } else {
+ status = socfpga_bridges_disable(~0);
+ }
+ }
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
/*
* This function is responsible for handling all SiP calls from the NS world
*/
-uintptr_t sip_smc_handler(uint32_t smc_fid,
+uintptr_t sip_smc_handler_v1(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
u_register_t x3,
@@ -432,13 +644,14 @@
void *handle,
u_register_t flags)
{
- uint32_t retval = 0;
- uint32_t completed_addr[3];
- uint64_t rsu_respbuf[9];
+ uint32_t retval = 0, completed_addr[3];
+ uint32_t retval2 = 0;
+ uint32_t mbox_error = 0;
+ uint64_t retval64, rsu_respbuf[9];
int status = INTEL_SIP_SMC_STATUS_OK;
int mbox_status;
unsigned int len_in_resp;
- u_register_t x5, x6;
+ u_register_t x5, x6, x7;
switch (smc_fid) {
case SIP_SVC_UID:
@@ -446,7 +659,7 @@
SMC_UUID_RET(handle, intl_svc_uid);
case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
- status = intel_mailbox_fpga_config_isdone(x1);
+ status = intel_mailbox_fpga_config_isdone();
SMC_RET4(handle, status, 0, 0, 0);
case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
@@ -530,24 +743,375 @@
SMC_RET2(handle, status, retval);
}
+ case INTEL_SIP_SMC_RSU_DCMF_VERSION:
+ SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
+ ((uint64_t)rsu_dcmf_ver[1] << 32) | rsu_dcmf_ver[0],
+ ((uint64_t)rsu_dcmf_ver[3] << 32) | rsu_dcmf_ver[2]);
+
+ case INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION:
+ status = intel_rsu_copy_dcmf_version(x1, x2);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_RSU_DCMF_STATUS:
+ SMC_RET2(handle, INTEL_SIP_SMC_STATUS_OK,
+ ((uint64_t)rsu_dcmf_stat[3] << 48) |
+ ((uint64_t)rsu_dcmf_stat[2] << 32) |
+ ((uint64_t)rsu_dcmf_stat[1] << 16) |
+ rsu_dcmf_stat[0]);
+
+ case INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS:
+ status = intel_rsu_copy_dcmf_status(x1);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_RSU_MAX_RETRY:
+ SMC_RET2(handle, INTEL_SIP_SMC_STATUS_OK, rsu_max_retry);
+
+ case INTEL_SIP_SMC_RSU_COPY_MAX_RETRY:
+ rsu_max_retry = x1;
+ SMC_RET1(handle, INTEL_SIP_SMC_STATUS_OK);
+
case INTEL_SIP_SMC_ECC_DBE:
status = intel_ecc_dbe_notification(x1);
SMC_RET1(handle, status);
+ case INTEL_SIP_SMC_SERVICE_COMPLETED:
+ status = intel_smc_service_completed(x1, x2, x3, &rcv_id,
+ &len_in_resp, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x1, len_in_resp);
+
+ case INTEL_SIP_SMC_FIRMWARE_VERSION:
+ status = intel_smc_fw_version(&retval);
+ SMC_RET2(handle, status, retval);
+
case INTEL_SIP_SMC_MBOX_SEND_CMD:
x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
- status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4,
- (uint32_t *)x5, x6, &mbox_status,
- &len_in_resp);
+ status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4, x5, x6,
+ &mbox_status, &len_in_resp);
SMC_RET3(handle, status, mbox_status, len_in_resp);
+ case INTEL_SIP_SMC_GET_USERCODE:
+ status = intel_smc_get_usercode(&retval);
+ SMC_RET2(handle, status, retval);
+
+ case INTEL_SIP_SMC_FCS_CRYPTION:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+
+ if (x1 == FCS_MODE_DECRYPT) {
+ status = intel_fcs_decryption(x2, x3, x4, x5, &send_id);
+ } else if (x1 == FCS_MODE_ENCRYPT) {
+ status = intel_fcs_encryption(x2, x3, x4, x5, &send_id);
+ } else {
+ status = INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ SMC_RET3(handle, status, x4, x5);
+
+ case INTEL_SIP_SMC_FCS_CRYPTION_EXT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+
+ if (x3 == FCS_MODE_DECRYPT) {
+ status = intel_fcs_decryption_ext(x1, x2, x4, x5, x6,
+ (uint32_t *) &x7, &mbox_error);
+ } else if (x3 == FCS_MODE_ENCRYPT) {
+ status = intel_fcs_encryption_ext(x1, x2, x4, x5, x6,
+ (uint32_t *) &x7, &mbox_error);
+ } else {
+ status = INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ SMC_RET4(handle, status, mbox_error, x6, x7);
+
+ case INTEL_SIP_SMC_FCS_RANDOM_NUMBER:
+ status = intel_fcs_random_number_gen(x1, &retval64,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x1, retval64);
+
+ case INTEL_SIP_SMC_FCS_RANDOM_NUMBER_EXT:
+ status = intel_fcs_random_number_gen_ext(x1, x2, x3,
+ &send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_FCS_SEND_CERTIFICATE:
+ status = intel_fcs_send_cert(x1, x2, &send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_FCS_GET_PROVISION_DATA:
+ status = intel_fcs_get_provision_data(&send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH:
+ status = intel_fcs_cntr_set_preauth(x1, x2, x3,
+ &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_HPS_SET_BRIDGES:
+ status = intel_hps_set_bridges(x1, x2);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_HWMON_READTEMP:
+ status = intel_hwmon_readtemp(x1, &retval);
+ SMC_RET2(handle, status, retval);
+
+ case INTEL_SIP_SMC_HWMON_READVOLT:
+ status = intel_hwmon_readvolt(x1, &retval);
+ SMC_RET2(handle, status, retval);
+
+ case INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN:
+ status = intel_fcs_sigma_teardown(x1, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_CHIP_ID:
+ status = intel_fcs_chip_id(&retval, &retval2, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, retval, retval2);
+
+ case INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY:
+ status = intel_fcs_attestation_subkey(x1, x2, x3,
+ (uint32_t *) &x4, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x3, x4);
+
+ case INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS:
+ status = intel_fcs_get_measurement(x1, x2, x3,
+ (uint32_t *) &x4, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x3, x4);
+
+ case INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT:
+ status = intel_fcs_get_attestation_cert(x1, x2,
+ (uint32_t *) &x3, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x2, x3);
+
+ case INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD:
+ status = intel_fcs_create_cert_on_reload(x1, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_OPEN_CS_SESSION:
+ status = intel_fcs_open_crypto_service_session(&retval, &mbox_error);
+ SMC_RET3(handle, status, mbox_error, retval);
+
+ case INTEL_SIP_SMC_FCS_CLOSE_CS_SESSION:
+ status = intel_fcs_close_crypto_service_session(x1, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_IMPORT_CS_KEY:
+ status = intel_fcs_import_crypto_service_key(x1, x2, &send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_FCS_EXPORT_CS_KEY:
+ status = intel_fcs_export_crypto_service_key(x1, x2, x3,
+ (uint32_t *) &x4, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x3, x4);
+
+ case INTEL_SIP_SMC_FCS_REMOVE_CS_KEY:
+ status = intel_fcs_remove_crypto_service_key(x1, x2,
+ &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_GET_CS_KEY_INFO:
+ status = intel_fcs_get_crypto_service_key_info(x1, x2, x3,
+ (uint32_t *) &x4, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x3, x4);
+
+ case INTEL_SIP_SMC_FCS_GET_DIGEST_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_get_digest_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_GET_DIGEST_UPDATE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_get_digest_update_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, false,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_get_digest_update_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, true,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_mac_verify_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_MAC_VERIFY_UPDATE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+ status = intel_fcs_mac_verify_update_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, x7,
+ false, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+ status = intel_fcs_mac_verify_update_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, x7,
+ true, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdsa_sha2_data_sign_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(x1, x2,
+ x3, x4, x5, (uint32_t *) &x6, false,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(x1, x2,
+ x3, x4, x5, (uint32_t *) &x6, true,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdsa_hash_sign_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_ecdsa_hash_sign_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdsa_hash_sig_verify_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_ecdsa_hash_sig_verify_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdsa_sha2_data_sig_verify_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+ status = intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(
+ x1, x2, x3, x4, x5, (uint32_t *) &x6,
+ x7, false, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+ status = intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(
+ x1, x2, x3, x4, x5, (uint32_t *) &x6,
+ x7, true, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdsa_get_pubkey_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE:
+ status = intel_fcs_ecdsa_get_pubkey_finalize(x1, x2, x3,
+ (uint32_t *) &x4, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x3, x4);
+
+ case INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdh_request_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_ecdh_request_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_AES_CRYPT_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_aes_crypt_init(x1, x2, x3, x4, x5,
+ &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4,
+ x5, x6, false, &send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_FCS_AES_CRYPT_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4,
+ x5, x6, true, &send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384:
+ status = intel_fcs_get_rom_patch_sha384(x1, &retval64,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x1, retval64);
+
+ case INTEL_SIP_SMC_SVC_VERSION:
+ SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
+ SIP_SVC_VERSION_MAJOR,
+ SIP_SVC_VERSION_MINOR);
+
default:
return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
cookie, handle, flags);
}
}
+uintptr_t sip_smc_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ uint32_t cmd = smc_fid & INTEL_SIP_SMC_CMD_MASK;
+
+ if (cmd >= INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN &&
+ cmd <= INTEL_SIP_SMC_CMD_V2_RANGE_END) {
+ return sip_smc_handler_v2(smc_fid, x1, x2, x3, x4,
+ cookie, handle, flags);
+ } else {
+ return sip_smc_handler_v1(smc_fid, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+}
+
DECLARE_RT_SVC(
socfpga_sip_svc,
OEN_SIP_START,
diff --git a/plat/intel/soc/common/socfpga_sip_svc_v2.c b/plat/intel/soc/common/socfpga_sip_svc_v2.c
new file mode 100644
index 0000000..791c714
--- /dev/null
+++ b/plat/intel/soc/common/socfpga_sip_svc_v2.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+
+#include "socfpga_mailbox.h"
+#include "socfpga_sip_svc.h"
+
+static uint32_t intel_v2_mbox_send_cmd(uint32_t req_header,
+ uint32_t *data, uint32_t data_size)
+{
+ uint32_t value;
+ uint32_t len;
+
+ if ((data == NULL) || (data_size == 0)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (data_size > (MBOX_INC_HEADER_MAX_WORD_SIZE * MBOX_WORD_BYTE)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(data_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /* Make sure client id align in SMC SiP V2 header and mailbox header */
+ value = (req_header >> INTEL_SIP_SMC_HEADER_CID_OFFSET) &
+ INTEL_SIP_SMC_HEADER_CID_MASK;
+
+ if (value != MBOX_RESP_CLIENT_ID(data[0])) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /* Make sure job id align in SMC SiP V2 header and mailbox header */
+ value = (req_header >> INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET) &
+ INTEL_SIP_SMC_HEADER_JOB_ID_MASK;
+
+ if (value != MBOX_RESP_JOB_ID(data[0])) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /*
+ * Make sure data length align in SMC SiP V2 header and
+ * mailbox header
+ */
+ len = (data_size / MBOX_WORD_BYTE) - 1;
+
+ if (len != MBOX_RESP_LEN(data[0])) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ return mailbox_send_cmd_async_ext(data[0], &data[1], len);
+}
+
+static uint32_t intel_v2_mbox_poll_resp(uint64_t req_header,
+ uint32_t *data, uint32_t *data_size,
+ uint64_t *resp_header)
+{
+ int status = 0;
+ uint32_t resp_len;
+ uint32_t job_id = 0;
+ uint32_t client_id = 0;
+ uint32_t version;
+
+ if ((data == NULL) || (data_size == NULL) || (resp_header == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(*data_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = (*data_size / MBOX_WORD_BYTE) - 1;
+ status = mailbox_read_response_async(&job_id, &data[0], &data[1],
+ &resp_len, 1);
+
+ if (status == MBOX_BUSY) {
+ status = INTEL_SIP_SMC_STATUS_BUSY;
+ } else if (status == MBOX_NO_RESPONSE) {
+ status = INTEL_SIP_SMC_STATUS_NO_RESPONSE;
+ } else {
+ *data_size = 0;
+
+ if (resp_len > 0) {
+ /*
+ * Fill in the final response length,
+ * the length include both mailbox header and payload
+ */
+ *data_size = (resp_len + 1) * MBOX_WORD_BYTE;
+
+ /* Extract the client id from mailbox header */
+ client_id = MBOX_RESP_CLIENT_ID(data[0]);
+ }
+
+ /*
+ * Extract SMC SiP V2 protocol version from
+ * SMC request header
+ */
+ version = (req_header >> INTEL_SIP_SMC_HEADER_VERSION_OFFSET) &
+ INTEL_SIP_SMC_HEADER_VERSION_MASK;
+
+ /* Fill in SMC SiP V2 protocol response header */
+ *resp_header = 0;
+ *resp_header |= (((uint64_t)job_id) &
+ INTEL_SIP_SMC_HEADER_JOB_ID_MASK) <<
+ INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET;
+ *resp_header |= (((uint64_t)client_id) &
+ INTEL_SIP_SMC_HEADER_CID_MASK) <<
+ INTEL_SIP_SMC_HEADER_CID_OFFSET;
+ *resp_header |= (((uint64_t)version) &
+ INTEL_SIP_SMC_HEADER_VERSION_MASK) <<
+ INTEL_SIP_SMC_HEADER_VERSION_OFFSET;
+ }
+
+ return status;
+}
+
+uintptr_t sip_smc_handler_v2(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ uint32_t retval = 0;
+ uint64_t retval64 = 0;
+ int status = INTEL_SIP_SMC_STATUS_OK;
+
+ switch (smc_fid) {
+ case INTEL_SIP_SMC_V2_GET_SVC_VERSION:
+ SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, x1,
+ SIP_SVC_VERSION_MAJOR,
+ SIP_SVC_VERSION_MINOR);
+
+ case INTEL_SIP_SMC_V2_REG_READ:
+ status = intel_secure_reg_read(x2, &retval);
+ SMC_RET4(handle, status, x1, retval, x2);
+
+ case INTEL_SIP_SMC_V2_REG_WRITE:
+ status = intel_secure_reg_write(x2, (uint32_t)x3, &retval);
+ SMC_RET4(handle, status, x1, retval, x2);
+
+ case INTEL_SIP_SMC_V2_REG_UPDATE:
+ status = intel_secure_reg_update(x2, (uint32_t)x3,
+ (uint32_t)x4, &retval);
+ SMC_RET4(handle, status, x1, retval, x2);
+
+ case INTEL_SIP_SMC_V2_HPS_SET_BRIDGES:
+ status = intel_hps_set_bridges(x2, x3);
+ SMC_RET2(handle, status, x1);
+
+ case INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND:
+ status = intel_v2_mbox_send_cmd(x1, (uint32_t *)x2, x3);
+ SMC_RET2(handle, status, x1);
+
+ case INTEL_SIP_SMC_V2_MAILBOX_POLL_RESPONSE:
+ status = intel_v2_mbox_poll_resp(x1, (uint32_t *)x2,
+ (uint32_t *) &x3, &retval64);
+ SMC_RET4(handle, status, retval64, x2, x3);
+
+ default:
+ ERROR("%s: unhandled SMC V2 (0x%x)\n", __func__, smc_fid);
+ SMC_RET1(handle, SMC_UNK);
+ }
+}
diff --git a/plat/intel/soc/n5x/bl31_plat_setup.c b/plat/intel/soc/n5x/bl31_plat_setup.c
index 2a8daa6..5ca1a71 100644
--- a/plat/intel/soc/n5x/bl31_plat_setup.c
+++ b/plat/intel/soc/n5x/bl31_plat_setup.c
@@ -42,8 +42,8 @@
mmio_write_64(PLAT_SEC_ENTRY, 0);
- console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
- &console);
+ console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+ PLAT_BAUDRATE, &console);
/*
* Check params passed from BL31 should not be NULL,
*/
diff --git a/plat/intel/soc/n5x/include/socfpga_plat_def.h b/plat/intel/soc/n5x/include/socfpga_plat_def.h
index 9186852..4c36f91 100644
--- a/plat/intel/soc/n5x/include/socfpga_plat_def.h
+++ b/plat/intel/soc/n5x/include/socfpga_plat_def.h
@@ -19,6 +19,9 @@
#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x2000000
/* Register Mapping */
+#define SOCFPGA_CCU_NOC_REG_BASE U(0xf7000000)
+#define SOCFPGA_F2SDRAMMGR_REG_BASE U(0xf8024000)
+
#define SOCFPGA_MMC_REG_BASE U(0xff808000)
#define SOCFPGA_RSTMGR_REG_BASE U(0xffd11000)
@@ -29,4 +32,11 @@
#define SOCFPGA_SOC2FPGA_SCR_REG_BASE U(0xffd21200)
#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE U(0xffd21300)
+/* Platform specific system counter */
+/*
+ * In N5X the clk init is done in Uboot SPL.
+ * BL31 shall bypass the clk init and only provides other APIs.
+ */
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ (400)
+
#endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index b72bcc4..953bf0c 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -38,6 +38,7 @@
plat/intel/soc/n5x/bl31_plat_setup.c \
plat/intel/soc/common/socfpga_psci.c \
plat/intel/soc/common/socfpga_sip_svc.c \
+ plat/intel/soc/common/socfpga_sip_svc_v2.c \
plat/intel/soc/common/socfpga_topology.c \
plat/intel/soc/common/sip/socfpga_sip_ecc.c \
plat/intel/soc/common/sip/socfpga_sip_fcs.c \
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index a8026ea..73e3216 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-2021, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2021, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,6 +18,7 @@
#include "qspi/cadence_qspi.h"
#include "socfpga_emac.h"
+#include "socfpga_f2sdram_manager.h"
#include "socfpga_handoff.h"
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
@@ -25,6 +26,7 @@
#include "socfpga_system_manager.h"
#include "s10_clock_manager.h"
#include "s10_memory_controller.h"
+#include "s10_mmc.h"
#include "s10_pinmux.h"
#include "wdt/watchdog.h"
@@ -69,16 +71,20 @@
watchdog_init(get_wdt_clk());
- console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE,
- &console);
+ console_16550_register(PLAT_INTEL_UART_BASE, get_uart_clk(),
+ PLAT_BAUDRATE, &console);
socfpga_emac_init();
socfpga_delay_timer_init();
init_hard_memory_controller();
mailbox_init();
+ s10_mmc_init();
- if (!intel_mailbox_is_fpga_not_ready())
- socfpga_bridges_enable();
+ if (!intel_mailbox_is_fpga_not_ready()) {
+ socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK |
+ FPGA2SOC_MASK | F2SDRAM0_MASK | F2SDRAM1_MASK |
+ F2SDRAM2_MASK);
+ }
}
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index 128a808..be0fae5 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2020, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,6 +17,7 @@
#include <platform_def.h>
#include "socfpga_mailbox.h"
+#include "socfpga_noc.h"
#include "socfpga_private.h"
#include "socfpga_reset_manager.h"
#include "socfpga_system_manager.h"
@@ -49,8 +50,8 @@
mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
- console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE,
- &console);
+ console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+ PLAT_BAUDRATE, &console);
/*
* Check params passed from BL31 should not be NULL,
*/
@@ -122,6 +123,8 @@
(uint64_t)plat_secondary_cpus_bl31_entry);
mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
+
+ enable_ocram_firewall();
}
const mmap_region_t plat_stratix10_mmap[] = {
diff --git a/plat/intel/soc/stratix10/include/s10_clock_manager.h b/plat/intel/soc/stratix10/include/s10_clock_manager.h
index acc700a..cf57df3 100644
--- a/plat/intel/soc/stratix10/include/s10_clock_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_clock_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -60,6 +60,7 @@
#define ALT_CLKMGR_PERPLL 0xffd100a4
#define ALT_CLKMGR_PERPLL_EN 0x0
+#define ALT_CLKMGR_PERPLL_EN_SDMMCCLK BIT(5)
#define ALT_CLKMGR_PERPLL_BYPASS 0xc
#define ALT_CLKMGR_PERPLL_CNTR2CLK 0x18
#define ALT_CLKMGR_PERPLL_CNTR3CLK 0x1c
@@ -92,5 +93,7 @@
uint32_t get_wdt_clk(void);
uint32_t get_uart_clk(void);
uint32_t get_mmc_clk(void);
+uint32_t get_l3_clk(uint32_t ref_clk);
+uint32_t get_ref_clk(uint32_t pllglob);
#endif
diff --git a/plat/intel/soc/stratix10/include/s10_mmc.h b/plat/intel/soc/stratix10/include/s10_mmc.h
new file mode 100644
index 0000000..99f86f5
--- /dev/null
+++ b/plat/intel/soc/stratix10/include/s10_mmc.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __S10_MMC_H__
+#define __S10_MMC_H__
+
+void s10_mmc_init(void);
+
+#endif /* S10_MMC_H */
diff --git a/plat/intel/soc/stratix10/include/s10_noc.h b/plat/intel/soc/stratix10/include/s10_noc.h
deleted file mode 100644
index 3e1e527..0000000
--- a/plat/intel/soc/stratix10/include/s10_noc.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#define AXI_AP (1<<0)
-#define FPGA2SOC (1<<16)
-#define MPU (1<<24)
-#define S10_NOC_PER_SCR_NAND 0xffd21000
-#define S10_NOC_PER_SCR_NAND_DATA 0xffd21004
-#define S10_NOC_PER_SCR_USB0 0xffd2100c
-#define S10_NOC_PER_SCR_USB1 0xffd21010
-#define S10_NOC_PER_SCR_SPI_M0 0xffd2101c
-#define S10_NOC_PER_SCR_SPI_M1 0xffd21020
-#define S10_NOC_PER_SCR_SPI_S0 0xffd21024
-#define S10_NOC_PER_SCR_SPI_S1 0xffd21028
-#define S10_NOC_PER_SCR_EMAC0 0xffd2102c
-#define S10_NOC_PER_SCR_EMAC1 0xffd21030
-#define S10_NOC_PER_SCR_EMAC2 0xffd21034
-#define S10_NOC_PER_SCR_SDMMC 0xffd21040
-#define S10_NOC_PER_SCR_GPIO0 0xffd21044
-#define S10_NOC_PER_SCR_GPIO1 0xffd21048
-#define S10_NOC_PER_SCR_I2C0 0xffd21050
-#define S10_NOC_PER_SCR_I2C1 0xffd21058
-#define S10_NOC_PER_SCR_I2C2 0xffd2105c
-#define S10_NOC_PER_SCR_I2C3 0xffd21060
-#define S10_NOC_PER_SCR_SP_TIMER0 0xffd21064
-#define S10_NOC_PER_SCR_SP_TIMER1 0xffd21068
-#define S10_NOC_PER_SCR_UART0 0xffd2106c
-#define S10_NOC_PER_SCR_UART1 0xffd21070
-
-
-#define S10_NOC_SYS_SCR_DMA_ECC 0xffd21108
-#define S10_NOC_SYS_SCR_EMAC0RX_ECC 0xffd2110c
-#define S10_NOC_SYS_SCR_EMAC0TX_ECC 0xffd21110
-#define S10_NOC_SYS_SCR_EMAC1RX_ECC 0xffd21114
-#define S10_NOC_SYS_SCR_EMAC1TX_ECC 0xffd21118
-#define S10_NOC_SYS_SCR_EMAC2RX_ECC 0xffd2111c
-#define S10_NOC_SYS_SCR_EMAC2TX_ECC 0xffd21120
-#define S10_NOC_SYS_SCR_NAND_ECC 0xffd2112c
-#define S10_NOC_SYS_SCR_NAND_READ_ECC 0xffd21130
-#define S10_NOC_SYS_SCR_NAND_WRITE_ECC 0xffd21134
-#define S10_NOC_SYS_SCR_OCRAM_ECC 0xffd21138
-#define S10_NOC_SYS_SCR_SDMMC_ECC 0xffd21140
-#define S10_NOC_SYS_SCR_USB0_ECC 0xffd21144
-#define S10_NOC_SYS_SCR_USB1_ECC 0xffd21148
-#define S10_NOC_SYS_SCR_CLK_MGR 0xffd2114c
-#define S10_NOC_SYS_SCR_IO_MGR 0xffd21154
-#define S10_NOC_SYS_SCR_RST_MGR 0xffd21158
-#define S10_NOC_SYS_SCR_SYS_MGR 0xffd2115c
-#define S10_NOC_SYS_SCR_OSC0_TIMER 0xffd21160
-#define S10_NOC_SYS_SCR_OSC1_TIMER 0xffd21164
-#define S10_NOC_SYS_SCR_WATCHDOG0 0xffd21168
-#define S10_NOC_SYS_SCR_WATCHDOG1 0xffd2116c
-#define S10_NOC_SYS_SCR_WATCHDOG2 0xffd21170
-#define S10_NOC_SYS_SCR_WATCHDOG3 0xffd21174
-#define S10_NOC_SYS_SCR_DAP 0xffd21178
-#define S10_NOC_SYS_SCR_L4_NOC_PROBES 0xffd21190
-#define S10_NOC_SYS_SCR_L4_NOC_QOS 0xffd21194
-
-#define S10_CCU_NOC_BRIDGE_CPU0_RAM 0xf7004688
-#define S10_CCU_NOC_BRIDGE_IOM_RAM 0xf7004688
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index b84a567..516cc75 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,6 +18,9 @@
#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x1000000
/* Register Mapping */
+#define SOCFPGA_CCU_NOC_REG_BASE 0xf7000000
+#define SOCFPGA_F2SDRAMMGR_REG_BASE U(0xf8024000)
+
#define SOCFPGA_MMC_REG_BASE 0xff808000
#define SOCFPGA_RSTMGR_REG_BASE 0xffd11000
@@ -29,6 +31,10 @@
#define SOCFPGA_SOC2FPGA_SCR_REG_BASE 0xffd21200
#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE 0xffd21300
+/* Platform specific system counter */
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ get_cpu_clk()
+
+uint32_t get_cpu_clk(void);
#endif /* PLATSOCFPGA_DEF_H */
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index d9d88d4..5c0b421 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -26,7 +26,8 @@
lib/xlat_tables/xlat_tables_common.c \
plat/intel/soc/common/aarch64/platform_common.c \
plat/intel/soc/common/aarch64/plat_helpers.S \
- plat/intel/soc/common/socfpga_delay_timer.c
+ plat/intel/soc/common/socfpga_delay_timer.c \
+ plat/intel/soc/common/soc/socfpga_firewall.c
BL2_SOURCES += \
common/desc_image_load.c \
@@ -42,26 +43,32 @@
plat/intel/soc/stratix10/bl2_plat_setup.c \
plat/intel/soc/stratix10/soc/s10_clock_manager.c \
plat/intel/soc/stratix10/soc/s10_memory_controller.c \
+ plat/intel/soc/stratix10/soc/s10_mmc.c \
plat/intel/soc/stratix10/soc/s10_pinmux.c \
- plat/intel/soc/common/bl2_plat_mem_params_desc.c \
+ plat/intel/soc/common/bl2_plat_mem_params_desc.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 \
- plat/intel/soc/common/soc/socfpga_system_manager.c \
plat/intel/soc/common/drivers/qspi/cadence_qspi.c \
plat/intel/soc/common/drivers/wdt/watchdog.c
+include lib/zlib/zlib.mk
+PLAT_INCLUDES += -Ilib/zlib
+BL2_SOURCES += $(ZLIB_SOURCES)
+
BL31_SOURCES += \
drivers/arm/cci/cci.c \
lib/cpus/aarch64/aem_generic.S \
lib/cpus/aarch64/cortex_a53.S \
plat/common/plat_psci_common.c \
+ plat/intel/soc/stratix10/soc/s10_clock_manager.c \
plat/intel/soc/stratix10/bl31_plat_setup.c \
plat/intel/soc/common/socfpga_psci.c \
plat/intel/soc/common/socfpga_sip_svc.c \
+ plat/intel/soc/common/socfpga_sip_svc_v2.c \
plat/intel/soc/common/socfpga_topology.c \
plat/intel/soc/common/sip/socfpga_sip_ecc.c \
plat/intel/soc/common/sip/socfpga_sip_fcs.c \
diff --git a/plat/intel/soc/stratix10/soc/s10_clock_manager.c b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
index 1e092de..30009f7 100644
--- a/plat/intel/soc/stratix10/soc/s10_clock_manager.c
+++ b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -307,3 +307,16 @@
return mmc_clk;
}
+
+/* Get cpu freq clock */
+uint32_t get_cpu_clk(void)
+{
+ uint32_t data32, ref_clk, cpu_clk;
+
+ data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB);
+ ref_clk = get_ref_clk(data32);
+
+ cpu_clk = get_l3_clk(ref_clk)/PLAT_SYS_COUNTER_CONVERT_TO_MHZ;
+
+ return cpu_clk;
+}
diff --git a/plat/intel/soc/stratix10/soc/s10_mmc.c b/plat/intel/soc/stratix10/soc/s10_mmc.c
new file mode 100644
index 0000000..333bdd6
--- /dev/null
+++ b/plat/intel/soc/stratix10/soc/s10_mmc.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+
+#include "s10_clock_manager.h"
+#include "socfpga_system_manager.h"
+
+void s10_mmc_init(void)
+{
+ mmio_clrbits_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EN,
+ ALT_CLKMGR_PERPLL_EN_SDMMCCLK);
+ mmio_write_32(SOCFPGA_SYSMGR(SDMMC),
+ SYSMGR_SDMMC_SMPLSEL(2) | SYSMGR_SDMMC_DRVSEL(3));
+ mmio_setbits_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EN,
+ ALT_CLKMGR_PERPLL_EN_SDMMCCLK);
+}
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
index d0e8688..5547201 100644
--- a/plat/marvell/armada/a3k/common/a3700_common.mk
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -205,12 +205,12 @@
@$(ECHO_BLANK_LINE)
$(Q)cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin
$(Q)truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin
- $(Q)openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \
+ $(Q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \
-out $(BUILD_PLAT)/$(WTMI_ENC_IMG) \
-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
-iv `cat $(IMAGESPATH)/iv.txt` -p
$(Q)truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
- $(Q)openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
+ $(Q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
-out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \
-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
-iv `cat $(IMAGESPATH)/iv.txt` -p
diff --git a/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c b/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c
index 8d909dc..6c55858 100644
--- a/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c
+++ b/plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c
@@ -22,84 +22,84 @@
static bl_mem_params_node_t bl2_mem_params_descs[] = {
#ifdef SCP_BL2_BASE
/* Fill SCP_BL2 related information if it exists */
- {
- .image_id = SCP_BL2_IMAGE_ID,
+ {
+ .image_id = SCP_BL2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = SCP_BL2_BASE,
- .image_info.image_max_size = SCP_BL2_SIZE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = SCP_BL2_BASE,
+ .image_info.image_max_size = SCP_BL2_SIZE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
#endif /* SCP_BL2_BASE */
#ifdef EL3_PAYLOAD_BASE
/* Fill EL3 payload related information (BL31 is EL3 payload)*/
- {
- .image_id = BL31_IMAGE_ID,
+ {
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = EL3_PAYLOAD_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = EL3_PAYLOAD_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t,
- IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING),
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
#else /* EL3_PAYLOAD_BASE */
/* Fill BL31 related information */
- {
- .image_id = BL31_IMAGE_ID,
+ {
+ .image_id = BL31_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t,
- SECURE | EXECUTABLE | EP_FIRST_EXE),
- .ep_info.pc = BL31_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
- DISABLE_ALL_EXCEPTIONS),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
#if DEBUG
- .ep_info.args.arg3 = MARVELL_BL31_PLAT_PARAM_VAL,
+ .ep_info.args.arg3 = MARVELL_BL31_PLAT_PARAM_VAL,
#endif
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
- .image_info.image_base = BL31_BASE,
- .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = BL31_LIMIT - BL31_BASE,
# ifdef BL32_BASE
- .next_handoff_image_id = BL32_IMAGE_ID,
+ .next_handoff_image_id = BL32_IMAGE_ID,
# else
- .next_handoff_image_id = BL33_IMAGE_ID,
+ .next_handoff_image_id = BL33_IMAGE_ID,
# endif
- },
+ },
# ifdef BL32_BASE
/* Fill BL32 related information */
- {
- .image_id = BL32_IMAGE_ID,
+ {
+ .image_id = BL32_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
- .ep_info.pc = BL32_BASE,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
+ .ep_info.pc = BL32_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = BL33_IMAGE_ID,
- },
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
/*
* Fill BL32 external 1 related information.
@@ -107,17 +107,17 @@
* where it is the pager image.
*/
{
- .image_id = BL32_EXTRA1_IMAGE_ID,
+ .image_id = BL32_EXTRA1_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
- .image_info.image_base = BL32_BASE,
- .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
},
/*
@@ -126,42 +126,42 @@
* where it is the paged image.
*/
{
- .image_id = BL32_EXTRA2_IMAGE_ID,
+ .image_id = BL32_EXTRA2_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
#ifdef SPD_opteed
- .image_info.image_base = MARVELL_OPTEE_PAGEABLE_LOAD_BASE,
- .image_info.image_max_size = MARVELL_OPTEE_PAGEABLE_LOAD_SIZE,
+ .image_info.image_base = MARVELL_OPTEE_PAGEABLE_LOAD_BASE,
+ .image_info.image_max_size = MARVELL_OPTEE_PAGEABLE_LOAD_SIZE,
#endif
- .next_handoff_image_id = INVALID_IMAGE_ID,
+ .next_handoff_image_id = INVALID_IMAGE_ID,
},
# endif /* BL32_BASE */
/* Fill BL33 related information */
- {
- .image_id = BL33_IMAGE_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
- VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+ {
+ .image_id = BL33_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
# ifdef PRELOADED_BL33_BASE
- .ep_info.pc = PRELOADED_BL33_BASE,
+ .ep_info.pc = PRELOADED_BL33_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
# else
- .ep_info.pc = MARVELL_DRAM_BASE,
+ .ep_info.pc = MARVELL_DRAM_BASE,
- SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = MARVELL_DRAM_BASE,
- .image_info.image_max_size = MARVELL_DRAM_SIZE,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = MARVELL_DRAM_BASE,
+ .image_info.image_max_size = MARVELL_DRAM_SIZE,
# endif /* PRELOADED_BL33_BASE */
- .next_handoff_image_id = INVALID_IMAGE_ID,
- }
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
#endif /* EL3_PAYLOAD_BASE */
};
diff --git a/plat/mediatek/build_helpers/conditional_eval_options.mk b/plat/mediatek/build_helpers/conditional_eval_options.mk
new file mode 100644
index 0000000..6bb3b4e
--- /dev/null
+++ b/plat/mediatek/build_helpers/conditional_eval_options.mk
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Conditional makefile variable assignment
+
+# Options depend on BUILD_TYPE variable
+ifeq ($(BUILD_TYPE),release)
+MTK_DEBUGSYS_LOCK := 1
+MTK_GET_PERM_DIS := 1
+ERRATA_KLEIN_2218950 := 0
+ERRATA_KLEIN_2184257 := 0
+ERRATA_KLEIN_BOOKER := 0
+ERRATA_MTH_BOOKER := 0
+ERRATA_MTHELP_BOOKER := 0
+CRASH_REPORTING := 1
+CONFIG_MTK_BL31_RAMDUMP := 0
+endif
+
+ifeq ($(BUILD_TYPE),debug)
+MTK_PTP3_PROC_DEBUG := 1
+MTK_SRAMRC_DEBUG := 1
+MTK_IOMMU_DEBUG := 1
+MTK_DCM_DEBUG := 1
+MTK_EMI_MPU_DEBUG := 1
+endif
+
+ifeq (${SPD},none)
+SPD_NONE:=1
+$(eval $(call add_define,SPD_NONE))
+endif
+
+# TEE OS config
+ifeq ($(SPD), tbase)
+CONFIG_TBASE := y
+endif
+
+# MICROTRUST OS config
+ifeq ($(SPD), teeid)
+CONFIG_MICROTRUST_TEEI := y
+endif
+
+ifeq (${CONFIG_ARCH_ARM_V8_2},y)
+ARCH_VERSION := armv8_2
+endif
+
+ifeq (${CONFIG_ARCH_ARM_V9},y)
+ARCH_VERSION := armv9
+endif
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
new file mode 100644
index 0000000..fc3876e
--- /dev/null
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -0,0 +1,142 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Get local directory path
+define GET_LOCAL_DIR
+$(patsubst %/,%,$(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))))
+endef
+
+# Clear module source variable
+define CLEAR_LOCAL_SRCS
+$(eval $(1) :=)
+endef
+
+define EXPAND_SUB_MAKEFILE
+include $(S)
+endef
+
+# Expand sub rules.mk
+define INCLUDE_MAKEFILE
+$(eval MODULES_SUB_MAKEFILE := $(patsubst %,%/rules.mk,$(1)))
+$(foreach S,$(MODULES_SUB_MAKEFILE),$(eval $(EXPAND_SUB_MAKEFILE)))
+endef
+
+# Determine option variable is defined or not then define it
+define add_defined_option
+ifdef $(1)
+ifeq ($(findstring $(value $(1)), $(uppercase_table)),)
+DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
+else
+ifeq ($(strip $(value $(1))),y)
+DEFINES += -D$(1)$(if $(value $(1)),=1,)
+endif
+endif
+endif
+endef
+
+define EXPAND_RULES_MAKEFILE
+LOCAL_SRCS-y :=
+MODULE :=
+SUB_RULES-y :=
+include $(S)
+endef
+
+# INCLUDE_MODULES macro expand included modules rules.mk
+# Arguments:
+# $(1) = MODULES variables
+define INCLUDE_MODULES
+$(eval MODULES_TEMP := $(1))
+$(eval MODULES_MAKEFILE := $(patsubst %,%/rules.mk,$(MODULES_TEMP)))
+$(foreach S,$(MODULES_MAKEFILE),$(eval $(EXPAND_RULES_MAKEFILE)))
+endef
+
+# MAKE_LOCALS expand module source file variable to BL${BL}_SOURCES
+# Arguments:
+# $(1) = source file
+# $(2) = BL stage (1, 2, 2u, 31, 32)
+define MAKE_LOCALS
+$(eval $(call uppercase,$(2))_SOURCES += $(1))
+endef
+
+# MAKE_LINKERFILE change linker script source file name to
+# target linker script
+# $(1) = linker script source file
+# $(2) = BL stage
+define MAKE_LINKERFILE
+$(eval EXTRA_GENERATED_LINKER_SCRIPT += $(BUILD_PLAT)/$(2)/$(patsubst %.ld.S,%.ld,$(notdir $(1))))
+endef
+
+# MAKE_LINKERFILE_ITER call MAKE_LINKERFILE iteratively
+# $(1) = linker script source file
+# $(2) = BL stage
+define MAKE_LINKERFILE_ITER
+$(eval $(foreach link_src,$(1),$(call MAKE_LINKERFILE,$(link_src),$(2))))
+endef
+
+# MAKE_LD_ITER generate the linker scripts using the C preprocessor iteratively
+# $(1) = output linker script
+# $(2) = input template
+# $(3) = BL stage (1, 2, 2u, 31, 32)
+define MAKE_LD_ITER
+$(eval index_list=$(shell seq $(words $(1))))
+$(eval $(foreach i, $(index_list), \
+$(call MAKE_LD,$(word $(i), $(1)), $(word $(i), $(2)),$(3))))
+endef
+
+# MAKE_MODULE reference MAKE_OBJS.
+# Create module folder under out/bl$(BL)/$(module)
+# Arguments:
+# $(1) = module name
+# $(2) = source file
+# $(3) = BL stage
+define MAKE_MODULE
+ $(eval MODULE := $(strip $(1)))
+ $(eval BUILD_DIR := ${BUILD_PLAT}/${3})
+ $(eval SOURCES := $(2))
+ $(eval OBJS_TEMP := $(addprefix $(BUILD_DIR)/$(MODULE)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
+ $(eval MODULE_OBJS += $(OBJS_TEMP))
+ # We use sort only to get a list of unique object directory names.
+ # ordering is not relevant but sort removes duplicates.
+ $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS_TEMP} ${LINKERFILE})))
+ # The $(dir ) function leaves a trailing / on the directory names
+ # Rip off the / to match directory names with make rule targets.
+ $(eval OBJ_DIRS := $(patsubst %/,%,$(TEMP_OBJ_DIRS)))
+
+$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
+${3}_dirs: | ${OBJ_DIRS}
+
+$(eval $(call MAKE_OBJS,$(BUILD_DIR)/$(MODULE),$(SOURCES),${3}))
+
+libraries: $(OBJS_TEMP)
+endef
+
+# Include MTK configuration files
+
+# MTK makefile variables
+ifeq (${COREBOOT},1)
+MTK_COMMON_CFG := $(MTK_PLAT)/common/coreboot_config.mk
+else
+MTK_COMMON_CFG := $(MTK_PLAT)/common/common_config.mk
+endif
+MTK_PLAT := plat/mediatek
+MTK_PLAT_SOC := ${MTK_PLAT}/${MTK_SOC}
+MTK_PLAT_CFG := $(MTK_PLAT_SOC)/plat_config.mk
+MTK_PROJECT_CFG := $(MTK_PLAT)/project/$(PLAT)/project_config.mk
+MTK_OPTIONS := $(MTK_PLAT)/build_helpers/options.mk
+MTK_COND_EVAL := $(MTK_PLAT)/build_helpers/conditional_eval_options.mk
+
+# Indicate which BL should be built in command line
+ifeq (${NEED_BL32},yes)
+MTK_BL := bl32
+else
+MTK_BL := bl31
+endif
+# Include common, platform, board level config
+include $(MTK_COMMON_CFG)
+include $(MTK_PLAT_CFG)
+-include $(MTK_PROJECT_CFG)
+include $(MTK_COND_EVAL)
+include $(MTK_OPTIONS)
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
new file mode 100644
index 0000000..22a546c
--- /dev/null
+++ b/plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Expand include modules
+$(eval $(call INCLUDE_MODULES,$(MODULES-y)))
+
+# Make next section align to page size
+ifneq ($(MTK_EXTRA_LINKERFILE),)
+$(eval $(call MAKE_LINKERFILE_ITER,$(MTK_LINKERFILE_SOURCE),bl31))
+
+# EXTRA_GENERATED_LINKER_SCRIPT is a global variable of derived linker
+# script list(from MTK_LINKERFILE_SOURCE) after MAKE_LINKERFILE_ITER
+# function call
+EXTRA_LINKERFILE += ${EXTRA_GENERATED_LINKER_SCRIPT}
+
+# Expand derived linker script as build target
+$(eval $(call MAKE_LD_ITER, $(EXTRA_GENERATED_LINKER_SCRIPT),$(MTK_LINKERFILE_SOURCE),bl31))
+
+# mtk_align.ld MUST BE THE LAST LINKER SCRIPT!
+EXTRA_LINKERFILE += ${MTK_PLAT}/include/mtk_align.ld
+
+# bl31.ld should depend on EXTRA_LINKERFILE
+$(eval ${BUILD_PLAT}/bl31/bl31.ld: ${EXTRA_LINKERFILE})
+EXTRA_LINKERFILE := $(addprefix -T,$(EXTRA_LINKERFILE))
+else
+EXTRA_LINKERFILE :=
+endif
diff --git a/plat/mediatek/build_helpers/options.mk b/plat/mediatek/build_helpers/options.mk
new file mode 100644
index 0000000..eb579e5
--- /dev/null
+++ b/plat/mediatek/build_helpers/options.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# call add_defined_option to evaluate MTK defined value
+$(eval $(call add_defined_option,MTK_SIP_KERNEL_BOOT_ENABLE))
+$(eval $(call add_defined_option,PLAT_EXTRA_RODATA_INCLUDES))
+$(eval $(call add_defined_option,MTK_EXTRA_LINKERFILE))
+$(eval $(call add_defined_option,MTK_BL31_AS_BL2))
+$(eval $(call add_defined_option,MTK_BL33_IS_64BIT))
+$(eval $(call add_defined_option,PLAT_XLAT_TABLES_DYNAMIC))
+$(eval $(call add_defined_option,MTK_ADAPTED))
+$(eval $(call add_defined_option,MTK_SOC))
+$(eval $(call add_defined_option,UART_CLOCK))
+$(eval $(call add_defined_option,UART_BAUDRATE))
diff --git a/plat/mediatek/common/cold_boot.c b/plat/mediatek/common/cold_boot.c
new file mode 100644
index 0000000..ff585fe
--- /dev/null
+++ b/plat/mediatek/common/cold_boot.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/el3_runtime/context_mgmt.h>
+
+/* Vendors headers */
+#include <cold_boot.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <mtk_sip_svc.h>
+
+static struct kernel_info k_info;
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+static bool el1_is_2nd_bootloader = true;
+static struct atf_arg_t atfarg;
+
+static int init_mtk_bl32_arg(void)
+{
+ struct mtk_bl_param_t *p_mtk_bl_param;
+ struct atf_arg_t *p_atfarg;
+
+ p_mtk_bl_param = (struct mtk_bl_param_t *) get_mtk_bl31_fw_config(BOOT_ARG_FROM_BL2);
+ if (p_mtk_bl_param == NULL) {
+ ERROR("p_mtk_bl_param is NULL!\n");
+ return -1;
+ }
+ p_atfarg = (struct atf_arg_t *)p_mtk_bl_param->atf_arg_addr;
+ if (p_atfarg == NULL) {
+ ERROR("bl32 argument is NULL!\n");
+ return -1;
+ }
+ memcpy((void *)&atfarg, (void *)p_atfarg, sizeof(struct atf_arg_t));
+ return 0;
+}
+MTK_EARLY_PLAT_INIT(init_mtk_bl32_arg);
+
+static void save_kernel_info(uint64_t pc, uint64_t r0, uint64_t r1, uint64_t k32_64)
+{
+ k_info.k32_64 = k32_64;
+ k_info.pc = pc;
+
+ if (k32_64 == LINUX_KERNEL_32) {
+ /* for 32 bits kernel */
+ k_info.r0 = 0;
+ /* machtype */
+ k_info.r1 = r0;
+ /* tags */
+ k_info.r2 = r1;
+ } else {
+ /* for 64 bits kernel */
+ k_info.r0 = r0;
+ k_info.r1 = r1;
+ }
+}
+
+static uint32_t plat_get_spsr_for_bl32_64_entry(void)
+{
+ return SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+}
+
+#if MTK_BL33_IS_64BIT
+static uint32_t plat_get_spsr_for_bl33_entry(void)
+{
+ uint32_t spsr;
+ uint32_t mode;
+
+ mode = MODE_EL1;
+ spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+#else
+static uint32_t plat_get_spsr_for_bl33_entry(void)
+{
+ unsigned int mode;
+ uint32_t spsr;
+ unsigned int ee;
+ unsigned long daif;
+
+ INFO("Secondary bootloader is AArch32\n");
+ mode = MODE32_svc;
+ ee = 0;
+ /*
+ * TODO: Choose async. exception bits if HYP mode is not
+ * implemented according to the values of SCR.{AW, FW} bits
+ */
+ daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT;
+
+ spsr = SPSR_MODE32(mode, 0, ee, daif);
+ return spsr;
+}
+#endif
+
+static void populate_bl32_image_ep(entry_point_info_t *bl32_ep_instance,
+ struct mtk_bl_param_t *p_mtk_bl_param)
+{
+ entry_point_info_t *populated_ep_bl32 = bl32_ep_instance;
+
+ if (p_mtk_bl_param == NULL) {
+ ERROR("p_mtk_bl_param is NULL!\n");
+ panic();
+ }
+ SET_SECURITY_STATE(bl32_ep_instance->h.attr, SECURE);
+ SET_PARAM_HEAD(populated_ep_bl32,
+ PARAM_EP,
+ VERSION_1,
+ populated_ep_bl32->h.attr);
+ populated_ep_bl32->pc = atfarg.tee_entry;
+ populated_ep_bl32->spsr = plat_get_spsr_for_bl32_64_entry();
+}
+
+static void populate_bl33_image_ep(entry_point_info_t *bl33_ep_instance,
+ struct mtk_bl_param_t *p_mtk_bl_param)
+{
+ entry_point_info_t *populated_ep_bl33 = bl33_ep_instance;
+
+ if (p_mtk_bl_param == NULL) {
+ ERROR("p_mtk_bl_param is NULL!\n");
+ panic();
+ }
+ SET_SECURITY_STATE(bl33_ep_instance->h.attr, NON_SECURE);
+ SET_PARAM_HEAD(populated_ep_bl33,
+ PARAM_EP,
+ VERSION_1,
+ populated_ep_bl33->h.attr);
+ populated_ep_bl33->pc = p_mtk_bl_param->bl33_start_addr;
+ /* standardize 2nd bootloader input argument */
+ populated_ep_bl33->args.arg0 = p_mtk_bl_param->bootarg_loc;
+ /* compatible to old GZ version */
+ populated_ep_bl33->args.arg4 = p_mtk_bl_param->bootarg_loc;
+ populated_ep_bl33->args.arg5 = p_mtk_bl_param->bootarg_size;
+ populated_ep_bl33->spsr = plat_get_spsr_for_bl33_entry();
+}
+
+static int populate_bl_images_ep(struct mtk_bl_param_t *p_mtk_bl_param)
+{
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+ populate_bl33_image_ep(&bl33_image_ep_info, p_mtk_bl_param);
+ populate_bl32_image_ep(&bl32_image_ep_info, p_mtk_bl_param);
+ return 0;
+}
+
+static int populate_bl_images_ep_init(void)
+{
+ return populate_bl_images_ep(get_mtk_bl31_fw_config(BOOT_ARG_FROM_BL2));
+}
+MTK_PLAT_SETUP_0_INIT(populate_bl_images_ep_init);
+
+static entry_point_info_t *bl31_plat_get_next_kernel64_ep_info(void)
+{
+ entry_point_info_t *next_image_info;
+ unsigned long el_status;
+ unsigned int mode;
+
+ el_status = 0;
+ mode = 0;
+
+ /* Kernel image is always non-secured */
+ next_image_info = &bl33_image_ep_info;
+
+ /* Figure out what mode we enter the non-secure world in */
+ el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+ el_status &= ID_AA64PFR0_ELX_MASK;
+
+ INFO("Kernel_EL %d\n", el_status?2:1);
+ if (el_status) {
+ mode = MODE_EL2;
+ } else {
+ mode = MODE_EL1;
+ }
+ INFO("Kernel is 64Bit\n");
+ next_image_info->spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ next_image_info->pc = k_info.pc;
+ next_image_info->args.arg0 = k_info.r0;
+ next_image_info->args.arg1 = k_info.r1;
+
+ INFO("pc=0x%lx, r0=0x%" PRIx64 ", r1=0x%" PRIx64 "\n",
+ next_image_info->pc,
+ next_image_info->args.arg0,
+ next_image_info->args.arg1);
+
+ SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
+
+ /* None of the images on this platform can have 0x0 as the entrypoint */
+ if (next_image_info->pc) {
+ return next_image_info;
+ }
+
+ return NULL;
+}
+
+static entry_point_info_t *bl31_plat_get_next_kernel32_ep_info(void)
+{
+ entry_point_info_t *next_image_info;
+ unsigned int mode;
+
+ mode = 0;
+
+ /* Kernel image is always non-secured */
+ next_image_info = &bl33_image_ep_info;
+
+ /* Figure out what mode we enter the non-secure world in */
+ mode = MODE32_hyp;
+ /*
+ * TODO: Consider the possibility of specifying the SPSR in
+ * the FIP ToC and allowing the platform to have a say as
+ * well.
+ */
+
+ INFO("Kernel is 32Bit\n");
+ next_image_info->spsr = SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE,
+ (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT));
+ next_image_info->pc = k_info.pc;
+ next_image_info->args.arg0 = k_info.r0;
+ next_image_info->args.arg1 = k_info.r1;
+ next_image_info->args.arg2 = k_info.r2;
+
+ INFO("pc=0x%lx, r0=0x%" PRIx64 ", r1=0x%" PRIx64 ", r2=0x%" PRIx64 "\n",
+ next_image_info->pc,
+ next_image_info->args.arg0,
+ next_image_info->args.arg1,
+ next_image_info->args.arg2);
+
+ SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
+
+ /* None of the images on this platform can have 0x0 as the entrypoint */
+ if (next_image_info->pc) {
+ return next_image_info;
+ }
+
+ return NULL;
+}
+
+static void bl31_prepare_kernel_entry(uint64_t k32_64)
+{
+ entry_point_info_t *next_image_info = NULL;
+ uint32_t image_type;
+
+ /* Determine which image to execute next */
+ image_type = NON_SECURE; /* bl31_get_next_image_type(); */
+
+ /* Leave 2nd bootloader then jump to kernel */
+ el1_is_2nd_bootloader = false;
+
+ /* Program EL3 registers to enable entry into the next EL */
+ if (k32_64 == LINUX_KERNEL_32) {
+ next_image_info = bl31_plat_get_next_kernel32_ep_info();
+ } else {
+ next_image_info = bl31_plat_get_next_kernel64_ep_info();
+ }
+
+ assert(next_image_info);
+ assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr));
+
+ INFO("BL31: Preparing for EL3 exit to %s world, Kernel\n",
+ (image_type == SECURE) ? "secure" : "normal");
+ INFO("BL31: Next image address = 0x%" PRIx64 "\n",
+ next_image_info->pc);
+ INFO("BL31: Next image spsr = 0x%x\n", next_image_info->spsr);
+ cm_init_my_context(next_image_info);
+ cm_prepare_el3_exit(image_type);
+}
+
+bool is_el1_2nd_bootloader(void)
+{
+ return el1_is_2nd_bootloader;
+}
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+
+ next_image_info = (type == NON_SECURE) ? &bl33_image_ep_info : &bl32_image_ep_info;
+
+ /* None of the images on this platform can have 0x0 as the entrypoint */
+ if (next_image_info->pc) {
+ return next_image_info;
+ }
+ return NULL;
+}
+
+u_register_t boot_to_kernel(u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *handle,
+ struct smccc_res *smccc_ret)
+{
+ static uint8_t kernel_boot_once_flag;
+
+ /* only support in booting flow */
+ if (kernel_boot_once_flag == 0) {
+ kernel_boot_once_flag = 1;
+
+ INFO("save kernel info\n");
+ save_kernel_info(x1, x2, x3, x4);
+ bl31_prepare_kernel_entry(x4);
+ INFO("el3_exit\n");
+ /*
+ * FIXME: no better way so far to prevent from
+ * SiP root handler wipe x0~x3 if not assign smccc_ret
+ * return register
+ */
+ smccc_ret->a1 = x3;
+
+ mtk_init_one_level(MTK_INIT_LVL_BL33_DEFER);
+
+#if MTK_CONSOLE_RUNTIME_DISABLE
+ INFO("Turn off BL31 console\n");
+ mtk_console_core_end();
+#endif
+
+ /* Re-assign as x0 register entering Linux kernel */
+ return x2;
+ }
+ return 0;
+}
+/* Register SiP SMC service */
+DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_BOOT, boot_to_kernel);
diff --git a/plat/mediatek/common/common_config.mk b/plat/mediatek/common/common_config.mk
new file mode 100644
index 0000000..851eb2c
--- /dev/null
+++ b/plat/mediatek/common/common_config.mk
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# indicate the reset vector address can be programmed
+PROGRAMMABLE_RESET_ADDRESS := 1
+MULTI_CONSOLE_API := 1
+COLD_BOOT_SINGLE_CPU := 1
+# Build flag to include AArch32 registers in cpu context save and restore during
+# world switch. This flag must be set to 0 for AArch64-only platforms.
+CTX_INCLUDE_AARCH32_REGS := 0
+PLAT_XLAT_TABLES_DYNAMIC := 1
+# enable this definition to print irq dump status in tf-a
+GIC_DEBUG := 0
+# Enable stack protector.
+# Allowed values are "all", "strong", "default" and "none"
+ENABLE_STACK_PROTECTOR := strong
+# AMU, Kernel will access amuserenr_el0 if PE supported
+# Firmware _must_ implement AMU support
+ENABLE_AMU := 1
+VENDOR_EXTEND_PUBEVENT_ENABLE := 1
+
+# MTK define options
+MTK_BL33_IS_64BIT := 0
+MTK_ADAPTED := 1
+
+# MTK module config
+CONFIG_MTK_INTERRUPT := y
+CONFIG_MTK_UART := y
+
+# UART baudrate
+UART_BAUDRATE := 921600
diff --git a/plat/mediatek/common/coreboot_config.mk b/plat/mediatek/common/coreboot_config.mk
new file mode 100644
index 0000000..59d18e8
--- /dev/null
+++ b/plat/mediatek/common/coreboot_config.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# indicate the reset vector address can be programmed
+PROGRAMMABLE_RESET_ADDRESS := 1
+COLD_BOOT_SINGLE_CPU := 1
+# Build flag to include AArch32 registers in cpu context save and restore during
+# world switch. This flag must be set to 0 for AArch64-only platforms.
+CTX_INCLUDE_AARCH32_REGS := 0
+PLAT_XLAT_TABLES_DYNAMIC := 1
+
+VENDOR_EXTEND_PUBEVENT_ENABLE := 1
diff --git a/plat/mediatek/common/custom/oem_svc.c b/plat/mediatek/common/custom/oem_svc.c
deleted file mode 100644
index 27ee6aa..0000000
--- a/plat/mediatek/common/custom/oem_svc.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <stdint.h>
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <plat/common/platform.h>
-#include <tools_share/uuid.h>
-
-#include <oem_svc.h>
-
-/* OEM Service UUID */
-DEFINE_SVC_UUID2(oem_svc_uid,
- 0xd0ad43b9, 0x9b06, 0xe411, 0x91, 0x91,
- 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66);
-
-/* Setup OEM Services */
-static int32_t oem_svc_setup(void)
-{
- /*
- * Invoke related module setup from here
- */
-
- return 0;
-}
-
-/*******************************************************************************
- * OEM top level handler for servicing SMCs.
- ******************************************************************************/
-uintptr_t oem_smc_handler(uint32_t smc_fid,
- u_register_t x1,
- u_register_t x2,
- u_register_t x3,
- u_register_t x4,
- void *cookie,
- void *handle,
- u_register_t flags)
-{
- WARN("Unimplemented OEM Call: 0x%x\n", smc_fid);
- SMC_RET1(handle, SMC_UNK);
-}
-
-/*
- * Top-level OEM Service SMC handler. This handler will in turn dispatch
- * calls to related SMC handler
- */
-uintptr_t oem_svc_smc_handler(uint32_t smc_fid,
- u_register_t x1,
- u_register_t x2,
- u_register_t x3,
- u_register_t x4,
- void *cookie,
- void *handle,
- u_register_t flags)
-{
- /*
- * Dispatch OEM calls to OEM Common handler and return its return value
- */
- if (is_oem_fid(smc_fid)) {
- return oem_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
- handle, flags);
- }
-
- switch (smc_fid) {
- case OEM_SVC_CALL_COUNT:
- /*
- * Return the number of OEM Service Calls.
- */
- SMC_RET1(handle, OEM_SVC_NUM_CALLS);
-
- case OEM_SVC_UID:
- /* Return UID to the caller */
- SMC_UUID_RET(handle, oem_svc_uid);
-
- case OEM_SVC_VERSION:
- /* Return the version of current implementation */
- SMC_RET2(handle, OEM_VERSION_MAJOR, OEM_VERSION_MINOR);
-
- default:
- WARN("Unimplemented OEM Service Call: 0x%x\n", smc_fid);
- SMC_RET1(handle, SMC_UNK);
- }
-}
-
-/* Register OEM Service Calls as runtime service */
-DECLARE_RT_SVC(
- oem_svc,
- OEN_OEM_START,
- OEN_OEM_END,
- SMC_TYPE_FAST,
- oem_svc_setup,
- oem_svc_smc_handler
-);
diff --git a/plat/mediatek/common/custom/oem_svc.h b/plat/mediatek/common/custom/oem_svc.h
deleted file mode 100644
index 76f7c24..0000000
--- a/plat/mediatek/common/custom/oem_svc.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef OEM_SVC_H
-#define OEM_SVC_H
-
-/*******************************************************************************
- * Defines for runtime services func ids
- ******************************************************************************/
-/*
- * Number of OEM calls (above) implemented.
- */
-#define OEM_SVC_NUM_CALLS 3
-
-/*******************************************************************************
- * Defines for OEM Service queries
- ******************************************************************************/
-/* 0x83000000 - 0x8300FEFF is OEM service calls */
-#define OEM_SVC_CALL_COUNT 0x8300ff00
-#define OEM_SVC_UID 0x8300ff01
-/* 0x8300ff02 is reserved */
-#define OEM_SVC_VERSION 0x8300ff03
-/* 0x8300ff04 - 0x8300FFFF is reserved for future expansion */
-
-/* OEM Service Calls version numbers */
-#define OEM_VERSION_MAJOR 0x0
-#define OEM_VERSION_MINOR 0x1
-
-/* The macros below are used to identify OEM calls from the SMC function ID */
-/* SMC32 ID range from 0x83000000 to 0x83000FFF */
-/* SMC64 ID range from 0xC3000000 to 0xC3000FFF */
-#define OEM_FID_MASK 0xf000u
-#define OEM_FID_VALUE 0u
-#define is_oem_fid(_fid) \
- (((_fid) & OEM_FID_MASK) == OEM_FID_VALUE)
-
-#define OEM_SVC_E_SUCCESS 0
-#define OEM_SVC_E_NOT_SUPPORTED -1
-#define OEM_SVC_E_INVALID_PARAMS -2
-
-#endif /* OEM_SVC_H */
diff --git a/plat/mediatek/common/mtk_bl31_setup.c b/plat/mediatek/common/mtk_bl31_setup.c
new file mode 100644
index 0000000..79ab29d
--- /dev/null
+++ b/plat/mediatek/common/mtk_bl31_setup.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/generic_delay_timer.h>
+#if XLAT_TABLES_LIB_V2 && PLAT_XLAT_TABLES_DYNAMIC
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#endif
+#include <plat/common/platform.h>
+
+#if COREBOOT
+#include <common/desc_image_load.h>
+
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/coreboot.h>
+#include <plat_params.h>
+#endif
+
+/* MTK headers */
+#if MTK_SIP_KERNEL_BOOT_ENABLE
+#include <cold_boot.h>
+#endif
+#include <lib/mtk_init/mtk_init.h>
+#include <mtk_mmap_pool.h>
+
+IMPORT_SYM(uintptr_t, __RW_START__, RW_START);
+IMPORT_SYM(uintptr_t, __DATA_START__, DATA_START);
+
+#if COREBOOT
+static entry_point_info_t bl32_ep_info;
+static entry_point_info_t bl33_ep_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+
+ next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
+ assert(next_image_info->h.type == PARAM_EP);
+
+ /* None of the images on this platform can have 0x0 as the entrypoint */
+ if (next_image_info->pc) {
+ return next_image_info;
+ } else {
+ return NULL;
+ }
+}
+#else
+#ifndef MTK_BL31_AS_BL2
+static struct mtk_bl31_fw_config bl31_fw_config;
+#else
+struct mtk_bl31_fw_config bl31_fw_config;
+#endif
+/* In order to be accessed after MMU enable */
+static struct mtk_bl_param_t bl_param_clone;
+
+void *get_mtk_bl31_fw_config(int index)
+{
+ void *arg = NULL;
+
+ switch (index) {
+ case BOOT_ARG_FROM_BL2:
+ arg = bl31_fw_config.from_bl2;
+ break;
+ case BOOT_ARG_SOC_FW_CONFIG:
+ arg = bl31_fw_config.soc_fw_config;
+ break;
+ case BOOT_ARG_HW_CONFIG:
+ arg = bl31_fw_config.hw_config;
+ break;
+ case BOOT_ARG_RESERVED:
+ arg = bl31_fw_config.reserved;
+ break;
+ default:
+ WARN("Fail to get boot arg, index:%d", index);
+ break;
+ }
+ return arg;
+}
+#endif
+/*****************************************************************************
+ * Perform the very early platform specific architectural setup shared between
+ * ARM standard platforms. This only does basic initialization. Later
+ * architectural setup (bl31_arch_setup()) does not do anything platform
+ * specific.
+ ******************************************************************************/
+void bl31_early_platform_setup2(u_register_t from_bl2,
+ u_register_t soc_fw_config,
+ u_register_t hw_config, u_register_t plat_params_from_bl2)
+
+{
+#if COREBOOT
+ static console_t console;
+
+ params_early_setup(soc_fw_config);
+ if (coreboot_serial.type) {
+ console_16550_register(coreboot_serial.baseaddr,
+ coreboot_serial.input_hertz,
+ coreboot_serial.baud,
+ &console);
+ }
+ bl31_params_parse_helper(from_bl2, &bl32_ep_info, &bl33_ep_info);
+#else
+ struct mtk_bl_param_t *p_mtk_bl_param = (struct mtk_bl_param_t *)from_bl2;
+
+ if (p_mtk_bl_param == NULL) {
+ ERROR("from_bl2 should not be NULL\n");
+ panic();
+ }
+ memcpy(&bl_param_clone, p_mtk_bl_param, sizeof(struct mtk_bl_param_t));
+ bl31_fw_config.from_bl2 = (void *)&bl_param_clone;
+ bl31_fw_config.soc_fw_config = (void *)soc_fw_config;
+ bl31_fw_config.hw_config = (void *)hw_config;
+ bl31_fw_config.reserved = (void *)plat_params_from_bl2;
+#endif
+
+ INFO("MTK BL31 start\n");
+ /* Init delay function */
+ generic_delay_timer_init();
+ /* Initialize module initcall */
+ mtk_init_one_level(MTK_INIT_LVL_EARLY_PLAT);
+}
+
+void bl31_plat_arch_setup(void)
+{
+ const mmap_region_t bl_regions[] = {
+ MAP_BL_RO,
+ MAP_BL_RW,
+#if USE_COHERENT_MEM
+ MAP_BL_COHERENT_RAM,
+#endif
+ {0},
+ };
+
+ mtk_xlat_init(bl_regions);
+ /* Initialize module initcall */
+ mtk_init_one_level(MTK_INIT_LVL_ARCH);
+}
+
+/*****************************************************************************
+ * Perform any BL31 platform setup common to ARM standard platforms
+ ******************************************************************************/
+
+void bl31_platform_setup(void)
+{
+ mtk_init_one_level(MTK_INIT_LVL_PLAT_SETUP_0);
+ mtk_init_one_level(MTK_INIT_LVL_PLAT_SETUP_1);
+}
+
+/*******************************************************************************
+ * Operations before cold CPU leave BL31.
+ * Switch console to runtime state.
+ ******************************************************************************/
+void bl31_plat_runtime_setup(void)
+{
+ mtk_init_one_level(MTK_INIT_LVL_PLAT_RUNTIME);
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return SYS_COUNTER_FREQ_IN_HZ;
+}
diff --git a/plat/mediatek/common/mtk_plat_common.c b/plat/mediatek/common/mtk_plat_common.c
index 142b5c9..76f74a9 100644
--- a/plat/mediatek/common/mtk_plat_common.c
+++ b/plat/mediatek/common/mtk_plat_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,8 +19,6 @@
#include <mtk_sip_svc.h>
#include <plat_private.h>
-struct atf_arg_t gteearg;
-
void clean_top_32b_of_param(uint32_t smc_fid,
u_register_t *px1,
u_register_t *px2,
@@ -28,96 +26,13 @@
u_register_t *px4)
{
/* if parameters from SMC32. Clean top 32 bits */
- if (0 == (smc_fid & SMC_AARCH64_BIT)) {
+ if (GET_SMC_CC(smc_fid) == SMC_64) {
*px1 = *px1 & SMC32_PARAM_MASK;
*px2 = *px2 & SMC32_PARAM_MASK;
*px3 = *px3 & SMC32_PARAM_MASK;
*px4 = *px4 & SMC32_PARAM_MASK;
}
}
-
-#if MTK_SIP_KERNEL_BOOT_ENABLE
-static struct kernel_info k_info;
-
-static void save_kernel_info(uint64_t pc,
- uint64_t r0,
- uint64_t r1,
- uint64_t k32_64)
-{
- k_info.k32_64 = k32_64;
- k_info.pc = pc;
-
- if (LINUX_KERNEL_32 == k32_64) {
- /* for 32 bits kernel */
- k_info.r0 = 0;
- /* machtype */
- k_info.r1 = r0;
- /* tags */
- k_info.r2 = r1;
- } else {
- /* for 64 bits kernel */
- k_info.r0 = r0;
- k_info.r1 = r1;
- }
-}
-
-uint64_t get_kernel_info_pc(void)
-{
- return k_info.pc;
-}
-
-uint64_t get_kernel_info_r0(void)
-{
- return k_info.r0;
-}
-
-uint64_t get_kernel_info_r1(void)
-{
- return k_info.r1;
-}
-
-uint64_t get_kernel_info_r2(void)
-{
- return k_info.r2;
-}
-
-void boot_to_kernel(uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4)
-{
- static uint8_t kernel_boot_once_flag;
- /* only support in booting flow */
- if (0 == kernel_boot_once_flag) {
- kernel_boot_once_flag = 1;
-
- console_init(gteearg.atf_log_port,
- UART_CLOCK, UART_BAUDRATE);
- INFO("save kernel info\n");
- save_kernel_info(x1, x2, x3, x4);
- bl31_prepare_kernel_entry(x4);
- INFO("el3_exit\n");
- console_uninit();
- }
-}
-#endif
-
-uint32_t plat_get_spsr_for_bl33_entry(void)
-{
- unsigned int mode;
- uint32_t spsr;
- unsigned int ee;
- unsigned long daif;
-
- INFO("Secondary bootloader is AArch32\n");
- mode = MODE32_svc;
- ee = 0;
- /*
- * TODO: Choose async. exception bits if HYP mode is not
- * implemented according to the values of SCR.{AW, FW} bits
- */
- daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT;
-
- spsr = SPSR_MODE32(mode, 0, ee, daif);
- return spsr;
-}
/*****************************************************************************
* plat_is_smccc_feature_available() - This function checks whether SMCCC
diff --git a/plat/mediatek/common/mtk_plat_common.h b/plat/mediatek/common/mtk_plat_common.h
index 919c173..4c14b9d 100644
--- a/plat/mediatek/common/mtk_plat_common.h
+++ b/plat/mediatek/common/mtk_plat_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,45 +14,11 @@
/*******************************************************************************
* Function and variable prototypes
******************************************************************************/
-#define DEVINFO_SIZE 4
-#define LINUX_KERNEL_32 0
#define SMC32_PARAM_MASK (0xFFFFFFFF)
#define JEDEC_MTK_BKID U(4)
#define JEDEC_MTK_MFID U(0x26)
-struct atf_arg_t {
- unsigned int atf_magic;
- unsigned int tee_support;
- unsigned int tee_entry;
- unsigned int tee_boot_arg_addr;
- unsigned int hwuid[4]; /* HW Unique id for t-base used */
- unsigned int HRID[2]; /* HW random id for t-base used */
- unsigned int atf_log_port;
- unsigned int atf_log_baudrate;
- unsigned int atf_log_buf_start;
- unsigned int atf_log_buf_size;
- unsigned int atf_irq_num;
- unsigned int devinfo[DEVINFO_SIZE];
- unsigned int atf_aee_debug_buf_start;
- unsigned int atf_aee_debug_buf_size;
-};
-
-struct kernel_info {
- uint64_t pc;
- uint64_t r0;
- uint64_t r1;
- uint64_t r2;
- uint64_t k32_64;
-};
-
-struct mtk_bl_param_t {
- uint64_t bootarg_loc;
- uint64_t bootarg_size;
- uint64_t bl33_start_addr;
- uint64_t tee_info_addr;
-};
-
struct mtk_bl31_params {
param_header_t h;
image_info_t *bl31_image_info;
diff --git a/plat/mediatek/common/mtk_sip_svc.h b/plat/mediatek/common/mtk_sip_svc.h
deleted file mode 100644
index 74b17b6..0000000
--- a/plat/mediatek/common/mtk_sip_svc.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef MTK_SIP_SVC_H
-#define MTK_SIP_SVC_H
-
-#include <stdint.h>
-
-/* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT 0x8200ff00
-#define SIP_SVC_UID 0x8200ff01
-/* 0x8200ff02 is reserved */
-#define SIP_SVC_VERSION 0x8200ff03
-
-/* Mediatek SiP Service Calls version numbers */
-#define MTK_SIP_SVC_VERSION_MAJOR 0x0
-#define MTK_SIP_SVC_VERSION_MINOR 0x1
-
-#define SMC_AARCH64_BIT 0x40000000
-
-/* Number of Mediatek SiP Calls implemented */
-#define MTK_COMMON_SIP_NUM_CALLS 4
-
-/* Mediatek SiP Service Calls function IDs */
-#define MTK_SIP_SET_AUTHORIZED_SECURE_REG 0x82000001
-
-/* For MTK SMC from Secure OS */
-/* 0x82000000 - 0x820000FF & 0xC2000000 - 0xC20000FF */
-#define MTK_SIP_KERNEL_BOOT_AARCH32 0x82000200
-#define MTK_SIP_KERNEL_BOOT_AARCH64 0xC2000200
-
-/* VCORE */
-#define MTK_SIP_VCORE_CONTROL_ARCH32 0x82000506
-#define MTK_SIP_VCORE_CONTROL_ARCH64 0xC2000506
-
-/* APUSYS SMC call */
-#define MTK_SIP_APUSYS_CONTROL_AARCH32 0x8200051E
-#define MTK_SIP_APUSYS_CONTROL_AARCH64 0xC200051E
-
-/* Mediatek SiP Calls error code */
-enum {
- MTK_SIP_E_SUCCESS = 0,
- MTK_SIP_E_INVALID_PARAM = -1,
- MTK_SIP_E_NOT_SUPPORTED = -2,
- MTK_SIP_E_INVALID_RANGE = -3,
- MTK_SIP_E_PERMISSION_DENY = -4,
- MTK_SIP_E_LOCK_FAIL = -5
-};
-
-/*
- * This function should be implemented in Mediatek SOC directory. It fullfills
- * MTK_SIP_SET_AUTHORIZED_SECURE_REG SiP call by checking the sreg with the
- * predefined secure register list, if a match was found, set val to sreg.
- *
- * Return MTK_SIP_E_SUCCESS on success, and MTK_SIP_E_INVALID_PARAM on failure.
- */
-uint64_t mt_sip_set_authorized_sreg(uint32_t sreg, uint32_t val);
-
-#endif /* MTK_SIP_SVC_H */
diff --git a/plat/mediatek/common/mtk_smc_handlers.c b/plat/mediatek/common/mtk_smc_handlers.c
new file mode 100644
index 0000000..24b978c
--- /dev/null
+++ b/plat/mediatek/common/mtk_smc_handlers.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <cold_boot.h>
+#include <lib/mtk_init/mtk_init.h>
+#include <mtk_sip_svc.h>
+
+#define SMC_HANDLER_DEBUG(...) VERBOSE(__VA_ARGS__)
+#define SMC_HANDLER_DEBUG_NOT_IMP_MSG "%s[0x%x] smc handler not implemented\n"
+#define SMC_HANDLER_DEBUG_START_MSG "%s[0x%x] smc handler start, smc desc. index:%d\n"
+#define SMC_HANDLER_DEBUG_END_MSG "%s[0x%x] smc handler end\n"
+
+/*
+ * These macros below are used to identify SIP calls from Kernel,
+ * Hypervisor, or 2ndBootloader
+ */
+#define SIP_FID_ORI_MASK (0xc000)
+#define SIP_FID_ORI_SHIFT (14)
+#define SIP_FID_KERNEL (0x0)
+#define SIP_FID_KERNEL_VIA_GZ (0x1)
+#define SIP_FID_GZ (0x2)
+
+#define GET_SMC_ORI(_fid) (((_fid) & SIP_FID_ORI_MASK) >> SIP_FID_ORI_SHIFT)
+#define GET_SMC_ORI_NUM(_fid) ((_fid) & ~(SIP_FID_ORI_MASK))
+
+#define is_from_nsel2(_ori) (_ori == SIP_FID_GZ)
+#define is_from_bl33(_ori) \
+ ((_ori != SIP_FID_GZ) && (is_el1_2nd_bootloader() == 1))
+#define is_from_nsel1(_ori) \
+ (((_ori == SIP_FID_KERNEL) || \
+ (_ori == SIP_FID_KERNEL_VIA_GZ)) && \
+ (is_el1_2nd_bootloader() == 0))
+
+#define is_smc_forbidden(_ori) (_ori == SIP_FID_KERNEL_VIA_GZ)
+
+#define MASK_32_BIT (0xffffffffU)
+#define SMC_ID_EXPAND_AS_SMC_OPERATION(_smc_id, _smc_num) \
+ case _smc_id##_AARCH32: \
+ { \
+ x1 = x1 & MASK_32_BIT; \
+ x2 = x2 & MASK_32_BIT; \
+ x3 = x3 & MASK_32_BIT; \
+ x4 = x4 & MASK_32_BIT; \
+ } \
+ case _smc_id##_AARCH64: \
+ { \
+ if (_smc_id##_descriptor_index < 0) { \
+ SMC_HANDLER_DEBUG(SMC_HANDLER_DEBUG_NOT_IMP_MSG, #_smc_id, smc_id); \
+ break; \
+ } \
+ if (_smc_id##_descriptor_index >= smc_id_descriptor_max) { \
+ SMC_HANDLER_DEBUG("smc descriptor index[%d] exceed max[%d]\n", \
+ _smc_id##_descriptor_index, smc_id_descriptor_max); \
+ break; \
+ } \
+ SMC_HANDLER_DEBUG(SMC_HANDLER_DEBUG_START_MSG, #_smc_id, smc_id, \
+ _smc_id##_descriptor_index); \
+ ret = smc_handler_pool[_smc_id##_descriptor_index].smc_handler(x1,\
+ x2, x3, x4, handle, &smc_ret); \
+ SMC_HANDLER_DEBUG(SMC_HANDLER_DEBUG_END_MSG, #_smc_id, smc_id); \
+ break; \
+ }
+
+#define SMC_ID_EXPAND_AS_DESCRIPTOR_INDEX(_smc_id, _smc_num) \
+ short _smc_id##_descriptor_index __section("mtk_plat_ro") = -1;
+
+MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_DESCRIPTOR_INDEX);
+MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_DESCRIPTOR_INDEX);
+
+IMPORT_SYM(uintptr_t, __MTK_SMC_POOL_START__, MTK_SMC_POOL_START);
+IMPORT_SYM(uintptr_t, __MTK_SMC_POOL_END_UNALIGNED__, MTK_SMC_POOL_END_UNALIGNED);
+
+static const struct smc_descriptor *smc_handler_pool;
+static short smc_id_descriptor_max;
+
+#if !MTK_SIP_KERNEL_BOOT_ENABLE
+/*
+ * If there is no SMC request needs to be served in 2nd bootloader,
+ * disable the service path inherently.
+ */
+bool is_el1_2nd_bootloader(void)
+{
+ return false;
+}
+#endif
+
+static void print_smc_descriptor(const struct smc_descriptor pool[])
+{
+ const struct smc_descriptor *p_smc_desc;
+
+ INFO("print smc descriptor pool\n");
+ for (p_smc_desc = &pool[0];
+ (char *)p_smc_desc < (char *)MTK_SMC_POOL_END_UNALIGNED;
+ p_smc_desc++) {
+ INFO("descriptor name:%s\n", p_smc_desc->smc_name);
+ INFO("descriptor index:%d\n", *p_smc_desc->smc_descriptor_index);
+ INFO("smc id 32:0x%x, smc id 64:0x%x\n",
+ p_smc_desc->smc_id_aarch32, p_smc_desc->smc_id_aarch64);
+ }
+}
+
+static int mtk_smc_handler_init(void)
+{
+ const struct smc_descriptor *iter;
+ short index_cnt;
+ int ret = 0;
+
+ smc_handler_pool = (const struct smc_descriptor *)MTK_SMC_POOL_START;
+ /* Designate descriptor index point to smc_handler_pool */
+ for (index_cnt = 0, iter = &smc_handler_pool[0];
+ (char *)iter < (char *)MTK_SMC_POOL_END_UNALIGNED;
+ iter++, index_cnt++) {
+ if (index_cnt < 0) {
+ SMC_HANDLER_DEBUG("smc handler pool index overflow!\n");
+ ret = -EPERM;
+ assert(0);
+ break;
+ }
+ *(iter->smc_descriptor_index) = index_cnt;
+ }
+ smc_id_descriptor_max = index_cnt;
+ print_smc_descriptor(smc_handler_pool);
+ return ret;
+}
+MTK_EARLY_PLAT_INIT(mtk_smc_handler_init);
+
+/* This function handles Mediatek defined SiP Calls from Bootloader */
+static uintptr_t mtk_smc_handler_bl33(uint32_t smc_id,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ uintptr_t ret = MTK_SIP_E_SUCCESS;
+ struct smccc_res smc_ret = {0};
+
+ switch (smc_id) {
+ MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_SMC_OPERATION);
+ default:
+ INFO("BL33 SMC ID:0x%x not supported\n", smc_id);
+ ret = SMC_UNK;
+ break;
+ }
+ SMC_RET4(handle, ret, smc_ret.a1, smc_ret.a2, smc_ret.a3);
+}
+
+/* This function handles Mediatek defined SiP Calls from Kernel */
+static uintptr_t mtk_smc_handler_nsel1(uint32_t smc_id,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ uintptr_t ret = MTK_SIP_E_SUCCESS;
+ struct smccc_res smc_ret = {0};
+
+ switch (smc_id) {
+ MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_SMC_OPERATION);
+ default:
+ INFO("NSEL1 SMC ID:0x%x not supported\n", smc_id);
+ ret = SMC_UNK;
+ break;
+ }
+ SMC_RET4(handle, ret, smc_ret.a1, smc_ret.a2, smc_ret.a3);
+}
+
+static uintptr_t mtk_smc_handler(uint32_t smc_id,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ uintptr_t ret = SMC_UNK;
+ uint32_t ns;
+ uint32_t smc_ori;
+ uint32_t smc_num;
+
+ /* Get SMC Originator bit 14.15 */
+ smc_ori = GET_SMC_ORI(smc_id);
+ /* Get SMC Number. Clean bit 14.15 */
+ smc_num = GET_SMC_ORI_NUM(smc_id);
+
+ /* Determine which security state this SMC originated from */
+ ns = is_caller_non_secure(flags);
+
+ if (ns && is_smc_forbidden(smc_ori)) {
+ ERROR("%s: Forbidden SMC call (0x%x)\n", __func__, smc_id);
+ SMC_RET1(handle, ret);
+ }
+
+ if (!ns) {
+ /* SiP SMC service secure world's call */
+ INFO("Secure SMC ID:0x%x not supported\n", smc_id);
+ SMC_RET1(handle, ret);
+ }
+ if (is_from_bl33(smc_ori)) {
+ /* SiP SMC service secure bootloader's call */
+ return mtk_smc_handler_bl33(smc_num, x1, x2, x3, x4,
+ cookie, handle, flags);
+ } else if (is_from_nsel1(smc_ori)) {
+ /* SiP SMC service kernel's call */
+ return mtk_smc_handler_nsel1(smc_num, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+ INFO("SMC ID:0x%x not supported\n", smc_id);
+ SMC_RET1(handle, ret);
+}
+
+/* Define a runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+ mtk_smc_handler,
+ OEN_SIP_START,
+ OEN_SIP_END,
+ SMC_TYPE_FAST,
+ NULL,
+ mtk_smc_handler
+);
diff --git a/plat/mediatek/common/rules.mk b/plat/mediatek/common/rules.mk
new file mode 100644
index 0000000..6acc731
--- /dev/null
+++ b/plat/mediatek/common/rules.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mtk_common
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_bl31_setup.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/mtk_smc_handlers.c
+LOCAL_SRCS-$(MTK_SIP_KERNEL_BOOT_ENABLE) += ${LOCAL_DIR}/cold_boot.c
+
+$(eval $(call MAKE_LOCALS,$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/common/mtk_cirq.c b/plat/mediatek/drivers/cirq/mt_cirq.c
similarity index 98%
rename from plat/mediatek/common/mtk_cirq.c
rename to plat/mediatek/drivers/cirq/mt_cirq.c
index 9cf7144..60534a2 100644
--- a/plat/mediatek/common/mtk_cirq.c
+++ b/plat/mediatek/drivers/cirq/mt_cirq.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,8 +9,8 @@
#include <drivers/arm/gic_common.h>
#include <lib/mmio.h>
+#include <mt_cirq.h>
#include <mt_gic_v3.h>
-#include <mtk_cirq.h>
static struct cirq_events cirq_all_events = {
.spi_start = CIRQ_SPI_START,
diff --git a/plat/mediatek/common/mtk_cirq.h b/plat/mediatek/drivers/cirq/mt_cirq.h
similarity index 97%
rename from plat/mediatek/common/mtk_cirq.h
rename to plat/mediatek/drivers/cirq/mt_cirq.h
index 6e63bb8..cb96295 100644
--- a/plat/mediatek/common/mtk_cirq.h
+++ b/plat/mediatek/drivers/cirq/mt_cirq.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/drivers/cirq/rules.mk b/plat/mediatek/drivers/cirq/rules.mk
new file mode 100644
index 0000000..710eae0
--- /dev/null
+++ b/plat/mediatek/drivers/cirq/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := cirq
+LOCAL_SRCS-y := $(LOCAL_DIR)/mt_cirq.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/mt8195/drivers/dp/mt_dp.c b/plat/mediatek/drivers/dp/mt_dp.c
similarity index 76%
rename from plat/mediatek/mt8195/drivers/dp/mt_dp.c
rename to plat/mediatek/drivers/dp/mt_dp.c
index 5930cd5..8aa246f 100644
--- a/plat/mediatek/mt8195/drivers/dp/mt_dp.c
+++ b/plat/mediatek/drivers/dp/mt_dp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,7 +15,7 @@
static uint32_t dp_write_sec_reg(uint32_t is_edp, uint32_t offset,
uint32_t value, uint32_t mask)
{
- uint32_t reg = (is_edp != 0U) ? eDP_SEC_BASE : DP_SEC_BASE;
+ uint32_t reg = (is_edp != 0U) ? EDP_SEC_BASE : DP_SEC_BASE;
mmio_clrsetbits_32(reg + offset, mask, value);
@@ -53,7 +53,7 @@
if (ret == MTK_SIP_E_SUCCESS) {
regmsk = (VIDEO_MUTE_SEL_SECURE_FLDMASK |
- VIDEO_MUTE_SW_SECURE_FLDMASK);
+ VIDEO_MUTE_SW_SECURE_FLDMASK);
if (para > 0U) {
fldmask = VIDEO_MUTE_SW_SECURE_FLDMASK;
} else {
@@ -67,3 +67,13 @@
return ret;
}
+
+u_register_t mtk_dp_sip_handler(u_register_t x1, u_register_t x2,
+ u_register_t x3, u_register_t x4,
+ void *handle, struct smccc_res *smccc_ret)
+{
+ uint32_t ret_val;
+
+ return dp_secure_handler(x1, x2, &ret_val);
+}
+DECLARE_SMC_HANDLER(MTK_SIP_DP_CONTROL, mtk_dp_sip_handler);
diff --git a/plat/mediatek/mt8195/drivers/dp/mt_dp.h b/plat/mediatek/drivers/dp/mt_dp.h
similarity index 87%
rename from plat/mediatek/mt8195/drivers/dp/mt_dp.h
rename to plat/mediatek/drivers/dp/mt_dp.h
index 8157598..d5dad29 100644
--- a/plat/mediatek/mt8195/drivers/dp/mt_dp.h
+++ b/plat/mediatek/drivers/dp/mt_dp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/drivers/dp/rules.mk b/plat/mediatek/drivers/dp/rules.mk
new file mode 100644
index 0000000..786d514
--- /dev/null
+++ b/plat/mediatek/drivers/dp/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := dp
+LOCAL_SRCS-y := $(LOCAL_DIR)/mt_dp.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/common/drivers/gic600/mt_gic_v3.c b/plat/mediatek/drivers/gic600/mt_gic_v3.c
similarity index 93%
rename from plat/mediatek/common/drivers/gic600/mt_gic_v3.c
rename to plat/mediatek/drivers/gic600/mt_gic_v3.c
index ae8d697..cca5d0a 100644
--- a/plat/mediatek/common/drivers/gic600/mt_gic_v3.c
+++ b/plat/mediatek/drivers/gic600/mt_gic_v3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +12,7 @@
#include <bl31/interrupt_mgmt.h>
#include <common/bl_common.h>
#include <common/debug.h>
-
+#include <lib/mtk_init/mtk_init.h>
#include <mt_gic_v3.h>
#include <mtk_plat_common.h>
#include <plat/common/platform.h>
@@ -194,3 +194,15 @@
mmio_write_32(BASE_GICD_BASE + GICD_ISPENDR +
irq / 32 * 4, bit);
}
+
+int mt_gic_one_init(void)
+{
+ INFO("[%s] GIC initialization\n", __func__);
+
+ /* Initialize the GIC driver, CPU and distributor interfaces */
+ mt_gic_driver_init();
+ mt_gic_init();
+
+ return 0;
+}
+MTK_PLAT_SETUP_0_INIT(mt_gic_one_init);
diff --git a/plat/mediatek/common/drivers/gic600/mt_gic_v3.h b/plat/mediatek/drivers/gic600/mt_gic_v3.h
similarity index 87%
rename from plat/mediatek/common/drivers/gic600/mt_gic_v3.h
rename to plat/mediatek/drivers/gic600/mt_gic_v3.h
index c4ab44f..31513ef 100644
--- a/plat/mediatek/common/drivers/gic600/mt_gic_v3.h
+++ b/plat/mediatek/drivers/gic600/mt_gic_v3.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,5 +23,6 @@
void gic_sgi_restore_all(void);
uint32_t mt_irq_get_pending(uint32_t irq);
void mt_irq_set_pending(uint32_t irq);
+int mt_gic_one_init(void);
#endif /* MT_GIC_V3_H */
diff --git a/plat/mediatek/drivers/gic600/rules.mk b/plat/mediatek/drivers/gic600/rules.mk
new file mode 100644
index 0000000..3070591
--- /dev/null
+++ b/plat/mediatek/drivers/gic600/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := gic600
+LOCAL_SRCS-y := $(LOCAL_DIR)/mt_gic_v3.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/gpio/mt8188/mtgpio.c b/plat/mediatek/drivers/gpio/mt8188/mtgpio.c
new file mode 100644
index 0000000..9e9fc5d
--- /dev/null
+++ b/plat/mediatek/drivers/gpio/mt8188/mtgpio.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <mtgpio.h>
+#include <platform_def.h>
+
+uintptr_t mt_gpio_find_reg_addr(uint32_t pin)
+{
+ uintptr_t reg_addr = 0U;
+ struct mt_pin_info gpio_info;
+
+ assert(pin < MAX_GPIO_PIN);
+
+ gpio_info = mt_pin_infos[pin];
+
+ switch (gpio_info.base & 0x0f) {
+ case 0:
+ reg_addr = IOCFG_RM_BASE;
+ break;
+ case 1:
+ reg_addr = IOCFG_LT_BASE;
+ break;
+ case 2:
+ reg_addr = IOCFG_LM_BASE;
+ break;
+ case 3:
+ reg_addr = IOCFG_RT_BASE;
+ break;
+ default:
+ break;
+ }
+
+ return reg_addr;
+}
diff --git a/plat/mediatek/drivers/gpio/mt8188/mtgpio.h b/plat/mediatek/drivers/gpio/mt8188/mtgpio.h
new file mode 100644
index 0000000..32a4608
--- /dev/null
+++ b/plat/mediatek/drivers/gpio/mt8188/mtgpio.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_GPIO_H
+#define MT_GPIO_H
+
+#include <mtgpio_common.h>
+
+/* Enumeration for GPIO pin */
+typedef enum GPIO_PIN {
+ GPIO_UNSUPPORTED = -1,
+ GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6,
+ GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, GPIO14,
+ GPIO15, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22,
+ GPIO23, GPIO24, GPIO25, GPIO26, GPIO27, GPIO28, GPIO29, GPIO30,
+ GPIO31, GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, GPIO37, GPIO38,
+ GPIO39, GPIO40, GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46,
+ GPIO47, GPIO48, GPIO49, GPIO50, GPIO51, GPIO52, GPIO53, GPIO54,
+ GPIO55, GPIO56, GPIO57, GPIO58, GPIO59, GPIO60, GPIO61, GPIO62,
+ GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70,
+ GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78,
+ GPIO79, GPIO80, GPIO81, GPIO82, GPIO83, GPIO84, GPIO85, GPIO86,
+ GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94,
+ GPIO95, GPIO96, GPIO97, GPIO98, GPIO99, GPIO100, GPIO101, GPIO102,
+ GPIO103, GPIO104, GPIO105, GPIO106, GPIO107, GPIO108, GPIO109, GPIO110,
+ GPIO111, GPIO112, GPIO113, GPIO114, GPIO115, GPIO116, GPIO117, GPIO118,
+ GPIO119, GPIO120, GPIO121, GPIO122, GPIO123, GPIO124, GPIO125, GPIO126,
+ GPIO127, GPIO128, GPIO129, GPIO130, GPIO131, GPIO132, GPIO133, GPIO134,
+ GPIO135, GPIO136, GPIO137, GPIO138, GPIO139, GPIO140, GPIO141, GPIO142,
+ GPIO143, GPIO144, GPIO145, GPIO146, GPIO147, GPIO148, GPIO149, GPIO150,
+ GPIO151, GPIO152, GPIO153, GPIO154, GPIO155, GPIO156, GPIO157, GPIO158,
+ GPIO159, GPIO160, GPIO161, GPIO162, GPIO163, GPIO164, GPIO165, GPIO166,
+ GPIO167, GPIO168, GPIO169, GPIO170, GPIO171, GPIO172, GPIO173, GPIO174,
+ GPIO175, GPIO176,
+ MT_GPIO_BASE_MAX
+} GPIO_PIN;
+
+static const struct mt_pin_info mt_pin_infos[] = {
+ PIN(0, 0, 6, 0x30, 0xb0),
+ PIN(1, 0, 7, 0x30, 0xb0),
+ PIN(2, 0, 8, 0x30, 0xb0),
+ PIN(3, 0, 9, 0x30, 0xb0),
+ PIN(4, 0, 10, 0x30, 0xb0),
+ PIN(5, 0, 11, 0x30, 0xb0),
+ PIN(6, 0, 12, 0x30, 0xb0),
+ PIN(7, 0, 13, 0x30, 0xb0),
+ PIN(8, 0, 14, 0x30, 0xb0),
+ PIN(9, 0, 15, 0x30, 0xb0),
+ PIN(10, 0, 16, 0x30, 0xb0),
+ PIN(11, 0, 17, 0x30, 0xb0),
+ PIN(12, 0, 12, 0x31, 0xa0),
+ PIN(13, 0, 13, 0x31, 0xa0),
+ PIN(14, 0, 14, 0x31, 0xa0),
+ PIN(15, 0, 15, 0x31, 0xa0),
+ PIN(16, 0, 1, 0x22, 0x50),
+ PIN(17, 0, 2, 0x22, 0x50),
+ PIN(18, 0, 3, 0x23, 0x60),
+ PIN(19, 0, 4, 0x23, 0x60),
+ PIN(20, 0, 5, 0x23, 0x60),
+ PIN(21, 0, 6, 0x23, 0x60),
+ PIN(22, 0, 0, 0x23, 0x60),
+ PIN(23, 0, 1, 0x23, 0x60),
+ PIN(24, 0, 2, 0x23, 0x60),
+ PIN(25, 0, 3, 0x30, 0xb0),
+ PIN(26, 0, 2, 0x30, 0xb0),
+ PIN(27, 0, 5, 0x30, 0xb0),
+ PIN(28, 0, 4, 0x30, 0xb0),
+ PIN(29, 0, 0, 0x30, 0xb0),
+ PIN(30, 0, 1, 0x30, 0xb0),
+ PIN(31, 0, 11, 0x30, 0xc0),
+ PIN(32, 0, 10, 0x30, 0xc0),
+ PIN(33, 0, 13, 0x30, 0xc0),
+ PIN(34, 0, 12, 0x30, 0xc0),
+ PIN(35, 0, 15, 0x30, 0xc0),
+ PIN(36, 0, 14, 0x30, 0xc0),
+ PIN(37, 0, 21, 0x30, 0xb0),
+ PIN(38, 0, 18, 0x30, 0xb0),
+ PIN(39, 0, 19, 0x30, 0xb0),
+ PIN(40, 0, 20, 0x30, 0xb0),
+ PIN(41, 0, 22, 0x30, 0xb0),
+ PIN(42, 1, 12, 0x31, 0xc0),
+ PIN(43, 1, 13, 0x31, 0xc0),
+ PIN(44, 1, 14, 0x31, 0xc0),
+ PIN(45, 1, 15, 0x31, 0xc0),
+ PIN(46, 0, 0, 0x22, 0x50),
+ PIN(47, 0, 25, 0x30, 0xb0),
+ PIN(48, 0, 24, 0x30, 0xb0),
+ PIN(49, 0, 23, 0x30, 0xb0),
+ PIN(50, 0, 5, 0x22, 0x50),
+ PIN(51, 0, 4, 0x22, 0x50),
+ PIN(52, 0, 3, 0x22, 0x50),
+ PIN(53, 0, 6, 0x22, 0x50),
+ PIN(54, 0, 7, 0x22, 0x50),
+ PIN(55, 0, 26, 0x30, 0xb0),
+ PIN(56, 0, 29, 0x30, 0xb0),
+ PIN(57, 0, 6, 0x31, 0xb0),
+ PIN(58, 0, 9, 0x31, 0xb0),
+ PIN(59, 0, 27, 0x30, 0xb0),
+ PIN(60, 0, 30, 0x30, 0xb0),
+ PIN(61, 0, 28, 0x30, 0xb0),
+ PIN(62, 0, 31, 0x30, 0xb0),
+ PIN(63, 0, 7, 0x31, 0xb0),
+ PIN(64, 0, 10, 0x31, 0xb0),
+ PIN(65, 0, 7, 0x23, 0x60),
+ PIN(66, 0, 9, 0x23, 0x60),
+ PIN(67, 0, 8, 0x23, 0x60),
+ PIN(68, 0, 10, 0x23, 0x60),
+ PIN(69, 0, 1, 0x30, 0xc0),
+ PIN(70, 0, 0, 0x30, 0xc0),
+ PIN(71, 0, 5, 0x30, 0xc0),
+ PIN(72, 0, 4, 0x30, 0xc0),
+ PIN(73, 0, 2, 0x30, 0xc0),
+ PIN(74, 0, 3, 0x30, 0xc0),
+ PIN(75, 0, 7, 0x30, 0xc0),
+ PIN(76, 0, 6, 0x30, 0xc0),
+ PIN(77, 0, 9, 0x30, 0xc0),
+ PIN(78, 0, 8, 0x30, 0xc0),
+ PIN(79, 0, 12, 0x23, 0x60),
+ PIN(80, 0, 11, 0x23, 0x60),
+ PIN(81, 0, 14, 0x23, 0x60),
+ PIN(82, 0, 13, 0x23, 0x60),
+ PIN(83, 0, 16, 0x31, 0xb0),
+ PIN(84, 0, 15, 0x31, 0xb0),
+ PIN(85, 0, 17, 0x31, 0xb0),
+ PIN(86, 0, 19, 0x31, 0xb0),
+ PIN(87, 0, 18, 0x31, 0xb0),
+ PIN(88, 0, 20, 0x31, 0xb0),
+ PIN(89, 0, 22, 0x31, 0xb0),
+ PIN(90, 0, 21, 0x31, 0xb0),
+ PIN(91, 0, 23, 0x31, 0xb0),
+ PIN(92, 0, 3, 0x31, 0xb0),
+ PIN(93, 0, 2, 0x31, 0xb0),
+ PIN(94, 0, 5, 0x31, 0xb0),
+ PIN(95, 0, 4, 0x31, 0xb0),
+ PIN(96, 0, 31, 0x31, 0xa0),
+ PIN(97, 0, 0, 0x31, 0xb0),
+ PIN(98, 0, 8, 0x31, 0xb0),
+ PIN(99, 0, 30, 0x31, 0xa0),
+ PIN(100, 0, 1, 0x31, 0xb0),
+ PIN(101, 0, 0, 0x31, 0xa0),
+ PIN(102, 0, 5, 0x31, 0xa0),
+ PIN(103, 0, 3, 0x31, 0xa0),
+ PIN(104, 0, 4, 0x31, 0xa0),
+ PIN(105, 0, 1, 0x31, 0xa0),
+ PIN(106, 0, 2, 0x31, 0xa0),
+ PIN(107, 0, 21, 0x31, 0xa0),
+ PIN(108, 0, 16, 0x31, 0xa0),
+ PIN(109, 0, 22, 0x31, 0xa0),
+ PIN(110, 0, 17, 0x31, 0xa0),
+ PIN(111, 0, 18, 0x31, 0xa0),
+ PIN(112, 0, 19, 0x31, 0xa0),
+ PIN(113, 0, 20, 0x31, 0xa0),
+ PIN(114, 0, 28, 0x31, 0xa0),
+ PIN(115, 0, 23, 0x31, 0xa0),
+ PIN(116, 0, 29, 0x31, 0xa0),
+ PIN(117, 0, 24, 0x31, 0xa0),
+ PIN(118, 0, 25, 0x31, 0xa0),
+ PIN(119, 0, 26, 0x31, 0xa0),
+ PIN(120, 0, 27, 0x31, 0xa0),
+ PIN(121, 0, 8, 0x22, 0x50),
+ PIN(122, 0, 11, 0x22, 0x50),
+ PIN(123, 0, 10, 0x22, 0x50),
+ PIN(124, 0, 9, 0x22, 0x50),
+ PIN(125, 0, 6, 0x31, 0xa0),
+ PIN(126, 0, 7, 0x31, 0xa0),
+ PIN(127, 0, 8, 0x31, 0xa0),
+ PIN(128, 0, 9, 0x31, 0xa0),
+ PIN(129, 0, 10, 0x31, 0xa0),
+ PIN(130, 0, 11, 0x31, 0xa0),
+ PIN(131, 1, 1, 0x30, 0xd0),
+ PIN(132, 1, 2, 0x30, 0xd0),
+ PIN(133, 1, 9, 0x30, 0xd0),
+ PIN(134, 1, 10, 0x30, 0xd0),
+ PIN(135, 1, 11, 0x30, 0xd0),
+ PIN(136, 1, 12, 0x30, 0xd0),
+ PIN(137, 1, 13, 0x30, 0xd0),
+ PIN(138, 1, 14, 0x30, 0xd0),
+ PIN(139, 1, 15, 0x30, 0xd0),
+ PIN(140, 1, 16, 0x30, 0xd0),
+ PIN(141, 1, 3, 0x30, 0xd0),
+ PIN(142, 1, 4, 0x30, 0xd0),
+ PIN(143, 1, 5, 0x30, 0xd0),
+ PIN(144, 1, 6, 0x30, 0xd0),
+ PIN(145, 1, 7, 0x30, 0xd0),
+ PIN(146, 1, 8, 0x30, 0xd0),
+ PIN(147, 1, 18, 0x30, 0xd0),
+ PIN(148, 1, 19, 0x30, 0xd0),
+ PIN(149, 1, 17, 0x30, 0xd0),
+ PIN(150, 1, 0, 0x30, 0xd0),
+ PIN(151, 1, 9, 0x31, 0xc0),
+ PIN(152, 1, 8, 0x31, 0xc0),
+ PIN(153, 1, 7, 0x31, 0xc0),
+ PIN(154, 1, 6, 0x31, 0xc0),
+ PIN(155, 1, 11, 0x31, 0xc0),
+ PIN(156, 1, 1, 0x31, 0xc0),
+ PIN(157, 1, 0, 0x31, 0xc0),
+ PIN(158, 1, 5, 0x31, 0xc0),
+ PIN(159, 1, 4, 0x31, 0xc0),
+ PIN(160, 1, 3, 0x31, 0xc0),
+ PIN(161, 1, 2, 0x31, 0xc0),
+ PIN(162, 1, 10, 0x31, 0xc0),
+ PIN(163, 1, 1, 0x23, 0x70),
+ PIN(164, 1, 0, 0x23, 0x70),
+ PIN(165, 1, 2, 0x23, 0x70),
+ PIN(166, 1, 3, 0x23, 0x70),
+ PIN(167, 1, 4, 0x23, 0x70),
+ PIN(168, 1, 5, 0x23, 0x70),
+ PIN(169, 1, 1, 0x22, 0x60),
+ PIN(170, 1, 0, 0x22, 0x60),
+ PIN(171, 1, 2, 0x22, 0x60),
+ PIN(172, 1, 3, 0x22, 0x60),
+ PIN(173, 1, 4, 0x22, 0x60),
+ PIN(174, 1, 5, 0x22, 0x60),
+ PIN(175, 0, 11, 0x31, 0xb0),
+ PIN(176, 0, 12, 0x31, 0xb0),
+};
+
+#endif /* MT_GPIO_H */
diff --git a/plat/mediatek/common/drivers/gpio/mtgpio_common.c b/plat/mediatek/drivers/gpio/mtgpio_common.c
similarity index 97%
rename from plat/mediatek/common/drivers/gpio/mtgpio_common.c
rename to plat/mediatek/drivers/gpio/mtgpio_common.c
index 89977a5..bad0190 100644
--- a/plat/mediatek/common/drivers/gpio/mtgpio_common.c
+++ b/plat/mediatek/drivers/gpio/mtgpio_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <drivers/delay_timer.h>
#include <drivers/gpio.h>
#include <lib/mmio.h>
+#include <lib/mtk_init/mtk_init.h>
#include <mtgpio.h>
#include <platform_def.h>
@@ -292,7 +293,10 @@
.get_pull = mt_get_gpio_pull,
};
-void mt_gpio_init(void)
+int mt_gpio_init(void)
{
gpio_init(&mtgpio_ops);
+
+ return 0;
}
+MTK_PLAT_SETUP_0_INIT(mt_gpio_init);
diff --git a/plat/mediatek/common/drivers/gpio/mtgpio_common.h b/plat/mediatek/drivers/gpio/mtgpio_common.h
similarity index 95%
rename from plat/mediatek/common/drivers/gpio/mtgpio_common.h
rename to plat/mediatek/drivers/gpio/mtgpio_common.h
index bf51055..d6b858c 100644
--- a/plat/mediatek/common/drivers/gpio/mtgpio_common.h
+++ b/plat/mediatek/drivers/gpio/mtgpio_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -104,6 +104,6 @@
uint16_t offset;
};
-void mt_gpio_init(void);
+int mt_gpio_init(void);
uintptr_t mt_gpio_find_reg_addr(uint32_t pin);
#endif /* MT_GPIO_COMMON_H */
diff --git a/plat/mediatek/drivers/gpio/rules.mk b/plat/mediatek/drivers/gpio/rules.mk
new file mode 100644
index 0000000..78061a8
--- /dev/null
+++ b/plat/mediatek/drivers/gpio/rules.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := gpio
+
+LOCAL_SRCS-y := drivers/gpio/gpio.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/mtgpio_common.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/mtgpio.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c
new file mode 100644
index 0000000..1d6863f
--- /dev/null
+++ b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mtk_iommu_plat.h>
+#include <mtk_mmap_pool.h>
+#include <platform_def.h>
+
+/* mm iommu */
+#define SMI_L0_ID (0)
+#define SMI_L1_ID (1)
+#define SMI_L2_ID (2)
+#define SMI_L3_ID (3)
+#define SMI_L4_ID (4)
+#define SMI_L5_ID (5)
+#define SMI_L6_ID (6)
+#define SMI_L7_ID (7)
+#define SMI_L9_ID (8)
+#define SMI_L10_ID (9)
+#define SMI_L11A_ID (10)
+#define SMI_L11B_ID (11)
+#define SMI_L11C_ID (12)
+#define SMI_L12_ID (13)
+#define SMI_L13_ID (14)
+#define SMI_L14_ID (15)
+#define SMI_L15_ID (16)
+#define SMI_L16A_ID (17)
+#define SMI_L16B_ID (18)
+#define SMI_L17A_ID (19)
+#define SMI_L17B_ID (20)
+#define SMI_L19_ID (21)
+#define SMI_L21_ID (22)
+#define SMI_L23_ID (23)
+#define SMI_L27_ID (24)
+#define SMI_L28_ID (25)
+
+/* infra iommu */
+#define PERI_MST_PROT (0x710)
+#define PERICFG_AO_IOMMU_1 (0x714)
+#define MMU_DEV_PCIE_0 (0)
+#define IFR_CFG_GROUP_NUM (1)
+
+static struct mtk_smi_larb_config mt8188_larb_cfg[SMI_LARB_NUM] = {
+ [SMI_L0_ID] = LARB_CFG_ENTRY(SMI_LARB_0_BASE, 7, 0),
+ [SMI_L1_ID] = LARB_CFG_ENTRY(SMI_LARB_1_BASE, 7, 0),
+ [SMI_L2_ID] = LARB_CFG_ENTRY(SMI_LARB_2_BASE, 5, 0),
+ [SMI_L3_ID] = LARB_CFG_ENTRY(SMI_LARB_3_BASE, 7, 0),
+ [SMI_L4_ID] = LARB_CFG_ENTRY(SMI_LARB_4_BASE, 7, 0),
+ [SMI_L5_ID] = LARB_CFG_ENTRY(SMI_LARB_5_BASE, 8, 0),
+ [SMI_L6_ID] = LARB_CFG_ENTRY(SMI_LARB_6_BASE, 4, 0),
+ [SMI_L7_ID] = LARB_CFG_ENTRY(SMI_LARB_7_BASE, 3, 0),
+ [SMI_L9_ID] = LARB_CFG_ENTRY(SMI_LARB_9_BASE, 25, 0),
+ [SMI_L10_ID] = LARB_CFG_ENTRY(SMI_LARB_10_BASE, 20, 0),
+ [SMI_L11A_ID] = LARB_CFG_ENTRY(SMI_LARB_11A_BASE, 30, 0),
+ [SMI_L11B_ID] = LARB_CFG_ENTRY(SMI_LARB_11B_BASE, 30, 0),
+ [SMI_L11C_ID] = LARB_CFG_ENTRY(SMI_LARB_11C_BASE, 30, 0),
+ [SMI_L12_ID] = LARB_CFG_ENTRY(SMI_LARB_12_BASE, 16, 0),
+ [SMI_L13_ID] = LARB_CFG_ENTRY(SMI_LARB_13_BASE, 24, 0),
+ [SMI_L14_ID] = LARB_CFG_ENTRY(SMI_LARB_14_BASE, 23, 0),
+ [SMI_L15_ID] = LARB_CFG_ENTRY(SMI_LARB_15_BASE, 19, 0),
+ [SMI_L16A_ID] = LARB_CFG_ENTRY(SMI_LARB_16A_BASE, 17, 0),
+ [SMI_L16B_ID] = LARB_CFG_ENTRY(SMI_LARB_16B_BASE, 17, 0),
+ [SMI_L17A_ID] = LARB_CFG_ENTRY(SMI_LARB_17A_BASE, 7, 0),
+ [SMI_L17B_ID] = LARB_CFG_ENTRY(SMI_LARB_17B_BASE, 7, 0),
+ /* venc nbm ports (5/6/11/15/16/17) to sram */
+ [SMI_L19_ID] = LARB_CFG_ENTRY_WITH_PATH(SMI_LARB_19_BASE, 27, 0, 0x38860),
+ [SMI_L21_ID] = LARB_CFG_ENTRY(SMI_LARB_21_BASE, 11, 0),
+ [SMI_L23_ID] = LARB_CFG_ENTRY(SMI_LARB_23_BASE, 9, 0),
+ [SMI_L27_ID] = LARB_CFG_ENTRY(SMI_LARB_27_BASE, 4, 0),
+ [SMI_L28_ID] = LARB_CFG_ENTRY(SMI_LARB_28_BASE, 0, 0),
+};
+
+static bool is_protected;
+
+static uint32_t mt8188_ifr_mst_cfg_base[IFR_CFG_GROUP_NUM] = {
+ PERICFG_AO_BASE,
+};
+static uint32_t mt8188_ifr_mst_cfg_offs[IFR_CFG_GROUP_NUM] = {
+ PERICFG_AO_IOMMU_1,
+};
+static struct mtk_ifr_mst_config mt8188_ifr_mst_cfg[MMU_DEV_NUM] = {
+ [MMU_DEV_PCIE_0] = IFR_MST_CFG_ENTRY(0, 18),
+};
+
+struct mtk_smi_larb_config *g_larb_cfg = &mt8188_larb_cfg[0];
+struct mtk_ifr_mst_config *g_ifr_mst_cfg = &mt8188_ifr_mst_cfg[0];
+uint32_t *g_ifr_mst_cfg_base = &mt8188_ifr_mst_cfg_base[0];
+uint32_t *g_ifr_mst_cfg_offs = &mt8188_ifr_mst_cfg_offs[0];
+
+/* Protect infra iommu enable setting registers as secure access. */
+void mtk_infra_iommu_enable_protect(void)
+{
+ if (!is_protected) {
+ mmio_write_32(PERICFG_AO_BASE + PERI_MST_PROT, 0xffffffff);
+ is_protected = true;
+ }
+}
diff --git a/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h
new file mode 100644
index 0000000..a59e0c7
--- /dev/null
+++ b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IOMMU_PLAT_H
+#define IOMMU_PLAT_H
+
+#include <mtk_iommu_priv.h>
+
+/* mm iommu */
+#define SMI_LARB_NUM (26)
+extern struct mtk_smi_larb_config *g_larb_cfg;
+
+/* infra iommu */
+#define MMU_DEV_NUM (1)
+extern struct mtk_ifr_mst_config *g_ifr_mst_cfg;
+extern uint32_t *g_ifr_mst_cfg_base;
+extern uint32_t *g_ifr_mst_cfg_offs;
+
+extern void mtk_infra_iommu_enable_protect(void);
+
+#endif /* IOMMU_PLAT_H */
diff --git a/plat/mediatek/drivers/iommu/mtk_iommu_priv.h b/plat/mediatek/drivers/iommu/mtk_iommu_priv.h
new file mode 100644
index 0000000..3404d31
--- /dev/null
+++ b/plat/mediatek/drivers/iommu/mtk_iommu_priv.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IOMMU_PRIV_H
+#define IOMMU_PRIV_H
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <mtk_sip_svc.h>
+
+#define LARB_CFG_ENTRY(bs, p_nr, dom) \
+ { .base = (bs), .port_nr = (p_nr), \
+ .dom_id = (dom), .to_sram = 0, }
+
+#define LARB_CFG_ENTRY_WITH_PATH(bs, p_nr, dom, sram) \
+ { .base = (bs), .port_nr = (p_nr), \
+ .dom_id = (dom), .to_sram = (sram), }
+
+#define IFR_MST_CFG_ENTRY(idx, bit) \
+ { .cfg_addr_idx = (idx), .r_mmu_en_bit = (bit), }
+
+enum IOMMU_ATF_CMD {
+ IOMMU_ATF_CMD_CONFIG_SMI_LARB, /* For mm master to enable iommu */
+ IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU, /* For infra master to enable iommu */
+ IOMMU_ATF_CMD_COUNT,
+};
+
+struct mtk_smi_larb_config {
+ uint32_t base;
+ uint32_t port_nr;
+ uint32_t dom_id;
+ uint32_t to_sram;
+ uint32_t sec_en_msk;
+};
+
+struct mtk_ifr_mst_config {
+ uint8_t cfg_addr_idx;
+ uint8_t r_mmu_en_bit;
+};
+
+#endif /* IOMMU_PRIV_H */
diff --git a/plat/mediatek/drivers/iommu/mtk_iommu_smc.c b/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
new file mode 100644
index 0000000..9762d0b
--- /dev/null
+++ b/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <mtk_iommu_plat.h>
+
+/* defination */
+/* smi larb */
+#define SMI_LARB_NON_SEC_CON(port) (0x380 + ((port) << 2))
+#define PATH_SEL_MASK (0xf0000) /* to sram (INT) */
+#define SMI_LARB_SEC_CON_INT(port) (0xf00 + ((port) << 2))
+#define SMI_LARB_SEC_CON(port) (0xf80 + ((port) << 2))
+#define MMU_MASK BIT(0)
+#define MMU_EN(en) ((!!(en)) << 0)
+#define SEC_MASK BIT(1)
+#define SEC_EN(en) ((!!(en)) << 1)
+#define DOMAIN_MASK (0x1f << 4)
+#define SMI_MMU_EN(port) (0x1 << (port))
+
+/* infra master */
+#define IFR_CFG_MMU_EN_MSK(r_bit) (0x3 << (r_bit))
+
+/* smi larb configure */
+/*
+ * If multimedia security config is enabled, the SMI config register must be
+ * configurated in security world.
+ * And the SRAM path is also configurated here to enhance security.
+ */
+static void mtk_smi_larb_port_config_to_sram(
+ const struct mtk_smi_larb_config *larb,
+ uint32_t port_id)
+{
+ mmio_clrbits_32(larb->base + SMI_LARB_SEC_CON_INT(port_id),
+ MMU_MASK | SEC_MASK | DOMAIN_MASK);
+
+ mmio_setbits_32(larb->base + SMI_LARB_NON_SEC_CON(port_id),
+ PATH_SEL_MASK);
+}
+
+static void mtk_smi_port_config(const struct mtk_smi_larb_config *larb,
+ uint32_t port_id, uint8_t mmu_en, uint8_t sec_en)
+{
+ mmio_clrsetbits_32(larb->base + SMI_LARB_SEC_CON(port_id),
+ MMU_MASK | SEC_MASK | DOMAIN_MASK,
+ MMU_EN(mmu_en) | SEC_EN(sec_en));
+}
+
+static int mtk_smi_larb_port_config_sec(uint32_t larb_id, uint32_t mmu_en_msk)
+{
+ uint32_t port_id, port_nr;
+ const struct mtk_smi_larb_config *larb;
+ uint32_t to_sram;
+ uint8_t mmu_en;
+
+ if (larb_id >= SMI_LARB_NUM) {
+ return MTK_SIP_E_INVALID_PARAM;
+ }
+
+ larb = &g_larb_cfg[larb_id];
+ port_nr = larb->port_nr;
+ to_sram = larb->to_sram;
+
+ for (port_id = 0; port_id < port_nr; port_id++) {
+ if ((to_sram & BIT(port_id)) > 0U) {
+ mtk_smi_larb_port_config_to_sram(larb, port_id);
+ continue;
+ }
+ mmu_en = !!(mmu_en_msk & SMI_MMU_EN(port_id));
+ mtk_smi_port_config(larb, port_id, mmu_en, 0);
+ }
+
+ return MTK_SIP_E_SUCCESS;
+}
+
+static int mtk_infra_master_config_sec(uint32_t dev_id, uint32_t enable)
+{
+ const struct mtk_ifr_mst_config *ifr_cfg;
+ uint32_t reg_addr;
+
+ mtk_infra_iommu_enable_protect();
+
+ if (dev_id >= MMU_DEV_NUM) {
+ return MTK_SIP_E_NOT_SUPPORTED;
+ }
+
+ ifr_cfg = &g_ifr_mst_cfg[dev_id];
+ reg_addr = g_ifr_mst_cfg_base[(ifr_cfg->cfg_addr_idx)] +
+ g_ifr_mst_cfg_offs[(ifr_cfg->cfg_addr_idx)];
+
+ if (enable > 0U) {
+ mmio_setbits_32(reg_addr, IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit));
+ } else {
+ mmio_clrbits_32(reg_addr, IFR_CFG_MMU_EN_MSK(ifr_cfg->r_mmu_en_bit));
+ }
+
+ return MTK_SIP_E_SUCCESS;
+}
+
+static u_register_t mtk_iommu_handler(u_register_t x1, u_register_t x2,
+ u_register_t x3, u_register_t x4,
+ void *handle, struct smccc_res *smccc_ret)
+{
+ uint32_t cmd_id = x1, mdl_id = x2, val = x3;
+ int ret = MTK_SIP_E_NOT_SUPPORTED;
+
+ (void)x4;
+ (void)handle;
+
+ switch (cmd_id) {
+ case IOMMU_ATF_CMD_CONFIG_SMI_LARB:
+ ret = mtk_smi_larb_port_config_sec(mdl_id, val);
+ break;
+ case IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU:
+ ret = mtk_infra_master_config_sec(mdl_id, val);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+DECLARE_SMC_HANDLER(MTK_SIP_IOMMU_CONTROL, mtk_iommu_handler);
diff --git a/plat/mediatek/drivers/iommu/rules.mk b/plat/mediatek/drivers/iommu/rules.mk
new file mode 100644
index 0000000..5490f41
--- /dev/null
+++ b/plat/mediatek/drivers/iommu/rules.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mtk_iommu
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_iommu_smc.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/mtk_iommu_plat.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/common/lpm/mt_lp_rm.c b/plat/mediatek/drivers/lpm/mt_lp_rm.c
similarity index 96%
rename from plat/mediatek/common/lpm/mt_lp_rm.c
rename to plat/mediatek/drivers/lpm/mt_lp_rm.c
index f3148fe..0bafc66 100644
--- a/plat/mediatek/common/lpm/mt_lp_rm.c
+++ b/plat/mediatek/drivers/lpm/mt_lp_rm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/common/lpm/mt_lp_rm.h b/plat/mediatek/drivers/lpm/mt_lp_rm.h
similarity index 94%
rename from plat/mediatek/common/lpm/mt_lp_rm.h
rename to plat/mediatek/drivers/lpm/mt_lp_rm.h
index 39759f1..e93dac3 100644
--- a/plat/mediatek/common/lpm/mt_lp_rm.h
+++ b/plat/mediatek/drivers/lpm/mt_lp_rm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/drivers/msdc/mt8186/mt_msdc_priv.h b/plat/mediatek/drivers/msdc/mt8186/mt_msdc_priv.h
new file mode 100644
index 0000000..b3337ca
--- /dev/null
+++ b/plat/mediatek/drivers/msdc/mt8186/mt_msdc_priv.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_MSDC_PRIV_H
+#define MT_MSDC_PRIV_H
+
+#define MSDC_CQHCI_CFG 0x808
+#define MSDC_CQHCI_CRYPTO_ENABLE BIT(1)
+
+#endif
diff --git a/plat/mediatek/drivers/msdc/mt_msdc.c b/plat/mediatek/drivers/msdc/mt_msdc.c
new file mode 100644
index 0000000..ccf440f
--- /dev/null
+++ b/plat/mediatek/drivers/msdc/mt_msdc.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <mt_msdc.h>
+#include <platform_def.h>
+
+uint64_t msdc_smc_dispatcher(uint64_t arg0, uint64_t arg1,
+ uint64_t arg2, uint64_t arg3)
+{
+ INFO("[%s] msdc setup call from kernel\n", __func__);
+ mmio_setbits_32(MSDC0_BASE + MSDC_CQHCI_CFG, MSDC_CQHCI_CRYPTO_ENABLE);
+
+ return 0L;
+}
diff --git a/plat/mediatek/drivers/msdc/mt_msdc.h b/plat/mediatek/drivers/msdc/mt_msdc.h
new file mode 100644
index 0000000..1c500c2
--- /dev/null
+++ b/plat/mediatek/drivers/msdc/mt_msdc.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MT_MSDC_H
+#define MT_MSDC_H
+
+#include <mt_msdc_priv.h>
+
+uint64_t msdc_smc_dispatcher(uint64_t arg0, uint64_t arg1,
+ uint64_t arg2, uint64_t arg3);
+
+#endif
diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic.c b/plat/mediatek/drivers/pmic/pmic.c
similarity index 73%
rename from plat/mediatek/mt8192/drivers/pmic/pmic.c
rename to plat/mediatek/drivers/pmic/pmic.c
index cca4413..a11ad9a 100644
--- a/plat/mediatek/mt8192/drivers/pmic/pmic.c
+++ b/plat/mediatek/drivers/pmic/pmic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic.h b/plat/mediatek/drivers/pmic/pmic.h
similarity index 63%
rename from plat/mediatek/mt8192/drivers/pmic/pmic.h
rename to plat/mediatek/drivers/pmic/pmic.h
index aac22af..6c10f65 100644
--- a/plat/mediatek/mt8192/drivers/pmic/pmic.h
+++ b/plat/mediatek/drivers/pmic/pmic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,7 +7,7 @@
#ifndef PMIC_H
#define PMIC_H
-#define PMIC_PWRHOLD 0xa08
+#define PMIC_PWRHOLD (0xa08)
/* external API */
void pmic_power_off(void);
diff --git a/plat/mediatek/drivers/pmic/rules.mk b/plat/mediatek/drivers/pmic/rules.mk
new file mode 100644
index 0000000..e408b03
--- /dev/null
+++ b/plat/mediatek/drivers/pmic/rules.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := pmic
+
+LOCAL_SRCS-y += ${LOCAL_DIR}/pmic.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}/
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/pmic_wrap/mt8188/pmic_wrap_init.h b/plat/mediatek/drivers/pmic_wrap/mt8188/pmic_wrap_init.h
new file mode 100644
index 0000000..9027daf
--- /dev/null
+++ b/plat/mediatek/drivers/pmic_wrap/mt8188/pmic_wrap_init.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMIC_WRAP_INIT_H
+#define PMIC_WRAP_INIT_H
+
+#include <stdint.h>
+
+#include "platform_def.h"
+#include <pmic_wrap_init_common.h>
+
+static struct mt8188_pmic_wrap_regs *const mtk_pwrap = (void *)PMIC_WRAP_BASE;
+
+/* PMIC_WRAP registers */
+struct mt8188_pmic_wrap_regs {
+ uint32_t init_done;
+ uint32_t reserved[543];
+ uint32_t wacs2_cmd;
+ uint32_t wacs2_wdata;
+ uint32_t reserved1[3];
+ uint32_t wacs2_rdata;
+ uint32_t reserved2[3];
+ uint32_t wacs2_vldclr;
+ uint32_t wacs2_sta;
+};
+
+#endif /* PMIC_WRAP_INIT_H */
diff --git a/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init.c b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init.c
similarity index 98%
rename from plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init.c
rename to plat/mediatek/drivers/pmic_wrap/pmic_wrap_init.c
index e3cfd46..0ee1c64 100644
--- a/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init.c
+++ b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2019-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_common.h b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_common.h
new file mode 100644
index 0000000..4ba1f5c
--- /dev/null
+++ b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_common.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMIC_WRAP_INIT_COMMON_H
+#define PMIC_WRAP_INIT_COMMON_H
+
+#include <stdint.h>
+
+#include "platform_def.h"
+
+/* external API */
+int32_t pwrap_read(uint32_t adr, uint32_t *rdata);
+int32_t pwrap_write(uint32_t adr, uint32_t wdata);
+
+#define GET_WACS_FSM(x) ((x >> 1) & 0x7)
+
+/* macro for SWINF_FSM */
+#define SWINF_FSM_IDLE (0x00)
+#define SWINF_FSM_REQ (0x02)
+#define SWINF_FSM_WFDLE (0x04)
+#define SWINF_FSM_WFVLDCLR (0x06)
+#define SWINF_INIT_DONE (0x01)
+
+/* timeout setting */
+#define PWRAP_READ_US (1000)
+#define PWRAP_WAIT_IDLE_US (1000)
+
+/* error information flag */
+enum pwrap_errno {
+ E_PWR_INVALID_ARG = 1,
+ E_PWR_INVALID_RW = 2,
+ E_PWR_INVALID_ADDR = 3,
+ E_PWR_INVALID_WDAT = 4,
+ E_PWR_INVALID_OP_MANUAL = 5,
+ E_PWR_NOT_IDLE_STATE = 6,
+ E_PWR_NOT_INIT_DONE = 7,
+ E_PWR_NOT_INIT_DONE_READ = 8,
+ E_PWR_WAIT_IDLE_TIMEOUT = 9,
+ E_PWR_WAIT_IDLE_TIMEOUT_READ = 10,
+ E_PWR_INIT_SIDLY_FAIL = 11,
+ E_PWR_RESET_TIMEOUT = 12,
+ E_PWR_TIMEOUT = 13,
+ E_PWR_INIT_RESET_SPI = 20,
+ E_PWR_INIT_SIDLY = 21,
+ E_PWR_INIT_REG_CLOCK = 22,
+ E_PWR_INIT_ENABLE_PMIC = 23,
+ E_PWR_INIT_DIO = 24,
+ E_PWR_INIT_CIPHER = 25,
+ E_PWR_INIT_WRITE_TEST = 26,
+ E_PWR_INIT_ENABLE_CRC = 27,
+ E_PWR_INIT_ENABLE_DEWRAP = 28,
+ E_PWR_INIT_ENABLE_EVENT = 29,
+ E_PWR_READ_TEST_FAIL = 30,
+ E_PWR_WRITE_TEST_FAIL = 31,
+ E_PWR_SWITCH_DIO = 32,
+};
+
+#endif /* PMIC_WRAP_INIT_COMMON_H */
diff --git a/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_v2.c
similarity index 97%
rename from plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c
rename to plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_v2.c
index d9a79c4..80f55de 100644
--- a/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c
+++ b/plat/mediatek/drivers/pmic_wrap/pmic_wrap_init_v2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/drivers/pmic_wrap/rules.mk b/plat/mediatek/drivers/pmic_wrap/rules.mk
new file mode 100644
index 0000000..9ba44a6
--- /dev/null
+++ b/plat/mediatek/drivers/pmic_wrap/rules.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := pmic_wrap
+
+ifeq (${USE_PMIC_WRAP_INIT_V2}, 1)
+LOCAL_SRCS-y += ${LOCAL_DIR}/pmic_wrap_init_v2.c
+else
+LOCAL_SRCS-y += ${LOCAL_DIR}/pmic_wrap_init.c
+endif
+
+PLAT_INCLUDES += -I${LOCAL_DIR}/
+PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/rtc/mt8188/rtc.h b/plat/mediatek/drivers/rtc/mt8188/rtc.h
new file mode 100644
index 0000000..734e89f
--- /dev/null
+++ b/plat/mediatek/drivers/rtc/mt8188/rtc.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RTC_H
+#define RTC_H
+
+#include <rtc_mt6359p.h>
+
+#endif /* RTC_H */
diff --git a/plat/mediatek/common/drivers/rtc/rtc_common.c b/plat/mediatek/drivers/rtc/rtc_common.c
similarity index 94%
rename from plat/mediatek/common/drivers/rtc/rtc_common.c
rename to plat/mediatek/drivers/rtc/rtc_common.c
index cad12a0..4efddff 100644
--- a/plat/mediatek/common/drivers/rtc/rtc_common.c
+++ b/plat/mediatek/drivers/rtc/rtc_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2019-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/common/drivers/rtc/rtc_mt6359p.c b/plat/mediatek/drivers/rtc/rtc_mt6359p.c
similarity index 97%
rename from plat/mediatek/common/drivers/rtc/rtc_mt6359p.c
rename to plat/mediatek/drivers/rtc/rtc_mt6359p.c
index 124bc8f..3bf4337 100644
--- a/plat/mediatek/common/drivers/rtc/rtc_mt6359p.c
+++ b/plat/mediatek/drivers/rtc/rtc_mt6359p.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/common/drivers/rtc/rtc_mt6359p.h b/plat/mediatek/drivers/rtc/rtc_mt6359p.h
similarity index 98%
rename from plat/mediatek/common/drivers/rtc/rtc_mt6359p.h
rename to plat/mediatek/drivers/rtc/rtc_mt6359p.h
index 04726e3..199f152 100644
--- a/plat/mediatek/common/drivers/rtc/rtc_mt6359p.h
+++ b/plat/mediatek/drivers/rtc/rtc_mt6359p.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/drivers/rtc/rules.mk b/plat/mediatek/drivers/rtc/rules.mk
new file mode 100644
index 0000000..2398f8a
--- /dev/null
+++ b/plat/mediatek/drivers/rtc/rules.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := rtc
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/rtc_common.c
+
+ifeq (${USE_RTC_MT6359P}, 1)
+LOCAL_SRCS-y += ${LOCAL_DIR}/rtc_mt6359p.c
+PLAT_INCLUDES += -I${LOCAL_DIR}
+endif
+
+PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/common/drivers/timer/mt_timer.c b/plat/mediatek/drivers/timer/mt_timer.c
similarity index 72%
rename from plat/mediatek/common/drivers/timer/mt_timer.c
rename to plat/mediatek/drivers/timer/mt_timer.c
index 0860885..11e4572 100644
--- a/plat/mediatek/common/drivers/timer/mt_timer.c
+++ b/plat/mediatek/drivers/timer/mt_timer.c
@@ -1,15 +1,16 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
+#include <common/debug.h>
#include <lib/mmio.h>
+#include <lib/mtk_init/mtk_init.h>
#include <mt_timer.h>
#include <platform_def.h>
-
uint64_t normal_time_base;
uint64_t atf_time_base;
@@ -30,9 +31,14 @@
return cval;
}
-void mt_systimer_init(void)
+int mt_systimer_init(void)
{
+ INFO("[%s] systimer initialization\n", __func__);
+
/* Enable access in NS mode */
mmio_write_32(CNTWACR_REG, CNT_WRITE_ACCESS_CTL_MASK);
mmio_write_32(CNTRACR_REG, CNT_READ_ACCESS_CTL_MASK);
+
+ return 0;
}
+MTK_PLAT_SETUP_0_INIT(mt_systimer_init);
diff --git a/plat/mediatek/common/drivers/timer/mt_timer.h b/plat/mediatek/drivers/timer/mt_timer.h
similarity index 91%
rename from plat/mediatek/common/drivers/timer/mt_timer.h
rename to plat/mediatek/drivers/timer/mt_timer.h
index b353177..1c08f90 100644
--- a/plat/mediatek/common/drivers/timer/mt_timer.h
+++ b/plat/mediatek/drivers/timer/mt_timer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,6 +30,6 @@
void sched_clock_init(uint64_t normal_base, uint64_t atf_base);
uint64_t sched_clock(void);
-void mt_systimer_init(void);
+int mt_systimer_init(void);
#endif /* MT_TIMER_H */
diff --git a/plat/mediatek/drivers/timer/rules.mk b/plat/mediatek/drivers/timer/rules.mk
new file mode 100644
index 0000000..005cf45
--- /dev/null
+++ b/plat/mediatek/drivers/timer/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := timer
+LOCAL_SRCS-y := $(LOCAL_DIR)/mt_timer.c
+
+PLAT_INCLUDES += -I${LOCAL_DIR}
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/common/drivers/uart/8250_console.S b/plat/mediatek/drivers/uart/8250_console.S
similarity index 98%
rename from plat/mediatek/common/drivers/uart/8250_console.S
rename to plat/mediatek/drivers/uart/8250_console.S
index 7a946f9..66f998d 100644
--- a/plat/mediatek/common/drivers/uart/8250_console.S
+++ b/plat/mediatek/drivers/uart/8250_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/common/drivers/uart/uart.c b/plat/mediatek/drivers/uart/uart.c
similarity index 97%
rename from plat/mediatek/common/drivers/uart/uart.c
rename to plat/mediatek/drivers/uart/uart.c
index b940eb3..fdaa793 100644
--- a/plat/mediatek/common/drivers/uart/uart.c
+++ b/plat/mediatek/drivers/uart/uart.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/common/drivers/uart/uart.h b/plat/mediatek/drivers/uart/uart.h
similarity index 97%
rename from plat/mediatek/common/drivers/uart/uart.h
rename to plat/mediatek/drivers/uart/uart.h
index ac8b94d..2ca74fa 100644
--- a/plat/mediatek/common/drivers/uart/uart.h
+++ b/plat/mediatek/drivers/uart/uart.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/common/drivers/uart/uart8250.h b/plat/mediatek/drivers/uart/uart8250.h
similarity index 93%
rename from plat/mediatek/common/drivers/uart/uart8250.h
rename to plat/mediatek/drivers/uart/uart8250.h
index da7c7a1..f0541d6 100644
--- a/plat/mediatek/common/drivers/uart/uart8250.h
+++ b/plat/mediatek/drivers/uart/uart8250.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/mediatek/include/cold_boot.h b/plat/mediatek/include/cold_boot.h
new file mode 100644
index 0000000..6b94b57
--- /dev/null
+++ b/plat/mediatek/include/cold_boot.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef COLD_BOOT_H
+#define COLD_BOOT_H
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+#define LINUX_KERNEL_32 (0)
+#define LINUX_KERNEL_64 (1)
+#define DEVINFO_SIZE (4)
+
+struct atf_arg_t {
+ uint32_t atf_magic;
+ uint32_t tee_support;
+ uint64_t tee_entry;
+ uint64_t tee_boot_arg_addr;
+ uint32_t hwuid[4]; /* HW Unique id for t-base used */
+ uint32_t HRID[8]; /* HW random id for t-base used */
+ uint32_t devinfo[DEVINFO_SIZE];
+};
+
+struct mtk_bl31_fw_config {
+ void *from_bl2; /* MTK boot tag */
+ void *soc_fw_config;
+ void *hw_config;
+ void *reserved;
+};
+
+enum {
+ BOOT_ARG_FROM_BL2,
+ BOOT_ARG_SOC_FW_CONFIG,
+ BOOT_ARG_HW_CONFIG,
+ BOOT_ARG_RESERVED
+};
+
+struct kernel_info {
+ uint64_t pc;
+ uint64_t r0;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t k32_64;
+};
+
+struct mtk_bl_param_t {
+ uint64_t bootarg_loc;
+ uint64_t bootarg_size;
+ uint64_t bl33_start_addr;
+ uint64_t atf_arg_addr;
+};
+
+void *get_mtk_bl31_fw_config(int index);
+bool is_el1_2nd_bootloader(void);
+
+#endif /* COLD_BOOT_H */
diff --git a/plat/mediatek/include/lib/mtk_init/mtk_init.h b/plat/mediatek/include/lib/mtk_init/mtk_init.h
new file mode 100644
index 0000000..6f23a9b
--- /dev/null
+++ b/plat/mediatek/include/lib/mtk_init/mtk_init.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_INIT_H
+#define MTK_INIT_H
+
+#include <cdefs.h>
+#include <lib/mtk_init/mtk_init_def.h>
+
+#define INIT_CALL_EXPAND_AS_ENUMERATION(_section_enum, _section_name, _level) \
+ _section_enum = _level,
+
+#define EXPAND_AS_LINK_SECTION(_section_enum, _section_name, _level) \
+ __##_section_enum##_START__ = .; \
+ KEEP(*(_section_name##_level));
+
+#define EXPAND_AS_EXTERN(_section_enum, _section_name, _level) \
+ extern struct initcall __##_section_enum##_START__[];
+
+#define EXPAND_AS_SYMBOL_ARR(_section_enum, _section_name, _level) \
+ __##_section_enum##_START__,
+
+#define DECLARE_MTK_INITCALL(_fn, _level) \
+ const struct initcall _mtk_initcall_##_fn \
+ __used \
+ __aligned(sizeof(void *)) \
+ __section(".mtk_plat_initcall_"#_level) \
+ = { \
+ .name = #_fn, \
+ .fn = _fn \
+ }
+
+/* initcall helpers */
+#define MTK_EARLY_PLAT_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 0)
+#define MTK_ARCH_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 1)
+#define MTK_PLAT_SETUP_0_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 2)
+#define MTK_PLAT_SETUP_1_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 3)
+#define MTK_PLAT_RUNTIME_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 4)
+#define MTK_PLAT_BL33_DEFER_INIT(_fn) DECLARE_MTK_INITCALL(_fn, 5)
+
+#ifndef __ASSEMBLER__
+struct initcall {
+ const char *name;
+ int (*fn)(void);
+};
+
+enum {
+ INIT_CALL_TABLE(INIT_CALL_EXPAND_AS_ENUMERATION)
+ MTK_INIT_LVL_MAX
+};
+
+void mtk_init_one_level(unsigned int level);
+#endif
+
+#endif /* MTK_INIT_H */
diff --git a/plat/mediatek/include/lib/mtk_init/mtk_init_def.h b/plat/mediatek/include/lib/mtk_init/mtk_init_def.h
new file mode 100644
index 0000000..8aae41d
--- /dev/null
+++ b/plat/mediatek/include/lib/mtk_init/mtk_init_def.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_INIT_DEF_H
+#define MTK_INIT_DEF_H
+
+/*
+ * Define init call sections here. _func is for 2nd level expansion, init
+ * section enum, and init section name.
+ */
+#define INIT_CALL_TABLE(_func) \
+ _func(MTK_INIT_LVL_EARLY_PLAT, .mtk_plat_initcall_, 0) \
+ _func(MTK_INIT_LVL_ARCH, .mtk_plat_initcall_, 1) \
+ _func(MTK_INIT_LVL_PLAT_SETUP_0, .mtk_plat_initcall_, 2) \
+ _func(MTK_INIT_LVL_PLAT_SETUP_1, .mtk_plat_initcall_, 3) \
+ _func(MTK_INIT_LVL_PLAT_RUNTIME, .mtk_plat_initcall_, 4) \
+ _func(MTK_INIT_LVL_BL33_DEFER, .mtk_plat_initcall_, 5)
+
+#endif /* MTK_INIT_DEF_H */
diff --git a/plat/mediatek/include/mt8188/platform_def.h b/plat/mediatek/include/mt8188/platform_def.h
new file mode 100644
index 0000000..962d952
--- /dev/null
+++ b/plat/mediatek/include/mt8188/platform_def.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#define PLAT_PRIMARY_CPU (0x0)
+
+#define MT_GIC_BASE (0x0C000000)
+#define MCUCFG_BASE (0x0C530000)
+#define IO_PHYS (0x10000000)
+
+/* Aggregate of all devices for MMU mapping */
+#define MTK_DEV_RNG0_BASE (MT_GIC_BASE)
+#define MTK_DEV_RNG0_SIZE (0x600000)
+#define MTK_DEV_RNG1_BASE (IO_PHYS)
+#define MTK_DEV_RNG1_SIZE (0x10000000)
+
+/*******************************************************************************
+ * GPIO related constants
+ ******************************************************************************/
+#define GPIO_BASE (IO_PHYS + 0x00005000)
+#define IOCFG_RM_BASE (IO_PHYS + 0x01C00000)
+#define IOCFG_LT_BASE (IO_PHYS + 0x01E10000)
+#define IOCFG_LM_BASE (IO_PHYS + 0x01E20000)
+#define IOCFG_RT_BASE (IO_PHYS + 0x01EA0000)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define UART0_BASE (IO_PHYS + 0x01002000)
+#define UART_BAUDRATE (115200)
+
+/*******************************************************************************
+ * PMIC related constants
+ ******************************************************************************/
+#define PMIC_WRAP_BASE (IO_PHYS + 0x00024000)
+
+/*******************************************************************************
+ * Infra IOMMU related constants
+ ******************************************************************************/
+#define PERICFG_AO_BASE (IO_PHYS + 0x01003000)
+#define PERICFG_AO_REG_SIZE (0x1000)
+
+/*******************************************************************************
+ * GIC-600 & interrupt handling related constants
+ ******************************************************************************/
+/* Base MTK_platform compatible GIC memory map */
+#define BASE_GICD_BASE (MT_GIC_BASE)
+#define MT_GIC_RDIST_BASE (MT_GIC_BASE + 0x40000)
+
+/*******************************************************************************
+ * CIRQ related constants
+ ******************************************************************************/
+#define SYS_CIRQ_BASE (IO_PHYS + 0x204000)
+#define MD_WDT_IRQ_BIT_ID (141)
+#define CIRQ_IRQ_NUM (730)
+#define CIRQ_REG_NUM (23)
+#define CIRQ_SPI_START (96)
+
+/*******************************************************************************
+ * MM IOMMU & SMI related constants
+ ******************************************************************************/
+#define SMI_LARB_0_BASE (IO_PHYS + 0x0c022000)
+#define SMI_LARB_1_BASE (IO_PHYS + 0x0c023000)
+#define SMI_LARB_2_BASE (IO_PHYS + 0x0c102000)
+#define SMI_LARB_3_BASE (IO_PHYS + 0x0c103000)
+#define SMI_LARB_4_BASE (IO_PHYS + 0x04013000)
+#define SMI_LARB_5_BASE (IO_PHYS + 0x04f02000)
+#define SMI_LARB_6_BASE (IO_PHYS + 0x04f03000)
+#define SMI_LARB_7_BASE (IO_PHYS + 0x04e04000)
+#define SMI_LARB_9_BASE (IO_PHYS + 0x05001000)
+#define SMI_LARB_10_BASE (IO_PHYS + 0x05120000)
+#define SMI_LARB_11A_BASE (IO_PHYS + 0x05230000)
+#define SMI_LARB_11B_BASE (IO_PHYS + 0x05530000)
+#define SMI_LARB_11C_BASE (IO_PHYS + 0x05630000)
+#define SMI_LARB_12_BASE (IO_PHYS + 0x05340000)
+#define SMI_LARB_13_BASE (IO_PHYS + 0x06001000)
+#define SMI_LARB_14_BASE (IO_PHYS + 0x06002000)
+#define SMI_LARB_15_BASE (IO_PHYS + 0x05140000)
+#define SMI_LARB_16A_BASE (IO_PHYS + 0x06008000)
+#define SMI_LARB_16B_BASE (IO_PHYS + 0x0600a000)
+#define SMI_LARB_17A_BASE (IO_PHYS + 0x06009000)
+#define SMI_LARB_17B_BASE (IO_PHYS + 0x0600b000)
+#define SMI_LARB_19_BASE (IO_PHYS + 0x0a010000)
+#define SMI_LARB_21_BASE (IO_PHYS + 0x0802e000)
+#define SMI_LARB_23_BASE (IO_PHYS + 0x0800d000)
+#define SMI_LARB_27_BASE (IO_PHYS + 0x07201000)
+#define SMI_LARB_28_BASE (IO_PHYS + 0x00000000)
+#define SMI_LARB_REG_RNG_SIZE (0x1000)
+
+/*******************************************************************************
+ * DP related constants
+ ******************************************************************************/
+#define EDP_SEC_BASE (IO_PHYS + 0x0C504000)
+#define DP_SEC_BASE (IO_PHYS + 0x0C604000)
+#define EDP_SEC_SIZE (0x1000)
+#define DP_SEC_SIZE (0x1000)
+
+/*******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_HZ (13000000)
+#define SYS_COUNTER_FREQ_IN_MHZ (13)
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+#define PLATFORM_STACK_SIZE (0x800)
+
+#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
+
+#define PLAT_MAX_PWR_LVL U(3)
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(9)
+
+#define PLATFORM_SYSTEM_COUNT U(1)
+#define PLATFORM_MCUSYS_COUNT U(1)
+#define PLATFORM_CLUSTER_COUNT U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT U(8)
+#define PLATFORM_CLUSTER1_CORE_COUNT U(0)
+
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER U(8)
+
+#define SOC_CHIP_ID U(0x8188)
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+#define TZRAM_BASE (0x54600000)
+#define TZRAM_SIZE (0x00030000)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if
+ * present). BL31_BASE is calculated using the current BL3-1 debug size plus a
+ * little space for growth.
+ */
+#define BL31_BASE (TZRAM_BASE + 0x1000)
+#define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#define MAX_XLAT_TABLES (16)
+#define MAX_MMAP_REGIONS (16)
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT (6)
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/include/mtk_mmap_pool.h b/plat/mediatek/include/mtk_mmap_pool.h
new file mode 100644
index 0000000..99d1bff
--- /dev/null
+++ b/plat/mediatek/include/mtk_mmap_pool.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_MMAP_POOL_H
+#define MTK_MMAP_POOL_H
+
+#include <cdefs.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
+
+struct mtk_mmap_descriptor {
+ const char *mmap_name;
+ const mmap_region_t *mmap_ptr;
+ const uint32_t mmap_size;
+};
+
+#define MTK_MMAP_SECTION \
+ __used \
+ __aligned(sizeof(void *)) \
+ __section(".mtk_mmap_lists")
+
+#define DECLARE_MTK_MMAP_REGIONS(_mmap_array) \
+ static const struct mtk_mmap_descriptor _mtk_mmap_descriptor_##_mmap_array \
+ __used \
+ __aligned(sizeof(void *)) \
+ __section(".mtk_mmap_pool") \
+ = { \
+ .mmap_name = #_mmap_array, \
+ .mmap_ptr = _mmap_array, \
+ .mmap_size = ARRAY_SIZE(_mmap_array) \
+ }
+
+#define MAP_BL_RW MAP_REGION_FLAT( \
+ DATA_START, \
+ BL_END - DATA_START, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#if SEPARATE_CODE_AND_RODATA
+#define MAP_BL_RO \
+ MAP_REGION_FLAT( \
+ BL_CODE_BASE, \
+ BL_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE), \
+ MAP_REGION_FLAT( \
+ BL_RO_DATA_BASE, \
+ BL_RO_DATA_END - BL_RO_DATA_BASE, \
+ MT_RO_DATA | MT_SECURE)
+#else
+#define MAP_BL_RO MAP_REGION_FLAT(BL_CODE_BASE, \
+ BL_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE)
+#endif
+
+void mtk_xlat_init(const mmap_region_t *bl_regions);
+
+#endif /* MTK_MMAP_POOL_H */
diff --git a/plat/mediatek/include/mtk_sip_def.h b/plat/mediatek/include/mtk_sip_def.h
new file mode 100644
index 0000000..907f0c1
--- /dev/null
+++ b/plat/mediatek/include/mtk_sip_def.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_SIP_DEF_H
+#define MTK_SIP_DEF_H
+
+/* Define SiP SMC ID here */
+#define MTK_SIP_SMC_FROM_NS_EL1_TABLE(_func) \
+ _func(MTK_SIP_KERNEL_TIME_SYNC, 0x202) \
+ _func(MTK_SIP_KERNEL_DFD, 0x205) \
+ _func(MTK_SIP_KERNEL_MSDC, 0x273) \
+ _func(MTK_SIP_VCORE_CONTROL, 0x506) \
+ _func(MTK_SIP_IOMMU_CONTROL, 0x514) \
+ _func(MTK_SIP_APUSYS_CONTROL, 0x51E) \
+ _func(MTK_SIP_DP_CONTROL, 0x523) \
+ _func(MTK_SIP_KERNEL_GIC_OP, 0x526)
+
+#define MTK_SIP_SMC_FROM_BL33_TABLE(_func) \
+ _func(MTK_SIP_KERNEL_BOOT, 0x115)
+
+#endif /* MTK_SIP_DEF_H */
diff --git a/plat/mediatek/include/mtk_sip_svc.h b/plat/mediatek/include/mtk_sip_svc.h
new file mode 100644
index 0000000..ce51048
--- /dev/null
+++ b/plat/mediatek/include/mtk_sip_svc.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MTK_SIP_SVC_H
+#define MTK_SIP_SVC_H
+
+#include <stdint.h>
+#include <lib/smccc.h>
+#include <mtk_sip_def.h>
+
+/* SMC function IDs for SiP Service queries */
+#define SIP_SVC_CALL_COUNT U(0x8200ff00)
+#define SIP_SVC_UID U(0x8200ff01)
+/* 0x8200ff02 is reserved */
+#define SIP_SVC_VERSION U(0x8200ff03)
+
+/* MediaTek SiP Service Calls version numbers */
+#define MTK_SIP_SVC_VERSION_MAJOR U(0x0)
+#define MTK_SIP_SVC_VERSION_MINOR U(0x1)
+
+/* Number of MediaTek SiP Calls implemented */
+#define MTK_COMMON_SIP_NUM_CALLS U(4)
+
+/* MediaTek SiP Service Calls function IDs */
+#define MTK_SIP_SET_AUTHORIZED_SECURE_REG U(0x82000001)
+
+#define SMC_ID_EXPAND_AS_ENUM(_smc_id, _smc_num) \
+ _smc_id##_AARCH32 = ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+ ((0) << FUNCID_CC_SHIFT) | \
+ (OEN_SIP_START << FUNCID_OEN_SHIFT) | \
+ ((_smc_num) << FUNCID_NUM_SHIFT)), \
+ _smc_id##_AARCH64 = ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+ ((1) << FUNCID_CC_SHIFT) | \
+ (OEN_SIP_START << FUNCID_OEN_SHIFT) | \
+ ((_smc_num) << FUNCID_NUM_SHIFT)),
+
+#define SMC_ID_EXPAND_AS_EXTERN_SMC_INDEX(_smc_id, _smc_num) \
+ extern short _smc_id##_descriptor_index;
+
+/* Bind SMC handler with SMC ID */
+#define DECLARE_SMC_HANDLER(_smc_id, _smc_handler) \
+ const struct smc_descriptor _smc_id##_descriptor \
+ __used \
+ __aligned(sizeof(void *)) \
+ __section(".mtk_smc_descriptor_pool") = { \
+ .smc_handler = _smc_handler, \
+ .smc_name = #_smc_id, \
+ .smc_id_aarch32 = _smc_id##_AARCH32, \
+ .smc_id_aarch64 = _smc_id##_AARCH64, \
+ .smc_descriptor_index = &_smc_id##_descriptor_index \
+ }
+
+MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_EXTERN_SMC_INDEX);
+MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_EXTERN_SMC_INDEX);
+
+/* Expand SiP SMC ID table as enum */
+enum {
+ MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_ENUM)
+ MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_ENUM)
+ MTK_SIP_SMC_MAX_NUMBER
+};
+
+/* MediaTek SiP Calls error code */
+enum {
+ MTK_SIP_E_SUCCESS = 0,
+ MTK_SIP_E_INVALID_PARAM = -1,
+ MTK_SIP_E_NOT_SUPPORTED = -2,
+ MTK_SIP_E_INVALID_RANGE = -3,
+ MTK_SIP_E_PERMISSION_DENY = -4,
+ MTK_SIP_E_LOCK_FAIL = -5,
+};
+
+struct smccc_res {
+ uint64_t a1;
+ uint64_t a2;
+ uint64_t a3;
+};
+
+typedef uintptr_t (*smc_handler_t)(u_register_t,
+ u_register_t,
+ u_register_t,
+ u_register_t,
+ void *,
+ struct smccc_res *);
+
+struct smc_descriptor {
+ smc_handler_t smc_handler;
+ const uint32_t smc_id_aarch32;
+ const uint32_t smc_id_aarch64;
+ const char *smc_name;
+ short *const smc_descriptor_index;
+};
+
+/*
+ * This function should be implemented in MediaTek SOC directory. It fullfills
+ * MTK_SIP_SET_AUTHORIZED_SECURE_REG SiP call by checking the sreg with the
+ * predefined secure register list, if a match was found, set val to sreg.
+ *
+ * Return MTK_SIP_E_SUCCESS on success, and MTK_SIP_E_INVALID_PARAM on failure.
+ */
+uint64_t mt_sip_set_authorized_sreg(uint32_t sreg, uint32_t val);
+
+#endif /* MTK_SIP_SVC_H */
diff --git a/plat/mediatek/include/plat.ld.rodata.inc b/plat/mediatek/include/plat.ld.rodata.inc
new file mode 100644
index 0000000..06ad491
--- /dev/null
+++ b/plat/mediatek/include/plat.ld.rodata.inc
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_LD_RODATA_INC
+#define PLAT_LD_RODATA_INC
+
+#include <lib/mtk_init/mtk_init.h>
+ . = ALIGN(32);
+ INIT_CALL_TABLE(EXPAND_AS_LINK_SECTION);
+ __MTK_PLAT_INITCALL_END__ = .;
+ . = ALIGN(32);
+ __MTK_MMAP_POINTER_POOL_START__ = .;
+ KEEP(*(.mtk_mmap_pool))
+ __MTK_MMAP_POINTER_POOL_END_UNALIGNED__ = .;
+ . = ALIGN(8);
+ __MTK_MMAP_POOL_START__ = .;
+ KEEP(*(.mtk_mmap_lists))
+ __MTK_MMAP_POOL_END_UNALIGNED__ = .;
+ . = ALIGN(32);
+ __MTK_SMC_POOL_START__ = .;
+ KEEP(*(.mtk_smc_descriptor_pool))
+ __MTK_SMC_POOL_END_UNALIGNED__ = .;
+ . = ALIGN(8);
+#include <vendor_pubsub_events.h>
+ *(mtk_plat_ro)
+
+#endif /* PLAT_LD_RODATA_INC */
diff --git a/plat/mediatek/include/vendor_pubsub_events.h b/plat/mediatek/include/vendor_pubsub_events.h
new file mode 100644
index 0000000..cb8d878
--- /dev/null
+++ b/plat/mediatek/include/vendor_pubsub_events.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VENDOR_PUBSUB_EVENTS_H
+#define VENDOR_PUBSUB_EVENTS_H
+
+#include <lib/el3_runtime/pubsub.h>
+
+REGISTER_PUBSUB_EVENT(lpm_publish_event);
+REGISTER_PUBSUB_EVENT(suspend_publish_event);
+REGISTER_PUBSUB_EVENT(mt_cpupm_publish_pwr_on);
+REGISTER_PUBSUB_EVENT(mt_cpupm_publish_pwr_off);
+REGISTER_PUBSUB_EVENT(mt_cpupm_publish_afflv_pwr_on);
+REGISTER_PUBSUB_EVENT(mt_cpupm_publish_afflv_pwr_off);
+REGISTER_PUBSUB_EVENT(publish_check_wakeup_irq);
+REGISTER_PUBSUB_EVENT(watchdog_timeout);
+
+#endif /* VENDOR_PUBSUB_EVENTS_H */
diff --git a/plat/mediatek/lib/mtk_init/mtk_init.c b/plat/mediatek/lib/mtk_init/mtk_init.c
new file mode 100644
index 0000000..2289659
--- /dev/null
+++ b/plat/mediatek/lib/mtk_init/mtk_init.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/utils_def.h>
+#include <lib/mtk_init/mtk_init.h>
+
+INIT_CALL_TABLE(EXPAND_AS_EXTERN);
+extern struct initcall __MTK_PLAT_INITCALL_END__[];
+
+struct initcall *initcall_list[] = {
+ INIT_CALL_TABLE(EXPAND_AS_SYMBOL_ARR)
+ __MTK_PLAT_INITCALL_END__
+};
+
+void mtk_init_one_level(uint32_t level)
+{
+ const struct initcall *entry;
+ int error;
+
+ if (level >= MTK_INIT_LVL_MAX) {
+ ERROR("invalid level:%u\n", level);
+ panic();
+ }
+
+ INFO("init calling level:%u\n", level);
+ for (entry = initcall_list[level];
+ (entry != NULL) && (entry < initcall_list[level + 1]);
+ entry++) {
+ INFO("calling %s\n", entry->name);
+ error = entry->fn();
+ if (error != 0) {
+ ERROR("init %s fail, errno:%d\n", entry->name, error);
+ }
+ }
+}
diff --git a/plat/mediatek/lib/mtk_init/mtk_mmap_init.c b/plat/mediatek/lib/mtk_init/mtk_mmap_init.c
new file mode 100644
index 0000000..e3dada0
--- /dev/null
+++ b/plat/mediatek/lib/mtk_init/mtk_mmap_init.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <mtk_mmap_pool.h>
+
+IMPORT_SYM(uintptr_t, __MTK_MMAP_POINTER_POOL_START__, MTK_MMAP_POINTER_POOL_START);
+IMPORT_SYM(uintptr_t, __MTK_MMAP_POINTER_POOL_END_UNALIGNED__, MTK_MMAP_POINTER_POOL_END_UNALIGNED);
+IMPORT_SYM(uintptr_t, __RW_START__, RW_START);
+IMPORT_SYM(uintptr_t, __DATA_START__, DATA_START);
+
+#define MAP_MTK_SECTIONS MAP_REGION_FLAT(RW_START, \
+ DATA_START - RW_START, \
+ MT_MEMORY | MT_RO | MT_SECURE)
+
+
+static void print_mmap(const mmap_region_t *regions)
+{
+ while (regions->size != 0U) {
+ VERBOSE("Region: 0x%lx - 0x%lx has attributes 0x%x\n",
+ regions->base_va,
+ regions->base_va + regions->size,
+ regions->attr);
+ regions++;
+ }
+}
+
+void mtk_xlat_init(const mmap_region_t *bl_regions)
+{
+ struct mtk_mmap_descriptor *iter;
+ const mmap_region_t *regions = bl_regions;
+
+ print_mmap(regions);
+ mmap_add(bl_regions);
+ if (MTK_MMAP_POINTER_POOL_START != MTK_MMAP_POINTER_POOL_END_UNALIGNED) {
+ for (iter = (struct mtk_mmap_descriptor *)MTK_MMAP_POINTER_POOL_START;
+ (char *)iter < (char *)MTK_MMAP_POINTER_POOL_END_UNALIGNED;
+ iter++) {
+ regions = iter->mmap_ptr;
+ INFO("mmap_name: %s\n", iter->mmap_name);
+ INFO("mmap_size: 0x%x\n", iter->mmap_size);
+ print_mmap(regions);
+ mmap_add(regions);
+ }
+ }
+ init_xlat_tables();
+ enable_mmu_el3(0);
+}
diff --git a/plat/mediatek/lib/mtk_init/rules.mk b/plat/mediatek/lib/mtk_init/rules.mk
new file mode 100644
index 0000000..cc6ca95
--- /dev/null
+++ b/plat/mediatek/lib/mtk_init/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := mtk_init
+
+LOCAL_SRCS-y := $(LOCAL_DIR)/mtk_init.c
+LOCAL_SRCS-y += $(LOCAL_DIR)/mtk_mmap_init.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/lib/pm/mtk_pm.c b/plat/mediatek/lib/pm/mtk_pm.c
new file mode 100644
index 0000000..632a1e7
--- /dev/null
+++ b/plat/mediatek/lib/pm/mtk_pm.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/psci/psci.h>
+
+static const plat_psci_ops_t plat_psci_ops = {
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ *psci_ops = &plat_psci_ops;
+
+ return 0;
+}
diff --git a/plat/mediatek/lib/pm/rules.mk b/plat/mediatek/lib/pm/rules.mk
new file mode 100644
index 0000000..77d0408
--- /dev/null
+++ b/plat/mediatek/lib/pm/rules.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := pm
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_pm.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/mt6795/aarch64/plat_helpers.S b/plat/mediatek/mt6795/aarch64/plat_helpers.S
deleted file mode 100644
index aaddb2b..0000000
--- a/plat/mediatek/mt6795/aarch64/plat_helpers.S
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#include <arch.h>
-#include <asm_macros.S>
-#include <platform_def.h>
-
- .globl plat_secondary_cold_boot_setup
- .globl plat_report_exception
- .globl platform_is_primary_cpu
- .globl plat_crash_console_init
- .globl plat_crash_console_putc
- .globl plat_crash_console_flush
- .globl platform_mem_init
-
-
- .macro crash_ram_log
- /*
- * Check teearg->atf_log_buf_size.
- * Exit if atf_log_buf_size equals 0
- */
- adr x2, ptr_atf_crash_flag
- ldr x2, [x2]
- /* exit if ptr_atf_crash_flag equals NULL */
- cbz x2, exit_putc
-
- /*
- * set atf crash magic number
- */
-1:
- adr x2, ptr_atf_crash_flag
- ldr x2, [x2]
- mov_imm x1, 0xdead1abf
- /* p_atf_log_ctrl->atf_crash_flag = 0xdead1abf */
- str w1, [x2]
- /* can't use w3 return addr, w4, start of buffer addr */
- ldr w2, [x2]
- cmp w2, w1
- b.ne 1b
-
- /*
- * get cpu id
- */
- mrs x1, mpidr_el1
- /* refer to platform_get_core_pos */
- and x2, x1, #MPIDR_CPU_MASK
- and x1, x1, #MPIDR_CLUSTER_MASK
- /* x1 = cpu id (cpu id = aff0 + aff1*4 ) */
- add x1, x2, x1, LSR #6
-
- adr x2, ptr_atf_except_write_pos_per_cpu
- ldr x2, [x2]
- /*
- * plus (cpu_id * 8)-->
- * &p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id]
- * x2 = &p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id];
- */
- add x2, x2, x1, LSL # 3
- /* log write */
- /* w1 = p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id] */
- ldr x1, [x2]
- /* *x1 = w0-->
- * *(p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id]) = c)
- */
- strb w0, [x1]
- /* w1++ */
- add x1, x1, #1
- /* p_atf_log_ctrl->atf_except_write_pos_per_cpu[cpu_id] = w1 */
- str x1, [x2]
-exit_putc:
- .endm
-
- /* -----------------------------------------------------
- * void plat_secondary_cold_boot_setup (void);
- *
- * This function performs any platform specific actions
- * needed for a secondary cpu after a cold reset e.g
- * mark the cpu's presence, mechanism to place it in a
- * holding pen etc.
- * -----------------------------------------------------
- */
-func plat_secondary_cold_boot_setup
- /* Do not do cold boot for secondary CPU */
-cb_panic:
- b cb_panic
-endfunc plat_secondary_cold_boot_setup
-
-func platform_is_primary_cpu
- and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
- cmp x0, #PLAT_PRIMARY_CPU
- cset x0, eq
- ret
-endfunc platform_is_primary_cpu
-
- /* ---------------------------------------------
- * int plat_crash_console_init(void)
- * Function to initialize the crash console
- * without a C Runtime to print crash report.
- * Clobber list : x0, x1, x2
- * ---------------------------------------------
- */
-func plat_crash_console_init
- mov_imm x0, UART0_BASE
- mov_imm x1, UART_CLOCK
- mov_imm x2, UART_BAUDRATE
- b console_init
- ret
-endfunc plat_crash_console_init
-
- /* ---------------------------------------------
- * int plat_crash_console_putc(void)
- * Function to print a character on the crash
- * console without a C Runtime.
- * Clobber list : x1, x2
- * ---------------------------------------------
- */
-func plat_crash_console_putc
- mov_imm x1, UART0_BASE
- b console_core_putc
- ret
-endfunc plat_crash_console_putc
-
- /* ---------------------------------------------
- * void plat_crash_console_flush(int c)
- * Function to force a write of all buffered
- * data that hasn't been output.
- * Out : void.
- * Clobber list : x0, x1
- * ---------------------------------------------
- */
-func plat_crash_console_flush
- mov_imm x0, UART0_BASE
- b console_core_flush
-endfunc plat_crash_console_flush
-
- /* --------------------------------------------------------
- * void platform_mem_init (void);
- *
- * Any memory init, relocation to be done before the
- * platform boots. Called very early in the boot process.
- * --------------------------------------------------------
- */
-func platform_mem_init
- ret
-endfunc platform_mem_init
-
diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S
deleted file mode 100644
index 3d881fc..0000000
--- a/plat/mediatek/mt6795/bl31.ld.S
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <common/bl_common.ld.h>
-#include <lib/xlat_tables/xlat_tables_defs.h>
-
-OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
-OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
-ENTRY(bl31_entrypoint)
-
-
-MEMORY {
- RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_TZRAM_SIZE
- RAM2 (rwx): ORIGIN = TZRAM2_BASE, LENGTH = TZRAM2_SIZE
-}
-
-
-SECTIONS
-{
- . = BL31_BASE;
-
- ASSERT(. == ALIGN(2048),
- "vector base is not aligned on a 2K boundary.")
-
- __RO_START__ = .;
- vector . : {
- *(.vectors)
- } >RAM
-
- ASSERT(. == ALIGN(PAGE_SIZE),
- "BL31_BASE address is not aligned on a page boundary.")
-
- ro . : {
- *bl31_entrypoint.o(.text*)
- *(.text*)
- *(.rodata*)
-
- RODATA_COMMON
-
- __RO_END_UNALIGNED__ = .;
- /*
- * Memory page(s) mapped to this section will be marked as read-only,
- * executable. No RW data from the next section must creep in.
- * Ensure the rest of the current memory page is unused.
- */
- . = ALIGN(PAGE_SIZE);
- __RO_END__ = .;
- } >RAM
-
- ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
- "cpu_ops not defined for this platform.")
-
- /*
- * Define a linker symbol to mark start of the RW memory area for this
- * image.
- */
- __RW_START__ = . ;
-
- DATA_SECTION >RAM
-
-#ifdef BL31_PROGBITS_LIMIT
- ASSERT(. <= BL31_PROGBITS_LIMIT, "BL3-1 progbits has exceeded its limit.")
-#endif
-
- STACK_SECTION >RAM
- BSS_SECTION >RAM
- __RW_END__ = __BSS_END__;
-
- ASSERT(. <= BL31_LIMIT, "BL3-1 image has exceeded its limit.")
-
- XLAT_TABLE_SECTION >RAM2
-
-#if USE_COHERENT_MEM
- /*
- * The base address of the coherent memory section must be page-aligned (4K)
- * to guarantee that the coherent data are stored on their own pages and
- * are not mixed with normal data. This is required to set up the correct
- * memory attributes for the coherent data page tables.
- */
- coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
- __COHERENT_RAM_START__ = .;
- /*
- * Bakery locks are stored in coherent memory
- *
- * Each lock's data is contiguous and fully allocated by the compiler
- */
- *(bakery_lock)
- *(tzfw_coherent_mem)
- __COHERENT_RAM_END_UNALIGNED__ = .;
- /*
- * Memory page(s) mapped to this section will be marked
- * as device memory. No other unexpected data must creep in.
- * Ensure the rest of the current memory page is unused.
- */
- . = ALIGN(PAGE_SIZE);
- __COHERENT_RAM_END__ = .;
- } >RAM2
-#endif
-
- /*
- * Define a linker symbol to mark end of the RW memory area for this
- * image.
- */
- __BL31_END__ = .;
-
- __BSS_SIZE__ = SIZEOF(.bss);
-#if USE_COHERENT_MEM
- __COHERENT_RAM_UNALIGNED_SIZE__ =
- __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
-
- ASSERT(. <= TZRAM2_LIMIT, "TZRAM2 image has exceeded its limit.")
-}
diff --git a/plat/mediatek/mt6795/bl31_plat_setup.c b/plat/mediatek/mt6795/bl31_plat_setup.c
deleted file mode 100644
index 2051fe7..0000000
--- a/plat/mediatek/mt6795/bl31_plat_setup.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <arch_helpers.h>
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <drivers/arm/cci.h>
-#include <drivers/console.h>
-#include <drivers/generic_delay_timer.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/mmio.h>
-#include <lib/utils_def.h>
-#include <lib/xlat_tables/xlat_tables.h>
-#include <plat/common/common_def.h>
-#include <plat/common/platform.h>
-
-#include <mcucfg.h>
-#include <mt_cpuxgpt.h>
-#include <mtk_plat_common.h>
-#include <mtk_sip_svc.h>
-#include <plat_private.h>
-
-/*******************************************************************************
- * Declarations of linker defined symbols which will help us find the layout
- * of trusted SRAM
- ******************************************************************************/
-/*
- * The next 2 constants identify the extents of the code & RO data region.
- * These addresses are used by the MMU setup code and therefore they must be
- * page-aligned. It is the responsibility of the linker script to ensure that
- * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
- */
-IMPORT_SYM(unsigned long, __RO_START__, BL31_RO_BASE);
-IMPORT_SYM(unsigned long, __RO_END__, BL31_RO_LIMIT);
-
-/*
- * Placeholder variables for copying the arguments that have been passed to
- * BL3-1 from BL2.
- */
-static entry_point_info_t bl32_image_ep_info;
-static entry_point_info_t bl33_image_ep_info;
-
-static const int cci_map[] = {
- PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX,
- PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX
-};
-
-static uint32_t cci_map_length = ARRAY_SIZE(cci_map);
-
-/* Table of regions to map using the MMU. */
-static const mmap_region_t plat_mmap[] = {
- /* for TF text, RO, RW */
- MAP_REGION_FLAT(MTK_DEV_RNG0_BASE, MTK_DEV_RNG0_SIZE,
- MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(MTK_DEV_RNG1_BASE, MTK_DEV_RNG1_SIZE,
- MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(RAM_CONSOLE_BASE & ~(PAGE_SIZE_MASK), RAM_CONSOLE_SIZE,
- MT_DEVICE | MT_RW | MT_NS),
- { 0 }
-
-};
-
-/*******************************************************************************
- * Macro generating the code for the function setting up the pagetables as per
- * the platform memory map & initialize the mmu, for the given exception level
- ******************************************************************************/
-#define DEFINE_CONFIGURE_MMU_EL(_el) \
- void plat_configure_mmu_el ## _el(unsigned long total_base, \
- unsigned long total_size, \
- unsigned long ro_start, \
- unsigned long ro_limit, \
- unsigned long coh_start, \
- unsigned long coh_limit) \
- { \
- mmap_add_region(total_base, total_base, \
- total_size, \
- MT_MEMORY | MT_RW | MT_SECURE); \
- mmap_add_region(ro_start, ro_start, \
- ro_limit - ro_start, \
- MT_MEMORY | MT_RO | MT_SECURE); \
- mmap_add_region(coh_start, coh_start, \
- coh_limit - coh_start, \
- MT_DEVICE | MT_RW | MT_SECURE); \
- mmap_add(plat_mmap); \
- init_xlat_tables(); \
- \
- enable_mmu_el ## _el(0); \
- }
-
-/* Define EL3 variants of the function initialising the MMU */
-DEFINE_CONFIGURE_MMU_EL(3)
-
-unsigned int plat_get_syscnt_freq2(void)
-{
- return SYS_COUNTER_FREQ_IN_TICKS;
-}
-
-void plat_cci_init(void)
-{
- /* Initialize CCI driver */
- cci_init(PLAT_MT_CCI_BASE, cci_map, cci_map_length);
-}
-
-void plat_cci_enable(void)
-{
- /*
- * Enable CCI coherency for this cluster.
- * No need for locks as no other cpu is active at the moment.
- */
- cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
-}
-
-void plat_cci_disable(void)
-{
- cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
-}
-
-
-static void platform_setup_cpu(void)
-{
- /* setup big cores */
- mmio_write_32((uintptr_t)&mt6795_mcucfg->mp1_config_res,
- MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK |
- MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK |
- MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK |
- MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK |
- MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK);
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_miscdbg, MP1_AINACTS);
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_clkenm_div,
- MP1_SW_CG_GEN);
- mmio_clrbits_32((uintptr_t)&mt6795_mcucfg->mp1_rst_ctl,
- MP1_L2RSTDISABLE);
-
- /* set big cores arm64 boot mode */
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_cpucfg,
- MP1_CPUCFG_64BIT);
-
- /* set LITTLE cores arm64 boot mode */
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp0_rv_addr[0].rv_addr_hw,
- MP0_CPUCFG_64BIT);
-}
-
-/*******************************************************************************
- * Return a pointer to the 'entry_point_info' structure of the next image for
- * the security state specified. BL33 corresponds to the non-secure image type
- * while BL32 corresponds to the secure image type. A NULL pointer is returned
- * if the image does not exist.
- ******************************************************************************/
-entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
-{
- entry_point_info_t *next_image_info;
-
- next_image_info = (type == NON_SECURE) ?
- &bl33_image_ep_info : &bl32_image_ep_info;
-
- /* None of the images on this platform can have 0x0 as the entrypoint */
- if (next_image_info->pc)
- return next_image_info;
- else
- return NULL;
-}
-
-/*******************************************************************************
- * Perform any BL3-1 early platform setup. Here is an opportunity to copy
- * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before they
- * are lost (potentially). This needs to be done before the MMU is initialized
- * so that the memory layout can be used while creating page tables.
- * BL2 has flushed this information to memory, so we are guaranteed to pick up
- * good data.
- ******************************************************************************/
-void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
- u_register_t arg2, u_register_t arg3)
-{
- struct mtk_bl_param_t *pmtk_bl_param = (struct mtk_bl_param_t *)arg0;
- struct atf_arg_t *teearg;
- unsigned long long normal_base;
- unsigned long long atf_base;
-
- assert(pmtk_bl_param != NULL);
- /*
- * Mediatek preloader(i.e, BL2) is in 32 bit state, high 32bits
- * of 64 bit GP registers are UNKNOWN if CPU warm reset from 32 bit
- * to 64 bit state. So we need to clear high 32bit,
- * which may be random value.
- */
- pmtk_bl_param =
- (struct mtk_bl_param_t *)((uint64_t)pmtk_bl_param & 0x00000000ffffffff);
-
- teearg = (struct atf_arg_t *)pmtk_bl_param->tee_info_addr;
-
- console_init(teearg->atf_log_port, UART_CLOCK, UART_BAUDRATE);
- memcpy((void *)>eearg, (void *)teearg, sizeof(struct atf_arg_t));
-
- normal_base = 0;
- /* in ATF boot time, timer for cntpct_el0 is not initialized
- * so it will not count now.
- */
- atf_base = read_cntpct_el0();
- sched_clock_init(normal_base, atf_base);
-
- VERBOSE("bl31_setup\n");
-
- /* Populate entry point information for BL3-2 and BL3-3 */
- SET_PARAM_HEAD(&bl32_image_ep_info,
- PARAM_EP,
- VERSION_1,
- 0);
- SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
- bl32_image_ep_info.pc = BL32_BASE;
-
- SET_PARAM_HEAD(&bl33_image_ep_info,
- PARAM_EP,
- VERSION_1,
- 0);
- /*
- * Tell BL3-1 where the non-trusted software image
- * is located and the entry state information
- */
- /* BL33_START_ADDRESS */
- bl33_image_ep_info.pc = pmtk_bl_param->bl33_start_addr;
- bl33_image_ep_info.spsr = plat_get_spsr_for_bl33_entry();
- bl33_image_ep_info.args.arg4 = pmtk_bl_param->bootarg_loc;
- bl33_image_ep_info.args.arg5 = pmtk_bl_param->bootarg_size;
- SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-}
-/*******************************************************************************
- * Perform any BL3-1 platform setup code
- ******************************************************************************/
-
-void bl31_platform_setup(void)
-{
- platform_setup_cpu();
-
- generic_delay_timer_init();
-
- plat_mt_gic_driver_init();
- /* Initialize the gic cpu and distributor interfaces */
- plat_mt_gic_init();
-
- /* Topologies are best known to the platform. */
- mt_setup_topology();
-}
-/*******************************************************************************
- * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
- * Init MTK propiartary log buffer control field.
- ******************************************************************************/
-void bl31_plat_arch_setup(void)
-{
- /* Enable non-secure access to CCI-400 registers */
- mmio_write_32(CCI400_BASE + CCI_SEC_ACCESS_OFFSET, 0x1);
-
- plat_cci_init();
- plat_cci_enable();
-
- if (gteearg.atf_log_buf_size != 0) {
- INFO("mmap atf buffer : 0x%x, 0x%x\n\r",
- gteearg.atf_log_buf_start,
- gteearg.atf_log_buf_size);
-
- mmap_add_region(
- gteearg.atf_log_buf_start &
- ~(PAGE_SIZE_2MB_MASK),
- gteearg.atf_log_buf_start &
- ~(PAGE_SIZE_2MB_MASK),
- PAGE_SIZE_2MB,
- MT_DEVICE | MT_RW | MT_NS);
-
- INFO("mmap atf buffer (force 2MB aligned):0x%x, 0x%x\n",
- (gteearg.atf_log_buf_start & ~(PAGE_SIZE_2MB_MASK)),
- PAGE_SIZE_2MB);
- }
- /*
- * add TZRAM_BASE to memory map
- * then set RO and COHERENT to different attribute
- */
- plat_configure_mmu_el3(
- (TZRAM_BASE & ~(PAGE_SIZE_MASK)),
- (TZRAM_SIZE & ~(PAGE_SIZE_MASK)),
- (BL31_RO_BASE & ~(PAGE_SIZE_MASK)),
- BL31_RO_LIMIT,
- BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END);
- /* Initialize for ATF log buffer */
- if (gteearg.atf_log_buf_size != 0) {
- gteearg.atf_aee_debug_buf_size = ATF_AEE_BUFFER_SIZE;
- gteearg.atf_aee_debug_buf_start =
- gteearg.atf_log_buf_start +
- gteearg.atf_log_buf_size - ATF_AEE_BUFFER_SIZE;
- INFO("ATF log service is registered (0x%x, aee:0x%x)\n",
- gteearg.atf_log_buf_start,
- gteearg.atf_aee_debug_buf_start);
- } else{
- gteearg.atf_aee_debug_buf_size = 0;
- gteearg.atf_aee_debug_buf_start = 0;
- }
-
- /* Platform code before bl31_main */
- /* compatible to the earlier chipset */
-
- /* Show to ATF log buffer & UART */
- INFO("BL3-1: %s\n", version_string);
- INFO("BL3-1: %s\n", build_message);
-
-}
-#if 0
-/* MTK Define */
-#define ACTLR_CPUECTLR_BIT (1 << 1)
-
-void enable_ns_access_to_cpuectlr(void)
-{
- unsigned int next_actlr;
-
-
- /* ACTLR_EL1 do not implement CUPECTLR */
- next_actlr = read_actlr_el2();
- next_actlr |= ACTLR_CPUECTLR_BIT;
- write_actlr_el2(next_actlr);
-
- next_actlr = read_actlr_el3();
- next_actlr |= ACTLR_CPUECTLR_BIT;
- write_actlr_el3(next_actlr);
-}
-#endif
-/*******************************************************************************
- * This function prepare boot argument for 64 bit kernel entry
- ******************************************************************************/
-static entry_point_info_t *bl31_plat_get_next_kernel64_ep_info(void)
-{
- entry_point_info_t *next_image_info;
- unsigned int mode;
-
- mode = 0;
-
- /* Kernel image is always non-secured */
- next_image_info = &bl33_image_ep_info;
-
- /* Figure out what mode we enter the non-secure world in */
- if (el_implemented(2) != EL_IMPL_NONE) {
- INFO("Kernel_EL2\n");
- mode = MODE_EL2;
- } else{
- INFO("Kernel_EL1\n");
- mode = MODE_EL1;
- }
-
- INFO("Kernel is 64Bit\n");
- next_image_info->spsr =
- SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
- next_image_info->pc = get_kernel_info_pc();
- next_image_info->args.arg0 = get_kernel_info_r0();
- next_image_info->args.arg1 = get_kernel_info_r1();
-
- INFO("pc=0x%lx, r0=0x%lx, r1=0x%lx\n",
- next_image_info->pc,
- next_image_info->args.arg0,
- next_image_info->args.arg1);
-
-
- SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
-
- /* None of the images on this platform can have 0x0 as the entrypoint */
- if (next_image_info->pc)
- return next_image_info;
- else
- return NULL;
-}
-
-/*******************************************************************************
- * This function prepare boot argument for 32 bit kernel entry
- ******************************************************************************/
-static entry_point_info_t *bl31_plat_get_next_kernel32_ep_info(void)
-{
- entry_point_info_t *next_image_info;
- unsigned int mode;
-
- mode = 0;
-
- /* Kernel image is always non-secured */
- next_image_info = &bl33_image_ep_info;
-
- /* Figure out what mode we enter the non-secure world in */
- mode = MODE32_hyp;
- /*
- * TODO: Consider the possibility of specifying the SPSR in
- * the FIP ToC and allowing the platform to have a say as
- * well.
- */
-
- INFO("Kernel is 32Bit\n");
- next_image_info->spsr =
- SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE,
- (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT));
- next_image_info->pc = get_kernel_info_pc();
- next_image_info->args.arg0 = get_kernel_info_r0();
- next_image_info->args.arg1 = get_kernel_info_r1();
- next_image_info->args.arg2 = get_kernel_info_r2();
-
- INFO("pc=0x%lx, r0=0x%lx, r1=0x%lx, r2=0x%lx\n",
- next_image_info->pc,
- next_image_info->args.arg0,
- next_image_info->args.arg1,
- next_image_info->args.arg2);
-
-
- SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE);
-
- /* None of the images on this platform can have 0x0 as the entrypoint */
- if (next_image_info->pc)
- return next_image_info;
- else
- return NULL;
-}
-
-/*******************************************************************************
- * This function prepare boot argument for kernel entrypoint
- ******************************************************************************/
-void bl31_prepare_kernel_entry(uint64_t k32_64)
-{
- entry_point_info_t *next_image_info;
- uint32_t image_type;
-
- /* Determine which image to execute next */
- /* image_type = bl31_get_next_image_type(); */
- image_type = NON_SECURE;
-
- /* Program EL3 registers to enable entry into the next EL */
- if (k32_64 == 0)
- next_image_info = bl31_plat_get_next_kernel32_ep_info();
- else
- next_image_info = bl31_plat_get_next_kernel64_ep_info();
-
- assert(next_image_info);
- assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr));
-
- INFO("BL3-1: Preparing for EL3 exit to %s world, Kernel\n",
- (image_type == SECURE) ? "secure" : "normal");
- INFO("BL3-1: Next image address = 0x%llx\n",
- (unsigned long long) next_image_info->pc);
- INFO("BL3-1: Next image spsr = 0x%x\n", next_image_info->spsr);
- cm_init_my_context(next_image_info);
- cm_prepare_el3_exit(image_type);
-}
diff --git a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c b/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c
deleted file mode 100644
index 3696f8e..0000000
--- a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdint.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <lib/mmio.h>
-#include <plat/common/platform.h>
-
-#include <mt_cpuxgpt.h>
-
-#define CPUXGPT_BASE 0x10200000
-#define INDEX_BASE (CPUXGPT_BASE+0x0674)
-#define CTL_BASE (CPUXGPT_BASE+0x0670)
-
-uint64_t normal_time_base;
-uint64_t atf_time_base;
-
-void sched_clock_init(uint64_t normal_base, uint64_t atf_base)
-{
- normal_time_base = normal_base;
- atf_time_base = atf_base;
-}
-
-uint64_t sched_clock(void)
-{
- uint64_t cval;
-
- cval = (((read_cntpct_el0() - atf_time_base)*1000)/
- SYS_COUNTER_FREQ_IN_MHZ) + normal_time_base;
- return cval;
-}
-
-/*
- * Return: 0 - Trying to disable the CPUXGPT control bit,
- * and not allowed to disable it.
- * Return: 1 - reg_addr is not realted to disable the control bit.
- */
-unsigned char check_cpuxgpt_write_permission(unsigned int reg_addr,
- unsigned int reg_value)
-{
- unsigned int idx;
- unsigned int ctl_val;
-
- if (reg_addr == CTL_BASE) {
- idx = mmio_read_32(INDEX_BASE);
-
- /* idx 0: CPUXGPT system control */
- if (idx == 0) {
- ctl_val = mmio_read_32(CTL_BASE);
- if (ctl_val & 1) {
- /*
- * if enable bit already set,
- * then bit 0 is not allow to set as 0
- */
- if (!(reg_value & 1))
- return 0;
- }
- }
- }
- return 1;
-}
-
diff --git a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.h b/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.h
deleted file mode 100644
index 84df081..0000000
--- a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MT_CPUXGPT_H
-#define MT_CPUXGPT_H
-
-/* REG */
-#define INDEX_CTL_REG 0x000
-#define INDEX_STA_REG 0x004
-#define INDEX_CNT_L_INIT 0x008
-#define INDEX_CNT_H_INIT 0x00C
-
-/* CTL_REG SET */
-#define EN_CPUXGPT 0x01
-#define EN_AHLT_DEBUG 0x02
-#define CLK_DIV1 (0x1 << 8)
-#define CLK_DIV2 (0x2 << 8)
-#define CLK_DIV4 (0x4 << 8)
-#define CLK_DIV_MASK (~(0x7<<8))
-
-void generic_timer_backup(void);
-void sched_clock_init(uint64_t normal_base, uint64_t atf_base);
-uint64_t sched_clock(void);
-
-#endif /* MT_CPUXGPT_H */
diff --git a/plat/mediatek/mt6795/include/mcucfg.h b/plat/mediatek/mt6795/include/mcucfg.h
deleted file mode 100644
index 21c5394..0000000
--- a/plat/mediatek/mt6795/include/mcucfg.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MCUCFG_H
-#define MCUCFG_H
-
-#include <stdint.h>
-
-#include <platform_def.h>
-
-struct mt6795_mcucfg_regs {
- uint32_t mp0_ca7l_cache_config;
- struct {
- uint32_t mem_delsel0;
- uint32_t mem_delsel1;
- } mp0_cpu[4];
- uint32_t mp0_cache_mem_delsel0;
- uint32_t mp0_cache_mem_delsel1;
- uint32_t mp0_axi_config;
- uint32_t mp0_misc_config[2];
- struct {
- uint32_t rv_addr_lw;
- uint32_t rv_addr_hw;
- } mp0_rv_addr[4];
- uint32_t mp0_ca7l_cfg_dis;
- uint32_t mp0_ca7l_clken_ctrl;
- uint32_t mp0_ca7l_rst_ctrl;
- uint32_t mp0_ca7l_misc_config;
- uint32_t mp0_ca7l_dbg_pwr_ctrl;
- uint32_t mp0_rw_rsvd0;
- uint32_t mp0_rw_rsvd1;
- uint32_t mp0_ro_rsvd;
- uint32_t reserved0_0[100];
- uint32_t mp1_cpucfg;
- uint32_t mp1_miscdbg;
- uint32_t reserved0_1[13];
- uint32_t mp1_rst_ctl;
- uint32_t mp1_clkenm_div;
- uint32_t reserved0_2[7];
- uint32_t mp1_config_res;
- uint32_t reserved0_3[13];
- struct {
- uint32_t rv_addr_lw;
- uint32_t rv_addr_hw;
- } mp1_rv_addr[2];
- uint32_t reserved0_4[84];
- uint32_t mp0_rst_status; /* 0x400 */
- uint32_t mp0_dbg_ctrl;
- uint32_t mp0_dbg_flag;
- uint32_t mp0_ca7l_ir_mon;
- struct {
- uint32_t pc_lw;
- uint32_t pc_hw;
- uint32_t fp_arch32;
- uint32_t sp_arch32;
- uint32_t fp_arch64_lw;
- uint32_t fp_arch64_hw;
- uint32_t sp_arch64_lw;
- uint32_t sp_arch64_hw;
- } mp0_dbg_core[4];
- uint32_t dfd_ctrl;
- uint32_t dfd_cnt_l;
- uint32_t dfd_cnt_h;
- uint32_t misccfg_mp0_rw_rsvd;
- uint32_t misccfg_sec_vio_status0;
- uint32_t misccfg_sec_vio_status1;
- uint32_t reserved1[22];
- uint32_t misccfg_rw_rsvd; /* 0x500 */
- uint32_t mcusys_dbg_mon_sel_a;
- uint32_t mcusys_dbg_mon;
- uint32_t reserved2[61];
- uint32_t mcusys_config_a; /* 0x600 */
- uint32_t mcusys_config1_a;
- uint32_t mcusys_gic_peribase_a;
- uint32_t reserved3;
- uint32_t sec_range0_start; /* 0x610 */
- uint32_t sec_range0_end;
- uint32_t sec_range_enable;
- uint32_t reserved4;
- uint32_t int_pol_ctl[8]; /* 0x620 */
- uint32_t aclken_div; /* 0x640 */
- uint32_t pclken_div;
- uint32_t l2c_sram_ctrl;
- uint32_t armpll_jit_ctrl;
- uint32_t cci_addrmap; /* 0x650 */
- uint32_t cci_config;
- uint32_t cci_periphbase;
- uint32_t cci_nevntcntovfl;
- uint32_t cci_clk_ctrl; /* 0x660 */
- uint32_t cci_acel_s1_ctrl;
- uint32_t bus_fabric_dcm_ctrl;
- uint32_t reserved5;
- uint32_t xgpt_ctl; /* 0x670 */
- uint32_t xgpt_idx;
- uint32_t ptpod2_ctl0;
- uint32_t ptpod2_ctl1;
- uint32_t mcusys_revid;
- uint32_t mcusys_rw_rsvd0;
- uint32_t mcusys_rw_rsvd1;
-};
-
-static struct mt6795_mcucfg_regs *const mt6795_mcucfg = (void *)MCUCFG_BASE;
-
-/* cpu boot mode */
-#define MP0_CPUCFG_64BIT_SHIFT 12
-#define MP1_CPUCFG_64BIT_SHIFT 28
-#define MP0_CPUCFG_64BIT (U(0xf) << MP0_CPUCFG_64BIT_SHIFT)
-#define MP1_CPUCFG_64BIT (U(0xf) << MP1_CPUCFG_64BIT_SHIFT)
-
-/* scu related */
-enum {
- MP0_ACINACTM_SHIFT = 4,
- MP1_ACINACTM_SHIFT = 0,
- MP0_ACINACTM = 1 << MP0_ACINACTM_SHIFT,
- MP1_ACINACTM = 1 << MP1_ACINACTM_SHIFT
-};
-
-enum {
- MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT = 0,
- MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT = 4,
- MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT = 8,
- MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT = 12,
- MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT = 16,
-
- MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK =
- 0xf << MP1_DIS_RGU0_WAIT_PD_CPUS_L1_ACK_SHIFT,
- MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK =
- 0xf << MP1_DIS_RGU1_WAIT_PD_CPUS_L1_ACK_SHIFT,
- MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK =
- 0xf << MP1_DIS_RGU2_WAIT_PD_CPUS_L1_ACK_SHIFT,
- MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK =
- 0xf << MP1_DIS_RGU3_WAIT_PD_CPUS_L1_ACK_SHIFT,
- MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK =
- 0xf << MP1_DIS_RGU_NOCPU_WAIT_PD_CPUS_L1_ACK_SHIFT
-};
-
-enum {
- MP1_AINACTS_SHIFT = 4,
- MP1_AINACTS = 1 << MP1_AINACTS_SHIFT
-};
-
-enum {
- MP1_SW_CG_GEN_SHIFT = 12,
- MP1_SW_CG_GEN = 1 << MP1_SW_CG_GEN_SHIFT
-};
-
-enum {
- MP1_L2RSTDISABLE_SHIFT = 14,
- MP1_L2RSTDISABLE = 1 << MP1_L2RSTDISABLE_SHIFT
-};
-
-#endif /* MCUCFG_H */
diff --git a/plat/mediatek/mt6795/include/plat_macros.S b/plat/mediatek/mt6795/include/plat_macros.S
deleted file mode 100644
index d198fdc..0000000
--- a/plat/mediatek/mt6795/include/plat_macros.S
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <drivers/arm/cci.h>
-#include <platform_def.h>
-
-.section .rodata.gic_reg_name, "aS"
-gicc_regs:
- .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
-gicd_pend_reg:
- .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \
- " Offset:\t\t\tvalue\n"
-newline:
- .asciz "\n"
-spacer:
- .asciz ":\t\t0x"
-
- /* ---------------------------------------------
- * The below macro prints out relevant GIC
- * registers whenever an unhandled exception is
- * taken in BL3-1.
- * Clobbers: x0 - x10, x16, x17, sp
- * ---------------------------------------------
- */
- .macro plat_crash_print_regs
- mov_imm x16, BASE_GICD_BASE
- mov_imm x17, BASE_GICC_BASE
- /* Load the gicc reg list to x6 */
- adr x6, gicc_regs
- /* Load the gicc regs to gp regs used by str_in_crash_buf_print */
- ldr w8, [x17, #GICC_HPPIR]
- ldr w9, [x17, #GICC_AHPPIR]
- ldr w10, [x17, #GICC_CTLR]
- /* Store to the crash buf and print to console */
- bl str_in_crash_buf_print
-
- /* Print the GICD_ISPENDR regs */
- add x7, x16, #GICD_ISPENDR
- adr x4, gicd_pend_reg
- bl asm_print_str
-gicd_ispendr_loop:
- sub x4, x7, x16
- cmp x4, #0x280
- b.eq exit_print_gic_regs
- bl asm_print_hex
-
- adr x4, spacer
- bl asm_print_str
-
- ldr x4, [x7], #8
- bl asm_print_hex
-
- adr x4, newline
- bl asm_print_str
- b gicd_ispendr_loop
-exit_print_gic_regs:
- .endm
-
-.section .rodata.cci_reg_name, "aS"
-cci_iface_regs:
- .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
-
- /* ------------------------------------------------
- * The below macro prints out relevant interconnect
- * registers whenever an unhandled exception is
- * taken in BL3-1.
- * Clobbers: x0 - x9, sp
- * ------------------------------------------------
- */
- .macro plat_print_interconnect_regs
- adr x6, cci_iface_regs
- /* Store in x7 the base address of the first interface */
- mov_imm x7, (PLAT_MT_CCI_BASE + SLAVE_IFACE_OFFSET( \
- PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX))
- ldr w8, [x7, #SNOOP_CTRL_REG]
- /* Store in x7 the base address of the second interface */
- mov_imm x7, (PLAT_MT_CCI_BASE + SLAVE_IFACE_OFFSET( \
- PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX))
- ldr w9, [x7, #SNOOP_CTRL_REG]
- /* Store to the crash buf and print to console */
- bl str_in_crash_buf_print
- .endm
diff --git a/plat/mediatek/mt6795/include/plat_private.h b/plat/mediatek/mt6795/include/plat_private.h
deleted file mode 100644
index f7450ca..0000000
--- a/plat/mediatek/mt6795/include/plat_private.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_PRIVATE_H
-#define PLAT_PRIVATE_H
-
-#include <stdint.h>
-
-#include <lib/xlat_tables/xlat_tables.h>
-
-void plat_configure_mmu_el3(unsigned long total_base,
- unsigned long total_size,
- unsigned long,
- unsigned long,
- unsigned long,
- unsigned long);
-
-void plat_cci_init(void);
-void plat_cci_enable(void);
-void plat_cci_disable(void);
-
-/* Declarations for plat_mt_gic.c */
-void plat_mt_gic_init(void);
-
-/* Declarations for plat_topology.c */
-int mt_setup_topology(void);
-void plat_delay_timer_init(void);
-
-void plat_mt_gic_driver_init(void);
-void plat_mt_gic_init(void);
-void plat_mt_gic_cpuif_enable(void);
-void plat_mt_gic_cpuif_disable(void);
-void plat_mt_gic_pcpu_init(void);
-
-#endif /* PLAT_PRIVATE_H */
diff --git a/plat/mediatek/mt6795/include/plat_sip_calls.h b/plat/mediatek/mt6795/include/plat_sip_calls.h
deleted file mode 100644
index b9a1363..0000000
--- a/plat/mediatek/mt6795/include/plat_sip_calls.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLAT_SIP_CALLS_H
-#define PLAT_SIP_CALLS_H
-
-/*******************************************************************************
- * Plat SiP function constants
- ******************************************************************************/
-#define MTK_PLAT_SIP_NUM_CALLS 0
-
-#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt6795/include/platform_def.h b/plat/mediatek/mt6795/include/platform_def.h
deleted file mode 100644
index b353a3d..0000000
--- a/plat/mediatek/mt6795/include/platform_def.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-
-#define PLAT_PRIMARY_CPU 0x0
-
-/* Special value used to verify platform parameters from BL2 to BL3-1 */
-#define MT_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
-
-#define IO_PHYS (0x10000000)
-#define INFRACFG_AO_BASE (IO_PHYS + 0x1000)
-#define MCUCFG_BASE (IO_PHYS + 0x200000)
-#define PERI_BASE (IO_PHYS + 0x1000000)
-
-
-#define GPIO_BASE (IO_PHYS + 0x370000)
-#define SPM_BASE (IO_PHYS + 0x6000)
-#define RGU_BASE (MCUCFG_BASE + 0x11000)
-#define PMIC_WRAP_BASE (IO_PHYS + 0x10000)
-
-#define TRNG_base (MCUCFG_BASE + 0x230000)
-#define MT_GIC_BASE (0x10220000)
-#define MCU_SYS_SIZE (0x700000)
-#define PLAT_MT_CCI_BASE (IO_PHYS + 0x390000)
-
-/* Aggregate of all devices in the first GB */
-#define MTK_DEV_RNG0_BASE IO_PHYS
-#define MTK_DEV_RNG0_SIZE 0x400000
-#define MTK_DEV_RNG1_BASE (PERI_BASE)
-#define MTK_DEV_RNG1_SIZE 0x4000000
-
-/*******************************************************************************
- * UART related constants
- ******************************************************************************/
-#define UART0_BASE (PERI_BASE + 0x2000)
-
-#define UART_BAUDRATE (921600)
-#define UART_CLOCK (26000000)
-
-/*******************************************************************************
- * System counter frequency related constants
- ******************************************************************************/
-#define SYS_COUNTER_FREQ_IN_TICKS 13000000
-#define SYS_COUNTER_FREQ_IN_MHZ (SYS_COUNTER_FREQ_IN_TICKS/1000000)
-
-/*******************************************************************************
- * GIC-400 & interrupt handling related constants
- ******************************************************************************/
-
-/* Base MTK_platform compatible GIC memory map */
-#define BASE_GICD_BASE (MT_GIC_BASE+0x1000)
-#define BASE_GICC_BASE (MT_GIC_BASE + 0x2000)
-#define BASE_GICR_BASE (MT_GIC_BASE + 0x200000)
-#define BASE_GICH_BASE (MT_GIC_BASE + 0x4000)
-#define BASE_GICV_BASE (MT_GIC_BASE + 0x6000)
-
-#define INT_POL_CTL0 0x10200620
-#define GIC_PRIVATE_SIGNALS (32)
-
-/*******************************************************************************
- * CCI-400 related constants
- ******************************************************************************/
-#define PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX 4
-#define PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX 3
-
-/*******************************************************************************
- * WDT Registers
- ******************************************************************************/
-#define MTK_WDT_BASE (RGU_BASE)
-#define MTK_WDT_SIZE (0x1000)
-#define MTK_WDT_MODE (MTK_WDT_BASE+0x0000)
-#define MTK_WDT_LENGTH (MTK_WDT_BASE+0x0004)
-#define MTK_WDT_RESTART (MTK_WDT_BASE+0x0008)
-#define MTK_WDT_STATUS (MTK_WDT_BASE+0x000C)
-#define MTK_WDT_INTERVAL (MTK_WDT_BASE+0x0010)
-#define MTK_WDT_SWRST (MTK_WDT_BASE+0x0014)
-#define MTK_WDT_SWSYSRST (MTK_WDT_BASE+0x0018)
-#define MTK_WDT_NONRST_REG (MTK_WDT_BASE+0x0020)
-#define MTK_WDT_NONRST_REG2 (MTK_WDT_BASE+0x0024)
-#define MTK_WDT_REQ_MODE (MTK_WDT_BASE+0x0030)
-#define MTK_WDT_REQ_IRQ_EN (MTK_WDT_BASE+0x0034)
-#define MTK_WDT_DEBUG_CTL (MTK_WDT_BASE+0x0040)
-
-/*WDT_STATUS*/
-#define MTK_WDT_STATUS_HWWDT_RST (0x80000000)
-#define MTK_WDT_STATUS_SWWDT_RST (0x40000000)
-#define MTK_WDT_STATUS_IRQWDT_RST (0x20000000)
-#define MTK_WDT_STATUS_DEBUGWDT_RST (0x00080000)
-#define MTK_WDT_STATUS_SPMWDT_RST (0x0002)
-#define MTK_WDT_STATUS_SPM_THERMAL_RST (0x0001)
-#define MTK_WDT_STATUS_THERMAL_DIRECT_RST (1<<18)
-#define MTK_WDT_STATUS_SECURITY_RST (1<<28)
-
-#define MTK_WDT_MODE_DUAL_MODE 0x0040
-#define MTK_WDT_MODE_IRQ 0x0008
-#define MTK_WDT_MODE_KEY 0x22000000
-#define MTK_WDT_MODE_EXTEN 0x0004
-#define MTK_WDT_SWRST_KEY 0x1209
-#define MTK_WDT_RESTART_KEY (0x1971)
-
-/* FIQ platform related define */
-#define MT_IRQ_SEC_SGI_0 8
-#define MT_IRQ_SEC_SGI_1 9
-#define MT_IRQ_SEC_SGI_2 10
-#define MT_IRQ_SEC_SGI_3 11
-#define MT_IRQ_SEC_SGI_4 12
-#define MT_IRQ_SEC_SGI_5 13
-#define MT_IRQ_SEC_SGI_6 14
-#define MT_IRQ_SEC_SGI_7 15
-
-#define FIQ_SMP_CALL_SGI MT_IRQ_SEC_SGI_5
-
-/*******************************************************************************
- * Platform binary types for linking
- ******************************************************************************/
-#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
-#define PLATFORM_LINKER_ARCH aarch64
-
-/*******************************************************************************
- * Generic platform constants
- ******************************************************************************/
-
-/* Size of cacheable stacks */
-#if defined(IMAGE_BL1)
-#define PLATFORM_STACK_SIZE 0x440
-#elif defined(IMAGE_BL2)
-#define PLATFORM_STACK_SIZE 0x400
-#elif defined(IMAGE_BL31)
-#define PLATFORM_STACK_SIZE 0x800
-#elif defined(IMAGE_BL32)
-#define PLATFORM_STACK_SIZE 0x440
-#endif
-
-#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
-#define PLAT_MAX_PWR_LVL U(2) /* MPIDR_AFFLVL2 */
-
-#define PLAT_MAX_RET_STATE U(1)
-#define PLAT_MAX_OFF_STATE U(2)
-
-#define PLATFORM_CACHE_LINE_SIZE 64
-#define PLATFORM_SYSTEM_COUNT U(1)
-#define PLATFORM_CLUSTER_COUNT U(2)
-#define PLATFORM_CLUSTER0_CORE_COUNT U(4)
-#define PLATFORM_CLUSTER1_CORE_COUNT U(4)
-#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
- PLATFORM_CLUSTER0_CORE_COUNT)
-#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
-#define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \
- PLATFORM_CLUSTER_COUNT + \
- PLATFORM_CORE_COUNT)
-
-/*******************************************************************************
- * Platform memory map related constants
- ******************************************************************************/
-/* ATF Argument */
-#define ATF_ARG_SIZE (0x800)
-
-/* TF txet, ro, rw, internal SRAM, Size: release: 80KB, debug: 92KB */
-#define TZRAM_BASE (0x110000)
-#if DEBUG
-#define TZRAM_SIZE (0x1C400)
-#else
-#define TZRAM_SIZE (0x1C400)
-#endif
-#define TZRAM2_BASE 0x00100000
-#define TZRAM2_SIZE 0xDC00
-#define TZRAM2_LIMIT (TZRAM2_BASE + TZRAM2_SIZE)
-
-#define RAM_CONSOLE_BASE 0x0012D000
-#define RAM_CONSOLE_SIZE 0x00001000
-/*******************************************************************************
- * BL31 specific defines.
- ******************************************************************************/
-/*
- * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if
- * present). BL31_BASE is calculated using the current BL3-1 debug size plus a
- * little space for growth.
- */
-#define BL31_BASE (TZRAM_BASE + 0x1000)
-#define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE)
-#define BSS1_STACK_LIMIT (TZRAM_BASE + TZRAM_SIZE)
-#define BL31_TZRAM_SIZE (TZRAM_SIZE - ATF_ARG_SIZE)
-
-/*******************************************************************************
- * Platform specific page table and MMU setup constants
- ******************************************************************************/
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
-#define MAX_XLAT_TABLES 7
-#define MAX_MMAP_REGIONS 16
-
-
-/*******************************************************************************
- * CCI-400 related constants
- ******************************************************************************/
-#define CCI400_BASE 0x10390000
-#define CCI400_SL_IFACE_CLUSTER0 4
-#define CCI400_SL_IFACE_CLUSTER1 3
-#define CCI400_SL_IFACE_INDEX(mpidr) (mpidr & MPIDR_CLUSTER_MASK ? \
- CCI400_SL_IFACE_CLUSTER1 : \
- CCI400_SL_IFACE_CLUSTER0)
-#define CCI_SEC_ACCESS_OFFSET (0x8)
-
-
-/*******************************************************************************
- * Declarations and constants to access the mailboxes safely. Each mailbox is
- * aligned on the biggest cache line size in the platform. This is known only
- * to the platform as it might have a combination of integrated and external
- * caches. Such alignment ensures that two maiboxes do not sit on the same cache
- * line at any cache level. They could belong to different cpus/clusters &
- * get written while being protected by different locks causing corruption of
- * a valid mailbox address.
- ******************************************************************************/
-#define CACHE_WRITEBACK_SHIFT 6
-#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
-
-#define BL32_BASE (0x0)
-
-/*
- * Load address of BL3-3 for this platform port
- */
-#define LK_SIZE_LIMIT (0x100000)
-#define PLAT_MTK_NS_IMAGE_OFFSET (0x41E00000)
-/* 16KB */
-#define ATF_AEE_BUFFER_SIZE (0x4000)
-#define PAGE_SIZE_2MB_MASK (PAGE_SIZE_2MB - 1)
-#define IS_PAGE_2MB_ALIGNED(addr) (((addr) & PAGE_SIZE_2MB_MASK) == 0)
-#define PAGE_SIZE_2MB (1 << PAGE_SIZE_2MB_SHIFT)
-#define PAGE_SIZE_2MB_SHIFT TWO_MB_SHIFT
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt6795/include/power_tracer.h b/plat/mediatek/mt6795/include/power_tracer.h
deleted file mode 100644
index 8c98dbd..0000000
--- a/plat/mediatek/mt6795/include/power_tracer.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef POWER_TRACER_H
-#define POWER_TRACER_H
-
-#define CPU_UP 0
-#define CPU_DOWN 1
-#define CPU_SUSPEND 2
-#define CLUSTER_UP 3
-#define CLUSTER_DOWN 4
-#define CLUSTER_SUSPEND 5
-
-void trace_power_flow(unsigned long mpidr, unsigned char mode);
-
-#endif /* POWER_TRACER_H */
diff --git a/plat/mediatek/mt6795/include/scu.h b/plat/mediatek/mt6795/include/scu.h
deleted file mode 100644
index 625418a..0000000
--- a/plat/mediatek/mt6795/include/scu.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SCU_H
-#define SCU_H
-
-void disable_scu(unsigned long mpidr);
-void enable_scu(unsigned long mpidr);
-
-#endif /* SCU_H */
diff --git a/plat/mediatek/mt6795/include/spm.h b/plat/mediatek/mt6795/include/spm.h
deleted file mode 100644
index 5227e1d..0000000
--- a/plat/mediatek/mt6795/include/spm.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_H
-#define SPM_H
-
-#define SPM_POWERON_CONFIG_SET (SPM_BASE + 0x000)
-#define SPM_POWER_ON_VAL0 (SPM_BASE + 0x010)
-#define SPM_POWER_ON_VAL1 (SPM_BASE + 0x014)
-#define SPM_CLK_SETTLE (SPM_BASE + 0x100)
-#define SPM_CA7_CPU1_PWR_CON (SPM_BASE + 0x218)
-#define SPM_CA7_CPU2_PWR_CON (SPM_BASE + 0x21c)
-#define SPM_CA7_CPU3_PWR_CON (SPM_BASE + 0x220)
-#define SPM_CA7_CPU1_L1_PDN (SPM_BASE + 0x264)
-#define SPM_CA7_CPU2_L1_PDN (SPM_BASE + 0x26c)
-#define SPM_CA7_CPU3_L1_PDN (SPM_BASE + 0x274)
-#define SPM_MD32_SRAM_CON (SPM_BASE + 0x2c8)
-#define SPM_PCM_CON0 (SPM_BASE + 0x310)
-#define SPM_PCM_CON1 (SPM_BASE + 0x314)
-#define SPM_PCM_IM_PTR (SPM_BASE + 0x318)
-#define SPM_PCM_IM_LEN (SPM_BASE + 0x31c)
-#define SPM_PCM_REG_DATA_INI (SPM_BASE + 0x320)
-#define SPM_PCM_EVENT_VECTOR0 (SPM_BASE + 0x340)
-#define SPM_PCM_EVENT_VECTOR1 (SPM_BASE + 0x344)
-#define SPM_PCM_EVENT_VECTOR2 (SPM_BASE + 0x348)
-#define SPM_PCM_EVENT_VECTOR3 (SPM_BASE + 0x34c)
-#define SPM_PCM_MAS_PAUSE_MASK (SPM_BASE + 0x354)
-#define SPM_PCM_PWR_IO_EN (SPM_BASE + 0x358)
-#define SPM_PCM_TIMER_VAL (SPM_BASE + 0x35c)
-#define SPM_PCM_TIMER_OUT (SPM_BASE + 0x360)
-#define SPM_PCM_REG0_DATA (SPM_BASE + 0x380)
-#define SPM_PCM_REG1_DATA (SPM_BASE + 0x384)
-#define SPM_PCM_REG2_DATA (SPM_BASE + 0x388)
-#define SPM_PCM_REG3_DATA (SPM_BASE + 0x38c)
-#define SPM_PCM_REG4_DATA (SPM_BASE + 0x390)
-#define SPM_PCM_REG5_DATA (SPM_BASE + 0x394)
-#define SPM_PCM_REG6_DATA (SPM_BASE + 0x398)
-#define SPM_PCM_REG7_DATA (SPM_BASE + 0x39c)
-#define SPM_PCM_REG8_DATA (SPM_BASE + 0x3a0)
-#define SPM_PCM_REG9_DATA (SPM_BASE + 0x3a4)
-#define SPM_PCM_REG10_DATA (SPM_BASE + 0x3a8)
-#define SPM_PCM_REG11_DATA (SPM_BASE + 0x3ac)
-#define SPM_PCM_REG12_DATA (SPM_BASE + 0x3b0)
-#define SPM_PCM_REG13_DATA (SPM_BASE + 0x3b4)
-#define SPM_PCM_REG14_DATA (SPM_BASE + 0x3b8)
-#define SPM_PCM_REG15_DATA (SPM_BASE + 0x3bc)
-#define SPM_PCM_EVENT_REG_STA (SPM_BASE + 0x3c0)
-#define SPM_PCM_FSM_STA (SPM_BASE + 0x3c4)
-#define SPM_PCM_IM_HOST_RW_PTR (SPM_BASE + 0x3c8)
-#define SPM_PCM_IM_HOST_RW_DAT (SPM_BASE + 0x3cc)
-#define SPM_PCM_EVENT_VECTOR4 (SPM_BASE + 0x3d0)
-#define SPM_PCM_EVENT_VECTOR5 (SPM_BASE + 0x3d4)
-#define SPM_PCM_EVENT_VECTOR6 (SPM_BASE + 0x3d8)
-#define SPM_PCM_EVENT_VECTOR7 (SPM_BASE + 0x3dc)
-#define SPM_PCM_SW_INT_SET (SPM_BASE + 0x3e0)
-#define SPM_PCM_SW_INT_CLEAR (SPM_BASE + 0x3e4)
-#define SPM_CLK_CON (SPM_BASE + 0x400)
-#define SPM_SLEEP_PTPOD2_CON (SPM_BASE + 0x408)
-#define SPM_APMCU_PWRCTL (SPM_BASE + 0x600)
-#define SPM_AP_DVFS_CON_SET (SPM_BASE + 0x604)
-#define SPM_AP_STANBY_CON (SPM_BASE + 0x608)
-#define SPM_PWR_STATUS (SPM_BASE + 0x60c)
-#define SPM_PWR_STATUS_2ND (SPM_BASE + 0x610)
-#define SPM_AP_BSI_REQ (SPM_BASE + 0x614)
-#define SPM_SLEEP_TIMER_STA (SPM_BASE + 0x720)
-#define SPM_SLEEP_WAKEUP_EVENT_MASK (SPM_BASE + 0x810)
-#define SPM_SLEEP_CPU_WAKEUP_EVENT (SPM_BASE + 0x814)
-#define SPM_SLEEP_MD32_WAKEUP_EVENT_MASK (SPM_BASE + 0x818)
-#define SPM_PCM_WDT_TIMER_VAL (SPM_BASE + 0x824)
-#define SPM_PCM_WDT_TIMER_OUT (SPM_BASE + 0x828)
-#define SPM_PCM_MD32_MAILBOX (SPM_BASE + 0x830)
-#define SPM_PCM_MD32_IRQ (SPM_BASE + 0x834)
-#define SPM_SLEEP_ISR_MASK (SPM_BASE + 0x900)
-#define SPM_SLEEP_ISR_STATUS (SPM_BASE + 0x904)
-#define SPM_SLEEP_ISR_RAW_STA (SPM_BASE + 0x910)
-#define SPM_SLEEP_MD32_ISR_RAW_STA (SPM_BASE + 0x914)
-#define SPM_SLEEP_WAKEUP_MISC (SPM_BASE + 0x918)
-#define SPM_SLEEP_BUS_PROTECT_RDY (SPM_BASE + 0x91c)
-#define SPM_SLEEP_SUBSYS_IDLE_STA (SPM_BASE + 0x920)
-#define SPM_PCM_RESERVE (SPM_BASE + 0xb00)
-#define SPM_PCM_RESERVE2 (SPM_BASE + 0xb04)
-#define SPM_PCM_FLAGS (SPM_BASE + 0xb08)
-#define SPM_PCM_SRC_REQ (SPM_BASE + 0xb0c)
-#define SPM_PCM_DEBUG_CON (SPM_BASE + 0xb20)
-#define SPM_CA7_CPU0_IRQ_MASK (SPM_BASE + 0xb30)
-#define SPM_CA7_CPU1_IRQ_MASK (SPM_BASE + 0xb34)
-#define SPM_CA7_CPU2_IRQ_MASK (SPM_BASE + 0xb38)
-#define SPM_CA7_CPU3_IRQ_MASK (SPM_BASE + 0xb3c)
-#define SPM_CA15_CPU0_IRQ_MASK (SPM_BASE + 0xb40)
-#define SPM_CA15_CPU1_IRQ_MASK (SPM_BASE + 0xb44)
-#define SPM_CA15_CPU2_IRQ_MASK (SPM_BASE + 0xb48)
-#define SPM_CA15_CPU3_IRQ_MASK (SPM_BASE + 0xb4c)
-#define SPM_PCM_PASR_DPD_0 (SPM_BASE + 0xb60)
-#define SPM_PCM_PASR_DPD_1 (SPM_BASE + 0xb64)
-#define SPM_PCM_PASR_DPD_2 (SPM_BASE + 0xb68)
-#define SPM_PCM_PASR_DPD_3 (SPM_BASE + 0xb6c)
-#define SPM_SLEEP_CA7_WFI0_EN (SPM_BASE + 0xf00)
-#define SPM_SLEEP_CA7_WFI1_EN (SPM_BASE + 0xf04)
-#define SPM_SLEEP_CA7_WFI2_EN (SPM_BASE + 0xf08)
-#define SPM_SLEEP_CA7_WFI3_EN (SPM_BASE + 0xf0c)
-#define SPM_SLEEP_CA15_WFI0_EN (SPM_BASE + 0xf10)
-#define SPM_SLEEP_CA15_WFI1_EN (SPM_BASE + 0xf14)
-#define SPM_SLEEP_CA15_WFI2_EN (SPM_BASE + 0xf18)
-#define SPM_SLEEP_CA15_WFI3_EN (SPM_BASE + 0xf1c)
-
-#define SPM_PROJECT_CODE 0xb16
-
-#define SPM_REGWR_EN (1U << 0)
-#define SPM_REGWR_CFG_KEY (SPM_PROJECT_CODE << 16)
-
-#define SPM_CPU_PDN_DIS (1U << 0)
-#define SPM_INFRA_PDN_DIS (1U << 1)
-#define SPM_DDRPHY_PDN_DIS (1U << 2)
-#define SPM_DUALVCORE_PDN_DIS (1U << 3)
-#define SPM_PASR_DIS (1U << 4)
-#define SPM_DPD_DIS (1U << 5)
-#define SPM_SODI_DIS (1U << 6)
-#define SPM_MEMPLL_RESET (1U << 7)
-#define SPM_MAINPLL_PDN_DIS (1U << 8)
-#define SPM_CPU_DVS_DIS (1U << 9)
-#define SPM_CPU_DORMANT (1U << 10)
-#define SPM_EXT_VSEL_GPIO103 (1U << 11)
-#define SPM_DDR_HIGH_SPEED (1U << 12)
-#define SPM_OPT (1U << 13)
-
-#define POWER_ON_VAL1_DEF 0x01011820
-#define PCM_FSM_STA_DEF 0x48490
-#define PCM_END_FSM_STA_DEF 0x08490
-#define PCM_END_FSM_STA_MASK 0x3fff0
-#define PCM_HANDSHAKE_SEND1 0xbeefbeef
-
-#define PCM_WDT_TIMEOUT (30 * 32768)
-#define PCM_TIMER_MAX (0xffffffff - PCM_WDT_TIMEOUT)
-
-#define CON0_PCM_KICK (1U << 0)
-#define CON0_IM_KICK (1U << 1)
-#define CON0_IM_SLEEP_DVS (1U << 3)
-#define CON0_PCM_SW_RESET (1U << 15)
-#define CON0_CFG_KEY (SPM_PROJECT_CODE << 16)
-
-#define CON1_IM_SLAVE (1U << 0)
-#define CON1_MIF_APBEN (1U << 3)
-#define CON1_PCM_TIMER_EN (1U << 5)
-#define CON1_IM_NONRP_EN (1U << 6)
-#define CON1_PCM_WDT_EN (1U << 8)
-#define CON1_PCM_WDT_WAKE_MODE (1U << 9)
-#define CON1_SPM_SRAM_SLP_B (1U << 10)
-#define CON1_SPM_SRAM_ISO_B (1U << 11)
-#define CON1_EVENT_LOCK_EN (1U << 12)
-#define CON1_CFG_KEY (SPM_PROJECT_CODE << 16)
-
-#define PCM_PWRIO_EN_R0 (1U << 0)
-#define PCM_PWRIO_EN_R7 (1U << 7)
-#define PCM_RF_SYNC_R0 (1U << 16)
-#define PCM_RF_SYNC_R2 (1U << 18)
-#define PCM_RF_SYNC_R6 (1U << 22)
-#define PCM_RF_SYNC_R7 (1U << 23)
-
-#define CC_SYSCLK0_EN_0 (1U << 0)
-#define CC_SYSCLK0_EN_1 (1U << 1)
-#define CC_SYSCLK1_EN_0 (1U << 2)
-#define CC_SYSCLK1_EN_1 (1U << 3)
-#define CC_SYSSETTLE_SEL (1U << 4)
-#define CC_LOCK_INFRA_DCM (1U << 5)
-#define CC_SRCLKENA_MASK_0 (1U << 6)
-#define CC_CXO32K_RM_EN_MD1 (1U << 9)
-#define CC_CXO32K_RM_EN_MD2 (1U << 10)
-#define CC_CLKSQ1_SEL (1U << 12)
-#define CC_DISABLE_DORM_PWR (1U << 14)
-#define CC_MD32_DCM_EN (1U << 18)
-
-#define WFI_OP_AND 1
-#define WFI_OP_OR 0
-
-#define WAKE_MISC_PCM_TIMER (1U << 19)
-#define WAKE_MISC_CPU_WAKE (1U << 20)
-
-/* define WAKE_SRC_XXX */
-#define WAKE_SRC_SPM_MERGE (1 << 0)
-#define WAKE_SRC_KP (1 << 2)
-#define WAKE_SRC_WDT (1 << 3)
-#define WAKE_SRC_GPT (1 << 4)
-#define WAKE_SRC_EINT (1 << 6)
-#define WAKE_SRC_LOW_BAT (1 << 9)
-#define WAKE_SRC_MD32 (1 << 10)
-#define WAKE_SRC_USB_CD (1 << 14)
-#define WAKE_SRC_USB_PDN (1 << 15)
-#define WAKE_SRC_AFE (1 << 20)
-#define WAKE_SRC_THERM (1 << 21)
-#define WAKE_SRC_SYSPWREQ (1 << 24)
-#define WAKE_SRC_SEJ (1 << 27)
-#define WAKE_SRC_ALL_MD32 (1 << 28)
-#define WAKE_SRC_CPU_IRQ (1 << 29)
-
-#endif /* SPM_H */
diff --git a/plat/mediatek/mt6795/plat_delay_timer.c b/plat/mediatek/mt6795/plat_delay_timer.c
deleted file mode 100644
index 965b653..0000000
--- a/plat/mediatek/mt6795/plat_delay_timer.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <arch_helpers.h>
-#include <drivers/delay_timer.h>
-
-static uint32_t plat_get_timer_value(void)
-{
- /*
- * Generic delay timer implementation expects the timer to be a down
- * counter. We apply bitwise NOT operator to the tick values returned
- * by read_cntpct_el0() to simulate the down counter.
- */
- return (uint32_t)(~read_cntpct_el0());
-}
-
-static const timer_ops_t plat_timer_ops = {
- .get_timer_value = plat_get_timer_value,
- .clk_mult = 1,
- .clk_div = SYS_COUNTER_FREQ_IN_MHZ,
-};
-
-void plat_delay_timer_init(void)
-{
- timer_init(&plat_timer_ops);
-}
diff --git a/plat/mediatek/mt6795/plat_mt_gic.c b/plat/mediatek/mt6795/plat_mt_gic.c
deleted file mode 100644
index 20cb26d..0000000
--- a/plat/mediatek/mt6795/plat_mt_gic.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <common/interrupt_props.h>
-#include <drivers/arm/gicv2.h>
-#include <plat/common/platform.h>
-
-static const interrupt_prop_t g0_interrupt_props[] = {
- INTR_PROP_DESC(FIQ_SMP_CALL_SGI, GIC_HIGHEST_SEC_PRIORITY,
- GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
-};
-
-gicv2_driver_data_t arm_gic_data = {
- .gicd_base = BASE_GICD_BASE,
- .gicc_base = BASE_GICC_BASE,
- .interrupt_props = g0_interrupt_props,
- .interrupt_props_num = ARRAY_SIZE(g0_interrupt_props),
-};
-
-void plat_mt_gic_driver_init(void)
-{
- gicv2_driver_init(&arm_gic_data);
-}
-
-void plat_mt_gic_init(void)
-{
- gicv2_distif_init();
- gicv2_pcpu_distif_init();
- gicv2_cpuif_enable();
-}
-
-void plat_mt_gic_cpuif_enable(void)
-{
- gicv2_cpuif_enable();
-}
-
-void plat_mt_gic_cpuif_disable(void)
-{
- gicv2_cpuif_disable();
-}
-
-void plat_mt_gic_pcpu_init(void)
-{
- gicv2_pcpu_distif_init();
-}
diff --git a/plat/mediatek/mt6795/plat_pm.c b/plat/mediatek/mt6795/plat_pm.c
deleted file mode 100644
index 0dfbd18..0000000
--- a/plat/mediatek/mt6795/plat_pm.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-
-#include <platform_def.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <drivers/arm/cci.h>
-#include <drivers/console.h>
-#include <lib/bakery_lock.h>
-#include <lib/mmio.h>
-#include <lib/psci/psci.h>
-
-#include <mcucfg.h>
-#include <plat_private.h>
-#include <power_tracer.h>
-#include <scu.h>
-
-struct core_context {
- unsigned long timer_data[8];
- unsigned int count;
- unsigned int rst;
- unsigned int abt;
- unsigned int brk;
-};
-
-struct cluster_context {
- struct core_context core[PLATFORM_MAX_CPUS_PER_CLUSTER];
-};
-
-/*
- * Top level structure to hold the complete context of a multi cluster system
- */
-struct system_context {
- struct cluster_context cluster[PLATFORM_CLUSTER_COUNT];
-};
-
-/*
- * Top level structure which encapsulates the context of the entire system
- */
-static struct system_context dormant_data[1];
-
-static inline struct cluster_context *system_cluster(
- struct system_context *system,
- uint32_t clusterid)
-{
- return &system->cluster[clusterid];
-}
-
-static inline struct core_context *cluster_core(struct cluster_context *cluster,
- uint32_t cpuid)
-{
- return &cluster->core[cpuid];
-}
-
-static struct cluster_context *get_cluster_data(unsigned long mpidr)
-{
- uint32_t clusterid;
-
- clusterid = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
-
- return system_cluster(dormant_data, clusterid);
-}
-
-static struct core_context *get_core_data(unsigned long mpidr)
-{
- struct cluster_context *cluster;
- uint32_t cpuid;
-
- cluster = get_cluster_data(mpidr);
- cpuid = mpidr & MPIDR_CPU_MASK;
-
- return cluster_core(cluster, cpuid);
-}
-
-static void mt_save_generic_timer(unsigned long *container)
-{
- uint64_t ctl;
- uint64_t val;
-
- __asm__ volatile("mrs %x0, cntkctl_el1\n\t"
- "mrs %x1, cntp_cval_el0\n\t"
- "stp %x0, %x1, [%2, #0]"
- : "=&r" (ctl), "=&r" (val)
- : "r" (container)
- : "memory");
-
- __asm__ volatile("mrs %x0, cntp_tval_el0\n\t"
- "mrs %x1, cntp_ctl_el0\n\t"
- "stp %x0, %x1, [%2, #16]"
- : "=&r" (val), "=&r" (ctl)
- : "r" (container)
- : "memory");
-
- __asm__ volatile("mrs %x0, cntv_tval_el0\n\t"
- "mrs %x1, cntv_ctl_el0\n\t"
- "stp %x0, %x1, [%2, #32]"
- : "=&r" (val), "=&r" (ctl)
- : "r" (container)
- : "memory");
-}
-
-static void mt_restore_generic_timer(unsigned long *container)
-{
- uint64_t ctl;
- uint64_t val;
-
- __asm__ volatile("ldp %x0, %x1, [%2, #0]\n\t"
- "msr cntkctl_el1, %x0\n\t"
- "msr cntp_cval_el0, %x1"
- : "=&r" (ctl), "=&r" (val)
- : "r" (container)
- : "memory");
-
- __asm__ volatile("ldp %x0, %x1, [%2, #16]\n\t"
- "msr cntp_tval_el0, %x0\n\t"
- "msr cntp_ctl_el0, %x1"
- : "=&r" (val), "=&r" (ctl)
- : "r" (container)
- : "memory");
-
- __asm__ volatile("ldp %x0, %x1, [%2, #32]\n\t"
- "msr cntv_tval_el0, %x0\n\t"
- "msr cntv_ctl_el0, %x1"
- : "=&r" (val), "=&r" (ctl)
- : "r" (container)
- : "memory");
-}
-
-static void stop_generic_timer(void)
-{
- /*
- * Disable the timer and mask the irq to prevent
- * suprious interrupts on this cpu interface. It
- * will bite us when we come back if we don't. It
- * will be replayed on the inbound cluster.
- */
- uint64_t cntpctl = read_cntp_ctl_el0();
-
- write_cntp_ctl_el0(clr_cntp_ctl_enable(cntpctl));
-}
-
-static void mt_cpu_save(unsigned long mpidr)
-{
- struct core_context *core;
-
- core = get_core_data(mpidr);
- mt_save_generic_timer(core->timer_data);
-
- /* disable timer irq, and upper layer should enable it again. */
- stop_generic_timer();
-}
-
-static void mt_cpu_restore(unsigned long mpidr)
-{
- struct core_context *core;
-
- core = get_core_data(mpidr);
- mt_restore_generic_timer(core->timer_data);
-}
-
-static void mt_platform_save_context(unsigned long mpidr)
-{
- /* mcusys_save_context: */
- mt_cpu_save(mpidr);
-}
-
-static void mt_platform_restore_context(unsigned long mpidr)
-{
- /* mcusys_restore_context: */
- mt_cpu_restore(mpidr);
-}
-
-/*******************************************************************************
-* Private function which is used to determine if any platform actions
-* should be performed for the specified affinity instance given its
-* state. Nothing needs to be done if the 'state' is not off or if this is not
-* the highest affinity level which will enter the 'state'.
-*******************************************************************************/
-static int32_t plat_do_plat_actions(unsigned int afflvl, unsigned int state)
-{
- unsigned int max_phys_off_afflvl;
-
- assert(afflvl <= MPIDR_AFFLVL2);
-
- if (state != PSCI_STATE_OFF)
- return -EAGAIN;
-
- /*
- * Find the highest affinity level which will be suspended and postpone
- * all the platform specific actions until that level is hit.
- */
- max_phys_off_afflvl = psci_get_max_phys_off_afflvl();
- assert(max_phys_off_afflvl != PSCI_INVALID_DATA);
- if (afflvl != max_phys_off_afflvl)
- return -EAGAIN;
-
- return 0;
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to enter
- * standby.
- ******************************************************************************/
-static void plat_affinst_standby(unsigned int power_state)
-{
- unsigned int target_afflvl;
-
- /* Sanity check the requested state */
- target_afflvl = psci_get_pstate_afflvl(power_state);
-
- /*
- * It's possible to enter standby only on affinity level 0 i.e. a cpu
- * on the MTK_platform. Ignore any other affinity level.
- */
- if (target_afflvl == MPIDR_AFFLVL0) {
- /*
- * Enter standby state. dsb is good practice before using wfi
- * to enter low power states.
- */
- dsb();
- wfi();
- }
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to be turned
- * on. The level and mpidr determine the affinity instance.
- ******************************************************************************/
-static int plat_affinst_on(unsigned long mpidr,
- unsigned long sec_entrypoint,
- unsigned int afflvl,
- unsigned int state)
-{
- int rc = PSCI_E_SUCCESS;
- unsigned long cpu_id;
- unsigned long cluster_id;
- uintptr_t rv;
-
- /*
- * It's possible to turn on only affinity level 0 i.e. a cpu
- * on the MTK_platform. Ignore any other affinity level.
- */
- if (afflvl != MPIDR_AFFLVL0)
- return rc;
-
- cpu_id = mpidr & MPIDR_CPU_MASK;
- cluster_id = mpidr & MPIDR_CLUSTER_MASK;
-
- if (cluster_id)
- rv = (uintptr_t)&mt6795_mcucfg->mp1_rv_addr[cpu_id].rv_addr_lw;
- else
- rv = (uintptr_t)&mt6795_mcucfg->mp0_rv_addr[cpu_id].rv_addr_lw;
-
- mmio_write_32(rv, sec_entrypoint);
- INFO("mt_on[%ld:%ld], entry %x\n",
- cluster_id, cpu_id, mmio_read_32(rv));
-
- return rc;
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to be turned
- * off. The level and mpidr determine the affinity instance. The 'state' arg.
- * allows the platform to decide whether the cluster is being turned off and
- * take apt actions.
- *
- * CAUTION: This function is called with coherent stacks so that caches can be
- * turned off, flushed and coherency disabled. There is no guarantee that caches
- * will remain turned on across calls to this function as each affinity level is
- * dealt with. So do not write & read global variables across calls. It will be
- * wise to do flush a write to the global to prevent unpredictable results.
- ******************************************************************************/
-static void plat_affinst_off(unsigned int afflvl, unsigned int state)
-{
- unsigned long mpidr = read_mpidr_el1();
-
- /* Determine if any platform actions need to be executed. */
- if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
- return;
-
- /* Prevent interrupts from spuriously waking up this cpu */
- plat_mt_gic_cpuif_disable();
-
- trace_power_flow(mpidr, CPU_DOWN);
-
- if (afflvl != MPIDR_AFFLVL0) {
- /* Disable coherency if this cluster is to be turned off */
- plat_cci_disable();
-
- trace_power_flow(mpidr, CLUSTER_DOWN);
- }
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance is about to be
- * suspended. The level and mpidr determine the affinity instance. The 'state'
- * arg. allows the platform to decide whether the cluster is being turned off
- * and take apt actions.
- *
- * CAUTION: This function is called with coherent stacks so that caches can be
- * turned off, flushed and coherency disabled. There is no guarantee that caches
- * will remain turned on across calls to this function as each affinity level is
- * dealt with. So do not write & read global variables across calls. It will be
- * wise to do flush a write to the global to prevent unpredictable results.
- ******************************************************************************/
-static void plat_affinst_suspend(unsigned long sec_entrypoint,
- unsigned int afflvl,
- unsigned int state)
-{
- unsigned long mpidr = read_mpidr_el1();
- unsigned long cluster_id;
- unsigned long cpu_id;
- uintptr_t rv;
-
- /* Determine if any platform actions need to be executed. */
- if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
- return;
-
- cpu_id = mpidr & MPIDR_CPU_MASK;
- cluster_id = mpidr & MPIDR_CLUSTER_MASK;
-
- if (cluster_id)
- rv = (uintptr_t)&mt6795_mcucfg->mp1_rv_addr[cpu_id].rv_addr_lw;
- else
- rv = (uintptr_t)&mt6795_mcucfg->mp0_rv_addr[cpu_id].rv_addr_lw;
-
- mmio_write_32(rv, sec_entrypoint);
-
- if (afflvl >= MPIDR_AFFLVL0)
- mt_platform_save_context(mpidr);
-
- /* Perform the common cluster specific operations */
- if (afflvl >= MPIDR_AFFLVL1) {
- /* Disable coherency if this cluster is to be turned off */
- plat_cci_disable();
- disable_scu(mpidr);
-
- trace_power_flow(mpidr, CLUSTER_SUSPEND);
- }
-
- if (afflvl >= MPIDR_AFFLVL2) {
- /* Prevent interrupts from spuriously waking up this cpu */
- plat_mt_gic_cpuif_disable();
- }
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance has just been powered
- * on after being turned off earlier. The level and mpidr determine the affinity
- * instance. The 'state' arg. allows the platform to decide whether the cluster
- * was turned off prior to wakeup and do what's necessary to setup it up
- * correctly.
- ******************************************************************************/
-static void plat_affinst_on_finish(unsigned int afflvl, unsigned int state)
-{
- unsigned long mpidr = read_mpidr_el1();
-
- /* Determine if any platform actions need to be executed. */
- if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
- return;
-
- /* Perform the common cluster specific operations */
- if (afflvl >= MPIDR_AFFLVL1) {
- enable_scu(mpidr);
-
- /* Enable coherency if this cluster was off */
- plat_cci_enable();
- trace_power_flow(mpidr, CLUSTER_UP);
- }
-
- /* Enable the gic cpu interface */
- plat_mt_gic_cpuif_enable();
- plat_mt_gic_pcpu_init();
- trace_power_flow(mpidr, CPU_UP);
-}
-
-/*******************************************************************************
- * MTK_platform handler called when an affinity instance has just been powered
- * on after having been suspended earlier. The level and mpidr determine the
- * affinity instance.
- ******************************************************************************/
-static void plat_affinst_suspend_finish(unsigned int afflvl, unsigned int state)
-{
- unsigned long mpidr = read_mpidr_el1();
-
- /* Determine if any platform actions need to be executed. */
- if (plat_do_plat_actions(afflvl, state) == -EAGAIN)
- return;
-
- if (afflvl >= MPIDR_AFFLVL2) {
- /* Enable the gic cpu interface */
- plat_mt_gic_init();
- plat_mt_gic_cpuif_enable();
- }
-
- /* Perform the common cluster specific operations */
- if (afflvl >= MPIDR_AFFLVL1) {
- enable_scu(mpidr);
-
- /* Enable coherency if this cluster was off */
- plat_cci_enable();
- trace_power_flow(mpidr, CLUSTER_UP);
- }
-
- if (afflvl >= MPIDR_AFFLVL0)
- mt_platform_restore_context(mpidr);
-
- plat_mt_gic_pcpu_init();
-}
-
-static unsigned int plat_get_sys_suspend_power_state(void)
-{
- /* StateID: 0, StateType: 1(power down), PowerLevel: 2(system) */
- return psci_make_powerstate(0, 1, 2);
-}
-
-/*******************************************************************************
- * MTK handlers to shutdown/reboot the system
- ******************************************************************************/
-static void __dead2 plat_system_off(void)
-{
- INFO("MTK System Off\n");
- wfi();
- ERROR("MTK System Off: operation not handled.\n");
- panic();
-}
-
-static void __dead2 plat_system_reset(void)
-{
- /* Write the System Configuration Control Register */
- INFO("MTK System Reset\n");
-
- mmio_clrbits_32(MTK_WDT_BASE,
- (MTK_WDT_MODE_DUAL_MODE | MTK_WDT_MODE_IRQ));
- mmio_setbits_32(MTK_WDT_BASE, (MTK_WDT_MODE_KEY | MTK_WDT_MODE_EXTEN));
- mmio_setbits_32(MTK_WDT_SWRST, MTK_WDT_SWRST_KEY);
-
- wfi();
- ERROR("MTK System Reset: operation not handled.\n");
- panic();
-}
-
-/*******************************************************************************
- * Export the platform handlers to enable psci to invoke them
- ******************************************************************************/
-static const plat_pm_ops_t plat_plat_pm_ops = {
- .affinst_standby = plat_affinst_standby,
- .affinst_on = plat_affinst_on,
- .affinst_off = plat_affinst_off,
- .affinst_suspend = plat_affinst_suspend,
- .affinst_on_finish = plat_affinst_on_finish,
- .affinst_suspend_finish = plat_affinst_suspend_finish,
- .system_off = plat_system_off,
- .system_reset = plat_system_reset,
- .get_sys_suspend_power_state = plat_get_sys_suspend_power_state,
-};
-
-/*******************************************************************************
- * Export the platform specific power ops & initialize the mtk_platform power
- * controller
- ******************************************************************************/
-int platform_setup_pm(const plat_pm_ops_t **plat_ops)
-{
- *plat_ops = &plat_plat_pm_ops;
- return 0;
-}
diff --git a/plat/mediatek/mt6795/plat_topology.c b/plat/mediatek/mt6795/plat_topology.c
deleted file mode 100644
index 7425d26..0000000
--- a/plat/mediatek/mt6795/plat_topology.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <arch.h>
-#include <lib/psci/psci.h>
-
-unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr)
-{
- /* Report 1 (absent) instance at levels higher that the cluster level */
- if (aff_lvl > MPIDR_AFFLVL1)
- return PLATFORM_SYSTEM_COUNT;
-
- if (aff_lvl == MPIDR_AFFLVL1)
- return PLATFORM_CLUSTER_COUNT;
-
- return mpidr & 0x100 ? PLATFORM_CLUSTER1_CORE_COUNT :
- PLATFORM_CLUSTER0_CORE_COUNT;
-}
-
-unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr)
-{
- return aff_lvl <= MPIDR_AFFLVL2 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT;
-}
-
-int mt_setup_topology(void)
-{
- /* [TODO] Make topology configurable via SCC */
- return 0;
-}
diff --git a/plat/mediatek/mt6795/platform.mk b/plat/mediatek/mt6795/platform.mk
deleted file mode 100644
index 4ab692d..0000000
--- a/plat/mediatek/mt6795/platform.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-MTK_PLAT := plat/mediatek
-MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
-
-# Add OEM customized codes
-OEMS := true
-MTK_SIP_KERNEL_BOOT_ENABLE := 1
-
-
-ifneq (${OEMS},none)
- OEMS_INCLUDES := -I${MTK_PLAT}/common/custom/
- OEMS_SOURCES := ${MTK_PLAT}/common/custom/oem_svc.c
-endif
-
-PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
- -I${MTK_PLAT}/common/drivers/uart \
- -I${MTK_PLAT_SOC}/ \
- -I${MTK_PLAT_SOC}/drivers/timer/ \
- -I${MTK_PLAT_SOC}/include/ \
- -Iinclude/plat/arm/common/ \
- ${OEMS_INCLUDES}
-
-PLAT_BL_COMMON_SOURCES := lib/xlat_tables/aarch64/xlat_tables.c \
- lib/xlat_tables/xlat_tables_common.c \
- plat/common/plat_gic.c
-
-BL31_SOURCES += drivers/arm/cci/cci.c \
- drivers/delay_timer/generic_delay_timer.c \
- drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
- plat/common/plat_gicv2.c \
- drivers/console/aarch64/console.S \
- drivers/delay_timer/delay_timer.c \
- lib/cpus/aarch64/cortex_a53.S \
- ${MTK_PLAT_SOC}/bl31_plat_setup.c \
- ${MTK_PLAT_SOC}/plat_mt_gic.c \
- ${MTK_PLAT}/common/mtk_sip_svc.c \
- ${MTK_PLAT}/common/mtk_plat_common.c \
- ${MTK_PLAT}/common/drivers/uart/8250_console.S \
- ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
- ${MTK_PLAT_SOC}/drivers/timer/mt_cpuxgpt.c \
- ${MTK_PLAT_SOC}/plat_delay_timer.c \
- ${MTK_PLAT_SOC}/plat_pm.c \
- ${MTK_PLAT_SOC}/plat_topology.c \
- ${MTK_PLAT_SOC}/power_tracer.c \
- ${MTK_PLAT_SOC}/scu.c \
- ${OEMS_SOURCES}
-
-# Enable workarounds for selected Cortex-A53 erratas.
-ERRATA_A53_826319 := 1
-ERRATA_A53_836870 := 1
-
-WORKAROUND_CVE_2017_5715 := 0
-
-# indicate the reset vector address can be programmed
-PROGRAMMABLE_RESET_ADDRESS := 1
-
-$(eval $(call add_define,MTK_SIP_KERNEL_BOOT_ENABLE))
-
-# Do not enable SVE
-ENABLE_SVE_FOR_NS := 0
diff --git a/plat/mediatek/mt6795/power_tracer.c b/plat/mediatek/mt6795/power_tracer.c
deleted file mode 100644
index 64d086d..0000000
--- a/plat/mediatek/mt6795/power_tracer.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <common/debug.h>
-
-#include <power_tracer.h>
-
-#define trace_log(...) INFO("psci: " __VA_ARGS__)
-
-void trace_power_flow(unsigned long mpidr, unsigned char mode)
-{
- switch (mode) {
- case CPU_UP:
- trace_log("core %lld:%lld ON\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
- (mpidr & MPIDR_CPU_MASK));
- break;
- case CPU_DOWN:
- trace_log("core %lld:%lld OFF\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
- (mpidr & MPIDR_CPU_MASK));
- break;
- case CPU_SUSPEND:
- trace_log("core %lld:%lld SUSPEND\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
- (mpidr & MPIDR_CPU_MASK));
- break;
- case CLUSTER_UP:
- trace_log("cluster %lld ON\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
- break;
- case CLUSTER_DOWN:
- trace_log("cluster %lld OFF\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
- break;
- case CLUSTER_SUSPEND:
- trace_log("cluster %lld SUSPEND\n",
- (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
- break;
- default:
- trace_log("unknown power mode\n");
- break;
- }
-}
diff --git a/plat/mediatek/mt6795/scu.c b/plat/mediatek/mt6795/scu.c
deleted file mode 100644
index 3b74527..0000000
--- a/plat/mediatek/mt6795/scu.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <lib/mmio.h>
-
-#include <mcucfg.h>
-
-void disable_scu(unsigned long mpidr)
-{
- if (mpidr & MPIDR_CLUSTER_MASK)
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp1_miscdbg,
- MP1_ACINACTM);
- else
- mmio_setbits_32((uintptr_t)&mt6795_mcucfg->mp0_axi_config,
- MP0_ACINACTM);
-}
-
-void enable_scu(unsigned long mpidr)
-{
- if (mpidr & MPIDR_CLUSTER_MASK)
- mmio_clrbits_32((uintptr_t)&mt6795_mcucfg->mp1_miscdbg,
- MP1_ACINACTM);
- else
- mmio_clrbits_32((uintptr_t)&mt6795_mcucfg->mp0_axi_config,
- MP0_ACINACTM);
-}
diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk
index f62802c..6bf1aa7 100644
--- a/plat/mediatek/mt8173/platform.mk
+++ b/plat/mediatek/mt8173/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,6 +8,7 @@
MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
+ -I${MTK_PLAT}/include/ \
-Iinclude/plat/arm/common/aarch64 \
-I${MTK_PLAT_SOC}/drivers/crypt/ \
-I${MTK_PLAT_SOC}/drivers/mtcmos/ \
@@ -36,10 +37,10 @@
lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a57.S \
lib/cpus/aarch64/cortex_a72.S \
- ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init.c \
- ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \
${MTK_PLAT}/common/mtk_plat_common.c \
${MTK_PLAT}/common/mtk_sip_svc.c \
+ ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init.c \
+ ${MTK_PLAT}/drivers/rtc/rtc_common.c \
${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
${MTK_PLAT_SOC}/aarch64/platform_common.c \
${MTK_PLAT_SOC}/bl31_plat_setup.c \
diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk
index 1615cf9..a737d24 100644
--- a/plat/mediatek/mt8183/platform.mk
+++ b/plat/mediatek/mt8183/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019, MediaTek Inc. All rights reserved.
+# Copyright (c) 2019-2022, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,7 +8,8 @@
MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
- -I${MTK_PLAT}/common/drivers/uart/ \
+ -I${MTK_PLAT}/drivers/uart/ \
+ -I${MTK_PLAT}/include/ \
-I${MTK_PLAT_SOC}/drivers/ \
-I${MTK_PLAT_SOC}/drivers/emi_mpu/ \
-I${MTK_PLAT_SOC}/drivers/devapc/ \
@@ -43,10 +44,10 @@
lib/cpus/aarch64/cortex_a73.S \
plat/common/plat_gicv3.c \
${MTK_PLAT}/common/mtk_plat_common.c \
- ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init.c \
- ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \
- ${MTK_PLAT}/common/drivers/uart/uart.c \
${MTK_PLAT}/common/params_setup.c \
+ ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init.c \
+ ${MTK_PLAT}/drivers/rtc/rtc_common.c \
+ ${MTK_PLAT}/drivers/uart/uart.c \
${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
${MTK_PLAT_SOC}/aarch64/platform_common.c \
${MTK_PLAT_SOC}/drivers/devapc/devapc.c \
diff --git a/plat/mediatek/mt8186/drivers/mcdi/mt_lp_irqremain.c b/plat/mediatek/mt8186/drivers/mcdi/mt_lp_irqremain.c
index 42b2808..b5a0284 100644
--- a/plat/mediatek/mt8186/drivers/mcdi/mt_lp_irqremain.c
+++ b/plat/mediatek/mt8186/drivers/mcdi/mt_lp_irqremain.c
@@ -4,9 +4,9 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <mt_cirq.h>
#include <mt_lp_irqremain.h>
#include <mt_lp_rm.h>
-#include <mtk_cirq.h>
#include <plat_mtk_lpm.h>
#define KEYPAD_IRQ_ID U(138)
diff --git a/plat/mediatek/mt8186/drivers/pmic/pmic_wrap_init.h b/plat/mediatek/mt8186/drivers/pmic/pmic_wrap_init.h
index e837456..e8cbf7e 100644
--- a/plat/mediatek/mt8186/drivers/pmic/pmic_wrap_init.h
+++ b/plat/mediatek/mt8186/drivers/pmic/pmic_wrap_init.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,10 +10,7 @@
#include <stdint.h>
#include "platform_def.h"
-
-/* external API */
-int32_t pwrap_read(uint32_t adr, uint32_t *rdata);
-int32_t pwrap_write(uint32_t adr, uint32_t wdata);
+#include <pmic_wrap_init_common.h>
static struct mt8186_pmic_wrap_regs *const mtk_pwrap = (void *)PMIC_WRAP_BASE;
@@ -61,34 +58,4 @@
WACS_SYNC_BUSY = 0x00
};
-/* error information flag */
-enum {
- E_PWR_INVALID_ARG = 1,
- E_PWR_INVALID_RW = 2,
- E_PWR_INVALID_ADDR = 3,
- E_PWR_INVALID_WDAT = 4,
- E_PWR_INVALID_OP_MANUAL = 5,
- E_PWR_NOT_IDLE_STATE = 6,
- E_PWR_NOT_INIT_DONE = 7,
- E_PWR_NOT_INIT_DONE_READ = 8,
- E_PWR_WAIT_IDLE_TIMEOUT = 9,
- E_PWR_WAIT_IDLE_TIMEOUT_READ = 10,
- E_PWR_INIT_SIDLY_FAIL = 11,
- E_PWR_RESET_TIMEOUT = 12,
- E_PWR_TIMEOUT = 13,
- E_PWR_INIT_RESET_SPI = 20,
- E_PWR_INIT_SIDLY = 21,
- E_PWR_INIT_REG_CLOCK = 22,
- E_PWR_INIT_ENABLE_PMIC = 23,
- E_PWR_INIT_DIO = 24,
- E_PWR_INIT_CIPHER = 25,
- E_PWR_INIT_WRITE_TEST = 26,
- E_PWR_INIT_ENABLE_CRC = 27,
- E_PWR_INIT_ENABLE_DEWRAP = 28,
- E_PWR_INIT_ENABLE_EVENT = 29,
- E_PWR_READ_TEST_FAIL = 30,
- E_PWR_WRITE_TEST_FAIL = 31,
- E_PWR_SWITCH_DIO = 32
-};
-
#endif /* PMIC_WRAP_INIT_H */
diff --git a/plat/mediatek/mt8186/drivers/spm/constraints/mt_spm_rc_bus26m.c b/plat/mediatek/mt8186/drivers/spm/constraints/mt_spm_rc_bus26m.c
index 66fbe91..dd2aee8 100644
--- a/plat/mediatek/mt8186/drivers/spm/constraints/mt_spm_rc_bus26m.c
+++ b/plat/mediatek/mt8186/drivers/spm/constraints/mt_spm_rc_bus26m.c
@@ -26,7 +26,7 @@
#include <mt_spm_suspend.h>
#ifndef ATF_PLAT_CIRQ_UNSUPPORT
-#include <mtk_cirq.h>
+#include <mt_cirq.h>
#endif
#include <plat_mtk_lpm.h>
diff --git a/plat/mediatek/mt8186/drivers/spm/notifier/mt_spm_sspm_notifier.c b/plat/mediatek/mt8186/drivers/spm/notifier/mt_spm_sspm_notifier.c
index 198bac5..20ef011 100644
--- a/plat/mediatek/mt8186/drivers/spm/notifier/mt_spm_sspm_notifier.c
+++ b/plat/mediatek/mt8186/drivers/spm/notifier/mt_spm_sspm_notifier.c
@@ -11,7 +11,7 @@
#include <mt_spm_sspm_intc.h>
#include <sspm_reg.h>
-#define MT_SPM_SSPM_MBOX_OFF(x) (SSPM_MBOX_3_BASE + x)
+#define MT_SPM_SSPM_MBOX_OFF(x) (SSPM_MBOX_BASE + x)
#define MT_SPM_MBOX(slot) MT_SPM_SSPM_MBOX_OFF((slot << 2UL))
#define SSPM_MBOX_SPM_LP_LOOKUP1 MT_SPM_MBOX(0)
diff --git a/plat/mediatek/mt8186/include/plat_sip_calls.h b/plat/mediatek/mt8186/include/plat_sip_calls.h
index 9e3726b..f5c15e3 100644
--- a/plat/mediatek/mt8186/include/plat_sip_calls.h
+++ b/plat/mediatek/mt8186/include/plat_sip_calls.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,10 +10,6 @@
/*******************************************************************************
* Plat SiP function constants
******************************************************************************/
-#define MTK_PLAT_SIP_NUM_CALLS (2)
-
-/* DFD */
-#define MTK_SIP_KERNEL_DFD_AARCH32 (0x82000205)
-#define MTK_SIP_KERNEL_DFD_AARCH64 (0xC2000205)
+#define MTK_PLAT_SIP_NUM_CALLS (6)
#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt8186/include/platform_def.h b/plat/mediatek/mt8186/include/platform_def.h
index b8b877a..850ce2f 100644
--- a/plat/mediatek/mt8186/include/platform_def.h
+++ b/plat/mediatek/mt8186/include/platform_def.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2021, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,6 +26,8 @@
#define INFRACFG_AO_BASE (IO_PHYS + 0x00001000)
#define SPM_BASE (IO_PHYS + 0x00006000)
#define APMIXEDSYS (IO_PHYS + 0x0000C000)
+#define SSPM_MCDI_SHARE_SRAM (IO_PHYS + 0x00420000)
+#define SSPM_CFGREG_BASE (IO_PHYS + 0x00440000) /* SSPM view: 0x30040000 */
#define SSPM_MBOX_BASE (IO_PHYS + 0x00480000)
#define PERICFG_AO_BASE (IO_PHYS + 0x01003000)
#define VPPSYS0_BASE (IO_PHYS + 0x04000000)
@@ -70,6 +72,11 @@
#define EMI_MPU_BASE (IO_PHYS + 0x0021B000)
/*******************************************************************************
+ * MSDC related constants
+ ******************************************************************************/
+#define MSDC0_BASE (IO_PHYS + 0x01230000)
+
+/*******************************************************************************
* GIC-600 & interrupt handling related constants
******************************************************************************/
/* Base MTK_platform compatible GIC memory map */
diff --git a/plat/mediatek/mt8186/include/sspm_reg.h b/plat/mediatek/mt8186/include/sspm_reg.h
index 3e8c3e2..40b71ac 100644
--- a/plat/mediatek/mt8186/include/sspm_reg.h
+++ b/plat/mediatek/mt8186/include/sspm_reg.h
@@ -9,12 +9,8 @@
#include "platform_def.h"
-#define SSPM_CFGREG_BASE (IO_PHYS + 0x440000) /* SSPM view: 0x30040000 */
#define SSPM_CFGREG_ADDR(ofs) (SSPM_CFGREG_BASE + (ofs))
-#define SSPM_MCDI_SHARE_SRAM (IO_PHYS + 0x420000)
-#define SSPM_MBOX_3_BASE (IO_PHYS + 0x480000)
-
#define SSPM_HW_SEM SSPM_CFGREG_ADDR(0x0048)
#define SSPM_ACAO_INT_SET SSPM_CFGREG_ADDR(0x00D8)
#define SSPM_ACAO_INT_CLR SSPM_CFGREG_ADDR(0x00DC)
diff --git a/plat/mediatek/mt8186/plat_sip_calls.c b/plat/mediatek/mt8186/plat_sip_calls.c
index cb66218..0e9c270 100644
--- a/plat/mediatek/mt8186/plat_sip_calls.c
+++ b/plat/mediatek/mt8186/plat_sip_calls.c
@@ -6,6 +6,8 @@
#include <common/debug.h>
#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <mt_msdc.h>
#include <mt_spm_vcorefs.h>
#include <mtk_sip_svc.h>
#include <plat_dfd.h>
@@ -23,8 +25,8 @@
uint64_t ret;
switch (smc_fid) {
- case MTK_SIP_VCORE_CONTROL_ARCH32:
- case MTK_SIP_VCORE_CONTROL_ARCH64:
+ case MTK_SIP_VCORE_CONTROL_AARCH32:
+ case MTK_SIP_VCORE_CONTROL_AARCH64:
ret = spm_vcorefs_args(x1, x2, x3, (uint64_t *)&x4);
SMC_RET2(handle, ret, x4);
break;
@@ -33,6 +35,11 @@
ret = dfd_smc_dispatcher(x1, x2, x3, x4);
SMC_RET1(handle, ret);
break;
+ case MTK_SIP_KERNEL_MSDC_AARCH32:
+ case MTK_SIP_KERNEL_MSDC_AARCH64:
+ ret = msdc_smc_dispatcher(x1, x2, x3, x4);
+ SMC_RET1(handle, ret);
+ break;
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
break;
diff --git a/plat/mediatek/mt8186/platform.mk b/plat/mediatek/mt8186/platform.mk
index b6d9ca8..6587970 100644
--- a/plat/mediatek/mt8186/platform.mk
+++ b/plat/mediatek/mt8186/platform.mk
@@ -8,16 +8,21 @@
MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
- -I${MTK_PLAT}/common/drivers/gic600/ \
- -I${MTK_PLAT}/common/drivers/gpio/ \
- -I${MTK_PLAT}/common/drivers/uart/ \
- -I${MTK_PLAT}/common/drivers/timer/ \
- -I${MTK_PLAT}/common/lpm/ \
+ -I${MTK_PLAT}/drivers/cirq/ \
+ -I${MTK_PLAT}/drivers/gic600/ \
+ -I${MTK_PLAT}/drivers/gpio/ \
+ -I${MTK_PLAT}/drivers/lpm/ \
+ -I${MTK_PLAT}/drivers/msdc/ \
+ -I${MTK_PLAT}/drivers/msdc/${PLAT} \
+ -I${MTK_PLAT}/drivers/pmic_wrap/ \
+ -I${MTK_PLAT}/drivers/timer/ \
+ -I${MTK_PLAT}/drivers/uart/ \
+ -I${MTK_PLAT}/include/ \
-I${MTK_PLAT_SOC}/drivers/spm/ \
-I${MTK_PLAT_SOC}/drivers/dcm/ \
- -I${MTK_PLAT_SOC}/drivers/dfd/ \
+ -I${MTK_PLAT_SOC}/drivers/dfd/ \
-I${MTK_PLAT_SOC}/drivers/emi_mpu/ \
- -I${MTK_PLAT_SOC}/drivers/gpio/ \
+ -I${MTK_PLAT_SOC}/drivers/gpio/ \
-I${MTK_PLAT_SOC}/drivers/mcdi/ \
-I${MTK_PLAT_SOC}/drivers/pmic/ \
-I${MTK_PLAT_SOC}/drivers/rtc/ \
@@ -43,17 +48,18 @@
lib/cpus/aarch64/cortex_a55.S \
lib/cpus/aarch64/cortex_a76.S \
plat/common/plat_gicv3.c \
- ${MTK_PLAT}/common/drivers/gic600/mt_gic_v3.c \
- ${MTK_PLAT}/common/drivers/gpio/mtgpio_common.c \
- ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init.c \
- ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \
${MTK_PLAT}/common/mtk_plat_common.c \
${MTK_PLAT}/common/mtk_sip_svc.c \
${MTK_PLAT}/common/params_setup.c \
- ${MTK_PLAT}/common/drivers/timer/mt_timer.c \
- ${MTK_PLAT}/common/drivers/uart/uart.c \
- ${MTK_PLAT}/common/mtk_cirq.c \
- ${MTK_PLAT}/common/lpm/mt_lp_rm.c \
+ ${MTK_PLAT}/drivers/cirq/mt_cirq.c \
+ ${MTK_PLAT}/drivers/gic600/mt_gic_v3.c \
+ ${MTK_PLAT}/drivers/gpio/mtgpio_common.c \
+ ${MTK_PLAT}/drivers/lpm/mt_lp_rm.c \
+ ${MTK_PLAT}/drivers/msdc/mt_msdc.c \
+ ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init.c \
+ ${MTK_PLAT}/drivers/rtc/rtc_common.c \
+ ${MTK_PLAT}/drivers/timer/mt_timer.c \
+ ${MTK_PLAT}/drivers/uart/uart.c \
${MTK_PLAT_SOC}/aarch64/platform_common.c \
${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
${MTK_PLAT_SOC}/bl31_plat_setup.c \
diff --git a/plat/mediatek/mt8188/aarch64/plat_helpers.S b/plat/mediatek/mt8188/aarch64/plat_helpers.S
new file mode 100644
index 0000000..7073ab1
--- /dev/null
+++ b/plat/mediatek/mt8188/aarch64/plat_helpers.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+ .globl plat_is_my_cpu_primary
+ .globl plat_my_core_pos
+ .globl plat_mediatek_calc_core_pos
+
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, #PLAT_PRIMARY_CPU
+ cset x0, eq
+ ret
+endfunc plat_is_my_cpu_primary
+
+ /* -----------------------------------------------------
+ * unsigned int plat_my_core_pos(void)
+ * This function uses the plat_mediatek_calc_core_pos()
+ * definition to get the index of the calling CPU.
+ * -----------------------------------------------------
+ */
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ b plat_mediatek_calc_core_pos
+endfunc plat_my_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
+ *
+ * With this function: CorePos = CoreID (AFF1)
+ * we do it with x0 = (x0 >> 8) & 0xff
+ * -----------------------------------------------------
+ */
+func plat_mediatek_calc_core_pos
+ mov x1, #MPIDR_AFFLVL_MASK
+ and x0, x1, x0, lsr #MPIDR_AFF1_SHIFT
+ ret
+endfunc plat_mediatek_calc_core_pos
diff --git a/plat/mediatek/mt8188/include/plat_helpers.h b/plat/mediatek/mt8188/include/plat_helpers.h
new file mode 100644
index 0000000..eb78623
--- /dev/null
+++ b/plat/mediatek/mt8188/include/plat_helpers.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_HELPERS_H
+#define PLAT_HELPERS_H
+
+unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
+
+#endif /* PLAT_HELPERS_H */
diff --git a/plat/mediatek/mt8188/include/plat_macros.S b/plat/mediatek/mt8188/include/plat_macros.S
new file mode 100644
index 0000000..a6e05a9
--- /dev/null
+++ b/plat/mediatek/mt8188/include/plat_macros.S
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <platform_def.h>
+
+.section .rodata.gic_reg_name, "aS"
+gicc_regs:
+ .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+gicd_pend_reg:
+ .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \
+ " Offset:\t\t\tvalue\n"
+newline:
+ .asciz "\n"
+spacer:
+ .asciz ":\t\t0x"
+
+.section .rodata.cci_reg_name, "aS"
+cci_iface_regs:
+ .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
+
+ /* ---------------------------------------------
+ * The below macro prints out relevant GIC
+ * registers whenever an unhandled exception
+ * is taken in BL31.
+ * Clobbers: x0 - x10, x26, x27, sp
+ * ---------------------------------------------
+ */
+ .macro plat_crash_print_regs
+ /* TODO: leave implementation to GIC owner */
+ .endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/mediatek/mt8188/include/plat_private.h b/plat/mediatek/mt8188/include/plat_private.h
new file mode 100644
index 0000000..4d4ac85
--- /dev/null
+++ b/plat/mediatek/mt8188/include/plat_private.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PRIVATE_H
+#define PLAT_PRIVATE_H
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void plat_configure_mmu_el3(uintptr_t total_base,
+ uintptr_t total_size,
+ uintptr_t ro_start,
+ uintptr_t ro_limit);
+
+#endif /* PLAT_PRIVATE_H */
diff --git a/plat/mediatek/mt8188/plat_config.mk b/plat/mediatek/mt8188/plat_config.mk
new file mode 100644
index 0000000..0c1e7cd
--- /dev/null
+++ b/plat/mediatek/mt8188/plat_config.mk
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Separate text code and read only data
+SEPARATE_CODE_AND_RODATA := 1
+# ARMv8.2 and above need enable HW assist coherence
+HW_ASSISTED_COHERENCY := 1
+# No need coherency memory because of HW assistency
+USE_COHERENT_MEM := 0
+# GIC600
+GICV3_SUPPORT_GIC600 := 1
+#
+# MTK options
+#
+PLAT_EXTRA_RODATA_INCLUDES := 1
+USE_PMIC_WRAP_INIT_V2 := 1
+USE_RTC_MT6359P := 1
+
+# Configs for A78 and A55
+CTX_INCLUDE_AARCH32_REGS := 0
+ERRATA_A55_1530923 := 1
+ERRATA_A55_1221012 := 1
+ERRATA_A78_1688305 := 1
+ERRATA_A78_1941498 := 1
+ERRATA_A78_1951500 := 1
+ERRATA_A78_1821534 := 1
+ERRATA_A78_2132060 := 1
+ERRATA_A78_2242635 := 1
+
+MACH_MT8188 := 1
+$(eval $(call add_define,MACH_MT8188))
diff --git a/plat/mediatek/mt8188/plat_mmap.c b/plat/mediatek/mt8188/plat_mmap.c
new file mode 100644
index 0000000..0d4cbe8
--- /dev/null
+++ b/plat/mediatek/mt8188/plat_mmap.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <mtk_mmap_pool.h>
+#include <platform_def.h>
+
+static const mmap_region_t plat_mmap[] = {
+ MAP_REGION_FLAT(MTK_DEV_RNG0_BASE, MTK_DEV_RNG0_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(MTK_DEV_RNG1_BASE, MTK_DEV_RNG1_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ { 0 }
+};
+DECLARE_MTK_MMAP_REGIONS(plat_mmap);
diff --git a/plat/mediatek/mt8188/plat_topology.c b/plat/mediatek/mt8188/plat_topology.c
new file mode 100644
index 0000000..9fa2855
--- /dev/null
+++ b/plat/mediatek/mt8188/plat_topology.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <lib/psci/psci.h>
+
+#include <plat_helpers.h>
+#include <platform_def.h>
+
+const unsigned char mtk_power_domain_tree_desc[] = {
+ /* Number of root nodes */
+ PLATFORM_SYSTEM_COUNT,
+ /* Number of children for the root node */
+ PLATFORM_MCUSYS_COUNT,
+ /* Number of children for the mcusys node */
+ PLATFORM_CLUSTER_COUNT,
+ /* Number of children for the first cluster node */
+ PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return mtk_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ unsigned int cluster_id, cpu_id;
+
+ if ((read_mpidr() & MPIDR_MT_MASK) != 0) {
+ /* ARMv8.2 arch */
+ if ((mpidr & (MPIDR_AFFLVL_MASK << MPIDR_AFF0_SHIFT)) != 0) {
+ return -1;
+ }
+ return plat_mediatek_calc_core_pos(mpidr);
+ }
+
+ mpidr &= MPIDR_AFFINITY_MASK;
+
+ if ((mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0) {
+ return -1;
+ }
+
+ cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+ cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+ if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+ return -1;
+ }
+
+ /*
+ * Validate cpu_id by checking whether it represents a CPU in
+ * one of the two clusters present on the platform.
+ */
+ if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
+ return -1;
+ }
+
+ return (cpu_id + (cluster_id * 8));
+}
diff --git a/plat/mediatek/mt8188/platform.mk b/plat/mediatek/mt8188/platform.mk
new file mode 100644
index 0000000..84bcfac
--- /dev/null
+++ b/plat/mediatek/mt8188/platform.mk
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 2022, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+MTK_PLAT := plat/mediatek
+MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
+MTK_SOC := ${PLAT}
+
+include plat/mediatek/build_helpers/mtk_build_helpers.mk
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_INCLUDES := -I${MTK_PLAT}/common \
+ -I${MTK_PLAT}/include \
+ -I${MTK_PLAT}/include/${MTK_SOC} \
+ -I${MTK_PLAT} \
+ -I${MTK_PLAT_SOC}/include \
+ -Idrivers/arm/gic \
+
+MODULES-y += $(MTK_PLAT)/common
+MODULES-y += $(MTK_PLAT)/lib/mtk_init
+MODULES-y += $(MTK_PLAT)/lib/pm
+MODULES-y += $(MTK_PLAT)/drivers/cirq
+MODULES-y += $(MTK_PLAT)/drivers/dp
+MODULES-y += $(MTK_PLAT)/drivers/gic600
+MODULES-y += $(MTK_PLAT)/drivers/gpio
+MODULES-y += $(MTK_PLAT)/drivers/iommu
+MODULES-y += $(MTK_PLAT)/drivers/pmic
+MODULES-y += $(MTK_PLAT)/drivers/pmic_wrap
+MODULES-y += $(MTK_PLAT)/drivers/rtc
+MODULES-y += $(MTK_PLAT)/drivers/timer
+
+PLAT_BL_COMMON_SOURCES := common/desc_image_load.c \
+ drivers/ti/uart/aarch64/16550_console.S \
+ lib/bl_aux_params/bl_aux_params.c
+
+BL31_SOURCES += drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ lib/cpus/aarch64/cortex_a55.S \
+ lib/cpus/aarch64/cortex_a78.S \
+ ${GICV3_SOURCES} \
+ ${XLAT_TABLES_LIB_SRCS} \
+ plat/common/plat_gicv3.c \
+ plat/common/plat_psci_common.c \
+ plat/common/aarch64/crash_console_helpers.S \
+ ${MTK_PLAT}/common/mtk_plat_common.c \
+ ${MTK_PLAT}/common/params_setup.c \
+ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
+ $(MTK_PLAT)/$(MTK_SOC)/plat_mmap.c \
+ $(MTK_PLAT)/$(MTK_SOC)/plat_topology.c
+
+include plat/mediatek/build_helpers/mtk_build_helpers_epilogue.mk
+
+include lib/coreboot/coreboot.mk
diff --git a/plat/mediatek/mt8192/drivers/mcdi/mt_lp_irqremain.c b/plat/mediatek/mt8192/drivers/mcdi/mt_lp_irqremain.c
index e74d3e7..872f4d0 100644
--- a/plat/mediatek/mt8192/drivers/mcdi/mt_lp_irqremain.c
+++ b/plat/mediatek/mt8192/drivers/mcdi/mt_lp_irqremain.c
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <mt_lp_rm.h>
+#include <mt_cirq.h>
#include <mt_lp_irqremain.h>
-#include <mtk_cirq.h>
+#include <mt_lp_rm.h>
#include <plat_mtk_lpm.h>
#define EDMA0_IRQ_ID U(448)
diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h b/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h
index ae892ed..b9ab586 100644
--- a/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h
+++ b/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,10 +10,7 @@
#include <stdint.h>
#include "platform_def.h"
-
-/* external API */
-int32_t pwrap_read(uint32_t adr, uint32_t *rdata);
-int32_t pwrap_write(uint32_t adr, uint32_t wdata);
+#include <pmic_wrap_init_common.h>
static struct mt8192_pmic_wrap_regs *const mtk_pwrap = (void *)PMIC_WRAP_BASE;
@@ -30,47 +27,4 @@
uint32_t wacs2_sta;
};
-#define GET_WACS_FSM(x) ((x >> 1) & 0x7)
-
-/* macro for SWINF_FSM */
-#define SWINF_FSM_IDLE (0x00)
-#define SWINF_FSM_REQ (0x02)
-#define SWINF_FSM_WFDLE (0x04)
-#define SWINF_FSM_WFVLDCLR (0x06)
-#define SWINF_INIT_DONE (0x01)
-
-/* timeout setting */
-#define PWRAP_READ_US 1000
-#define PWRAP_WAIT_IDLE_US 1000
-
-/* error information flag */
-enum pwrap_errno {
- E_PWR_INVALID_ARG = 1,
- E_PWR_INVALID_RW = 2,
- E_PWR_INVALID_ADDR = 3,
- E_PWR_INVALID_WDAT = 4,
- E_PWR_INVALID_OP_MANUAL = 5,
- E_PWR_NOT_IDLE_STATE = 6,
- E_PWR_NOT_INIT_DONE = 7,
- E_PWR_NOT_INIT_DONE_READ = 8,
- E_PWR_WAIT_IDLE_TIMEOUT = 9,
- E_PWR_WAIT_IDLE_TIMEOUT_READ = 10,
- E_PWR_INIT_SIDLY_FAIL = 11,
- E_PWR_RESET_TIMEOUT = 12,
- E_PWR_TIMEOUT = 13,
- E_PWR_INIT_RESET_SPI = 20,
- E_PWR_INIT_SIDLY = 21,
- E_PWR_INIT_REG_CLOCK = 22,
- E_PWR_INIT_ENABLE_PMIC = 23,
- E_PWR_INIT_DIO = 24,
- E_PWR_INIT_CIPHER = 25,
- E_PWR_INIT_WRITE_TEST = 26,
- E_PWR_INIT_ENABLE_CRC = 27,
- E_PWR_INIT_ENABLE_DEWRAP = 28,
- E_PWR_INIT_ENABLE_EVENT = 29,
- E_PWR_READ_TEST_FAIL = 30,
- E_PWR_WRITE_TEST_FAIL = 31,
- E_PWR_SWITCH_DIO = 32
-};
-
#endif /* PMIC_WRAP_INIT_H */
diff --git a/plat/mediatek/mt8192/drivers/spm/constraints/mt_spm_rc_bus26m.c b/plat/mediatek/mt8192/drivers/spm/constraints/mt_spm_rc_bus26m.c
index f66b8ec..18c43b1 100644
--- a/plat/mediatek/mt8192/drivers/spm/constraints/mt_spm_rc_bus26m.c
+++ b/plat/mediatek/mt8192/drivers/spm/constraints/mt_spm_rc_bus26m.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,8 +23,8 @@
#include <plat_mtk_lpm.h>
#ifndef ATF_PLAT_CIRQ_UNSUPPORT
+#include <mt_cirq.h>
#include <mt_gic_v3.h>
-#include <mtk_cirq.h>
#endif
#define CONSTRAINT_BUS26M_ALLOW \
diff --git a/plat/mediatek/mt8192/include/plat_sip_calls.h b/plat/mediatek/mt8192/include/plat_sip_calls.h
index f68a4ea..fdc7bea 100644
--- a/plat/mediatek/mt8192/include/plat_sip_calls.h
+++ b/plat/mediatek/mt8192/include/plat_sip_calls.h
@@ -10,10 +10,6 @@
/*******************************************************************************
* Plat SiP function constants
******************************************************************************/
-#define MTK_PLAT_SIP_NUM_CALLS 2
-
-/* DFD */
-#define MTK_SIP_KERNEL_DFD_AARCH32 0x82000205
-#define MTK_SIP_KERNEL_DFD_AARCH64 0xC2000205
+#define MTK_PLAT_SIP_NUM_CALLS (4)
#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt8192/plat_sip_calls.c b/plat/mediatek/mt8192/plat_sip_calls.c
index 353faf8..0fffed5 100644
--- a/plat/mediatek/mt8192/plat_sip_calls.c
+++ b/plat/mediatek/mt8192/plat_sip_calls.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,8 +25,8 @@
uint32_t rnd_val0 = 0U;
switch (smc_fid) {
- case MTK_SIP_VCORE_CONTROL_ARCH32:
- case MTK_SIP_VCORE_CONTROL_ARCH64:
+ case MTK_SIP_VCORE_CONTROL_AARCH32:
+ case MTK_SIP_VCORE_CONTROL_AARCH64:
ret = spm_vcorefs_args(x1, x2, x3, (uint64_t *)&x4);
SMC_RET2(handle, ret, x4);
break;
diff --git a/plat/mediatek/mt8192/platform.mk b/plat/mediatek/mt8192/platform.mk
index cbdaadd..efc14ec 100644
--- a/plat/mediatek/mt8192/platform.mk
+++ b/plat/mediatek/mt8192/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020, MediaTek Inc. All rights reserved.
+# Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,12 +8,16 @@
MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
- -I${MTK_PLAT}/common/drivers/gic600/ \
- -I${MTK_PLAT}/common/drivers/gpio/ \
- -I${MTK_PLAT}/common/drivers/rtc/ \
- -I${MTK_PLAT}/common/drivers/timer/ \
- -I${MTK_PLAT}/common/drivers/uart/ \
- -I${MTK_PLAT}/common/lpm/ \
+ -I${MTK_PLAT}/drivers/cirq/ \
+ -I${MTK_PLAT}/drivers/gic600/ \
+ -I${MTK_PLAT}/drivers/gpio/ \
+ -I${MTK_PLAT}/drivers/lpm/ \
+ -I${MTK_PLAT}/drivers/pmic/ \
+ -I${MTK_PLAT}/drivers/pmic_wrap/ \
+ -I${MTK_PLAT}/drivers/rtc/ \
+ -I${MTK_PLAT}/drivers/timer/ \
+ -I${MTK_PLAT}/drivers/uart/ \
+ -I${MTK_PLAT}/include/ \
-I${MTK_PLAT_SOC}/include/ \
-I${MTK_PLAT_SOC}/drivers/ \
-I${MTK_PLAT_SOC}/drivers/apusys/ \
@@ -45,22 +49,22 @@
lib/cpus/aarch64/cortex_a55.S \
lib/cpus/aarch64/cortex_a76.S \
plat/common/plat_gicv3.c \
- ${MTK_PLAT}/common/drivers/gic600/mt_gic_v3.c \
- ${MTK_PLAT}/common/drivers/gpio/mtgpio_common.c \
- ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init_v2.c \
- ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \
- ${MTK_PLAT}/common/drivers/rtc/rtc_mt6359p.c \
- ${MTK_PLAT}/common/drivers/timer/mt_timer.c \
- ${MTK_PLAT}/common/drivers/uart/uart.c \
- ${MTK_PLAT}/common/lpm/mt_lp_rm.c \
- ${MTK_PLAT}/common/mtk_cirq.c \
${MTK_PLAT}/common/mtk_plat_common.c \
${MTK_PLAT}/common/mtk_sip_svc.c \
${MTK_PLAT}/common/params_setup.c \
+ ${MTK_PLAT}/drivers/cirq/mt_cirq.c \
+ ${MTK_PLAT}/drivers/gic600/mt_gic_v3.c \
+ ${MTK_PLAT}/drivers/gpio/mtgpio_common.c \
+ ${MTK_PLAT}/drivers/lpm/mt_lp_rm.c \
+ ${MTK_PLAT}/drivers/pmic/pmic.c \
+ ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init_v2.c \
+ ${MTK_PLAT}/drivers/rtc/rtc_common.c \
+ ${MTK_PLAT}/drivers/rtc/rtc_mt6359p.c \
+ ${MTK_PLAT}/drivers/timer/mt_timer.c \
+ ${MTK_PLAT}/drivers/uart/uart.c \
${MTK_PLAT_SOC}/aarch64/platform_common.c \
${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
${MTK_PLAT_SOC}/bl31_plat_setup.c \
- ${MTK_PLAT_SOC}/drivers/pmic/pmic.c \
${MTK_PLAT_SOC}/plat_pm.c \
${MTK_PLAT_SOC}/plat_topology.c \
${MTK_PLAT_SOC}/plat_sip_calls.c \
diff --git a/plat/mediatek/mt8195/aarch64/platform_common.c b/plat/mediatek/mt8195/aarch64/platform_common.c
index 2b95171..1f5c5fa 100644
--- a/plat/mediatek/mt8195/aarch64/platform_common.c
+++ b/plat/mediatek/mt8195/aarch64/platform_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,7 +19,7 @@
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(DP_SEC_BASE, DP_SEC_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(eDP_SEC_BASE, eDP_SEC_SIZE,
+ MAP_REGION_FLAT(EDP_SEC_BASE, EDP_SEC_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(APUSYS_SCTRL_REVISER_BASE, APUSYS_SCTRL_REVISER_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
diff --git a/plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.c b/plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.c
index 4147184..f415cb8 100644
--- a/plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.c
+++ b/plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.c
@@ -1,15 +1,14 @@
/*
- * Copyright (c) 2021, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <mt_lp_rm.h>
+#include <mt_cirq.h>
#include <mt_lp_irqremain.h>
-#include <mtk_cirq.h>
+#include <mt_lp_rm.h>
#include <plat_mtk_lpm.h>
-
#define KEYPAD_IRQ_ID U(138)
#define KEYPAD_WAKESRC 0x4
diff --git a/plat/mediatek/mt8195/drivers/pmic/pmic.c b/plat/mediatek/mt8195/drivers/pmic/pmic.c
deleted file mode 100644
index cca4413..0000000
--- a/plat/mediatek/mt8195/drivers/pmic/pmic.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <pmic.h>
-#include <pmic_wrap_init.h>
-
-void pmic_power_off(void)
-{
- pwrap_write(PMIC_PWRHOLD, 0x0);
-}
diff --git a/plat/mediatek/mt8195/drivers/pmic/pmic.h b/plat/mediatek/mt8195/drivers/pmic/pmic.h
deleted file mode 100644
index aac22af..0000000
--- a/plat/mediatek/mt8195/drivers/pmic/pmic.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PMIC_H
-#define PMIC_H
-
-#define PMIC_PWRHOLD 0xa08
-
-/* external API */
-void pmic_power_off(void);
-
-#endif /* PMIC_H */
diff --git a/plat/mediatek/mt8195/drivers/pmic/pmic_wrap_init.h b/plat/mediatek/mt8195/drivers/pmic/pmic_wrap_init.h
index 39e78f5..9e6e74c 100644
--- a/plat/mediatek/mt8195/drivers/pmic/pmic_wrap_init.h
+++ b/plat/mediatek/mt8195/drivers/pmic/pmic_wrap_init.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,10 +10,7 @@
#include <stdint.h>
#include "platform_def.h"
-
-/* external API */
-int32_t pwrap_read(uint32_t adr, uint32_t *rdata);
-int32_t pwrap_write(uint32_t adr, uint32_t wdata);
+#include <pmic_wrap_init_common.h>
static struct mt8195_pmic_wrap_regs *const mtk_pwrap = (void *)PMIC_WRAP_BASE;
@@ -30,47 +27,4 @@
uint32_t wacs2_sta;
};
-#define GET_WACS_FSM(x) ((x >> 1) & 0x7)
-
-/* macro for SWINF_FSM */
-#define SWINF_FSM_IDLE (0x00)
-#define SWINF_FSM_REQ (0x02)
-#define SWINF_FSM_WFDLE (0x04)
-#define SWINF_FSM_WFVLDCLR (0x06)
-#define SWINF_INIT_DONE (0x01)
-
-/* timeout setting */
-#define PWRAP_READ_US 1000
-#define PWRAP_WAIT_IDLE_US 1000
-
-/* error information flag */
-enum pwrap_errno {
- E_PWR_INVALID_ARG = 1,
- E_PWR_INVALID_RW = 2,
- E_PWR_INVALID_ADDR = 3,
- E_PWR_INVALID_WDAT = 4,
- E_PWR_INVALID_OP_MANUAL = 5,
- E_PWR_NOT_IDLE_STATE = 6,
- E_PWR_NOT_INIT_DONE = 7,
- E_PWR_NOT_INIT_DONE_READ = 8,
- E_PWR_WAIT_IDLE_TIMEOUT = 9,
- E_PWR_WAIT_IDLE_TIMEOUT_READ = 10,
- E_PWR_INIT_SIDLY_FAIL = 11,
- E_PWR_RESET_TIMEOUT = 12,
- E_PWR_TIMEOUT = 13,
- E_PWR_INIT_RESET_SPI = 20,
- E_PWR_INIT_SIDLY = 21,
- E_PWR_INIT_REG_CLOCK = 22,
- E_PWR_INIT_ENABLE_PMIC = 23,
- E_PWR_INIT_DIO = 24,
- E_PWR_INIT_CIPHER = 25,
- E_PWR_INIT_WRITE_TEST = 26,
- E_PWR_INIT_ENABLE_CRC = 27,
- E_PWR_INIT_ENABLE_DEWRAP = 28,
- E_PWR_INIT_ENABLE_EVENT = 29,
- E_PWR_READ_TEST_FAIL = 30,
- E_PWR_WRITE_TEST_FAIL = 31,
- E_PWR_SWITCH_DIO = 32
-};
-
#endif /* PMIC_WRAP_INIT_H */
diff --git a/plat/mediatek/mt8195/drivers/spm/constraints/mt_spm_rc_bus26m.c b/plat/mediatek/mt8195/drivers/spm/constraints/mt_spm_rc_bus26m.c
index d2ad282..87278d7 100644
--- a/plat/mediatek/mt8195/drivers/spm/constraints/mt_spm_rc_bus26m.c
+++ b/plat/mediatek/mt8195/drivers/spm/constraints/mt_spm_rc_bus26m.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,8 +23,8 @@
#include <plat_mtk_lpm.h>
#ifndef ATF_PLAT_CIRQ_UNSUPPORT
+#include <mt_cirq.h>
#include <mt_gic_v3.h>
-#include <mtk_cirq.h>
#endif
#define CONSTRAINT_BUS26M_ALLOW \
diff --git a/plat/mediatek/mt8195/include/plat_sip_calls.h b/plat/mediatek/mt8195/include/plat_sip_calls.h
index 5562a67..7d1f9fc 100644
--- a/plat/mediatek/mt8195/include/plat_sip_calls.h
+++ b/plat/mediatek/mt8195/include/plat_sip_calls.h
@@ -10,18 +10,6 @@
/*******************************************************************************
* Plat SiP function constants
******************************************************************************/
-#define MTK_PLAT_SIP_NUM_CALLS 6
-
-/* DFD */
-#define MTK_SIP_KERNEL_DFD_AARCH32 0x82000205
-#define MTK_SIP_KERNEL_DFD_AARCH64 0xC2000205
-
-/* DP/eDP */
-#define MTK_SIP_DP_CONTROL_AARCH32 0x82000523
-#define MTK_SIP_DP_CONTROL_AARCH64 0xC2000523
-
-/* APUSYS SMC call */
-#define MTK_SIP_APUSYS_CONTROL_AARCH32 0x8200051E
-#define MTK_SIP_APUSYS_CONTROL_AARCH64 0xC200051E
+#define MTK_PLAT_SIP_NUM_CALLS (8)
#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h
index d4f2f83..2a2f559 100644
--- a/plat/mediatek/mt8195/include/platform_def.h
+++ b/plat/mediatek/mt8195/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -48,9 +48,9 @@
/*******************************************************************************
* DP/eDP related constants
******************************************************************************/
-#define eDP_SEC_BASE (IO_PHYS + 0x0C504000)
+#define EDP_SEC_BASE (IO_PHYS + 0x0C504000)
#define DP_SEC_BASE (IO_PHYS + 0x0C604000)
-#define eDP_SEC_SIZE 0x1000
+#define EDP_SEC_SIZE 0x1000
#define DP_SEC_SIZE 0x1000
/*******************************************************************************
diff --git a/plat/mediatek/mt8195/plat_sip_calls.c b/plat/mediatek/mt8195/plat_sip_calls.c
index 7d3c512..1cdd622 100644
--- a/plat/mediatek/mt8195/plat_sip_calls.c
+++ b/plat/mediatek/mt8195/plat_sip_calls.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,8 +32,8 @@
ret = dp_secure_handler(x1, x2, &ret_val);
SMC_RET2(handle, ret, ret_val);
break;
- case MTK_SIP_VCORE_CONTROL_ARCH32:
- case MTK_SIP_VCORE_CONTROL_ARCH64:
+ case MTK_SIP_VCORE_CONTROL_AARCH32:
+ case MTK_SIP_VCORE_CONTROL_AARCH64:
ret = spm_vcorefs_v2_args(x1, x2, x3, &x4);
SMC_RET2(handle, ret, x4);
break;
diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk
index a81c093..414d655 100644
--- a/plat/mediatek/mt8195/platform.mk
+++ b/plat/mediatek/mt8195/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2021, MediaTek Inc. All rights reserved.
+# Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,22 +8,26 @@
MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
- -I${MTK_PLAT}/common/drivers/gic600/ \
- -I${MTK_PLAT}/common/drivers/gpio/ \
- -I${MTK_PLAT}/common/drivers/rtc/ \
- -I${MTK_PLAT}/common/drivers/timer/ \
- -I${MTK_PLAT}/common/drivers/uart/ \
- -I${MTK_PLAT}/common/lpm/ \
+ -I${MTK_PLAT}/drivers/cirq/ \
+ -I${MTK_PLAT}/drivers/dp/ \
+ -I${MTK_PLAT}/drivers/gic600/ \
+ -I${MTK_PLAT}/drivers/gpio/ \
+ -I${MTK_PLAT}/drivers/lpm/ \
+ -I${MTK_PLAT}/drivers/pmic/ \
+ -I${MTK_PLAT}/drivers/pmic_wrap/ \
+ -I${MTK_PLAT}/drivers/rtc/ \
+ -I${MTK_PLAT}/drivers/timer/ \
+ -I${MTK_PLAT}/drivers/uart/ \
+ -I${MTK_PLAT}/include/ \
-I${MTK_PLAT_SOC}/drivers/apusys/ \
-I${MTK_PLAT_SOC}/drivers/dcm \
-I${MTK_PLAT_SOC}/drivers/dfd \
- -I${MTK_PLAT_SOC}/drivers/dp/ \
-I${MTK_PLAT_SOC}/drivers/emi_mpu/ \
-I${MTK_PLAT_SOC}/drivers/gpio/ \
-I${MTK_PLAT_SOC}/drivers/mcdi/ \
-I${MTK_PLAT_SOC}/drivers/pmic/ \
-I${MTK_PLAT_SOC}/drivers/spmc/ \
- -I${MTK_PLAT_SOC}/drivers/ptp3/ \
+ -I${MTK_PLAT_SOC}/drivers/ptp3/ \
-I${MTK_PLAT_SOC}/include/
GICV3_SUPPORT_GIC600 := 1
@@ -45,36 +49,36 @@
lib/cpus/aarch64/cortex_a55.S \
lib/cpus/aarch64/cortex_a78.S \
plat/common/plat_gicv3.c \
- ${MTK_PLAT}/common/drivers/gic600/mt_gic_v3.c \
- ${MTK_PLAT}/common/drivers/gpio/mtgpio_common.c \
- ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init_v2.c \
- ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \
- ${MTK_PLAT}/common/drivers/rtc/rtc_mt6359p.c \
- ${MTK_PLAT}/common/drivers/timer/mt_timer.c \
- ${MTK_PLAT}/common/drivers/uart/uart.c \
- ${MTK_PLAT}/common/lpm/mt_lp_rm.c \
- ${MTK_PLAT}/common/mtk_cirq.c \
${MTK_PLAT}/common/mtk_plat_common.c \
${MTK_PLAT}/common/mtk_sip_svc.c \
${MTK_PLAT}/common/params_setup.c \
+ ${MTK_PLAT}/drivers/cirq/mt_cirq.c \
+ ${MTK_PLAT}/drivers/dp/mt_dp.c \
+ ${MTK_PLAT}/drivers/gic600/mt_gic_v3.c \
+ ${MTK_PLAT}/drivers/gpio/mtgpio_common.c \
+ ${MTK_PLAT}/drivers/lpm/mt_lp_rm.c \
+ ${MTK_PLAT}/drivers/pmic/pmic.c \
+ ${MTK_PLAT}/drivers/pmic_wrap/pmic_wrap_init_v2.c \
+ ${MTK_PLAT}/drivers/rtc/rtc_common.c \
+ ${MTK_PLAT}/drivers/rtc/rtc_mt6359p.c \
+ ${MTK_PLAT}/drivers/timer/mt_timer.c \
+ ${MTK_PLAT}/drivers/uart/uart.c \
${MTK_PLAT_SOC}/aarch64/platform_common.c \
${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
${MTK_PLAT_SOC}/bl31_plat_setup.c \
${MTK_PLAT_SOC}/drivers/apusys/apupll.c \
${MTK_PLAT_SOC}/drivers/apusys/apupwr_clkctl.c \
- ${MTK_PLAT_SOC}/drivers/apusys/mtk_apusys.c \
+ ${MTK_PLAT_SOC}/drivers/apusys/mtk_apusys.c \
${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm.c \
${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm_utils.c \
${MTK_PLAT_SOC}/drivers/dfd/plat_dfd.c \
- ${MTK_PLAT_SOC}/drivers/dp/mt_dp.c \
${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \
${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \
${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm.c \
${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm_cpc.c \
${MTK_PLAT_SOC}/drivers/mcdi/mt_mcdi.c \
- ${MTK_PLAT_SOC}/drivers/mcdi/mt_lp_irqremain.c \
+ ${MTK_PLAT_SOC}/drivers/mcdi/mt_lp_irqremain.c \
${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \
- ${MTK_PLAT_SOC}/drivers/pmic/pmic.c \
${MTK_PLAT_SOC}/drivers/ptp3/mtk_ptp3_main.c \
${MTK_PLAT_SOC}/drivers/spmc/mtspmc.c \
${MTK_PLAT_SOC}/plat_pm.c \
diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c
index dbd6272..02f6158 100644
--- a/plat/nvidia/tegra/soc/t194/plat_ras.c
+++ b/plat/nvidia/tegra/soc/t194/plat_ras.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -152,12 +152,6 @@
/* enable specified errors, or set to 0 if no supported error */
write_erxctlr_el1(err_ctrl);
-
- /*
- * Check if all the bit settings have been enabled to detect
- * uncorrected/corrected errors, if not assert.
- */
- assert(read_erxctlr_el1() == err_ctrl);
}
}
}
diff --git a/plat/nxp/common/img_loadr/load_img.c b/plat/nxp/common/img_loadr/load_img.c
index c185c36..51011e4 100644
--- a/plat/nxp/common/img_loadr/load_img.c
+++ b/plat/nxp/common/img_loadr/load_img.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -49,10 +49,14 @@
/* Create MMU entry for the CSF header */
#if PLAT_XLAT_TABLES_DYNAMIC
#ifdef CSF_HEADER_PREPENDED
- mmap_add_dynamic_region(img_info.image_info.image_base,
+ err = mmap_add_dynamic_region(img_info.image_info.image_base,
img_info.image_info.image_base,
CSF_HDR_SZ,
MT_MEMORY | MT_RW | MT_SECURE);
+ if (err != 0) {
+ ERROR("Failed to add dynamic memory region.\n");
+ return err;
+ }
#endif
#endif
diff --git a/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h b/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h
index e8a7645..8d64f04 100644
--- a/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h
+++ b/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -15,12 +15,13 @@
#define NXP_DCSR_ADDR 0x700000000
#define NXP_DCSR_SIZE 0x40000000
-/* Flex-SPI controller address */
-#define NXP_FLEXSPI_ADDR 0x020C0000
-/* Flex-SPI Flash Start address */
-#define NXP_FLEXSPI_FLASH_ADDR 0x20000000
+/* Quad SPI Region #1 base address */
+#define NXP_QSPI_FLASH_ADDR 0x20000000
-/* MMU 500 soc.c*/
+/* IFC Region #1 base address */
+#define NXP_NOR_FLASH_ADDR 0x30000000
+
+/* MMU 500 */
#define NXP_SMMU_ADDR 0x05000000
#define NXP_SNVS_ADDR 0x01E90000
@@ -34,8 +35,12 @@
#define NXP_I2C_ADDR 0x02000000
#define NXP_ESDHC_ADDR 0x02140000
#define NXP_ESDHC2_ADDR 0x02150000
-#define NXP_UART_ADDR 0x021C0000
-#define NXP_UART1_ADDR 0x021D0000
+#ifndef NXP_UART_ADDR
+#define NXP_UART_ADDR 0x021C0500
+#endif
+#ifndef NXP_UART1_ADDR
+#define NXP_UART1_ADDR 0x021C0600
+#endif
#define NXP_GPIO1_ADDR 0x02300000
#define NXP_GPIO2_ADDR 0x02310000
@@ -50,8 +55,8 @@
#define NXP_TIMER_STATUS_ADDR 0x023F0000
#define NXP_GICD_ADDR 0x06000000
-#define NXP_GICR_ADDR 0x06200000
-#define NXP_GICR_SGI_ADDR 0x06210000
+#define NXP_GICR_ADDR 0x06100000
+#define NXP_GICR_SGI_ADDR 0x06110000
#define NXP_CAAM_ADDR 0x08000000
@@ -61,4 +66,35 @@
#define NXP_RESET_ADDR 0x01E60000
#define NXP_SEC_REGFILE_ADDR 0x01E88000
-#endif /* SOC_DEFAULT_BASE_ADDR_H */
+
+#define NXP_RST_ADDR 0x01E88000
+
+/* DDR memory Map */
+#define NXP_DDR_ADDR 0x01080000
+#define NXP_DDR2_ADDR 0x01090000
+#define NXP_DDR3_ADDR 0x08210000
+
+/* QuadSPI base address */
+#define NXP_QSPI_ADDR 0x020C0000
+/* IFC base address */
+#define NXP_IFC_ADDR 0x02240000
+
+/* CCI400 base address */
+#define NXP_CCI_ADDR 0x04090000
+
+/* Global Generic Reference Timer base address */
+#define NXP_TIMER_ADDR 0x023E0000
+
+/* OCRAM TZPC base address */
+#define NXP_OCRAM_TZPC_ADDR 0x02200000
+
+#define NXP_EPU_ADDR 0x700060000
+
+#define NXP_CCN_ADDR 0x04000000
+#define NXP_CCN_HNI_ADDR 0x04080000
+#define NXP_CCN_HN_F_0_ADDR 0x04200000
+#define NXP_CCN_HN_F_1_ADDR 0x04210000
+
+#define TPMWAKEMR0_ADDR 0x700123c50
+
+#endif /* SOC_DEFAULT_BASE_ADDR_H */
diff --git a/plat/nxp/common/include/default/ch_3/soc_default_helper_macros.h b/plat/nxp/common/include/default/ch_3/soc_default_helper_macros.h
new file mode 100644
index 0000000..8e68367
--- /dev/null
+++ b/plat/nxp/common/include/default/ch_3/soc_default_helper_macros.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef SOC_DEFAULT_HELPER_MACROS_H
+#define SOC_DEFAULT_HELPER_MACROS_H
+
+#ifdef NXP_OCRAM_TZPC_ADDR
+#define TZPC_BLOCK_SIZE 0x1000
+#endif
+
+/* Reset block register offsets */
+#ifdef NXP_RESET_ADDR
+
+/* Register Offset */
+#define RST_RSTCR_OFFSET 0x0
+#define RST_RSTRQMR1_OFFSET 0x10
+#define RST_RSTRQSR1_OFFSET 0x18
+#define BRR_OFFSET 0x60
+
+/* helper macros */
+#define RSTRQMR_RPTOE_MASK (1 << 19)
+#endif /* NXP_RESET_ADDR */
+
+#define PCIeRC_RN_I_NODE_ID_OFFSET 0x8
+#define PoS_CONTROL_REG_OFFSET 0x0
+#define POS_EARLY_WR_COMP_EN 0x20
+#define HNI_POS_EN 0x01
+#define POS_TERMINATE_BARRIERS 0x10
+#define SERIALIZE_DEV_nGnRnE_WRITES 0x200
+#define ENABLE_ERR_SIGNAL_TO_MN 0x4
+#define ENABLE_RESERVE_BIT53 0x400
+#define ENABLE_WUO 0x10
+
+#define PORT_S0_CTRL_REG_RNI 0x010
+#define PORT_S1_CTRL_REG_RNI 0x110
+#define PORT_S2_CTRL_REG_RNI 0x210
+#define ENABLE_FORCE_RD_QUO 0x20
+#define QOS_SETTING 0x00FF000C
+
+/* epu register offsets and values */
+#define EPU_EPGCR_OFFSET 0x0
+#define EPU_EPIMCR10_OFFSET 0x128
+#define EPU_EPCTR10_OFFSET 0xa28
+#define EPU_EPCCR10_OFFSET 0x828
+#ifndef EPU_EPCCR10_VAL
+#define EPU_EPCCR10_VAL 0xb2800000
+#endif
+#define EPU_EPIMCR10_VAL 0xba000000
+#define EPU_EPCTR10_VAL 0x0
+#define EPU_EPGCR_VAL (1 << 31)
+
+#ifdef NXP_CCN_ADDR
+#define NXP_CCN_HN_F_1_ADDR 0x04210000
+
+#define CCN_HN_F_SAM_NODEID_MASK 0x7f
+#define CCN_HN_F_SNP_DMN_CTL_OFFSET 0x200
+#define CCN_HN_F_SNP_DMN_CTL_SET_OFFSET 0x210
+#define CCN_HN_F_SNP_DMN_CTL_CLR_OFFSET 0x220
+#define CCN_HN_F_SNP_DMN_CTL_MASK 0x80a00
+#define CCN_HNF_NODE_COUNT 8
+#define CCN_HNF_OFFSET 0x10000
+
+#define SA_AUX_CTRL_REG_OFFSET 0x500
+#define NUM_HNI_NODE 2
+#define CCN_HNI_MEMORY_MAP_SIZE 0x10000
+
+#define PCIeRC_RN_I_NODE_ID_OFFSET 0x8
+#define PoS_CONTROL_REG_OFFSET 0x0
+#define POS_EARLY_WR_COMP_EN 0x20
+#define HNI_POS_EN 0x01
+#define POS_TERMINATE_BARRIERS 0x10
+#define SERIALIZE_DEV_nGnRnE_WRITES 0x200
+#define ENABLE_ERR_SIGNAL_TO_MN 0x4
+#define ENABLE_RESERVE_BIT53 0x400
+#define ENABLE_WUO 0x10
+#endif
+
+/* reset register bit */
+#define RSTRQMR_RPTOE_MASK (1 << 19)
+
+/* secmon register offsets and bitfields */
+#define SECMON_HPCOMR_OFFSET 0x4
+#define SECMON_HPCOMR_NPSWAEN 0x80000000
+
+/* Secure-Register-File register offsets and bit masks */
+#ifdef NXP_RST_ADDR
+/* Register Offset */
+#define CORE_HOLD_OFFSET 0x140
+#endif
+
+#define DCFG_SBEESR2_ADDR 0x00100534
+#define DCFG_MBEESR2_ADDR 0x00100544
+/* SBEESR and MBEESR bit mask */
+#define OCRAM_EESR_MASK 0x00000008
+
+#endif /* SOC_DEFAULT_HELPER_MACROS_H */
diff --git a/plat/nxp/common/plat_make_helper/soc_common_def.mk b/plat/nxp/common/plat_make_helper/soc_common_def.mk
index 22cd39a..52f2867 100644
--- a/plat/nxp/common/plat_make_helper/soc_common_def.mk
+++ b/plat/nxp/common/plat_make_helper/soc_common_def.mk
@@ -1,4 +1,4 @@
-# Copyright 2020-2021 NXP
+# Copyright 2020-2022 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -11,14 +11,12 @@
$(eval $(call add_define_val,CACHE_WRITEBACK_GRANULE,$(CACHE_WRITEBACK_GRANULE)))
endif
-ifeq (${INTERCONNECT}, "CCI400")
+ifneq (${INTERCONNECT},)
$(eval $(call add_define,NXP_HAS_${INTERCONNECT}))
+ifeq (${INTERCONNECT}, CCI400)
ICNNCT_ID := 0x420
$(eval $(call add_define,ICNNCT_ID))
endif
-
-ifeq (${INTERCONNECT}, "CCN508")
-$(eval $(call add_define,NXP_HAS_CCN508))
endif
ifneq (${CHASSIS},)
diff --git a/plat/nxp/common/setup/ls_bl2_el3_setup.c b/plat/nxp/common/setup/ls_bl2_el3_setup.c
index 5b5144d..a4cbaef 100644
--- a/plat/nxp/common/setup/ls_bl2_el3_setup.c
+++ b/plat/nxp/common/setup/ls_bl2_el3_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -182,7 +182,7 @@
unsigned int flags = 0U;
/* Initialise the IO layer and register platform IO devices */
ls_setup_page_tables(
-#if SEPARATE_RW_AND_NOLOAD
+#if SEPARATE_BL2_NOLOAD_REGION
BL2_START,
BL2_LIMIT - BL2_START,
#else
@@ -289,8 +289,9 @@
if ((dram_regions_info.region[0].addr == 0)
&& (dram_regions_info.total_dram_size > 0)) {
populate_dram_regions_info();
-
+#ifdef PLAT_XLAT_TABLES_DYNAMIC
mmap_add_ddr_region_dynamically();
+#endif
}
/* setup the memory region access permissions */
diff --git a/plat/nxp/common/setup/ls_common.c b/plat/nxp/common/setup/ls_common.c
index e7ae060..28d6b72 100644
--- a/plat/nxp/common/setup/ls_common.c
+++ b/plat/nxp/common/setup/ls_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2021 NXP
+ * Copyright 2018-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -113,7 +113,8 @@
#if defined(PLAT_XLAT_TABLES_DYNAMIC)
void mmap_add_ddr_region_dynamically(void)
{
- int i = 0;
+ int ret, i = 0;
+
dram_regions_info_t *info_dram_regions = get_dram_regions_info();
/* MMU map for Non-Secure DRAM Regions */
VERBOSE("DRAM Region %d: %p - %p\n", i,
@@ -121,10 +122,14 @@
(void *) (info_dram_regions->region[i].addr
+ info_dram_regions->region[i].size
- 1));
- mmap_add_dynamic_region(info_dram_regions->region[i].addr,
+ ret = mmap_add_dynamic_region(info_dram_regions->region[i].addr,
info_dram_regions->region[i].addr,
info_dram_regions->region[i].size,
MT_MEMORY | MT_RW | MT_NS);
+ if (ret != 0) {
+ ERROR("Failed to add dynamic memory region\n");
+ panic();
+ }
/* MMU map for Secure DDR Region on DRAM-0 */
if (info_dram_regions->region[i].size >
@@ -137,12 +142,16 @@
+ NXP_SECURE_DRAM_SIZE
+ NXP_SP_SHRD_DRAM_SIZE
- 1));
- mmap_add_dynamic_region((info_dram_regions->region[i].addr
+ ret = mmap_add_dynamic_region((info_dram_regions->region[i].addr
+ info_dram_regions->region[i].size),
(info_dram_regions->region[i].addr
+ info_dram_regions->region[i].size),
(NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE),
MT_MEMORY | MT_RW | MT_SECURE);
+ if (ret != 0) {
+ ERROR("Failed to add dynamic memory region\n");
+ panic();
+ }
}
#ifdef IMAGE_BL31
@@ -155,10 +164,14 @@
(void *) (info_dram_regions->region[i].addr
+ info_dram_regions->region[i].size
- 1));
- mmap_add_dynamic_region(info_dram_regions->region[i].addr,
+ ret = mmap_add_dynamic_region(info_dram_regions->region[i].addr,
info_dram_regions->region[i].addr,
info_dram_regions->region[i].size,
MT_MEMORY | MT_RW | MT_NS);
+ if (ret != 0) {
+ ERROR("Failed to add dynamic memory region\n");
+ panic();
+ }
}
#endif
}
diff --git a/plat/nxp/common/soc_errata/errata.c b/plat/nxp/common/soc_errata/errata.c
index a117c91..55ef604 100644
--- a/plat/nxp/common/soc_errata/errata.c
+++ b/plat/nxp/common/soc_errata/errata.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -19,6 +19,15 @@
INFO("SoC workaround for Errata A008850 Early-Phase was applied\n");
erratum_a008850_early();
#endif
+#if ERRATA_SOC_A009660
+ INFO("SoC workaround for Errata A009660 was applied\n");
+ erratum_a009660();
+#endif
+#if ERRATA_SOC_A010539
+ INFO("SoC workaround for Errata A010539 was applied\n");
+ erratum_a010539();
+#endif
+
/*
* The following DDR Erratas workaround are implemented in DDR driver,
* but print information here.
@@ -29,4 +38,22 @@
#if ERRATA_DDR_A050450
INFO("SoC workaround for DDR Errata A050450 was applied\n");
#endif
+#if ERRATA_DDR_A050958
+ INFO("SoC workaround for DDR Errata A050958 was applied\n");
+#endif
+#if ERRATA_DDR_A008511
+ INFO("SoC workaround for DDR Errata A008511 was applied\n");
+#endif
+#if ERRATA_DDR_A009803
+ INFO("SoC workaround for DDR Errata A009803 was applied\n");
+#endif
+#if ERRATA_DDR_A009942
+ INFO("SoC workaround for DDR Errata A009942 was applied\n");
+#endif
+#if ERRATA_DDR_A010165
+ INFO("SoC workaround for DDR Errata A010165 was applied\n");
+#endif
+#if ERRATA_DDR_A009663
+ INFO("SoC workaround for DDR Errata A009663 was applied\n");
+#endif
}
diff --git a/plat/nxp/common/soc_errata/errata.mk b/plat/nxp/common/soc_errata/errata.mk
index d2511bb..3deef3d 100644
--- a/plat/nxp/common/soc_errata/errata.mk
+++ b/plat/nxp/common/soc_errata/errata.mk
@@ -1,5 +1,5 @@
#
-# Copyright 2021 NXP
+# Copyright 2021-2022 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -9,7 +9,9 @@
ERRATA := \
ERRATA_SOC_A050426 \
- ERRATA_SOC_A008850
+ ERRATA_SOC_A008850 \
+ ERRATA_SOC_A009660 \
+ ERRATA_SOC_A010539
define enable_errata
$(1) ?= 0
diff --git a/plat/nxp/common/soc_errata/errata_a009660.c b/plat/nxp/common/soc_errata/errata_a009660.c
new file mode 100644
index 0000000..d31a4d7
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_a009660.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <mmio.h>
+#include <soc_default_base_addr.h>
+
+void erratum_a009660(void)
+{
+ mmio_write_32(NXP_SCFG_ADDR + 0x20c, 0x63b20042);
+}
diff --git a/plat/nxp/common/soc_errata/errata_a010539.c b/plat/nxp/common/soc_errata/errata_a010539.c
new file mode 100644
index 0000000..3dcbdc8
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_a010539.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <mmio.h>
+
+#include <plat_common.h>
+
+void erratum_a010539(void)
+{
+ if (get_boot_dev() == BOOT_DEVICE_QSPI) {
+ unsigned int *porsr1 = (void *)(NXP_DCFG_ADDR +
+ DCFG_PORSR1_OFFSET);
+ uint32_t val;
+
+ val = (gur_in32(porsr1) & ~PORSR1_RCW_MASK);
+ mmio_write_32((uint32_t)(NXP_DCSR_DCFG_ADDR +
+ DCFG_DCSR_PORCR1_OFFSET), htobe32(val));
+ /* Erratum need to set '1' to all bits for reserved SCFG register 0x1a8 */
+ mmio_write_32((uint32_t)(NXP_SCFG_ADDR + 0x1a8),
+ htobe32(0xffffffff));
+ }
+}
diff --git a/plat/nxp/common/soc_errata/errata_list.h b/plat/nxp/common/soc_errata/errata_list.h
index ae95fa2..f6741e2 100644
--- a/plat/nxp/common/soc_errata/errata_list.h
+++ b/plat/nxp/common/soc_errata/errata_list.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -17,4 +17,12 @@
void erratum_a008850_post(void);
#endif
+#ifdef ERRATA_SOC_A009660
+void erratum_a009660(void);
+#endif
+
+#ifdef ERRATA_SOC_A010539
+void erratum_a010539(void);
+#endif
+
#endif /* ERRATA_LIST_H */
diff --git a/plat/nxp/common/tbbr/tbbr.mk b/plat/nxp/common/tbbr/tbbr.mk
index 25852ba..4aac9d6 100644
--- a/plat/nxp/common/tbbr/tbbr.mk
+++ b/plat/nxp/common/tbbr/tbbr.mk
@@ -1,5 +1,5 @@
#
-# Copyright 2020 NXP
+# Copyright 2020-2022 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -13,6 +13,12 @@
CSF_FILE := input_blx_ch${CHASSIS}
BL2_CSF_FILE := input_bl2_ch${CHASSIS}
else
+ifeq ($(CHASSIS), 3)
+CSF_FILE := input_blx_ch${CHASSIS}
+BL2_CSF_FILE := input_bl2_ch${CHASSIS}
+PBI_CSF_FILE := input_pbi_ch${CHASSIS}
+$(eval $(call add_define, CSF_HDR_CH3))
+else
ifeq ($(CHASSIS), 3_2)
CSF_FILE := input_blx_ch3
BL2_CSF_FILE := input_bl2_ch${CHASSIS}
@@ -22,6 +28,7 @@
$(error -> CHASSIS not set!)
endif
endif
+endif
PLAT_AUTH_PATH := $(PLAT_DRIVERS_PATH)/auth
@@ -126,13 +133,13 @@
$(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
@if [ ! -f $(ROT_KEY) ]; then \
- openssl genrsa 2048 > $@ 2>/dev/null; \
+ ${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
fi
$(ROTPK_HASH): $(ROT_KEY)
@echo " OPENSSL $@"
- $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
- openssl dgst -sha256 -binary > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
endif #MBEDTLS_DIR
diff --git a/plat/nxp/soc-ls1088a/aarch64/ls1088a.S b/plat/nxp/soc-ls1088a/aarch64/ls1088a.S
new file mode 100644
index 0000000..0c6b7ea
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/aarch64/ls1088a.S
@@ -0,0 +1,1817 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+.section .text, "ax"
+
+#include <asm_macros.S>
+#include <lib/psci/psci.h>
+#include <nxp_timer.h>
+#include <plat_gic.h>
+
+#include "bl31_data.h"
+#include "plat_psci.h"
+#include "platform_def.h"
+
+/*
+ * the BASE address for these offsets is AUX_01_DATA in the
+ * bootcore's psci data region
+ */
+#define DEVDISR2_MASK_OFFSET 0x0 /* references AUX_01_DATA */
+#define DEVDISR5_MASK_OFFSET 0x8 /* references AUX_02_DATA */
+
+/*
+ * the BASE address for these offsets is AUX_04_DATA in the
+ * bootcore's psci data region
+ */
+#define GICD_BASE_ADDR_OFFSET 0x0 /* references AUX_04_DATA */
+#define GICC_BASE_ADDR_OFFSET 0x8 /* references AUX_05_DATA */
+
+#define IPSTPACK_RETRY_CNT 0x10000
+#define DDR_SLEEP_RETRY_CNT 0x10000
+#define CPUACTLR_EL1 S3_1_C15_C2_0
+#define DDR_SDRAM_CFG_2_FRCSR 0x80000000
+#define DDR_SDRAM_CFG_2_OFFSET 0x114
+#define DDR_TIMING_CFG_4_OFFSET 0x160
+#define DDR_CNTRL_BASE_ADDR 0x01080000
+
+#define DLL_LOCK_MASK 0x3
+#define DLL_LOCK_VALUE 0x2
+
+#define ERROR_DDR_SLEEP -1
+#define ERROR_DDR_WAKE -2
+#define ERROR_NO_QUIESCE -3
+
+#define CORE_RESTARTABLE 0
+#define CORE_NOT_RESTARTABLE 1
+
+.global soc_init_lowlevel
+.global soc_init_percpu
+
+.global _soc_core_release
+.global _soc_core_restart
+.global _soc_ck_disabled
+.global _soc_sys_reset
+.global _soc_sys_off
+
+.global _soc_core_prep_off
+.global _soc_core_entr_off
+.global _soc_core_exit_off
+
+.global _soc_core_prep_stdby
+.global _soc_core_entr_stdby
+.global _soc_core_exit_stdby
+.global _soc_core_prep_pwrdn
+.global _soc_core_entr_pwrdn
+.global _soc_core_exit_pwrdn
+.global _soc_clstr_prep_stdby
+.global _soc_clstr_exit_stdby
+.global _soc_clstr_prep_pwrdn
+.global _soc_clstr_exit_pwrdn
+.global _soc_sys_prep_stdby
+.global _soc_sys_exit_stdby
+.global _soc_sys_prep_pwrdn
+.global _soc_sys_pwrdn_wfi
+.global _soc_sys_exit_pwrdn
+
+.global _set_platform_security
+.global _soc_set_start_addr
+
+.equ TZPCDECPROT_0_SET_BASE, 0x02200804
+.equ TZPCDECPROT_1_SET_BASE, 0x02200810
+.equ TZPCDECPROT_2_SET_BASE, 0x0220081C
+
+.equ TZASC_REGION_ATTRIBUTES_0_0, 0x01100110
+
+.equ MPIDR_AFFINITY0_MASK, 0x00FF
+.equ MPIDR_AFFINITY1_MASK, 0xFF00
+.equ CPUECTLR_DISABLE_TWALK_PREFETCH, 0x4000000000
+.equ CPUECTLR_INS_PREFETCH_MASK, 0x1800000000
+.equ CPUECTLR_DAT_PREFETCH_MASK, 0x0300000000
+.equ OSDLR_EL1_DLK_LOCK, 0x1
+.equ CNTP_CTL_EL0_EN, 0x1
+.equ CNTP_CTL_EL0_IMASK, 0x2
+/* shifted value for incrementing cluster count in mpidr */
+.equ MPIDR_CLUSTER, 0x100
+
+/*
+ * This function initialize the soc,
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11
+ */
+func soc_init_lowlevel
+ /*
+ * called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ /*
+ * make sure the personality has been established by releasing cores
+ * that are marked "to-be-disabled" from reset
+ */
+ bl release_disabled
+
+ /* set SCRATCHRW7 to 0x0 */
+ ldr x0, =DCFG_SCRATCHRW7_OFFSET
+ mov x1, xzr
+ bl _write_reg_dcfg
+
+ /* restore the aarch32/64 non-volatile registers */
+ ldp x18, x30, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ ret
+endfunc soc_init_lowlevel
+
+/*
+ * void soc_init_percpu(void)
+ * this function performs any soc-specific initialization that is needed on
+ * a per-core basis
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+func soc_init_percpu
+ stp x4, x30, [sp, #-16]!
+
+ bl plat_my_core_mask
+ mov x2, x0
+
+ /* x2 = core mask */
+
+ /* see if this core is marked for prefetch disable */
+ mov x0, #PREFETCH_DIS_OFFSET
+ bl _get_global_data
+ tst x0, x2
+ b.eq 1f
+ bl _disable_ldstr_pfetch_A53
+1:
+ mov x0, #NXP_PMU_ADDR
+ bl enable_timer_base_to_cluster
+ ldp x4, x30, [sp], #16
+ ret
+endfunc soc_init_percpu
+
+/*
+ * this function sets the security mechanisms in the SoC to implement the
+ * Platform Security Policy
+ */
+func _set_platform_security
+ mov x3, x30
+
+#if (!SUPPRESS_TZC)
+ /* initialize the tzpc */
+ bl init_tzpc
+#endif
+
+#if (!SUPPRESS_SEC)
+ /* initialize secmon */
+ bl initSecMon
+#endif
+ mov x30, x3
+ ret
+endfunc _set_platform_security
+
+/*
+ * this function writes a 64-bit address to bootlocptrh/l
+ * in: x0, 64-bit address to write to BOOTLOCPTRL/H
+ * out: none
+ * uses x0, x1, x2
+ */
+func _soc_set_start_addr
+ /* get the 64-bit base address of the dcfg block */
+ ldr x2, =NXP_DCFG_ADDR
+
+ /* write the 32-bit BOOTLOCPTRL register */
+ mov x1, x0
+ str w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET]
+
+ /* write the 32-bit BOOTLOCPTRH register */
+ lsr x1, x0, #32
+ str w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET]
+ ret
+endfunc _soc_set_start_addr
+
+/*
+ * part of CPU_ON
+ * this function releases a secondary core from reset
+ * in: x0 = core_mask_lsb
+ * out: none
+ * uses: x0, x1, x2, x3
+ */
+_soc_core_release:
+ mov x3, x30
+
+ /* x0 = core mask */
+
+ ldr x1, =NXP_SEC_REGFILE_ADDR
+ /*
+ * write to CORE_HOLD to tell the bootrom that we want this core
+ * to run
+ */
+ str w0, [x1, #CORE_HOLD_OFFSET]
+
+ /* x0 = core mask */
+
+ /* read-modify-write BRRL to release core */
+ mov x1, #NXP_RESET_ADDR
+ ldr w2, [x1, #BRR_OFFSET]
+ orr w2, w2, w0
+ str w2, [x1, #BRR_OFFSET]
+ dsb sy
+ isb
+
+ /* send event */
+ sev
+ isb
+
+ mov x30, x3
+ ret
+
+/*
+ * this function determines if a core is disabled via COREDISABLEDSR
+ * in: w0 = core_mask_lsb
+ * out: w0 = 0, core not disabled
+ * w0 != 0, core disabled
+ * uses x0, x1
+ */
+_soc_ck_disabled:
+ /* get base addr of dcfg block */
+ ldr x1, =NXP_DCFG_ADDR
+
+ /* read COREDISABLEDSR */
+ ldr w1, [x1, #DCFG_COREDISABLEDSR_OFFSET]
+
+ /* test core bit */
+ and w0, w1, w0
+
+ ret
+
+/*
+ * part of CPU_ON
+ * this function restarts a core shutdown via _soc_core_entr_off
+ * in: x0 = core mask lsb (of the target cpu)
+ * out: x0 == 0, on success
+ * x0 != 0, on failure
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_core_restart:
+ mov x6, x30
+ mov x4, x0
+
+ /* x4 = core mask lsb */
+
+ /* pgm GICD_CTLR - enable secure grp0 */
+ mov x5, #NXP_GICD_ADDR
+ ldr w2, [x5, #GICD_CTLR_OFFSET]
+ orr w2, w2, #GICD_CTLR_EN_GRP_0
+ str w2, [x5, #GICD_CTLR_OFFSET]
+ dsb sy
+ isb
+ /* poll on RWP til write completes */
+4:
+ ldr w2, [x5, #GICD_CTLR_OFFSET]
+ tst w2, #GICD_CTLR_RWP
+ b.ne 4b
+
+ /*
+ * x4 = core mask lsb
+ * x5 = gicd base addr
+ */
+
+ mov x0, x4
+ bl get_mpidr_value
+
+ /*
+ * x0 = mpidr of target core
+ * x4 = core mask lsb of target core
+ * x5 = gicd base addr
+ */
+
+ /* generate target list bit */
+ and x1, x0, #MPIDR_AFFINITY0_MASK
+ mov x2, #1
+ lsl x2, x2, x1
+ /* get the affinity1 field */
+ and x1, x0, #MPIDR_AFFINITY1_MASK
+ lsl x1, x1, #8
+ orr x2, x2, x1
+ /* insert the INTID for SGI15 */
+ orr x2, x2, #ICC_SGI0R_EL1_INTID
+ /* fire the SGI */
+ msr ICC_SGI0R_EL1, x2
+ dsb sy
+ isb
+
+ /* load '0' on success */
+ mov x0, xzr
+
+ mov x30, x6
+ ret
+
+/*
+ * part of CPU_OFF
+ * this function programs SoC & GIC registers in preparation for shutting down
+ * the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7
+ */
+_soc_core_prep_off:
+ mov x8, x30
+ mov x7, x0
+
+ /* x7 = core mask lsb */
+
+ mrs x1, CPUECTLR_EL1
+ /* set smp and disable L2 snoops in cpuectlr */
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ orr x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH
+ bic x1, x1, #CPUECTLR_INS_PREFETCH_MASK
+ bic x1, x1, #CPUECTLR_DAT_PREFETCH_MASK
+ /* set retention control in cpuectlr */
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ orr x1, x1, #CPUECTLR_TIMER_8TICKS
+ msr CPUECTLR_EL1, x1
+
+ /* get redistributor rd base addr for this core */
+ mov x0, x7
+ bl get_gic_rd_base
+ mov x6, x0
+
+ /* get redistributor sgi base addr for this core */
+ mov x0, x7
+ bl get_gic_sgi_base
+ mov x5, x0
+
+ /* x5 = gicr sgi base addr
+ * x6 = gicr rd base addr
+ * x7 = core mask lsb
+ */
+
+ /* disable SGI 15 at redistributor - GICR_ICENABLER0 */
+ mov w3, #GICR_ICENABLER0_SGI15
+ str w3, [x5, #GICR_ICENABLER0_OFFSET]
+2:
+ /* poll on rwp bit in GICR_CTLR */
+ ldr w4, [x6, #GICR_CTLR_OFFSET]
+ tst w4, #GICR_CTLR_RWP
+ b.ne 2b
+
+ /* disable GRP1 interrupts at cpu interface */
+ msr ICC_IGRPEN1_EL3, xzr
+
+ /* disable GRP0 ints at cpu interface */
+ msr ICC_IGRPEN0_EL1, xzr
+
+ /* program the redistributor - poll on GICR_CTLR.RWP as needed */
+
+ /* define SGI 15 as Grp0 - GICR_IGROUPR0 */
+ ldr w4, [x5, #GICR_IGROUPR0_OFFSET]
+ bic w4, w4, #GICR_IGROUPR0_SGI15
+ str w4, [x5, #GICR_IGROUPR0_OFFSET]
+
+ /* define SGI 15 as Grp0 - GICR_IGRPMODR0 */
+ ldr w3, [x5, #GICR_IGRPMODR0_OFFSET]
+ bic w3, w3, #GICR_IGRPMODR0_SGI15
+ str w3, [x5, #GICR_IGRPMODR0_OFFSET]
+
+ /* set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */
+ ldr w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+ bic w4, w4, #GICR_IPRIORITYR3_SGI15_MASK
+ str w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+
+ /* enable SGI 15 at redistributor - GICR_ISENABLER0 */
+ mov w3, #GICR_ISENABLER0_SGI15
+ str w3, [x5, #GICR_ISENABLER0_OFFSET]
+ dsb sy
+ isb
+3:
+ /* poll on rwp bit in GICR_CTLR */
+ ldr w4, [x6, #GICR_CTLR_OFFSET]
+ tst w4, #GICR_CTLR_RWP
+ b.ne 3b
+
+ /* quiesce the debug interfaces */
+ mrs x3, osdlr_el1
+ orr x3, x3, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x3
+ isb
+
+ /* enable grp0 ints */
+ mov x3, #ICC_IGRPEN0_EL1_EN
+ msr ICC_IGRPEN0_EL1, x3
+
+ /*
+ * x5 = gicr sgi base addr
+ * x6 = gicr rd base addr
+ * x7 = core mask lsb
+ */
+
+ /* clear any pending interrupts */
+ mvn w1, wzr
+ str w1, [x5, #GICR_ICPENDR0_OFFSET]
+
+ /* make sure system counter is enabled */
+ ldr x3, =NXP_TIMER_ADDR
+ ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 4f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+4:
+ /* enable the core timer and mask timer interrupt */
+ mov x1, #CNTP_CTL_EL0_EN
+ orr x1, x1, #CNTP_CTL_EL0_IMASK
+ msr cntp_ctl_el0, x1
+
+ mov x30, x8
+ ret
+
+/*
+ * part of CPU_OFF
+ * this function performs the final steps to shutdown the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5
+ */
+_soc_core_entr_off:
+ mov x5, x30
+ mov x4, x0
+
+ /* x4 = core mask */
+1:
+ /* enter low-power state by executing wfi */
+ wfi
+
+ /* see if SGI15 woke us up */
+ mrs x2, ICC_IAR0_EL1
+ mov x3, #ICC_IAR0_EL1_SGI15
+ cmp x2, x3
+ b.ne 2f
+
+ /* deactivate the int */
+ msr ICC_EOIR0_EL1, x2
+
+ /* x4 = core mask */
+2:
+ /* check if core has been turned on */
+ mov x0, x4
+ bl _getCoreState
+
+ /* x0 = core state */
+
+ cmp x0, #CORE_WAKEUP
+ b.ne 1b
+
+ /* if we get here, then we have exited the wfi */
+
+ mov x30, x5
+ ret
+
+/*
+ * part of CPU_OFF
+ * this function starts the process of starting a core back up
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_core_exit_off:
+ mov x6, x30
+ mov x5, x0
+
+ /* disable forwarding of GRP0 ints at cpu interface */
+ msr ICC_IGRPEN0_EL1, xzr
+
+ /* get redistributor sgi base addr for this core */
+ mov x0, x5
+ bl get_gic_sgi_base
+ mov x4, x0
+
+ /*
+ * x4 = gicr sgi base addr
+ * x5 = core mask
+ */
+
+ /* disable SGI 15 at redistributor - GICR_ICENABLER0 */
+ mov w1, #GICR_ICENABLER0_SGI15
+ str w1, [x4, #GICR_ICENABLER0_OFFSET]
+
+ /* get redistributor rd base addr for this core */
+ mov x0, x5
+ bl get_gic_rd_base
+ mov x4, x0
+
+ /* x4 = gicr rd base addr */
+2:
+ /* poll on rwp bit in GICR_CTLR */
+ ldr w2, [x4, #GICR_CTLR_OFFSET]
+ tst w2, #GICR_CTLR_RWP
+ b.ne 2b
+
+ /* x4 = gicr rd base addr */
+
+ /* unlock the debug interfaces */
+ mrs x3, osdlr_el1
+ bic x3, x3, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x3
+ isb
+
+ dsb sy
+ isb
+ mov x30, x6
+ ret
+
+/*
+ * this function requests a reset of the entire SOC
+ * in: none
+ * out: none
+ * uses: x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_sys_reset:
+ mov x3, x30
+
+ /* make sure the mask is cleared in the reset request mask register */
+ mov x0, #RST_RSTRQMR1_OFFSET
+ mov w1, wzr
+ bl _write_reg_reset
+
+ /* set the reset request */
+ mov x4, #RST_RSTCR_OFFSET
+ mov x0, x4
+ mov w1, #RSTCR_RESET_REQ
+ bl _write_reg_reset
+
+ /* x4 = RST_RSTCR_OFFSET */
+
+ /*
+ * just in case this address range is mapped as cacheable,
+ * flush the write out of the dcaches
+ */
+ mov x2, #NXP_RESET_ADDR
+ add x2, x2, x4
+ dc cvac, x2
+ dsb st
+ isb
+
+ /* this function does not return */
+ b .
+
+/*
+ * this function turns off the SoC
+ * Note: this function is not intended to return, and the only allowable
+ * recovery is POR
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_sys_off:
+ /*
+ * A-009810: LPM20 entry sequence might cause
+ * spurious timeout reset request
+ * workaround: MASK RESET REQ RPTOE
+ */
+ ldr x0, =NXP_RESET_ADDR
+ ldr w1, [x0, #RST_RSTRQMR1_OFFSET]
+ orr w1, w1, #RSTRQMR_RPTOE_MASK
+ str w1, [x0, #RST_RSTRQMR1_OFFSET]
+
+ /* disable SEC, QBman spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, =DCFG_DEVDISR1_SEC
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR3_OFFSET
+ ldr w1, =DCFG_DEVDISR3_QBMAIN
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, =DCFG_DEVDISR4_SPI_QSPI
+ str w1, [x2, x0]
+
+ /* set TPMWAKEMR0 */
+ ldr x0, =TPMWAKEMR0_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ /* disable icache, dcache, mmu @ EL1 */
+ mov x1, #SCTLR_I_C_M_MASK
+ mrs x0, sctlr_el1
+ bic x0, x0, x1
+ msr sctlr_el1, x0
+
+ /* disable L2 prefetches */
+ mrs x0, CPUECTLR_EL1
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ orr x0, x0, #CPUECTLR_TIMER_8TICKS
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+
+ /* disable CCN snoop domain */
+ ldr x0, =NXP_CCI_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ mov x2, #DAIF_SET_MASK
+
+ mrs x1, spsr_el1
+ orr x1, x1, x2
+ msr spsr_el1, x1
+
+ mrs x1, spsr_el2
+ orr x1, x1, x2
+ msr spsr_el2, x1
+
+ bl get_pmu_idle_cluster_mask
+ mov x3, #NXP_PMU_ADDR
+
+ /* x3 = pmu base addr */
+
+ /* idle the ACP interfaces */
+ str w0, [x3, #PMU_CLAINACTSETR_OFFSET]
+
+ /* force the debug interface to be quiescent */
+ mrs x0, osdlr_el1
+ orr x0, x0, #0x1
+ msr osdlr_el1, x0
+
+ bl get_pmu_flush_cluster_mask
+ /* x3 = pmu base addr */
+ mov x3, #NXP_PMU_ADDR
+
+ /* clear flush request and status */
+ ldr x2, =PMU_CLSL2FLUSHCLRR_OFFSET
+ str w0, [x3, x2]
+
+ /* close the Skyros master port */
+ ldr x2, =PMU_CLSINACTSETR_OFFSET
+ str w0, [x3, x2]
+
+ /* request lpm20 */
+ ldr x0, =PMU_POWMGTCSR_OFFSET
+ ldr w1, =PMU_POWMGTCSR_VAL
+ str w1, [x3, x0]
+
+ /* this function does not return */
+1:
+ wfi
+ b 1b
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_core_prep_stdby:
+ /* clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core into standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_stdby:
+ /* X0 = core mask lsb */
+ dsb sy
+ isb
+ wfi
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_core_exit_stdby:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_core_prep_pwrdn:
+ /* make sure system counter is enabled */
+ ldr x3, =NXP_TIMER_ADDR
+ ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 1f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+ /*
+ * enable dynamic retention control (CPUECTLR[2:0])
+ * set the SMPEN bit (CPUECTLR[6])
+ */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_RET_MASK
+ orr x1, x1, #CPUECTLR_TIMER_8TICKS
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x1
+
+ isb
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core into a power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_pwrdn:
+ /* X0 = core mask lsb */
+ dsb sy
+ isb
+ wfi
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function cleans up after a core exits power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses
+ */
+_soc_core_exit_pwrdn:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_clstr_prep_stdby:
+ /* clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_clstr_exit_stdby:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_clstr_prep_pwrdn:
+ /* make sure system counter is enabled */
+ ldr x3, =NXP_TIMER_ADDR
+ ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 1f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+ /*
+ * enable dynamic retention control (CPUECTLR[2:0])
+ * set the SMPEN bit (CPUECTLR[6])
+ */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_RET_MASK
+ orr x1, x1, #CPUECTLR_TIMER_8TICKS
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x1
+
+ isb
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function cleans up after a core exits power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses
+ */
+_soc_clstr_exit_pwrdn:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_prep_stdby:
+ /* clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_sys_exit_stdby:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to
+ * suspend-to-power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_sys_prep_pwrdn:
+ /* set retention control */
+ mrs x0, CPUECTLR_EL1
+ bic x0, x0, #CPUECTLR_TIMER_MASK
+ orr x0, x0, #CPUECTLR_TIMER_8TICKS
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core, and potentially the soc, into a
+ * low-power state
+ * in: x0 = core mask lsb
+ * out: x0 = 0, success
+ * x0 < 0, failure
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
+ */
+_soc_sys_pwrdn_wfi:
+ /* Save LR to stack */
+ stp x18, x30, [sp, #-16]!
+
+ /* Poll PCPW20SR for all secondary cores to be placed in PW20 */
+ bl get_tot_num_cores
+ mov x3, #0x1
+ lsl x3, x3, x0
+ sub x3, x3, #2
+1:
+ mov x0, #NXP_PMU_ADDR
+ ldr w1, [x0, #PMU_PCPW20SR_OFFSET]
+ cmp w1, w3
+ b.ne 1b
+
+ /* backup EPU registers to stack */
+ mov x3, #NXP_PMU_ADDR
+ ldr x2, =NXP_EPU_ADDR
+ ldr w4, [x2, #EPU_EPIMCR10_OFFSET]
+ ldr w5, [x2, #EPU_EPCCR10_OFFSET]
+ ldr w6, [x2, #EPU_EPCTR10_OFFSET]
+ ldr w7, [x2, #EPU_EPGCR_OFFSET]
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+
+ /*
+ * x2 = epu base addr
+ * x3 = pmu base addr
+ */
+
+ /* set up EPU event to receive the wake signal from PMU */
+ mov w4, #EPU_EPIMCR10_VAL
+ mov w5, #EPU_EPCCR10_VAL
+ mov w6, #EPU_EPCTR10_VAL
+ mov w7, #EPU_EPGCR_VAL
+ str w4, [x2, #EPU_EPIMCR10_OFFSET]
+ str w5, [x2, #EPU_EPCCR10_OFFSET]
+ str w6, [x2, #EPU_EPCTR10_OFFSET]
+ str w7, [x2, #EPU_EPGCR_OFFSET]
+
+ /*
+ * A-010194: There is logic problem
+ * in the path of GIC-to-PMU to issue
+ * wake request to core0
+ * Workaround: Re-target the wakeup interrupts
+ * to a core other than the last active core0
+ */
+ ldr x2, =NXP_GICD_ADDR
+
+ /* backup flextimer/mmc/usb interrupt router */
+ ldr x0, =GICD_IROUTER60_OFFSET
+ ldr x1, =GICD_IROUTER76_OFFSET
+ ldr w4, [x2, x0]
+ ldr w5, [x2, x1]
+ ldr x0, =GICD_IROUTER112_OFFSET
+ ldr x1, =GICD_IROUTER113_OFFSET
+ ldr w6, [x2, x0]
+ ldr w7, [x2, x1]
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+
+ /*
+ * x2 = gicd base addr
+ * x0 = GICD_IROUTER112_OFFSET
+ * x1 = GICD_IROUTER113_OFFSET
+ */
+
+ /* re-route interrupt to cluster 1 */
+ ldr w4, =GICD_IROUTER_VALUE
+ str w4, [x2, x0]
+ str w4, [x2, x1]
+ ldr x0, =GICD_IROUTER60_OFFSET
+ ldr x1, =GICD_IROUTER76_OFFSET
+ str w4, [x2, x0]
+ str w4, [x2, x1]
+ dsb sy
+ isb
+
+ /* backup flextimer/mmc/usb interrupt enabler */
+ ldr x0, =GICD_ISENABLER_1
+ ldr w4, [x2, x0]
+ ldr x1, =GICD_ISENABLER_2
+ ldr w5, [x2, x1]
+ stp x4, x5, [sp, #-16]!
+
+ ldr x0, =GICD_ISENABLER_3
+ ldr w4, [x2, x0]
+ ldr x1, =GICD_ICENABLER_1
+ ldr w5, [x2, x1]
+ stp x4, x5, [sp, #-16]!
+
+ ldr x0, =GICD_ICENABLER_2
+ ldr w4, [x2, x0]
+ ldr x1, =GICD_ICENABLER_3
+ ldr w5, [x2, x1]
+ stp x4, x5, [sp, #-16]!
+
+ /* enable related interrupt routing */
+ ldr w4, =GICD_ISENABLER_1_VALUE
+ ldr x0, =GICD_ISENABLER_1
+ str w4, [x2, x0]
+ dsb sy
+ isb
+
+ ldr w4, =GICD_ISENABLER_2_VALUE
+ ldr x0, =GICD_ISENABLER_2
+ str w4, [x2, x0]
+ dsb sy
+ isb
+
+ ldr w4, =GICD_ISENABLER_3_VALUE
+ ldr x0, =GICD_ISENABLER_3
+ str w4, [x2, x0]
+ dsb sy
+ isb
+
+ /* set POWMGTDCR [STP_PV_EN] = 1 */
+ ldr x2, =NXP_POWMGTDCR
+ ldr w4, =0x01
+ str w4, [x2]
+
+ /* program IPSTPCR for override stop request (except DDR) */
+ mov x3, #NXP_PMU_ADDR
+
+ /* build an override mask for IPSTPCR4/IPSTPACK4/DEVDISR5 */
+ ldr x2, =PMU_IPPDEXPCR4_OFFSET
+ ldr w7, [x3, x2]
+
+ mov x5, xzr
+ ldr x6, =IPPDEXPCR4_MASK
+ and x6, x6, x7
+ cbz x6, 1f
+
+ /*
+ * x5 = override mask
+ * x6 = IPPDEXPCR bits for DEVDISR5
+ * x7 = IPPDEXPCR
+ */
+
+ /* get the overrides */
+ orr x4, x5, #DEVDISR5_FLX_TMR
+ tst x6, #IPPDEXPCR_FLX_TMR
+ csel x5, x5, x4, EQ
+1:
+ /* store the DEVDISR5 override mask */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, #AUX_01_DATA
+ str w5, [x2, #DEVDISR5_MASK_OFFSET]
+
+ mov x3, #NXP_PMU_ADDR
+
+ /* write IPSTPCR0 - no overrides */
+ ldr x2, =PMU_IPSTPCR0_OFFSET
+ ldr w5, =IPSTPCR0_VALUE
+ str w5, [x3, x2]
+
+ /* write IPSTPCR1 - no overrides */
+ ldr x2, =PMU_IPSTPCR1_OFFSET
+ ldr w5, =IPSTPCR1_VALUE
+ str w5, [x3, x2]
+
+ /* write IPSTPCR2 - no overrides */
+ ldr x2, =PMU_IPSTPCR2_OFFSET
+ ldr w5, =IPSTPCR2_VALUE
+ str w5, [x3, x2]
+
+ /* write IPSTPCR3 - no overrides */
+ ldr x2, =PMU_IPSTPCR3_OFFSET
+ ldr w5, =IPSTPCR3_VALUE
+ str w5, [x3, x2]
+
+ /* write IPSTPCR4 - overrides possible */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, #AUX_01_DATA
+ ldr w6, [x2, #DEVDISR5_MASK_OFFSET]
+ ldr x2, =PMU_IPSTPCR4_OFFSET
+ ldr w5, =IPSTPCR4_VALUE
+ bic x5, x5, x6
+ str w5, [x3, x2]
+
+ /* write IPSTPCR5 - no overrides */
+ ldr x2, =PMU_IPSTPCR5_OFFSET
+ ldr w5, =IPSTPCR5_VALUE
+ str w5, [x3, x2]
+
+ /* write IPSTPCR6 - no overrides */
+ ldr x2, =PMU_IPSTPCR6_OFFSET
+ ldr w5, =IPSTPCR6_VALUE
+ str w5, [x3, x2]
+
+ /* poll IPSTPACK for IP stop acknowledgment (except DDR) */
+ mov x3, #NXP_PMU_ADDR
+
+ /* poll on IPSTPACK0 */
+ ldr x2, =PMU_IPSTPACK0_OFFSET
+ ldr x4, =IPSTPCR0_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+3:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 14f
+ sub x7, x7, #1
+ cbnz x7, 3b
+
+14:
+ /* poll on IPSTPACK1 */
+ ldr x2, =PMU_IPSTPACK1_OFFSET
+ ldr x4, =IPSTPCR1_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+4:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 15f
+ sub x7, x7, #1
+ cbnz x7, 4b
+
+15:
+ /* poll on IPSTPACK2 */
+ ldr x2, =PMU_IPSTPACK2_OFFSET
+ ldr x4, =IPSTPCR2_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+5:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 16f
+ sub x7, x7, #1
+ cbnz x7, 5b
+
+16:
+ /* poll on IPSTPACK3 */
+ ldr x2, =PMU_IPSTPACK3_OFFSET
+ ldr x4, =IPSTPCR3_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+6:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 17f
+ sub x7, x7, #1
+ cbnz x7, 6b
+
+17:
+ /* poll on IPSTPACK4 */
+ ldr x2, =PMU_IPSTPACK4_OFFSET
+ ldr x4, =IPSTPCR4_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+7:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 18f
+ sub x7, x7, #1
+ cbnz x7, 7b
+
+18:
+ /* poll on IPSTPACK5 */
+ ldr x2, =PMU_IPSTPACK5_OFFSET
+ ldr x4, =IPSTPCR5_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+8:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 19f
+ sub x7, x7, #1
+ cbnz x7, 8b
+
+19:
+ /* poll on IPSTPACK6 */
+ ldr x2, =PMU_IPSTPACK6_OFFSET
+ ldr x4, =IPSTPCR6_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+9:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 20f
+ sub x7, x7, #1
+ cbnz x7, 9b
+
+20:
+ /* save current DEVDISR states to DDR. */
+ ldr x2, =NXP_DCFG_ADDR
+
+ /* save DEVDISR1 and load new value */
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, [x2, x0]
+ mov w13, w1
+ ldr x1, =DEVDISR1_VALUE
+ str w1, [x2, x0]
+ /* save DEVDISR2 and load new value */
+ ldr x0, =DCFG_DEVDISR2_OFFSET
+ ldr w1, [x2, x0]
+ mov w14, w1
+ ldr x1, =DEVDISR2_VALUE
+ str w1, [x2, x0]
+
+ /* x6 = DEVDISR5 override mask */
+
+ /* save DEVDISR3 and load new value */
+ ldr x0, =DCFG_DEVDISR3_OFFSET
+ ldr w1, [x2, x0]
+ mov w15, w1
+ ldr x1, =DEVDISR3_VALUE
+ str w1, [x2, x0]
+
+ /* save DEVDISR4 and load new value */
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, [x2, x0]
+ mov w16, w1
+ /* not stop uart print */
+ ldr x1, =0x0000332
+ str w1, [x2, x0]
+
+ /* save DEVDISR5 and load new value */
+ ldr x0, =DCFG_DEVDISR5_OFFSET
+ ldr w1, [x2, x0]
+ mov w17, w1
+ /* Enable this wakeup will fail, should enable OCRAM */
+ ldr x1, =0x00102300
+ str w1, [x2, x0]
+
+ /* save DEVDISR6 and load new value */
+ ldr x0, =DCFG_DEVDISR6_OFFSET
+ ldr w1, [x2, x0]
+ mov w18, w1
+ ldr x1, =DEVDISR6_VALUE
+ str w1, [x2, x0]
+
+ /*
+ * w13 = DEVDISR1 saved value
+ * w14 = DEVDISR2 saved value
+ * w15 = DEVDISR3 saved value
+ * w16 = DEVDISR4 saved value
+ * w17 = DEVDISR5 saved value
+ * w18 = DEVDISR6 saved value
+ */
+ /*
+ * A-009810: LPM20 entry sequence might cause
+ * spurious timeout reset request
+ * workaround: MASK RESET REQ RPTOE
+ */
+ ldr x0, =NXP_RESET_ADDR
+ ldr w1, =RSTRQMR_RPTOE_MASK
+ str w1, [x0, #RST_RSTRQMR1_OFFSET]
+
+ /* disable SEC, QBman spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, =DCFG_DEVDISR1_SEC
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR3_OFFSET
+ ldr w1, =DCFG_DEVDISR3_QBMAIN
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, =DCFG_DEVDISR4_SPI_QSPI
+ str w1, [x2, x0]
+
+ /*
+ * write the GICR_WAKER.ProcessorSleep bits to 1
+ * enable the WakeRequest signal
+ * x3 is cpu mask starting from cpu7
+ */
+ bl get_tot_num_cores
+ sub x0, x0, #1
+ mov x3, #0x1
+ lsl x3, x3, x0
+2:
+ mov x0, x3
+ bl get_gic_rd_base
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ orr w1, w1, #GICR_WAKER_SLEEP_BIT
+ str w1, [x0, #GICR_WAKER_OFFSET]
+1:
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ cmp w1, #GICR_WAKER_ASLEEP
+ b.ne 1b
+
+ lsr x3, x3, #1
+ cbnz x3, 2b
+
+ /* x3 = pmu base addr */
+
+ /* perform Icache Warming Sequence */
+ ldr x5, =IPSTPCR4_VALUE
+ mov x6, DDR_CNTRL_BASE_ADDR
+ mov x7, #NXP_PMU_ADDR
+ mov x8, #NXP_DCFG_ADDR
+ mov x10, #PMU_IPSTPCR4_OFFSET
+ mov x11, #PMU_IPSTPACK4_OFFSET
+ mov x12, #PMU_IPSTPCR3_OFFSET
+ mov x18, #PMU_IPSTPCR2_OFFSET
+ mov x19, #PMU_IPSTPCR1_OFFSET
+ mov x21, #PMU_IPSTPCR0_OFFSET
+ ldr x22, =DCFG_DEVDISR5_OFFSET
+ ldr x23, =NXP_EPU_ADDR
+ mov x9, #CORE_RESTARTABLE
+ bl final_pwrdown
+
+ /*
+ * disable the WakeRequest signal on cpu 0-7
+ * x3 is cpu mask starting from cpu7
+ */
+ bl get_tot_num_cores
+ sub x0, x0, #1
+ mov x3, #0x1
+ lsl x3, x3, x0
+2:
+ mov x0, x3
+ bl get_gic_rd_base
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ bic w1, w1, #GICR_WAKER_SLEEP_BIT
+ str w1, [x0, #GICR_WAKER_OFFSET]
+1:
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ cbnz w1, 1b
+
+ lsr x3, x3, #1
+ cbnz x3, 2b
+
+ /* set SGI for secondary core wakeup */
+ ldr x0, =0x1000002
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x2000004
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x3000008
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x4010001
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x5010002
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x6010004
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x7010008
+ msr S3_0_C12_C11_7, x0
+
+ /* enable SEC, QBman spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ str wzr, [x2, #DCFG_DEVDISR1_OFFSET]
+ str wzr, [x2, #DCFG_DEVDISR3_OFFSET]
+ str wzr, [x2, #DCFG_DEVDISR4_OFFSET]
+
+ /* clear POWMGTDCR [STP_PV_EN] */
+ ldr x2, =NXP_POWMGTDCR
+ ldr w4, [x2]
+ bic w4, w4, #0x01
+ str w4, [x2]
+
+ /* restore flextimer/mmc/usb interrupt enabler */
+ ldr x3, =NXP_GICD_ADDR
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_ICENABLER_2
+ mvn w0, w0
+ str w0, [x3, x1]
+ ldr x1, =GICD_ICENABLER_3
+ mvn w2, w2
+ str w2, [x3, x1]
+
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_ISENABLER_3
+ str w0, [x3, x1]
+ ldr x1, =GICD_ICENABLER_1
+ mvn w2, w2
+ str w0, [x3, x1]
+
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_ISENABLER_1
+ str w0, [x3, x1]
+ ldr x1, =GICD_ISENABLER_2
+ str w0, [x3, x1]
+
+ /* restore flextimer/mmc/usb interrupt router */
+ ldr x3, =NXP_GICD_ADDR
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_IROUTER113_OFFSET
+ str w2, [x3, x1]
+ ldr x1, =GICD_IROUTER112_OFFSET
+ str w0, [x3, x1]
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_IROUTER76_OFFSET
+ str w2, [x3, x1]
+ ldr x1, =GICD_IROUTER60_OFFSET
+ str w0, [x3, x1]
+
+ /* restore EPU registers */
+ ldr x3, =NXP_EPU_ADDR
+ ldp x0, x2, [sp], #16
+ str w2, [x3, #EPU_EPGCR_OFFSET]
+ str w0, [x3, #EPU_EPCTR10_OFFSET]
+ ldp x2, x1, [sp], #16
+ str w1, [x3, #EPU_EPCCR10_OFFSET]
+ str w2, [x3, #EPU_EPIMCR10_OFFSET]
+
+ isb
+ /* Restor LR */
+ ldp x18, x30, [sp], #16
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_exit_pwrdn:
+ mrs x1, SCTLR_EL1
+ orr x1, x1, #SCTLR_I_MASK
+ msr SCTLR_EL1, x1
+ isb
+ ret
+
+/*
+ * this function checks to see if cores which are to be disabled have been
+ * released from reset - if not, it releases them
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
+ */
+release_disabled:
+ mov x8, x30
+
+ /* read COREDISABLESR */
+ mov x0, #NXP_DCFG_ADDR
+ ldr w4, [x0, #DCFG_COREDISABLEDSR_OFFSET]
+
+ /* get the number of cpus on this device */
+ mov x6, #PLATFORM_CORE_COUNT
+
+ mov x0, #NXP_RESET_ADDR
+ ldr w5, [x0, #BRR_OFFSET]
+
+ /* load the core mask for the first core */
+ mov x7, #1
+
+ /*
+ * x4 = COREDISABLESR
+ * x5 = BRR
+ * x6 = loop count
+ * x7 = core mask bit
+ */
+2:
+ /* check if the core is to be disabled */
+ tst x4, x7
+ b.eq 1f
+
+ /* see if disabled cores have already been released from reset */
+ tst x5, x7
+ b.ne 1f
+
+ /* if core has not been released, then release it (0-3) */
+ mov x0, x7
+ bl _soc_core_release
+
+ /* record the core state in the data area (0-3) */
+ mov x0, x7
+ mov x1, #CORE_DISABLED
+ bl _setCoreState
+
+1:
+ /* decrement the counter */
+ subs x6, x6, #1
+ b.le 3f
+
+ /* shift the core mask to the next core */
+ lsl x7, x7, #1
+ /* continue */
+ b 2b
+3:
+ mov x30, x8
+ ret
+
+/*
+ * write a register in the DCFG block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2
+ */
+_write_reg_dcfg:
+ ldr x2, =NXP_DCFG_ADDR
+ str w1, [x2, x0]
+ ret
+
+/*
+ * read a register in the DCFG block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1
+ */
+_read_reg_dcfg:
+ ldr x1, =NXP_DCFG_ADDR
+ ldr w0, [x1, x0]
+ ret
+
+/*
+ * this function sets up the TrustZone Address Space Controller (TZASC)
+ * in: none
+ * out: none
+ * uses x0, x1
+ */
+init_tzpc:
+ /*
+ * set Non Secure access for all devices protected via TZPC
+ * decode Protection-0 Set Reg
+ */
+ ldr x1, =TZPCDECPROT_0_SET_BASE
+ /* set decode region to NS, Bits[7:0] */
+ mov w0, #0xFF
+ str w0, [x1]
+
+ /* decode Protection-1 Set Reg */
+ ldr x1, =TZPCDECPROT_1_SET_BASE
+ /* set decode region to NS, Bits[7:0] */
+ mov w0, #0xFF
+ str w0, [x1]
+
+ /* decode Protection-2 Set Reg */
+ ldr x1, =TZPCDECPROT_2_SET_BASE
+ /* set decode region to NS, Bits[7:0] */
+ mov w0, #0xFF
+ str w0, [x1]
+
+ /*
+ * entire SRAM as NS
+ * secure RAM region size Reg
+ */
+ ldr x1, =NXP_OCRAM_TZPC_ADDR
+ /* 0x00000000 = no secure region */
+ mov w0, #0x00000000
+ str w0, [x1]
+
+ ret
+
+/* this function performs initialization on SecMon for boot services */
+initSecMon:
+ /* read the register hpcomr */
+ ldr x1, =NXP_SNVS_ADDR
+ ldr w0, [x1, #SECMON_HPCOMR_OFFSET]
+ /* turn off secure access for the privileged registers */
+ orr w0, w0, #SECMON_HPCOMR_NPSWAEN
+ /* write back */
+ str w0, [x1, #SECMON_HPCOMR_OFFSET]
+
+ ret
+
+/*
+ * this function returns the redistributor base address for the core specified
+ * in x1
+ * in: x0 - core mask lsb of specified core
+ * out: x0 = redistributor rd base address for specified core
+ * uses x0, x1, x2
+ */
+get_gic_rd_base:
+ /* get the 0-based core number */
+ clz w1, w0
+ mov w2, #0x20
+ sub w2, w2, w1
+ sub w2, w2, #1
+
+ /* x2 = core number / loop counter */
+
+ ldr x0, =NXP_GICR_ADDR
+ mov x1, #GIC_RD_OFFSET
+2:
+ cbz x2, 1f
+ add x0, x0, x1
+ sub x2, x2, #1
+ b 2b
+1:
+ ret
+
+/*
+ * this function returns the redistributor base address for the core specified
+ * in x1
+ * in: x0 - core mask lsb of specified core
+ * out: x0 = redistributor sgi base address for specified core
+ * uses x0, x1, x2
+ */
+get_gic_sgi_base:
+ /* get the 0-based core number */
+ clz w1, w0
+ mov w2, #0x20
+ sub w2, w2, w1
+ sub w2, w2, #1
+
+ /* x2 = core number / loop counter */
+
+ ldr x0, =NXP_GICR_SGI_ADDR
+ mov x1, #GIC_SGI_OFFSET
+2:
+ cbz x2, 1f
+ add x0, x0, x1
+ sub x2, x2, #1
+ b 2b
+1:
+ ret
+
+/*
+ * this function returns an mpidr value for a core, given a core_mask_lsb
+ * in: x0 = core mask lsb
+ * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits
+ * uses x0, x1
+ */
+get_mpidr_value:
+ /* convert a core mask to an SoC core number */
+ clz w0, w0
+ mov w1, #31
+ sub w0, w1, w0
+
+ /* w0 = SoC core number */
+
+ mov w1, wzr
+2:
+ cmp w0, #CORES_PER_CLUSTER
+ b.lt 1f
+ sub w0, w0, #CORES_PER_CLUSTER
+ add w1, w1, #MPIDR_CLUSTER
+ b 2b
+
+ /* insert the mpidr core number */
+1:
+ orr w0, w1, w0
+ ret
+
+/*
+ * write a register in the RESET block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2
+ */
+_write_reg_reset:
+ ldr x2, =NXP_RESET_ADDR
+ str w1, [x2, x0]
+ ret
+
+/*
+ * read a register in the RESET block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1
+ */
+_read_reg_reset:
+ ldr x1, =NXP_RESET_ADDR
+ ldr w0, [x1, x0]
+ ret
+
+/*
+ * this function will pwrdown ddr and the final core - it will do this
+ * by loading itself into the icache and then executing from there
+ * in: x5 = ipstpcr4 (IPSTPCR4_VALUE bic DEVDISR5_MASK)
+ * x6 = DDR_CNTRL_BASE_ADDR
+ * x7 = NXP_PMU_ADDR
+ * x8 = NXP_DCFG_ADDR
+ * x9 = 0, restartable
+ * = 1, non-restartable
+ * x10 = PMU_IPSTPCR4_OFFSET
+ * x11 = PMU_IPSTPACK4_OFFSET
+ * x12 = PMU_IPSTPCR3_OFFSET
+ * x18 = PMU_IPSTPCR2_OFFSET
+ * x19 = PMU_IPSTPCR1_OFFSET
+ * x21 = PMU_IPSTPCR0_OFFSET
+ * w13 = DEVDISR1 saved value
+ * w14 = DEVDISR2 saved value
+ * w15 = DEVDISR3 saved value
+ * w16 = DEVDISR4 saved value
+ * w17 = DEVDISR5 saved value
+ * x22 = DCFG_DEVDISR5_OFFSET
+ * x23 = NXP_EPU_ADDR
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x13, x14, x15, x16, x17
+ * x10, x11, x12, x18, x19, x21, x22, x23
+ */
+
+final_pwrdown:
+ /* delay */
+ mov w4, #0xffffff
+554:
+ sub w4, w4, #1
+ cmp w4, #0
+ b.ge 554b
+
+ mov x0, xzr
+ b touch_line_0
+
+/* 4Kb aligned */
+.align 12
+start_line_0:
+ mov x0, #1
+ /* put ddr in self refresh - start */
+ mov x2, #DDR_SDRAM_CFG_2_FRCSR
+ ldr w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ orr w3, w3, w2
+ /* put ddr in self refresh - end */
+ str w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ nop
+ nop
+touch_line_0:
+ cbz x0, touch_line_1
+
+start_line_1:
+ /* quiesce ddr clocks - start */
+ orr w3, w5, #DCFG_DEVDISR5_MEM
+ mov w4, w3
+ /* quiesce ddr clocks - end */
+ str w4, [x7, x10]
+ mov w3, #DCFG_DEVDISR5_MEM
+ /* poll on ipstpack4 - start */
+ mov x2, #DDR_SLEEP_RETRY_CNT
+ nop
+ nop
+touch_line_1:
+ cbz x0, touch_line_2
+
+start_line_2:
+ /* x11 = PMU_IPSTPACK4_OFFSET */
+ ldr w1, [x7, x11]
+ tst w1, w3
+ b.ne 5f
+ subs x2, x2, #1
+ /* poll on ipstpack4 - end */
+ b.gt start_line_2
+
+ /* if we get here, we have a timeout err */
+ mov w4, w5
+ /* x10 = PMU_IPSTPCR4_OFFSET re-enable ddr clks interface */
+ str w4, [x7, x10]
+touch_line_2:
+ cbz x0, touch_line_3
+
+start_line_3:
+ /* load error code */
+ mov x0, #ERROR_DDR_SLEEP
+ b 2f
+5:
+ wfe
+ ldr w1, [x23, #EPU_EPCTR10_OFFSET]
+ cbz w1, 5b
+
+ mov w4, w5
+touch_line_3:
+ cbz x0, touch_line_4
+
+start_line_4:
+ /* re-enable ddr in devdisr5 */
+ str w4, [x8, x22]
+ /* re-enable ddr clk in ipstpcr4 */
+ str w4, [x7, x10]
+13:
+ /* poll on ipstpack4 - start */
+ ldr w1, [x7, x11]
+ tst w1, w3
+ b.eq 2f
+ nop
+ b 13b
+ /* poll on ipstpack4 - end */
+2:
+touch_line_4:
+ cbz x0, touch_line_5
+
+start_line_5:
+ /* take ddr out-of self refresh - start */
+ mov x2, #DDR_SDRAM_CFG_2_FRCSR
+ ldr w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ mov w4, w3
+ bic w4, w4, w2
+ mov w3, w4
+ /* wait for ddr cntrlr clock- start */
+ mov x1, #DDR_SLEEP_RETRY_CNT
+3:
+ subs x1, x1, #1
+touch_line_5:
+ cbz x0, touch_line_6
+
+start_line_6:
+ /* wait for ddr cntrlr clock - end */
+ b.gt 3b
+ /* take ddr out-of self refresh - end */
+ str w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ mov w1, w17
+ /* reset devdisr5 */
+ str w1, [x8, #DCFG_DEVDISR5_OFFSET]
+ mov w1, w16
+ /* reset devdisr4 */
+ str w1, [x8, #DCFG_DEVDISR4_OFFSET]
+ mov w1, w15
+touch_line_6:
+ cbz x0, touch_line_7
+
+start_line_7:
+ /* reset devdisr3 */
+ str w1, [x8, #DCFG_DEVDISR3_OFFSET]
+ mov w1, w14
+ /* reset devdisr2 */
+ str w1, [x8, #DCFG_DEVDISR2_OFFSET]
+ mov w1, w13
+ /* reset devdisr1 */
+ str w1, [x8, #DCFG_DEVDISR1_OFFSET]
+ /* reset ipstpcr4 */
+ str wzr, [x7, x10]
+ /* reset ipstpcr3 */
+ str wzr, [x7, x12]
+touch_line_7:
+ cbz x0, touch_line_8
+
+start_line_8:
+ /* reset ipstpcr2 */
+ str wzr, [x7, x18]
+ /* reset ipstpcr1 */
+ str wzr, [x7, x19]
+ /* reset ipstpcr0 */
+ str wzr, [x7, x21]
+
+touch_line_8:
+ cbz x0, touch_line_9
+
+start_line_9:
+ b continue_restart
+touch_line_9:
+ cbz x0, start_line_0
+
+/* execute here after ddr is back up */
+continue_restart:
+ /*
+ * if x0 = 1, all is well
+ * if x0 < 1, we had an error
+ */
+ cmp x0, #1
+ b.ne 4f
+ mov x0, #0
+4:
+ ret
diff --git a/plat/nxp/soc-ls1088a/aarch64/ls1088a_helpers.S b/plat/nxp/soc-ls1088a/aarch64/ls1088a_helpers.S
new file mode 100644
index 0000000..890cf81
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/aarch64/ls1088a_helpers.S
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+ .globl plat_secondary_cold_boot_setup
+ .globl plat_is_my_cpu_primary
+ .globl plat_reset_handler
+ .globl platform_mem_init
+
+func platform_mem1_init
+ ret
+endfunc platform_mem1_init
+
+func platform_mem_init
+ ret
+endfunc platform_mem_init
+
+func apply_platform_errata
+ ret
+endfunc apply_platform_errata
+
+func plat_reset_handler
+ mov x29, x30
+ bl apply_platform_errata
+
+#if defined(IMAGE_BL31)
+ ldr x0, =POLICY_SMMU_PAGESZ_64K
+ cbz x0, 1f
+ /* Set the SMMU page size in the sACR register */
+ bl _set_smmu_pagesz_64
+#endif
+1:
+ mov x30, x29
+ ret
+endfunc plat_reset_handler
+
+ /*
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ */
+func plat_secondary_cold_boot_setup
+ /* ls1088a does not do cold boot for secondary CPU */
+cb_panic:
+ b cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+ /*
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu.
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, 0x0
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
diff --git a/plat/nxp/soc-ls1088a/include/soc.h b/plat/nxp/soc-ls1088a/include/soc.h
new file mode 100644
index 0000000..eb36c2e
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/include/soc.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOC_H
+#define SOC_H
+
+/* Chassis specific defines - common across SoC's of a particular platform */
+#include "dcfg_lsch3.h"
+#include "soc_default_base_addr.h"
+#include "soc_default_helper_macros.h"
+
+/*
+ * SVR Definition of LS1088A
+ * A: without security
+ * AE: with security
+ * (not include major and minor rev)
+ */
+#define SVR_LS1044A 0x870323
+#define SVR_LS1044AE 0x870322
+#define SVR_LS1048A 0x870321
+#define SVR_LS1048AE 0x870320
+#define SVR_LS1084A 0x870303
+#define SVR_LS1084AE 0x870302
+#define SVR_LS1088A 0x870301
+#define SVR_LS1088AE 0x870300
+
+#define SVR_WO_E 0xFFFFFE
+
+/* Number of cores in platform */
+#define NUMBER_OF_CLUSTERS 2
+#define CORES_PER_CLUSTER 4
+#define PLATFORM_CORE_COUNT (NUMBER_OF_CLUSTERS * CORES_PER_CLUSTER)
+
+/* set to 0 if the clusters are not symmetrical */
+#define SYMMETRICAL_CLUSTERS 1
+
+
+#define NUM_DRAM_REGIONS 2
+#define NXP_DRAM0_ADDR 0x80000000
+#define NXP_DRAM0_MAX_SIZE 0x80000000 /* 2 GB */
+
+#define NXP_DRAM1_ADDR 0x8080000000
+#define NXP_DRAM1_MAX_SIZE 0x7F80000000 /* 510 G */
+
+/* DRAM0 Size defined in platform_def.h */
+#define NXP_DRAM0_SIZE PLAT_DEF_DRAM0_SIZE
+
+#define NXP_POWMGTDCR 0x700123C20
+
+/* epu register offsets and values */
+#define EPU_EPGCR_OFFSET 0x0
+#define EPU_EPIMCR10_OFFSET 0x128
+#define EPU_EPCTR10_OFFSET 0xa28
+#define EPU_EPCCR10_OFFSET 0x828
+
+#ifdef EPU_EPCCR10_VAL
+#undef EPU_EPCCR10_VAL
+#endif
+#define EPU_EPCCR10_VAL 0xf2800000
+
+#define EPU_EPIMCR10_VAL 0xba000000
+#define EPU_EPCTR10_VAL 0x0
+#define EPU_EPGCR_VAL (1 << 31)
+
+/* pmu register offsets and values */
+#define PMU_PCPW20SR_OFFSET 0x830
+#define PMU_CLAINACTSETR_OFFSET 0x1100
+#define PMU_CLAINACTCLRR_OFFSET 0x1104
+#define PMU_CLSINACTSETR_OFFSET 0x1108
+#define PMU_CLSINACTCLRR_OFFSET 0x110C
+#define PMU_CLL2FLUSHSETR_OFFSET 0x1110
+#define PMU_CLSL2FLUSHCLRR_OFFSET 0x1114
+#define PMU_CLL2FLUSHSR_OFFSET 0x1118
+#define PMU_POWMGTCSR_OFFSET 0x4000
+#define PMU_IPPDEXPCR0_OFFSET 0x4040
+#define PMU_IPPDEXPCR1_OFFSET 0x4044
+#define PMU_IPPDEXPCR2_OFFSET 0x4048
+#define PMU_IPPDEXPCR3_OFFSET 0x404C
+#define PMU_IPPDEXPCR4_OFFSET 0x4050
+#define PMU_IPPDEXPCR5_OFFSET 0x4054
+#define PMU_IPSTPCR0_OFFSET 0x4120
+#define PMU_IPSTPCR1_OFFSET 0x4124
+#define PMU_IPSTPCR2_OFFSET 0x4128
+#define PMU_IPSTPCR3_OFFSET 0x412C
+#define PMU_IPSTPCR4_OFFSET 0x4130
+#define PMU_IPSTPCR5_OFFSET 0x4134
+#define PMU_IPSTPCR6_OFFSET 0x4138
+#define PMU_IPSTPACK0_OFFSET 0x4140
+#define PMU_IPSTPACK1_OFFSET 0x4144
+#define PMU_IPSTPACK2_OFFSET 0x4148
+#define PMU_IPSTPACK3_OFFSET 0x414C
+#define PMU_IPSTPACK4_OFFSET 0x4150
+#define PMU_IPSTPACK5_OFFSET 0x4154
+#define PMU_IPSTPACK6_OFFSET 0x4158
+#define PMU_POWMGTCSR_VAL (1 << 20)
+
+#define IPPDEXPCR0_MASK 0xFFFFFFFF
+#define IPPDEXPCR1_MASK 0xFFFFFFFF
+#define IPPDEXPCR2_MASK 0xFFFFFFFF
+#define IPPDEXPCR3_MASK 0xFFFFFFFF
+#define IPPDEXPCR4_MASK 0xFFFFFFFF
+#define IPPDEXPCR5_MASK 0xFFFFFFFF
+
+/* DEVDISR5_FLX_TMR */
+#define IPPDEXPCR_FLX_TMR 0x00004000
+#define DEVDISR5_FLX_TMR 0x00004000
+
+#define IPSTPCR0_VALUE 0x0041310C
+#define IPSTPCR1_VALUE 0x000003FF
+#define IPSTPCR2_VALUE 0x00013006
+
+/* Dont' stop UART */
+#define IPSTPCR3_VALUE 0x0000033A
+
+#define IPSTPCR4_VALUE 0x00103300
+#define IPSTPCR5_VALUE 0x00000001
+#define IPSTPCR6_VALUE 0x00000000
+
+
+#define TZPC_BLOCK_SIZE 0x1000
+
+/* PORSR1 */
+#define PORSR1_RCW_MASK 0xFF800000
+#define PORSR1_RCW_SHIFT 23
+
+/* CFG_RCW_SRC[6:0] */
+#define RCW_SRC_TYPE_MASK 0x70
+
+/* RCW SRC NOR */
+#define NOR_16B_VAL 0x20
+
+/*
+ * RCW SRC Serial Flash
+ * 1. SERAIL NOR (QSPI)
+ * 2. OTHERS (SD/MMC, SPI, I2C1)
+ */
+#define RCW_SRC_SERIAL_MASK 0x7F
+#define QSPI_VAL 0x62
+#define SDHC_VAL 0x40
+#define EMMC_VAL 0x41
+
+/*
+ * Required LS standard platform porting definitions
+ * for CCN-504 - Read from RN-F node ID register
+ */
+#define PLAT_CLUSTER_TO_CCN_ID_MAP 1, 9, 11, 19
+
+/* Defines required for using XLAT tables from ARM common code */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 40)
+
+/*
+ * Clock Divisors
+ */
+#define NXP_PLATFORM_CLK_DIVIDER 1
+#define NXP_UART_CLK_DIVIDER 2
+
+/* dcfg register offsets and values */
+#define DCFG_DEVDISR1_OFFSET 0x70
+#define DCFG_DEVDISR2_OFFSET 0x74
+#define DCFG_DEVDISR3_OFFSET 0x78
+#define DCFG_DEVDISR5_OFFSET 0x80
+#define DCFG_DEVDISR6_OFFSET 0x84
+
+#define DCFG_DEVDISR1_SEC (1 << 22)
+#define DCFG_DEVDISR3_QBMAIN (1 << 12)
+#define DCFG_DEVDISR4_SPI_QSPI (1 << 4 | 1 << 5)
+#define DCFG_DEVDISR5_MEM (1 << 0)
+
+#define DEVDISR1_VALUE 0x0041310c
+#define DEVDISR2_VALUE 0x000003ff
+#define DEVDISR3_VALUE 0x00013006
+#define DEVDISR4_VALUE 0x0000033e
+#define DEVDISR5_VALUE 0x00103300
+#define DEVDISR6_VALUE 0x00000001
+
+/*
+ * pwr mgmt features supported in the soc-specific code:
+ * value == 0x0, the soc code does not support this feature
+ * value != 0x0, the soc code supports this feature
+ */
+#define SOC_CORE_RELEASE 0x1
+#define SOC_CORE_RESTART 0x1
+#define SOC_CORE_OFF 0x1
+#define SOC_CORE_STANDBY 0x1
+#define SOC_CORE_PWR_DWN 0x1
+#define SOC_CLUSTER_STANDBY 0x1
+#define SOC_CLUSTER_PWR_DWN 0x1
+#define SOC_SYSTEM_STANDBY 0x1
+#define SOC_SYSTEM_PWR_DWN 0x1
+#define SOC_SYSTEM_OFF 0x1
+#define SOC_SYSTEM_RESET 0x1
+
+#define SYSTEM_PWR_DOMAINS 1
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
+ NUMBER_OF_CLUSTERS + \
+ SYSTEM_PWR_DOMAINS)
+
+/* Power state coordination occurs at the system level */
+#define PLAT_PD_COORD_LVL MPIDR_AFFLVL2
+#define PLAT_MAX_PWR_LVL PLAT_PD_COORD_LVL
+
+/* Local power state for power domains in Run state */
+#define LS_LOCAL_STATE_RUN PSCI_LOCAL_STATE_RUN
+
+/* define retention state */
+#define PLAT_MAX_RET_STATE (PSCI_LOCAL_STATE_RUN + 1)
+#define LS_LOCAL_STATE_RET PLAT_MAX_RET_STATE
+
+/* define power-down state */
+#define PLAT_MAX_OFF_STATE (PLAT_MAX_RET_STATE + 1)
+#define LS_LOCAL_STATE_OFF PLAT_MAX_OFF_STATE
+
+#ifndef __ASSEMBLER__
+/* CCI slave interfaces */
+static const int cci_map[] = {
+ 3,
+ 4,
+};
+void soc_init_lowlevel(void);
+void soc_init_percpu(void);
+void _soc_set_start_addr(unsigned long addr);
+void _set_platform_security(void);
+#endif
+
+#endif /* SOC_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c b/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c
new file mode 100644
index 0000000..b7397ba
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <utils.h>
+
+#include <errata.h>
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+#error No static value defined
+#endif
+
+static const struct rc_timing rce[] = {
+ {U(1600), U(8), U(8)},
+ {U(1867), U(8), U(8)},
+ {U(2134), U(8), U(9)},
+ {}
+};
+
+static const struct board_timing udimm[] = {
+ {U(0x04), rce, U(0x01020307), U(0x08090b06)},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ int ret;
+ struct memctl_opt *popts = &priv->opt;
+
+ if (popts->rdimm != 0) {
+ debug("RDIMM parameters not set.\n");
+ return -EINVAL;
+ }
+
+ ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm));
+ if (ret != 0) {
+ return ret;
+ }
+
+ popts->addr_hash = 1;
+ popts->cpo_sample = U(0x7b);
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
+ DDR_CDR2_VREF_TRAIN_EN |
+ DDR_CDR2_VREF_RANGE_2;
+
+ return 0;
+}
+
+long long init_ddr(void)
+{
+ int spd_addr[] = { NXP_SPD_EEPROM0 };
+ struct ddr_info info;
+ struct sysinfo sys;
+ long long dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ get_clocks(&sys);
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL %lu\n", sys.freq_ddr_pll0);
+
+ zeromem(&info, sizeof(struct ddr_info));
+ info.num_ctlrs = NUM_OF_DDRC;
+ info.dimm_on_ctlr = DDRC_NUM_DIMM;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.spd_addr = spd_addr;
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+ dram_size = dram_init(&info);
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+ erratum_a008850_post();
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/plat_def.h b/plat/nxp/soc-ls1088a/ls1088aqds/plat_def.h
new file mode 100644
index 0000000..ebd3a26
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/plat_def.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+#define NXP_SPD_EEPROM0 0x51
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+#define BL2_START NXP_OCRAM_ADDR
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#define BL2_NOLOAD_START NXP_OCRAM_ADDR
+#define BL2_NOLOAD_LIMIT BL2_BASE
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES 4
+#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_HANDLES 4
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES 2
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES 1
+#endif
+
+#define BL32_IRQ_SEC_PHY_TIMER 29
+#define BL31_WDOG_SEC 89
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define PLAT_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define PLAT_LS_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(15, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/platform.c b/plat/nxp/soc-ls1088a/ls1088aqds/platform.c
new file mode 100644
index 0000000..8b3eada
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/platform.mk b/plat/nxp/soc-ls1088a/ls1088aqds/platform.mk
new file mode 100644
index 0000000..97ccf26
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/platform.mk
@@ -0,0 +1,31 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+BOOT_MODE ?= qspi
+BOARD := ls1088aqds
+
+# DDR Compilation Configs
+NUM_OF_DDRC := 1
+DDRC_NUM_DIMM := 1
+DDR_ECC_EN := yes
+
+# On-Board Flash Details
+QSPI_FLASH_SZ := 0x4000000
+NOR_FLASH_SZ := 0x20000000
+
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c \
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := qspi \
+ sd \
+ nor
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-ls1088a/soc.mk
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/platform_def.h b/plat/nxp/soc-ls1088a/ls1088aqds/platform_def.h
new file mode 100644
index 0000000..7daf1c0
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/policy.h b/plat/nxp/soc-ls1088a/ls1088aqds/policy.h
new file mode 100644
index 0000000..0eaafae
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/policy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/*
+ * Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c b/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c
new file mode 100644
index 0000000..c88583f
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <utils.h>
+
+#include <errata.h>
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+#error No static value defined
+#endif
+
+static const struct rc_timing rce[] = {
+ {U(1600), U(8), U(8)},
+ {U(1867), U(8), U(8)},
+ {U(2134), U(8), U(9)},
+ {}
+};
+
+static const struct board_timing udimm[] = {
+ {U(0x04), rce, U(0x01030508), U(0x090b0d06)},
+ {U(0x1f), rce, U(0x01030508), U(0x090b0d06)},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ int ret;
+ struct memctl_opt *popts = &priv->opt;
+
+ if (popts->rdimm != 0) {
+ debug("RDIMM parameters not set.\n");
+ return -EINVAL;
+ }
+
+ ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm));
+ if (ret != 0) {
+ return ret;
+ }
+
+ popts->addr_hash = 1;
+ popts->cpo_sample = U(0x7b);
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
+ DDR_CDR2_VREF_TRAIN_EN |
+ DDR_CDR2_VREF_RANGE_2;
+
+ return 0;
+}
+
+long long init_ddr(void)
+{
+ int spd_addr[] = { NXP_SPD_EEPROM0 };
+ struct ddr_info info;
+ struct sysinfo sys;
+ long long dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ get_clocks(&sys);
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL %lu\n", sys.freq_ddr_pll0);
+
+ zeromem(&info, sizeof(struct ddr_info));
+ info.num_ctlrs = NUM_OF_DDRC;
+ info.dimm_on_ctlr = DDRC_NUM_DIMM;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.spd_addr = spd_addr;
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+ dram_size = dram_init(&info);
+
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+ erratum_a008850_post();
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/plat_def.h b/plat/nxp/soc-ls1088a/ls1088ardb/plat_def.h
new file mode 100644
index 0000000..a6b14fe
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/plat_def.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+#define NXP_SPD_EEPROM0 0x51
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+#define BL2_START NXP_OCRAM_ADDR
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#define BL2_NOLOAD_START NXP_OCRAM_ADDR
+#define BL2_NOLOAD_LIMIT BL2_BASE
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES 4
+#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_HANDLES 4
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES 2
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES 1
+#endif
+
+#define BL32_IRQ_SEC_PHY_TIMER 29
+#define BL31_WDOG_SEC 89
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define PLAT_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define PLAT_LS_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(15, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/platform.c b/plat/nxp/soc-ls1088a/ls1088ardb/platform.c
new file mode 100644
index 0000000..8b3eada
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/platform.mk b/plat/nxp/soc-ls1088a/ls1088ardb/platform.mk
new file mode 100644
index 0000000..6884faf
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/platform.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+BOOT_MODE ?= qspi
+BOARD := ls1088ardb
+
+# DDR Compilation Configs
+NUM_OF_DDRC := 1
+DDRC_NUM_DIMM := 1
+DDR_ECC_EN := yes
+
+# On-Board Flash Details
+QSPI_FLASH_SZ := 0x4000000
+
+# Adding Platform files build files
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c \
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := qspi \
+ sd
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-ls1088a/soc.mk
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/platform_def.h b/plat/nxp/soc-ls1088a/ls1088ardb/platform_def.h
new file mode 100644
index 0000000..7daf1c0
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/policy.h b/plat/nxp/soc-ls1088a/ls1088ardb/policy.h
new file mode 100644
index 0000000..af206f9
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/policy.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/* Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1088a/soc.c b/plat/nxp/soc-ls1088a/soc.c
new file mode 100644
index 0000000..5f9f313
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/soc.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <caam.h>
+#include <cci.h>
+#include <common/debug.h>
+#include <dcfg.h>
+#ifdef I2C_INIT
+#include <i2c.h>
+#endif
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <ls_interconnect.h>
+#if TRUSTED_BOARD_BOOT
+#include <nxp_smmu.h>
+#endif
+#include <nxp_timer.h>
+#include <plat_console.h>
+#include <plat_gic.h>
+#include <plat_tzc400.h>
+#include <pmu.h>
+#if defined(NXP_SFP_ENABLED)
+#include <sfp.h>
+#endif
+
+#include <errata.h>
+#ifdef CONFIG_OCRAM_ECC_EN
+#include <ocram.h>
+#endif
+#include <plat_common.h>
+#include <platform_def.h>
+#include <soc.h>
+
+static unsigned char _power_domain_tree_desc[NUMBER_OF_CLUSTERS + 2];
+static struct soc_type soc_list[] = {
+ SOC_ENTRY(LS1044A, LS1044A, 1, 4),
+ SOC_ENTRY(LS1044AE, LS1044AE, 1, 4),
+ SOC_ENTRY(LS1048A, LS1048A, 1, 4),
+ SOC_ENTRY(LS1048AE, LS1048AE, 1, 4),
+ SOC_ENTRY(LS1084A, LS1084A, 2, 4),
+ SOC_ENTRY(LS1084AE, LS1084AE, 2, 4),
+ SOC_ENTRY(LS1088A, LS1088A, 2, 4),
+ SOC_ENTRY(LS1088AE, LS1088AE, 2, 4),
+};
+
+static dcfg_init_info_t dcfg_init_data = {
+ .g_nxp_dcfg_addr = NXP_DCFG_ADDR,
+ .nxp_sysclk_freq = NXP_SYSCLK_FREQ,
+ .nxp_ddrclk_freq = NXP_DDRCLK_FREQ,
+ .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER,
+};
+
+/*
+ * This function dynamically constructs the topology according to
+ * SoC Flavor and returns it.
+ */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ unsigned int i;
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+ /*
+ * The highest level is the system level. The next level is constituted
+ * by clusters and then cores in clusters.
+ */
+ _power_domain_tree_desc[0] = 1;
+ _power_domain_tree_desc[1] = num_clusters;
+
+ for (i = 0; i < _power_domain_tree_desc[1]; i++) {
+ _power_domain_tree_desc[i + 2] = cores_per_cluster;
+ }
+
+
+ return _power_domain_tree_desc;
+}
+
+CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256,
+ assert_invalid_ls1088a_cluster_count);
+
+/*
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ */
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr)
+{
+ return CORES_PER_CLUSTER;
+}
+
+/*
+ * This function returns the total number of cores in the SoC
+ */
+unsigned int get_tot_num_cores(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+ return (num_clusters * cores_per_cluster);
+}
+
+/*
+ * This function returns the PMU IDLE Cluster mask.
+ */
+unsigned int get_pmu_idle_cluster_mask(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+ return ((1 << num_clusters) - 2);
+}
+
+/*
+ * This function returns the PMU Flush Cluster mask.
+ */
+unsigned int get_pmu_flush_cluster_mask(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+ return ((1 << num_clusters) - 2);
+}
+
+/*
+ * This function returns the PMU IDLE Core mask.
+ */
+unsigned int get_pmu_idle_core_mask(void)
+{
+ return ((1 << get_tot_num_cores()) - 2);
+}
+
+#ifdef IMAGE_BL2
+
+void soc_bl2_prepare_exit(void)
+{
+#if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE)
+ set_sfp_wr_disable();
+#endif
+}
+
+void soc_preload_setup(void)
+{
+
+}
+
+/*
+ * This function returns the boot device based on RCW_SRC
+ */
+enum boot_device get_boot_dev(void)
+{
+ enum boot_device src = BOOT_DEVICE_NONE;
+ uint32_t porsr1;
+ uint32_t rcw_src, val;
+
+ porsr1 = read_reg_porsr1();
+
+ rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT;
+
+ /* RCW SRC NOR */
+ val = rcw_src & RCW_SRC_TYPE_MASK;
+ if (val == NOR_16B_VAL) {
+ src = BOOT_DEVICE_IFC_NOR;
+ INFO("RCW BOOT SRC is IFC NOR\n");
+ } else {
+ val = rcw_src & RCW_SRC_SERIAL_MASK;
+ switch (val) {
+ case QSPI_VAL:
+ src = BOOT_DEVICE_QSPI;
+ INFO("RCW BOOT SRC is QSPI\n");
+ break;
+ case SDHC_VAL:
+ src = BOOT_DEVICE_EMMC;
+ INFO("RCW BOOT SRC is SD/EMMC\n");
+ break;
+ case EMMC_VAL:
+ src = BOOT_DEVICE_EMMC;
+ INFO("RCW BOOT SRC is SD/EMMC\n");
+ break;
+ default:
+ src = BOOT_DEVICE_NONE;
+ }
+ }
+
+ return src;
+}
+
+/*
+ * This function sets up access permissions on memory regions
+ */
+void soc_mem_access(void)
+{
+ dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+ int i = 0;
+ struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION];
+ int dram_idx, index = 1;
+
+ for (dram_idx = 0; dram_idx < info_dram_regions->num_dram_regions;
+ dram_idx++) {
+ if (info_dram_regions->region[i].size == 0) {
+ ERROR("DDR init failure, or");
+ ERROR("DRAM regions not populated correctly.\n");
+ break;
+ }
+
+ index = populate_tzc400_reg_list(tzc400_reg_list,
+ dram_idx, index,
+ info_dram_regions->region[dram_idx].addr,
+ info_dram_regions->region[dram_idx].size,
+ NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE);
+ }
+
+ mem_access_setup(NXP_TZC_ADDR, index,
+ tzc400_reg_list);
+}
+
+/*
+ * This function implements soc specific erratum
+ * This is called before DDR is initialized or MMU is enabled
+ */
+void soc_early_init(void)
+{
+ enum boot_device dev;
+ dram_regions_info_t *dram_regions_info = get_dram_regions_info();
+
+#ifdef CONFIG_OCRAM_ECC_EN
+ ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE);
+#endif
+ dcfg_init(&dcfg_init_data);
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+ enable_timer_base_to_cluster(NXP_PMU_ADDR);
+ enable_core_tb(NXP_PMU_ADDR);
+
+ /*
+ * Use the region(NXP_SD_BLOCK_BUF_ADDR + NXP_SD_BLOCK_BUF_SIZE)
+ * as dma of sd
+ */
+ dev = get_boot_dev();
+ if (dev == BOOT_DEVICE_EMMC) {
+ mmap_add_region(NXP_SD_BLOCK_BUF_ADDR, NXP_SD_BLOCK_BUF_ADDR,
+ NXP_SD_BLOCK_BUF_SIZE,
+ MT_DEVICE | MT_RW | MT_NS);
+ }
+
+#if TRUSTED_BOARD_BOOT
+ uint32_t mode;
+
+ sfp_init(NXP_SFP_ADDR);
+ /*
+ * For secure boot disable SMMU.
+ * Later when platform security policy comes in picture,
+ * this might get modified based on the policy
+ */
+ if (check_boot_mode_secure(&mode) == true) {
+ bypass_smmu(NXP_SMMU_ADDR);
+ }
+
+ /*
+ * For Mbedtls currently crypto is not supported via CAAM
+ * enable it when that support is there. In tbbr.mk
+ * the CAAM_INTEG is set as 0.
+ */
+#ifndef MBEDTLS_X509
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled() == false) {
+ INFO("SEC is disabled.\n");
+ } else {
+ sec_init(NXP_CAAM_ADDR);
+ }
+#endif
+#endif
+
+ soc_errata();
+
+ delay_timer_init(NXP_TIMER_ADDR);
+ i2c_init(NXP_I2C_ADDR);
+ dram_regions_info->total_dram_size = init_ddr();
+}
+#else /* !IMAGE_BL2 */
+
+void soc_early_platform_setup2(void)
+{
+ dcfg_init(&dcfg_init_data);
+ /*
+ * Initialize system level generic timer for Socs
+ */
+ delay_timer_init(NXP_TIMER_ADDR);
+
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+}
+
+void soc_platform_setup(void)
+{
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ static uintptr_t target_mask_array[PLATFORM_CORE_COUNT];
+ static interrupt_prop_t ls_interrupt_props[] = {
+ PLAT_LS_G1S_IRQ_PROPS(INTR_GROUP1S),
+ PLAT_LS_G0_IRQ_PROPS(INTR_GROUP0)
+ };
+
+ plat_ls_gic_driver_init(NXP_GICD_ADDR, NXP_GICR_ADDR,
+ PLATFORM_CORE_COUNT,
+ ls_interrupt_props,
+ ARRAY_SIZE(ls_interrupt_props),
+ target_mask_array,
+ plat_core_pos);
+
+ plat_ls_gic_init();
+ enable_init_timer();
+}
+
+/*
+ * This function initializes the soc from the BL31 module
+ */
+void soc_init(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ /* low-level init of the soc */
+ soc_init_lowlevel();
+ _init_global_data();
+ soc_init_percpu();
+ _initialize_psci();
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+ /*
+ * Enable Interconnect coherency for the primary CPU's cluster.
+ */
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ plat_ls_interconnect_enter_coherency(num_clusters);
+
+ /* set platform security policies */
+ _set_platform_security();
+
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled() == false) {
+ INFO("SEC is disabled.\n");
+ } else {
+ sec_init(NXP_CAAM_ADDR);
+ }
+}
+
+void soc_runtime_setup(void)
+{
+
+}
+#endif /* IMAGE_BL2 */
+
+/*
+ * Function to return the SoC SYS CLK
+ */
+unsigned int get_sys_clk(void)
+{
+ return NXP_SYSCLK_FREQ;
+}
+
+/*
+ * Function returns the base counter frequency
+ * after reading the first entry at CNTFID0 (0x20 offset).
+ *
+ * Function is used by:
+ * 1. ARM common code for PSCI management.
+ * 2. ARM Generic Timer init.
+ */
+unsigned int plat_get_syscnt_freq2(void)
+{
+ unsigned int counter_base_frequency;
+ /*
+ * Below register specifies the base frequency of the system counter.
+ * As per NXP Board Manuals:
+ * The system counter always works with SYS_REF_CLK/4 frequency clock.
+ */
+ counter_base_frequency = mmio_read_32(NXP_TIMER_ADDR + CNTFID_OFF);
+
+ return counter_base_frequency;
+}
diff --git a/plat/nxp/soc-ls1088a/soc.def b/plat/nxp/soc-ls1088a/soc.def
new file mode 100644
index 0000000..25d0847
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/soc.def
@@ -0,0 +1,87 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# This file contains the basic architecture definitions that drive the build
+#
+# -----------------------------------------------------------------------------
+
+CORE_TYPE := a53
+
+CACHE_LINE := 6
+
+# Set to GIC400 or GIC500
+GIC := GIC500
+
+# Set to CCI400 or CCN504 or CCN508
+INTERCONNECT := CCI400
+
+# Select the DDR PHY generation to be used
+PLAT_DDR_PHY := PHY_GEN1
+
+PHYS_SYS := 64
+
+# Indicate layerscape chassis level - set to 3=LSCH3 or 2=LSCH2
+CHASSIS := 3
+
+# TZC IP Details TZC used is TZC380 or TZC400
+TZC_ID := TZC400
+
+# CONSOLE Details available is NS16550 or PL011
+CONSOLE := NS16550
+
+NXP_SFP_VER := 3_4
+
+# In IMAGE_BL2, compile time flag for handling Cache coherency
+# with CAAM for BL2 running from OCRAM
+SEC_MEM_NON_COHERENT := yes
+
+
+# OCRAM MAP for BL2
+# Before BL2
+# 0x18000000 - 0x18009fff -> Used by ROM code, (TBD - can it be used for xlat tables)
+# 0x1800a000 - 0x1801Cfff -> Reserved for BL2 binary (76 KB)
+# 0x1801D000 - 0x1801ffff -> CSF header for BL2 (12 KB)
+OCRAM_START_ADDR := 0x18000000
+OCRAM_SIZE := 0x20000
+
+CSF_HDR_SZ := 0x3000
+
+# Area of OCRAM reserved by ROM code
+NXP_ROM_RSVD := 0xa000
+
+# Input to CST create_hdr_isbc tool
+BL2_HDR_LOC := 0x1801D000
+
+# Location of BL2 on OCRAM
+# BL2_BASE=OCRAM_START_ADDR+NXP_ROM_RSVD
+BL2_BASE := 0x1800a000
+
+# SoC ERRATUM to be enabled
+ERRATA_SOC_A008850 := 1
+
+# ARM Erratum
+ERRATA_A53_855873 := 1
+
+# DDR Erratum
+ERRATA_DDR_A008511 := 1
+ERRATA_DDR_A009803 := 1
+ERRATA_DDR_A009942 := 1
+ERRATA_DDR_A010165 := 1
+
+# Define Endianness of each module
+NXP_ESDHC_ENDIANNESS := LE
+NXP_SFP_ENDIANNESS := LE
+NXP_GPIO_ENDIANNESS := LE
+NXP_SNVS_ENDIANNESS := LE
+NXP_GUR_ENDIANNESS := LE
+NXP_SEC_ENDIANNESS := LE
+NXP_DDR_ENDIANNESS := LE
+NXP_QSPI_ENDIANNESS := LE
+
+# OCRAM ECC Enabled
+OCRAM_ECC_EN := yes
diff --git a/plat/nxp/soc-ls1088a/soc.mk b/plat/nxp/soc-ls1088a/soc.mk
new file mode 100644
index 0000000..83ac9d0
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/soc.mk
@@ -0,0 +1,110 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# SoC-specific build parameters
+SOC := ls1088a
+PLAT_PATH := plat/nxp
+PLAT_COMMON_PATH:= plat/nxp/common
+PLAT_DRIVERS_PATH:= drivers/nxp
+PLAT_SOC_PATH := ${PLAT_PATH}/soc-${SOC}
+BOARD_PATH := ${PLAT_SOC_PATH}/${BOARD}
+
+# Separate BL2 NOLOAD region (.bss, stack, page tables). need to
+# define BL2_NOLOAD_START and BL2_NOLOAD_LIMIT
+SEPARATE_BL2_NOLOAD_REGION := 1
+
+# get SoC-specific defnitions
+include ${PLAT_SOC_PATH}/soc.def
+include ${PLAT_COMMON_PATH}/plat_make_helper/soc_common_def.mk
+include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+
+# For Security Features
+DISABLE_FUSE_WRITE := 1
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+ifeq (${GENERATE_COT},1)
+# Save Keys to be used by DDR FIP image
+SAVE_KEYS=1
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
+# Used by create_pbl tool to
+# create bl2_<boot_mode>_sec.pbl image
+SECURE_BOOT := yes
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,CRYPTO_NEEDED,BL_COMM))
+
+# Selecting Drivers for SoC
+$(eval $(call SET_NXP_MAKE_FLAG,DCFG_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,TIMER_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,INTERCONNECT_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,GIC_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,PMU_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,DDR_DRIVER_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,TZASC_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,I2C_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
+
+# Selecting PSCI & SIP_SVC support
+$(eval $(call SET_NXP_MAKE_FLAG,PSCI_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,SIPSVC_NEEDED,BL31))
+
+
+# Adding SoC specific files
+include ${PLAT_COMMON_PATH}/soc_errata/errata.mk
+
+PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/include/default\
+ -I${BOARD_PATH}\
+ -I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\
+ -I${PLAT_COMMON_PATH}/soc_errata\
+ -I${PLAT_COMMON_PATH}/include\
+ -I${PLAT_SOC_PATH}/include
+
+ifeq (${SECURE_BOOT},yes)
+include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk
+endif
+
+ifeq (${PSCI_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/psci/psci.mk
+endif
+
+ifeq (${SIPSVC_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/sip_svc/sipsvc.mk
+endif
+
+# for fuse-fip & fuse-programming
+ifeq (${FUSE_PROG}, 1)
+include ${PLAT_COMMON_PATH}/fip_handler/fuse_fip/fuse.mk
+endif
+
+ifeq (${IMG_LOADR_NEEDED},yes)
+include $(PLAT_COMMON_PATH)/img_loadr/img_loadr.mk
+endif
+
+# Adding source files for the above selected drivers.
+include ${PLAT_DRIVERS_PATH}/drivers.mk
+
+PLAT_BL_COMMON_SOURCES += ${PLAT_COMMON_PATH}/$(ARCH)/ls_helpers.S\
+ ${PLAT_SOC_PATH}/${ARCH}/${SOC}_helpers.S\
+ ${PLAT_SOC_PATH}/soc.c
+
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}.S\
+ ${PSCI_SOURCES}\
+ ${SIPSVC_SOURCES}\
+ ${PLAT_COMMON_PATH}/$(ARCH)/bl31_data.S
+
+ifeq (${TEST_BL31}, 1)
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/bootmain64.S \
+ ${PLAT_SOC_PATH}/$(ARCH)/nonboot64.S
+endif
+
+BL2_SOURCES += ${DDR_CNTLR_SOURCES}\
+ ${TBBR_SOURCES}\
+ ${FUSE_SOURCES}
+
+# Adding TFA setup files
+include ${PLAT_PATH}/common/setup/common.mk
diff --git a/plat/nxp/soc-lx2160a/soc.def b/plat/nxp/soc-lx2160a/soc.def
index 24d1d13..81d6744 100644
--- a/plat/nxp/soc-lx2160a/soc.def
+++ b/plat/nxp/soc-lx2160a/soc.def
@@ -1,6 +1,6 @@
#
# Copyright (c) 2015, 2016 Freescale Semiconductor, Inc.
-# Copyright 2017-2020 NXP Semiconductors
+# Copyright 2017-2022 NXP Semiconductors
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -107,5 +107,10 @@
# SoC Errata
ERRATA_SOC_A050426 := 1
+# DDR Errata
+ERRATA_DDR_A011396 := 1
+ERRATA_DDR_A050450 := 1
+ERRATA_DDR_A050958 := 1
+
# enable dynamic memory mapping
PLAT_XLAT_TABLES_DYNAMIC := 1
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 47ec791..0c184f4 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,7 @@
#include <common/bl_common.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
#include "qemu_private.h"
#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \
@@ -160,4 +161,9 @@
DEFINE_CONFIGURE_MMU_EL(svc_mon)
#endif
-
+#if MEASURED_BOOT || TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
+#endif
diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h
index 4dc62f5..c313cb6 100644
--- a/plat/qemu/common/qemu_private.h
+++ b/plat/qemu/common/qemu_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -34,4 +34,18 @@
void qemu_pwr_gic_on_finish(void);
void qemu_pwr_gic_off(void);
+int qemu_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr,
+ size_t log_size);
+
+int qemu_set_nt_fw_info(
+/*
+ * Currently OP-TEE does not support reading DTBs from Secure memory
+ * and this option should be removed when feature is supported.
+ */
+#ifdef SPD_opteed
+ uintptr_t log_addr,
+#endif
+ size_t log_size,
+ uintptr_t *ns_log_addr);
+
#endif /* QEMU_PRIVATE_H */
diff --git a/plat/qemu/common/qemu_trusted_boot.c b/plat/qemu/common/qemu_trusted_boot.c
index 1ef7e43..6a8edca 100644
--- a/plat/qemu/common/qemu_trusted_boot.c
+++ b/plat/qemu/common/qemu_trusted_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,8 +29,3 @@
{
return 1;
}
-
-int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
-{
- return get_mbedtls_heap_helper(heap_addr, heap_size);
-}
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index c02eff9..c9ed640 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -84,7 +84,7 @@
#define NS_DRAM0_SIZE ULL(0xc0000000)
#define SEC_SRAM_BASE 0x0e000000
-#define SEC_SRAM_SIZE 0x00060000
+#define SEC_SRAM_SIZE 0x00100000
#define SEC_DRAM_BASE 0x0e100000
#define SEC_DRAM_SIZE 0x00f00000
@@ -146,7 +146,7 @@
* Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
* current BL3-1 debug size plus a little space for growth.
*/
-#define BL31_BASE (BL31_LIMIT - 0x20000)
+#define BL31_BASE (BL31_LIMIT - 0x60000)
#define BL31_LIMIT (BL_RAM_BASE + BL_RAM_SIZE)
#define BL31_PROGBITS_LIMIT BL1_RW_BASE
@@ -270,4 +270,9 @@
*/
#define SYS_COUNTER_FREQ_IN_TICKS ((1000 * 1000 * 1000) / 16)
+/*
+ * Maximum size of Event Log buffer used in Measured Boot Event Log driver
+ */
+#define PLAT_EVENT_LOG_MAX_SIZE UL(0x400)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index a8f978a..e0b5271 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -57,11 +57,7 @@
ifneq (${TRUSTED_BOARD_BOOT},0)
- include drivers/auth/mbedtls/mbedtls_crypto.mk
- include drivers/auth/mbedtls/mbedtls_x509.mk
-
AUTH_SOURCES := drivers/auth/auth_mod.c \
- drivers/auth/crypto_mod.c \
drivers/auth/img_parser_mod.c \
drivers/auth/tbbr/tbbr_cot_common.c
@@ -78,6 +74,8 @@
$(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S \
drivers/auth/tbbr/tbbr_cot_bl2.c
+ include drivers/auth/mbedtls/mbedtls_x509.mk
+
ROT_KEY = $(BUILD_PLAT)/rot_key.pem
ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
@@ -90,12 +88,44 @@
$(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
- $(Q)openssl genrsa 2048 > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
$(ROTPK_HASH): $(ROT_KEY)
@echo " OPENSSL $@"
- $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
- openssl dgst -sha256 -binary > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
+endif
+
+# Include Measured Boot makefile before any Crypto library makefile.
+# Crypto library makefile may need default definitions of Measured Boot build
+# flags present in Measured Boot makefile.
+ifeq (${MEASURED_BOOT},1)
+ MEASURED_BOOT_MK := drivers/measured_boot/event_log/event_log.mk
+ $(info Including ${MEASURED_BOOT_MK})
+ include ${MEASURED_BOOT_MK}
+
+ ifneq (${MBOOT_EL_HASH_ALG}, sha256)
+ $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
+ endif
+
+ BL2_SOURCES += plat/qemu/qemu/qemu_measured_boot.c \
+ plat/qemu/qemu/qemu_common_measured_boot.c \
+ plat/qemu/qemu/qemu_helpers.c \
+ ${EVENT_LOG_SOURCES}
+
+ BL1_SOURCES += plat/qemu/qemu/qemu_bl1_measured_boot.c
+
+endif
+
+ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT}),)
+ CRYPTO_SOURCES := drivers/auth/crypto_mod.c
+
+ BL1_SOURCES += ${CRYPTO_SOURCES}
+ BL2_SOURCES += ${CRYPTO_SOURCES}
+
+ # We expect to locate the *.mk files under the directories specified below
+ #
+ include drivers/auth/mbedtls/mbedtls_crypto.mk
endif
BL1_SOURCES += drivers/io/io_semihosting.c \
@@ -131,6 +161,7 @@
${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c \
${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c \
common/fdt_fixup.c \
+ common/fdt_wrappers.c \
common/desc_image_load.c
ifeq ($(add-lib-optee),yes)
diff --git a/plat/qemu/qemu/qemu_bl1_measured_boot.c b/plat/qemu/qemu/qemu_bl1_measured_boot.c
new file mode 100644
index 0000000..3d20f97
--- /dev/null
+++ b/plat/qemu/qemu/qemu_bl1_measured_boot.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <common/desc_image_load.h>
+
+/*
+ * Add dummy functions for measured boot for BL1.
+ * In most of the SoC's, ROM/BL1 code is pre-built. So we are assumimg that
+ * it doesn't have the capability to do measurements and extend eventlog.
+ * hence these are dummy functions.
+ */
+void bl1_plat_mboot_init(void)
+{
+}
+
+void bl1_plat_mboot_finish(void)
+{
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+ return 0;
+}
diff --git a/plat/qemu/qemu/qemu_common_measured_boot.c b/plat/qemu/qemu/qemu_common_measured_boot.c
new file mode 100644
index 0000000..41f7f87
--- /dev/null
+++ b/plat/qemu/qemu/qemu_common_measured_boot.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/event_log/event_log.h>
+#include <plat/common/platform.h>
+
+extern event_log_metadata_t qemu_event_log_metadata[];
+
+const event_log_metadata_t *plat_event_log_get_metadata(void)
+{
+ return qemu_event_log_metadata;
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+ /* Calculate image hash and record data in Event Log */
+ int err = event_log_measure_and_record(image_data->image_base,
+ image_data->image_size,
+ image_id);
+ if (err != 0) {
+ ERROR("%s%s image id %u (%i)\n",
+ "Failed to ", "record", image_id, err);
+ return err;
+ }
+
+ return 0;
+}
diff --git a/plat/qemu/qemu/qemu_helpers.c b/plat/qemu/qemu/qemu_helpers.c
new file mode 100644
index 0000000..01b8249
--- /dev/null
+++ b/plat/qemu/qemu/qemu_helpers.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#if MEASURED_BOOT
+#include <common/desc_image_load.h>
+#endif
+#include <common/fdt_wrappers.h>
+
+#include <libfdt.h>
+
+#ifdef SPD_opteed
+/*
+ * Currently OP-TEE does not support reading DTBs from Secure memory
+ * and this property should be removed when this feature is supported.
+ */
+#define DTB_PROP_HW_SM_LOG_ADDR "tpm_event_log_sm_addr"
+#endif
+
+#define DTB_PROP_HW_LOG_ADDR "tpm_event_log_addr"
+#define DTB_PROP_HW_LOG_SIZE "tpm_event_log_size"
+
+#if MEASURED_BOOT
+
+#ifdef SPD_opteed
+int qemu_set_tee_fw_info(uintptr_t config_base, uintptr_t log_addr,
+ size_t log_size)
+{
+ int offs, err = 0;
+ void *dtb = (void *)config_base;
+ const char *compatible = "arm,tpm_event_log";
+ uint64_t sec_base = cpu_to_fdt64(log_addr);
+ uint32_t sz = cpu_to_fdt32(log_size);
+
+ offs = fdtw_find_or_add_subnode(dtb, 0, "tpm-event-log");
+ if (offs < 0) {
+ ERROR("Failed to add node tpm-event-log %d\n", offs);
+ return offs;
+ }
+
+ if (fdt_appendprop(dtb, offs, "compatible", compatible,
+ strlen(compatible) + 1) < 0) {
+ return -1;
+ }
+
+ err = fdt_setprop(dtb, offs, DTB_PROP_HW_SM_LOG_ADDR, &sec_base, 8);
+ if (err < 0) {
+ ERROR("Failed to add log addr err %d\n", err);
+ return err;
+ }
+
+ err = fdt_setprop(dtb, offs, DTB_PROP_HW_LOG_SIZE, &sz, 4);
+ if (err < 0) {
+ ERROR("Failed to add log addr err %d\n", err);
+ return err;
+ }
+
+ return err;
+}
+#endif
+
+/*
+ * Write the Event Log address and its size in the DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+static int qemu_set_event_log_info(uintptr_t config_base,
+#ifdef SPD_opteed
+ uintptr_t sm_log_addr,
+#endif
+ uintptr_t log_addr, size_t log_size)
+{
+ /* As libfdt uses void *, we can't avoid this cast */
+ void *dtb = (void *)config_base;
+ const char *compatible_tpm = "tcg,tpm-tis-mmio";
+ uint64_t base = cpu_to_fdt64(log_addr);
+ uint32_t sz = cpu_to_fdt32(log_size);
+ int err, node;
+
+ err = fdt_open_into(dtb, dtb, PLAT_QEMU_DT_MAX_SIZE);
+ if (err < 0) {
+ ERROR("Invalid Device Tree at %p: error %d\n", dtb, err);
+ return err;
+ }
+
+ /*
+ * Verify that the DTB is valid, before attempting to write to it,
+ * and get the DTB root node.
+ */
+
+ /* Check if the pointer to DT is correct */
+ err = fdt_check_header(dtb);
+ if (err < 0) {
+ WARN("Invalid DTB file passed\n");
+ return err;
+ }
+
+ /*
+ * Find the TPM node in device tree. On qemu, we assume it will
+ * be sw-tpm.
+ */
+ node = fdt_node_offset_by_compatible(dtb, -1, compatible_tpm);
+ if (node < 0) {
+ ERROR("The compatible property '%s' not%s", compatible_tpm,
+ " found in the config\n");
+ return node;
+ }
+
+ err = fdt_setprop(dtb, node, DTB_PROP_HW_LOG_ADDR, &base, 8);
+ if (err < 0) {
+ ERROR("Failed to add log addr err %d\n", err);
+ return err;
+ }
+
+ err = fdt_setprop(dtb, node, DTB_PROP_HW_LOG_SIZE, &sz, 4);
+ if (err < 0) {
+ ERROR("Failed to add log addr err %d\n", err);
+ return err;
+ }
+
+#ifdef SPD_opteed
+ err = qemu_set_tee_fw_info(config_base, sm_log_addr, log_size);
+ if (err < 0) {
+ ERROR("Failed to add tpm-event-node at %p: err %d\n", dtb, err);
+ return err;
+ }
+#endif
+
+ err = fdt_pack(dtb);
+ if (err < 0) {
+ ERROR("Failed to pack Device Tree at %p: err %d\n", dtb, err);
+ return err;
+ }
+
+ /*
+ * Ensure that the info written to the DTB is visible
+ * to other images.
+ */
+ flush_dcache_range(config_base, fdt_totalsize(dtb));
+
+ return err;
+}
+
+/*
+ * This function writes the Event Log address and its size
+ * in the TOS_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+int qemu_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr,
+ size_t log_size)
+{
+ int err = 0;
+
+ assert(config_base != 0UL);
+ assert(log_addr != 0UL);
+
+ /*
+ * FIXME - add code to add/update Log address and it's
+ * size in TOS FW CONFIG.
+ * For now we don't have support for TOS FW config in OP-TEE.
+ * So leave this function blank
+ */
+
+ return err;
+}
+
+/*
+ * This function writes the Event Log address and its size
+ * in the QEMU DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+int qemu_set_nt_fw_info(
+#ifdef SPD_opteed
+ uintptr_t log_addr,
+#endif
+ size_t log_size, uintptr_t *ns_log_addr)
+{
+ uintptr_t ns_addr;
+ int err;
+
+ assert(ns_log_addr != NULL);
+
+ ns_addr = PLAT_QEMU_DT_BASE + PLAT_QEMU_DT_MAX_SIZE;
+
+ /* Write the Event Log address and its size in the DTB */
+ err = qemu_set_event_log_info(PLAT_QEMU_DT_BASE,
+#ifdef SPD_opteed
+ log_addr,
+#endif
+ ns_addr, log_size);
+
+ /* Return Event Log address in Non-secure memory */
+ *ns_log_addr = (err < 0) ? 0UL : ns_addr;
+ return err;
+}
+#endif /* MEASURED_BOOT */
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
new file mode 100644
index 0000000..d9e475a
--- /dev/null
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, Linaro.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/measured_boot/event_log/event_log.h>
+#include <plat/common/common_def.h>
+#include <tools_share/tbbr_oid.h>
+
+#include "../common/qemu_private.h"
+
+/* Event Log data */
+static uint8_t event_log[PLAT_EVENT_LOG_MAX_SIZE];
+static uint64_t event_log_base;
+
+/* FVP table with platform specific image IDs, names and PCRs */
+const event_log_metadata_t qemu_event_log_metadata[] = {
+ { BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
+ { BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
+ { BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
+ { BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
+ { BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
+ { HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
+ { NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
+ { SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
+ { SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
+ { TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
+
+ { EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
+};
+
+void bl2_plat_mboot_init(void)
+{
+ /*
+ * Here we assume that BL1/ROM code doesn't have the driver
+ * to measure the BL2 code which is a common case for
+ * already existing platforms
+ */
+ event_log_init(event_log, event_log + sizeof(event_log));
+ event_log_write_header();
+
+ /*
+ * TBD - Add code to do self measurement of BL2 code and add an
+ * event for BL2 measurement
+ */
+
+ event_log_base = (uintptr_t)event_log;
+}
+
+void bl2_plat_mboot_finish(void)
+{
+ int rc;
+
+ /* Event Log address in Non-Secure memory */
+ uintptr_t ns_log_addr;
+
+ /* Event Log filled size */
+ size_t event_log_cur_size;
+
+ event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
+
+ rc = qemu_set_nt_fw_info(
+#ifdef SPD_opteed
+ (uintptr_t)event_log_base,
+#endif
+ event_log_cur_size, &ns_log_addr);
+ if (rc != 0) {
+ ERROR("%s(): Unable to update %s_FW_CONFIG\n",
+ __func__, "NT");
+ /*
+ * It is a fatal error because on QEMU secure world software
+ * assumes that a valid event log exists and will use it to
+ * record the measurements into the fTPM or sw-tpm.
+ * Note: In QEMU platform, OP-TEE uses nt_fw_config to get the
+ * secure Event Log buffer address.
+ */
+ panic();
+ }
+
+ /* Copy Event Log to Non-secure memory */
+ (void)memcpy((void *)ns_log_addr, (const void *)event_log_base,
+ event_log_cur_size);
+
+ /* Ensure that the Event Log is visible in Non-secure memory */
+ flush_dcache_range(ns_log_addr, event_log_cur_size);
+
+#if defined(SPD_tspd) || defined(SPD_spmd)
+ /* Set Event Log data in TOS_FW_CONFIG */
+ rc = qemu_set_tos_fw_info((uintptr_t)event_log_base,
+ event_log_cur_size);
+ if (rc != 0) {
+ ERROR("%s(): Unable to update %s_FW_CONFIG\n",
+ __func__, "TOS");
+ panic();
+ }
+#endif /* defined(SPD_tspd) || defined(SPD_spmd) */
+
+ dump_event_log((uint8_t *)event_log_base, event_log_cur_size);
+}
diff --git a/plat/qti/common/inc/qti_plat.h b/plat/qti/common/inc/qti_plat.h
index 4d9d320..d616efe 100644
--- a/plat/qti/common/inc/qti_plat.h
+++ b/plat/qti/common/inc/qti_plat.h
@@ -25,13 +25,14 @@
/*
* Utility functions common to ARM standard platforms
*/
-void qti_setup_page_tables(uintptr_t total_base,
+void qti_setup_page_tables(
+ uintptr_t total_base,
size_t total_size,
uintptr_t code_start,
uintptr_t code_limit,
uintptr_t rodata_start,
- uintptr_t rodata_limit,
- uintptr_t coh_start, uintptr_t coh_limit);
+ uintptr_t rodata_limit
+ );
/*
* Mandatory functions required in ARM standard platforms
diff --git a/plat/qti/common/src/aarch64/qti_helpers.S b/plat/qti/common/src/aarch64/qti_helpers.S
index c1ea7b3..d34b530 100644
--- a/plat/qti/common/src/aarch64/qti_helpers.S
+++ b/plat/qti/common/src/aarch64/qti_helpers.S
@@ -72,17 +72,10 @@
/* save the lr */
mov x18, x30
- /* Serialize CPUSS boot setup. Multi core enter simultaneously. */
- ldr x0, =g_qti_cpuss_boot_lock
- bl spin_lock
-
/* pass cold boot status. */
ldr w0, g_qti_bl31_cold_booted
/* Execuete CPUSS boot set up on every core. */
bl qtiseclib_cpuss_reset_asm
- ldr x0, =g_qti_cpuss_boot_lock
- bl spin_unlock
-
ret x18
endfunc plat_reset_handler
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_gold.S b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
index a1b40c8..9bcdf54 100644
--- a/plat/qti/common/src/aarch64/qti_kryo4_gold.S
+++ b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
@@ -28,19 +28,11 @@
mov x19, x30
bl qtiseclib_kryo4_gold_reset_asm
-
- ret x19
+ mov x30, x19
+ b cortex_a76_reset_func
endfunc qti_kryo4_gold_reset_func
-/* ----------------------------------------------------
- * The CPU Ops core power down function for Kryo-3 Gold
- * ----------------------------------------------------
- */
-func qti_kryo4_gold_core_pwr_dwn
- ret
-endfunc qti_kryo4_gold_core_pwr_dwn
-
/* -------------------------------------------------------
* The CPU Ops cluster power down function for Kryo-3 Gold
* -------------------------------------------------------
@@ -77,7 +69,9 @@
ret
endfunc qti_kryo4_gold_cpu_reg_dump
-declare_cpu_ops qti_kryo4_gold, QTI_KRYO4_GOLD_MIDR, \
+declare_cpu_ops_wa qti_kryo4_gold, QTI_KRYO4_GOLD_MIDR, \
qti_kryo4_gold_reset_func, \
- qti_kryo4_gold_core_pwr_dwn, \
+ CPU_NO_EXTRA1_FUNC, \
+ cortex_a76_disable_wa_cve_2018_3639, \
+ cortex_a76_core_pwr_dwn, \
qti_kryo4_gold_cluster_pwr_dwn
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_silver.S b/plat/qti/common/src/aarch64/qti_kryo4_silver.S
index 183eeb0..36374b7 100644
--- a/plat/qti/common/src/aarch64/qti_kryo4_silver.S
+++ b/plat/qti/common/src/aarch64/qti_kryo4_silver.S
@@ -22,19 +22,11 @@
mov x19, x30
bl qtiseclib_kryo4_silver_reset_asm
-
- ret x19
+ mov x30, x19
+ b cortex_a55_reset_func
endfunc qti_kryo4_silver_reset_func
-/* ------------------------------------------------------
- * The CPU Ops core power down function for Kryo-3 Silver
- * ------------------------------------------------------
- */
-func qti_kryo4_silver_core_pwr_dwn
- ret
-endfunc qti_kryo4_silver_core_pwr_dwn
-
/* ---------------------------------------------------------
* The CPU Ops cluster power down function for Kryo-3 Silver
* ---------------------------------------------------------
@@ -75,5 +67,5 @@
declare_cpu_ops qti_kryo4_silver, QTI_KRYO4_SILVER_MIDR, \
qti_kryo4_silver_reset_func, \
- qti_kryo4_silver_core_pwr_dwn, \
+ cortex_a55_core_pwr_dwn, \
qti_kryo4_silver_cluster_pwr_dwn
diff --git a/plat/qti/common/src/aarch64/qti_kryo6_gold.S b/plat/qti/common/src/aarch64/qti_kryo6_gold.S
index db1a304..577e7ff 100644
--- a/plat/qti/common/src/aarch64/qti_kryo6_gold.S
+++ b/plat/qti/common/src/aarch64/qti_kryo6_gold.S
@@ -28,19 +28,11 @@
mov x19, x30
bl qtiseclib_kryo6_gold_reset_asm
-
- ret x19
+ mov x30, x19
+ b cortex_a78_reset_func
endfunc qti_kryo6_gold_reset_func
-/* ----------------------------------------------------
- * The CPU Ops core power down function for Kryo-3 Gold
- * ----------------------------------------------------
- */
-func qti_kryo6_gold_core_pwr_dwn
- ret
-endfunc qti_kryo6_gold_core_pwr_dwn
-
/* -------------------------------------------------------
* The CPU Ops cluster power down function for Kryo-3 Gold
* -------------------------------------------------------
@@ -79,5 +71,5 @@
declare_cpu_ops qti_kryo6_gold, QTI_KRYO6_GOLD_MIDR, \
qti_kryo6_gold_reset_func, \
- qti_kryo6_gold_core_pwr_dwn, \
+ cortex_a78_core_pwr_dwn, \
qti_kryo6_gold_cluster_pwr_dwn
diff --git a/plat/qti/common/src/aarch64/qti_kryo6_silver.S b/plat/qti/common/src/aarch64/qti_kryo6_silver.S
index 2d189f2..6ad0bca 100644
--- a/plat/qti/common/src/aarch64/qti_kryo6_silver.S
+++ b/plat/qti/common/src/aarch64/qti_kryo6_silver.S
@@ -22,19 +22,11 @@
mov x19, x30
bl qtiseclib_kryo6_silver_reset_asm
-
- ret x19
+ mov x30, x19
+ b cortex_a55_reset_func
endfunc qti_kryo6_silver_reset_func
-/* ------------------------------------------------------
- * The CPU Ops core power down function for Kryo-3 Silver
- * ------------------------------------------------------
- */
-func qti_kryo6_silver_core_pwr_dwn
- ret
-endfunc qti_kryo6_silver_core_pwr_dwn
-
/* ---------------------------------------------------------
* The CPU Ops cluster power down function for Kryo-3 Silver
* ---------------------------------------------------------
@@ -75,5 +67,5 @@
declare_cpu_ops qti_kryo6_silver, QTI_KRYO6_SILVER_MIDR, \
qti_kryo6_silver_reset_func, \
- qti_kryo6_silver_core_pwr_dwn, \
+ cortex_a55_core_pwr_dwn, \
qti_kryo6_silver_cluster_pwr_dwn
diff --git a/plat/qti/common/src/qti_bl31_setup.c b/plat/qti/common/src/qti_bl31_setup.c
index b2bc543..dac0253 100644
--- a/plat/qti/common/src/qti_bl31_setup.c
+++ b/plat/qti/common/src/qti_bl31_setup.c
@@ -36,16 +36,10 @@
static uint64_t g_qti_cpu_cntfrq;
/*
- * Lock variable to serialize cpuss reset execution.
- */
-spinlock_t g_qti_cpuss_boot_lock __attribute__ ((section("tzfw_coherent_mem"),
- aligned(CACHE_WRITEBACK_GRANULE))) = {0x0};
-
-/*
* Variable to hold bl31 cold boot status. Default value 0x0 means yet to boot.
* Any other value means cold booted.
*/
-uint32_t g_qti_bl31_cold_booted __attribute__ ((section("tzfw_coherent_mem"))) = 0x0;
+uint32_t g_qti_bl31_cold_booted;
/*******************************************************************************
* Perform any BL31 early platform setup common to ARM standard platforms.
@@ -91,13 +85,14 @@
******************************************************************************/
void bl31_plat_arch_setup(void)
{
- qti_setup_page_tables(BL_CODE_BASE,
- BL_COHERENT_RAM_END - BL_CODE_BASE,
+ qti_setup_page_tables(
+ BL31_START,
+ BL31_END-BL31_START,
BL_CODE_BASE,
BL_CODE_END,
BL_RO_DATA_BASE,
- BL_RO_DATA_END,
- BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
+ BL_RO_DATA_END
+ );
enable_mmu_el3(0);
}
diff --git a/plat/qti/common/src/qti_common.c b/plat/qti/common/src/qti_common.c
index da0eaec..8821731 100644
--- a/plat/qti/common/src/qti_common.c
+++ b/plat/qti/common/src/qti_common.c
@@ -77,13 +77,14 @@
* - Read-only data section;
* - Coherent memory region, if applicable.
*/
-void qti_setup_page_tables(uintptr_t total_base,
+void qti_setup_page_tables(
+ uintptr_t total_base,
size_t total_size,
uintptr_t code_start,
uintptr_t code_limit,
uintptr_t rodata_start,
- uintptr_t rodata_limit,
- uintptr_t coh_start, uintptr_t coh_limit)
+ uintptr_t rodata_limit
+ )
{
/*
* Map the Trusted SRAM with appropriate memory attributes.
@@ -106,12 +107,6 @@
mmap_add_region(rodata_start, rodata_start,
rodata_limit - rodata_start, MT_RO_DATA | MT_SECURE);
- /* Re-map the coherent memory region */
- VERBOSE("Coherent region: %p - %p\n",
- (void *)coh_start, (void *)coh_limit);
- mmap_add_region(coh_start, coh_start,
- coh_limit - coh_start, MT_DEVICE | MT_RW | MT_SECURE);
-
/* Now (re-)map the platform-specific memory regions */
mmap_add(plat_qti_mmap);
diff --git a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
index 9c93d51..cdaa0a7 100644
--- a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
+++ b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
@@ -50,6 +50,21 @@
}
/*
+ * Execute CPU (Kryo4 gold) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo6_gold_reset_asm(void)
+{
+}
+
+
+void qtiseclib_kryo6_silver_reset_asm(void)
+{
+}
+
+/*
* C Api's
*/
void qtiseclib_bl31_platform_setup(void)
diff --git a/plat/qti/sc7180/platform.mk b/plat/qti/sc7180/platform.mk
index 141e2c3..41a08ca 100644
--- a/plat/qti/sc7180/platform.mk
+++ b/plat/qti/sc7180/platform.mk
@@ -12,12 +12,17 @@
# Turn On Separate code & data.
SEPARATE_CODE_AND_RODATA := 1
-USE_COHERENT_MEM := 1
+USE_COHERENT_MEM := 0
WARMBOOT_ENABLE_DCACHE_EARLY := 1
+HW_ASSISTED_COHERENCY := 1
# Disable the PSCI platform compatibility layer
ENABLE_PLAT_COMPAT := 0
+#Enable errata for cortex_a55 and cortex_a76
+ERRATA_A55_1530923 := 1
+ERRATA_A76_1165522 := 1
+
# Enable PSCI v1.0 extended state ID format
PSCI_EXTENDED_STATE_ID := 1
ARM_RECOM_STATE_ID_ENC := 1
@@ -93,10 +98,14 @@
GIC_SOURCES := plat/common/plat_gicv3.c \
${GICV3_SOURCES} \
-BL31_SOURCES += ${QTI_BL31_SOURCES} \
- ${PSCI_SOURCES} \
- ${GIC_SOURCES} \
- ${TIMER_SOURCES} \
+CPU_SOURCES := lib/cpus/aarch64/cortex_a76.S \
+ lib/cpus/aarch64/cortex_a55.S \
+
+BL31_SOURCES += ${QTI_BL31_SOURCES} \
+ ${PSCI_SOURCES} \
+ ${GIC_SOURCES} \
+ ${TIMER_SOURCES} \
+ ${CPU_SOURCES} \
LIB_QTI_PATH := ${QTI_PLAT_PATH}/qtiseclib/lib/${CHIPSET}
diff --git a/plat/qti/sc7280/platform.mk b/plat/qti/sc7280/platform.mk
index bc2c221..df07bc4 100644
--- a/plat/qti/sc7280/platform.mk
+++ b/plat/qti/sc7280/platform.mk
@@ -12,8 +12,15 @@
# Turn On Separate code & data.
SEPARATE_CODE_AND_RODATA := 1
-USE_COHERENT_MEM := 1
+USE_COHERENT_MEM := 0
WARMBOOT_ENABLE_DCACHE_EARLY := 1
+HW_ASSISTED_COHERENCY := 1
+
+#Enable errata configs for cortex_a78 and cortex_a55
+ERRATA_A55_1530923 := 1
+ERRATA_A78_1941498 := 1
+ERRATA_A78_1951500 := 1
+ERRATA_A78_2132060 := 1
# Disable the PSCI platform compatibility layer
ENABLE_PLAT_COMPAT := 0
@@ -93,10 +100,14 @@
GIC_SOURCES := plat/common/plat_gicv3.c \
${GICV3_SOURCES} \
-BL31_SOURCES += ${QTI_BL31_SOURCES} \
- ${PSCI_SOURCES} \
- ${GIC_SOURCES} \
- ${TIMER_SOURCES} \
+CPU_SOURCES := lib/cpus/aarch64/cortex_a78.S \
+ lib/cpus/aarch64/cortex_a55.S \
+
+BL31_SOURCES += ${QTI_BL31_SOURCES} \
+ ${PSCI_SOURCES} \
+ ${GIC_SOURCES} \
+ ${TIMER_SOURCES} \
+ ${CPU_SOURCES} \
LIB_QTI_PATH := ${QTI_PLAT_PATH}/qtiseclib/lib/${CHIPSET}
diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk
index aef0ad1..26a5798 100644
--- a/plat/renesas/common/common.mk
+++ b/plat/renesas/common/common.mk
@@ -140,5 +140,4 @@
drivers/arm/cci/cci.c
include lib/xlat_tables_v2/xlat_tables.mk
-include drivers/auth/mbedtls/mbedtls_crypto.mk
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index 6c23923..53c97e2 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -212,10 +212,10 @@
$(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
- $(Q)openssl genrsa 2048 > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
$(ROTPK_HASH): $(ROT_KEY)
@echo " OPENSSL $@"
- $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
- openssl dgst -sha256 -binary > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
endif
diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h
index 49ffbf9..a84660b 100644
--- a/plat/socionext/synquacer/include/platform_def.h
+++ b/plat/socionext/synquacer/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -42,16 +42,52 @@
#define MAX_XLAT_TABLES 8
#define MAX_MMAP_REGIONS 8
+#if TRUSTED_BOARD_BOOT
+#define PLATFORM_STACK_SIZE 0x1000
+#else
#define PLATFORM_STACK_SIZE 0x400
+#endif
+
+#if !RESET_TO_BL31
+
+/* A mailbox page will be mapped from BL2 and BL31 */
+#define BL2_MAILBOX_BASE 0x0403f000
+#define BL2_MAILBOX_SIZE 0x1000
+
+#define PLAT_SQ_BOOTIDX_BASE 0x08510000
+#define PLAT_SQ_MAX_BOOT_INDEX 2
+
+#define MAX_IO_HANDLES 2
+#define MAX_IO_DEVICES 2
+#define MAX_IO_BLOCK_DEVICES U(1)
+
+#define BL2_BASE 0x04000000
+#define BL2_SIZE (256 * 1024)
+#define BL2_LIMIT (BL2_BASE + BL2_SIZE)
+
+/* If BL2 is enabled, the BL31 is loaded on secure DRAM */
+#define BL31_BASE 0xfbe00000
+#define BL31_SIZE 0x00100000
+#else
#define BL31_BASE 0x04000000
#define BL31_SIZE 0x00080000
+#endif
+
#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
#define BL32_BASE 0xfc000000
#define BL32_SIZE 0x03c00000
#define BL32_LIMIT (BL32_BASE + BL32_SIZE)
+/* Alternative BL33 */
+#define PLAT_SQ_BL33_BASE 0xe0000000
+#define PLAT_SQ_BL33_SIZE 0x00100000
+
+/* FWU FIP IO base */
+#define PLAT_SQ_FIP_IOBASE 0x08600000
+#define PLAT_SQ_FIP_MAXSIZE 0x00400000
+
#define PLAT_SQ_CCN_BASE 0x32000000
#define PLAT_SQ_CLUSTER_TO_CCN_ID_MAP \
0, /* Cluster 0 */ \
diff --git a/plat/socionext/synquacer/include/sq_common.h b/plat/socionext/synquacer/include/sq_common.h
index b09d22a..eef0e1f 100644
--- a/plat/socionext/synquacer/include/sq_common.h
+++ b/plat/socionext/synquacer/include/sq_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -39,6 +39,8 @@
void sq_gic_cpuif_disable(void);
void sq_gic_pcpu_init(void);
+int sq_io_setup(void);
+struct image_info *sq_get_image_info(unsigned int image_id);
void sq_mmap_setup(uintptr_t total_base, size_t total_size,
const struct mmap_region *mmap);
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index dcd5d31..b76ae88 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -1,18 +1,26 @@
#
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
-override RESET_TO_BL31 := 1
override PROGRAMMABLE_RESET_ADDRESS := 1
override USE_COHERENT_MEM := 1
override SEPARATE_CODE_AND_RODATA := 1
override ENABLE_SVE_FOR_NS := 0
# Enable workarounds for selected Cortex-A53 erratas.
ERRATA_A53_855873 := 1
-# Enable SCMI support
-SQ_USE_SCMI_DRIVER ?= 0
+
+ifeq (${RESET_TO_BL31}, 1)
+override RESET_TO_BL31 := 1
+override TRUSTED_BOARD_BOOT := 0
+SQ_USE_SCMI_DRIVER ?= 0
+else
+override RESET_TO_BL31 := 0
+override BL2_AT_EL3 := 1
+SQ_USE_SCMI_DRIVER := 1
+BL2_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
+endif
# Libraries
include lib/xlat_tables_v2/xlat_tables.mk
@@ -28,14 +36,55 @@
drivers/arm/pl011/aarch64/pl011_console.S \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ lib/cpus/aarch64/cortex_a53.S \
+ $(PLAT_PATH)/sq_xlat_setup.c \
${XLAT_TABLES_LIB_SRCS}
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
+ifneq (${RESET_TO_BL31}, 1)
+BL2_SOURCES += common/desc_image_load.c \
+ drivers/io/io_fip.c \
+ drivers/io/io_memmap.c \
+ drivers/io/io_storage.c \
+ $(PLAT_PATH)/sq_bl2_setup.c \
+ $(PLAT_PATH)/sq_image_desc.c \
+ $(PLAT_PATH)/sq_io_storage.c
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+include drivers/auth/mbedtls/mbedtls_x509.mk
+BL2_SOURCES += drivers/auth/auth_mod.c \
+ drivers/auth/crypto_mod.c \
+ drivers/auth/img_parser_mod.c \
+ drivers/auth/tbbr/tbbr_cot_common.c \
+ drivers/auth/tbbr/tbbr_cot_bl2.c \
+ plat/common/tbbr/plat_tbbr.c \
+ $(PLAT_PATH)/sq_rotpk.S \
+ $(PLAT_PATH)/sq_tbbr.c
+
+ROT_KEY = $(BUILD_PLAT)/rot_key.pem
+ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
+
+$(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl2/sq_rotpk.o: $(ROTPK_HASH)
+
+certificates: $(ROT_KEY)
+$(ROT_KEY): | $(BUILD_PLAT)
+ @echo " OPENSSL $@"
+ $(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+
+$(ROTPK_HASH): $(ROT_KEY)
+ @echo " OPENSSL $@"
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
+
+endif # TRUSTED_BOARD_BOOT
+endif
+
BL31_SOURCES += drivers/arm/ccn/ccn.c \
${GICV3_SOURCES} \
- lib/cpus/aarch64/cortex_a53.S \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
$(PLAT_PATH)/sq_bl31_setup.c \
@@ -43,7 +92,6 @@
$(PLAT_PATH)/sq_topology.c \
$(PLAT_PATH)/sq_psci.c \
$(PLAT_PATH)/sq_gicv3.c \
- $(PLAT_PATH)/sq_xlat_setup.c \
$(PLAT_PATH)/drivers/scp/sq_scp.c
ifeq (${SQ_USE_SCMI_DRIVER},0)
diff --git a/plat/socionext/synquacer/sq_bl2_setup.c b/plat/socionext/synquacer/sq_bl2_setup.c
new file mode 100644
index 0000000..a98d912
--- /dev/null
+++ b/plat/socionext/synquacer/sq_bl2_setup.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2022, Socionext Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <common/image_decompress.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/io/io_storage.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+#include <sq_common.h>
+
+static console_t console;
+
+void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
+ u_register_t x2, u_register_t x3)
+{
+ /* Initialize the console to provide early debug support */
+ (void)console_pl011_register(PLAT_SQ_BOOT_UART_BASE,
+ PLAT_SQ_BOOT_UART_CLK_IN_HZ,
+ SQ_CONSOLE_BAUDRATE, &console);
+ console_set_scope(&console, CONSOLE_FLAG_BOOT);
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+ int ret;
+
+ sq_mmap_setup(BL2_BASE, BL2_SIZE, NULL);
+
+ ret = sq_io_setup();
+ if (ret) {
+ ERROR("failed to setup io devices\n");
+ plat_error_handler(ret);
+ }
+}
+
+void bl2_platform_setup(void)
+{
+}
+
+void plat_flush_next_bl_params(void)
+{
+ flush_bl_params_desc();
+}
+
+bl_load_info_t *plat_get_bl_image_load_info(void)
+{
+ return get_bl_load_info_from_mem_params_desc();
+}
+
+bl_params_t *plat_get_next_bl_params(void)
+{
+ return get_next_bl_params_from_mem_params_desc();
+}
+
+void bl2_plat_preload_setup(void)
+{
+}
+
+int bl2_plat_handle_pre_image_load(unsigned int image_id)
+{
+ struct image_info *image_info;
+
+ image_info = sq_get_image_info(image_id);
+
+ return mmap_add_dynamic_region(image_info->image_base,
+ image_info->image_base,
+ image_info->image_max_size,
+ MT_MEMORY | MT_RW | MT_NS);
+}
+
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ return 0;
+}
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index a7a0ce0..967437b 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -44,6 +44,35 @@
return type == NON_SECURE ? &bl33_image_ep_info : &bl32_image_ep_info;
}
+#if !RESET_TO_BL31
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ void *from_bl2 = (void *) arg0;
+ bl_params_node_t *bl_params = ((bl_params_t *) from_bl2)->head;
+
+ /* Initialize the console to provide early debug support */
+ (void)console_pl011_register(PLAT_SQ_BOOT_UART_BASE,
+ PLAT_SQ_BOOT_UART_CLK_IN_HZ,
+ SQ_CONSOLE_BAUDRATE, &console);
+
+ console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+
+ /* Initialize power controller before setting up topology */
+ plat_sq_pwrc_setup();
+
+ while (bl_params) {
+ if (bl_params->image_id == BL32_IMAGE_ID)
+ bl32_image_ep_info = *bl_params->ep_info;
+
+ if (bl_params->image_id == BL33_IMAGE_ID)
+ bl33_image_ep_info = *bl_params->ep_info;
+
+ bl_params = bl_params->next_params_info;
+ }
+}
+
+#else
/*******************************************************************************
* Gets SPSR for BL32 entry
******************************************************************************/
@@ -129,6 +158,7 @@
bl33_image_ep_info.spsr = sq_get_spsr_for_bl33_entry();
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
}
+#endif
static void sq_configure_sys_timer(void)
{
@@ -192,6 +222,11 @@
PLAT_SQ_SP_PRIV_SIZE,
MT_RW_DATA | MT_SECURE),
#endif
+#if !RESET_TO_BL31
+ MAP_REGION_FLAT(BL2_MAILBOX_BASE,
+ BL2_MAILBOX_SIZE,
+ MT_RW | MT_SECURE),
+#endif
{0},
};
diff --git a/plat/socionext/synquacer/sq_helpers.S b/plat/socionext/synquacer/sq_helpers.S
index 7a2d97b..5f9eab4 100644
--- a/plat/socionext/synquacer/sq_helpers.S
+++ b/plat/socionext/synquacer/sq_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -46,7 +46,12 @@
* code that secondary CPUs jump to.
*/
func plat_secondary_cold_boot_setup
+#if !RESET_TO_BL31
+ mov_imm x0, BL2_MAILBOX_BASE
+ ldr x0, [x0]
+#else
ldr x0, sq_sec_entrypoint
+#endif
/* Wait until the mailbox gets populated */
poll_mailbox:
diff --git a/plat/socionext/synquacer/sq_image_desc.c b/plat/socionext/synquacer/sq_image_desc.c
new file mode 100644
index 0000000..5fe125b
--- /dev/null
+++ b/plat/socionext/synquacer/sq_image_desc.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2022, Socionext Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <common/desc_image_load.h>
+
+#include <platform_def.h>
+
+static struct bl_mem_params_node sq_image_descs[] = {
+ {
+ .image_id = BL31_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = BL31_SIZE,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
+
+ .next_handoff_image_id = BL32_IMAGE_ID,
+ },
+ {
+ .image_id = BL32_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_SIZE,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE),
+ .ep_info.pc = BL32_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
+
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
+ {
+ .image_id = BL33_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = PLAT_SQ_BL33_BASE,
+ .image_info.image_max_size = PLAT_SQ_BL33_SIZE,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ NON_SECURE | EXECUTABLE),
+ .ep_info.pc = PLAT_SQ_BL33_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+};
+REGISTER_BL_IMAGE_DESCS(sq_image_descs)
+
+struct image_info *sq_get_image_info(unsigned int image_id)
+{
+ struct bl_mem_params_node *desc;
+
+ desc = get_bl_mem_params_node(image_id);
+ assert(desc);
+ return &desc->image_info;
+}
diff --git a/plat/socionext/synquacer/sq_io_storage.c b/plat/socionext/synquacer/sq_io_storage.c
new file mode 100644
index 0000000..ea83dad
--- /dev/null
+++ b/plat/socionext/synquacer/sq_io_storage.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2022, Socionext Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <drivers/io/io_block.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_fip.h>
+#include <drivers/io/io_memmap.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <platform_def.h>
+#include <sq_common.h>
+
+static const io_dev_connector_t *sq_fip_dev_con;
+static uintptr_t sq_fip_dev_handle;
+
+static const io_dev_connector_t *sq_backend_dev_con;
+static uintptr_t sq_backend_dev_handle;
+
+static io_block_spec_t sq_fip_spec = {
+ .offset = PLAT_SQ_FIP_IOBASE, /* FIP Image is at 5MB offset on memory-mapped NOR flash */
+ .length = PLAT_SQ_FIP_MAXSIZE, /* Expected maximum FIP image size */
+};
+
+static const io_uuid_spec_t sq_bl2_spec = {
+ .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+};
+
+static const io_uuid_spec_t sq_bl31_spec = {
+ .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+};
+
+static const io_uuid_spec_t sq_bl32_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32,
+};
+
+static const io_uuid_spec_t sq_bl33_spec = {
+ .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+};
+
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t sq_tb_fw_cert_spec = {
+ .uuid = UUID_TRUSTED_BOOT_FW_CERT,
+};
+
+static const io_uuid_spec_t sq_trusted_key_cert_spec = {
+ .uuid = UUID_TRUSTED_KEY_CERT,
+};
+
+static const io_uuid_spec_t sq_soc_fw_key_cert_spec = {
+ .uuid = UUID_SOC_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t sq_tos_fw_key_cert_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t sq_nt_fw_key_cert_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t sq_soc_fw_cert_spec = {
+ .uuid = UUID_SOC_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t sq_tos_fw_cert_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t sq_nt_fw_cert_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
+struct sq_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ uintptr_t init_params;
+};
+
+static const struct sq_io_policy sq_io_policies[] = {
+ [FIP_IMAGE_ID] = {
+ .dev_handle = &sq_backend_dev_handle,
+ .image_spec = (uintptr_t)&sq_fip_spec,
+ },
+ [BL2_IMAGE_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_bl2_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+ [BL31_IMAGE_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_bl31_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+ [BL32_IMAGE_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_bl32_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+ [BL33_IMAGE_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_bl33_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_tb_fw_cert_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+ [TRUSTED_KEY_CERT_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_trusted_key_cert_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+ [SOC_FW_KEY_CERT_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_soc_fw_key_cert_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+ [TRUSTED_OS_FW_KEY_CERT_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_tos_fw_key_cert_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+ [NON_TRUSTED_FW_KEY_CERT_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_nt_fw_key_cert_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+ [SOC_FW_CONTENT_CERT_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_soc_fw_cert_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+ [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_tos_fw_cert_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+ .dev_handle = &sq_fip_dev_handle,
+ .image_spec = (uintptr_t)&sq_nt_fw_cert_spec,
+ .init_params = FIP_IMAGE_ID,
+ },
+#endif
+};
+
+static int sq_update_fip_spec(void)
+{
+ uint32_t boot_index;
+ int ret;
+
+ ret = mmap_add_dynamic_region(PLAT_SQ_BOOTIDX_BASE, PLAT_SQ_BOOTIDX_BASE,
+ PAGE_SIZE, MT_RO_DATA | MT_SECURE);
+ if (ret) {
+ return ret;
+ }
+
+ boot_index = mmio_read_32(PLAT_SQ_BOOTIDX_BASE);
+ if (boot_index < PLAT_SQ_MAX_BOOT_INDEX) {
+ sq_fip_spec.offset += PLAT_SQ_FIP_MAXSIZE * boot_index;
+ INFO("FWU Enabled: boot_index %d\n", boot_index);
+ } else {
+ WARN("FWU Disabled: wrong boot_index value. Fallback to index 0.\n");
+ }
+
+ mmap_remove_dynamic_region(PLAT_SQ_BOOTIDX_BASE, PAGE_SIZE);
+ return 0;
+}
+
+static int sq_io_memmap_setup(void)
+{
+ int ret;
+
+ ret = sq_update_fip_spec();
+ if (ret) {
+ return ret;
+ }
+
+ ret = mmap_add_dynamic_region(sq_fip_spec.offset, sq_fip_spec.offset,
+ sq_fip_spec.length, MT_RO_DATA | MT_SECURE);
+ if (ret) {
+ return ret;
+ }
+
+ ret = register_io_dev_memmap(&sq_backend_dev_con);
+ if (ret) {
+ return ret;
+ }
+
+ return io_dev_open(sq_backend_dev_con, 0, &sq_backend_dev_handle);
+}
+
+static int sq_io_fip_setup(void)
+{
+ int ret;
+
+ ret = register_io_dev_fip(&sq_fip_dev_con);
+ if (ret) {
+ return ret;
+ }
+
+ return io_dev_open(sq_fip_dev_con, 0, &sq_fip_dev_handle);
+}
+
+int sq_io_setup(void)
+{
+ int ret;
+
+ ret = sq_io_memmap_setup();
+ if (ret) {
+ return ret;
+ }
+
+ ret = sq_io_fip_setup();
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec)
+{
+ uintptr_t init_params;
+
+ assert(image_id < ARRAY_SIZE(sq_io_policies));
+
+ *dev_handle = *sq_io_policies[image_id].dev_handle;
+ *image_spec = sq_io_policies[image_id].image_spec;
+ init_params = sq_io_policies[image_id].init_params;
+
+ return io_dev_init(*dev_handle, init_params);
+}
diff --git a/plat/socionext/synquacer/sq_psci.c b/plat/socionext/synquacer/sq_psci.c
index 3062f63..017516f 100644
--- a/plat/socionext/synquacer/sq_psci.c
+++ b/plat/socionext/synquacer/sq_psci.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -197,9 +197,17 @@
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const struct plat_psci_ops **psci_ops)
{
+#if !RESET_TO_BL31
+ uintptr_t *sq_sec_ep = (uintptr_t *)BL2_MAILBOX_BASE;
+
+ *sq_sec_ep = sec_entrypoint;
+ flush_dcache_range((uint64_t)sq_sec_ep,
+ sizeof(*sq_sec_ep));
+#else
sq_sec_entrypoint = sec_entrypoint;
flush_dcache_range((uint64_t)&sq_sec_entrypoint,
sizeof(sq_sec_entrypoint));
+#endif
*psci_ops = &sq_psci_ops;
diff --git a/plat/socionext/synquacer/sq_rotpk.S b/plat/socionext/synquacer/sq_rotpk.S
new file mode 100644
index 0000000..61227ed
--- /dev/null
+++ b/plat/socionext/synquacer/sq_rotpk.S
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2022, Socionext Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .global sq_rotpk_hash
+ .global sq_rotpk_hash_end
+ .section .rodata.sq_rotpk_hash, "a"
+sq_rotpk_hash:
+ /* DER header */
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ /* SHA256 */
+ .incbin ROTPK_HASH
+sq_rotpk_hash_end:
diff --git a/plat/socionext/synquacer/sq_tbbr.c b/plat/socionext/synquacer/sq_tbbr.c
new file mode 100644
index 0000000..e9fa18c
--- /dev/null
+++ b/plat/socionext/synquacer/sq_tbbr.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022, Socionext Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+extern char sq_rotpk_hash[], sq_rotpk_hash_end[];
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ *key_ptr = sq_rotpk_hash;
+ *key_len = sq_rotpk_hash_end - sq_rotpk_hash;
+ *flags = ROTPK_IS_HASH;
+
+ return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ /*
+ * No support for non-volatile counter. Update the ROT key to protect
+ * the system against rollback.
+ */
+ *nv_ctr = 0;
+
+ return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ return 0;
+}
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index 6edd181..378497a 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -107,12 +107,12 @@
certificates: $(ROT_KEY)
$(ROT_KEY): | $(BUILD_PLAT)
@echo " OPENSSL $@"
- $(Q)openssl genrsa 2048 > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
$(ROTPK_HASH): $(ROT_KEY)
@echo " OPENSSL $@"
- $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
- openssl dgst -sha256 -binary > $@ 2>/dev/null
+ $(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
endif
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index e129dfd..7222584 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -37,7 +37,9 @@
#include <platform_def.h>
#include <stm32cubeprogrammer.h>
+#include <stm32mp_efi.h>
#include <stm32mp_fconf_getter.h>
+#include <stm32mp_io_storage.h>
#include <usb_dfu.h>
/* IO devices */
@@ -121,6 +123,37 @@
return io_dev_init(storage_dev_handle, 0);
}
+#if STM32MP_EMMC_BOOT
+static uint32_t get_boot_part_fip_header(void)
+{
+ io_block_spec_t emmc_boot_fip_block_spec = {
+ .offset = STM32MP_EMMC_BOOT_FIP_OFFSET,
+ .length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */
+ };
+ uint32_t magic = 0U;
+ int io_result;
+ size_t bytes_read;
+ uintptr_t fip_hdr_handle;
+
+ io_result = io_open(storage_dev_handle, (uintptr_t)&emmc_boot_fip_block_spec,
+ &fip_hdr_handle);
+ assert(io_result == 0);
+
+ io_result = io_read(fip_hdr_handle, (uintptr_t)&magic, sizeof(magic),
+ &bytes_read);
+ if ((io_result != 0) || (bytes_read != sizeof(magic))) {
+ panic();
+ }
+
+ io_close(fip_hdr_handle);
+
+ VERBOSE("%s: eMMC boot magic at offset 256K: %08x\n",
+ __func__, magic);
+
+ return magic;
+}
+#endif
+
static void print_boot_device(boot_api_context_t *boot_context)
{
switch (boot_context->boot_interface_selected) {
@@ -188,13 +221,17 @@
break;
}
+ if (mmc_dev_type != MMC_IS_EMMC) {
+ params.flags = MMC_FLAG_SD_CMD6;
+ }
+
params.device_info = &mmc_info;
if (stm32_sdmmc2_mmc_init(¶ms) != 0) {
ERROR("SDMMC%u init failed\n", boot_interface_instance);
panic();
}
- /* Open MMC as a block device to read GPT table */
+ /* Open MMC as a block device to read FIP */
io_result = register_io_dev_block(&mmc_dev_con);
if (io_result != 0) {
panic();
@@ -203,6 +240,26 @@
io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec,
&storage_dev_handle);
assert(io_result == 0);
+
+#if STM32MP_EMMC_BOOT
+ if (mmc_dev_type == MMC_IS_EMMC) {
+ io_result = mmc_part_switch_current_boot();
+ assert(io_result == 0);
+
+ if (get_boot_part_fip_header() != TOC_HEADER_NAME) {
+ WARN("%s: Can't find FIP header on eMMC boot partition. Trying GPT\n",
+ __func__);
+ io_result = mmc_part_switch_user();
+ assert(io_result == 0);
+ return;
+ }
+
+ VERBOSE("%s: FIP header found on eMMC boot partition\n",
+ __func__);
+ image_block_spec.offset = STM32MP_EMMC_BOOT_FIP_OFFSET;
+ image_block_spec.length = mmc_boot_part_size() - STM32MP_EMMC_BOOT_FIP_OFFSET;
+ }
+#endif
}
#endif /* STM32MP_SDMMC || STM32MP_EMMC */
@@ -384,8 +441,14 @@
switch (boot_itf) {
#if STM32MP_SDMMC || STM32MP_EMMC
- case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
+#if STM32MP_EMMC_BOOT
+ if (image_block_spec.offset == STM32MP_EMMC_BOOT_FIP_OFFSET) {
+ break;
+ }
+#endif
+ /* fallthrough */
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
if (!gpt_init_done) {
/*
* With FWU Multi Bank feature enabled, the selection of
@@ -394,13 +457,20 @@
*/
#if !PSA_FWU_SUPPORT
const partition_entry_t *entry;
+ const struct efi_guid img_type_guid = STM32MP_FIP_GUID;
+ uuid_t img_type_uuid;
+ guidcpy(&img_type_uuid, &img_type_guid);
partition_init(GPT_IMAGE_ID);
- entry = get_partition_entry(FIP_IMAGE_NAME);
+ entry = get_partition_entry_by_type(&img_type_uuid);
if (entry == NULL) {
- ERROR("Could NOT find the %s partition!\n",
- FIP_IMAGE_NAME);
- return -ENOENT;
+ entry = get_partition_entry(FIP_IMAGE_NAME);
+ if (entry == NULL) {
+ ERROR("Could NOT find the %s partition!\n",
+ FIP_IMAGE_NAME);
+
+ return -ENOENT;
+ }
}
image_block_spec.offset = entry->start;
@@ -409,6 +479,7 @@
gpt_init_done = true;
} else {
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+ assert(bl_mem_params != NULL);
mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base;
mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size;
@@ -485,22 +556,46 @@
#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
/*
- * Eventually, this function will return the
- * boot index to be passed on to the Update
- * Agent after performing certain checks like
- * a watchdog timeout, or Auth failure while
- * trying to load from a certain bank.
- * For now, since we do not have that logic
- * implemented, just pass the active_index
- * read from the metadata.
+ * In each boot in non-trial mode, we set the BKP register to
+ * FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata.
+ *
+ * As long as the update agent didn't update the "accepted" field in metadata
+ * (i.e. we are in trial mode), we select the new active_index.
+ * To avoid infinite boot loop at trial boot we decrement a BKP register.
+ * If this counter is 0:
+ * - an unexpected TAMPER event raised (that resets the BKP registers to 0)
+ * - a power-off occurs before the update agent was able to update the
+ * "accepted' field
+ * - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode.
+ * we select the previous_active_index.
*/
+#define INVALID_BOOT_IDX 0xFFFFFFFF
+
uint32_t plat_fwu_get_boot_idx(void)
{
- const struct fwu_metadata *metadata;
+ /*
+ * Select boot index and update boot counter only once per boot
+ * even if this function is called several times.
+ */
+ static uint32_t boot_idx = INVALID_BOOT_IDX;
+ const struct fwu_metadata *data;
+
+ data = fwu_get_metadata();
- metadata = fwu_get_metadata();
+ if (boot_idx == INVALID_BOOT_IDX) {
+ boot_idx = data->active_index;
+ if (fwu_is_trial_run_state()) {
+ if (stm32_get_and_dec_fwu_trial_boot_cnt() == 0U) {
+ WARN("Trial FWU fails %u times\n",
+ FWU_MAX_TRIAL_REBOOT);
+ boot_idx = data->previous_active_index;
+ }
+ } else {
+ stm32_set_max_fwu_trial_boot_cnt();
+ }
+ }
- return metadata->active_index;
+ return boot_idx;
}
static void *stm32_get_image_spec(const uuid_t *img_type_uuid)
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index d8d1c13..79f81db 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -127,8 +127,13 @@
void stm32_save_boot_interface(uint32_t interface, uint32_t instance);
void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance);
+/* Functions to save and get boot authentication status and partition used */
+void stm32_save_boot_auth(uint32_t auth_status, uint32_t boot_partition);
+
#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
void stm32mp1_fwu_set_boot_idx(void);
+uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void);
+void stm32_set_max_fwu_trial_boot_cnt(void);
#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
#endif /* STM32MP_COMMON_H */
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index ea71571..c9efeb5 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.c
@@ -11,8 +11,6 @@
#include <common/fdt_wrappers.h>
#include <drivers/st/regulator.h>
#include <drivers/st/stm32_gpio.h>
-#include <drivers/st/stm32mp1_ddr.h>
-#include <drivers/st/stm32mp1_ram.h>
#include <libfdt.h>
#include <platform_def.h>
@@ -328,48 +326,32 @@
int dt_find_otp_name(const char *name, uint32_t *otp, uint32_t *otp_len)
{
int node;
- int index, len;
+ int len;
const fdt32_t *cuint;
if ((name == NULL) || (otp == NULL)) {
return -FDT_ERR_BADVALUE;
}
- node = fdt_node_offset_by_compatible(fdt, -1, DT_NVMEM_LAYOUT_COMPAT);
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_BSEC_COMPAT);
if (node < 0) {
return node;
}
- index = fdt_stringlist_search(fdt, node, "nvmem-cell-names", name);
- if (index < 0) {
- return index;
- }
-
- cuint = fdt_getprop(fdt, node, "nvmem-cells", &len);
- if (cuint == NULL) {
- return -FDT_ERR_NOTFOUND;
- }
-
- if ((index * (int)sizeof(uint32_t)) > len) {
- return -FDT_ERR_BADVALUE;
- }
-
- cuint += index;
-
- node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+ node = fdt_subnode_offset(fdt, node, name);
if (node < 0) {
- ERROR("Malformed nvmem_layout node: ignored\n");
+ ERROR("nvmem node %s not found\n", name);
return node;
}
cuint = fdt_getprop(fdt, node, "reg", &len);
if ((cuint == NULL) || (len != (2 * (int)sizeof(uint32_t)))) {
- ERROR("Malformed nvmem_layout node: ignored\n");
+ ERROR("Malformed nvmem node %s: ignored\n", name);
return -FDT_ERR_BADVALUE;
}
if (fdt32_to_cpu(*cuint) % sizeof(uint32_t)) {
- ERROR("Misaligned nvmem_layout element: ignored\n");
+ ERROR("Misaligned nvmem %s element: ignored\n", name);
return -FDT_ERR_BADVALUE;
}
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 33ad56f..5015f7d 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -47,7 +47,9 @@
};
#endif
+#if STM32MP15
static struct stm32mp_auth_ops stm32mp1_auth_ops;
+#endif
static void print_reset_reason(void)
{
@@ -82,6 +84,7 @@
return;
}
+#if STM32MP15
if ((rstsr & RCC_MP_RSTSCLRR_MCSYSRSTF) != 0U) {
if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
INFO(" System reset generated by MCU (MCSYSRST)\n");
@@ -90,6 +93,7 @@
}
return;
}
+#endif
if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
INFO(" System reset generated by MPU (MPSYSRST)\n");
@@ -116,10 +120,12 @@
return;
}
+#if STM32MP15
if ((rstsr & RCC_MP_RSTSCLRR_MPUP1RSTF) != 0U) {
INFO(" MPU Processor 1 Reset\n");
return;
}
+#endif
if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
INFO(" Pad Reset from NRST\n");
@@ -171,6 +177,7 @@
#endif /* STM32MP_USE_STM32IMAGE */
}
+#if STM32MP15
static void update_monotonic_counter(void)
{
uint32_t version;
@@ -204,6 +211,7 @@
version);
}
}
+#endif
void bl2_el3_plat_arch_setup(void)
{
@@ -271,8 +279,10 @@
mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST);
}
+#if STM32MP15
/* Disable MCKPROT */
mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT);
+#endif
/*
* Set minimum reset pulse duration to 31ms for discrete power
@@ -306,8 +316,10 @@
stm32_save_boot_interface(boot_context->boot_interface_selected,
boot_context->boot_interface_instance);
+ stm32_save_boot_auth(boot_context->auth_status,
+ boot_context->boot_partition_used_toboot);
-#if STM32MP_USB_PROGRAMMER
+#if STM32MP_USB_PROGRAMMER && STM32MP15
/* Deconfigure all UART RX pins configured by ROM code */
stm32mp1_deconfigure_uart_pins();
#endif
@@ -338,6 +350,10 @@
if (dt_pmic_status() > 0) {
initialize_pmic();
+ if (pmic_voltages_init() != 0) {
+ ERROR("PMIC voltages init failed\n");
+ panic();
+ }
print_pmic_info_and_debug();
}
@@ -359,6 +375,7 @@
}
}
+#if STM32MP15
if (stm32mp_is_auth_supported()) {
stm32mp1_auth_ops.check_key =
boot_context->bootrom_ecdsa_check_key;
@@ -367,12 +384,15 @@
stm32mp_init_auth(&stm32mp1_auth_ops);
}
+#endif
stm32mp1_arch_security_setup();
print_reset_reason();
+#if STM32MP15
update_monotonic_counter();
+#endif
stm32mp1_syscfg_enable_io_compensation_finish();
@@ -414,7 +434,8 @@
#if !STM32MP_USE_STM32IMAGE
case FW_CONFIG_ID:
/* Set global DTB info for fixed fw_config information */
- set_config_info(STM32MP_FW_CONFIG_BASE, STM32MP_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID);
+ set_config_info(STM32MP_FW_CONFIG_BASE, ~0UL, STM32MP_FW_CONFIG_MAX_SIZE,
+ FW_CONFIG_ID);
fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE);
idx = dyn_cfg_dtb_info_get_index(TOS_FW_CONFIG_ID);
@@ -444,16 +465,20 @@
/* In case of OPTEE, initialize address space with tos_fw addr */
pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ assert(pager_mem_params != NULL);
pager_mem_params->image_info.image_base = config_info->config_addr;
pager_mem_params->image_info.image_max_size =
config_info->config_max_size;
/* Init base and size for pager if exist */
paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
- paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
- (dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
- STM32MP_DDR_SHMEM_SIZE);
- paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE;
+ if (paged_mem_params != NULL) {
+ paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
+ (dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
+ STM32MP_DDR_SHMEM_SIZE);
+ paged_mem_params->image_info.image_max_size =
+ STM32MP_DDR_S_SIZE;
+ }
break;
case BL33_IMAGE_ID:
@@ -473,11 +498,17 @@
case BL32_IMAGE_ID:
if (optee_header_is_valid(bl_mem_params->image_info.image_base)) {
+ image_info_t *paged_image_info = NULL;
+
/* BL32 is OP-TEE header */
bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ assert(pager_mem_params != NULL);
+
paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
- assert((pager_mem_params != NULL) && (paged_mem_params != NULL));
+ if (paged_mem_params != NULL) {
+ paged_image_info = &paged_mem_params->image_info;
+ }
#if STM32MP_USE_STM32IMAGE && defined(AARCH32_SP_OPTEE)
/* Set OP-TEE extra image load areas at run-time */
@@ -493,20 +524,27 @@
err = parse_optee_header(&bl_mem_params->ep_info,
&pager_mem_params->image_info,
- &paged_mem_params->image_info);
- if (err) {
+ paged_image_info);
+ if (err != 0) {
ERROR("OPTEE header parse error.\n");
panic();
}
/* Set optee boot info from parsed header data */
- bl_mem_params->ep_info.args.arg0 = paged_mem_params->image_info.image_base;
- bl_mem_params->ep_info.args.arg1 = 0; /* Unused */
- bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */
+ if (paged_mem_params != NULL) {
+ bl_mem_params->ep_info.args.arg0 =
+ paged_mem_params->image_info.image_base;
+ } else {
+ bl_mem_params->ep_info.args.arg0 = 0U;
+ }
+
+ bl_mem_params->ep_info.args.arg1 = 0U; /* Unused */
+ bl_mem_params->ep_info.args.arg2 = 0U; /* No DT supported */
} else {
#if !STM32MP_USE_STM32IMAGE
bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
tos_fw_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
+ assert(tos_fw_mem_params != NULL);
bl_mem_params->image_info.image_max_size +=
tos_fw_mem_params->image_info.image_max_size;
#endif /* !STM32MP_USE_STM32IMAGE */
diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h
index 198ffa9..7638418 100644
--- a/plat/st/stm32mp1/include/boot_api.h
+++ b/plat/st/stm32mp1/include/boot_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,12 +13,22 @@
/*
* Possible value of boot context field 'auth_status'
*/
+#if STM32MP13
+ /* No authentication done */
+#define BOOT_API_CTX_AUTH_NO 0x7CFDD351U
+ /* Authentication done and failed */
+#define BOOT_API_CTX_AUTH_FAILED 0x51330884U
+ /* Authentication done and success */
+#define BOOT_API_CTX_AUTH_SUCCESS 0x67E8CAE1U
+#endif
+#if STM32MP15
/* No authentication done */
#define BOOT_API_CTX_AUTH_NO 0x0U
/* Authentication done and failed */
#define BOOT_API_CTX_AUTH_FAILED 0x1U
/* Authentication done and succeeded */
#define BOOT_API_CTX_AUTH_SUCCESS 0x2U
+#endif
/*
* Possible value of boot context field 'boot_interface_sel'
@@ -70,11 +80,17 @@
#define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_NOT_FOUND 0x5U
#define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_SIZE_ZERO 0x6U
#define BOOT_API_CTX_EMMC_ERROR_STATUS_IMAGE_NOT_COMPLETE 0x7U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_ACK_ERROR 0x8U
/* Image Header related definitions */
/* Definition of header version */
+#if STM32MP13
+#define BOOT_API_HEADER_VERSION 0x00020000U
+#endif
+#if STM32MP15
#define BOOT_API_HEADER_VERSION 0x00010000U
+#endif
/*
* Magic number used to detect header in memory
@@ -94,6 +110,49 @@
#define BOOT_API_ECDSA_ALGO_TYPE_BRAINPOOL256 2
/*
+ * Extension headers related definitions
+ */
+/* 'bootapi_image_header_t.extension_flag' used for authentication feature */
+#define BOOT_API_AUTHENTICATION_EXTENSION_BIT BIT(0)
+/* 'bootapi_image_header_t.extension_flag' used for FSBL decryption feature */
+#define BOOT_API_FSBL_DECRYPTION_EXTENSION_BIT BIT(1)
+/* 'bootapi_image_header_t.extension_flag' used for padding header feature */
+#define BOOT_API_PADDING_EXTENSION_BIT BIT(31)
+/*
+ * mask of bits of field 'bootapi_image_header_t.extension_flag'
+ * used for extension headers
+ */
+#define BOOT_API_ALL_EXTENSIONS_MASK \
+ (BOOT_API_AUTHENTICATION_EXTENSION_BIT | \
+ BOOT_API_FSBL_DECRYPTION_EXTENSION_BIT | \
+ BOOT_API_PADDING_EXTENSION_BIT)
+/*
+ * Magic number of FSBL decryption extension header
+ * The value shall gives the four bytes 'S','T',0x00,0x01 in memory
+ */
+#define BOOT_API_FSBL_DECRYPTION_HEADER_MAGIC_NB 0x01005453U
+
+/*
+ * Magic number of PKH revocation extension header
+ * The value shall gives the four bytes 'S','T',0x00,0x02 in memory
+ */
+#define BOOT_API_AUTHENTICATION_HEADER_MAGIC_NB 0x02005453U
+
+/* Max number of ECDSA public key hash in table */
+#define BOOT_API_AUTHENTICATION_NB_PKH_MAX 8U
+
+/* ECDSA public key hash table size in bytes */
+#define BOOT_API_AUTHENTICATION_TABLE_SIZE_BYTES \
+ (BOOT_API_AUTHENTICATION_NB_PKH_MAX * \
+ BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES)
+
+/*
+ * Magic number of padding extension header
+ * The value shall gives the four bytes 'S','T',0xFF,0xFF in memory
+ */
+#define BOOT_API_PADDING_HEADER_MAGIC_NB 0xFFFF5453U
+
+/*
* Cores secure magic numbers
* Constant to be stored in bakcup register
* BOOT_API_MAGIC_NUMBER_TAMP_BCK_REG_IDX
@@ -157,11 +216,20 @@
*/
uint16_t boot_interface_selected;
uint16_t boot_interface_instance;
+#if STM32MP13
+ uint32_t reserved1[12];
+#endif
+#if STM32MP15
uint32_t reserved1[13];
+#endif
uint32_t otp_afmux_values[3];
- uint32_t reserved[5];
+ uint32_t reserved[3];
+#if STM32MP15
+ uint32_t reserved2[2];
+#endif
uint32_t auth_status;
+#if STM32MP15
/*
* Pointers to bootROM External Secure Services
* - ECDSA check key
@@ -179,7 +247,7 @@
uint8_t *signature,
uint32_t ecc_algo,
uint32_t *entry_in);
-
+#endif
/*
* Information specific to an SD boot
* Updated each time an SD boot is at least attempted,
@@ -227,10 +295,10 @@
uint8_t image_signature[BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES];
/*
* Checksum of payload
- * 32-bit sum all all payload bytes considered as 8 bit unigned numbers,
- * discarding any overflow bits.
+ * 32-bit sum all payload bytes considered as 8 bit unsigned
+ * numbers, discarding any overflow bits.
* Use to check UART/USB downloaded image integrity when signature
- * is not used (i.e bit 0 : 'No_sig_check' = 1 in option flags)
+ * is not used
*/
uint32_t payload_checksum;
/* Image header version : should have value BOOT_API_HEADER_VERSION */
@@ -255,6 +323,25 @@
* counter value in OTP_CFG4 prior executing the downloaded image
*/
uint32_t image_version;
+
+#if STM32MP13
+ /*
+ * Extension flags :
+ *
+ * Bit 0 : Authentication extension header
+ * value 0 : No signature check request
+ * Bit 1 : Encryption extension header
+ * Bit 2 : Padding extension header
+ */
+ uint32_t extension_flags;
+ /* Length in bytes of all extension headers */
+ uint32_t extension_headers_length;
+ /* Add binary type information */
+ uint32_t binary_type;
+ /* Pad up to 128 byte total size */
+ uint8_t pad[16];
+#endif
+#if STM32MP15
/*
* Option flags:
* Bit 0 : No signature check request : 'No_sig_check'
@@ -280,6 +367,7 @@
uint8_t pad[83];
/* Add binary type information */
uint8_t binary_type;
+#endif
} __packed boot_api_image_header_t;
#endif /* BOOT_API_H */
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index 38de1b7..23934e9 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -21,6 +21,16 @@
void stm32mp1_syscfg_enable_io_compensation_start(void);
void stm32mp1_syscfg_enable_io_compensation_finish(void);
void stm32mp1_syscfg_disable_io_compensation(void);
+uint32_t stm32mp1_syscfg_get_chip_version(void);
+uint32_t stm32mp1_syscfg_get_chip_dev_id(void);
+#if STM32MP13
+void stm32mp1_syscfg_boot_mode_enable(void);
+void stm32mp1_syscfg_boot_mode_disable(void);
+#endif
+#if STM32MP15
+static inline void stm32mp1_syscfg_boot_mode_enable(void){}
+static inline void stm32mp1_syscfg_boot_mode_disable(void){}
+#endif
void stm32mp1_deconfigure_uart_pins(void);
diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
index 7963c4a..9ca0930 100644
--- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -68,6 +68,7 @@
.next_handoff_image_id = INVALID_IMAGE_ID,
},
+#if STM32MP15
/* Fill BL32 external 2 image related information */
{
.image_id = BL32_EXTRA2_IMAGE_ID,
@@ -82,6 +83,7 @@
.next_handoff_image_id = INVALID_IMAGE_ID,
},
+#endif
/* Fill HW_CONFIG related information if it exists */
{
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
index 36a3a1c..f68eb38 100644
--- a/plat/st/stm32mp1/plat_image_load.c
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -1,14 +1,16 @@
/*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <platform_def.h>
+#include <assert.h>
#include <common/desc_image_load.h>
#include <plat/common/platform.h>
+#include <platform_def.h>
+
/*******************************************************************************
* This function flushes the data structures so that they are visible
* in memory for the next BL image.
@@ -27,6 +29,8 @@
bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID);
uint32_t ddr_ns_size = stm32mp_get_ddr_ns_size();
+ assert(bl33 != NULL);
+
/* Max size is non-secure DDR end address minus image_base */
bl33->image_info.image_max_size = STM32MP_DDR_BASE + ddr_ns_size -
bl33->image_info.image_base;
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index a4c40c4..7203de8 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -24,10 +24,56 @@
# Enable dynamic memory mapping
PLAT_XLAT_TABLES_DYNAMIC := 1
+# Default Device tree
+DTB_FILE_NAME ?= stm32mp157c-ev1.dtb
+
+STM32MP13 ?= 0
+STM32MP15 ?= 0
+
+ifeq ($(STM32MP13),1)
+ifeq ($(STM32MP15),1)
+$(error Cannot enable both flags STM32MP13 and STM32MP15)
+endif
+STM32MP13 := 1
+STM32MP15 := 0
+else ifeq ($(STM32MP15),1)
+STM32MP13 := 0
+STM32MP15 := 1
+else ifneq ($(findstring stm32mp13,$(DTB_FILE_NAME)),)
+STM32MP13 := 1
+STM32MP15 := 0
+else ifneq ($(findstring stm32mp15,$(DTB_FILE_NAME)),)
+STM32MP13 := 0
+STM32MP15 := 1
+endif
+
+ifeq ($(STM32MP13),1)
+# DDR controller with single AXI port and 16-bit interface
+STM32MP_DDR_DUAL_AXI_PORT:= 0
+STM32MP_DDR_32BIT_INTERFACE:= 0
+
+# STM32 image header version v2.0
+STM32_HEADER_VERSION_MAJOR:= 2
+STM32_HEADER_VERSION_MINOR:= 0
+endif
+
+ifeq ($(STM32MP15),1)
# DDR controller with dual AXI port and 32-bit interface
STM32MP_DDR_DUAL_AXI_PORT:= 1
STM32MP_DDR_32BIT_INTERFACE:= 1
+# STM32 image header version v1.0
+STM32_HEADER_VERSION_MAJOR:= 1
+STM32_HEADER_VERSION_MINOR:= 0
+
+# Add OP-TEE reserved shared memory area in mapping
+STM32MP15_OPTEE_RSV_SHM := 1
+$(eval $(call add_defines,STM32MP15_OPTEE_RSV_SHM))
+endif
+
+# STM32 image header binary type for BL2
+STM32_HEADER_BL2_BINARY_TYPE:= 0x10
+
ifeq ($(AARCH32_SP),sp_min)
# Disable Neon support: sp_min runtime may conflict with non-secure world
TF_CFLAGS += -mfloat-abi=soft
@@ -40,34 +86,28 @@
WORKAROUND_CVE_2017_5715:= 0
WORKAROUND_CVE_2022_23960:= 0
+# Number of TF-A copies in the device
+STM32_TF_A_COPIES := 2
+
+# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
+# such as metadata (2) to find all the FIP partitions (default is 2).
+PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 4)))
+
ifeq (${PSA_FWU_SUPPORT},1)
ifneq (${STM32MP_USE_STM32IMAGE},1)
# Number of banks of updatable firmware
NR_OF_FW_BANKS := 2
NR_OF_IMAGES_IN_FW_BANK := 1
-# Number of TF-A copies in the device
-STM32_TF_A_COPIES := 2
-STM32_BL33_PARTS_NUM := 2
-STM32_RUNTIME_PARTS_NUM := 4
-else
-$(error FWU Feature enabled only with FIP images)
+FWU_MAX_PART = $(shell echo $$(($(STM32_TF_A_COPIES) + 2 + $(NR_OF_FW_BANKS))))
+ifeq ($(shell test $(FWU_MAX_PART) -gt $(PLAT_PARTITION_MAX_ENTRIES); echo $$?),0)
+$(error "Required partition number is $(FWU_MAX_PART) where PLAT_PARTITION_MAX_ENTRIES is only \
+$(PLAT_PARTITION_MAX_ENTRIES)")
endif
else
-# Number of TF-A copies in the device
-STM32_TF_A_COPIES := 2
-STM32_BL33_PARTS_NUM := 1
-ifeq ($(AARCH32_SP),optee)
-STM32_RUNTIME_PARTS_NUM := 3
-else ifeq ($(STM32MP_USE_STM32IMAGE),1)
-STM32_RUNTIME_PARTS_NUM := 0
-else
-STM32_RUNTIME_PARTS_NUM := 1
+$(error FWU Feature enabled only with FIP images)
endif
endif
-PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + \
- $(STM32_BL33_PARTS_NUM) + \
- $(STM32_RUNTIME_PARTS_NUM))))
# Boot devices
STM32MP_EMMC ?= 0
@@ -82,7 +122,10 @@
STM32MP_UART_PROGRAMMER ?= 0
# Device tree
-DTB_FILE_NAME ?= stm32mp157c-ev1.dtb
+ifeq ($(STM32MP13),1)
+BL2_DTSI := stm32mp13-bl2.dtsi
+FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
+else
ifeq ($(STM32MP_USE_STM32IMAGE),1)
ifeq ($(AARCH32_SP),optee)
BL2_DTSI := stm32mp15-bl2.dtsi
@@ -98,9 +141,10 @@
FDT_SOURCES += $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dts,$(DTB_FILE_NAME)))
endif
endif
+endif
$(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
-$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g")))
+$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o "[0-9]*")))
DTC_CPPFLAGS += ${INCLUDES}
DTC_FLAGS += -Wno-unit_address_vs_reg
ifeq ($(shell test $(DTC_VERSION) -ge 10601; echo $$?),0)
@@ -167,6 +211,8 @@
STM32MP_UART_PROGRAMMER \
STM32MP_USB_PROGRAMMER \
STM32MP_USE_STM32IMAGE \
+ STM32MP13 \
+ STM32MP15 \
)))
$(eval $(call assert_numerics,\
@@ -196,6 +242,8 @@
STM32MP_UART_PROGRAMMER \
STM32MP_USB_PROGRAMMER \
STM32MP_USE_STM32IMAGE \
+ STM32MP13 \
+ STM32MP15 \
)))
# Include paths and source files
@@ -230,7 +278,6 @@
drivers/delay_timer/generic_delay_timer.c \
drivers/st/bsec/bsec2.c \
drivers/st/clk/stm32mp_clkfunc.c \
- drivers/st/clk/stm32mp1_clk.c \
drivers/st/ddr/stm32mp_ddr.c \
drivers/st/ddr/stm32mp1_ddr_helpers.c \
drivers/st/gpio/stm32_gpio.c \
@@ -246,6 +293,13 @@
plat/st/stm32mp1/stm32mp1_helper.S \
plat/st/stm32mp1/stm32mp1_syscfg.c
+ifeq ($(STM32MP13),1)
+PLAT_BL_COMMON_SOURCES += drivers/st/clk/clk-stm32-core.c \
+ drivers/st/clk/clk-stm32mp13.c
+else
+PLAT_BL_COMMON_SOURCES += drivers/st/clk/stm32mp1_clk.c
+endif
+
ifneq (${STM32MP_USE_STM32IMAGE},1)
BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES}
@@ -264,20 +318,26 @@
plat/st/stm32mp1/stm32mp1_security.c
endif
-ifeq (${PSA_FWU_SUPPORT},1)
include lib/zlib/zlib.mk
+
+ifeq (${PSA_FWU_SUPPORT},1)
include drivers/fwu/fwu.mk
+endif
+
BL2_SOURCES += $(ZLIB_SOURCES)
-endif
BL2_SOURCES += drivers/io/io_block.c \
drivers/io/io_mtd.c \
drivers/io/io_storage.c \
drivers/st/crypto/stm32_hash.c \
- plat/st/common/stm32mp_auth.c \
plat/st/stm32mp1/bl2_plat_setup.c
+
+ifeq ($(STM32MP15),1)
+BL2_SOURCES += plat/st/common/stm32mp_auth.c
+endif
+
ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),)
BL2_SOURCES += drivers/mmc/mmc.c \
drivers/partition/gpt.c \
@@ -297,6 +357,9 @@
endif
ifeq (${STM32MP_SPI_NOR},1)
+ifneq (${STM32MP_FORCE_MTD_START_OFFSET},)
+$(eval $(call add_define_val,STM32MP_NOR_FIP_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET}))
+endif
BL2_SOURCES += drivers/mtd/nor/spi_nor.c
endif
@@ -306,6 +369,9 @@
endif
ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND}),)
+ifneq (${STM32MP_FORCE_MTD_START_OFFSET},)
+$(eval $(call add_define_val,STM32MP_NAND_FIP_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET}))
+endif
BL2_SOURCES += drivers/mtd/nand/core.c
endif
@@ -427,5 +493,8 @@
$(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
${Q}${STM32IMAGE} -s $(word 2,$^) -d $@ \
-l $(LOADADDR) -e ${ENTRY} \
- -v ${STM32_TF_VERSION}
+ -v ${STM32_TF_VERSION} \
+ -m ${STM32_HEADER_VERSION_MAJOR} \
+ -n ${STM32_HEADER_VERSION_MINOR} \
+ -b ${STM32_HEADER_BL2_BINARY_TYPE}
@echo
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index b506e95..c3fc2cb 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -4,6 +4,10 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+ifeq ($(STM32MP13),1)
+$(error "SP_min is not supported on STM32MP13 platform")
+endif
+
SP_MIN_WITH_SECURE_FIQ := 1
ifneq ($(STM32MP_USE_STM32IMAGE),1)
diff --git a/plat/st/stm32mp1/stm32mp1_boot_device.c b/plat/st/stm32mp1/stm32mp1_boot_device.c
index b05de1c..3a8a27a 100644
--- a/plat/st/stm32mp1/stm32mp1_boot_device.c
+++ b/plat/st/stm32mp1/stm32mp1_boot_device.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <errno.h>
#include <common/debug.h>
@@ -15,9 +16,21 @@
#include <plat/common/platform.h>
#if STM32MP_RAW_NAND || STM32MP_SPI_NAND
+#if STM32MP13
+void plat_get_scratch_buffer(void **buffer_addr, size_t *buf_size)
+{
+ assert(buffer_addr != NULL);
+ assert(buf_size != NULL);
+
+ *buffer_addr = (void *)STM32MP_MTD_BUFFER;
+ *buf_size = PLATFORM_MTD_MAX_PAGE_SIZE;
+}
+#endif
+
static int get_data_from_otp(struct nand_device *nand_dev, bool is_slc)
{
uint32_t nand_param;
+ uint32_t nand2_param __maybe_unused;
/* Check if NAND parameters are stored in OTP */
if (stm32_get_otp_value(NAND_OTP, &nand_param) != 0) {
@@ -26,12 +39,39 @@
}
if (nand_param == 0U) {
+#if STM32MP13
+ if (is_slc) {
+ return 0;
+ }
+#endif
+#if STM32MP15
return 0;
+#endif
}
if ((nand_param & NAND_PARAM_STORED_IN_OTP) == 0U) {
+#if STM32MP13
+ if (is_slc) {
+ goto ecc;
+ }
+#endif
+#if STM32MP15
goto ecc;
+#endif
+ }
+
+#if STM32MP13
+ if (stm32_get_otp_value(NAND2_OTP, &nand2_param) != 0) {
+ ERROR("BSEC: NAND_OTP Error\n");
+ return -EACCES;
+ }
+
+ /* Check OTP configuration for this device */
+ if ((((nand2_param & NAND2_CONFIG_DISTRIB) == NAND2_PNAND_NAND1_SNAND_NAND2) && !is_slc) ||
+ (((nand2_param & NAND2_CONFIG_DISTRIB) == NAND2_PNAND_NAND2_SNAND_NAND1) && is_slc)) {
+ nand_param = nand2_param << (NAND_PAGE_SIZE_SHIFT - NAND2_PAGE_SIZE_SHIFT);
}
+#endif
/* NAND parameter shall be read from OTP */
if ((nand_param & NAND_WIDTH_MASK) != 0U) {
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 801b947..116bd5d 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -36,6 +36,23 @@
/*******************************************************************************
* CHIP ID
******************************************************************************/
+#if STM32MP13
+#define STM32MP1_CHIP_ID U(0x501)
+
+#define STM32MP135C_PART_NB U(0x05010000)
+#define STM32MP135A_PART_NB U(0x05010001)
+#define STM32MP133C_PART_NB U(0x050100C0)
+#define STM32MP133A_PART_NB U(0x050100C1)
+#define STM32MP131C_PART_NB U(0x050106C8)
+#define STM32MP131A_PART_NB U(0x050106C9)
+#define STM32MP135F_PART_NB U(0x05010800)
+#define STM32MP135D_PART_NB U(0x05010801)
+#define STM32MP133F_PART_NB U(0x050108C0)
+#define STM32MP133D_PART_NB U(0x050108C1)
+#define STM32MP131F_PART_NB U(0x05010EC8)
+#define STM32MP131D_PART_NB U(0x05010EC9)
+#endif
+#if STM32MP15
#define STM32MP1_CHIP_ID U(0x500)
#define STM32MP157C_PART_NB U(0x05000000)
@@ -50,17 +67,26 @@
#define STM32MP153D_PART_NB U(0x050000A5)
#define STM32MP151F_PART_NB U(0x050000AE)
#define STM32MP151D_PART_NB U(0x050000AF)
+#endif
#define STM32MP1_REV_B U(0x2000)
+#if STM32MP13
+#define STM32MP1_REV_Y U(0x1003)
+#define STM32MP1_REV_Z U(0x1001)
+#endif
+#if STM32MP15
#define STM32MP1_REV_Z U(0x2001)
+#endif
/*******************************************************************************
* PACKAGE ID
******************************************************************************/
+#if STM32MP15
#define PKG_AA_LFBGA448 U(4)
#define PKG_AB_LFBGA354 U(3)
#define PKG_AC_TFBGA361 U(2)
#define PKG_AD_TFBGA257 U(1)
+#endif
/*******************************************************************************
* STM32MP1 memory map related constants
@@ -69,8 +95,22 @@
#define STM32MP_ROM_SIZE U(0x00020000)
#define STM32MP_ROM_SIZE_2MB_ALIGNED U(0x00200000)
+#if STM32MP13
+#define STM32MP_SYSRAM_BASE U(0x2FFE0000)
+#define STM32MP_SYSRAM_SIZE U(0x00020000)
+#define SRAM1_BASE U(0x30000000)
+#define SRAM1_SIZE U(0x00004000)
+#define SRAM2_BASE U(0x30004000)
+#define SRAM2_SIZE U(0x00002000)
+#define SRAM3_BASE U(0x30006000)
+#define SRAM3_SIZE U(0x00002000)
+#define SRAMS_BASE SRAM1_BASE
+#define SRAMS_SIZE_2MB_ALIGNED U(0x00200000)
+#endif /* STM32MP13 */
+#if STM32MP15
#define STM32MP_SYSRAM_BASE U(0x2FFC0000)
#define STM32MP_SYSRAM_SIZE U(0x00040000)
+#endif /* STM32MP15 */
#define STM32MP_NS_SYSRAM_SIZE PAGE_SIZE
#define STM32MP_NS_SYSRAM_BASE (STM32MP_SYSRAM_BASE + \
@@ -98,6 +138,15 @@
#endif
/* Section used inside TF binaries */
+#if STM32MP13
+/* 512 Octets reserved for header */
+#define STM32MP_HEADER_RESERVED_SIZE U(0x200)
+
+#define STM32MP_BINARY_BASE STM32MP_SEC_SYSRAM_BASE
+
+#define STM32MP_BINARY_SIZE STM32MP_SEC_SYSRAM_SIZE
+#endif
+#if STM32MP15
#define STM32MP_PARAM_LOAD_SIZE U(0x00002400) /* 9 KB for param */
/* 256 Octets reserved for header */
#define STM32MP_HEADER_SIZE U(0x00000100)
@@ -111,6 +160,7 @@
#define STM32MP_BINARY_SIZE (STM32MP_SEC_SYSRAM_SIZE - \
(STM32MP_PARAM_LOAD_SIZE + \
STM32MP_HEADER_SIZE))
+#endif
/* BL2 and BL32/sp_min require finer granularity tables */
#if defined(IMAGE_BL2)
@@ -133,12 +183,23 @@
#endif
#endif
+#if STM32MP13
+#define STM32MP_BL33_BASE STM32MP_DDR_BASE
+#endif
+#if STM32MP15
#define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x100000))
+#endif
#define STM32MP_BL33_MAX_SIZE U(0x400000)
/* Define maximum page size for NAND devices */
#define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000)
+/* Define location for the MTD scratch buffer */
+#if STM32MP13
+#define STM32MP_MTD_BUFFER (SRAM1_BASE + \
+ SRAM1_SIZE - \
+ PLATFORM_MTD_MAX_PAGE_SIZE)
+#endif
/*******************************************************************************
* STM32MP1 device/io map related constants (used for MMU)
******************************************************************************/
@@ -170,9 +231,11 @@
#define GPIOG_BASE U(0x50008000)
#define GPIOH_BASE U(0x50009000)
#define GPIOI_BASE U(0x5000A000)
+#if STM32MP15
#define GPIOJ_BASE U(0x5000B000)
#define GPIOK_BASE U(0x5000C000)
#define GPIOZ_BASE U(0x54004000)
+#endif
#define GPIO_BANK_OFFSET U(0x1000)
/* Bank IDs used in GPIO driver API */
@@ -185,17 +248,25 @@
#define GPIO_BANK_G U(6)
#define GPIO_BANK_H U(7)
#define GPIO_BANK_I U(8)
+#if STM32MP15
#define GPIO_BANK_J U(9)
#define GPIO_BANK_K U(10)
#define GPIO_BANK_Z U(25)
#define STM32MP_GPIOZ_PIN_MAX_COUNT 8
+#endif
/*******************************************************************************
* STM32MP1 UART
******************************************************************************/
+#if STM32MP13
+#define USART1_BASE U(0x4C000000)
+#define USART2_BASE U(0x4C001000)
+#endif
+#if STM32MP15
#define USART1_BASE U(0x5C000000)
#define USART2_BASE U(0x4000E000)
+#endif
#define USART3_BASE U(0x4000F000)
#define UART4_BASE U(0x40010000)
#define UART5_BASE U(0x40011000)
@@ -205,6 +276,18 @@
/* For UART crash console */
#define STM32MP_DEBUG_USART_BASE UART4_BASE
+#if STM32MP13
+/* UART4 on HSI@64MHz, TX on GPIOF12 Alternate 8 (Disco board) */
+#define STM32MP_DEBUG_USART_CLK_FRQ 64000000
+#define DEBUG_UART_TX_GPIO_BANK_ADDRESS GPIOD_BASE
+#define DEBUG_UART_TX_GPIO_BANK_CLK_REG RCC_MP_S_AHB4ENSETR
+#define DEBUG_UART_TX_GPIO_BANK_CLK_EN RCC_MP_S_AHB4ENSETR_GPIODEN
+#define DEBUG_UART_TX_GPIO_PORT 6
+#define DEBUG_UART_TX_GPIO_ALTERNATE 8
+#define DEBUG_UART_TX_CLKSRC_REG RCC_UART4CKSELR
+#define DEBUG_UART_TX_CLKSRC RCC_UART4CKSELR_HSI
+#endif /* STM32MP13 */
+#if STM32MP15
/* UART4 on HSI@64MHz, TX on GPIOG11 Alternate 6 */
#define STM32MP_DEBUG_USART_CLK_FRQ 64000000
#define DEBUG_UART_TX_GPIO_BANK_ADDRESS GPIOG_BASE
@@ -214,6 +297,7 @@
#define DEBUG_UART_TX_GPIO_ALTERNATE 6
#define DEBUG_UART_TX_CLKSRC_REG RCC_UART24CKSELR
#define DEBUG_UART_TX_CLKSRC RCC_UART24CKSELR_HSI
+#endif /* STM32MP15 */
#define DEBUG_UART_TX_EN_REG RCC_MP_APB1ENSETR
#define DEBUG_UART_TX_EN RCC_MP_APB1ENSETR_UART4EN
#define DEBUG_UART_RST_REG RCC_APB1RSTSETR
@@ -322,8 +406,13 @@
******************************************************************************/
#define STM32MP1_TZC_BASE U(0x5C006000)
+#if STM32MP13
+#define STM32MP1_FILTER_BIT_ALL TZC_400_REGION_ATTR_FILTER_BIT(0)
+#endif
+#if STM32MP15
#define STM32MP1_FILTER_BIT_ALL (TZC_400_REGION_ATTR_FILTER_BIT(0) | \
TZC_400_REGION_ATTR_FILTER_BIT(1))
+#endif
/*******************************************************************************
* STM32MP1 SDMMC
@@ -349,24 +438,49 @@
/* OTP labels */
#define CFG0_OTP "cfg0_otp"
#define PART_NUMBER_OTP "part_number_otp"
+#if STM32MP15
#define PACKAGE_OTP "package_otp"
+#endif
#define HW2_OTP "hw2_otp"
+#if STM32MP13
+#define NAND_OTP "cfg9_otp"
+#define NAND2_OTP "cfg10_otp"
+#endif
+#if STM32MP15
#define NAND_OTP "nand_otp"
+#endif
#define MONOTONIC_OTP "monotonic_otp"
#define UID_OTP "uid_otp"
#define BOARD_ID_OTP "board_id"
/* OTP mask */
/* CFG0 */
+#if STM32MP13
+#define CFG0_OTP_MODE_MASK GENMASK_32(9, 0)
+#define CFG0_OTP_MODE_SHIFT 0
+#define CFG0_OPEN_DEVICE 0x17U
+#define CFG0_CLOSED_DEVICE 0x3FU
+#define CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN 0x17FU
+#define CFG0_CLOSED_DEVICE_NO_JTAG 0x3FFU
+#endif
+#if STM32MP15
#define CFG0_CLOSED_DEVICE BIT(6)
+#endif
/* PART NUMBER */
+#if STM32MP13
+#define PART_NUMBER_OTP_PART_MASK GENMASK_32(11, 0)
+#endif
+#if STM32MP15
#define PART_NUMBER_OTP_PART_MASK GENMASK_32(7, 0)
+#endif
#define PART_NUMBER_OTP_PART_SHIFT 0
/* PACKAGE */
+#if STM32MP15
#define PACKAGE_OTP_PKG_MASK GENMASK_32(29, 27)
#define PACKAGE_OTP_PKG_SHIFT 27
+#endif
/* IWDG OTP */
#define HW2_OTP_IWDG_HW_POS U(3)
@@ -394,7 +508,7 @@
#define NAND_BLOCK_SIZE_128_PAGES U(1)
#define NAND_BLOCK_SIZE_256_PAGES U(2)
-/* NAND number of block (in unit of 256 blocs) */
+/* NAND number of block (in unit of 256 blocks) */
#define NAND_BLOCK_NB_MASK GENMASK_32(26, 19)
#define NAND_BLOCK_NB_SHIFT 19
#define NAND_BLOCK_NB_UNIT U(256)
@@ -415,12 +529,23 @@
/* NAND number of planes */
#define NAND_PLANE_BIT_NB_MASK BIT(14)
+/* NAND2 OTP */
+#define NAND2_PAGE_SIZE_SHIFT 16
+
+/* NAND2 config distribution */
+#define NAND2_CONFIG_DISTRIB BIT(0)
+#define NAND2_PNAND_NAND2_SNAND_NAND1 U(0)
+#define NAND2_PNAND_NAND1_SNAND_NAND2 U(1)
+
/* MONOTONIC OTP */
#define MAX_MONOTONIC_VALUE 32
/* UID OTP */
#define UID_WORD_NB U(3)
+/* FWU configuration (max supported value is 15) */
+#define FWU_MAX_TRIAL_REBOOT U(3)
+
/*******************************************************************************
* STM32MP1 TAMP
******************************************************************************/
@@ -463,34 +588,83 @@
* Miscellaneous STM32MP1 peripherals base address
******************************************************************************/
#define BSEC_BASE U(0x5C005000)
+#if STM32MP13
+#define CRYP_BASE U(0x54002000)
+#endif
+#if STM32MP15
#define CRYP1_BASE U(0x54001000)
+#endif
#define DBGMCU_BASE U(0x50081000)
+#if STM32MP13
+#define HASH_BASE U(0x54003000)
+#endif
+#if STM32MP15
#define HASH1_BASE U(0x54002000)
+#endif
+#if STM32MP13
+#define I2C3_BASE U(0x4C004000)
+#define I2C4_BASE U(0x4C005000)
+#define I2C5_BASE U(0x4C006000)
+#endif
+#if STM32MP15
#define I2C4_BASE U(0x5C002000)
#define I2C6_BASE U(0x5c009000)
+#endif
+#if STM32MP13
+#define RNG_BASE U(0x54004000)
+#endif
+#if STM32MP15
#define RNG1_BASE U(0x54003000)
+#endif
#define RTC_BASE U(0x5c004000)
+#if STM32MP13
+#define SPI4_BASE U(0x4C002000)
+#define SPI5_BASE U(0x4C003000)
+#endif
+#if STM32MP15
#define SPI6_BASE U(0x5c001000)
+#endif
#define STGEN_BASE U(0x5c008000)
#define SYSCFG_BASE U(0x50020000)
/*******************************************************************************
+ * STM32MP13 SAES
+ ******************************************************************************/
+#define SAES_BASE U(0x54005000)
+
+/*******************************************************************************
+ * STM32MP13 PKA
+ ******************************************************************************/
+#define PKA_BASE U(0x54006000)
+
+/*******************************************************************************
* REGULATORS
******************************************************************************/
/* 3 PWR + 1 VREFBUF + 14 PMIC regulators + 1 FIXED */
#define PLAT_NB_RDEVS U(19)
-/* 1 FIXED */
-#define PLAT_NB_FIXED_REGS U(1)
+/* 2 FIXED */
+#define PLAT_NB_FIXED_REGS U(2)
/*******************************************************************************
* Device Tree defines
******************************************************************************/
#define DT_BSEC_COMPAT "st,stm32mp15-bsec"
+#if STM32MP13
+#define DT_DDR_COMPAT "st,stm32mp13-ddr"
+#endif
+#if STM32MP15
#define DT_DDR_COMPAT "st,stm32mp1-ddr"
+#endif
#define DT_IWDG_COMPAT "st,stm32mp1-iwdg"
-#define DT_NVMEM_LAYOUT_COMPAT "st,stm32-nvmem-layout"
#define DT_PWR_COMPAT "st,stm32mp1,pwr-reg"
+#if STM32MP13
+#define DT_RCC_CLK_COMPAT "st,stm32mp13-rcc"
+#define DT_RCC_SEC_CLK_COMPAT "st,stm32mp13-rcc-secure"
+#endif
+#if STM32MP15
#define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc"
#define DT_RCC_SEC_CLK_COMPAT "st,stm32mp1-rcc-secure"
+#endif
+#define DT_SDMMC2_COMPAT "st,stm32-sdmmc2"
#endif /* STM32MP1_DEF_H */
diff --git a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
index a1969eb..f2568ab 100644
--- a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
+++ b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -31,8 +31,13 @@
void stm32mp1_arch_security_setup(void)
{
+#if STM32MP13
+ clk_enable(TZC);
+#endif
+#if STM32MP15
clk_enable(TZC1);
clk_enable(TZC2);
+#endif
tzc400_init(STM32MP1_TZC_BASE);
tzc400_disable_filters();
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
index 41972e4..5652597 100644
--- a/plat/st/stm32mp1/stm32mp1_fip_def.h
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -7,32 +7,59 @@
#ifndef STM32MP1_FIP_DEF_H
#define STM32MP1_FIP_DEF_H
+#if STM32MP15_OPTEE_RSV_SHM
#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */
#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */
+#else
+#define STM32MP_DDR_S_SIZE U(0x02000000) /* 32 MB */
+#define STM32MP_DDR_SHMEM_SIZE U(0) /* empty */
+#endif
+#if STM32MP13
+#define STM32MP_BL2_RO_SIZE U(0x00015000) /* 84 KB */
+#define STM32MP_BL2_SIZE U(0x00017000) /* 92 KB for BL2 */
+#define STM32MP_BL2_DTB_SIZE U(0x00004000) /* 16 KB for DTB */
+#endif /* STM32MP13 */
+#if STM32MP15
#define STM32MP_BL2_RO_SIZE U(0x00011000) /* 68 KB */
#define STM32MP_BL2_SIZE U(0x00016000) /* 88 KB for BL2 */
#define STM32MP_BL2_DTB_SIZE U(0x00007000) /* 28 KB for DTB */
+#endif /* STM32MP15 */
#define STM32MP_BL32_SIZE U(0x0001B000) /* 108 KB for BL32 */
#define STM32MP_BL32_DTB_SIZE U(0x00005000) /* 20 KB for DTB */
#define STM32MP_FW_CONFIG_MAX_SIZE PAGE_SIZE /* 4 KB for FCONF DTB */
#define STM32MP_HW_CONFIG_MAX_SIZE U(0x40000) /* 256 KB for HW config DTB */
+#if STM32MP13
+#define STM32MP_BL2_BASE (STM32MP_BL2_DTB_BASE + \
+ STM32MP_BL2_DTB_SIZE)
+#endif /* STM32MP13 */
+#if STM32MP15
#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \
STM32MP_SEC_SYSRAM_SIZE - \
STM32MP_BL2_SIZE)
+#endif /* STM32MP15 */
#define STM32MP_BL2_RO_BASE STM32MP_BL2_BASE
#define STM32MP_BL2_RW_BASE (STM32MP_BL2_RO_BASE + \
STM32MP_BL2_RO_SIZE)
+#if STM32MP13
+#define STM32MP_BL2_RW_SIZE (STM32MP_SYSRAM_BASE + \
+ STM32MP_SYSRAM_SIZE - \
+ STM32MP_BL2_RW_BASE)
+
+#define STM32MP_BL2_DTB_BASE STM32MP_SEC_SYSRAM_BASE
+#endif /* STM32MP13 */
+#if STM32MP15
#define STM32MP_BL2_RW_SIZE (STM32MP_SEC_SYSRAM_BASE + \
STM32MP_SEC_SYSRAM_SIZE - \
STM32MP_BL2_RW_BASE)
#define STM32MP_BL2_DTB_BASE (STM32MP_BL2_BASE - \
STM32MP_BL2_DTB_SIZE)
+#endif /* STM32MP15 */
#define STM32MP_BL32_DTB_BASE STM32MP_SYSRAM_BASE
@@ -56,9 +83,14 @@
STM32MP_OPTEE_BASE)
#endif
+#if STM32MP13
+#define STM32MP_FW_CONFIG_BASE SRAM3_BASE
+#endif /* STM32MP13 */
+#if STM32MP15
#define STM32MP_FW_CONFIG_BASE (STM32MP_SYSRAM_BASE + \
STM32MP_SYSRAM_SIZE - \
PAGE_SIZE)
+#endif /* STM32MP15 */
#define STM32MP_HW_CONFIG_BASE (STM32MP_BL33_BASE + \
STM32MP_BL33_MAX_SIZE)
@@ -71,9 +103,14 @@
#endif
/*******************************************************************************
- * STM32MP1 RAW partition offset for MTD devices
+ * STM32MP1 RAW partition offset for devices without GPT
******************************************************************************/
+#define STM32MP_EMMC_BOOT_FIP_OFFSET U(0x00040000)
+#ifndef STM32MP_NOR_FIP_OFFSET
#define STM32MP_NOR_FIP_OFFSET U(0x00080000)
+#endif
+#ifndef STM32MP_NAND_FIP_OFFSET
#define STM32MP_NAND_FIP_OFFSET U(0x00200000)
+#endif
#endif /* STM32MP1_FIP_DEF_H */
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index 1125a69..c40e045 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -37,11 +37,27 @@
BOARD_ID_VARFG_SHIFT)
#define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK)
+#if STM32MP13
+#define TAMP_BOOT_MODE_BACKUP_REG_ID U(30)
+#endif
+#if STM32MP15
#define TAMP_BOOT_MODE_BACKUP_REG_ID U(20)
-#define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00)
+#endif
+#define TAMP_BOOT_MODE_ITF_MASK GENMASK(15, 8)
#define TAMP_BOOT_MODE_ITF_SHIFT 8
+#define TAMP_BOOT_MODE_AUTH_MASK GENMASK(23, 16)
+#define TAMP_BOOT_MODE_AUTH_SHIFT 16
-#define TAMP_BOOT_COUNTER_REG_ID U(21)
+/*
+ * Backup register to store fwu update information.
+ * It should be writeable only by secure world, but also readable by non secure
+ * (so it should be in Zone 2).
+ */
+#define TAMP_BOOT_FWU_INFO_REG_ID U(10)
+#define TAMP_BOOT_FWU_INFO_IDX_MSK GENMASK(3, 0)
+#define TAMP_BOOT_FWU_INFO_IDX_OFF U(0)
+#define TAMP_BOOT_FWU_INFO_CNT_MSK GENMASK(7, 4)
+#define TAMP_BOOT_FWU_INFO_CNT_OFF U(4)
#if defined(IMAGE_BL2)
#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
@@ -67,6 +83,15 @@
MT_EXECUTE_NEVER)
#endif
+#if STM32MP13
+#define MAP_SRAM_ALL MAP_REGION_FLAT(SRAMS_BASE, \
+ SRAMS_SIZE_2MB_ALIGNED, \
+ MT_MEMORY | \
+ MT_RW | \
+ MT_SECURE | \
+ MT_EXECUTE_NEVER)
+#endif
+
#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
STM32MP1_DEVICE1_SIZE, \
MT_DEVICE | \
@@ -84,6 +109,9 @@
#if defined(IMAGE_BL2)
static const mmap_region_t stm32mp1_mmap[] = {
MAP_SEC_SYSRAM,
+#if STM32MP13
+ MAP_SRAM_ALL,
+#endif
MAP_DEVICE1,
#if STM32MP_RAW_NAND
MAP_DEVICE2,
@@ -111,48 +139,70 @@
uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
{
+#if STM32MP13
+ assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
+#endif
+#if STM32MP15
if (bank == GPIO_BANK_Z) {
return GPIOZ_BASE;
}
assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
+#endif
return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
}
uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
{
+#if STM32MP13
+ assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
+#endif
+#if STM32MP15
if (bank == GPIO_BANK_Z) {
return 0;
}
assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
+#endif
return bank * GPIO_BANK_OFFSET;
}
bool stm32_gpio_is_secure_at_reset(unsigned int bank)
{
+#if STM32MP13
+ return true;
+#endif
+#if STM32MP15
if (bank == GPIO_BANK_Z) {
return true;
}
return false;
+#endif
}
unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
{
+#if STM32MP13
+ assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
+#endif
+#if STM32MP15
if (bank == GPIO_BANK_Z) {
return GPIOZ;
}
assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
+#endif
return GPIOA + (bank - GPIO_BANK_A);
}
int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
{
+ const char *node_compatible = NULL;
+
switch (bank) {
case GPIO_BANK_A:
case GPIO_BANK_B:
@@ -163,14 +213,24 @@
case GPIO_BANK_G:
case GPIO_BANK_H:
case GPIO_BANK_I:
+#if STM32MP13
+ node_compatible = "st,stm32mp135-pinctrl";
+ break;
+#endif
+#if STM32MP15
case GPIO_BANK_J:
case GPIO_BANK_K:
- return fdt_path_offset(fdt, "/soc/pin-controller");
+ node_compatible = "st,stm32mp157-pinctrl";
+ break;
case GPIO_BANK_Z:
- return fdt_path_offset(fdt, "/soc/pin-controller-z");
+ node_compatible = "st,stm32mp157-z-pinctrl";
+ break;
+#endif
default:
panic();
}
+
+ return fdt_node_offset_by_compatible(fdt, -1, node_compatible);
}
#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
@@ -248,6 +308,10 @@
uint32_t stm32mp_get_chip_version(void)
{
+#if STM32MP13
+ return stm32mp1_syscfg_get_chip_version();
+#endif
+#if STM32MP15
uint32_t version = 0U;
if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
@@ -256,10 +320,15 @@
}
return version;
+#endif
}
uint32_t stm32mp_get_chip_dev_id(void)
{
+#if STM32MP13
+ return stm32mp1_syscfg_get_chip_dev_id();
+#endif
+#if STM32MP15
uint32_t dev_id;
if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
@@ -268,6 +337,7 @@
}
return dev_id;
+#endif
}
static uint32_t get_part_number(void)
@@ -290,6 +360,7 @@
return part_number;
}
+#if STM32MP15
static uint32_t get_cpu_package(void)
{
uint32_t package;
@@ -303,6 +374,7 @@
return package;
}
+#endif
void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
{
@@ -310,6 +382,45 @@
/* MPUs Part Numbers */
switch (get_part_number()) {
+#if STM32MP13
+ case STM32MP135F_PART_NB:
+ cpu_s = "135F";
+ break;
+ case STM32MP135D_PART_NB:
+ cpu_s = "135D";
+ break;
+ case STM32MP135C_PART_NB:
+ cpu_s = "135C";
+ break;
+ case STM32MP135A_PART_NB:
+ cpu_s = "135A";
+ break;
+ case STM32MP133F_PART_NB:
+ cpu_s = "133F";
+ break;
+ case STM32MP133D_PART_NB:
+ cpu_s = "133D";
+ break;
+ case STM32MP133C_PART_NB:
+ cpu_s = "133C";
+ break;
+ case STM32MP133A_PART_NB:
+ cpu_s = "133A";
+ break;
+ case STM32MP131F_PART_NB:
+ cpu_s = "131F";
+ break;
+ case STM32MP131D_PART_NB:
+ cpu_s = "131D";
+ break;
+ case STM32MP131C_PART_NB:
+ cpu_s = "131C";
+ break;
+ case STM32MP131A_PART_NB:
+ cpu_s = "131A";
+ break;
+#endif
+#if STM32MP15
case STM32MP157C_PART_NB:
cpu_s = "157C";
break;
@@ -346,12 +457,18 @@
case STM32MP151D_PART_NB:
cpu_s = "151D";
break;
+#endif
default:
cpu_s = "????";
break;
}
/* Package */
+#if STM32MP13
+ /* On STM32MP13, package is not present in OTP */
+ pkg = "";
+#endif
+#if STM32MP15
switch (get_cpu_package()) {
case PKG_AA_LFBGA448:
pkg = "AA";
@@ -369,12 +486,18 @@
pkg = "??";
break;
}
+#endif
/* REVISION */
switch (stm32mp_get_chip_version()) {
case STM32MP1_REV_B:
cpu_r = "B";
break;
+#if STM32MP13
+ case STM32MP1_REV_Y:
+ cpu_r = "Y";
+ break;
+#endif
case STM32MP1_REV_Z:
cpu_r = "Z";
break;
@@ -420,6 +543,10 @@
/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
bool stm32mp_is_single_core(void)
{
+#if STM32MP13
+ return true;
+#endif
+#if STM32MP15
bool single_core = false;
switch (get_part_number()) {
@@ -434,6 +561,7 @@
}
return single_core;
+#endif
}
/* Return true when device is in closed state */
@@ -445,7 +573,23 @@
return true;
}
+#if STM32MP13
+ value = (value & CFG0_OTP_MODE_MASK) >> CFG0_OTP_MODE_SHIFT;
+
+ switch (value) {
+ case CFG0_OPEN_DEVICE:
+ return false;
+ case CFG0_CLOSED_DEVICE:
+ case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
+ case CFG0_CLOSED_DEVICE_NO_JTAG:
+ return true;
+ default:
+ panic();
+ }
+#endif
+#if STM32MP15
return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
+#endif
}
/* Return true when device supports secure boot */
@@ -454,12 +598,22 @@
bool supported = false;
switch (get_part_number()) {
+#if STM32MP13
+ case STM32MP131C_PART_NB:
+ case STM32MP131F_PART_NB:
+ case STM32MP133C_PART_NB:
+ case STM32MP133F_PART_NB:
+ case STM32MP135C_PART_NB:
+ case STM32MP135F_PART_NB:
+#endif
+#if STM32MP15
case STM32MP151C_PART_NB:
case STM32MP151F_PART_NB:
case STM32MP153C_PART_NB:
case STM32MP153F_PART_NB:
case STM32MP157C_PART_NB:
case STM32MP157F_PART_NB:
+#endif
supported = true;
break;
default:
@@ -599,12 +753,59 @@
*instance = itf & 0xFU;
}
+void stm32_save_boot_auth(uint32_t auth_status, uint32_t boot_partition)
+{
+ uint32_t boot_status = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
+
+ clk_enable(RTCAPB);
+
+ mmio_clrsetbits_32(boot_status,
+ TAMP_BOOT_MODE_AUTH_MASK,
+ ((auth_status << 4) | (boot_partition & 0xFU)) <<
+ TAMP_BOOT_MODE_AUTH_SHIFT);
+
+ clk_disable(RTCAPB);
+}
+
#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
void stm32mp1_fwu_set_boot_idx(void)
{
clk_enable(RTCAPB);
+ mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
+ TAMP_BOOT_FWU_INFO_IDX_MSK,
+ (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
+ TAMP_BOOT_FWU_INFO_IDX_MSK);
+ clk_disable(RTCAPB);
+}
+
+uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
+{
+ uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
+ uint32_t try_cnt;
+
+ clk_enable(RTCAPB);
+ try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
+ TAMP_BOOT_FWU_INFO_CNT_OFF;
+
+ assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
+
+ if (try_cnt != 0U) {
+ mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
+ (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
+ }
+ clk_disable(RTCAPB);
+
+ return try_cnt;
+}
+
+void stm32_set_max_fwu_trial_boot_cnt(void)
+{
+ uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
+
+ clk_enable(RTCAPB);
- mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID),
- plat_fwu_get_boot_idx());
+ mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
+ (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
+ TAMP_BOOT_FWU_INFO_CNT_MSK);
clk_disable(RTCAPB);
}
#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */
diff --git a/plat/st/stm32mp1/stm32mp1_stm32image_def.h b/plat/st/stm32mp1/stm32mp1_stm32image_def.h
index 8efa342..6260cb9 100644
--- a/plat/st/stm32mp1/stm32mp1_stm32image_def.h
+++ b/plat/st/stm32mp1/stm32mp1_stm32image_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2021-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,9 +8,14 @@
#define STM32MP1_STM32IMAGE_DEF_H
#ifdef AARCH32_SP_OPTEE
+#if STM32MP15_OPTEE_RSV_SHM
#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */
#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */
#else
+#define STM32MP_DDR_S_SIZE U(0x02000000) /* 32 MB */
+#define STM32MP_DDR_SHMEM_SIZE U(0) /* empty */
+#endif
+#else
#define STM32MP_DDR_S_SIZE U(0)
#define STM32MP_DDR_SHMEM_SIZE U(0)
#endif
diff --git a/plat/st/stm32mp1/stm32mp1_syscfg.c b/plat/st/stm32mp1/stm32mp1_syscfg.c
index 3f34af1..ff79428 100644
--- a/plat/st/stm32mp1/stm32mp1_syscfg.c
+++ b/plat/st/stm32mp1/stm32mp1_syscfg.c
@@ -4,11 +4,16 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+#include <errno.h>
+
#include <common/debug.h>
#include <drivers/clk.h>
#include <drivers/delay_timer.h>
#include <drivers/st/stpmic1.h>
#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <libfdt.h>
#include <platform_def.h>
#include <stm32mp_common.h>
@@ -19,11 +24,24 @@
* SYSCFG REGISTER OFFSET (base relative)
*/
#define SYSCFG_BOOTR 0x00U
+#define SYSCFG_BOOTCR 0x0CU
+#if STM32MP15
#define SYSCFG_IOCTRLSETR 0x18U
#define SYSCFG_ICNR 0x1CU
+#endif
#define SYSCFG_CMPCR 0x20U
#define SYSCFG_CMPENSETR 0x24U
#define SYSCFG_CMPENCLRR 0x28U
+#if STM32MP13
+#define SYSCFG_CMPSD1CR 0x30U
+#define SYSCFG_CMPSD1ENSETR 0x34U
+#define SYSCFG_CMPSD1ENCLRR 0x38U
+#define SYSCFG_CMPSD2CR 0x40U
+#define SYSCFG_CMPSD2ENSETR 0x44U
+#define SYSCFG_CMPSD2ENCLRR 0x48U
+#define SYSCFG_HSLVEN0R 0x50U
+#endif
+#define SYSCFG_IDC 0x380U
#define CMPCR_CMPENSETR_OFFSET 0x4U
#define CMPCR_CMPENCLRR_OFFSET 0x8U
@@ -32,8 +50,16 @@
* SYSCFG_BOOTR Register
*/
#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
+#if STM32MP15
#define SYSCFG_BOOTR_BOOTPD_MASK GENMASK(6, 4)
#define SYSCFG_BOOTR_BOOTPD_SHIFT 4
+#endif
+
+/*
+ * SYSCFG_BOOTCR Register
+ */
+#define SYSCFG_BOOTCR_BMEN BIT(0)
+
/*
* SYSCFG_IOCTRLSETR Register
*/
@@ -65,6 +91,32 @@
*/
#define SYSCFG_CMPENSETR_MPU_EN BIT(0)
+/*
+ * HSLV definitions
+ */
+#define HSLV_IDX_TPIU 0U
+#define HSLV_IDX_QSPI 1U
+#define HSLV_IDX_ETH1 2U
+#define HSLV_IDX_ETH2 3U
+#define HSLV_IDX_SDMMC1 4U
+#define HSLV_IDX_SDMMC2 5U
+#define HSLV_IDX_SPI1 6U
+#define HSLV_IDX_SPI2 7U
+#define HSLV_IDX_SPI3 8U
+#define HSLV_IDX_SPI4 9U
+#define HSLV_IDX_SPI5 10U
+#define HSLV_IDX_LTDC 11U
+#define HSLV_NB_IDX 12U
+
+#define HSLV_KEY 0x1018U
+
+/*
+ * SYSCFG_IDC Register
+ */
+#define SYSCFG_IDC_DEV_ID_MASK GENMASK(11, 0)
+#define SYSCFG_IDC_REV_ID_MASK GENMASK(31, 16)
+#define SYSCFG_IDC_REV_ID_SHIFT 16
+
static void enable_io_comp_cell_finish(uintptr_t cmpcr_off)
{
uint64_t start;
@@ -103,15 +155,108 @@
mmio_setbits_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENCLRR_OFFSET, SYSCFG_CMPENSETR_MPU_EN);
}
+
+#if STM32MP13
+static int get_regu_max_voltage(void *fdt, int sdmmc_node,
+ const char *regu_name, uint32_t *regu_val)
+{
+ int node;
+ const fdt32_t *cuint;
+
+ cuint = fdt_getprop(fdt, sdmmc_node, regu_name, NULL);
+ if (cuint == NULL) {
+ return -ENODEV;
+ }
+
+ node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+ if (node < 0) {
+ return -ENODEV;
+ }
+
+ cuint = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
+ if (cuint == NULL) {
+ return -ENODEV;
+ }
+
+ *regu_val = fdt32_to_cpu(*cuint);
+
+ return 0;
+}
+
+static bool sdmmc_is_low_voltage(uintptr_t sdmmc_base)
+{
+ int ret;
+ int node;
+ void *fdt = NULL;
+ uint32_t regu_max_val;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return false;
+ }
+
+ if (fdt == NULL) {
+ return false;
+ }
+
+ node = dt_match_instance_by_compatible(DT_SDMMC2_COMPAT, sdmmc_base);
+ if (node < 0) {
+ /* No SD or eMMC device on this instance, enable HSLV */
+ return true;
+ }
+
+ ret = get_regu_max_voltage(fdt, node, "vqmmc-supply", ®u_max_val);
+ if ((ret < 0) || (regu_max_val > 1800000U)) {
+ /*
+ * The vqmmc-supply property should always be present for eMMC.
+ * For SD-card, if it is not, then the card only supports 3.3V.
+ */
+ return false;
+ }
+
+ return true;
+}
+
+static void enable_hslv_by_index(uint32_t index)
+{
+ bool apply_hslv;
+
+ assert(index < HSLV_NB_IDX);
+
+ switch (index) {
+ case HSLV_IDX_SDMMC1:
+ apply_hslv = sdmmc_is_low_voltage(STM32MP_SDMMC1_BASE);
+ break;
+ case HSLV_IDX_SDMMC2:
+ apply_hslv = sdmmc_is_low_voltage(STM32MP_SDMMC2_BASE);
+ break;
+ default:
+ apply_hslv = true;
+ break;
+ }
+
+ if (apply_hslv) {
+ mmio_write_32(SYSCFG_BASE + SYSCFG_HSLVEN0R + index * sizeof(uint32_t), HSLV_KEY);
+ }
+}
+#endif
static void enable_high_speed_mode_low_voltage(void)
{
+#if STM32MP13
+ uint32_t idx;
+
+ for (idx = 0U; idx < HSLV_NB_IDX; idx++) {
+ enable_hslv_by_index(idx);
+ }
+#endif
+#if STM32MP15
mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR,
SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
SYSCFG_IOCTRLSETR_HSLVEN_ETH |
SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
SYSCFG_IOCTRLSETR_HSLVEN_SPI);
+#endif
}
static void stm32mp1_syscfg_set_hslv(void)
@@ -165,6 +310,7 @@
void stm32mp1_syscfg_init(void)
{
+#if STM32MP15
uint32_t bootr;
/*
@@ -178,6 +324,7 @@
SYSCFG_BOOTR_BOOT_MASK;
mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK,
bootr << SYSCFG_BOOTR_BOOTPD_SHIFT);
+#endif
stm32mp1_syscfg_set_hslv();
@@ -195,11 +342,22 @@
mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPCR,
SYSCFG_CMPENSETR_MPU_EN);
+#if STM32MP13
+ mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD1CR,
+ SYSCFG_CMPENSETR_MPU_EN);
+ mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD2CR,
+ SYSCFG_CMPENSETR_MPU_EN);
+
+#endif
}
void stm32mp1_syscfg_enable_io_compensation_finish(void)
{
enable_io_comp_cell_finish(SYSCFG_CMPCR);
+#if STM32MP13
+ enable_io_comp_cell_finish(SYSCFG_CMPSD1CR);
+ enable_io_comp_cell_finish(SYSCFG_CMPSD2CR);
+#endif
}
void stm32mp1_syscfg_disable_io_compensation(void)
@@ -213,6 +371,41 @@
* Disable non-secure SYSCFG clock, we assume non-secure is suspended.
*/
disable_io_comp_cell(SYSCFG_CMPCR);
+#if STM32MP13
+ disable_io_comp_cell(SYSCFG_CMPSD1CR);
+ disable_io_comp_cell(SYSCFG_CMPSD2CR);
+#endif
clk_disable(SYSCFG);
}
+
+/*
+ * @brief Get silicon revision from SYSCFG registers.
+ * @retval chip version (REV_ID).
+ */
+uint32_t stm32mp1_syscfg_get_chip_version(void)
+{
+ return (mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) &
+ SYSCFG_IDC_REV_ID_MASK) >> SYSCFG_IDC_REV_ID_SHIFT;
+}
+
+/*
+ * @brief Get device ID from SYSCFG registers.
+ * @retval device ID (DEV_ID).
+ */
+uint32_t stm32mp1_syscfg_get_chip_dev_id(void)
+{
+ return mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & SYSCFG_IDC_DEV_ID_MASK;
+}
+
+#if STM32MP13
+void stm32mp1_syscfg_boot_mode_enable(void)
+{
+ mmio_setbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
+}
+
+void stm32mp1_syscfg_boot_mode_disable(void)
+{
+ mmio_clrbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
+}
+#endif
diff --git a/plat/st/stm32mp1/stm32mp1_usb_dfu.c b/plat/st/stm32mp1/stm32mp1_usb_dfu.c
index 33b12d0..0fe2d24 100644
--- a/plat/st/stm32mp1/stm32mp1_usb_dfu.c
+++ b/plat/st/stm32mp1/stm32mp1_usb_dfu.c
@@ -28,7 +28,12 @@
#define USBD_CONFIGURATION_STRING "DFU Config"
#define USBD_INTERFACE_STRING "DFU Interface"
+#if STM32MP13
+#define USB_DFU_ITF_NUM 2
+#endif
+#if STM32MP15
#define USB_DFU_ITF_NUM 6
+#endif
#define USB_DFU_CONFIG_DESC_SIZ USB_DFU_DESC_SIZ(USB_DFU_ITF_NUM)
@@ -98,11 +103,18 @@
/* Descriptor of DFU interface 0 Alternate setting 0..N */
USBD_DFU_IF_DESC(0),
USBD_DFU_IF_DESC(1),
+#if USB_DFU_ITF_NUM > 2
USBD_DFU_IF_DESC(2),
+#endif
+#if USB_DFU_ITF_NUM > 3
USBD_DFU_IF_DESC(3),
+#endif
+#if USB_DFU_ITF_NUM > 4
USBD_DFU_IF_DESC(4),
+#endif
+#if USB_DFU_ITF_NUM > 5
USBD_DFU_IF_DESC(5),
-
+#endif
/* DFU Functional Descriptor */
0x09, /* blength = 9 Bytes */
DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor */
@@ -115,6 +127,13 @@
};
/* The user strings: one by alternate as defined in USBD_DFU_IF_DESC */
+#if STM32MP13
+const char *const if_desc_string[USB_DFU_ITF_NUM] = {
+ "@SSBL /0x03/1*16Me",
+ "@virtual /0xF1/1*512Ba"
+};
+#endif
+#if STM32MP15
const char *const if_desc_string[USB_DFU_ITF_NUM] = {
"@Partition0 /0x00/1*256Ke",
"@FSBL /0x01/1*1Me",
@@ -123,6 +142,7 @@
"@Partition4 /0x04/1*16Me",
"@virtual /0xF1/1*512Ba"
};
+#endif
/* Buffer to build the unicode string provided to USB device stack */
static uint8_t usb_str_dec[USBD_MAX_STR_DESC_SIZ];
@@ -354,9 +374,11 @@
stm32mp1_usb_init_driver(&usb_core_handle, &pcd_handle,
(uint32_t *)USB_OTG_BASE);
+#if STM32MP15
/* STM32MP15 = keep the configuration from ROM code */
usb_core_handle.ep0_state = USBD_EP0_DATA_IN;
usb_core_handle.dev_state = USBD_STATE_CONFIGURED;
+#endif
/* Update the serial number string descriptor from the unique ID */
update_serial_num_string();
@@ -376,12 +398,22 @@
uint8_t ret;
switch (alt) {
+#if STM32MP13
+ case 0:
+ ret = PHASE_SSBL;
+ break;
+ case 1:
+ ret = PHASE_CMD;
+ break;
+#endif
+#if STM32MP15
case 3:
ret = PHASE_SSBL;
break;
case 5:
ret = PHASE_CMD;
break;
+#endif
default:
ret = PHASE_RESET;
break;
diff --git a/plat/ti/k3/board/j784s4/board.mk b/plat/ti/k3/board/j784s4/board.mk
new file mode 100644
index 0000000..92433ab
--- /dev/null
+++ b/plat/ti/k3/board/j784s4/board.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_BASE ?= 0x9e800000
+$(eval $(call add_define,BL32_BASE))
+
+PRELOADED_BL33_BASE ?= 0x80080000
+$(eval $(call add_define,PRELOADED_BL33_BASE))
+
+K3_HW_CONFIG_BASE ?= 0x82000000
+$(eval $(call add_define,K3_HW_CONFIG_BASE))
+
+# Define sec_proxy usage as the full prioritized communication scheme
+K3_SEC_PROXY_LITE := 0
+$(eval $(call add_define,K3_SEC_PROXY_LITE))
+
+# System coherency is managed in hardware
+USE_COHERENT_MEM := 1
+
+PLAT_INCLUDES += \
+ -Iplat/ti/k3/board/j784s4/include \
diff --git a/plat/ti/k3/board/j784s4/include/board_def.h b/plat/ti/k3/board/j784s4/include/board_def.h
new file mode 100644
index 0000000..c2debc7
--- /dev/null
+++ b/plat/ti/k3/board/j784s4/include/board_def.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BOARD_DEF_H
+#define BOARD_DEF_H
+
+#include <lib/utils_def.h>
+
+/* The ports must be in order and contiguous */
+#define K3_CLUSTER0_CORE_COUNT U(4)
+#define K3_CLUSTER1_CORE_COUNT U(4)
+#define K3_CLUSTER2_CORE_COUNT U(0)
+#define K3_CLUSTER3_CORE_COUNT U(0)
+/*
+ * This RAM will be used for the bootloader including code, bss, and stacks.
+ * It may need to be increased if BL31 grows in size.
+ *
+ * The link addresses are determined by SEC_SRAM_BASE + offset.
+ * When ENABLE_PIE is set, the TF images can be loaded anywhere, so
+ * SEC_SRAM_BASE is really arbitrary.
+ *
+ * When ENABLE_PIE is unset, SEC_SRAM_BASE should be chosen so that
+ * it matches to the physical address where BL31 is loaded, that is,
+ * SEC_SRAM_BASE should be the base address of the RAM region.
+ *
+ * Lets make things explicit by mapping SRAM_BASE to 0x0 since ENABLE_PIE is
+ * defined as default for our platform.
+ */
+#define SEC_SRAM_BASE UL(0x00000000) /* PIE remapped on fly */
+#define SEC_SRAM_SIZE UL(0x00020000) /* 128k */
+
+#define PLAT_MAX_OFF_STATE U(2)
+#define PLAT_MAX_RET_STATE U(1)
+
+#define PLAT_PROC_START_ID U(32)
+
+#define PLAT_PROC_DEVICE_START_ID U(202)
+#define PLAT_CLUSTER_DEVICE_START_ID U(198)
+
+#endif /* BOARD_DEF_H */
diff --git a/plat/ti/k3/board/lite/include/board_def.h b/plat/ti/k3/board/lite/include/board_def.h
index 18b7f42..fd4e5b1 100644
--- a/plat/ti/k3/board/lite/include/board_def.h
+++ b/plat/ti/k3/board/lite/include/board_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -33,7 +33,7 @@
* defined as default for our platform.
*/
#define SEC_SRAM_BASE UL(0x00000000) /* PIE remapped on fly */
-#define SEC_SRAM_SIZE UL(0x0001c000) /* 112k */
+#define SEC_SRAM_SIZE UL(0x00020000) /* 128k */
#define PLAT_MAX_OFF_STATE U(2)
#define PLAT_MAX_RET_STATE U(1)
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index 2c3313c..2cbfa3d 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -2,7 +2,7 @@
* Texas Instruments System Control Interface Driver
* Based on Linux and U-Boot implementation
*
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -1664,6 +1664,57 @@
}
/**
+ * ti_sci_enter_sleep - Command to initiate system transition into suspend.
+ *
+ * @proc_id: Processor ID.
+ * @mode: Low power mode to enter.
+ * @core_resume_addr: Address that core should be
+ * resumed from after low power transition.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_enter_sleep(uint8_t proc_id,
+ uint8_t mode,
+ uint64_t core_resume_addr)
+{
+ struct ti_sci_msg_req_enter_sleep req;
+ struct ti_sci_msg_hdr *hdr;
+ struct k3_sec_proxy_msg tx_message;
+ int ret;
+
+ /* Ensure we have sane transfer size */
+ if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE) {
+ return -ERANGE;
+ }
+
+ hdr = (struct ti_sci_msg_hdr *)&req;
+ hdr->seq = ++message_sequence;
+ hdr->type = TI_SCI_MSG_ENTER_SLEEP;
+ hdr->host = TI_SCI_HOST_ID;
+ /* Setup with NORESPONSE flag to keep response queue clean */
+ hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
+
+ req.processor_id = proc_id;
+ req.mode = mode;
+ req.core_resume_lo = core_resume_addr & TISCI_ADDR_LOW_MASK;
+ req.core_resume_hi = (core_resume_addr & TISCI_ADDR_HIGH_MASK) >>
+ TISCI_ADDR_HIGH_SHIFT;
+
+ tx_message.buf = (uint8_t *)&req;
+ tx_message.len = sizeof(req);
+
+ /* Send message */
+ ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &tx_message);
+ if (ret != 0) {
+ ERROR("Message sending failed (%d)\n", ret);
+ return ret;
+ }
+
+ /* Return without waiting for response */
+ return 0;
+}
+
+/**
* ti_sci_init() - Basic initialization
*
* Return: 0 if all goes well, else appropriate error message
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
index c7b09b3..06944a7 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -2,7 +2,7 @@
* Texas Instruments System Control Interface API
* Based on Linux and U-Boot implementation
*
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -207,6 +207,22 @@
uint32_t status_flags_1_clr_any_wait);
/**
+ * System Low Power Operations
+ *
+ * - ti_sci_enter_sleep - Command to initiate system transition into suspend.
+ * @proc_id: Processor ID.
+ * @mode: Low power mode to enter.
+ * @core_resume_addr: Address that core should be resumed from
+ * after low power transition.
+ *
+ * NOTE: for all these functions, the following are generic in nature:
+ * Returns 0 for successful request, else returns corresponding error message.
+ */
+int ti_sci_enter_sleep(uint8_t proc_id,
+ uint8_t mode,
+ uint64_t core_resume_addr);
+
+/**
* ti_sci_init() - Basic initialization
*
* Return: 0 if all goes good, else appropriate error message.
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index 310bf45..d220612 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -5,7 +5,7 @@
* The system works in a message response protocol
* See: http://processors.wiki.ti.com/index.php/TISCI for details
*
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -28,6 +28,9 @@
#define TI_SCI_MSG_GET_DEVICE_STATE 0x0201
#define TI_SCI_MSG_SET_DEVICE_RESETS 0x0202
+/* Low Power Mode Requests */
+#define TI_SCI_MSG_ENTER_SLEEP 0x0301
+
/* Clock requests */
#define TI_SCI_MSG_SET_CLOCK_STATE 0x0100
#define TI_SCI_MSG_GET_CLOCK_STATE 0x0101
@@ -706,4 +709,26 @@
uint32_t status_flags_1_clr_any_wait;
} __packed;
+/**
+ * struct ti_sci_msg_req_enter_sleep - Request for TI_SCI_MSG_ENTER_SLEEP.
+ *
+ * @hdr Generic Header
+ * @mode Low power mode to enter.
+ * @proc_id Processor id to be restored.
+ * @core_resume_lo Low 32-bits of physical pointer to address for core
+ * to begin execution upon resume.
+ * @core_resume_hi High 32-bits of physical pointer to address for core
+ * to begin execution upon resume.
+ *
+ * This message is to be sent after TI_SCI_MSG_PREPARE_SLEEP is sent from OS
+ * and is what actually triggers entry into the specified low power mode.
+ */
+struct ti_sci_msg_req_enter_sleep {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t mode;
+ uint8_t processor_id;
+ uint32_t core_resume_lo;
+ uint32_t core_resume_hi;
+} __packed;
+
#endif /* TI_SCI_PROTOCOL_H */
diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c
index 1932eaa..0199822 100644
--- a/plat/ti/k3/common/k3_gicv3.c
+++ b/plat/ti/k3/common/k3_gicv3.c
@@ -19,6 +19,11 @@
/* The GICv3 driver only needs to be initialized in EL3 */
uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+#if K3_PM_SYSTEM_SUSPEND
+static gicv3_redist_ctx_t rdist_ctx[PLATFORM_CORE_COUNT];
+static gicv3_dist_ctx_t dist_ctx;
+#endif
+
static const interrupt_prop_t k3_interrupt_props[] = {
PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
@@ -88,3 +93,21 @@
{
gicv3_rdistif_init(plat_my_core_pos());
}
+
+#if K3_PM_SYSTEM_SUSPEND
+void k3_gic_save_context(void)
+{
+ for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+ gicv3_rdistif_save(i, &rdist_ctx[i]);
+ }
+ gicv3_distif_save(&dist_ctx);
+}
+
+void k3_gic_restore_context(void)
+{
+ gicv3_distif_init_restore(&dist_ctx);
+ for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+ gicv3_rdistif_init_restore(i, &rdist_ctx[i]);
+ }
+}
+#endif
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index 0500740..6febbc6 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -234,11 +234,50 @@
return PSCI_E_SUCCESS;
}
+#if K3_PM_SYSTEM_SUSPEND
+static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+ unsigned int core, proc_id;
+
+ core = plat_my_core_pos();
+ proc_id = PLAT_PROC_START_ID + core;
+
+ /* Prevent interrupts from spuriously waking up this cpu */
+ k3_gic_cpuif_disable();
+ k3_gic_save_context();
+
+ k3_pwr_domain_off(target_state);
+
+ ti_sci_enter_sleep(proc_id, 0, k3_sec_entrypoint);
+}
+
+static void k3_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+ k3_gic_restore_context();
+ k3_gic_cpuif_enable();
+}
+
+static void k3_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ unsigned int i;
+
+ /* CPU & cluster off, system in retention */
+ for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) {
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+ }
+}
+#endif
+
static const plat_psci_ops_t k3_plat_psci_ops = {
.cpu_standby = k3_cpu_standby,
.pwr_domain_on = k3_pwr_domain_on,
.pwr_domain_off = k3_pwr_domain_off,
.pwr_domain_on_finish = k3_pwr_domain_on_finish,
+#if K3_PM_SYSTEM_SUSPEND
+ .pwr_domain_suspend = k3_pwr_domain_suspend,
+ .pwr_domain_suspend_finish = k3_pwr_domain_suspend_finish,
+ .get_sys_suspend_power_state = k3_get_sys_suspend_power_state,
+#endif
.system_off = k3_system_off,
.system_reset = k3_system_reset,
.validate_power_state = k3_validate_power_state,
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index ab7366b..e299c30 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -45,6 +45,10 @@
K3_USART_BAUD := 115200
$(eval $(call add_define,K3_USART_BAUD))
+# Enable system suspend modes
+K3_PM_SYSTEM_SUSPEND := 0
+$(eval $(call add_define,K3_PM_SYSTEM_SUSPEND))
+
# Libraries
include lib/xlat_tables_v2/xlat_tables.mk
diff --git a/plat/ti/k3/include/k3_gicv3.h b/plat/ti/k3/include/k3_gicv3.h
index 2329a16..2c68a75 100644
--- a/plat/ti/k3/include/k3_gicv3.h
+++ b/plat/ti/k3/include/k3_gicv3.h
@@ -14,5 +14,7 @@
void k3_gic_cpuif_enable(void);
void k3_gic_cpuif_disable(void);
void k3_gic_pcpu_init(void);
+void k3_gic_save_context(void);
+void k3_gic_restore_context(void);
#endif /* K3_GICV3_H */
diff --git a/plat/xilinx/common/include/ipi.h b/plat/xilinx/common/include/ipi.h
index 483902e..ac76bf0 100644
--- a/plat/xilinx/common/include/ipi.h
+++ b/plat/xilinx/common/include/ipi.h
@@ -47,7 +47,7 @@
********************************************************************/
/* Initialize IPI configuration table */
-void ipi_config_table_init(const struct ipi_config *ipi_table,
+void ipi_config_table_init(const struct ipi_config *ipi_config_table,
uint32_t total_ipi);
/* Validate IPI mailbox access */
diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h
index 66e7933..5ccb774 100644
--- a/plat/xilinx/common/include/plat_startup.h
+++ b/plat/xilinx/common/include/plat_startup.h
@@ -15,8 +15,25 @@
FSBL_HANDOFF_TOO_MANY_PARTS
};
-enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32_image_ep_info,
- entry_point_info_t *bl33_image_ep_info,
+#define FSBL_MAX_PARTITIONS 8U
+
+/* Structure corresponding to each partition entry */
+struct xfsbl_partition {
+ uint64_t entry_point;
+ uint64_t flags;
+};
+
+/* Structure for handoff parameters to ARM Trusted Firmware (ATF) */
+struct xfsbl_atf_handoff_params {
+ uint8_t magic[4];
+ uint32_t num_entries;
+ struct xfsbl_partition partition[FSBL_MAX_PARTITIONS];
+};
+
+#define ATF_HANDOFF_PARAMS_MAX_SIZE sizeof(struct xfsbl_atf_handoff_params)
+
+enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32,
+ entry_point_info_t *bl33,
uint64_t atf_handoff_addr);
#endif /* PLAT_STARTUP_H */
diff --git a/plat/xilinx/common/include/pm_client.h b/plat/xilinx/common/include/pm_client.h
index e91bb8f..eae1d98 100644
--- a/plat/xilinx/common/include/pm_client.h
+++ b/plat/xilinx/common/include/pm_client.h
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,17 +18,16 @@
#include "pm_defs.h"
/* Functions to be implemented by each PU */
-void pm_client_suspend(const struct pm_proc *proc, unsigned int state);
+void pm_client_suspend(const struct pm_proc *proc, uint32_t state);
void pm_client_abort_suspend(void);
void pm_client_wakeup(const struct pm_proc *proc);
/* Global variables to be set in pm_client.c */
extern const struct pm_proc *primary_proc;
-#ifndef VERSAL_PLATFORM
-enum pm_ret_status set_ocm_retention(void);
+#if defined(PLAT_zynqmp)
enum pm_ret_status pm_set_suspend_mode(uint32_t mode);
const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
-#endif
+#endif /* PLAT_zynqmp */
#endif /* PM_CLIENT_H */
diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h
index 0c24a36..06efa4b 100644
--- a/plat/xilinx/common/include/pm_common.h
+++ b/plat/xilinx/common/include/pm_common.h
@@ -48,10 +48,10 @@
*/
struct pm_proc {
const uint32_t node_id;
- const unsigned int pwrdn_mask;
+ const uint32_t pwrdn_mask;
const struct pm_ipi *ipi;
};
-const struct pm_proc *pm_get_proc(unsigned int cpuid);
+const struct pm_proc *pm_get_proc(uint32_t cpuid);
#endif /* PM_COMMON_H */
diff --git a/plat/xilinx/common/include/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h
index 8c7738d..8a15668 100644
--- a/plat/xilinx/common/include/pm_ipi.h
+++ b/plat/xilinx/common/include/pm_ipi.h
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,12 +10,13 @@
#define PM_IPI_H
#include <plat_ipi.h>
+#include <stddef.h>
#include "pm_common.h"
#define IPI_BLOCKING 1
#define IPI_NON_BLOCKING 0
-int pm_ipi_init(const struct pm_proc *proc);
+int32_t pm_ipi_init(const struct pm_proc *proc);
enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
uint32_t payload[PAYLOAD_ARG_CNT]);
@@ -21,8 +24,8 @@
uint32_t payload[PAYLOAD_ARG_CNT]);
enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
uint32_t payload[PAYLOAD_ARG_CNT],
- unsigned int *value, size_t count);
-void pm_ipi_buff_read_callb(unsigned int *value, size_t count);
+ uint32_t *value, size_t count);
+void pm_ipi_buff_read_callb(uint32_t *value, size_t count);
void pm_ipi_irq_enable(const struct pm_proc *proc);
void pm_ipi_irq_clear(const struct pm_proc *proc);
uint32_t pm_ipi_irq_status(const struct pm_proc *proc);
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 0b8020b..318079b 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,7 +18,6 @@
#include <lib/mmio.h>
#include <ipi.h>
-#include <plat_ipi.h>
#include <plat_private.h>
/*********************************************************************
@@ -69,8 +69,9 @@
{
int ret = 1;
- if (remote >= ipi_total || local >= ipi_total)
+ if (remote >= ipi_total || local >= ipi_total) {
ret = 0;
+ }
return ret;
}
@@ -88,12 +89,15 @@
{
int ret = 0;
- if (!is_ipi_mb_within_range(local, remote))
+ if (!is_ipi_mb_within_range(local, remote)) {
ret = -EINVAL;
- else if (IPI_IS_SECURE(local) && !is_secure)
+ } else if (IPI_IS_SECURE(local) && !is_secure) {
ret = -EPERM;
- else if (IPI_IS_SECURE(remote) && !is_secure)
+ } else if (IPI_IS_SECURE(remote) && !is_secure) {
ret = -EPERM;
+ } else {
+ /* To fix the misra 15.7 warning */
+ }
return ret;
}
@@ -141,11 +145,13 @@
uint32_t status;
status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
- if (status & IPI_BIT_MASK(remote))
+ if (status & IPI_BIT_MASK(remote)) {
ret |= IPI_MB_STATUS_SEND_PENDING;
+ }
status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
- if (status & IPI_BIT_MASK(remote))
+ if (status & IPI_BIT_MASK(remote)) {
ret |= IPI_MB_STATUS_RECV_PENDING;
+ }
return ret;
}
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index f531158..cb6aaa5 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -64,13 +64,13 @@
* function with rt_svc_handle signature
*/
uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
- uint64_t x3, uint64_t x4, void *cookie,
+ uint64_t x3, uint64_t x4, const void *cookie,
void *handle, uint64_t flags)
{
- int ret;
+ int32_t ret;
uint32_t ipi_local_id;
uint32_t ipi_remote_id;
- unsigned int is_secure;
+ uint32_t is_secure;
ipi_local_id = x1 & UNSIGNED32_MASK;
ipi_remote_id = x2 & UNSIGNED32_MASK;
@@ -94,7 +94,7 @@
SMC_RET1(handle, 0);
case IPI_MAILBOX_STATUS_ENQUIRY:
{
- int disable_irq;
+ int32_t disable_irq;
disable_irq = (x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) ? 1 : 0;
ret = ipi_mb_enquire_status(ipi_local_id, ipi_remote_id);
@@ -112,7 +112,7 @@
}
case IPI_MAILBOX_ACK:
{
- int enable_irq;
+ int32_t enable_irq;
enable_irq = (x3 & IPI_SMC_ACK_EIRQ_MASK) ? 1 : 0;
ipi_mb_ack(ipi_local_id, ipi_remote_id);
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h
index 10682d8..af13db9 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h
@@ -33,7 +33,7 @@
/* IPI SMC handler */
uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
- uint64_t x3, uint64_t x4, void *cookie, void *handle,
+ uint64_t x3, uint64_t x4, const void *cookie, void *handle,
uint64_t flags);
#endif /* IPI_MAILBOX_SVC_H */
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index f02f41e..de9cf4d 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -24,49 +24,34 @@
* CPU# 5:6 00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3
*/
-#define FSBL_FLAGS_ESTATE_SHIFT 0
-#define FSBL_FLAGS_ESTATE_MASK (1 << FSBL_FLAGS_ESTATE_SHIFT)
-#define FSBL_FLAGS_ESTATE_A64 0
-#define FSBL_FLAGS_ESTATE_A32 1
+#define FSBL_FLAGS_ESTATE_SHIFT 0U
+#define FSBL_FLAGS_ESTATE_MASK (1U << FSBL_FLAGS_ESTATE_SHIFT)
+#define FSBL_FLAGS_ESTATE_A64 0U
+#define FSBL_FLAGS_ESTATE_A32 1U
-#define FSBL_FLAGS_ENDIAN_SHIFT 1
-#define FSBL_FLAGS_ENDIAN_MASK (1 << FSBL_FLAGS_ENDIAN_SHIFT)
-#define FSBL_FLAGS_ENDIAN_LE 0
-#define FSBL_FLAGS_ENDIAN_BE 1
+#define FSBL_FLAGS_ENDIAN_SHIFT 1U
+#define FSBL_FLAGS_ENDIAN_MASK (1U << FSBL_FLAGS_ENDIAN_SHIFT)
+#define FSBL_FLAGS_ENDIAN_LE 0U
+#define FSBL_FLAGS_ENDIAN_BE 1U
-#define FSBL_FLAGS_TZ_SHIFT 2
-#define FSBL_FLAGS_TZ_MASK (1 << FSBL_FLAGS_TZ_SHIFT)
-#define FSBL_FLAGS_NON_SECURE 0
-#define FSBL_FLAGS_SECURE 1
+#define FSBL_FLAGS_TZ_SHIFT 2U
+#define FSBL_FLAGS_TZ_MASK (1U << FSBL_FLAGS_TZ_SHIFT)
+#define FSBL_FLAGS_NON_SECURE 0U
+#define FSBL_FLAGS_SECURE 1U
-#define FSBL_FLAGS_EL_SHIFT 3
-#define FSBL_FLAGS_EL_MASK (3 << FSBL_FLAGS_EL_SHIFT)
-#define FSBL_FLAGS_EL0 0
-#define FSBL_FLAGS_EL1 1
-#define FSBL_FLAGS_EL2 2
-#define FSBL_FLAGS_EL3 3
+#define FSBL_FLAGS_EL_SHIFT 3U
+#define FSBL_FLAGS_EL_MASK (3U << FSBL_FLAGS_EL_SHIFT)
+#define FSBL_FLAGS_EL0 0U
+#define FSBL_FLAGS_EL1 1U
+#define FSBL_FLAGS_EL2 2U
+#define FSBL_FLAGS_EL3 3U
-#define FSBL_FLAGS_CPU_SHIFT 5
-#define FSBL_FLAGS_CPU_MASK (3 << FSBL_FLAGS_CPU_SHIFT)
-#define FSBL_FLAGS_A53_0 0
-#define FSBL_FLAGS_A53_1 1
-#define FSBL_FLAGS_A53_2 2
-#define FSBL_FLAGS_A53_3 3
-
-#define FSBL_MAX_PARTITIONS 8
-
-/* Structure corresponding to each partition entry */
-struct xfsbl_partition {
- uint64_t entry_point;
- uint64_t flags;
-};
-
-/* Structure for handoff parameters to ARM Trusted Firmware (ATF) */
-struct xfsbl_atf_handoff_params {
- uint8_t magic[4];
- uint32_t num_entries;
- struct xfsbl_partition partition[FSBL_MAX_PARTITIONS];
-};
+#define FSBL_FLAGS_CPU_SHIFT 5U
+#define FSBL_FLAGS_CPU_MASK (3U << FSBL_FLAGS_CPU_SHIFT)
+#define FSBL_FLAGS_A53_0 0U
+#define FSBL_FLAGS_A53_1 1U
+#define FSBL_FLAGS_A53_2 2U
+#define FSBL_FLAGS_A53_3 3U
/**
* @partition: Pointer to partition struct
@@ -75,7 +60,7 @@
*
* Return: FSBL_FLAGS_A53_0, FSBL_FLAGS_A53_1, FSBL_FLAGS_A53_2 or FSBL_FLAGS_A53_3
*/
-static int get_fsbl_cpu(const struct xfsbl_partition *partition)
+static int32_t get_fsbl_cpu(const struct xfsbl_partition *partition)
{
uint64_t flags = partition->flags & FSBL_FLAGS_CPU_MASK;
@@ -89,7 +74,7 @@
*
* Return: FSBL_FLAGS_EL0, FSBL_FLAGS_EL1, FSBL_FLAGS_EL2 or FSBL_FLAGS_EL3
*/
-static int get_fsbl_el(const struct xfsbl_partition *partition)
+static int32_t get_fsbl_el(const struct xfsbl_partition *partition)
{
uint64_t flags = partition->flags & FSBL_FLAGS_EL_MASK;
@@ -103,7 +88,7 @@
*
* Return: FSBL_FLAGS_NON_SECURE or FSBL_FLAGS_SECURE
*/
-static int get_fsbl_ss(const struct xfsbl_partition *partition)
+static int32_t get_fsbl_ss(const struct xfsbl_partition *partition)
{
uint64_t flags = partition->flags & FSBL_FLAGS_TZ_MASK;
@@ -117,16 +102,17 @@
*
* Return: SPSR_E_LITTLE or SPSR_E_BIG
*/
-static int get_fsbl_endian(const struct xfsbl_partition *partition)
+static int32_t get_fsbl_endian(const struct xfsbl_partition *partition)
{
uint64_t flags = partition->flags & FSBL_FLAGS_ENDIAN_MASK;
flags >>= FSBL_FLAGS_ENDIAN_SHIFT;
- if (flags == FSBL_FLAGS_ENDIAN_BE)
+ if (flags == FSBL_FLAGS_ENDIAN_BE) {
return SPSR_E_BIG;
- else
+ } else {
return SPSR_E_LITTLE;
+ }
}
/**
@@ -136,7 +122,7 @@
*
* Return: FSBL_FLAGS_ESTATE_A32 or FSBL_FLAGS_ESTATE_A64
*/
-static int get_fsbl_estate(const struct xfsbl_partition *partition)
+static int32_t get_fsbl_estate(const struct xfsbl_partition *partition)
{
uint64_t flags = partition->flags & FSBL_FLAGS_ESTATE_MASK;
@@ -160,8 +146,6 @@
uint64_t atf_handoff_addr)
{
const struct xfsbl_atf_handoff_params *ATFHandoffParams;
- assert((atf_handoff_addr < BL31_BASE) ||
- (atf_handoff_addr > (uint64_t)&__BL31_END__));
if (!atf_handoff_addr) {
WARN("BL31: No ATF handoff structure passed\n");
return FSBL_HANDOFF_NO_STRUCT;
@@ -192,8 +176,8 @@
*/
for (size_t i = 0; i < ATFHandoffParams->num_entries; i++) {
entry_point_info_t *image;
- int target_estate, target_secure;
- int target_cpu, target_endianness, target_el;
+ int32_t target_estate, target_secure, target_cpu;
+ uint32_t target_endianness, target_el;
VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i,
ATFHandoffParams->partition[i].entry_point,
@@ -226,30 +210,33 @@
if (target_secure == FSBL_FLAGS_SECURE) {
image = bl32;
- if (target_estate == FSBL_FLAGS_ESTATE_A32)
+ if (target_estate == FSBL_FLAGS_ESTATE_A32) {
bl32->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
target_endianness,
DISABLE_ALL_EXCEPTIONS);
- else
+ } else {
bl32->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
+ }
} else {
image = bl33;
if (target_estate == FSBL_FLAGS_ESTATE_A32) {
- if (target_el == FSBL_FLAGS_EL2)
+ if (target_el == FSBL_FLAGS_EL2) {
target_el = MODE32_hyp;
- else
+ } else {
target_el = MODE32_sys;
+ }
bl33->spsr = SPSR_MODE32(target_el, SPSR_T_ARM,
target_endianness,
DISABLE_ALL_EXCEPTIONS);
} else {
- if (target_el == FSBL_FLAGS_EL2)
+ if (target_el == FSBL_FLAGS_EL2) {
target_el = MODE_EL2;
- else
+ } else {
target_el = MODE_EL1;
+ }
bl33->spsr = SPSR_64(target_el, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
@@ -262,10 +249,11 @@
target_el);
image->pc = ATFHandoffParams->partition[i].entry_point;
- if (target_endianness == SPSR_E_BIG)
+ if (target_endianness == SPSR_E_BIG) {
EP_SET_EE(image->h.attr, EP_EE_BIG);
- else
+ } else {
EP_SET_EE(image->h.attr, EP_EE_LITTLE);
+ }
}
return FSBL_HANDOFF_SUCCESS;
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 03a7278..9c9fd62 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +15,7 @@
#include <plat_private.h>
#include <plat/common/platform.h>
+#include "pm_defs.h"
#include "pm_ipi.h"
#define ERROR_CODE_MASK 0xFFFFU
@@ -30,7 +33,7 @@
*
* Called from pm_setup initialization function
*/
-int pm_ipi_init(const struct pm_proc *proc)
+int32_t pm_ipi_init(const struct pm_proc *proc)
{
bakery_lock_init(&pm_secure_lock);
ipi_mb_open(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
@@ -131,12 +134,12 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
- unsigned int *value, size_t count)
+ uint32_t *value, size_t count)
{
size_t i;
#if IPI_CRC_CHECK
size_t j;
- unsigned int response_payload[PAYLOAD_ARG_CNT];
+ uint32_t response_payload[PAYLOAD_ARG_CNT];
#endif
uintptr_t buffer_base = proc->ipi->buffer_base +
IPI_BUFFER_TARGET_REMOTE_OFFSET +
@@ -154,14 +157,16 @@
value++;
}
#if IPI_CRC_CHECK
- for (j = 0; j < PAYLOAD_ARG_CNT; j++)
+ for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
response_payload[j] = mmio_read_32(buffer_base +
(j * PAYLOAD_ARG_SIZE));
+ }
if (response_payload[PAYLOAD_CRC_POS] !=
- calculate_crc(response_payload, IPI_W0_TO_W6_SIZE))
+ calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
NOTICE("ERROR in CRC response payload value:0x%x\n",
response_payload[PAYLOAD_CRC_POS]);
+ }
#endif
return mmio_read_32(buffer_base);
@@ -175,7 +180,7 @@
*
* @return Returns status, either success or error+reason
*/
-void pm_ipi_buff_read_callb(unsigned int *value, size_t count)
+void pm_ipi_buff_read_callb(uint32_t *value, size_t count)
{
size_t i;
#if IPI_CRC_CHECK
@@ -186,22 +191,25 @@
IPI_BUFFER_TARGET_LOCAL_OFFSET +
IPI_BUFFER_REQ_OFFSET;
- if (count > IPI_BUFFER_MAX_WORDS)
+ if (count > IPI_BUFFER_MAX_WORDS) {
count = IPI_BUFFER_MAX_WORDS;
+ }
for (i = 0; i <= count; i++) {
*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
value++;
}
#if IPI_CRC_CHECK
- for (j = 0; j < PAYLOAD_ARG_CNT; j++)
+ for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
response_payload[j] = mmio_read_32(buffer_base +
(j * PAYLOAD_ARG_SIZE));
+ }
if (response_payload[PAYLOAD_CRC_POS] !=
- calculate_crc(response_payload, IPI_W0_TO_W6_SIZE))
+ calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
NOTICE("ERROR in CRC response payload value:0x%x\n",
response_payload[PAYLOAD_CRC_POS]);
+ }
#endif
}
@@ -219,15 +227,16 @@
*/
enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
uint32_t payload[PAYLOAD_ARG_CNT],
- unsigned int *value, size_t count)
+ uint32_t *value, size_t count)
{
enum pm_ret_status ret;
bakery_lock_get(&pm_secure_lock);
ret = pm_ipi_send_common(proc, payload, IPI_BLOCKING);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
goto unlock;
+ }
ret = ERROR_CODE_MASK & (pm_ipi_buff_read(proc, value, count));
@@ -249,18 +258,19 @@
uint32_t pm_ipi_irq_status(const struct pm_proc *proc)
{
- int ret;
+ int32_t ret;
ret = ipi_mb_enquire_status(proc->ipi->local_ipi_id,
proc->ipi->remote_ipi_id);
- if (ret & IPI_MB_STATUS_RECV_PENDING)
+ if (ret & IPI_MB_STATUS_RECV_PENDING) {
return 1;
- else
+ } else {
return 0;
+ }
}
#if IPI_CRC_CHECK
-uint32_t calculate_crc(uint32_t *payload, uint32_t bufsize)
+uint32_t calculate_crc(uint32_t payload[PAYLOAD_ARG_CNT], uint32_t bufsize)
{
uint32_t crcinit = CRC_INIT_VALUE;
uint32_t order = CRC_ORDER;
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index 897ed59..f55cde9 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -47,7 +47,7 @@
generic_delay_timer_init();
}
-unsigned int plat_get_syscnt_freq2(void)
+uint32_t plat_get_syscnt_freq2(void)
{
return VERSAL_CPU_CLOCK;
}
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 78bfc29..9b36208 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,6 +22,9 @@
#include <versal_def.h>
#include <plat_private.h>
#include <plat_startup.h>
+#include <pm_ipi.h>
+#include "pm_client.h"
+#include "pm_api_sys.h"
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
@@ -63,23 +68,26 @@
u_register_t arg2, u_register_t arg3)
{
uint64_t atf_handoff_addr;
+ uint32_t payload[PAYLOAD_ARG_CNT], max_size = ATF_HANDOFF_PARAMS_MAX_SIZE;
+ enum pm_ret_status ret_status;
+ uint64_t addr[ATF_HANDOFF_PARAMS_MAX_SIZE];
if (VERSAL_CONSOLE_IS(pl011) || (VERSAL_CONSOLE_IS(pl011_1))) {
static console_t versal_runtime_console;
/* Initialize the console to provide early debug support */
- int rc = console_pl011_register((unsigned long)VERSAL_UART_BASE,
- (unsigned int)VERSAL_UART_CLOCK,
- (unsigned int)VERSAL_UART_BAUDRATE,
+ int32_t rc = console_pl011_register((uintptr_t)VERSAL_UART_BASE,
+ (uint32_t)VERSAL_UART_CLOCK,
+ (uint32_t)VERSAL_UART_BAUDRATE,
&versal_runtime_console);
if (rc == 0) {
panic();
}
- console_set_scope(&versal_runtime_console, (unsigned int)(CONSOLE_FLAG_BOOT |
+ console_set_scope(&versal_runtime_console, (uint32_t)(CONSOLE_FLAG_BOOT |
CONSOLE_FLAG_RUNTIME));
} else if (VERSAL_CONSOLE_IS(dcc)) {
/* Initialize the dcc console for debug */
- int rc = console_dcc_register();
+ int32_t rc = console_dcc_register();
if (rc == 0) {
panic();
}
@@ -106,7 +114,17 @@
SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
- atf_handoff_addr = mmio_read_32(PMC_GLOBAL_GLOB_GEN_STORAGE4);
+ PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, 1, PM_LOAD_GET_HANDOFF_PARAMS,
+ (uintptr_t)addr >> 32U, (uintptr_t)addr, max_size);
+ ret_status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ if (ret_status == PM_RET_SUCCESS) {
+ INFO("BL31: GET_HANDOFF_PARAMS call success=%d\n", ret_status);
+ atf_handoff_addr = (uintptr_t)&addr;
+ } else {
+ ERROR("BL31: GET_HANDOFF_PARAMS Failed, read atf_handoff_addr from reg\n");
+ atf_handoff_addr = mmio_read_32(PMC_GLOBAL_GLOB_GEN_STORAGE4);
+ }
+
enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info,
&bl33_image_ep_info,
atf_handoff_addr);
@@ -124,16 +142,29 @@
NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
}
-static interrupt_type_handler_t type_el3_interrupt_handler;
+static versal_intr_info_type_el3_t type_el3_interrupt_table[MAX_INTR_EL3];
int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
{
- /* Validate 'handler'*/
- if (handler == NULL) {
+ static uint32_t index;
+ uint32_t i;
+
+ /* Validate 'handler' and 'id' parameters */
+ if (handler == NULL || index >= MAX_INTR_EL3) {
return -EINVAL;
}
+ /* Check if a handler has already been registered */
+ for (i = 0; i < index; i++) {
+ if (id == type_el3_interrupt_table[i].id) {
+ return -EALREADY;
+ }
+ }
+
- type_el3_interrupt_handler = handler;
+ type_el3_interrupt_table[index].id = id;
+ type_el3_interrupt_table[index].handler = handler;
+
+ index++;
return 0;
}
@@ -142,16 +173,17 @@
void *handle, void *cookie)
{
uint32_t intr_id;
- interrupt_type_handler_t handler;
+ uint32_t i;
+ interrupt_type_handler_t handler = NULL;
intr_id = plat_ic_get_pending_interrupt_id();
- /* Currently we support one interrupt */
- if (intr_id != PLAT_VERSAL_IPI_IRQ) {
- WARN("Unexpected interrupt call: 0x%x\n", intr_id);
- return 0;
+
+ for (i = 0; i < MAX_INTR_EL3; i++) {
+ if (intr_id == type_el3_interrupt_table[i].id) {
+ handler = type_el3_interrupt_table[i].handler;
+ }
}
- handler = type_el3_interrupt_handler;
if (handler != NULL) {
return handler(intr_id, flags, handle, cookie);
}
diff --git a/plat/xilinx/versal/include/plat_pm_common.h b/plat/xilinx/versal/include/plat_pm_common.h
index 22c9d11..fb4812d 100644
--- a/plat/xilinx/versal/include/plat_pm_common.h
+++ b/plat/xilinx/versal/include/plat_pm_common.h
@@ -19,8 +19,8 @@
#define NON_SECURE_FLAG 1U
#define SECURE_FLAG 0U
-#define VERSAL_TZ_VERSION_MAJOR 1
-#define VERSAL_TZ_VERSION_MINOR 0
-#define VERSAL_TZ_VERSION ((VERSAL_TZ_VERSION_MAJOR << 16) | \
+#define VERSAL_TZ_VERSION_MAJOR 1U
+#define VERSAL_TZ_VERSION_MINOR 0U
+#define VERSAL_TZ_VERSION ((VERSAL_TZ_VERSION_MAJOR << 16U) | \
VERSAL_TZ_VERSION_MINOR)
#endif /* PLAT_PM_COMMON_H */
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index d12d13a..818797d 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +12,11 @@
#include <lib/xlat_tables/xlat_tables.h>
#include <bl31/interrupt_mgmt.h>
+typedef struct versal_intr_info_type_el3 {
+ uint32_t id;
+ interrupt_type_handler_t handler;
+} versal_intr_info_type_el3_t;
+
void versal_config_setup(void);
const mmap_region_t *plat_versal_get_mmap(void);
@@ -22,11 +29,11 @@
void plat_versal_gic_save(void);
void plat_versal_gic_resume(void);
-unsigned int versal_calc_core_pos(u_register_t mpidr);
+uint32_t versal_calc_core_pos(u_register_t mpidr);
/*
* Register handler to specific GIC entrance
* for INTR_TYPE_EL3 type of interrupt
*/
-int request_intr_type_el3(uint32_t irq, interrupt_type_handler_t fiq_handler);
+int32_t request_intr_type_el3(uint32_t irq, interrupt_type_handler_t fiq_handler);
#endif /* PLAT_PRIVATE_H */
diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index 83e5083..6d95fdc 100644
--- a/plat/xilinx/versal/include/platform_def.h
+++ b/plat/xilinx/versal/include/platform_def.h
@@ -15,7 +15,7 @@
******************************************************************************/
/* Size of cacheable stacks */
-#define PLATFORM_STACK_SIZE 0x440
+#define PLATFORM_STACK_SIZE U(0x440)
#define PLATFORM_CORE_COUNT U(2)
#define PLAT_MAX_PWR_LVL U(1)
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index 9372954..60431a5 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -1,5 +1,7 @@
/*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +12,8 @@
#include <plat/arm/common/smccc_def.h>
#include <plat/common/common_def.h>
+/* number of interrupt handlers. increase as required */
+#define MAX_INTR_EL3 2
/* List all consoles */
#define VERSAL_CONSOLE_ID_pl011 1
#define VERSAL_CONSOLE_ID_pl011_0 1
@@ -20,6 +24,8 @@
/* List all supported platforms */
#define VERSAL_PLATFORM_ID_versal_virt 1
+#define VERSAL_PLATFORM_ID_spp_itr6 2
+#define VERSAL_PLATFORM_ID_emu_itr6 3
#define VERSAL_PLATFORM_ID_silicon 4
#define VERSAL_PLATFORM_IS(con) (VERSAL_PLATFORM_ID_ ## con == VERSAL_PLATFORM)
@@ -35,20 +41,6 @@
#define DEVICE1_BASE 0xF9000000
#define DEVICE1_SIZE 0x00800000
-/* CRL */
-#define VERSAL_CRL 0xFF5E0000
-#define VERSAL_CRL_TIMESTAMP_REF_CTRL (VERSAL_CRL + 0x14C)
-#define VERSAL_CRL_RST_TIMESTAMP_OFFSET (VERSAL_CRL + 0x348)
-
-#define VERSAL_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT (1 << 25)
-
-/* IOU SCNTRS */
-#define VERSAL_IOU_SCNTRS 0xFF140000
-#define VERSAL_IOU_SCNTRS_COUNTER_CONTROL_REG (VERSAL_IOU_SCNTRS + 0x0)
-#define VERSAL_IOU_SCNTRS_BASE_FREQ (VERSAL_IOU_SCNTRS + 0x20)
-
-#define VERSAL_IOU_SCNTRS_CONTROL_EN 1
-
/*******************************************************************************
* IRQ constants
******************************************************************************/
@@ -92,6 +84,16 @@
# define VERSAL_UART_CLOCK 100000000
# define VERSAL_UART_BAUDRATE 115200
# define VERSAL_CPU_CLOCK 100000000
+#elif VERSAL_PLATFORM_IS(spp_itr6)
+# define PLATFORM_NAME "SPP ITR6"
+# define VERSAL_UART_CLOCK 25000000
+# define VERSAL_UART_BAUDRATE 115200
+# define VERSAL_CPU_CLOCK 2720000
+#elif VERSAL_PLATFORM_IS(emu_itr6)
+# define PLATFORM_NAME "EMU ITR6"
+# define VERSAL_UART_CLOCK 212000
+# define VERSAL_UART_BAUDRATE 9600
+# define VERSAL_CPU_CLOCK 212000
#endif
/* Access control register defines */
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index eb05e58..6787f31 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -19,9 +19,9 @@
static uintptr_t versal_sec_entry;
-static int versal_pwr_domain_on(u_register_t mpidr)
+static int32_t versal_pwr_domain_on(u_register_t mpidr)
{
- int cpu_id = plat_core_pos_by_mpidr(mpidr);
+ int32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
const struct pm_proc *proc;
VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
@@ -30,7 +30,7 @@
return PSCI_E_INTERN_FAIL;
}
- proc = pm_get_proc((unsigned int)cpu_id);
+ proc = pm_get_proc((uint32_t)cpu_id);
/* Send request to PMC to wake up selected ACPU core */
(void)pm_req_wakeup(proc->node_id, (versal_sec_entry & 0xFFFFFFFFU) | 0x1U,
@@ -50,8 +50,8 @@
*/
static void versal_pwr_domain_suspend(const psci_power_state_t *target_state)
{
- unsigned int state;
- unsigned int cpu_id = plat_my_core_pos();
+ uint32_t state;
+ uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -88,7 +88,7 @@
static void versal_pwr_domain_suspend_finish(
const psci_power_state_t *target_state)
{
- unsigned int cpu_id = plat_my_core_pos();
+ uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -156,7 +156,7 @@
*/
static void versal_pwr_domain_off(const psci_power_state_t *target_state)
{
- unsigned int cpu_id = plat_my_core_pos();
+ uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -188,12 +188,12 @@
*
* @return Returns status, either success or reason
*/
-static int versal_validate_power_state(unsigned int power_state,
+static int32_t versal_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state)
{
VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
- unsigned int pstate = psci_get_pstate_type(power_state);
+ uint32_t pstate = psci_get_pstate_type(power_state);
assert(req_state);
@@ -238,7 +238,7 @@
/*******************************************************************************
* Export the platform specific power ops.
******************************************************************************/
-int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+int32_t plat_setup_psci_ops(uintptr_t sec_entrypoint,
const struct plat_psci_ops **psci_ops)
{
versal_sec_entry = sec_entrypoint;
diff --git a/plat/xilinx/versal/plat_topology.c b/plat/xilinx/versal/plat_topology.c
index 66d4fae..6a94544 100644
--- a/plat/xilinx/versal/plat_topology.c
+++ b/plat/xilinx/versal/plat_topology.c
@@ -6,9 +6,9 @@
#include <platform_def.h>
-static const unsigned char plat_power_domain_tree_desc[] = {1, PLATFORM_CORE_COUNT};
+static const uint8_t plat_power_domain_tree_desc[] = {1, PLATFORM_CORE_COUNT};
-const unsigned char *plat_get_power_domain_tree_desc(void)
+const uint8_t *plat_get_power_domain_tree_desc(void)
{
return plat_power_domain_tree_desc;
}
diff --git a/plat/xilinx/versal/plat_versal.c b/plat/xilinx/versal/plat_versal.c
index 54c35b6..132c7b7 100644
--- a/plat/xilinx/versal/plat_versal.c
+++ b/plat/xilinx/versal/plat_versal.c
@@ -7,7 +7,7 @@
#include <plat_private.h>
#include <plat/common/platform.h>
-int plat_core_pos_by_mpidr(u_register_t mpidr)
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
{
if ((mpidr & MPIDR_CLUSTER_MASK) != 0U) {
return -1;
@@ -17,5 +17,5 @@
return -1;
}
- return (int)versal_calc_core_pos(mpidr);
+ return (int32_t)versal_calc_core_pos(mpidr);
}
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index 534d910..ecd8d08 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,93 +19,46 @@
#include "pm_svc_main.h"
#include "../drivers/arm/gic/v3/gicv3_private.h"
-/*********************************************************************
- * Target module IDs macros
- ********************************************************************/
-#define LIBPM_MODULE_ID 0x2U
-#define LOADER_MODULE_ID 0x7U
-
-#define MODE 0x80000000U
/* default shutdown/reboot scope is system(2) */
-static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
+static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
/**
* pm_get_shutdown_scope() - Get the currently set shutdown scope
*
* @return Shutdown scope value
*/
-unsigned int pm_get_shutdown_scope(void)
+uint32_t pm_get_shutdown_scope(void)
{
return pm_shutdown_scope;
}
-/**
- * Assigning of argument values into array elements.
- */
-#define PM_PACK_PAYLOAD1(pl, mid, flag, arg0) { \
- pl[0] = (uint32_t)(((uint32_t)(arg0) & 0xFFU) | ((mid) << 8U) | ((flag) << 24U)); \
-}
-
-#define PM_PACK_PAYLOAD2(pl, mid, flag, arg0, arg1) { \
- pl[1] = (uint32_t)(arg1); \
- PM_PACK_PAYLOAD1(pl, (mid), (flag), (arg0)); \
-}
-
-#define PM_PACK_PAYLOAD3(pl, mid, flag, arg0, arg1, arg2) { \
- pl[2] = (uint32_t)(arg2); \
- PM_PACK_PAYLOAD2(pl, (mid), (flag), (arg0), (arg1)); \
-}
-
-#define PM_PACK_PAYLOAD4(pl, mid, flag, arg0, arg1, arg2, arg3) { \
- pl[3] = (uint32_t)(arg3); \
- PM_PACK_PAYLOAD3(pl, (mid), (flag), (arg0), (arg1), (arg2)); \
-}
-
-#define PM_PACK_PAYLOAD5(pl, mid, flag, arg0, arg1, arg2, arg3, arg4) { \
- pl[4] = (uint32_t)(arg4); \
- PM_PACK_PAYLOAD4(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3)); \
-}
-
-#define PM_PACK_PAYLOAD6(pl, mid, flag, arg0, arg1, arg2, arg3, arg4, arg5) { \
- pl[5] = (uint32_t)(arg5); \
- PM_PACK_PAYLOAD5(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4)); \
-}
-
/* PM API functions */
/**
- * pm_get_api_version() - Get version number of PMC PM firmware
- * @version Returns 32-bit version number of PMC Power Management Firmware
+ * pm_handle_eemi_call() - PM call for processor to send eemi payload
* @flag 0 - Call from secure source
* 1 - Call from non-secure source
+ * @x0 to x5 Arguments received per SMC64 standard
+ * @result Payload received from firmware
*
- * @return Returns status, either success or error+reason
+ * @return PM_RET_SUCCESS on success or error code
*/
-enum pm_ret_status pm_get_api_version(unsigned int *version, uint32_t flag)
+enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
+ uint32_t x2, uint32_t x3, uint32_t x4,
+ uint32_t x5, uint64_t *result)
{
- uint32_t payload[PAYLOAD_ARG_CNT];
+ uint32_t payload[PAYLOAD_ARG_CNT] = {0};
+ uint32_t module_id;
- /* Send request to the PMC */
- PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_API_VERSION);
- return pm_ipi_send_sync(primary_proc, payload, version, 1);
-}
+ module_id = (x0 & MODULE_ID_MASK) >> 8U;
-/**
- * pm_init_finalize() - Call to notify PMC PM firmware that master has power
- * management enabled and that it has finished its
- * initialization
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Status returned by the PMU firmware
- */
-enum pm_ret_status pm_init_finalize(uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
+ //default module id is for LIBPM
+ if (module_id == 0) {
+ module_id = LIBPM_MODULE_ID;
+ }
- /* Send request to the PMU */
- PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_INIT_FINALIZE);
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
+ return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
}
/**
@@ -122,12 +76,12 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_self_suspend(uint32_t nid,
- unsigned int latency,
- unsigned int state,
+ uint32_t latency,
+ uint32_t state,
uintptr_t address, uint32_t flag)
{
uint32_t payload[PAYLOAD_ARG_CNT];
- unsigned int cpuid = plat_my_core_pos();
+ uint32_t cpuid = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpuid);
if (proc == NULL) {
@@ -189,7 +143,7 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack,
- unsigned int latency, unsigned int state,
+ uint32_t latency, uint32_t state,
uint32_t flag)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -235,142 +189,16 @@
}
/**
- * pm_request_device() - Request a device
- * @device_id Device ID
- * @capabilities Requested capabilities for the device
- * @qos Required Quality of Service
- * @ack Flag to specify whether acknowledge requested
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
- uint32_t qos, uint32_t ack, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQUEST_DEVICE,
- device_id, capabilities, qos, ack);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_release_device() - Release a device
- * @device_id Device ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_release_device(uint32_t device_id, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RELEASE_DEVICE,
- device_id);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_set_requirement() - Set requirement for the device
- * @device_id Device ID
- * @capabilities Requested capabilities for the device
- * @latency Requested maximum latency
- * @qos Required Quality of Service
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
- uint32_t latency, uint32_t qos,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_SET_REQUIREMENT,
- device_id, capabilities, latency, qos);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_get_device_status() - Get device's status
- * @device_id Device ID
- * @response Buffer to store device status response
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_GET_DEVICE_STATUS,
- device_id);
-
- return pm_ipi_send_sync(primary_proc, payload, response, 3);
-}
-
-/**
- * pm_reset_assert() - Assert/De-assert reset
- * @reset Reset ID
- * @assert Assert (1) or de-assert (0)
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT, reset,
- assert);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_reset_get_status() - Get current status of a reset line
- * @reset Reset ID
- * @status Returns current status of selected reset ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT,
- reset);
-
- return pm_ipi_send_sync(primary_proc, payload, status, 1);
-}
-
-/**
* pm_get_callbackdata() - Read from IPI response buffer
* @data - array of PAYLOAD_ARG_CNT elements
* @flag - 0 - Call from secure source
* 1 - Call from non-secure source
+ * @ack - 0 - Do not ack IPI after reading payload
+ * 1 - Ack IPI after reading payload
*
* Read value from ipi buffer response buffer.
*/
-void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag)
+void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack)
{
/* Return if interrupt is not from PMU */
if (pm_ipi_irq_status(primary_proc) == 0) {
@@ -378,298 +206,19 @@
}
pm_ipi_buff_read_callb(data, count);
- pm_ipi_irq_clear(primary_proc);
-}
-
-/**
- * pm_pinctrl_request() - Request a pin
- * @pin Pin ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_request(uint32_t pin, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_REQUEST,
- pin);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_release() - Release a pin
- * @pin Pin ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_release(uint32_t pin, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_RELEASE,
- pin);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_set_function() - Set pin function
- * @pin Pin ID
- * @function Function ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
- PM_PINCTRL_SET_FUNCTION, pin, function)
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_get_function() - Get function set on the pin
- * @pin Pin ID
- * @function Function set on the pin
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
- PM_PINCTRL_SET_FUNCTION, pin);
-
- return pm_ipi_send_sync(primary_proc, payload, function, 1);
-}
-
-/**
- * pm_pinctrl_set_pin_param() - Set configuration parameter for the pin
- * @pin Pin ID
- * @param Parameter ID
- * @value Parameter value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
- uint32_t value, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag,
- PM_PINCTRL_CONFIG_PARAM_SET, pin, param, value);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pinctrl_get_pin_param() - Get configuration parameter value for the pin
- * @pin Pin ID
- * @param Parameter ID
- * @value Buffer to store parameter value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
- uint32_t *value, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
- PM_PINCTRL_CONFIG_PARAM_GET, pin, param);
- return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-/**
- * pm_clock_enable() - Enable the clock
- * @clk_id Clock ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_enable(uint32_t clk_id, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_ENABLE,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_disable() - Disable the clock
- * @clk_id Clock ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_disable(uint32_t clk_id, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_DISABLE,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_get_state() - Get clock status
- * @clk_id Clock ID
- * @state: Buffer to store clock status (1: Enabled, 0:Disabled)
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETSTATE,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, state, 1);
-}
-
-/**
- * pm_clock_set_divider() - Set divider for the clock
- * @clk_id Clock ID
- * @divider Divider value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETDIVIDER,
- clk_id, divider);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_clock_get_divider() - Get divider value for the clock
- * @clk_id Clock ID
- * @divider: Buffer to store clock divider value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETDIVIDER,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, divider, 1);
-}
-
-/**
- * pm_clock_set_parent() - Set parent for the clock
- * @clk_id Clock ID
- * @parent Parent ID
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETPARENT,
- clk_id, parent);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+ if (ack != 0U) {
+ pm_ipi_irq_clear(primary_proc);
+ }
}
/**
- * pm_clock_get_parent() - Get parent value for the clock
- * @clk_id Clock ID
- * @parent: Buffer to store clock parent value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
+ * pm_pll_set_param() - Set PLL parameter
*
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETPARENT,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, parent, 1);
-}
-/**
- * pm_clock_get_rate() - Get the rate value for the clock
- * @clk_id Clock ID
- * @rate: Buffer to store clock rate value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
*
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETRATE,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, clk_rate, 2);
-}
-
-/**
- * pm_pll_set_param() - Set PLL parameter
* @clk_id PLL clock ID
* @param PLL parameter ID
* @value Value to set for PLL parameter
@@ -692,6 +241,11 @@
/**
* pm_pll_get_param() - Get PLL parameter value
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
* @clk_id PLL clock ID
* @param PLL parameter ID
* @value: Buffer to store PLL parameter value
@@ -714,6 +268,11 @@
/**
* pm_pll_set_mode() - Set PLL mode
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
* @clk_id PLL clock ID
* @mode PLL mode
* @flag 0 - Call from secure source
@@ -735,6 +294,11 @@
/**
* pm_pll_get_mode() - Get PLL mode
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
* @clk_id PLL clock ID
* @mode: Buffer to store PLL mode
* @flag 0 - Call from secure source
@@ -808,22 +372,28 @@
}
/**
-* pm_query_data() - PM API for querying firmware data
-* @qid The type of data to query
-* @arg1 Argument 1 to requested query data call
-* @arg2 Argument 2 to requested query data call
-* @arg3 Argument 3 to requested query data call
-* @data Returned output data
-* @flag 0 - Call from secure source
-* 1 - Call from non-secure source
-*
-* This function returns requested data.
-*/
+ * pm_query_data() - PM API for querying firmware data
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
+ * @qid The type of data to query
+ * @arg1 Argument 1 to requested query data call
+ * @arg2 Argument 2 to requested query data call
+ * @arg3 Argument 3 to requested query data call
+ * @data Returned output data
+ * @flag 0 - Call from secure source
+ * 1 - Call from non-secure source
+ *
+ * @retur - 0 if success else non-zero error code of type
+ * enum pm_ret_status
+ */
enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t *data, uint32_t flag)
{
uint32_t ret;
- uint32_t version;
+ uint32_t version[PAYLOAD_ARG_CNT] = {0};
uint32_t payload[PAYLOAD_ARG_CNT];
uint32_t fw_api_version;
@@ -831,42 +401,50 @@
PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
arg1, arg2, arg3);
- ret = pm_feature_check(PM_QUERY_DATA, &version, flag);
- if (PM_RET_SUCCESS == ret) {
- fw_api_version = version & 0xFFFFU;
- if ((2U == fw_api_version) &&
- ((XPM_QID_CLOCK_GET_NAME == qid) ||
- (XPM_QID_PINCTRL_GET_FUNCTION_NAME == qid))) {
- ret = pm_ipi_send_sync(primary_proc, payload, data, 8);
- ret = data[0];
- data[0] = data[1];
- data[1] = data[2];
- data[2] = data[3];
+ ret = pm_feature_check(PM_QUERY_DATA, &version[0], flag);
+ if (ret == PM_RET_SUCCESS) {
+ fw_api_version = version[0] & 0xFFFFU;
+ if ((fw_api_version == 2U) &&
+ ((qid == XPM_QID_CLOCK_GET_NAME) ||
+ (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
+ ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
+ if (ret == PM_RET_SUCCESS) {
+ ret = data[0];
+ data[0] = data[1];
+ data[1] = data[2];
+ data[2] = data[3];
+ }
} else {
- ret = pm_ipi_send_sync(primary_proc, payload, data, 4);
+ ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
}
}
return ret;
}
/**
* pm_api_ioctl() - PM IOCTL API for device control and configs
+ *
+ * This API is deprecated and maintained here for backward compatibility.
+ * New use of this API should be avoided for versal platform.
+ * This API and its use cases will be removed for versal platform.
+ *
* @device_id Device ID
* @ioctl_id ID of the requested IOCTL
* @arg1 Argument 1 to requested IOCTL call
* @arg2 Argument 2 to requested IOCTL call
+ * @arg3 Argument 3 to requested IOCTL call
* @value Returned output value
* @flag 0 - Call from secure source
* 1 - Call from non-secure source
*
* This function calls IOCTL to firmware for device control and configuration.
*
- * @return Returns status, either success or error+reason
+ * @return Returns status, either 0 on success or non-zero error code
+ * of type enum pm_ret_status
*/
enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
- uint32_t arg1, uint32_t arg2, uint32_t *value,
- uint32_t flag)
+ uint32_t arg1, uint32_t arg2, uint32_t arg3,
+ uint32_t *value, uint32_t flag)
{
- uint32_t payload[PAYLOAD_ARG_CNT];
enum pm_ret_status ret;
switch (ioctl_id) {
@@ -884,19 +462,16 @@
break;
case IOCTL_SET_SGI:
/* Get the sgi number */
- if (pm_register_sgi(arg1) != 0) {
+ ret = pm_register_sgi(arg1, arg2);
+ if (ret != 0) {
return PM_RET_ERROR_ARGS;
}
gicd_write_irouter(gicv3_driver_data->gicd_base,
- (unsigned int)PLAT_VERSAL_IPI_IRQ, MODE);
- ret = PM_RET_SUCCESS;
+ (uint32_t)PLAT_VERSAL_IPI_IRQ, MODE);
+ ret = PM_RET_SUCCESS;
break;
default:
- /* Send request to the PMC */
- PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_IOCTL,
- device_id, ioctl_id, arg1, arg2);
- ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
- break;
+ return PM_RET_ERROR_NOTSUPPORTED;
}
return ret;
@@ -923,116 +498,48 @@
}
/**
- * pm_get_chipid() - Read silicon ID registers
- * @value Buffer for return values. Must be large enough
- * to hold 8 bytes.
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns silicon ID registers
- */
-enum pm_ret_status pm_get_chipid(uint32_t *value, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_CHIPID);
-
- return pm_ipi_send_sync(primary_proc, payload, value, 2);
-}
-
-/**
* pm_feature_check() - Returns the supported API version if supported
* @api_id API ID to check
- * @value Returned supported API version
* @flag 0 - Call from secure source
* 1 - Call from non-secure source
+ * @ret_payload pointer to array of PAYLOAD_ARG_CNT number of
+ * words Returned supported API version and bitmasks
+ * for IOCTL and QUERY ID
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version,
+enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
uint32_t flag)
{
- uint32_t payload[PAYLOAD_ARG_CNT], fw_api_version;
- enum pm_ret_status status = PM_RET_ERROR_NOFEATURE;
+ uint32_t payload[PAYLOAD_ARG_CNT];
+ uint32_t module_id;
+ /* Return version of API which are implemented in ATF only */
switch (api_id) {
case PM_GET_CALLBACK_DATA:
case PM_GET_TRUSTZONE_VERSION:
- case PM_LOAD_PDI:
- *version = (PM_API_BASE_VERSION << 16);
- status = PM_RET_SUCCESS;
- break;
- case PM_GET_API_VERSION:
- case PM_GET_DEVICE_STATUS:
- case PM_GET_OP_CHARACTERISTIC:
- case PM_REQ_SUSPEND:
- case PM_SELF_SUSPEND:
- case PM_FORCE_POWERDOWN:
- case PM_ABORT_SUSPEND:
- case PM_REQ_WAKEUP:
- case PM_SET_WAKEUP_SOURCE:
- case PM_SYSTEM_SHUTDOWN:
- case PM_REQUEST_DEVICE:
- case PM_RELEASE_DEVICE:
- case PM_SET_REQUIREMENT:
- case PM_RESET_ASSERT:
- case PM_RESET_GET_STATUS:
- case PM_GET_CHIPID:
- case PM_PINCTRL_REQUEST:
- case PM_PINCTRL_RELEASE:
- case PM_PINCTRL_GET_FUNCTION:
- case PM_PINCTRL_SET_FUNCTION:
- case PM_PINCTRL_CONFIG_PARAM_GET:
- case PM_PINCTRL_CONFIG_PARAM_SET:
- case PM_IOCTL:
- case PM_CLOCK_ENABLE:
- case PM_CLOCK_DISABLE:
- case PM_CLOCK_GETSTATE:
- case PM_CLOCK_SETDIVIDER:
- case PM_CLOCK_GETDIVIDER:
- case PM_CLOCK_SETPARENT:
- case PM_CLOCK_GETPARENT:
- case PM_CLOCK_GETRATE:
- case PM_PLL_SET_PARAMETER:
- case PM_PLL_GET_PARAMETER:
- case PM_PLL_SET_MODE:
- case PM_PLL_GET_MODE:
- case PM_FEATURE_CHECK:
- case PM_INIT_FINALIZE:
- case PM_SET_MAX_LATENCY:
- case PM_REGISTER_NOTIFIER:
- *version = (PM_API_BASE_VERSION << 16);
- status = PM_RET_SUCCESS;
- break;
- case PM_QUERY_DATA:
- *version = (PM_API_QUERY_DATA_VERSION << 16);
- status = PM_RET_SUCCESS;
- break;
+ ret_payload[0] = PM_API_VERSION_2;
+ return PM_RET_SUCCESS;
+ case TF_A_PM_REGISTER_SGI:
+ ret_payload[0] = PM_API_BASE_VERSION;
+ return PM_RET_SUCCESS;
default:
- *version = 0U;
- status = PM_RET_ERROR_NOFEATURE;
break;
}
- if (status != PM_RET_SUCCESS) {
- goto done;
+ module_id = (api_id & MODULE_ID_MASK) >> 8U;
+
+ /*
+ * feature check should be done only for LIBPM module
+ * If module_id is 0, then we consider it LIBPM module as default id
+ */
+ if ((module_id > 0) && (module_id != LIBPM_MODULE_ID)) {
+ return PM_RET_SUCCESS;
}
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
PM_FEATURE_CHECK, api_id);
-
- status = pm_ipi_send_sync(primary_proc, payload, &fw_api_version, 1);
- if (status != PM_RET_SUCCESS) {
- goto done;
- }
-
- *version |= fw_api_version;
-
- status = PM_RET_SUCCESS;
-
-done:
- return status;
+ return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
}
/**
@@ -1060,54 +567,6 @@
}
/**
- * pm_get_op_characteristic() - PM call to request operating characteristics
- * of a device
- * @device_id Device id
- * @type Type of the operating characteristic
- * (power, temperature and latency)
- * @result Returns the operating characteristic for the requested device,
- * specified by the type
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
- enum pm_opchar_type type,
- uint32_t *result, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
- PM_GET_OP_CHARACTERISTIC, device_id, type);
- return pm_ipi_send_sync(primary_proc, payload, result, 1);
-}
-
-/**
- * pm_set_max_latency() - PM call to change in the maximum wake-up latency
- * requirements for a specific device currently
- * used by that CPU.
- * @device_id Device ID
- * @latency Latency value
- * @flag 0 - Call from secure source
- * 1 - Call from non-secure source
- *
- * @return Returns status, either success or error+reason
- */
-enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SET_MAX_LATENCY,
- device_id, latency);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
* pm_register_notifier() - PM call to register a subsystem to be notified
* about the device event
* @device_id Device ID for the Node to which the event is related
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index 5a92704..e2a3cf8 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,61 +11,36 @@
#include <stdint.h>
#include "pm_defs.h"
+/*********************************************************************
+ * Target module IDs macros
+ ********************************************************************/
+#define LIBPM_MODULE_ID 0x2U
+#define LOADER_MODULE_ID 0x7U
+
+#define MODE 0x80000000U
+#define MODULE_ID_MASK 0x0000ff00U
/**********************************************************
* PM API function declarations
**********************************************************/
-enum pm_ret_status pm_get_api_version(unsigned int *version, uint32_t flag);
-enum pm_ret_status pm_init_finalize(uint32_t flag);
+enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
+ uint32_t x2, uint32_t x3, uint32_t x4,
+ uint32_t x5, uint64_t *result);
enum pm_ret_status pm_self_suspend(uint32_t nid,
- unsigned int latency,
- unsigned int state,
+ uint32_t latency,
+ uint32_t state,
uintptr_t address, uint32_t flag);
enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason, uint32_t flag);
enum pm_ret_status pm_req_suspend(uint32_t target,
uint8_t ack,
- unsigned int latency,
- unsigned int state, uint32_t flag);
+ uint32_t latency,
+ uint32_t state, uint32_t flag);
enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
uintptr_t address, uint8_t ack, uint32_t flag);
enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t device_id,
uint8_t enable, uint32_t flag);
-enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
- uint32_t qos, uint32_t ack, uint32_t flag);
-enum pm_ret_status pm_release_device(uint32_t device_id, uint32_t flag);
-enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
- uint32_t latency, uint32_t qos,
- uint32_t flag);
-enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response,
- uint32_t flag);
-enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert, uint32_t flag);
-enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status,
- uint32_t flag);
-void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag);
-enum pm_ret_status pm_pinctrl_request(uint32_t pin, uint32_t flag);
-enum pm_ret_status pm_pinctrl_release(uint32_t pin, uint32_t flag);
-enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function,
- uint32_t flag);
-enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function,
- uint32_t flag);
-enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
- uint32_t value, uint32_t flag);
-enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
- uint32_t *value, uint32_t flag);
-enum pm_ret_status pm_clock_enable(uint32_t clk_id, uint32_t flag);
-enum pm_ret_status pm_clock_disable(uint32_t clk_id, uint32_t flag);
-enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state,
- uint32_t flag);
-enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider,
- uint32_t flag);
-enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider,
- uint32_t flag);
-enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent,
- uint32_t flag);
-enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent,
- uint32_t flag);
-enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate,
- uint32_t flag);
+void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag,
+ uint32_t ack);
enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
uint32_t value, uint32_t flag);
enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
@@ -78,22 +54,49 @@
enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
uint32_t flag);
enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
- uint32_t arg1, uint32_t arg2, uint32_t *value,
- uint32_t flag);
+ uint32_t arg1, uint32_t arg2, uint32_t arg3,
+ uint32_t *value, uint32_t flag);
enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t *data, uint32_t flag);
-unsigned int pm_get_shutdown_scope(void);
-enum pm_ret_status pm_get_chipid(uint32_t *value, uint32_t flag);
-enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version,
+uint32_t pm_get_shutdown_scope(void);
+enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
uint32_t flag);
enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
uint32_t address_high, uint32_t flag);
-enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
- enum pm_opchar_type type,
- uint32_t *result, uint32_t flag);
-enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency,
- uint32_t flag);
enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
uint32_t wake, uint32_t enable,
uint32_t flag);
+
+/**
+ * Assigning of argument values into array elements.
+ */
+#define PM_PACK_PAYLOAD1(pl, mid, flag, arg0) { \
+ pl[0] = (uint32_t)(((uint32_t)(arg0) & 0xFFU) | ((mid) << 8U) | ((flag) << 24U)); \
+}
+
+#define PM_PACK_PAYLOAD2(pl, mid, flag, arg0, arg1) { \
+ pl[1] = (uint32_t)(arg1); \
+ PM_PACK_PAYLOAD1(pl, (mid), (flag), (arg0)); \
+}
+
+#define PM_PACK_PAYLOAD3(pl, mid, flag, arg0, arg1, arg2) { \
+ pl[2] = (uint32_t)(arg2); \
+ PM_PACK_PAYLOAD2(pl, (mid), (flag), (arg0), (arg1)); \
+}
+
+#define PM_PACK_PAYLOAD4(pl, mid, flag, arg0, arg1, arg2, arg3) { \
+ pl[3] = (uint32_t)(arg3); \
+ PM_PACK_PAYLOAD3(pl, (mid), (flag), (arg0), (arg1), (arg2)); \
+}
+
+#define PM_PACK_PAYLOAD5(pl, mid, flag, arg0, arg1, arg2, arg3, arg4) { \
+ pl[4] = (uint32_t)(arg4); \
+ PM_PACK_PAYLOAD4(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3)); \
+}
+
+#define PM_PACK_PAYLOAD6(pl, mid, flag, arg0, arg1, arg2, arg3, arg4, arg5) { \
+ pl[5] = (uint32_t)(arg5); \
+ PM_PACK_PAYLOAD5(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4)); \
+}
+
#endif /* PM_API_SYS_H */
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 4c1d340..ce5e533 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,6 +21,7 @@
#include <plat/common/platform.h>
#include "pm_api_sys.h"
#include "pm_client.h"
+#include "pm_defs.h"
#define UNDEFINED_CPUID (~0)
#define IRQ_MAX 142U
@@ -104,7 +105,7 @@
*
* Return: PM node index corresponding to the specified interrupt
*/
-static enum pm_device_node_idx irq_to_pm_node_idx(unsigned int irq)
+static enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
{
assert(irq <= IRQ_MAX);
return irq_node_map[irq];
@@ -147,14 +148,16 @@
node_idx = irq_to_pm_node_idx(irq);
reg &= ~lowest_set;
- if ((node_idx != XPM_NODEIDX_DEV_MIN) &&
- (pm_wakeup_nodes_set[node_idx] == 0U)) {
- /* Get device ID from node index */
- device_id = PERIPH_DEVID(node_idx);
- ret = pm_set_wakeup_source(node_id,
- device_id, 1,
- SECURE_FLAG);
- pm_wakeup_nodes_set[node_idx] = (uint8_t)(!ret);
+ if (node_idx > XPM_NODEIDX_DEV_MIN && node_idx < XPM_NODEIDX_DEV_MAX) {
+ if (pm_wakeup_nodes_set[node_idx] == 0U) {
+ /* Get device ID from node index */
+ device_id = PERIPH_DEVID(node_idx);
+ ret = pm_set_wakeup_source(node_id,
+ device_id, 1,
+ SECURE_FLAG);
+ pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ?
+ 1 : 0;
+ }
}
}
}
@@ -167,7 +170,7 @@
* required prior to sending suspend request to PMU
* Actions taken depend on the state system is suspending to.
*/
-void pm_client_suspend(const struct pm_proc *proc, unsigned int state)
+void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
{
bakery_lock_get(&pm_client_secure_lock);
@@ -208,7 +211,7 @@
*
* Return: the cpu ID (starting from 0) for the subsystem
*/
-static unsigned int pm_get_cpuid(uint32_t nid)
+static uint32_t pm_get_cpuid(uint32_t nid)
{
for (size_t i = 0U; i < ARRAY_SIZE(pm_procs_all); i++) {
if (pm_procs_all[i].node_id == nid) {
@@ -226,7 +229,7 @@
*/
void pm_client_wakeup(const struct pm_proc *proc)
{
- unsigned int cpuid = pm_get_cpuid(proc->node_id);
+ uint32_t cpuid = pm_get_cpuid(proc->node_id);
if (cpuid == UNDEFINED_CPUID) {
return;
@@ -248,7 +251,7 @@
*
* Return: pointer to a proc structure if proc is found, otherwise NULL
*/
-const struct pm_proc *pm_get_proc(unsigned int cpuid)
+const struct pm_proc *pm_get_proc(uint32_t cpuid)
{
if (cpuid < ARRAY_SIZE(pm_procs_all)) {
return &pm_procs_all[cpuid];
diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h
index 08b46e2..2922b5d 100644
--- a/plat/xilinx/versal/pm_service/pm_defs.h
+++ b/plat/xilinx/versal/pm_service/pm_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -35,16 +35,13 @@
#define PM_GET_CALLBACK_DATA 0xa01U
#define PM_GET_TRUSTZONE_VERSION 0xa03U
+#define TF_A_PM_REGISTER_SGI 0xa04U
/* PM API Versions */
#define PM_API_BASE_VERSION 1U
-
-#define PM_API_QUERY_DATA_VERSION 2U
+#define PM_API_VERSION_2 2U
/* PM API ids */
-#define PM_GET_API_VERSION 1U
-#define PM_GET_DEVICE_STATUS 3U
-#define PM_GET_OP_CHARACTERISTIC 4U
#define PM_REGISTER_NOTIFIER 5U
#define PM_REQ_SUSPEND 6U
#define PM_SELF_SUSPEND 7U
@@ -53,31 +50,8 @@
#define PM_REQ_WAKEUP 10U
#define PM_SET_WAKEUP_SOURCE 11U
#define PM_SYSTEM_SHUTDOWN 12U
-#define PM_REQUEST_DEVICE 13U
-#define PM_RELEASE_DEVICE 14U
-#define PM_SET_REQUIREMENT 15U
-#define PM_SET_MAX_LATENCY 16U
-#define PM_RESET_ASSERT 17U
-#define PM_RESET_GET_STATUS 18U
-#define PM_INIT_FINALIZE 21U
-#define PM_GET_CHIPID 24U
-#define PM_PINCTRL_REQUEST 28U
-#define PM_PINCTRL_RELEASE 29U
-#define PM_PINCTRL_GET_FUNCTION 30U
-#define PM_PINCTRL_SET_FUNCTION 31U
-#define PM_PINCTRL_CONFIG_PARAM_GET 32U
-#define PM_PINCTRL_CONFIG_PARAM_SET 33U
#define PM_IOCTL 34U
#define PM_QUERY_DATA 35U
-#define PM_CLOCK_ENABLE 36U
-#define PM_CLOCK_DISABLE 37U
-#define PM_CLOCK_GETSTATE 38U
-#define PM_CLOCK_SETDIVIDER 39U
-#define PM_CLOCK_GETDIVIDER 40U
-#define PM_CLOCK_SETRATE 41U
-#define PM_CLOCK_GETRATE 42U
-#define PM_CLOCK_SETPARENT 43U
-#define PM_CLOCK_GETPARENT 44U
#define PM_PLL_SET_PARAMETER 48U
#define PM_PLL_GET_PARAMETER 49U
#define PM_PLL_SET_MODE 50U
@@ -86,6 +60,7 @@
/* Loader API ids */
#define PM_LOAD_PDI 0x701U
+#define PM_LOAD_GET_HANDOFF_PARAMS 0x70BU
/* IOCTL IDs for clock driver */
#define IOCTL_SET_PLL_FRAC_MODE 8U
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index b082acb..14329dc 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,24 +22,46 @@
#define XSCUGIC_SGIR_EL1_INITID_SHIFT 24U
#define INVALID_SGI 0xFFU
+#define PM_INIT_SUSPEND_CB (30U)
+#define PM_NOTIFY_CB (32U)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r_el1, S3_0_C12_C11_6)
/* pm_up = true - UP, pm_up = false - DOWN */
static bool pm_up;
-static unsigned int sgi = (unsigned int)INVALID_SGI;
+static uint32_t sgi = (uint32_t)INVALID_SGI;
+
+static void notify_os(void)
+{
+ int32_t cpu;
+ uint32_t reg;
+
+ cpu = plat_my_core_pos() + 1U;
+
+ reg = (cpu | (sgi << XSCUGIC_SGIR_EL1_INITID_SHIFT));
+ write_icc_asgi1r_el1(reg);
+}
static uint64_t ipi_fiq_handler(uint32_t id, uint32_t flags, void *handle,
void *cookie)
{
- unsigned int cpu;
- unsigned int reg;
+ uint32_t payload[4] = {0};
+
+ VERBOSE("Received IPI FIQ from firmware\n");
(void)plat_ic_acknowledge_interrupt();
- cpu = plat_my_core_pos() + 1U;
- if ((unsigned int)sgi != (unsigned int)INVALID_SGI) {
- reg = (cpu | ((unsigned int)sgi << (unsigned int)XSCUGIC_SGIR_EL1_INITID_SHIFT));
- write_icc_asgi1r_el1(reg);
+ pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
+ switch (payload[0]) {
+ case PM_INIT_SUSPEND_CB:
+ case PM_NOTIFY_CB:
+ if (sgi != INVALID_SGI) {
+ notify_os();
+ }
+ break;
+ default:
+ pm_ipi_irq_clear(primary_proc);
+ WARN("Invalid IPI payload\n");
+ break;
}
/* Clear FIQ */
@@ -51,6 +74,7 @@
* pm_register_sgi() - PM register the IPI interrupt
*
* @sgi - SGI number to be used for communication.
+ * @reset - Reset to invalid SGI when reset=1.
* @return On success, the initialization function must return 0.
* Any other return value will cause the framework to ignore
* the service
@@ -58,9 +82,14 @@
* Update the SGI number to be used.
*
*/
-int pm_register_sgi(unsigned int sgi_num)
+int32_t pm_register_sgi(uint32_t sgi_num, uint32_t reset)
{
- if ((unsigned int)sgi != (unsigned int)INVALID_SGI) {
+ if (reset == 1U) {
+ sgi = INVALID_SGI;
+ return 0;
+ }
+
+ if (sgi != INVALID_SGI) {
return -EBUSY;
}
@@ -68,7 +97,7 @@
return -EINVAL;
}
- sgi = (unsigned int)sgi_num;
+ sgi = (uint32_t)sgi_num;
return 0;
}
@@ -85,9 +114,9 @@
* Called from sip_svc_setup initialization function with the
* rt_svc_init signature.
*/
-int pm_setup(void)
+int32_t pm_setup(void)
{
- int status, ret = 0;
+ int32_t status, ret = 0;
status = pm_ipi_init(primary_proc);
@@ -114,323 +143,254 @@
}
/**
- * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
- * @smc_fid - Function Identifier
- * @x1 - x4 - Arguments
- * @cookie - Unused
- * @handler - Pointer to caller's context structure
+ * eemi_for_compatibility() - EEMI calls handler for deprecated calls
*
- * @return - Unused
+ * @return - If EEMI API found then, uintptr_t type address, else 0
*
- * Determines that smc_fid is valid and supported PM SMC Function ID from the
- * list of pm_api_ids, otherwise completes the request with
- * the unknown SMC Function ID
- *
- * The SMC calls for PM service are forwarded from SIP Service SMC handler
- * function with rt_svc_handle signature
+ * Some EEMI API's use case needs to be changed in Linux driver, so they
+ * can take advantage of common EEMI handler in TF-A. As of now the old
+ * implementation of these APIs are required to maintain backward compatibility
+ * until their use case in linux driver changes.
*/
-uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
- uint64_t x4, void *cookie, void *handle, uint64_t flags)
+static uintptr_t eemi_for_compatibility(uint32_t api_id, uint32_t *pm_arg,
+ void *handle, uint32_t security_flag)
{
enum pm_ret_status ret;
- uint32_t pm_arg[4];
- uint32_t security_flag = SECURE_FLAG;
+ switch (api_id) {
- /* Handle case where PM wasn't initialized properly */
- if (pm_up == false) {
- SMC_RET1(handle, SMC_UNK);
- }
+ case PM_IOCTL:
+ {
+ uint32_t value;
- pm_arg[0] = (uint32_t)x1;
- pm_arg[1] = (uint32_t)(x1 >> 32);
- pm_arg[2] = (uint32_t)x2;
- pm_arg[3] = (uint32_t)(x2 >> 32);
+ ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
+ pm_arg[3], pm_arg[4],
+ &value, security_flag);
+ if (ret == PM_RET_ERROR_NOTSUPPORTED)
+ return (uintptr_t)0;
- /*
- * Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
- * if smc called is non secure
- */
- if (is_caller_non_secure(flags) != 0) {
- security_flag = NON_SECURE_FLAG;
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
}
- switch (smc_fid & FUNCID_NUM_MASK) {
- /* PM API Functions */
- case PM_SELF_SUSPEND:
- ret = pm_self_suspend(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_FORCE_POWERDOWN:
- ret = pm_force_powerdown(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_REQ_SUSPEND:
- ret = pm_req_suspend(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_ABORT_SUSPEND:
- ret = pm_abort_suspend(pm_arg[0], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_SYSTEM_SHUTDOWN:
- ret = pm_system_shutdown(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_REQ_WAKEUP:
- ret = pm_req_wakeup(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
- security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_SET_WAKEUP_SOURCE:
- ret = pm_set_wakeup_source(pm_arg[0], pm_arg[1], pm_arg[2],
- security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_REQUEST_DEVICE:
- ret = pm_request_device(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_RELEASE_DEVICE:
- ret = pm_release_device(pm_arg[0], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_SET_REQUIREMENT:
- ret = pm_set_requirement(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_GET_API_VERSION:
+ case PM_QUERY_DATA:
{
- uint32_t api_version;
+ uint32_t data[PAYLOAD_ARG_CNT] = { 0 };
- ret = pm_get_api_version(&api_version, security_flag);
- SMC_RET1(handle, (u_register_t)PM_RET_SUCCESS |
- ((u_register_t)api_version << 32));
- }
-
- case PM_GET_DEVICE_STATUS:
- {
- uint32_t buff[3];
+ ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
+ pm_arg[3], data, security_flag);
- ret = pm_get_device_status(pm_arg[0], buff, security_flag);
- SMC_RET2(handle, (u_register_t)ret | ((u_register_t)buff[0] << 32),
- (u_register_t)buff[1] | ((u_register_t)buff[2] << 32));
+ SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32U),
+ (uint64_t)data[1] | ((uint64_t)data[2] << 32U));
}
- case PM_RESET_ASSERT:
- ret = pm_reset_assert(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_RESET_GET_STATUS:
+ case PM_FEATURE_CHECK:
{
- uint32_t reset_status;
+ uint32_t result[PAYLOAD_ARG_CNT] = {0U};
- ret = pm_reset_get_status(pm_arg[0], &reset_status,
- security_flag);
- SMC_RET1(handle, (u_register_t)ret |
- ((u_register_t)reset_status << 32));
+ ret = pm_feature_check(pm_arg[0], result, security_flag);
+ SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
+ (uint64_t)result[1] | ((uint64_t)result[2] << 32U));
}
- case PM_INIT_FINALIZE:
- ret = pm_init_finalize(security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_GET_CALLBACK_DATA:
+ case PM_LOAD_PDI:
{
- uint32_t result[4] = {0};
-
- pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag);
- SMC_RET2(handle,
- (u_register_t)result[0] | ((u_register_t)result[1] << 32),
- (u_register_t)result[2] | ((u_register_t)result[3] << 32));
- }
-
- case PM_PINCTRL_REQUEST:
- ret = pm_pinctrl_request(pm_arg[0], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_PINCTRL_RELEASE:
- ret = pm_pinctrl_release(pm_arg[0], security_flag);
+ ret = pm_load_pdi(pm_arg[0], pm_arg[1], pm_arg[2],
+ security_flag);
SMC_RET1(handle, (uint64_t)ret);
-
- case PM_PINCTRL_GET_FUNCTION:
- {
- uint32_t value = 0;
-
- ret = pm_pinctrl_get_function(pm_arg[0], &value, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
}
- case PM_PINCTRL_SET_FUNCTION:
- ret = pm_pinctrl_set_function(pm_arg[0], pm_arg[1],
- security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_PINCTRL_CONFIG_PARAM_GET:
- {
- uint32_t value;
-
- ret = pm_pinctrl_get_pin_param(pm_arg[0], pm_arg[1], &value,
- security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
+ default:
+ return (uintptr_t)0;
}
-
- case PM_PINCTRL_CONFIG_PARAM_SET:
- ret = pm_pinctrl_set_pin_param(pm_arg[0], pm_arg[1], pm_arg[2],
- security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_IOCTL:
- {
- uint32_t value;
+}
- ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], &value, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
- }
+/**
+ * eemi_psci_debugfs_handler() - EEMI API invoked from PSCI
+ *
+ * These EEMI APIs performs CPU specific power management tasks.
+ * These EEMI APIs are invoked either from PSCI or from debugfs in kernel.
+ * These calls require CPU specific processing before sending IPI request to
+ * Platform Management Controller. For example enable/disable CPU specific
+ * interrupts. This requires separate handler for these calls and may not be
+ * handled using common eemi handler
+ */
+static uintptr_t eemi_psci_debugfs_handler(uint32_t api_id, uint32_t *pm_arg,
+ void *handle, uint32_t security_flag)
+{
+ enum pm_ret_status ret;
- case PM_QUERY_DATA:
- {
- uint32_t data[8] = { 0 };
+ switch (api_id) {
- ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], data, security_flag);
+ case PM_SELF_SUSPEND:
+ ret = pm_self_suspend(pm_arg[0], pm_arg[1], pm_arg[2],
+ pm_arg[3], security_flag);
+ SMC_RET1(handle, (u_register_t)ret);
- SMC_RET2(handle, (u_register_t)ret | ((u_register_t)data[0] << 32),
- (u_register_t)data[1] | ((u_register_t)data[2] << 32));
+ case PM_FORCE_POWERDOWN:
+ ret = pm_force_powerdown(pm_arg[0], pm_arg[1], security_flag);
+ SMC_RET1(handle, (u_register_t)ret);
- }
- case PM_CLOCK_ENABLE:
- ret = pm_clock_enable(pm_arg[0], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
+ case PM_REQ_SUSPEND:
+ ret = pm_req_suspend(pm_arg[0], pm_arg[1], pm_arg[2],
+ pm_arg[3], security_flag);
+ SMC_RET1(handle, (u_register_t)ret);
- case PM_CLOCK_DISABLE:
- ret = pm_clock_disable(pm_arg[0], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
+ case PM_ABORT_SUSPEND:
+ ret = pm_abort_suspend(pm_arg[0], security_flag);
+ SMC_RET1(handle, (u_register_t)ret);
- case PM_CLOCK_GETSTATE:
- {
- uint32_t value;
+ case PM_SYSTEM_SHUTDOWN:
+ ret = pm_system_shutdown(pm_arg[0], pm_arg[1], security_flag);
+ SMC_RET1(handle, (u_register_t)ret);
- ret = pm_clock_get_state(pm_arg[0], &value, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
+ default:
+ return (uintptr_t)0;
}
+}
- case PM_CLOCK_SETDIVIDER:
- ret = pm_clock_set_divider(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
+/**
+ * TF_A_specific_handler() - SMC handler for TF-A specific functionality
+ *
+ * These EEMI calls performs functionality that does not require
+ * IPI transaction. The handler ends in TF-A and returns requested data to
+ * kernel from TF-A.
+ */
+static uintptr_t TF_A_specific_handler(uint32_t api_id, uint32_t *pm_arg,
+ void *handle, uint32_t security_flag)
+{
+ switch (api_id) {
- case PM_CLOCK_GETDIVIDER:
+ case TF_A_PM_REGISTER_SGI:
{
- uint32_t value;
-
- ret = pm_clock_get_divider(pm_arg[0], &value, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
- }
+ int32_t ret;
- case PM_CLOCK_SETPARENT:
- ret = pm_clock_set_parent(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
+ ret = pm_register_sgi(pm_arg[0], pm_arg[1]);
+ if (ret != 0) {
+ SMC_RET1(handle, (uint32_t)PM_RET_ERROR_ARGS);
+ }
- case PM_CLOCK_GETPARENT:
- {
- uint32_t value;
-
- ret = pm_clock_get_parent(pm_arg[0], &value, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
+ SMC_RET1(handle, (uint32_t)PM_RET_SUCCESS);
}
- case PM_CLOCK_GETRATE:
+ case PM_GET_CALLBACK_DATA:
{
- uint32_t rate[2] = { 0 };
+ uint32_t result[4] = {0};
- ret = pm_clock_get_rate(pm_arg[0], rate, security_flag);
- SMC_RET2(handle, (u_register_t)ret | ((u_register_t)rate[0] << 32),
- (u_register_t)rate[1] | ((u_register_t)0U << 32));
+ pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag, 1U);
+ SMC_RET2(handle,
+ (uint64_t)result[0] | ((uint64_t)result[1] << 32U),
+ (uint64_t)result[2] | ((uint64_t)result[3] << 32U));
}
- case PM_PLL_SET_PARAMETER:
- ret = pm_pll_set_param(pm_arg[0], pm_arg[1], pm_arg[2],
- security_flag);
- SMC_RET1(handle, (uint64_t)ret);
-
- case PM_PLL_GET_PARAMETER:
- {
- uint32_t value;
+ case PM_GET_TRUSTZONE_VERSION:
+ SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
+ ((uint64_t)VERSAL_TZ_VERSION << 32U));
- ret = pm_pll_get_param(pm_arg[0], pm_arg[1], &value,
- security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value << 32));
+ default:
+ return (uintptr_t)0;
}
-
- case PM_PLL_SET_MODE:
- ret = pm_pll_set_mode(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (uint64_t)ret);
+}
- case PM_PLL_GET_MODE:
- {
- uint32_t mode;
+/**
+ * eemi_handler() - Prepare EEMI payload and perform IPI transaction
+ *
+ * EEMI - Embedded Energy Management Interface is Xilinx proprietary protocol
+ * to allow communication between power management controller and different
+ * processing clusters.
+ *
+ * This handler prepares EEMI protocol payload received from kernel and performs
+ * IPI transaction.
+ */
+static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
+ void *handle, uint32_t security_flag)
+{
+ enum pm_ret_status ret;
+ uint32_t buf[PAYLOAD_ARG_CNT] = {0};
- ret = pm_pll_get_mode(pm_arg[0], &mode, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)mode << 32));
+ ret = pm_handle_eemi_call(security_flag, api_id, pm_arg[0], pm_arg[1],
+ pm_arg[2], pm_arg[3], pm_arg[4],
+ (uint64_t *)buf);
+ /*
+ * Two IOCTLs, to get clock name and pinctrl name of pm_query_data API
+ * receives 5 words of respoonse from firmware. Currently linux driver can
+ * receive only 4 words from TF-A. So, this needs to be handled separately
+ * than other eemi calls.
+ */
+ if (api_id == PM_QUERY_DATA) {
+ if ((pm_arg[0] == XPM_QID_CLOCK_GET_NAME ||
+ pm_arg[0] == XPM_QID_PINCTRL_GET_FUNCTION_NAME) &&
+ ret == PM_RET_SUCCESS) {
+ SMC_RET2(handle, (uint64_t)buf[0] | ((uint64_t)buf[1] << 32U),
+ (uint64_t)buf[2] | ((uint64_t)buf[3] << 32U));
+ }
}
- case PM_GET_TRUSTZONE_VERSION:
- SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
- ((uint64_t)VERSAL_TZ_VERSION << 32));
-
- case PM_GET_CHIPID:
- {
- uint32_t result[2];
-
- ret = pm_get_chipid(result, security_flag);
- SMC_RET2(handle, (u_register_t)ret | ((u_register_t)result[0] << 32),
- (u_register_t)result[1] | ((u_register_t)0U << 32));
- }
+ SMC_RET2(handle, (uint64_t)ret | ((uint64_t)buf[0] << 32U),
+ (uint64_t)buf[1] | ((uint64_t)buf[2] << 32U));
+}
- case PM_FEATURE_CHECK:
- {
- uint32_t version;
+/**
+ * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
+ * @smc_fid - Function Identifier
+ * @x1 - x4 - SMC64 Arguments from kernel
+ * x3 (upper 32-bits) and x4 are Unused
+ * @cookie - Unused
+ * @handler - Pointer to caller's context structure
+ *
+ * @return - Unused
+ *
+ * Determines that smc_fid is valid and supported PM SMC Function ID from the
+ * list of pm_api_ids, otherwise completes the request with
+ * the unknown SMC Function ID
+ *
+ * The SMC calls for PM service are forwarded from SIP Service SMC handler
+ * function with rt_svc_handle signature
+ */
+uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+ uint64_t x4, const void *cookie, void *handle, uint64_t flags)
+{
+ uintptr_t ret;
+ uint32_t pm_arg[PAYLOAD_ARG_CNT] = {0};
+ uint32_t security_flag = SECURE_FLAG;
+ uint32_t api_id;
- ret = pm_feature_check(pm_arg[0], &version, security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)version << 32));
+ /* Handle case where PM wasn't initialized properly */
+ if (pm_up == false) {
+ SMC_RET1(handle, SMC_UNK);
}
- case PM_LOAD_PDI:
- {
- ret = pm_load_pdi(pm_arg[0], pm_arg[1], pm_arg[2],
- security_flag);
- SMC_RET1(handle, (u_register_t)ret);
+ /*
+ * Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
+ * if smc called is non secure
+ */
+ if (is_caller_non_secure(flags) != 0) {
+ security_flag = NON_SECURE_FLAG;
}
- case PM_GET_OP_CHARACTERISTIC:
- {
- uint32_t result;
+ pm_arg[0] = (uint32_t)x1;
+ pm_arg[1] = (uint32_t)(x1 >> 32U);
+ pm_arg[2] = (uint32_t)x2;
+ pm_arg[3] = (uint32_t)(x2 >> 32U);
+ pm_arg[4] = (uint32_t)x3;
+ (void)(x4);
+ api_id = smc_fid & FUNCID_NUM_MASK;
- ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1], &result,
- security_flag);
- SMC_RET1(handle, (u_register_t)ret | ((u_register_t)result << 32));
+ ret = eemi_for_compatibility(api_id, pm_arg, handle, security_flag);
+ if (ret != (uintptr_t)0) {
+ return ret;
}
- case PM_SET_MAX_LATENCY:
- {
- ret = pm_set_max_latency(pm_arg[0], pm_arg[1], security_flag);
- SMC_RET1(handle, (u_register_t)ret);
+ ret = eemi_psci_debugfs_handler(api_id, pm_arg, handle, flags);
+ if (ret != (uintptr_t)0) {
+ return ret;
}
- case PM_REGISTER_NOTIFIER:
- {
- ret = pm_register_notifier(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], security_flag);
- SMC_RET1(handle, (u_register_t)ret);
+ ret = TF_A_specific_handler(api_id, pm_arg, handle, security_flag);
+ if (ret != (uintptr_t)0) {
+ return ret;
}
- default:
- WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
- SMC_RET1(handle, SMC_UNK);
- }
+ ret = eemi_handler(api_id, pm_arg, handle, security_flag);
+
+ return ret;
}
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.h b/plat/xilinx/versal/pm_service/pm_svc_main.h
index 4f8dc2b..b6e764f 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.h
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,10 +9,10 @@
#include <pm_common.h>
-int pm_setup(void);
+int32_t pm_setup(void);
uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
- uint64_t x4, void *cookie, void *handle,
+ uint64_t x4, const void *cookie, void *handle,
uint64_t flags);
-int pm_register_sgi(unsigned int sgi_num);
+int32_t pm_register_sgi(uint32_t sgi_num, uint32_t reset);
#endif /* PM_SVC_MAIN_H */
diff --git a/plat/xilinx/versal/versal_gicv3.c b/plat/xilinx/versal/versal_gicv3.c
index 08e7cf9..d410906 100644
--- a/plat/xilinx/versal/versal_gicv3.c
+++ b/plat/xilinx/versal/versal_gicv3.c
@@ -53,7 +53,7 @@
* - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
* - No CPUs implemented in the system use affinity level 3.
*/
-static unsigned int versal_gicv3_mpidr_hash(u_register_t mpidr)
+static uint32_t versal_gicv3_mpidr_hash(u_register_t mpidr)
{
mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
return versal_calc_core_pos(mpidr);
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index fae73cf..3946e9b 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,7 +29,7 @@
{0}
};
-static unsigned int zynqmp_get_silicon_ver(void)
+static uint32_t zynqmp_get_silicon_ver(void)
{
static unsigned int ver;
@@ -43,20 +43,21 @@
return ver;
}
-unsigned int zynqmp_get_uart_clk(void)
+uint32_t zynqmp_get_uart_clk(void)
{
unsigned int ver = zynqmp_get_silicon_ver();
- if (ver == ZYNQMP_CSU_VERSION_QEMU)
+ if (ver == ZYNQMP_CSU_VERSION_QEMU) {
return 133000000;
- else
+ } else {
return 100000000;
+ }
}
#if LOG_LEVEL >= LOG_LEVEL_NOTICE
static const struct {
- unsigned int id;
- unsigned int ver;
+ uint32_t id;
+ uint32_t ver;
char *name;
bool evexists;
} zynqmp_devices[] = {
@@ -214,7 +215,8 @@
#define ZYNQMP_PL_STATUS_MASK BIT(ZYNQMP_PL_STATUS_BIT)
#define ZYNQMP_CSU_VERSION_MASK ~(ZYNQMP_PL_STATUS_MASK)
-#define SILICON_ID_XCK26 0x4724093
+#define SILICON_ID_XCK24 0x4714093U
+#define SILICON_ID_XCK26 0x4724093U
static char *zynqmp_get_silicon_idcode_name(void)
{
@@ -232,8 +234,9 @@
chipid[0] = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
chipid[1] = mmio_read_32(EFUSE_BASEADDR + EFUSE_IPDISABLE_OFFSET);
#else
- if (pm_get_chipid(chipid) != PM_RET_SUCCESS)
+ if (pm_get_chipid(chipid) != PM_RET_SUCCESS) {
return "XCZUUNKN";
+ }
#endif
id = chipid[0] & (ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
@@ -243,23 +246,29 @@
for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
if (zynqmp_devices[i].id == id &&
- zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK))
+ zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK)) {
break;
+ }
}
if (i >= ARRAY_SIZE(zynqmp_devices)) {
- if (chipid[0] == SILICON_ID_XCK26) {
+ switch (chipid[0]) {
+ case SILICON_ID_XCK24:
+ return "XCK24";
+ case SILICON_ID_XCK26:
return "XCK26";
- } else {
+ default:
return "XCZUUNKN";
}
}
- if (!zynqmp_devices[i].evexists)
+ if (!zynqmp_devices[i].evexists) {
return zynqmp_devices[i].name;
+ }
- if (ver & ZYNQMP_PL_STATUS_MASK)
+ if ((ver & ZYNQMP_PL_STATUS_MASK) != 0U) {
return zynqmp_devices[i].name;
+ }
len = strlen(zynqmp_devices[i].name) - 2;
for (j = 0; j < strlen(name); j++) {
@@ -301,20 +310,20 @@
return zynqmp_get_silicon_idcode_name();
}
-static unsigned int zynqmp_get_ps_ver(void)
+static uint32_t zynqmp_get_ps_ver(void)
{
uint32_t ver = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_VERSION_OFFSET);
ver &= ZYNQMP_PS_VER_MASK;
ver >>= ZYNQMP_PS_VER_SHIFT;
- return ver + 1;
+ return ver + 1U;
}
static void zynqmp_print_platform_name(void)
{
- unsigned int ver = zynqmp_get_silicon_ver();
- unsigned int rtl = zynqmp_get_rtl_ver();
+ uint32_t ver = zynqmp_get_silicon_ver();
+ uint32_t rtl = zynqmp_get_rtl_ver();
char *label = "Unknown";
switch (ver) {
@@ -329,8 +338,8 @@
break;
}
- NOTICE("TF-A running on %s/%s at 0x%x\n",
- zynqmp_print_silicon_idcode(), label, BL31_BASE);
+ VERBOSE("TF-A running on %s/%s at 0x%x\n",
+ zynqmp_print_silicon_idcode(), label, BL31_BASE);
VERBOSE("TF-A running on v%d/RTL%d.%d\n",
zynqmp_get_ps_ver(), (rtl & 0xf0) >> 4, rtl & 0xf);
}
@@ -338,15 +347,16 @@
static inline void zynqmp_print_platform_name(void) { }
#endif
-unsigned int zynqmp_get_bootmode(void)
+uint32_t zynqmp_get_bootmode(void)
{
uint32_t r;
unsigned int ret;
ret = pm_mmio_read(CRL_APB_BOOT_MODE_USER, &r);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
r = mmio_read_32(CRL_APB_BOOT_MODE_USER);
+ }
return r & CRL_APB_BOOT_MODE_MASK;
}
@@ -369,12 +379,13 @@
generic_delay_timer_init();
}
-unsigned int plat_get_syscnt_freq2(void)
+uint32_t plat_get_syscnt_freq2(void)
{
- unsigned int ver = zynqmp_get_silicon_ver();
+ uint32_t ver = zynqmp_get_silicon_ver();
- if (ver == ZYNQMP_CSU_VERSION_QEMU)
+ if (ver == ZYNQMP_CSU_VERSION_QEMU) {
return 65000000;
- else
+ } else {
return mmio_read_32(IOU_SCNTRS_BASEFREQ);
+ }
}
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 58eee3a..1d59537 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -33,15 +33,18 @@
* while BL32 corresponds to the secure image type. A NULL pointer is returned
* if the image does not exist.
*/
-entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
{
- assert(sec_state_is_valid(type));
+ entry_point_info_t *next_image_info;
+ assert(sec_state_is_valid(type));
if (type == NON_SECURE) {
- return &bl33_image_ep_info;
+ next_image_info = &bl33_image_ep_info;
+ } else {
+ next_image_info = &bl32_image_ep_info;
}
- return &bl32_image_ep_info;
+ return next_image_info;
}
/*
@@ -79,10 +82,12 @@
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
} else if (ZYNQMP_CONSOLE_IS(dcc)) {
/* Initialize the dcc console for debug */
- int rc = console_dcc_register();
+ int32_t rc = console_dcc_register();
if (rc == 0) {
panic();
}
+ } else {
+ ERROR("BL31: No console device found.\n");
}
/* Initialize the platform config for future decision making */
zynqmp_config_setup();
@@ -119,10 +124,10 @@
panic();
}
}
- if (bl32_image_ep_info.pc) {
+ if (bl32_image_ep_info.pc != 0) {
VERBOSE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
}
- if (bl33_image_ep_info.pc) {
+ if (bl33_image_ep_info.pc != 0) {
VERBOSE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
}
}
@@ -171,7 +176,7 @@
/* Return if no device tree is detected */
if (fdt_check_header(dtb) != 0) {
- NOTICE("Can't read DT at 0x%p\n", dtb);
+ NOTICE("Can't read DT at %p\n", dtb);
return;
}
diff --git a/plat/xilinx/zynqmp/include/plat_private.h b/plat/xilinx/zynqmp/include/plat_private.h
index 288cc53..534777b 100644
--- a/plat/xilinx/zynqmp/include/plat_private.h
+++ b/plat/xilinx/zynqmp/include/plat_private.h
@@ -15,11 +15,11 @@
void zynqmp_config_setup(void);
-unsigned int zynqmp_calc_core_pos(u_register_t mpidr);
+uint32_t zynqmp_calc_core_pos(u_register_t mpidr);
/* ZynqMP specific functions */
-unsigned int zynqmp_get_uart_clk(void);
-unsigned int zynqmp_get_bootmode(void);
+uint32_t zynqmp_get_uart_clk(void);
+uint32_t zynqmp_get_bootmode(void);
#if ZYNQMP_WDT_RESTART
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 1c4daa1..66bbf30 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -37,11 +37,11 @@
*/
#ifndef ZYNQMP_ATF_MEM_BASE
#if !DEBUG && defined(SPD_none) && !SDEI_SUPPORT
-# define BL31_BASE 0xfffea000
-# define BL31_LIMIT 0x100000000
+# define BL31_BASE U(0xfffea000)
+# define BL31_LIMIT U(0x100000000)
#else
-# define BL31_BASE 0x1000
-# define BL31_LIMIT 0x7ffff
+# define BL31_BASE U(0xfff5a000)
+# define BL31_LIMIT U(0x100000000)
#endif
#else
# define BL31_BASE (ZYNQMP_ATF_MEM_BASE)
@@ -55,8 +55,8 @@
* BL32 specific defines.
******************************************************************************/
#ifndef ZYNQMP_BL32_MEM_BASE
-# define BL32_BASE 0x60000000
-# define BL32_LIMIT 0x7fffffff
+# define BL32_BASE U(0x60000000)
+# define BL32_LIMIT U(0x7fffffff)
#else
# define BL32_BASE (ZYNQMP_BL32_MEM_BASE)
# define BL32_LIMIT (ZYNQMP_BL32_MEM_BASE + ZYNQMP_BL32_MEM_SIZE - 1)
@@ -66,7 +66,7 @@
* BL33 specific defines.
******************************************************************************/
#ifndef PRELOADED_BL33_BASE
-# define PLAT_ARM_NS_IMAGE_BASE 0x8000000
+# define PLAT_ARM_NS_IMAGE_BASE U(0x8000000)
#else
# define PLAT_ARM_NS_IMAGE_BASE PRELOADED_BL33_BASE
#endif
@@ -83,9 +83,9 @@
/*******************************************************************************
* Platform specific page table and MMU setup constants
******************************************************************************/
-#define XILINX_OF_BOARD_DTB_ADDR 0x100000
-#define XILINX_OF_BOARD_DTB_MAX_SIZE 0x200000
-#define PLAT_DDR_LOWMEM_MAX 0x80000000
+#define XILINX_OF_BOARD_DTB_ADDR U(0x100000)
+#define XILINX_OF_BOARD_DTB_MAX_SIZE U(0x200000)
+#define PLAT_DDR_LOWMEM_MAX U(0x80000000)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 7e58391..428bed5 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -74,11 +74,11 @@
#define ZYNQMP_ULPI_RESET_VAL_LOW CRL_APB_BOOT_ENABLE_PIN_1
/* system counter registers and bitfields */
-#define IOU_SCNTRS_BASE 0xFF260000
+#define IOU_SCNTRS_BASE U(0xFF260000)
#define IOU_SCNTRS_BASEFREQ (IOU_SCNTRS_BASE + 0x20)
/* APU registers and bitfields */
-#define APU_BASE 0xFD5C0000
+#define APU_BASE U(0xFD5C0000)
#define APU_CONFIG_0 (APU_BASE + 0x20)
#define APU_RVBAR_L_0 (APU_BASE + 0x40)
#define APU_RVBAR_H_0 (APU_BASE + 0x44)
@@ -91,7 +91,7 @@
#define APU_3_PWRCTL_CPUPWRDWNREQ_MASK 8
/* PMU registers and bitfields */
-#define PMU_GLOBAL_BASE 0xFFD80000
+#define PMU_GLOBAL_BASE U(0xFFD80000)
#define PMU_GLOBAL_CNTRL (PMU_GLOBAL_BASE + 0)
#define PMU_GLOBAL_GEN_STORAGE6 (PMU_GLOBAL_BASE + 0x48)
#define PMU_GLOBAL_REQ_PWRUP_STATUS (PMU_GLOBAL_BASE + 0x110)
@@ -104,22 +104,22 @@
/*******************************************************************************
* CCI-400 related constants
******************************************************************************/
-#define PLAT_ARM_CCI_BASE 0xFD6E0000
+#define PLAT_ARM_CCI_BASE U(0xFD6E0000)
#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 3
#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 4
/*******************************************************************************
* GIC-400 & interrupt handling related constants
******************************************************************************/
-#define BASE_GICD_BASE 0xF9010000
-#define BASE_GICC_BASE 0xF9020000
-#define BASE_GICH_BASE 0xF9040000
-#define BASE_GICV_BASE 0xF9060000
+#define BASE_GICD_BASE U(0xF9010000)
+#define BASE_GICC_BASE U(0xF9020000)
+#define BASE_GICH_BASE U(0xF9040000)
+#define BASE_GICV_BASE U(0xF9060000)
#if ZYNQMP_WDT_RESTART
#define IRQ_SEC_IPI_APU 67
#define IRQ_TTC3_1 77
-#define TTC3_BASE_ADDR 0xFF140000
+#define TTC3_BASE_ADDR U(0xFF140000)
#define TTC3_INTR_REGISTER_1 (TTC3_BASE_ADDR + 0x54)
#define TTC3_INTR_ENABLE_1 (TTC3_BASE_ADDR + 0x60)
#endif
@@ -140,8 +140,8 @@
/*******************************************************************************
* UART related constants
******************************************************************************/
-#define ZYNQMP_UART0_BASE 0xFF000000
-#define ZYNQMP_UART1_BASE 0xFF010000
+#define ZYNQMP_UART0_BASE U(0xFF000000)
+#define ZYNQMP_UART1_BASE U(0xFF010000)
#if ZYNQMP_CONSOLE_IS(cadence) || ZYNQMP_CONSOLE_IS(dcc)
# define ZYNQMP_UART_BASE ZYNQMP_UART0_BASE
@@ -163,43 +163,43 @@
#define ZYNQMP_CSU_VERSION_SILICON 0
#define ZYNQMP_CSU_VERSION_QEMU 3
-#define ZYNQMP_RTL_VER_MASK 0xFF0
+#define ZYNQMP_RTL_VER_MASK 0xFF0U
#define ZYNQMP_RTL_VER_SHIFT 4
-#define ZYNQMP_PS_VER_MASK 0xF
+#define ZYNQMP_PS_VER_MASK 0xFU
#define ZYNQMP_PS_VER_SHIFT 0
-#define ZYNQMP_CSU_BASEADDR 0xFFCA0000
-#define ZYNQMP_CSU_IDCODE_OFFSET 0x40
+#define ZYNQMP_CSU_BASEADDR U(0xFFCA0000)
+#define ZYNQMP_CSU_IDCODE_OFFSET 0x40U
-#define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT 0
-#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK (0xFFF << \
+#define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT 0U
+#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK (0xFFFU << \
ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
#define ZYNQMP_CSU_IDCODE_XILINX_ID 0x093
-#define ZYNQMP_CSU_IDCODE_SVD_SHIFT 12
-#define ZYNQMP_CSU_IDCODE_SVD_MASK (0x7 << \
+#define ZYNQMP_CSU_IDCODE_SVD_SHIFT 12U
+#define ZYNQMP_CSU_IDCODE_SVD_MASK (0x7U << \
ZYNQMP_CSU_IDCODE_SVD_SHIFT)
-#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT 15
-#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK (0xF << \
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT 15U
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK (0xFU << \
ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
-#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT 19
-#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK (0x3 << \
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT 19U
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK (0x3U << \
ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
-#define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT 21
-#define ZYNQMP_CSU_IDCODE_FAMILY_MASK (0x7F << \
+#define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT 21U
+#define ZYNQMP_CSU_IDCODE_FAMILY_MASK (0x7FU << \
ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
#define ZYNQMP_CSU_IDCODE_FAMILY 0x23
-#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT 28
-#define ZYNQMP_CSU_IDCODE_REVISION_MASK (0xF << \
+#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT 28U
+#define ZYNQMP_CSU_IDCODE_REVISION_MASK (0xFU << \
ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
-#define ZYNQMP_CSU_IDCODE_REVISION 0
+#define ZYNQMP_CSU_IDCODE_REVISION 0U
-#define ZYNQMP_CSU_VERSION_OFFSET 0x44
+#define ZYNQMP_CSU_VERSION_OFFSET 0x44U
/* Efuse */
-#define EFUSE_BASEADDR 0xFFCC0000
+#define EFUSE_BASEADDR U(0xFFCC0000)
#define EFUSE_IPDISABLE_OFFSET 0x1018
#define EFUSE_IPDISABLE_VERSION 0x1FFU
#define ZYNQMP_EFUSE_IPDISABLE_SHIFT 20
@@ -352,14 +352,14 @@
#define RESTART_SCOPE_SHIFT (3)
#define RESTART_SCOPE_MASK (0x3U << RESTART_SCOPE_SHIFT)
-/*AFI registers */
+/* AFI registers */
#define AFIFM6_WRCTRL U(13)
#define FABRIC_WIDTH U(3)
/* CSUDMA Module Base Address*/
-#define CSUDMA_BASE 0xFFC80000
+#define CSUDMA_BASE U(0xFFC80000)
/* RSA-CORE Module Base Address*/
-#define RSA_CORE_BASE 0xFFCE0000
+#define RSA_CORE_BASE U(0xFFCE0000)
#endif /* ZYNQMP_DEF_H */
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index b2b473a..b7408b1 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -19,9 +19,9 @@
#include "pm_api_sys.h"
#include "pm_client.h"
-uintptr_t zynqmp_sec_entry;
+static uintptr_t zynqmp_sec_entry;
-void zynqmp_cpu_standby(plat_local_state_t cpu_state)
+static void zynqmp_cpu_standby(plat_local_state_t cpu_state)
{
VERBOSE("%s: cpu_state: 0x%x\n", __func__, cpu_state);
@@ -29,18 +29,18 @@
wfi();
}
-static int zynqmp_pwr_domain_on(u_register_t mpidr)
+static int32_t zynqmp_pwr_domain_on(u_register_t mpidr)
{
- unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
+ uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
const struct pm_proc *proc;
uint32_t buff[3];
enum pm_ret_status ret;
VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
- if (cpu_id == -1)
+ if (cpu_id == -1) {
return PSCI_E_INTERN_FAIL;
-
+ }
proc = pm_get_proc(cpu_id);
/* Check the APU proc status before wakeup */
@@ -60,12 +60,13 @@
static void zynqmp_pwr_domain_off(const psci_power_state_t *target_state)
{
- unsigned int cpu_id = plat_my_core_pos();
+ uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+ for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
+ }
/* Prevent interrupts from spuriously waking up this cpu */
gicv2_cpuif_disable();
@@ -83,8 +84,8 @@
static void zynqmp_pwr_domain_suspend(const psci_power_state_t *target_state)
{
- unsigned int state;
- unsigned int cpu_id = plat_my_core_pos();
+ uint32_t state;
+ uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
@@ -106,21 +107,23 @@
static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+ for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
+ }
plat_arm_gic_pcpu_init();
gicv2_cpuif_enable();
}
static void zynqmp_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
{
- unsigned int cpu_id = plat_my_core_pos();
+ uint32_t cpu_id = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpu_id);
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
+ for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
+ }
/* Clear the APU power control register for this cpu */
pm_client_wakeup(proc);
@@ -149,8 +152,9 @@
pm_system_shutdown(PMF_SHUTDOWN_TYPE_SHUTDOWN,
pm_get_shutdown_scope());
- while (1)
+ while (1) {
wfi();
+ }
}
static void __dead2 zynqmp_system_reset(void)
@@ -162,33 +166,35 @@
pm_system_shutdown(PMF_SHUTDOWN_TYPE_RESET,
pm_get_shutdown_scope());
- while (1)
+ while (1) {
wfi();
+ }
}
-int zynqmp_validate_power_state(unsigned int power_state,
+static int32_t zynqmp_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state)
{
VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
- int pstate = psci_get_pstate_type(power_state);
+ uint32_t pstate = psci_get_pstate_type(power_state);
assert(req_state);
/* Sanity check the requested state */
- if (pstate == PSTATE_TYPE_STANDBY)
+ if (pstate == PSTATE_TYPE_STANDBY) {
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
- else
+ } else {
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
-
+ }
/* We expect the 'state id' to be zero */
- if (psci_get_pstate_id(power_state))
+ if (psci_get_pstate_id(power_state)) {
return PSCI_E_INVALID_PARAMS;
+ }
return PSCI_E_SUCCESS;
}
-void zynqmp_get_sys_suspend_power_state(psci_power_state_t *req_state)
+static void zynqmp_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] = PLAT_MAX_OFF_STATE;
req_state->pwr_domain_state[1] = PLAT_MAX_OFF_STATE;
diff --git a/plat/xilinx/zynqmp/plat_topology.c b/plat/xilinx/zynqmp/plat_topology.c
index aab24aa..41add9f 100644
--- a/plat/xilinx/zynqmp/plat_topology.c
+++ b/plat/xilinx/zynqmp/plat_topology.c
@@ -3,10 +3,11 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <stdint.h>
-static const unsigned char plat_power_domain_tree_desc[] = {1, 4};
+static const uint8_t plat_power_domain_tree_desc[] = {1, 4};
-const unsigned char *plat_get_power_domain_tree_desc(void)
+const uint8_t *plat_get_power_domain_tree_desc(void)
{
return plat_power_domain_tree_desc;
}
diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c
index 58a52a3..25ebac6 100644
--- a/plat/xilinx/zynqmp/plat_zynqmp.c
+++ b/plat/xilinx/zynqmp/plat_zynqmp.c
@@ -7,7 +7,7 @@
#include <plat_private.h>
#include <plat/common/platform.h>
-int plat_core_pos_by_mpidr(u_register_t mpidr)
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
{
if (mpidr & MPIDR_CLUSTER_MASK) {
return -1;
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 620bf6c..dd82bc0 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -21,6 +21,10 @@
WORKAROUND_CVE_2017_5715 := 0
+ARM_XLAT_TABLES_LIB_V1 := 1
+$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
+$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
+
ifdef ZYNQMP_ATF_MEM_BASE
$(eval $(call add_define,ZYNQMP_ATF_MEM_BASE))
@@ -56,6 +60,10 @@
$(eval $(call add_define,IPI_CRC_CHECK))
endif
+ifdef ZYNQMP_SECURE_EFUSES
+ $(eval $(call add_define,ZYNQMP_SECURE_EFUSES))
+endif
+
PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
-Iinclude/plat/arm/common/aarch64/ \
-Iplat/xilinx/common/include/ \
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 4109830..c6bed7d 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -228,8 +228,8 @@
struct pm_clock {
char name[CLK_NAME_LEN];
uint8_t num_nodes;
- unsigned int control_reg;
- unsigned int status_reg;
+ uint32_t control_reg;
+ uint32_t status_reg;
int32_t (*parents)[];
struct pm_clock_node(*nodes)[];
};
@@ -2396,7 +2396,7 @@
*
* Return: Returns 1 if clock is valid else 0.
*/
-static bool pm_clock_valid(unsigned int clock_id)
+static bool pm_clock_valid(uint32_t clock_id)
{
unsigned int i;
@@ -2415,7 +2415,7 @@
*
* Return: Returns type of clock (OUTPUT/EXTERNAL).
*/
-static unsigned int pm_clock_type(unsigned int clock_id)
+static uint32_t pm_clock_type(uint32_t clock_id)
{
return (clock_id < CLK_MAX_OUTPUT_CLK) ?
CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL;
@@ -2429,7 +2429,7 @@
*
* @return Returns success.
*/
-enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks)
+enum pm_ret_status pm_api_clock_get_num_clocks(uint32_t *nclocks)
{
*nclocks = CLK_MAX;
@@ -2444,18 +2444,19 @@
* This function is used by master to get nmae of clock specified
* by given clock ID.
*/
-void pm_api_clock_get_name(unsigned int clock_id, char *name)
+void pm_api_clock_get_name(uint32_t clock_id, char *name)
{
- if (clock_id == CLK_MAX)
+ if (clock_id == CLK_MAX) {
memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ?
CLK_NAME_LEN : sizeof(END_OF_CLK));
- else if (!pm_clock_valid(clock_id))
+ } else if (!pm_clock_valid(clock_id)) {
memset(name, 0, CLK_NAME_LEN);
- else if (clock_id < CLK_MAX_OUTPUT_CLK)
+ } else if (clock_id < CLK_MAX_OUTPUT_CLK) {
memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
- else
+ } else {
memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
CLK_NAME_LEN);
+ }
}
/**
@@ -2471,33 +2472,37 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
- unsigned int index,
+enum pm_ret_status pm_api_clock_get_topology(uint32_t clock_id,
+ uint32_t index,
uint32_t *topology)
{
struct pm_clock_node *clock_nodes;
uint8_t num_nodes;
- unsigned int i;
+ uint32_t i;
uint16_t typeflags;
- if (!pm_clock_valid(clock_id))
+ if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
+ }
- if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
return PM_RET_ERROR_NOTSUPPORTED;
-
+ }
memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
clock_nodes = *clocks[clock_id].nodes;
num_nodes = clocks[clock_id].num_nodes;
/* Skip parent till index */
- if (index >= num_nodes)
+ if (index >= num_nodes) {
return PM_RET_SUCCESS;
+ }
for (i = 0; i < 3U; i++) {
- if ((index + i) == num_nodes)
+ if ((index + i) == num_nodes) {
break;
+ }
+
topology[i] = clock_nodes[index + i].type;
topology[i] |= clock_nodes[index + i].clkflags <<
CLK_CLKFLAGS_SHIFT;
@@ -2523,19 +2528,21 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
+enum pm_ret_status pm_api_clock_get_fixedfactor_params(uint32_t clock_id,
uint32_t *mul,
uint32_t *div)
{
struct pm_clock_node *clock_nodes;
uint8_t num_nodes;
- unsigned int type, i;
+ uint32_t type, i;
- if (!pm_clock_valid(clock_id))
+ if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
+ }
- if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
return PM_RET_ERROR_NOTSUPPORTED;
+ }
clock_nodes = *clocks[clock_id].nodes;
num_nodes = clocks[clock_id].num_nodes;
@@ -2550,8 +2557,9 @@
}
/* Clock is not fixed clock */
- if (i == num_nodes)
+ if (i == num_nodes) {
return PM_RET_ERROR_ARGS;
+ }
return PM_RET_SUCCESS;
}
@@ -2573,34 +2581,40 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
- unsigned int index,
+enum pm_ret_status pm_api_clock_get_parents(uint32_t clock_id,
+ uint32_t index,
uint32_t *parents)
{
- unsigned int i;
+ uint32_t i;
int32_t *clk_parents;
- if (!pm_clock_valid(clock_id))
+ if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
+ }
- if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
return PM_RET_ERROR_NOTSUPPORTED;
+ }
clk_parents = *clocks[clock_id].parents;
- if (clk_parents == NULL)
+ if (clk_parents == NULL) {
return PM_RET_ERROR_ARGS;
+ }
memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
/* Skip parent till index */
- for (i = 0; i < index; i++)
- if (clk_parents[i] == CLK_NA_PARENT)
+ for (i = 0; i < index; i++) {
+ if (clk_parents[i] == CLK_NA_PARENT) {
return PM_RET_SUCCESS;
+ }
+ }
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < 3U; i++) {
parents[i] = clk_parents[index + i];
- if (clk_parents[index + i] == CLK_NA_PARENT)
+ if (clk_parents[index + i] == CLK_NA_PARENT) {
break;
+ }
}
return PM_RET_SUCCESS;
@@ -2616,11 +2630,12 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
+enum pm_ret_status pm_api_clock_get_attributes(uint32_t clock_id,
uint32_t *attr)
{
- if (clock_id >= CLK_MAX)
+ if (clock_id >= CLK_MAX) {
return PM_RET_ERROR_ARGS;
+ }
/* Clock valid bit */
*attr = pm_clock_valid(clock_id);
@@ -2648,8 +2663,9 @@
uint32_t i;
struct pm_clock_node *nodes;
- if (clock_id >= CLK_MAX_OUTPUT_CLK)
+ if (clock_id >= CLK_MAX_OUTPUT_CLK) {
return PM_RET_ERROR_ARGS;
+ }
nodes = *clocks[clock_id].nodes;
for (i = 0; i < clocks[clock_id].num_nodes; i++) {
@@ -2738,8 +2754,9 @@
uint32_t i;
for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
- if (pm_plls[i].cid == clock_id)
+ if (pm_plls[i].cid == clock_id) {
return &pm_plls[i];
+ }
}
return NULL;
@@ -2798,12 +2815,14 @@
*/
enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll)
{
- if (!pll)
+ if (!pll) {
return PM_RET_ERROR_ARGS;
+ }
/* Set the PLL mode according to the buffered mode value */
- if (pll->mode == PLL_FRAC_MODE)
+ if (pll->mode == PLL_FRAC_MODE) {
return pm_pll_set_mode(pll->nid, PM_PLL_MODE_FRACTIONAL);
+ }
return pm_pll_set_mode(pll->nid, PM_PLL_MODE_INTEGER);
}
@@ -2819,8 +2838,9 @@
*/
enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll)
{
- if (!pll)
+ if (!pll) {
return PM_RET_ERROR_ARGS;
+ }
return pm_pll_set_mode(pll->nid, PM_PLL_MODE_RESET);
}
@@ -2837,22 +2857,25 @@
* returned state value is valid or an error if returned by PMU
*/
enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
- unsigned int *state)
+ uint32_t *state)
{
enum pm_ret_status status;
enum pm_pll_mode mode;
- if (!pll || !state)
+ if (!pll || !state) {
return PM_RET_ERROR_ARGS;
+ }
status = pm_pll_get_mode(pll->nid, &mode);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
- if (mode == PM_PLL_MODE_RESET)
+ if (mode == PM_PLL_MODE_RESET) {
*state = 0;
- else
+ } else {
*state = 1;
+ }
return PM_RET_SUCCESS;
}
@@ -2871,19 +2894,23 @@
*/
enum pm_ret_status pm_clock_pll_set_parent(struct pm_pll *pll,
enum clock_id clock_id,
- unsigned int parent_index)
+ uint32_t parent_index)
{
- if (!pll)
+ if (!pll) {
return PM_RET_ERROR_ARGS;
- if (pll->pre_src == clock_id)
+ }
+ if (pll->pre_src == clock_id) {
return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
parent_index);
- if (pll->post_src == clock_id)
+ }
+ if (pll->post_src == clock_id) {
return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
parent_index);
- if (pll->div2 == clock_id)
+ }
+ if (pll->div2 == clock_id) {
return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_DIV2,
parent_index);
+ }
return PM_RET_ERROR_ARGS;
}
@@ -2900,19 +2927,23 @@
*/
enum pm_ret_status pm_clock_pll_get_parent(struct pm_pll *pll,
enum clock_id clock_id,
- unsigned int *parent_index)
+ uint32_t *parent_index)
{
- if (!pll)
+ if (!pll) {
return PM_RET_ERROR_ARGS;
- if (pll->pre_src == clock_id)
+ }
+ if (pll->pre_src == clock_id) {
return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
parent_index);
- if (pll->post_src == clock_id)
+ }
+ if (pll->post_src == clock_id) {
return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
parent_index);
- if (pll->div2 == clock_id)
+ }
+ if (pll->div2 == clock_id) {
return pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_DIV2,
parent_index);
+ }
if (pll->bypass == clock_id) {
*parent_index = 0;
return PM_RET_SUCCESS;
@@ -2931,12 +2962,13 @@
* @return Success if mode is buffered or error if an argument is invalid
*/
enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id,
- unsigned int mode)
+ uint32_t mode)
{
struct pm_pll *pll = pm_clock_get_pll(clock_id);
- if (!pll || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE))
+ if (!pll || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) {
return PM_RET_ERROR_ARGS;
+ }
pll->mode = mode;
return PM_RET_SUCCESS;
@@ -2952,12 +2984,13 @@
* @return Success if mode is stored or error if an argument is invalid
*/
enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
- unsigned int *mode)
+ uint32_t *mode)
{
struct pm_pll *pll = pm_clock_get_pll(clock_id);
- if (!pll || !mode)
+ if (!pll || !mode) {
return PM_RET_ERROR_ARGS;
+ }
*mode = pll->mode;
return PM_RET_SUCCESS;
@@ -2969,13 +3002,15 @@
*
* @return Returns success if clock_id is valid, otherwise an error
*/
-enum pm_ret_status pm_clock_id_is_valid(unsigned int clock_id)
+enum pm_ret_status pm_clock_id_is_valid(uint32_t clock_id)
{
- if (!pm_clock_valid(clock_id))
+ if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
+ }
- if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
return PM_RET_ERROR_NOTSUPPORTED;
+ }
return PM_RET_SUCCESS;
}
@@ -2987,13 +3022,14 @@
*
* @return True(1)=clock has the divider, false(0)=otherwise
*/
-uint8_t pm_clock_has_div(unsigned int clock_id, enum pm_clock_div_id div_id)
+uint8_t pm_clock_has_div(uint32_t clock_id, enum pm_clock_div_id div_id)
{
uint32_t i;
struct pm_clock_node *nodes;
- if (clock_id >= CLK_MAX_OUTPUT_CLK)
+ if (clock_id >= CLK_MAX_OUTPUT_CLK) {
return 0;
+ }
nodes = *clocks[clock_id].nodes;
for (i = 0; i < clocks[clock_id].num_nodes; i++) {
@@ -3003,6 +3039,8 @@
} else if (nodes[i].type == TYPE_DIV2) {
if (div_id == PM_CLOCK_DIV1_ID)
return 1;
+ } else {
+ /* To fix the misra 15.7 warning */
}
}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index 5efd63f..bc15592 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -292,20 +292,20 @@
struct pm_pll;
struct pm_pll *pm_clock_get_pll(enum clock_id clock_id);
struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id);
-uint8_t pm_clock_has_div(unsigned int clock_id, enum pm_clock_div_id div_id);
+uint8_t pm_clock_has_div(uint32_t clock_id, enum pm_clock_div_id div_id);
-void pm_api_clock_get_name(unsigned int clock_id, char *name);
-enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks);
-enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
- unsigned int index,
+void pm_api_clock_get_name(uint32_t clock_id, char *name);
+enum pm_ret_status pm_api_clock_get_num_clocks(uint32_t *nclocks);
+enum pm_ret_status pm_api_clock_get_topology(uint32_t clock_id,
+ uint32_t index,
uint32_t *topology);
-enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
+enum pm_ret_status pm_api_clock_get_fixedfactor_params(uint32_t clock_id,
uint32_t *mul,
uint32_t *div);
-enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
- unsigned int index,
+enum pm_ret_status pm_api_clock_get_parents(uint32_t clock_id,
+ uint32_t index,
uint32_t *parents);
-enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
+enum pm_ret_status pm_api_clock_get_attributes(uint32_t clock_id,
uint32_t *attr);
enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id,
uint8_t div_type,
@@ -313,21 +313,21 @@
enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id,
enum pm_node_id *node_id);
-enum pm_ret_status pm_clock_id_is_valid(unsigned int clock_id);
+enum pm_ret_status pm_clock_id_is_valid(uint32_t clock_id);
enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll);
enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll);
enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
- unsigned int *state);
+ uint32_t *state);
enum pm_ret_status pm_clock_pll_set_parent(struct pm_pll *pll,
enum clock_id clock_id,
- unsigned int parent_index);
+ uint32_t parent_index);
enum pm_ret_status pm_clock_pll_get_parent(struct pm_pll *pll,
enum clock_id clock_id,
- unsigned int *parent_index);
+ uint32_t *parent_index);
enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id,
- unsigned int mode);
+ uint32_t mode);
enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
- unsigned int *mode);
+ uint32_t *mode);
#endif /* PM_API_CLOCK_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index a87681b..48e1b8d 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -29,16 +29,17 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(unsigned int *mode)
+static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(uint32_t *mode)
{
- unsigned int val;
+ uint32_t val;
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
val &= ZYNQMP_SLSPLIT_MASK;
- if (val == 0)
+ if (val == 0U) {
*mode = PM_RPU_MODE_LOCKSTEP;
- else
+ } else {
*mode = PM_RPU_MODE_SPLIT;
+ }
return PM_RET_SUCCESS;
}
@@ -54,12 +55,13 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(unsigned int mode)
+static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
{
- unsigned int val;
+ uint32_t val;
- if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET)
+ if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) {
return PM_RET_ERROR_ACCESS;
+ }
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
@@ -90,25 +92,27 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
- unsigned int value)
+ uint32_t value)
{
- unsigned int rpu_cfg_addr, val;
+ uint32_t rpu_cfg_addr, val;
- if (nid == NODE_RPU_0)
+ if (nid == NODE_RPU_0) {
rpu_cfg_addr = ZYNQMP_RPU0_CFG;
- else if (nid == NODE_RPU_1)
+ } else if (nid == NODE_RPU_1) {
rpu_cfg_addr = ZYNQMP_RPU1_CFG;
- else
+ } else {
return PM_RET_ERROR_ARGS;
+ }
val = mmio_read_32(rpu_cfg_addr);
- if (value == PM_RPU_BOOTMEM_LOVEC)
+ if (value == PM_RPU_BOOTMEM_LOVEC) {
val &= ~ZYNQMP_VINITHI_MASK;
- else if (value == PM_RPU_BOOTMEM_HIVEC)
+ } else if (value == PM_RPU_BOOTMEM_HIVEC) {
val |= ZYNQMP_VINITHI_MASK;
- else
+ } else {
return PM_RET_ERROR_ARGS;
+ }
mmio_write_32(rpu_cfg_addr, val);
@@ -124,18 +128,19 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_config_tcm_comb(unsigned int value)
+static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
{
- unsigned int val;
+ uint32_t val;
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
- if (value == PM_RPU_TCM_SPLIT)
+ if (value == PM_RPU_TCM_SPLIT) {
val &= ~ZYNQMP_TCM_COMB_MASK;
- else if (value == PM_RPU_TCM_COMB)
+ } else if (value == PM_RPU_TCM_COMB) {
val |= ZYNQMP_TCM_COMB_MASK;
- else
+ } else {
return PM_RET_ERROR_ARGS;
+ }
mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
@@ -151,12 +156,13 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(unsigned int type,
- unsigned int value)
+static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
+ uint32_t value)
{
if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
- value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX)
+ value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX) {
return PM_RET_ERROR_ARGS;
+ }
return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
}
@@ -173,13 +179,14 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
- unsigned int value)
+ uint32_t value)
{
- unsigned int val, mask, shift;
+ uint32_t val, mask, shift;
enum pm_ret_status ret;
- if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE)
+ if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE) {
return PM_RET_ERROR_ARGS;
+ }
switch (nid) {
case NODE_ETH_0:
@@ -206,8 +213,9 @@
mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
return ret;
+ }
/* Set the GEM to SGMII mode */
mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
@@ -229,9 +237,9 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
- unsigned int type)
+ uint32_t type)
{
- unsigned int mask, val;
+ uint32_t mask, val;
enum pm_ret_status ret;
if (nid == NODE_SD_0) {
@@ -248,11 +256,13 @@
case PM_DLL_RESET_ASSERT:
case PM_DLL_RESET_PULSE:
ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
return ret;
+ }
- if (type == PM_DLL_RESET_ASSERT)
+ if (type == PM_DLL_RESET_ASSERT) {
break;
+ }
mdelay(1);
/* Fallthrough */
case PM_DLL_RESET_RELEASE:
@@ -278,11 +288,11 @@
*/
static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
enum tap_delay_type type,
- unsigned int value)
+ uint32_t value)
{
- unsigned int shift;
+ uint32_t shift;
enum pm_ret_status ret;
- unsigned int val, mask;
+ uint32_t val, mask;
if (nid == NODE_SD_0) {
shift = 0;
@@ -299,7 +309,7 @@
return ret;
}
- if ((val & mask) == 0) {
+ if ((val & mask) == 0U) {
ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
if (ret != PM_RET_SUCCESS) {
return ret;
@@ -310,31 +320,44 @@
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
(ZYNQMP_SD_ITAPCHGWIN << shift));
- if (ret != PM_RET_SUCCESS)
+
+ if (ret != PM_RET_SUCCESS) {
goto reset_release;
- if (value == 0)
+ }
+
+ if (value == 0U) {
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPDLYENA_MASK <<
shift), 0);
- else
+ } else {
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPDLYENA_MASK <<
shift), (ZYNQMP_SD_ITAPDLYENA <<
shift));
- if (ret != PM_RET_SUCCESS)
+ }
+
+ if (ret != PM_RET_SUCCESS) {
goto reset_release;
+ }
+
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
(value << shift));
- if (ret != PM_RET_SUCCESS)
+
+ if (ret != PM_RET_SUCCESS) {
goto reset_release;
+ }
+
ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
(ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
} else if (type == PM_TAPDELAY_OUTPUT) {
ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
(ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
- if (ret != PM_RET_SUCCESS)
+
+ if (ret != PM_RET_SUCCESS) {
goto reset_release;
+ }
+
ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
(ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
(value << shift));
@@ -361,7 +384,7 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_set_pll_frac_mode
- (unsigned int pll, unsigned int mode)
+ (uint32_t pll, uint32_t mode)
{
return pm_clock_set_pll_mode(pll, mode);
}
@@ -377,7 +400,7 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_get_pll_frac_mode
- (unsigned int pll, unsigned int *mode)
+ (uint32_t pll, uint32_t *mode)
{
return pm_clock_get_pll_mode(pll, mode);
}
@@ -394,15 +417,16 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_set_pll_frac_data
- (unsigned int pll, unsigned int data)
+ (uint32_t pll, uint32_t data)
{
enum pm_node_id pll_nid;
enum pm_ret_status status;
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(pll, &pll_nid);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
}
@@ -418,15 +442,16 @@
* @return Returns status, either success or error+reason
*/
static enum pm_ret_status pm_ioctl_get_pll_frac_data
- (unsigned int pll, unsigned int *data)
+ (uint32_t pll, uint32_t *data)
{
enum pm_node_id pll_nid;
enum pm_ret_status status;
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(pll, &pll_nid);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
}
@@ -441,11 +466,12 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
- unsigned int value)
+static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
+ uint32_t value)
{
- if (index >= GGS_NUM_REGS)
+ if (index >= GGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
+ }
return pm_mmio_write(GGS_BASEADDR + (index << 2),
0xFFFFFFFFU, value);
@@ -461,11 +487,12 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
- unsigned int *value)
+static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
+ uint32_t *value)
{
- if (index >= GGS_NUM_REGS)
+ if (index >= GGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
+ }
return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
}
@@ -480,11 +507,12 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
- unsigned int value)
+static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
+ uint32_t value)
{
- if (index >= PGGS_NUM_REGS)
+ if (index >= PGGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
+ }
return pm_mmio_write(PGGS_BASEADDR + (index << 2),
0xFFFFFFFFU, value);
@@ -499,35 +527,37 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_afi(unsigned int index,
- unsigned int value)
+static enum pm_ret_status pm_ioctl_afi(uint32_t index,
+ uint32_t value)
{
- unsigned int mask;
- unsigned int regarr[] = {0xFD360000,
- 0xFD360014,
- 0xFD370000,
- 0xFD370014,
- 0xFD380000,
- 0xFD380014,
- 0xFD390000,
- 0xFD390014,
- 0xFD3a0000,
- 0xFD3a0014,
- 0xFD3b0000,
- 0xFD3b0014,
- 0xFF9b0000,
- 0xFF9b0014,
- 0xFD615000,
- 0xFF419000,
+ uint32_t mask;
+ uint32_t regarr[] = {0xFD360000U,
+ 0xFD360014U,
+ 0xFD370000U,
+ 0xFD370014U,
+ 0xFD380000U,
+ 0xFD380014U,
+ 0xFD390000U,
+ 0xFD390014U,
+ 0xFD3a0000U,
+ 0xFD3a0014U,
+ 0xFD3b0000U,
+ 0xFD3b0014U,
+ 0xFF9b0000U,
+ 0xFF9b0014U,
+ 0xFD615000U,
+ 0xFF419000U,
};
- if (index >= ARRAY_SIZE(regarr))
+ if (index >= ARRAY_SIZE(regarr)) {
return PM_RET_ERROR_ARGS;
+ }
- if (index < AFIFM6_WRCTRL)
+ if (index <= AFIFM6_WRCTRL) {
mask = FABRIC_WIDTH;
- else
+ } else {
mask = 0xf00;
+ }
return pm_mmio_write(regarr[index], mask, value);
}
@@ -542,11 +572,12 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
- unsigned int *value)
+static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
+ uint32_t *value)
{
- if (index >= PGGS_NUM_REGS)
+ if (index >= PGGS_NUM_REGS) {
return PM_RET_ERROR_ARGS;
+ }
return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
}
@@ -565,16 +596,18 @@
ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
ZYNQMP_ULPI_RESET_VAL_HIGH);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
return ret;
+ }
/* Drive ULPI assert for atleast 1ms */
mdelay(1);
ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
ZYNQMP_ULPI_RESET_VAL_LOW);
- if (ret != PM_RET_SUCCESS)
+ if (ret != PM_RET_SUCCESS) {
return ret;
+ }
/* Drive ULPI de-assert for atleast 1ms */
mdelay(1);
@@ -593,7 +626,7 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_ioctl_set_boot_health_status(unsigned int value)
+static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value)
{
return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4,
PM_BOOT_HEALTH_STATUS_MASK, value);
@@ -612,10 +645,10 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
- unsigned int ioctl_id,
- unsigned int arg1,
- unsigned int arg2,
- unsigned int *value)
+ uint32_t ioctl_id,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t *value)
{
enum pm_ret_status ret;
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -717,7 +750,7 @@
IOCTL_AFI,
};
uint8_t i, ioctl_id;
- int ret;
+ int32_t ret;
for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
ioctl_id = supported_ids[i];
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
index 0c5f33f..3b0d6ee 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -88,9 +88,9 @@
#define PM_DLL_RESET_PULSE 2U
enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
- unsigned int ioctl_id,
- unsigned int arg1,
- unsigned int arg2,
- unsigned int *value);
+ uint32_t ioctl_id,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t *value);
enum pm_ret_status atf_ioctl_bitmask(uint32_t *bit_mask);
#endif /* PM_API_IOCTL_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 9a6b497..0192f81 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -21,7 +21,8 @@
struct pinctrl_function {
char name[FUNCTION_NAME_LEN];
- uint16_t (*groups)[];
+ uint16_t group_base;
+ uint8_t group_size;
uint8_t regval;
};
@@ -36,904 +37,344 @@
[PINCTRL_FUNC_CAN0] = {
.name = "can0",
.regval = 0x20,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_CAN0_0,
- PINCTRL_GRP_CAN0_1,
- PINCTRL_GRP_CAN0_2,
- PINCTRL_GRP_CAN0_3,
- PINCTRL_GRP_CAN0_4,
- PINCTRL_GRP_CAN0_5,
- PINCTRL_GRP_CAN0_6,
- PINCTRL_GRP_CAN0_7,
- PINCTRL_GRP_CAN0_8,
- PINCTRL_GRP_CAN0_9,
- PINCTRL_GRP_CAN0_10,
- PINCTRL_GRP_CAN0_11,
- PINCTRL_GRP_CAN0_12,
- PINCTRL_GRP_CAN0_13,
- PINCTRL_GRP_CAN0_14,
- PINCTRL_GRP_CAN0_15,
- PINCTRL_GRP_CAN0_16,
- PINCTRL_GRP_CAN0_17,
- PINCTRL_GRP_CAN0_18,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_CAN0_0,
+ .group_size = PINCTRL_GRP_CAN0_18 - PINCTRL_GRP_CAN0_0 + 1U,
},
[PINCTRL_FUNC_CAN1] = {
.name = "can1",
.regval = 0x20,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_CAN1_0,
- PINCTRL_GRP_CAN1_1,
- PINCTRL_GRP_CAN1_2,
- PINCTRL_GRP_CAN1_3,
- PINCTRL_GRP_CAN1_4,
- PINCTRL_GRP_CAN1_5,
- PINCTRL_GRP_CAN1_6,
- PINCTRL_GRP_CAN1_7,
- PINCTRL_GRP_CAN1_8,
- PINCTRL_GRP_CAN1_9,
- PINCTRL_GRP_CAN1_10,
- PINCTRL_GRP_CAN1_11,
- PINCTRL_GRP_CAN1_12,
- PINCTRL_GRP_CAN1_13,
- PINCTRL_GRP_CAN1_14,
- PINCTRL_GRP_CAN1_15,
- PINCTRL_GRP_CAN1_16,
- PINCTRL_GRP_CAN1_17,
- PINCTRL_GRP_CAN1_18,
- PINCTRL_GRP_CAN1_19,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_CAN1_0,
+ .group_size = PINCTRL_GRP_CAN1_19 - PINCTRL_GRP_CAN1_0 + 1U,
},
[PINCTRL_FUNC_ETHERNET0] = {
.name = "ethernet0",
.regval = 0x02,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_ETHERNET0_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_ETHERNET0_0,
+ .group_size = PINCTRL_GRP_ETHERNET0_0 - PINCTRL_GRP_ETHERNET0_0 + 1U,
},
[PINCTRL_FUNC_ETHERNET1] = {
.name = "ethernet1",
.regval = 0x02,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_ETHERNET1_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_ETHERNET1_0,
+ .group_size = PINCTRL_GRP_ETHERNET1_0 - PINCTRL_GRP_ETHERNET1_0 + 1U,
},
[PINCTRL_FUNC_ETHERNET2] = {
.name = "ethernet2",
.regval = 0x02,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_ETHERNET2_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_ETHERNET2_0,
+ .group_size = PINCTRL_GRP_ETHERNET2_0 - PINCTRL_GRP_ETHERNET2_0 + 1U,
},
[PINCTRL_FUNC_ETHERNET3] = {
.name = "ethernet3",
.regval = 0x02,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_ETHERNET3_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_ETHERNET3_0,
+ .group_size = PINCTRL_GRP_ETHERNET3_0 - PINCTRL_GRP_ETHERNET3_0 + 1U,
},
[PINCTRL_FUNC_GEMTSU0] = {
.name = "gemtsu0",
.regval = 0x02,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_GEMTSU0_0,
- PINCTRL_GRP_GEMTSU0_1,
- PINCTRL_GRP_GEMTSU0_2,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_GEMTSU0_0,
+ .group_size = PINCTRL_GRP_GEMTSU0_2 - PINCTRL_GRP_GEMTSU0_0 + 1U,
},
[PINCTRL_FUNC_GPIO0] = {
.name = "gpio0",
.regval = 0x00,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_GPIO0_0,
- PINCTRL_GRP_GPIO0_1,
- PINCTRL_GRP_GPIO0_2,
- PINCTRL_GRP_GPIO0_3,
- PINCTRL_GRP_GPIO0_4,
- PINCTRL_GRP_GPIO0_5,
- PINCTRL_GRP_GPIO0_6,
- PINCTRL_GRP_GPIO0_7,
- PINCTRL_GRP_GPIO0_8,
- PINCTRL_GRP_GPIO0_9,
- PINCTRL_GRP_GPIO0_10,
- PINCTRL_GRP_GPIO0_11,
- PINCTRL_GRP_GPIO0_12,
- PINCTRL_GRP_GPIO0_13,
- PINCTRL_GRP_GPIO0_14,
- PINCTRL_GRP_GPIO0_15,
- PINCTRL_GRP_GPIO0_16,
- PINCTRL_GRP_GPIO0_17,
- PINCTRL_GRP_GPIO0_18,
- PINCTRL_GRP_GPIO0_19,
- PINCTRL_GRP_GPIO0_20,
- PINCTRL_GRP_GPIO0_21,
- PINCTRL_GRP_GPIO0_22,
- PINCTRL_GRP_GPIO0_23,
- PINCTRL_GRP_GPIO0_24,
- PINCTRL_GRP_GPIO0_25,
- PINCTRL_GRP_GPIO0_26,
- PINCTRL_GRP_GPIO0_27,
- PINCTRL_GRP_GPIO0_28,
- PINCTRL_GRP_GPIO0_29,
- PINCTRL_GRP_GPIO0_30,
- PINCTRL_GRP_GPIO0_31,
- PINCTRL_GRP_GPIO0_32,
- PINCTRL_GRP_GPIO0_33,
- PINCTRL_GRP_GPIO0_34,
- PINCTRL_GRP_GPIO0_35,
- PINCTRL_GRP_GPIO0_36,
- PINCTRL_GRP_GPIO0_37,
- PINCTRL_GRP_GPIO0_38,
- PINCTRL_GRP_GPIO0_39,
- PINCTRL_GRP_GPIO0_40,
- PINCTRL_GRP_GPIO0_41,
- PINCTRL_GRP_GPIO0_42,
- PINCTRL_GRP_GPIO0_43,
- PINCTRL_GRP_GPIO0_44,
- PINCTRL_GRP_GPIO0_45,
- PINCTRL_GRP_GPIO0_46,
- PINCTRL_GRP_GPIO0_47,
- PINCTRL_GRP_GPIO0_48,
- PINCTRL_GRP_GPIO0_49,
- PINCTRL_GRP_GPIO0_50,
- PINCTRL_GRP_GPIO0_51,
- PINCTRL_GRP_GPIO0_52,
- PINCTRL_GRP_GPIO0_53,
- PINCTRL_GRP_GPIO0_54,
- PINCTRL_GRP_GPIO0_55,
- PINCTRL_GRP_GPIO0_56,
- PINCTRL_GRP_GPIO0_57,
- PINCTRL_GRP_GPIO0_58,
- PINCTRL_GRP_GPIO0_59,
- PINCTRL_GRP_GPIO0_60,
- PINCTRL_GRP_GPIO0_61,
- PINCTRL_GRP_GPIO0_62,
- PINCTRL_GRP_GPIO0_63,
- PINCTRL_GRP_GPIO0_64,
- PINCTRL_GRP_GPIO0_65,
- PINCTRL_GRP_GPIO0_66,
- PINCTRL_GRP_GPIO0_67,
- PINCTRL_GRP_GPIO0_68,
- PINCTRL_GRP_GPIO0_69,
- PINCTRL_GRP_GPIO0_70,
- PINCTRL_GRP_GPIO0_71,
- PINCTRL_GRP_GPIO0_72,
- PINCTRL_GRP_GPIO0_73,
- PINCTRL_GRP_GPIO0_74,
- PINCTRL_GRP_GPIO0_75,
- PINCTRL_GRP_GPIO0_76,
- PINCTRL_GRP_GPIO0_77,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_GPIO0_0,
+ .group_size = PINCTRL_GRP_GPIO0_77 - PINCTRL_GRP_GPIO0_0 + 1U,
},
[PINCTRL_FUNC_I2C0] = {
.name = "i2c0",
.regval = 0x40,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_I2C0_0,
- PINCTRL_GRP_I2C0_1,
- PINCTRL_GRP_I2C0_2,
- PINCTRL_GRP_I2C0_3,
- PINCTRL_GRP_I2C0_4,
- PINCTRL_GRP_I2C0_5,
- PINCTRL_GRP_I2C0_6,
- PINCTRL_GRP_I2C0_7,
- PINCTRL_GRP_I2C0_8,
- PINCTRL_GRP_I2C0_9,
- PINCTRL_GRP_I2C0_10,
- PINCTRL_GRP_I2C0_11,
- PINCTRL_GRP_I2C0_12,
- PINCTRL_GRP_I2C0_13,
- PINCTRL_GRP_I2C0_14,
- PINCTRL_GRP_I2C0_15,
- PINCTRL_GRP_I2C0_16,
- PINCTRL_GRP_I2C0_17,
- PINCTRL_GRP_I2C0_18,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_I2C0_0,
+ .group_size = PINCTRL_GRP_I2C0_18 - PINCTRL_GRP_I2C0_0 + 1U,
},
[PINCTRL_FUNC_I2C1] = {
.name = "i2c1",
.regval = 0x40,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_I2C1_0,
- PINCTRL_GRP_I2C1_1,
- PINCTRL_GRP_I2C1_2,
- PINCTRL_GRP_I2C1_3,
- PINCTRL_GRP_I2C1_4,
- PINCTRL_GRP_I2C1_5,
- PINCTRL_GRP_I2C1_6,
- PINCTRL_GRP_I2C1_7,
- PINCTRL_GRP_I2C1_8,
- PINCTRL_GRP_I2C1_9,
- PINCTRL_GRP_I2C1_10,
- PINCTRL_GRP_I2C1_11,
- PINCTRL_GRP_I2C1_12,
- PINCTRL_GRP_I2C1_13,
- PINCTRL_GRP_I2C1_14,
- PINCTRL_GRP_I2C1_15,
- PINCTRL_GRP_I2C1_16,
- PINCTRL_GRP_I2C1_17,
- PINCTRL_GRP_I2C1_18,
- PINCTRL_GRP_I2C1_19,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_I2C1_0,
+ .group_size = PINCTRL_GRP_I2C1_19 - PINCTRL_GRP_I2C1_0 + 1U,
},
[PINCTRL_FUNC_MDIO0] = {
.name = "mdio0",
.regval = 0x60,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_MDIO0_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_MDIO0_0,
+ .group_size = PINCTRL_GRP_MDIO0_0 - PINCTRL_GRP_MDIO0_0 + 1U,
},
[PINCTRL_FUNC_MDIO1] = {
.name = "mdio1",
.regval = 0x80,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_MDIO1_0,
- PINCTRL_GRP_MDIO1_1,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_MDIO1_0,
+ .group_size = PINCTRL_GRP_MDIO1_1 - PINCTRL_GRP_MDIO1_0 + 1U,
},
[PINCTRL_FUNC_MDIO2] = {
.name = "mdio2",
.regval = 0xa0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_MDIO2_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_MDIO2_0,
+ .group_size = PINCTRL_GRP_MDIO2_0 - PINCTRL_GRP_MDIO2_0 + 1U,
},
[PINCTRL_FUNC_MDIO3] = {
.name = "mdio3",
.regval = 0xc0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_MDIO3_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_MDIO3_0,
+ .group_size = PINCTRL_GRP_MDIO3_0 - PINCTRL_GRP_MDIO3_0 + 1U,
},
[PINCTRL_FUNC_QSPI0] = {
.name = "qspi0",
.regval = 0x02,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_QSPI0_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_QSPI0_0,
+ .group_size = PINCTRL_GRP_QSPI0_0 - PINCTRL_GRP_QSPI0_0 + 1U,
},
[PINCTRL_FUNC_QSPI_FBCLK] = {
.name = "qspi_fbclk",
.regval = 0x02,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_QSPI_FBCLK,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_QSPI_FBCLK,
+ .group_size = PINCTRL_GRP_QSPI_FBCLK - PINCTRL_GRP_QSPI_FBCLK + 1U,
},
[PINCTRL_FUNC_QSPI_SS] = {
.name = "qspi_ss",
.regval = 0x02,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_QSPI_SS,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_QSPI_SS,
+ .group_size = PINCTRL_GRP_QSPI_SS - PINCTRL_GRP_QSPI_SS + 1U,
},
[PINCTRL_FUNC_SPI0] = {
.name = "spi0",
.regval = 0x80,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SPI0_0,
- PINCTRL_GRP_SPI0_1,
- PINCTRL_GRP_SPI0_2,
- PINCTRL_GRP_SPI0_3,
- PINCTRL_GRP_SPI0_4,
- PINCTRL_GRP_SPI0_5,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SPI0_0,
+ .group_size = PINCTRL_GRP_SPI0_5 - PINCTRL_GRP_SPI0_0 + 1U,
},
[PINCTRL_FUNC_SPI1] = {
.name = "spi1",
.regval = 0x80,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SPI1_0,
- PINCTRL_GRP_SPI1_1,
- PINCTRL_GRP_SPI1_2,
- PINCTRL_GRP_SPI1_3,
- PINCTRL_GRP_SPI1_4,
- PINCTRL_GRP_SPI1_5,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SPI1_0,
+ .group_size = PINCTRL_GRP_SPI1_5 - PINCTRL_GRP_SPI1_0 + 1U,
},
[PINCTRL_FUNC_SPI0_SS] = {
.name = "spi0_ss",
.regval = 0x80,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SPI0_0_SS0,
- PINCTRL_GRP_SPI0_0_SS1,
- PINCTRL_GRP_SPI0_0_SS2,
- PINCTRL_GRP_SPI0_1_SS0,
- PINCTRL_GRP_SPI0_1_SS1,
- PINCTRL_GRP_SPI0_1_SS2,
- PINCTRL_GRP_SPI0_2_SS0,
- PINCTRL_GRP_SPI0_2_SS1,
- PINCTRL_GRP_SPI0_2_SS2,
- PINCTRL_GRP_SPI0_3_SS0,
- PINCTRL_GRP_SPI0_3_SS1,
- PINCTRL_GRP_SPI0_3_SS2,
- PINCTRL_GRP_SPI0_4_SS0,
- PINCTRL_GRP_SPI0_4_SS1,
- PINCTRL_GRP_SPI0_4_SS2,
- PINCTRL_GRP_SPI0_5_SS0,
- PINCTRL_GRP_SPI0_5_SS1,
- PINCTRL_GRP_SPI0_5_SS2,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SPI0_0_SS0,
+ .group_size = PINCTRL_GRP_SPI0_5_SS2 - PINCTRL_GRP_SPI0_0_SS0 + 1U,
},
[PINCTRL_FUNC_SPI1_SS] = {
.name = "spi1_ss",
.regval = 0x80,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SPI1_0_SS0,
- PINCTRL_GRP_SPI1_0_SS1,
- PINCTRL_GRP_SPI1_0_SS2,
- PINCTRL_GRP_SPI1_1_SS0,
- PINCTRL_GRP_SPI1_1_SS1,
- PINCTRL_GRP_SPI1_1_SS2,
- PINCTRL_GRP_SPI1_2_SS0,
- PINCTRL_GRP_SPI1_2_SS1,
- PINCTRL_GRP_SPI1_2_SS2,
- PINCTRL_GRP_SPI1_3_SS0,
- PINCTRL_GRP_SPI1_3_SS1,
- PINCTRL_GRP_SPI1_3_SS2,
- PINCTRL_GRP_SPI1_4_SS0,
- PINCTRL_GRP_SPI1_4_SS1,
- PINCTRL_GRP_SPI1_4_SS2,
- PINCTRL_GRP_SPI1_5_SS0,
- PINCTRL_GRP_SPI1_5_SS1,
- PINCTRL_GRP_SPI1_5_SS2,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SPI1_0_SS0,
+ .group_size = PINCTRL_GRP_SPI1_5_SS2 - PINCTRL_GRP_SPI1_0_SS0 + 1U,
},
[PINCTRL_FUNC_SDIO0] = {
.name = "sdio0",
.regval = 0x08,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SDIO0_0,
- PINCTRL_GRP_SDIO0_1,
- PINCTRL_GRP_SDIO0_2,
- PINCTRL_GRP_SDIO0_4BIT_0_0,
- PINCTRL_GRP_SDIO0_4BIT_0_1,
- PINCTRL_GRP_SDIO0_4BIT_1_0,
- PINCTRL_GRP_SDIO0_4BIT_1_1,
- PINCTRL_GRP_SDIO0_4BIT_2_0,
- PINCTRL_GRP_SDIO0_4BIT_2_1,
- PINCTRL_GRP_SDIO0_1BIT_0_0,
- PINCTRL_GRP_SDIO0_1BIT_0_1,
- PINCTRL_GRP_SDIO0_1BIT_0_2,
- PINCTRL_GRP_SDIO0_1BIT_0_3,
- PINCTRL_GRP_SDIO0_1BIT_0_4,
- PINCTRL_GRP_SDIO0_1BIT_0_5,
- PINCTRL_GRP_SDIO0_1BIT_0_6,
- PINCTRL_GRP_SDIO0_1BIT_0_7,
- PINCTRL_GRP_SDIO0_1BIT_1_0,
- PINCTRL_GRP_SDIO0_1BIT_1_1,
- PINCTRL_GRP_SDIO0_1BIT_1_2,
- PINCTRL_GRP_SDIO0_1BIT_1_3,
- PINCTRL_GRP_SDIO0_1BIT_1_4,
- PINCTRL_GRP_SDIO0_1BIT_1_5,
- PINCTRL_GRP_SDIO0_1BIT_1_6,
- PINCTRL_GRP_SDIO0_1BIT_1_7,
- PINCTRL_GRP_SDIO0_1BIT_2_0,
- PINCTRL_GRP_SDIO0_1BIT_2_1,
- PINCTRL_GRP_SDIO0_1BIT_2_2,
- PINCTRL_GRP_SDIO0_1BIT_2_3,
- PINCTRL_GRP_SDIO0_1BIT_2_4,
- PINCTRL_GRP_SDIO0_1BIT_2_5,
- PINCTRL_GRP_SDIO0_1BIT_2_6,
- PINCTRL_GRP_SDIO0_1BIT_2_7,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SDIO0_0,
+ .group_size = PINCTRL_GRP_SDIO0_1BIT_2_7 - PINCTRL_GRP_SDIO0_0 + 1U,
},
[PINCTRL_FUNC_SDIO0_PC] = {
.name = "sdio0_pc",
.regval = 0x08,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SDIO0_0_PC,
- PINCTRL_GRP_SDIO0_1_PC,
- PINCTRL_GRP_SDIO0_2_PC,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SDIO0_0_PC,
+ .group_size = PINCTRL_GRP_SDIO0_2_PC - PINCTRL_GRP_SDIO0_0_PC + 1U,
},
[PINCTRL_FUNC_SDIO0_CD] = {
.name = "sdio0_cd",
.regval = 0x08,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SDIO0_0_CD,
- PINCTRL_GRP_SDIO0_1_CD,
- PINCTRL_GRP_SDIO0_2_CD,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SDIO0_0_CD,
+ .group_size = PINCTRL_GRP_SDIO0_2_CD - PINCTRL_GRP_SDIO0_0_CD + 1U,
},
[PINCTRL_FUNC_SDIO0_WP] = {
.name = "sdio0_wp",
.regval = 0x08,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SDIO0_0_WP,
- PINCTRL_GRP_SDIO0_1_WP,
- PINCTRL_GRP_SDIO0_2_WP,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SDIO0_0_WP,
+ .group_size = PINCTRL_GRP_SDIO0_2_WP - PINCTRL_GRP_SDIO0_0_WP + 1U,
},
[PINCTRL_FUNC_SDIO1] = {
.name = "sdio1",
.regval = 0x10,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SDIO1_0,
- PINCTRL_GRP_SDIO1_4BIT_0_0,
- PINCTRL_GRP_SDIO1_4BIT_0_1,
- PINCTRL_GRP_SDIO1_4BIT_1_0,
- PINCTRL_GRP_SDIO1_1BIT_0_0,
- PINCTRL_GRP_SDIO1_1BIT_0_1,
- PINCTRL_GRP_SDIO1_1BIT_0_2,
- PINCTRL_GRP_SDIO1_1BIT_0_3,
- PINCTRL_GRP_SDIO1_1BIT_0_4,
- PINCTRL_GRP_SDIO1_1BIT_0_5,
- PINCTRL_GRP_SDIO1_1BIT_0_6,
- PINCTRL_GRP_SDIO1_1BIT_0_7,
- PINCTRL_GRP_SDIO1_1BIT_1_0,
- PINCTRL_GRP_SDIO1_1BIT_1_1,
- PINCTRL_GRP_SDIO1_1BIT_1_2,
- PINCTRL_GRP_SDIO1_1BIT_1_3,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SDIO1_0,
+ .group_size = PINCTRL_GRP_SDIO1_1BIT_1_3 - PINCTRL_GRP_SDIO1_0 + 1U,
},
[PINCTRL_FUNC_SDIO1_PC] = {
.name = "sdio1_pc",
.regval = 0x10,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SDIO1_0_PC,
- PINCTRL_GRP_SDIO1_1_PC,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SDIO1_0_PC,
+ .group_size = PINCTRL_GRP_SDIO1_1_PC - PINCTRL_GRP_SDIO1_0_PC + 1U,
},
[PINCTRL_FUNC_SDIO1_CD] = {
.name = "sdio1_cd",
.regval = 0x10,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SDIO1_0_CD,
- PINCTRL_GRP_SDIO1_1_CD,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SDIO1_0_CD,
+ .group_size = PINCTRL_GRP_SDIO1_1_CD - PINCTRL_GRP_SDIO1_0_CD + 1U,
},
[PINCTRL_FUNC_SDIO1_WP] = {
.name = "sdio1_wp",
.regval = 0x10,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SDIO1_0_WP,
- PINCTRL_GRP_SDIO1_1_WP,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SDIO1_0_WP,
+ .group_size = PINCTRL_GRP_SDIO1_1_WP - PINCTRL_GRP_SDIO1_0_WP + 1U,
},
[PINCTRL_FUNC_NAND0] = {
.name = "nand0",
.regval = 0x04,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_NAND0_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_NAND0_0,
+ .group_size = PINCTRL_GRP_NAND0_0 - PINCTRL_GRP_NAND0_0 + 1U,
},
[PINCTRL_FUNC_NAND0_CE] = {
.name = "nand0_ce",
.regval = 0x04,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_NAND0_0_CE,
- PINCTRL_GRP_NAND0_1_CE,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_NAND0_0_CE,
+ .group_size = PINCTRL_GRP_NAND0_1_CE - PINCTRL_GRP_NAND0_0_CE + 1U,
},
[PINCTRL_FUNC_NAND0_RB] = {
.name = "nand0_rb",
.regval = 0x04,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_NAND0_0_RB,
- PINCTRL_GRP_NAND0_1_RB,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_NAND0_0_RB,
+ .group_size = PINCTRL_GRP_NAND0_1_RB - PINCTRL_GRP_NAND0_0_RB + 1U,
},
[PINCTRL_FUNC_NAND0_DQS] = {
.name = "nand0_dqs",
.regval = 0x04,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_NAND0_0_DQS,
- PINCTRL_GRP_NAND0_1_DQS,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_NAND0_0_DQS,
+ .group_size = PINCTRL_GRP_NAND0_1_DQS - PINCTRL_GRP_NAND0_0_DQS + 1U,
},
[PINCTRL_FUNC_TTC0_CLK] = {
.name = "ttc0_clk",
.regval = 0xa0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TTC0_0_CLK,
- PINCTRL_GRP_TTC0_1_CLK,
- PINCTRL_GRP_TTC0_2_CLK,
- PINCTRL_GRP_TTC0_3_CLK,
- PINCTRL_GRP_TTC0_4_CLK,
- PINCTRL_GRP_TTC0_5_CLK,
- PINCTRL_GRP_TTC0_6_CLK,
- PINCTRL_GRP_TTC0_7_CLK,
- PINCTRL_GRP_TTC0_8_CLK,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_TTC0_0_CLK,
+ .group_size = PINCTRL_GRP_TTC0_8_CLK - PINCTRL_GRP_TTC0_0_CLK + 1U,
},
[PINCTRL_FUNC_TTC0_WAV] = {
.name = "ttc0_wav",
.regval = 0xa0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TTC0_0_WAV,
- PINCTRL_GRP_TTC0_1_WAV,
- PINCTRL_GRP_TTC0_2_WAV,
- PINCTRL_GRP_TTC0_3_WAV,
- PINCTRL_GRP_TTC0_4_WAV,
- PINCTRL_GRP_TTC0_5_WAV,
- PINCTRL_GRP_TTC0_6_WAV,
- PINCTRL_GRP_TTC0_7_WAV,
- PINCTRL_GRP_TTC0_8_WAV,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_TTC0_0_WAV,
+ .group_size = PINCTRL_GRP_TTC0_8_WAV - PINCTRL_GRP_TTC0_0_WAV + 1U,
},
[PINCTRL_FUNC_TTC1_CLK] = {
.name = "ttc1_clk",
.regval = 0xa0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TTC1_0_CLK,
- PINCTRL_GRP_TTC1_1_CLK,
- PINCTRL_GRP_TTC1_2_CLK,
- PINCTRL_GRP_TTC1_3_CLK,
- PINCTRL_GRP_TTC1_4_CLK,
- PINCTRL_GRP_TTC1_5_CLK,
- PINCTRL_GRP_TTC1_6_CLK,
- PINCTRL_GRP_TTC1_7_CLK,
- PINCTRL_GRP_TTC1_8_CLK,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_TTC1_0_CLK,
+ .group_size = PINCTRL_GRP_TTC1_8_CLK - PINCTRL_GRP_TTC1_0_CLK + 1U,
},
[PINCTRL_FUNC_TTC1_WAV] = {
.name = "ttc1_wav",
- .regval = 0xa0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TTC1_0_WAV,
- PINCTRL_GRP_TTC1_1_WAV,
- PINCTRL_GRP_TTC1_2_WAV,
- PINCTRL_GRP_TTC1_3_WAV,
- PINCTRL_GRP_TTC1_4_WAV,
- PINCTRL_GRP_TTC1_5_WAV,
- PINCTRL_GRP_TTC1_6_WAV,
- PINCTRL_GRP_TTC1_7_WAV,
- PINCTRL_GRP_TTC1_8_WAV,
- END_OF_GROUPS,
- }),
+ .regval = 0xa0,
+ .group_base = PINCTRL_GRP_TTC1_0_WAV,
+ .group_size = PINCTRL_GRP_TTC1_8_WAV - PINCTRL_GRP_TTC1_0_WAV + 1U,
},
[PINCTRL_FUNC_TTC2_CLK] = {
.name = "ttc2_clk",
.regval = 0xa0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TTC2_0_CLK,
- PINCTRL_GRP_TTC2_1_CLK,
- PINCTRL_GRP_TTC2_2_CLK,
- PINCTRL_GRP_TTC2_3_CLK,
- PINCTRL_GRP_TTC2_4_CLK,
- PINCTRL_GRP_TTC2_5_CLK,
- PINCTRL_GRP_TTC2_6_CLK,
- PINCTRL_GRP_TTC2_7_CLK,
- PINCTRL_GRP_TTC2_8_CLK,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_TTC2_0_CLK,
+ .group_size = PINCTRL_GRP_TTC2_8_CLK - PINCTRL_GRP_TTC2_0_CLK + 1U,
},
[PINCTRL_FUNC_TTC2_WAV] = {
.name = "ttc2_wav",
.regval = 0xa0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TTC2_0_WAV,
- PINCTRL_GRP_TTC2_1_WAV,
- PINCTRL_GRP_TTC2_2_WAV,
- PINCTRL_GRP_TTC2_3_WAV,
- PINCTRL_GRP_TTC2_4_WAV,
- PINCTRL_GRP_TTC2_5_WAV,
- PINCTRL_GRP_TTC2_6_WAV,
- PINCTRL_GRP_TTC2_7_WAV,
- PINCTRL_GRP_TTC2_8_WAV,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_TTC2_0_WAV,
+ .group_size = PINCTRL_GRP_TTC2_8_WAV - PINCTRL_GRP_TTC2_0_WAV + 1U,
},
[PINCTRL_FUNC_TTC3_CLK] = {
.name = "ttc3_clk",
.regval = 0xa0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TTC3_0_CLK,
- PINCTRL_GRP_TTC3_1_CLK,
- PINCTRL_GRP_TTC3_2_CLK,
- PINCTRL_GRP_TTC3_3_CLK,
- PINCTRL_GRP_TTC3_4_CLK,
- PINCTRL_GRP_TTC3_5_CLK,
- PINCTRL_GRP_TTC3_6_CLK,
- PINCTRL_GRP_TTC3_7_CLK,
- PINCTRL_GRP_TTC3_8_CLK,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_TTC3_0_CLK,
+ .group_size = PINCTRL_GRP_TTC3_8_CLK - PINCTRL_GRP_TTC3_0_CLK + 1U,
},
[PINCTRL_FUNC_TTC3_WAV] = {
.name = "ttc3_wav",
.regval = 0xa0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TTC3_0_WAV,
- PINCTRL_GRP_TTC3_1_WAV,
- PINCTRL_GRP_TTC3_2_WAV,
- PINCTRL_GRP_TTC3_3_WAV,
- PINCTRL_GRP_TTC3_4_WAV,
- PINCTRL_GRP_TTC3_5_WAV,
- PINCTRL_GRP_TTC3_6_WAV,
- PINCTRL_GRP_TTC3_7_WAV,
- PINCTRL_GRP_TTC3_8_WAV,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_TTC3_0_WAV,
+ .group_size = PINCTRL_GRP_TTC3_8_WAV - PINCTRL_GRP_TTC3_0_WAV + 1U,
},
[PINCTRL_FUNC_UART0] = {
.name = "uart0",
.regval = 0xc0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_UART0_0,
- PINCTRL_GRP_UART0_1,
- PINCTRL_GRP_UART0_2,
- PINCTRL_GRP_UART0_3,
- PINCTRL_GRP_UART0_4,
- PINCTRL_GRP_UART0_5,
- PINCTRL_GRP_UART0_6,
- PINCTRL_GRP_UART0_7,
- PINCTRL_GRP_UART0_8,
- PINCTRL_GRP_UART0_9,
- PINCTRL_GRP_UART0_10,
- PINCTRL_GRP_UART0_11,
- PINCTRL_GRP_UART0_12,
- PINCTRL_GRP_UART0_13,
- PINCTRL_GRP_UART0_14,
- PINCTRL_GRP_UART0_15,
- PINCTRL_GRP_UART0_16,
- PINCTRL_GRP_UART0_17,
- PINCTRL_GRP_UART0_18,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_UART0_0,
+ .group_size = PINCTRL_GRP_UART0_18 - PINCTRL_GRP_UART0_0 + 1U,
},
[PINCTRL_FUNC_UART1] = {
.name = "uart1",
.regval = 0xc0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_UART1_0,
- PINCTRL_GRP_UART1_1,
- PINCTRL_GRP_UART1_2,
- PINCTRL_GRP_UART1_3,
- PINCTRL_GRP_UART1_4,
- PINCTRL_GRP_UART1_5,
- PINCTRL_GRP_UART1_6,
- PINCTRL_GRP_UART1_7,
- PINCTRL_GRP_UART1_8,
- PINCTRL_GRP_UART1_9,
- PINCTRL_GRP_UART1_10,
- PINCTRL_GRP_UART1_11,
- PINCTRL_GRP_UART1_12,
- PINCTRL_GRP_UART1_13,
- PINCTRL_GRP_UART1_14,
- PINCTRL_GRP_UART1_15,
- PINCTRL_GRP_UART1_16,
- PINCTRL_GRP_UART1_17,
- PINCTRL_GRP_UART1_18,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_UART1_0,
+ .group_size = PINCTRL_GRP_UART1_18 - PINCTRL_GRP_UART1_0 + 1U,
},
[PINCTRL_FUNC_USB0] = {
.name = "usb0",
.regval = 0x04,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_USB0_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_USB0_0,
+ .group_size = PINCTRL_GRP_USB0_0 - PINCTRL_GRP_USB0_0 + 1U,
},
[PINCTRL_FUNC_USB1] = {
.name = "usb1",
.regval = 0x04,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_USB1_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_USB1_0,
+ .group_size = PINCTRL_GRP_USB1_0 - PINCTRL_GRP_USB1_0 + 1U,
},
[PINCTRL_FUNC_SWDT0_CLK] = {
.name = "swdt0_clk",
.regval = 0x60,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SWDT0_0_CLK,
- PINCTRL_GRP_SWDT0_1_CLK,
- PINCTRL_GRP_SWDT0_2_CLK,
- PINCTRL_GRP_SWDT0_3_CLK,
- PINCTRL_GRP_SWDT0_4_CLK,
- PINCTRL_GRP_SWDT0_5_CLK,
- PINCTRL_GRP_SWDT0_6_CLK,
- PINCTRL_GRP_SWDT0_7_CLK,
- PINCTRL_GRP_SWDT0_8_CLK,
- PINCTRL_GRP_SWDT0_9_CLK,
- PINCTRL_GRP_SWDT0_10_CLK,
- PINCTRL_GRP_SWDT0_11_CLK,
- PINCTRL_GRP_SWDT0_12_CLK,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SWDT0_0_CLK,
+ .group_size = PINCTRL_GRP_SWDT0_12_CLK - PINCTRL_GRP_SWDT0_0_CLK + 1U,
},
[PINCTRL_FUNC_SWDT0_RST] = {
.name = "swdt0_rst",
.regval = 0x60,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SWDT0_0_RST,
- PINCTRL_GRP_SWDT0_1_RST,
- PINCTRL_GRP_SWDT0_2_RST,
- PINCTRL_GRP_SWDT0_3_RST,
- PINCTRL_GRP_SWDT0_4_RST,
- PINCTRL_GRP_SWDT0_5_RST,
- PINCTRL_GRP_SWDT0_6_RST,
- PINCTRL_GRP_SWDT0_7_RST,
- PINCTRL_GRP_SWDT0_8_RST,
- PINCTRL_GRP_SWDT0_9_RST,
- PINCTRL_GRP_SWDT0_10_RST,
- PINCTRL_GRP_SWDT0_11_RST,
- PINCTRL_GRP_SWDT0_12_RST,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SWDT0_0_RST,
+ .group_size = PINCTRL_GRP_SWDT0_12_RST - PINCTRL_GRP_SWDT0_0_RST + 1U,
},
[PINCTRL_FUNC_SWDT1_CLK] = {
.name = "swdt1_clk",
.regval = 0x60,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SWDT1_0_CLK,
- PINCTRL_GRP_SWDT1_1_CLK,
- PINCTRL_GRP_SWDT1_2_CLK,
- PINCTRL_GRP_SWDT1_3_CLK,
- PINCTRL_GRP_SWDT1_4_CLK,
- PINCTRL_GRP_SWDT1_5_CLK,
- PINCTRL_GRP_SWDT1_6_CLK,
- PINCTRL_GRP_SWDT1_7_CLK,
- PINCTRL_GRP_SWDT1_8_CLK,
- PINCTRL_GRP_SWDT1_9_CLK,
- PINCTRL_GRP_SWDT1_10_CLK,
- PINCTRL_GRP_SWDT1_11_CLK,
- PINCTRL_GRP_SWDT1_12_CLK,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SWDT1_0_CLK,
+ .group_size = PINCTRL_GRP_SWDT1_12_CLK - PINCTRL_GRP_SWDT1_0_CLK + 1U,
},
[PINCTRL_FUNC_SWDT1_RST] = {
.name = "swdt1_rst",
.regval = 0x60,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_SWDT1_0_RST,
- PINCTRL_GRP_SWDT1_1_RST,
- PINCTRL_GRP_SWDT1_2_RST,
- PINCTRL_GRP_SWDT1_3_RST,
- PINCTRL_GRP_SWDT1_4_RST,
- PINCTRL_GRP_SWDT1_5_RST,
- PINCTRL_GRP_SWDT1_6_RST,
- PINCTRL_GRP_SWDT1_7_RST,
- PINCTRL_GRP_SWDT1_8_RST,
- PINCTRL_GRP_SWDT1_9_RST,
- PINCTRL_GRP_SWDT1_10_RST,
- PINCTRL_GRP_SWDT1_11_RST,
- PINCTRL_GRP_SWDT1_12_RST,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_SWDT1_0_RST,
+ .group_size = PINCTRL_GRP_SWDT1_12_RST - PINCTRL_GRP_SWDT1_0_RST + 1U,
},
[PINCTRL_FUNC_PMU0] = {
.name = "pmu0",
.regval = 0x08,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_PMU0_0,
- PINCTRL_GRP_PMU0_1,
- PINCTRL_GRP_PMU0_2,
- PINCTRL_GRP_PMU0_3,
- PINCTRL_GRP_PMU0_4,
- PINCTRL_GRP_PMU0_5,
- PINCTRL_GRP_PMU0_6,
- PINCTRL_GRP_PMU0_7,
- PINCTRL_GRP_PMU0_8,
- PINCTRL_GRP_PMU0_9,
- PINCTRL_GRP_PMU0_10,
- PINCTRL_GRP_PMU0_11,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_PMU0_0,
+ .group_size = PINCTRL_GRP_PMU0_11 - PINCTRL_GRP_PMU0_0 + 1U,
},
[PINCTRL_FUNC_PCIE0] = {
.name = "pcie0",
.regval = 0x04,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_PCIE0_0,
- PINCTRL_GRP_PCIE0_1,
- PINCTRL_GRP_PCIE0_2,
- PINCTRL_GRP_PCIE0_3,
- PINCTRL_GRP_PCIE0_4,
- PINCTRL_GRP_PCIE0_5,
- PINCTRL_GRP_PCIE0_6,
- PINCTRL_GRP_PCIE0_7,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_PCIE0_0,
+ .group_size = PINCTRL_GRP_PCIE0_7 - PINCTRL_GRP_PCIE0_0 + 1U,
},
[PINCTRL_FUNC_CSU0] = {
.name = "csu0",
.regval = 0x18,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_CSU0_0,
- PINCTRL_GRP_CSU0_1,
- PINCTRL_GRP_CSU0_2,
- PINCTRL_GRP_CSU0_3,
- PINCTRL_GRP_CSU0_4,
- PINCTRL_GRP_CSU0_5,
- PINCTRL_GRP_CSU0_6,
- PINCTRL_GRP_CSU0_7,
- PINCTRL_GRP_CSU0_8,
- PINCTRL_GRP_CSU0_9,
- PINCTRL_GRP_CSU0_10,
- PINCTRL_GRP_CSU0_11,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_CSU0_0,
+ .group_size = PINCTRL_GRP_CSU0_11 - PINCTRL_GRP_CSU0_0 + 1U,
},
[PINCTRL_FUNC_DPAUX0] = {
.name = "dpaux0",
.regval = 0x18,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_DPAUX0_0,
- PINCTRL_GRP_DPAUX0_1,
- PINCTRL_GRP_DPAUX0_2,
- PINCTRL_GRP_DPAUX0_3,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_DPAUX0_0,
+ .group_size = PINCTRL_GRP_DPAUX0_3 - PINCTRL_GRP_DPAUX0_0 + 1U,
},
[PINCTRL_FUNC_PJTAG0] = {
.name = "pjtag0",
.regval = 0x60,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_PJTAG0_0,
- PINCTRL_GRP_PJTAG0_1,
- PINCTRL_GRP_PJTAG0_2,
- PINCTRL_GRP_PJTAG0_3,
- PINCTRL_GRP_PJTAG0_4,
- PINCTRL_GRP_PJTAG0_5,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_PJTAG0_0,
+ .group_size = PINCTRL_GRP_PJTAG0_5 - PINCTRL_GRP_PJTAG0_0 + 1U,
},
[PINCTRL_FUNC_TRACE0] = {
.name = "trace0",
.regval = 0xe0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TRACE0_0,
- PINCTRL_GRP_TRACE0_1,
- PINCTRL_GRP_TRACE0_2,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_TRACE0_0,
+ .group_size = PINCTRL_GRP_TRACE0_2 - PINCTRL_GRP_TRACE0_0 + 1U,
},
[PINCTRL_FUNC_TRACE0_CLK] = {
.name = "trace0_clk",
.regval = 0xe0,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TRACE0_0_CLK,
- PINCTRL_GRP_TRACE0_1_CLK,
- PINCTRL_GRP_TRACE0_2_CLK,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_TRACE0_0_CLK,
+ .group_size = PINCTRL_GRP_TRACE0_2_CLK - PINCTRL_GRP_TRACE0_0_CLK + 1U,
},
[PINCTRL_FUNC_TESTSCAN0] = {
.name = "testscan0",
.regval = 0x10,
- .groups = &((uint16_t []) {
- PINCTRL_GRP_TESTSCAN0_0,
- END_OF_GROUPS,
- }),
+ .group_base = PINCTRL_GRP_TESTSCAN0_0,
+ .group_size = PINCTRL_GRP_TESTSCAN0_0 - PINCTRL_GRP_TESTSCAN0_0 + 1U,
},
};
@@ -2511,7 +1952,7 @@
*
* @return Returns success.
*/
-enum pm_ret_status pm_api_pinctrl_get_num_pins(unsigned int *npins)
+enum pm_ret_status pm_api_pinctrl_get_num_pins(uint32_t *npins)
{
*npins = MAX_PIN;
@@ -2526,7 +1967,7 @@
*
* @return Returns success.
*/
-enum pm_ret_status pm_api_pinctrl_get_num_functions(unsigned int *nfuncs)
+enum pm_ret_status pm_api_pinctrl_get_num_functions(uint32_t *nfuncs)
{
*nfuncs = MAX_FUNCTION;
@@ -2543,23 +1984,14 @@
*
* @return Returns success.
*/
-enum pm_ret_status pm_api_pinctrl_get_num_func_groups(unsigned int fid,
- unsigned int *ngroups)
+enum pm_ret_status pm_api_pinctrl_get_num_func_groups(uint32_t fid,
+ uint32_t *ngroups)
{
- int i = 0;
- uint16_t *grps;
-
- if (fid >= MAX_FUNCTION)
+ if (fid >= MAX_FUNCTION) {
return PM_RET_ERROR_ARGS;
-
- *ngroups = 0;
-
- grps = *pinctrl_functions[fid].groups;
- if (grps == NULL)
- return PM_RET_SUCCESS;
+ }
- while (grps[i++] != (uint16_t)END_OF_GROUPS)
- (*ngroups)++;
+ *ngroups = pinctrl_functions[fid].group_size;
return PM_RET_SUCCESS;
}
@@ -2572,12 +2004,13 @@
* This function is used by master to get name of function specified
* by given function ID.
*/
-void pm_api_pinctrl_get_function_name(unsigned int fid, char *name)
+void pm_api_pinctrl_get_function_name(uint32_t fid, char *name)
{
- if (fid >= MAX_FUNCTION)
+ if (fid >= MAX_FUNCTION) {
memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
- else
+ } else {
memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
+ }
}
/**
@@ -2598,31 +2031,28 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid,
- unsigned int index,
+enum pm_ret_status pm_api_pinctrl_get_function_groups(uint32_t fid,
+ uint32_t index,
uint16_t *groups)
{
+ uint16_t grps;
+ uint16_t end_of_grp_offset;
unsigned int i;
- uint16_t *grps;
- if (fid >= MAX_FUNCTION)
+ if (fid >= MAX_FUNCTION) {
return PM_RET_ERROR_ARGS;
+ }
memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
- grps = *pinctrl_functions[fid].groups;
- if (grps == NULL)
- return PM_RET_SUCCESS;
-
- /* Skip groups till index */
- for (i = 0; i < index; i++)
- if (grps[i] == (uint16_t)END_OF_GROUPS)
- return PM_RET_SUCCESS;
+ grps = pinctrl_functions[fid].group_base;
+ end_of_grp_offset = grps + pinctrl_functions[fid].group_size;
for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
- groups[i] = grps[index + i];
- if (groups[i] == (uint16_t)END_OF_GROUPS)
+ if ((grps + index + i) >= end_of_grp_offset) {
break;
+ }
+ groups[i] = (grps + index + i);
}
return PM_RET_SUCCESS;
@@ -2646,31 +2076,36 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin,
- unsigned int index,
+enum pm_ret_status pm_api_pinctrl_get_pin_groups(uint32_t pin,
+ uint32_t index,
uint16_t *groups)
{
- unsigned int i;
+ uint32_t i;
uint16_t *grps;
- if (pin >= MAX_PIN)
+ if (pin >= MAX_PIN) {
return PM_RET_ERROR_ARGS;
+ }
memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
grps = *zynqmp_pin_groups[pin].groups;
- if (!grps)
+ if (grps == NULL) {
return PM_RET_SUCCESS;
+ }
/* Skip groups till index */
- for (i = 0; i < index; i++)
- if (grps[i] == (uint16_t)END_OF_GROUPS)
+ for (i = 0; i < index; i++) {
+ if (grps[i] == (uint16_t)END_OF_GROUPS) {
return PM_RET_SUCCESS;
+ }
+ }
for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
groups[i] = grps[index + i];
- if (groups[i] == (uint16_t)END_OF_GROUPS)
+ if (groups[i] == (uint16_t)END_OF_GROUPS) {
break;
+ }
}
return PM_RET_SUCCESS;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
index 2b8fca3..b3159c2 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
@@ -187,50 +187,50 @@
PINCTRL_GRP_QSPI_SS,
PINCTRL_GRP_QSPI_FBCLK,
PINCTRL_GRP_SPI0_0,
+ PINCTRL_GRP_SPI0_1,
+ PINCTRL_GRP_SPI0_2,
+ PINCTRL_GRP_SPI0_3,
+ PINCTRL_GRP_SPI0_4,
+ PINCTRL_GRP_SPI0_5,
PINCTRL_GRP_SPI0_0_SS0,
PINCTRL_GRP_SPI0_0_SS1,
PINCTRL_GRP_SPI0_0_SS2,
- PINCTRL_GRP_SPI0_1,
PINCTRL_GRP_SPI0_1_SS0,
PINCTRL_GRP_SPI0_1_SS1,
PINCTRL_GRP_SPI0_1_SS2,
- PINCTRL_GRP_SPI0_2,
PINCTRL_GRP_SPI0_2_SS0,
PINCTRL_GRP_SPI0_2_SS1,
PINCTRL_GRP_SPI0_2_SS2,
- PINCTRL_GRP_SPI0_3,
PINCTRL_GRP_SPI0_3_SS0,
PINCTRL_GRP_SPI0_3_SS1,
PINCTRL_GRP_SPI0_3_SS2,
- PINCTRL_GRP_SPI0_4,
PINCTRL_GRP_SPI0_4_SS0,
PINCTRL_GRP_SPI0_4_SS1,
PINCTRL_GRP_SPI0_4_SS2,
- PINCTRL_GRP_SPI0_5,
PINCTRL_GRP_SPI0_5_SS0,
PINCTRL_GRP_SPI0_5_SS1,
PINCTRL_GRP_SPI0_5_SS2,
PINCTRL_GRP_SPI1_0,
+ PINCTRL_GRP_SPI1_1,
+ PINCTRL_GRP_SPI1_2,
+ PINCTRL_GRP_SPI1_3,
+ PINCTRL_GRP_SPI1_4,
+ PINCTRL_GRP_SPI1_5,
PINCTRL_GRP_SPI1_0_SS0,
PINCTRL_GRP_SPI1_0_SS1,
PINCTRL_GRP_SPI1_0_SS2,
- PINCTRL_GRP_SPI1_1,
PINCTRL_GRP_SPI1_1_SS0,
PINCTRL_GRP_SPI1_1_SS1,
PINCTRL_GRP_SPI1_1_SS2,
- PINCTRL_GRP_SPI1_2,
PINCTRL_GRP_SPI1_2_SS0,
PINCTRL_GRP_SPI1_2_SS1,
PINCTRL_GRP_SPI1_2_SS2,
- PINCTRL_GRP_SPI1_3,
PINCTRL_GRP_SPI1_3_SS0,
PINCTRL_GRP_SPI1_3_SS1,
PINCTRL_GRP_SPI1_3_SS2,
- PINCTRL_GRP_SPI1_4,
PINCTRL_GRP_SPI1_4_SS0,
PINCTRL_GRP_SPI1_4_SS1,
PINCTRL_GRP_SPI1_4_SS2,
- PINCTRL_GRP_SPI1_5,
PINCTRL_GRP_SPI1_5_SS0,
PINCTRL_GRP_SPI1_5_SS1,
PINCTRL_GRP_SPI1_5_SS2,
@@ -268,13 +268,13 @@
PINCTRL_GRP_SDIO0_1BIT_2_6,
PINCTRL_GRP_SDIO0_1BIT_2_7,
PINCTRL_GRP_SDIO0_0_PC,
- PINCTRL_GRP_SDIO0_0_CD,
- PINCTRL_GRP_SDIO0_0_WP,
PINCTRL_GRP_SDIO0_1_PC,
- PINCTRL_GRP_SDIO0_1_CD,
- PINCTRL_GRP_SDIO0_1_WP,
PINCTRL_GRP_SDIO0_2_PC,
+ PINCTRL_GRP_SDIO0_0_CD,
+ PINCTRL_GRP_SDIO0_1_CD,
PINCTRL_GRP_SDIO0_2_CD,
+ PINCTRL_GRP_SDIO0_0_WP,
+ PINCTRL_GRP_SDIO0_1_WP,
PINCTRL_GRP_SDIO0_2_WP,
PINCTRL_GRP_SDIO1_0,
PINCTRL_GRP_SDIO1_4BIT_0_0,
@@ -293,17 +293,17 @@
PINCTRL_GRP_SDIO1_1BIT_1_2,
PINCTRL_GRP_SDIO1_1BIT_1_3,
PINCTRL_GRP_SDIO1_0_PC,
- PINCTRL_GRP_SDIO1_0_CD,
- PINCTRL_GRP_SDIO1_0_WP,
PINCTRL_GRP_SDIO1_1_PC,
+ PINCTRL_GRP_SDIO1_0_CD,
PINCTRL_GRP_SDIO1_1_CD,
+ PINCTRL_GRP_SDIO1_0_WP,
PINCTRL_GRP_SDIO1_1_WP,
PINCTRL_GRP_NAND0_0,
PINCTRL_GRP_NAND0_0_CE,
- PINCTRL_GRP_NAND0_0_RB,
- PINCTRL_GRP_NAND0_0_DQS,
PINCTRL_GRP_NAND0_1_CE,
+ PINCTRL_GRP_NAND0_0_RB,
PINCTRL_GRP_NAND0_1_RB,
+ PINCTRL_GRP_NAND0_0_DQS,
PINCTRL_GRP_NAND0_1_DQS,
PINCTRL_GRP_CAN0_0,
PINCTRL_GRP_CAN0_1,
@@ -422,128 +422,128 @@
PINCTRL_GRP_I2C1_18,
PINCTRL_GRP_I2C1_19,
PINCTRL_GRP_TTC0_0_CLK,
- PINCTRL_GRP_TTC0_0_WAV,
PINCTRL_GRP_TTC0_1_CLK,
- PINCTRL_GRP_TTC0_1_WAV,
PINCTRL_GRP_TTC0_2_CLK,
- PINCTRL_GRP_TTC0_2_WAV,
PINCTRL_GRP_TTC0_3_CLK,
- PINCTRL_GRP_TTC0_3_WAV,
PINCTRL_GRP_TTC0_4_CLK,
- PINCTRL_GRP_TTC0_4_WAV,
PINCTRL_GRP_TTC0_5_CLK,
- PINCTRL_GRP_TTC0_5_WAV,
PINCTRL_GRP_TTC0_6_CLK,
- PINCTRL_GRP_TTC0_6_WAV,
PINCTRL_GRP_TTC0_7_CLK,
- PINCTRL_GRP_TTC0_7_WAV,
PINCTRL_GRP_TTC0_8_CLK,
+ PINCTRL_GRP_TTC0_0_WAV,
+ PINCTRL_GRP_TTC0_1_WAV,
+ PINCTRL_GRP_TTC0_2_WAV,
+ PINCTRL_GRP_TTC0_3_WAV,
+ PINCTRL_GRP_TTC0_4_WAV,
+ PINCTRL_GRP_TTC0_5_WAV,
+ PINCTRL_GRP_TTC0_6_WAV,
+ PINCTRL_GRP_TTC0_7_WAV,
PINCTRL_GRP_TTC0_8_WAV,
PINCTRL_GRP_TTC1_0_CLK,
- PINCTRL_GRP_TTC1_0_WAV,
PINCTRL_GRP_TTC1_1_CLK,
- PINCTRL_GRP_TTC1_1_WAV,
PINCTRL_GRP_TTC1_2_CLK,
- PINCTRL_GRP_TTC1_2_WAV,
PINCTRL_GRP_TTC1_3_CLK,
- PINCTRL_GRP_TTC1_3_WAV,
PINCTRL_GRP_TTC1_4_CLK,
- PINCTRL_GRP_TTC1_4_WAV,
PINCTRL_GRP_TTC1_5_CLK,
- PINCTRL_GRP_TTC1_5_WAV,
PINCTRL_GRP_TTC1_6_CLK,
- PINCTRL_GRP_TTC1_6_WAV,
PINCTRL_GRP_TTC1_7_CLK,
- PINCTRL_GRP_TTC1_7_WAV,
PINCTRL_GRP_TTC1_8_CLK,
+ PINCTRL_GRP_TTC1_0_WAV,
+ PINCTRL_GRP_TTC1_1_WAV,
+ PINCTRL_GRP_TTC1_2_WAV,
+ PINCTRL_GRP_TTC1_3_WAV,
+ PINCTRL_GRP_TTC1_4_WAV,
+ PINCTRL_GRP_TTC1_5_WAV,
+ PINCTRL_GRP_TTC1_6_WAV,
+ PINCTRL_GRP_TTC1_7_WAV,
PINCTRL_GRP_TTC1_8_WAV,
PINCTRL_GRP_TTC2_0_CLK,
- PINCTRL_GRP_TTC2_0_WAV,
PINCTRL_GRP_TTC2_1_CLK,
- PINCTRL_GRP_TTC2_1_WAV,
PINCTRL_GRP_TTC2_2_CLK,
- PINCTRL_GRP_TTC2_2_WAV,
PINCTRL_GRP_TTC2_3_CLK,
- PINCTRL_GRP_TTC2_3_WAV,
PINCTRL_GRP_TTC2_4_CLK,
- PINCTRL_GRP_TTC2_4_WAV,
PINCTRL_GRP_TTC2_5_CLK,
- PINCTRL_GRP_TTC2_5_WAV,
PINCTRL_GRP_TTC2_6_CLK,
- PINCTRL_GRP_TTC2_6_WAV,
PINCTRL_GRP_TTC2_7_CLK,
- PINCTRL_GRP_TTC2_7_WAV,
PINCTRL_GRP_TTC2_8_CLK,
+ PINCTRL_GRP_TTC2_0_WAV,
+ PINCTRL_GRP_TTC2_1_WAV,
+ PINCTRL_GRP_TTC2_2_WAV,
+ PINCTRL_GRP_TTC2_3_WAV,
+ PINCTRL_GRP_TTC2_4_WAV,
+ PINCTRL_GRP_TTC2_5_WAV,
+ PINCTRL_GRP_TTC2_6_WAV,
+ PINCTRL_GRP_TTC2_7_WAV,
PINCTRL_GRP_TTC2_8_WAV,
PINCTRL_GRP_TTC3_0_CLK,
- PINCTRL_GRP_TTC3_0_WAV,
PINCTRL_GRP_TTC3_1_CLK,
- PINCTRL_GRP_TTC3_1_WAV,
PINCTRL_GRP_TTC3_2_CLK,
- PINCTRL_GRP_TTC3_2_WAV,
PINCTRL_GRP_TTC3_3_CLK,
- PINCTRL_GRP_TTC3_3_WAV,
PINCTRL_GRP_TTC3_4_CLK,
- PINCTRL_GRP_TTC3_4_WAV,
PINCTRL_GRP_TTC3_5_CLK,
- PINCTRL_GRP_TTC3_5_WAV,
PINCTRL_GRP_TTC3_6_CLK,
- PINCTRL_GRP_TTC3_6_WAV,
PINCTRL_GRP_TTC3_7_CLK,
- PINCTRL_GRP_TTC3_7_WAV,
PINCTRL_GRP_TTC3_8_CLK,
+ PINCTRL_GRP_TTC3_0_WAV,
+ PINCTRL_GRP_TTC3_1_WAV,
+ PINCTRL_GRP_TTC3_2_WAV,
+ PINCTRL_GRP_TTC3_3_WAV,
+ PINCTRL_GRP_TTC3_4_WAV,
+ PINCTRL_GRP_TTC3_5_WAV,
+ PINCTRL_GRP_TTC3_6_WAV,
+ PINCTRL_GRP_TTC3_7_WAV,
PINCTRL_GRP_TTC3_8_WAV,
PINCTRL_GRP_SWDT0_0_CLK,
- PINCTRL_GRP_SWDT0_0_RST,
PINCTRL_GRP_SWDT0_1_CLK,
- PINCTRL_GRP_SWDT0_1_RST,
PINCTRL_GRP_SWDT0_2_CLK,
- PINCTRL_GRP_SWDT0_2_RST,
PINCTRL_GRP_SWDT0_3_CLK,
- PINCTRL_GRP_SWDT0_3_RST,
PINCTRL_GRP_SWDT0_4_CLK,
- PINCTRL_GRP_SWDT0_4_RST,
PINCTRL_GRP_SWDT0_5_CLK,
- PINCTRL_GRP_SWDT0_5_RST,
PINCTRL_GRP_SWDT0_6_CLK,
- PINCTRL_GRP_SWDT0_6_RST,
PINCTRL_GRP_SWDT0_7_CLK,
- PINCTRL_GRP_SWDT0_7_RST,
PINCTRL_GRP_SWDT0_8_CLK,
- PINCTRL_GRP_SWDT0_8_RST,
PINCTRL_GRP_SWDT0_9_CLK,
- PINCTRL_GRP_SWDT0_9_RST,
PINCTRL_GRP_SWDT0_10_CLK,
- PINCTRL_GRP_SWDT0_10_RST,
PINCTRL_GRP_SWDT0_11_CLK,
- PINCTRL_GRP_SWDT0_11_RST,
PINCTRL_GRP_SWDT0_12_CLK,
+ PINCTRL_GRP_SWDT0_0_RST,
+ PINCTRL_GRP_SWDT0_1_RST,
+ PINCTRL_GRP_SWDT0_2_RST,
+ PINCTRL_GRP_SWDT0_3_RST,
+ PINCTRL_GRP_SWDT0_4_RST,
+ PINCTRL_GRP_SWDT0_5_RST,
+ PINCTRL_GRP_SWDT0_6_RST,
+ PINCTRL_GRP_SWDT0_7_RST,
+ PINCTRL_GRP_SWDT0_8_RST,
+ PINCTRL_GRP_SWDT0_9_RST,
+ PINCTRL_GRP_SWDT0_10_RST,
+ PINCTRL_GRP_SWDT0_11_RST,
PINCTRL_GRP_SWDT0_12_RST,
PINCTRL_GRP_SWDT1_0_CLK,
- PINCTRL_GRP_SWDT1_0_RST,
PINCTRL_GRP_SWDT1_1_CLK,
- PINCTRL_GRP_SWDT1_1_RST,
PINCTRL_GRP_SWDT1_2_CLK,
- PINCTRL_GRP_SWDT1_2_RST,
PINCTRL_GRP_SWDT1_3_CLK,
- PINCTRL_GRP_SWDT1_3_RST,
PINCTRL_GRP_SWDT1_4_CLK,
- PINCTRL_GRP_SWDT1_4_RST,
PINCTRL_GRP_SWDT1_5_CLK,
- PINCTRL_GRP_SWDT1_5_RST,
PINCTRL_GRP_SWDT1_6_CLK,
- PINCTRL_GRP_SWDT1_6_RST,
PINCTRL_GRP_SWDT1_7_CLK,
- PINCTRL_GRP_SWDT1_7_RST,
PINCTRL_GRP_SWDT1_8_CLK,
- PINCTRL_GRP_SWDT1_8_RST,
PINCTRL_GRP_SWDT1_9_CLK,
- PINCTRL_GRP_SWDT1_9_RST,
PINCTRL_GRP_SWDT1_10_CLK,
- PINCTRL_GRP_SWDT1_10_RST,
PINCTRL_GRP_SWDT1_11_CLK,
- PINCTRL_GRP_SWDT1_11_RST,
PINCTRL_GRP_SWDT1_12_CLK,
+ PINCTRL_GRP_SWDT1_0_RST,
+ PINCTRL_GRP_SWDT1_1_RST,
+ PINCTRL_GRP_SWDT1_2_RST,
+ PINCTRL_GRP_SWDT1_3_RST,
+ PINCTRL_GRP_SWDT1_4_RST,
+ PINCTRL_GRP_SWDT1_5_RST,
+ PINCTRL_GRP_SWDT1_6_RST,
+ PINCTRL_GRP_SWDT1_7_RST,
+ PINCTRL_GRP_SWDT1_8_RST,
+ PINCTRL_GRP_SWDT1_9_RST,
+ PINCTRL_GRP_SWDT1_10_RST,
+ PINCTRL_GRP_SWDT1_11_RST,
PINCTRL_GRP_SWDT1_12_RST,
PINCTRL_GRP_GPIO0_0,
PINCTRL_GRP_GPIO0_1,
@@ -668,10 +668,10 @@
PINCTRL_GRP_PJTAG0_4,
PINCTRL_GRP_PJTAG0_5,
PINCTRL_GRP_TRACE0_0,
- PINCTRL_GRP_TRACE0_0_CLK,
PINCTRL_GRP_TRACE0_1,
- PINCTRL_GRP_TRACE0_1_CLK,
PINCTRL_GRP_TRACE0_2,
+ PINCTRL_GRP_TRACE0_0_CLK,
+ PINCTRL_GRP_TRACE0_1_CLK,
PINCTRL_GRP_TRACE0_2_CLK,
PINCTRL_GRP_TESTSCAN0_0,
};
@@ -709,15 +709,15 @@
#define PINCTRL_DRIVE_STRENGTH_8MA 2U
#define PINCTRL_DRIVE_STRENGTH_12MA 3U
-void pm_api_pinctrl_get_function_name(unsigned int fid, char *name);
-enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid,
- unsigned int index,
+void pm_api_pinctrl_get_function_name(uint32_t fid, char *name);
+enum pm_ret_status pm_api_pinctrl_get_function_groups(uint32_t fid,
+ uint32_t index,
uint16_t *groups);
-enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin,
- unsigned int index,
+enum pm_ret_status pm_api_pinctrl_get_pin_groups(uint32_t pin,
+ uint32_t index,
uint16_t *groups);
-enum pm_ret_status pm_api_pinctrl_get_num_pins(unsigned int *npins);
-enum pm_ret_status pm_api_pinctrl_get_num_functions(unsigned int *nfuncs);
-enum pm_ret_status pm_api_pinctrl_get_num_func_groups(unsigned int fid,
- unsigned int *ngroups);
+enum pm_ret_status pm_api_pinctrl_get_num_pins(uint32_t *npins);
+enum pm_ret_status pm_api_pinctrl_get_num_functions(uint32_t *nfuncs);
+enum pm_ret_status pm_api_pinctrl_get_num_func_groups(uint32_t fid,
+ uint32_t *ngroups);
#endif /* PM_API_PINCTRL_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index f9af451..a17b6c5 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -240,14 +240,14 @@
};
/* default shutdown/reboot scope is system(2) */
-static unsigned int pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
+static uint32_t pm_shutdown_scope = PMF_SHUTDOWN_SUBTYPE_SYSTEM;
/**
* pm_get_shutdown_scope() - Get the currently set shutdown scope
*
* @return Shutdown scope value
*/
-unsigned int pm_get_shutdown_scope(void)
+uint32_t pm_get_shutdown_scope(void)
{
return pm_shutdown_scope;
}
@@ -269,12 +269,12 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
- unsigned int latency,
- unsigned int state,
+ uint32_t latency,
+ uint32_t state,
uintptr_t address)
{
uint32_t payload[PAYLOAD_ARG_CNT];
- unsigned int cpuid = plat_my_core_pos();
+ uint32_t cpuid = plat_my_core_pos();
const struct pm_proc *proc = pm_get_proc(cpuid);
/*
@@ -300,16 +300,17 @@
*/
enum pm_ret_status pm_req_suspend(enum pm_node_id target,
enum pm_request_ack ack,
- unsigned int latency, unsigned int state)
+ uint32_t latency, uint32_t state)
{
uint32_t payload[PAYLOAD_ARG_CNT];
/* Send request to the PMU */
PM_PACK_PAYLOAD5(payload, PM_REQ_SUSPEND, target, ack, latency, state);
- if (ack == REQ_ACK_BLOCKING)
+ if (ack == REQ_ACK_BLOCKING) {
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
- else
+ } else {
return pm_ipi_send(primary_proc, payload);
+ }
}
/**
@@ -329,7 +330,7 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
- unsigned int set_address,
+ uint32_t set_address,
uintptr_t address,
enum pm_request_ack ack)
{
@@ -345,10 +346,11 @@
PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address,
encoded_address >> 32, ack);
- if (ack == REQ_ACK_BLOCKING)
+ if (ack == REQ_ACK_BLOCKING) {
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
- else
+ } else {
return pm_ipi_send(primary_proc, payload);
+ }
}
/**
@@ -367,10 +369,11 @@
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_FORCE_POWERDOWN, target, ack);
- if (ack == REQ_ACK_BLOCKING)
+ if (ack == REQ_ACK_BLOCKING) {
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
- else
+ } else {
return pm_ipi_send(primary_proc, payload);
+ }
}
/**
@@ -409,7 +412,7 @@
*/
enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
enum pm_node_id wkup_node,
- unsigned int enable)
+ uint32_t enable)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -425,7 +428,7 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_system_shutdown(unsigned int type, unsigned int subtype)
+enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -451,18 +454,19 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_req_node(enum pm_node_id nid,
- unsigned int capabilities,
- unsigned int qos,
+ uint32_t capabilities,
+ uint32_t qos,
enum pm_request_ack ack)
{
uint32_t payload[PAYLOAD_ARG_CNT];
PM_PACK_PAYLOAD5(payload, PM_REQ_NODE, nid, capabilities, qos, ack);
- if (ack == REQ_ACK_BLOCKING)
+ if (ack == REQ_ACK_BLOCKING) {
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
- else
+ } else {
return pm_ipi_send(primary_proc, payload);
+ }
}
/**
@@ -477,8 +481,8 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
- unsigned int capabilities,
- unsigned int qos,
+ uint32_t capabilities,
+ uint32_t qos,
enum pm_request_ack ack)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -486,10 +490,11 @@
PM_PACK_PAYLOAD5(payload, PM_SET_REQUIREMENT, nid, capabilities, qos,
ack);
- if (ack == REQ_ACK_BLOCKING)
+ if (ack == REQ_ACK_BLOCKING) {
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
- else
+ } else {
return pm_ipi_send(primary_proc, payload);
+ }
}
/* Miscellaneous API functions */
@@ -500,7 +505,7 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_get_api_version(unsigned int *version)
+enum pm_ret_status pm_get_api_version(uint32_t *version)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -540,8 +545,8 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_mmio_write(uintptr_t address,
- unsigned int mask,
- unsigned int value)
+ uint32_t mask,
+ uint32_t value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -560,7 +565,7 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_mmio_read(uintptr_t address, unsigned int *value)
+enum pm_ret_status pm_mmio_read(uintptr_t address, uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -604,7 +609,7 @@
* the fpga status
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_fpga_get_status(unsigned int *value)
+enum pm_ret_status pm_fpga_get_status(uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -689,8 +694,9 @@
void pm_get_callbackdata(uint32_t *data, size_t count)
{
/* Return if interrupt is not from PMU */
- if (!pm_ipi_irq_status(primary_proc))
+ if (!pm_ipi_irq_status(primary_proc)) {
return;
+ }
pm_ipi_buff_read_callb(data, count);
pm_ipi_irq_clear(primary_proc);
@@ -709,10 +715,10 @@
* @return Returns status, either success or error+reason
*/
enum pm_ret_status pm_ioctl(enum pm_node_id nid,
- unsigned int ioctl_id,
- unsigned int arg1,
- unsigned int arg2,
- unsigned int *value)
+ uint32_t ioctl_id,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t *value)
{
return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
}
@@ -941,7 +947,7 @@
*
* Return: Returns status, either success or error+reason.
*/
-static enum pm_ret_status pm_clock_get_max_divisor(unsigned int clock_id,
+static enum pm_ret_status pm_clock_get_max_divisor(uint32_t clock_id,
uint8_t div_type,
uint32_t *max_div)
{
@@ -969,7 +975,7 @@
* This function is used by master to get nmae of clock specified
* by given clock ID.
*/
-static void pm_clock_get_name(unsigned int clock_id, char *name)
+static void pm_clock_get_name(uint32_t clock_id, char *name)
{
pm_api_clock_get_name(clock_id, name);
}
@@ -987,8 +993,8 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_clock_get_topology(unsigned int clock_id,
- unsigned int index,
+static enum pm_ret_status pm_clock_get_topology(uint32_t clock_id,
+ uint32_t index,
uint32_t *topology)
{
return pm_api_clock_get_topology(clock_id, index, topology);
@@ -1006,7 +1012,7 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_clock_get_fixedfactor_params(unsigned int clock_id,
+static enum pm_ret_status pm_clock_get_fixedfactor_params(uint32_t clock_id,
uint32_t *mul,
uint32_t *div)
{
@@ -1030,8 +1036,8 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_clock_get_parents(unsigned int clock_id,
- unsigned int index,
+static enum pm_ret_status pm_clock_get_parents(uint32_t clock_id,
+ uint32_t index,
uint32_t *parents)
{
return pm_api_clock_get_parents(clock_id, index, parents);
@@ -1047,7 +1053,7 @@
*
* @return Returns status, either success or error+reason
*/
-static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
+static enum pm_ret_status pm_clock_get_attributes(uint32_t clock_id,
uint32_t *attr)
{
return pm_api_clock_get_attributes(clock_id, attr);
@@ -1061,8 +1067,8 @@
* @return Error if an argument is not valid or status as returned by the
* PM controller (PMU)
*/
-static enum pm_ret_status pm_clock_gate(unsigned int clock_id,
- unsigned char enable)
+static enum pm_ret_status pm_clock_gate(uint32_t clock_id,
+ uint8_t enable)
{
uint32_t payload[PAYLOAD_ARG_CNT];
enum pm_ret_status status;
@@ -1070,21 +1076,24 @@
/* Check if clock ID is valid and return an error if it is not */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
- if (enable)
+ if (enable) {
api_id = PM_CLOCK_ENABLE;
- else
+ } else {
api_id = PM_CLOCK_DISABLE;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, api_id, clock_id);
status = pm_ipi_send_sync(primary_proc, payload, NULL, 0);
/* If action fails due to the lack of permissions filter the error */
- if (status == PM_RET_ERROR_ACCESS)
+ if (status == PM_RET_ERROR_ACCESS) {
status = PM_RET_SUCCESS;
+ }
return status;
}
@@ -1099,14 +1108,15 @@
* @return: Error if an argument is not valid or status as returned by the
* pm_clock_gate
*/
-enum pm_ret_status pm_clock_enable(unsigned int clock_id)
+enum pm_ret_status pm_clock_enable(uint32_t clock_id)
{
struct pm_pll *pll;
/* First try to handle it as a PLL */
pll = pm_clock_get_pll(clock_id);
- if (pll)
+ if (pll) {
return pm_clock_pll_enable(pll);
+ }
/* It's an on-chip clock, PMU should configure clock's gate */
return pm_clock_gate(clock_id, 1);
@@ -1122,14 +1132,15 @@
* @return: Error if an argument is not valid or status as returned by the
* pm_clock_gate
*/
-enum pm_ret_status pm_clock_disable(unsigned int clock_id)
+enum pm_ret_status pm_clock_disable(uint32_t clock_id)
{
struct pm_pll *pll;
/* First try to handle it as a PLL */
pll = pm_clock_get_pll(clock_id);
- if (pll)
+ if (pll) {
return pm_clock_pll_disable(pll);
+ }
/* It's an on-chip clock, PMU should configure clock's gate */
return pm_clock_gate(clock_id, 0);
@@ -1145,8 +1156,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
- unsigned int *state)
+enum pm_ret_status pm_clock_getstate(uint32_t clock_id,
+ uint32_t *state)
{
struct pm_pll *pll;
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1159,8 +1170,9 @@
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETSTATE, clock_id);
@@ -1177,8 +1189,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
- unsigned int divider)
+enum pm_ret_status pm_clock_setdivider(uint32_t clock_id,
+ uint32_t divider)
{
enum pm_ret_status status;
enum pm_node_id nid;
@@ -1190,13 +1202,15 @@
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(clock_id, &nid);
- if (status == PM_RET_SUCCESS)
+ if (status == PM_RET_SUCCESS) {
return pm_pll_set_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
+ }
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
if (div0 == (divider & div0)) {
div_id = PM_CLOCK_DIV0_ID;
@@ -1223,8 +1237,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
- unsigned int *divider)
+enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
+ uint32_t *divider)
{
enum pm_ret_status status;
enum pm_node_id nid;
@@ -1233,21 +1247,24 @@
/* Get PLL node ID using PLL clock ID */
status = pm_clock_get_pll_node_id(clock_id, &nid);
- if (status == PM_RET_SUCCESS)
+ if (status == PM_RET_SUCCESS) {
return pm_pll_get_parameter(nid, PM_PLL_PARAM_FBDIV, divider);
+ }
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
if (pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) {
/* Send request to the PMU to get div0 */
PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
PM_CLOCK_DIV0_ID);
status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
*divider = val;
}
@@ -1256,8 +1273,9 @@
PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
PM_CLOCK_DIV1_ID);
status = pm_ipi_send_sync(primary_proc, payload, &val, 1);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
*divider |= val << 16;
}
@@ -1273,7 +1291,7 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
+enum pm_ret_status pm_clock_setrate(uint32_t clock_id,
uint64_t rate)
{
return PM_RET_ERROR_NOTSUPPORTED;
@@ -1289,7 +1307,7 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
+enum pm_ret_status pm_clock_getrate(uint32_t clock_id,
uint64_t *rate)
{
return PM_RET_ERROR_NOTSUPPORTED;
@@ -1304,8 +1322,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
- unsigned int parent_index)
+enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
+ uint32_t parent_index)
{
struct pm_pll *pll;
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1313,13 +1331,15 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll_by_related_clk(clock_id);
- if (pll)
+ if (pll) {
return pm_clock_pll_set_parent(pll, clock_id, parent_index);
+ }
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_CLOCK_SETPARENT, clock_id, parent_index);
@@ -1336,8 +1356,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
- unsigned int *parent_index)
+enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
+ uint32_t *parent_index)
{
struct pm_pll *pll;
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1345,13 +1365,15 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll_by_related_clk(clock_id);
- if (pll)
+ if (pll) {
return pm_clock_pll_get_parent(pll, clock_id, parent_index);
+ }
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
- if (status != PM_RET_SUCCESS)
+ if (status != PM_RET_SUCCESS) {
return status;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETPARENT, clock_id);
@@ -1395,7 +1417,7 @@
*
* Return: Returns status, either success or error+reason.
*/
-static enum pm_ret_status pm_pinctrl_get_num_function_groups(unsigned int fid,
+static enum pm_ret_status pm_pinctrl_get_num_function_groups(uint32_t fid,
uint32_t *ngroups)
{
return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
@@ -1409,7 +1431,7 @@
* This function is used by master to get name of function specified
* by given function Id
*/
-static void pm_pinctrl_get_function_name(unsigned int fid, char *name)
+static void pm_pinctrl_get_function_name(uint32_t fid, char *name)
{
pm_api_pinctrl_get_function_name(fid, name);
}
@@ -1431,8 +1453,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-static enum pm_ret_status pm_pinctrl_get_function_groups(unsigned int fid,
- unsigned int index,
+static enum pm_ret_status pm_pinctrl_get_function_groups(uint32_t fid,
+ uint32_t index,
uint16_t *groups)
{
return pm_api_pinctrl_get_function_groups(fid, index, groups);
@@ -1455,8 +1477,8 @@
*
* Return: Returns status, either success or error+reason.
*/
-static enum pm_ret_status pm_pinctrl_get_pin_groups(unsigned int pin_id,
- unsigned int index,
+static enum pm_ret_status pm_pinctrl_get_pin_groups(uint32_t pin_id,
+ uint32_t index,
uint16_t *groups)
{
return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
@@ -1472,8 +1494,8 @@
*
* This function returns requested data.
*/
-void pm_query_data(enum pm_query_id qid, unsigned int arg1, unsigned int arg2,
- unsigned int arg3, unsigned int *data)
+void pm_query_data(enum pm_query_id qid, uint32_t arg1, uint32_t arg2,
+ uint32_t arg3, uint32_t *data)
{
switch (qid) {
case PM_QID_CLOCK_GET_NAME:
@@ -1522,6 +1544,7 @@
default:
data[0] = PM_RET_ERROR_ARGS;
WARN("Unimplemented query service call: 0x%x\n", qid);
+ break;
}
}
@@ -1609,17 +1632,19 @@
*/
enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
enum pm_pll_param param_id,
- unsigned int value)
+ uint32_t value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL)
+ if (nid < NODE_APLL || nid > NODE_IOPLL) {
return PM_RET_ERROR_ARGS;
+ }
/* Check if parameter ID is valid and return an error if it's not */
- if (param_id >= PM_PLL_PARAM_MAX)
+ if (param_id >= PM_PLL_PARAM_MAX) {
return PM_RET_ERROR_ARGS;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD4(payload, PM_PLL_SET_PARAMETER, nid, param_id, value);
@@ -1637,17 +1662,19 @@
*/
enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
enum pm_pll_param param_id,
- unsigned int *value)
+ uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL)
+ if (nid < NODE_APLL || nid > NODE_IOPLL) {
return PM_RET_ERROR_ARGS;
+ }
/* Check if parameter ID is valid and return an error if it's not */
- if (param_id >= PM_PLL_PARAM_MAX)
+ if (param_id >= PM_PLL_PARAM_MAX) {
return PM_RET_ERROR_ARGS;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_PLL_GET_PARAMETER, nid, param_id);
@@ -1672,12 +1699,14 @@
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL)
+ if (nid < NODE_APLL || nid > NODE_IOPLL) {
return PM_RET_ERROR_ARGS;
+ }
/* Check if PLL mode is valid */
- if (mode >= PM_PLL_MODE_MAX)
+ if (mode >= PM_PLL_MODE_MAX) {
return PM_RET_ERROR_ARGS;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD3(payload, PM_PLL_SET_MODE, nid, mode);
@@ -1697,8 +1726,9 @@
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL)
+ if (nid < NODE_APLL || nid > NODE_IOPLL) {
return PM_RET_ERROR_ARGS;
+ }
/* Send request to the PMU */
PM_PACK_PAYLOAD2(payload, PM_PLL_GET_MODE, nid);
@@ -1722,19 +1752,20 @@
*
* @return Returns status, either success or error+reason
*/
-enum pm_ret_status pm_register_access(unsigned int register_access_id,
- unsigned int address,
- unsigned int mask,
- unsigned int value,
- unsigned int *out)
+enum pm_ret_status pm_register_access(uint32_t register_access_id,
+ uint32_t address,
+ uint32_t mask,
+ uint32_t value,
+ uint32_t *out)
{
enum pm_ret_status ret;
if (((ZYNQMP_CSU_BASEADDR & address) != ZYNQMP_CSU_BASEADDR) &&
((CSUDMA_BASE & address) != CSUDMA_BASE) &&
((RSA_CORE_BASE & address) != RSA_CORE_BASE) &&
- ((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE))
+ ((PMU_GLOBAL_BASE & address) != PMU_GLOBAL_BASE)) {
return PM_RET_ERROR_ACCESS;
+ }
switch (register_access_id) {
case CONFIG_REG_WRITE:
@@ -1746,6 +1777,7 @@
default:
ret = PM_RET_ERROR_ARGS;
WARN("Unimplemented register_access call\n\r");
+ break;
}
return ret;
}
@@ -1776,7 +1808,7 @@
return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
-enum pm_ret_status em_set_action(unsigned int *value)
+enum pm_ret_status em_set_action(uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1785,7 +1817,7 @@
return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
-enum pm_ret_status em_remove_action(unsigned int *value)
+enum pm_ret_status em_remove_action(uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
@@ -1794,7 +1826,7 @@
return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
-enum pm_ret_status em_send_errors(unsigned int *value)
+enum pm_ret_status em_send_errors(uint32_t *value)
{
uint32_t payload[PAYLOAD_ARG_CNT];
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index 48b3877..d3e9a34 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -68,100 +68,89 @@
/**********************************************************
* System-level API function declarations
**********************************************************/
-enum pm_ret_status pm_req_suspend(enum pm_node_id nid,
+enum pm_ret_status pm_req_suspend(enum pm_node_id target,
enum pm_request_ack ack,
- unsigned int latency,
- unsigned int state);
+ uint32_t latency,
+ uint32_t state);
enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
- unsigned int latency,
- unsigned int state,
+ uint32_t latency,
+ uint32_t state,
uintptr_t address);
-enum pm_ret_status pm_force_powerdown(enum pm_node_id nid,
+enum pm_ret_status pm_force_powerdown(enum pm_node_id target,
enum pm_request_ack ack);
enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason);
-enum pm_ret_status pm_req_wakeup(enum pm_node_id nid,
- unsigned int set_address,
+enum pm_ret_status pm_req_wakeup(enum pm_node_id target,
+ uint32_t set_address,
uintptr_t address,
enum pm_request_ack ack);
enum pm_ret_status pm_set_wakeup_source(enum pm_node_id target,
enum pm_node_id wkup_node,
- unsigned int enable);
+ uint32_t enable);
-enum pm_ret_status pm_system_shutdown(unsigned int type, unsigned int subtype);
-
-enum pm_ret_status pm_init_suspend_cb(enum pm_suspend_reason reason,
- unsigned int latency,
- unsigned int state,
- unsigned int timeout);
+enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype);
/* API functions for managing PM Slaves */
enum pm_ret_status pm_req_node(enum pm_node_id nid,
- unsigned int capabilities,
- unsigned int qos,
+ uint32_t capabilities,
+ uint32_t qos,
enum pm_request_ack ack);
enum pm_ret_status pm_set_requirement(enum pm_node_id nid,
- unsigned int capabilities,
- unsigned int qos,
+ uint32_t capabilities,
+ uint32_t qos,
enum pm_request_ack ack);
/* Miscellaneous API functions */
-enum pm_ret_status pm_get_api_version(unsigned int *version);
-enum pm_ret_status pm_get_node_status(enum pm_node_id node,
+enum pm_ret_status pm_get_api_version(uint32_t *version);
+enum pm_ret_status pm_get_node_status(enum pm_node_id nid,
uint32_t *ret_buff);
-enum pm_ret_status pm_acknowledge_cb(enum pm_node_id nid,
- enum pm_ret_status status,
- unsigned int oppoint);
-enum pm_ret_status pm_notify_cb(enum pm_node_id nid,
- unsigned int event,
- unsigned int oppoint);
/* Direct-Control API functions */
enum pm_ret_status pm_mmio_write(uintptr_t address,
- unsigned int mask,
- unsigned int value);
-enum pm_ret_status pm_mmio_read(uintptr_t address, unsigned int *value);
+ uint32_t mask,
+ uint32_t value);
+enum pm_ret_status pm_mmio_read(uintptr_t address, uint32_t *value);
enum pm_ret_status pm_fpga_load(uint32_t address_low,
uint32_t address_high,
uint32_t size,
uint32_t flags);
-enum pm_ret_status pm_fpga_get_status(unsigned int *value);
+enum pm_ret_status pm_fpga_get_status(uint32_t *value);
enum pm_ret_status pm_get_chipid(uint32_t *value);
-enum pm_ret_status pm_secure_rsaaes(uint32_t address_high,
- uint32_t address_low,
+enum pm_ret_status pm_secure_rsaaes(uint32_t address_low,
+ uint32_t address_high,
uint32_t size,
uint32_t flags);
unsigned int pm_get_shutdown_scope(void);
void pm_get_callbackdata(uint32_t *data, size_t count);
enum pm_ret_status pm_ioctl(enum pm_node_id nid,
- unsigned int ioctl_id,
- unsigned int arg1,
- unsigned int arg2,
- unsigned int *value);
-enum pm_ret_status pm_clock_enable(unsigned int clock_id);
-enum pm_ret_status pm_clock_disable(unsigned int clock_id);
-enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
- unsigned int *state);
-enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
- unsigned int divider);
-enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
- unsigned int *divider);
-enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
+ uint32_t ioctl_id,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t *value);
+enum pm_ret_status pm_clock_enable(uint32_t clock_id);
+enum pm_ret_status pm_clock_disable(uint32_t clock_id);
+enum pm_ret_status pm_clock_getstate(uint32_t clock_id,
+ uint32_t *state);
+enum pm_ret_status pm_clock_setdivider(uint32_t clock_id,
+ uint32_t divider);
+enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
+ uint32_t *divider);
+enum pm_ret_status pm_clock_setrate(uint32_t clock_id,
uint64_t rate);
-enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
+enum pm_ret_status pm_clock_getrate(uint32_t clock_id,
uint64_t *rate);
-enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
- unsigned int parent_id);
-enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
- unsigned int *parent_id);
-void pm_query_data(enum pm_query_id qid, unsigned int arg1, unsigned int arg2,
- unsigned int arg3, unsigned int *data);
+enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
+ uint32_t parent_index);
+enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
+ uint32_t *parent_index);
+void pm_query_data(enum pm_query_id qid, uint32_t arg1, uint32_t arg2,
+ uint32_t arg3, uint32_t *data);
enum pm_ret_status pm_sha_hash(uint32_t address_high,
uint32_t address_low,
uint32_t size,
@@ -183,28 +172,24 @@
enum pm_ret_status pm_aes_engine(uint32_t address_high,
uint32_t address_low,
uint32_t *value);
-enum pm_ret_status pm_register_access(unsigned int register_access_id,
- unsigned int address,
- unsigned int mask,
- unsigned int value,
- unsigned int *out);
+enum pm_ret_status pm_register_access(uint32_t register_access_id,
+ uint32_t address,
+ uint32_t mask,
+ uint32_t value,
+ uint32_t *out);
enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
enum pm_pll_param param_id,
- unsigned int value);
+ uint32_t value);
enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
enum pm_pll_param param_id,
- unsigned int *value);
+ uint32_t *value);
enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode);
enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode);
enum pm_ret_status pm_efuse_access(uint32_t address_high,
uint32_t address_low, uint32_t *value);
-enum pm_ret_status em_set_action(unsigned int *value);
-enum pm_ret_status em_remove_action(unsigned int *value);
-enum pm_ret_status em_send_errors(unsigned int *value);
-enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
- unsigned int config_id,
- unsigned int value,
- unsigned int *response);
+enum pm_ret_status em_set_action(uint32_t *value);
+enum pm_ret_status em_remove_action(uint32_t *value);
+enum pm_ret_status em_send_errors(uint32_t *value);
enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
uint32_t *bit_mask, uint8_t len);
enum pm_ret_status check_api_dependency(uint8_t id);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 163e891..34b931e 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -163,7 +163,7 @@
*
* Return: PM node ID corresponding to the specified interrupt
*/
-static enum pm_node_id irq_to_pm_node(unsigned int irq)
+static enum pm_node_id irq_to_pm_node(uint32_t irq)
{
assert(irq <= IRQ_MAX);
return irq_node_map[irq];
@@ -188,8 +188,9 @@
* If NODE_EXTERN could not be set as wake source, proceed with
* standard suspend (no one will wake the system otherwise)
*/
- if (ret == PM_RET_SUCCESS)
+ if (ret == PM_RET_SUCCESS) {
return;
+ }
}
zeromem(&pm_wakeup_nodes_set, sizeof(pm_wakeup_nodes_set));
@@ -198,8 +199,9 @@
uint32_t base_irq = reg_num << ISENABLER_SHIFT;
uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
- if (!reg)
+ if (!reg) {
continue;
+ }
while (reg) {
enum pm_node_id node;
@@ -208,16 +210,18 @@
idx = __builtin_ctz(lowest_set);
irq = base_irq + idx;
- if (irq > IRQ_MAX)
+ if (irq > IRQ_MAX) {
break;
+ }
node = irq_to_pm_node(irq);
reg &= ~lowest_set;
- if ((node != NODE_UNKNOWN) &&
- (!pm_wakeup_nodes_set[node])) {
- ret = pm_set_wakeup_source(NODE_APU, node, 1);
- pm_wakeup_nodes_set[node] = !ret;
+ if (node > NODE_UNKNOWN && node < NODE_MAX) {
+ if (pm_wakeup_nodes_set[node] == 0U) {
+ ret = pm_set_wakeup_source(NODE_APU, node, 1U);
+ pm_wakeup_nodes_set[node] = (ret == PM_RET_SUCCESS) ? 1U : 0U;
+ }
}
}
}
@@ -229,10 +233,11 @@
*
* Return: pointer to a proc structure if proc is found, otherwise NULL
*/
-const struct pm_proc *pm_get_proc(unsigned int cpuid)
+const struct pm_proc *pm_get_proc(uint32_t cpuid)
{
- if (cpuid < ARRAY_SIZE(pm_procs_all))
+ if (cpuid < ARRAY_SIZE(pm_procs_all)) {
return &pm_procs_all[cpuid];
+ }
return NULL;
}
@@ -246,8 +251,9 @@
const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid)
{
for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
- if (nid == pm_procs_all[i].node_id)
+ if (nid == pm_procs_all[i].node_id) {
return &pm_procs_all[i];
+ }
}
return NULL;
}
@@ -258,11 +264,12 @@
*
* Return: the cpu ID (starting from 0) for the subsystem
*/
-static unsigned int pm_get_cpuid(enum pm_node_id nid)
+static uint32_t pm_get_cpuid(enum pm_node_id nid)
{
for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
- if (pm_procs_all[i].node_id == nid)
+ if (pm_procs_all[i].node_id == nid) {
return i;
+ }
}
return UNDEFINED_CPUID;
}
@@ -276,12 +283,13 @@
* required prior to sending suspend request to PMU
* Actions taken depend on the state system is suspending to.
*/
-void pm_client_suspend(const struct pm_proc *proc, unsigned int state)
+void pm_client_suspend(const struct pm_proc *proc, uint32_t state)
{
bakery_lock_get(&pm_client_secure_lock);
- if (state == PM_STATE_SUSPEND_TO_RAM)
+ if (state == PM_STATE_SUSPEND_TO_RAM) {
pm_client_set_wakeup_sources();
+ }
/* Set powerdown request */
mmio_write_32(APU_PWRCTL, mmio_read_32(APU_PWRCTL) | proc->pwrdn_mask);
@@ -318,10 +326,11 @@
*/
void pm_client_wakeup(const struct pm_proc *proc)
{
- unsigned int cpuid = pm_get_cpuid(proc->node_id);
+ uint32_t cpuid = pm_get_cpuid(proc->node_id);
- if (cpuid == UNDEFINED_CPUID)
+ if (cpuid == UNDEFINED_CPUID) {
return;
+ }
bakery_lock_get(&pm_client_secure_lock);
@@ -336,8 +345,9 @@
enum pm_ret_status pm_set_suspend_mode(uint32_t mode)
{
if ((mode != PM_SUSPEND_MODE_STD) &&
- (mode != PM_SUSPEND_MODE_POWER_OFF))
+ (mode != PM_SUSPEND_MODE_POWER_OFF)) {
return PM_RET_ERROR_ARGS;
+ }
suspend_mode = mode;
return PM_RET_SUCCESS;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index 8eb197a..bf5ecfe 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -17,10 +17,10 @@
* Version number is a 32bit value, like:
* (PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR
*/
-#define PM_VERSION_MAJOR 1
-#define PM_VERSION_MINOR 1
+#define PM_VERSION_MAJOR 1U
+#define PM_VERSION_MINOR 1U
-#define PM_VERSION ((PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR)
+#define PM_VERSION ((PM_VERSION_MAJOR << 16U) | PM_VERSION_MINOR)
/**
* PM API versions
@@ -245,6 +245,7 @@
* @PM_RET_SUCCESS: success
* @PM_RET_ERROR_ARGS: illegal arguments provided (deprecated)
* @PM_RET_ERROR_NOTSUPPORTED: feature not supported (deprecated)
+ * @PM_RET_ERROR_NOT_ENABLED: feature is not enabled
* @PM_RET_ERROR_INTERNAL: internal error
* @PM_RET_ERROR_CONFLICT: conflict
* @PM_RET_ERROR_ACCESS: access rights violation
@@ -258,6 +259,7 @@
PM_RET_SUCCESS,
PM_RET_ERROR_ARGS = 1,
PM_RET_ERROR_NOTSUPPORTED = 4,
+ PM_RET_ERROR_NOT_ENABLED = 29,
PM_RET_ERROR_INTERNAL = 2000,
PM_RET_ERROR_CONFLICT = 2001,
PM_RET_ERROR_ACCESS = 2002,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index d88e5fa..82da57c 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -151,6 +151,8 @@
0xffffffff);
}
+ dsb();
+
spin_unlock(&inc_lock);
if (active_cores == 0) {
@@ -203,9 +205,9 @@
* Called from sip_svc_setup initialization function with the
* rt_svc_init signature.
*/
-int pm_setup(void)
+int32_t pm_setup(void)
{
- int status, ret;
+ int32_t status, ret;
status = pm_ipi_init(primary_proc);
@@ -214,7 +216,7 @@
ERROR("BL31: Platform Management API version error. Expected: "
"v%d.%d - Found: v%d.%d\n", PM_VERSION_MAJOR,
PM_VERSION_MINOR, pm_ctx.api_version >> 16,
- pm_ctx.api_version & 0xFFFF);
+ pm_ctx.api_version & 0xFFFFU);
return -EINVAL;
}
@@ -255,12 +257,12 @@
* function with rt_svc_handle signature
*/
uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
- uint64_t x4, void *cookie, void *handle, uint64_t flags)
+ uint64_t x4, const void *cookie, void *handle, uint64_t flags)
{
enum pm_ret_status ret;
uint32_t payload[PAYLOAD_ARG_CNT];
- uint32_t pm_arg[4];
+ uint32_t pm_arg[5];
uint32_t result[PAYLOAD_ARG_CNT];
uint32_t api_id;
@@ -291,7 +293,7 @@
case PM_REQ_WAKEUP:
{
/* Use address flag is encoded in the 1st bit of the low-word */
- unsigned int set_addr = pm_arg[1] & 0x1;
+ uint32_t set_addr = pm_arg[1] & 0x1;
uint64_t address = (uint64_t)pm_arg[2] << 32;
address |= pm_arg[1] & (~0x1);
@@ -419,7 +421,7 @@
case PM_CLOCK_GETRATE:
{
- uint64_t value;
+ uint64_t value = 0;
ret = pm_clock_getrate(pm_arg[0], &value);
SMC_RET2(handle, (uint64_t)ret |
@@ -520,6 +522,13 @@
{
uint32_t value;
+#if defined(ZYNQMP_SECURE_EFUSES)
+ if (is_caller_non_secure(flags)) {
+ SMC_RET1(handle,
+ (((uint64_t)PM_RET_ERROR_NOT_ENABLED) << 32) |
+ (uint64_t)PM_RET_ERROR_ACCESS);
+ }
+#endif
ret = pm_efuse_access(pm_arg[0], pm_arg[1], &value);
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
}
@@ -538,7 +547,7 @@
case PM_FEATURE_CHECK:
{
- uint32_t version;
+ uint32_t version = 0;
uint32_t bit_mask[2] = {0};
ret = pm_feature_check(pm_arg[0], &version, bit_mask,
@@ -575,7 +584,7 @@
* function with rt_svc_handle signature
*/
uint64_t em_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
- uint64_t x4, void *cookie, void *handle, uint64_t flags)
+ uint64_t x4, const void *cookie, void *handle, uint64_t flags)
{
enum pm_ret_status ret;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
index abadd40..c1781f3 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.h
@@ -9,12 +9,12 @@
#include "pm_common.h"
-int pm_setup(void);
+int32_t pm_setup(void);
uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
- uint64_t x4, void *cookie, void *handle,
+ uint64_t x4, const void *cookie, void *handle,
uint64_t flags);
uint64_t em_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
- uint64_t x4, void *cookie, void *handle,
+ uint64_t x4, const void *cookie, void *handle,
uint64_t flags);
#endif /* PM_SVC_MAIN_H */
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 114da33..4ce9b8a 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -13,9 +13,9 @@
#include "pm_svc_main.h"
/* SMC function IDs for SiP Service queries */
-#define ZYNQMP_SIP_SVC_CALL_COUNT 0x8200ff00
-#define ZYNQMP_SIP_SVC_UID 0x8200ff01
-#define ZYNQMP_SIP_SVC_VERSION 0x8200ff03
+#define ZYNQMP_SIP_SVC_CALL_COUNT U(0x8200ff00)
+#define ZYNQMP_SIP_SVC_UID U(0x8200ff01)
+#define ZYNQMP_SIP_SVC_VERSION U(0x8200ff03)
/* SiP Service Calls version numbers */
#define SIP_SVC_VERSION_MAJOR 0
@@ -53,7 +53,7 @@
* Handler for all SiP SMC calls. Handles standard SIP requests
* and calls PM SMC handler if the call is for a PM-API function.
*/
-uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
+static uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
u_register_t x3,
@@ -100,6 +100,6 @@
sip_svc,
OEN_SIP_START,
OEN_SIP_END,
- SMC_TYPE_FAST,
+ (uint8_t)SMC_TYPE_FAST,
sip_svc_setup,
sip_svc_smc_handler);
diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.c b/plat/xilinx/zynqmp/zynqmp_ipi.c
index f57369f..4ea3c6a 100644
--- a/plat/xilinx/zynqmp/zynqmp_ipi.c
+++ b/plat/xilinx/zynqmp/zynqmp_ipi.c
@@ -25,67 +25,67 @@
/* APU IPI */
{
.ipi_bit_mask = 0x1,
- .ipi_reg_base = 0xFF300000,
+ .ipi_reg_base = 0xFF300000U,
.secure_only = 0,
},
/* RPU0 IPI */
{
.ipi_bit_mask = 0x100,
- .ipi_reg_base = 0xFF310000,
+ .ipi_reg_base = 0xFF310000U,
.secure_only = 0,
},
/* RPU1 IPI */
{
.ipi_bit_mask = 0x200,
- .ipi_reg_base = 0xFF320000,
+ .ipi_reg_base = 0xFF320000U,
.secure_only = 0,
},
/* PMU0 IPI */
{
.ipi_bit_mask = 0x10000,
- .ipi_reg_base = 0xFF330000,
+ .ipi_reg_base = 0xFF330000U,
.secure_only = IPI_SECURE_MASK,
},
/* PMU1 IPI */
{
.ipi_bit_mask = 0x20000,
- .ipi_reg_base = 0xFF331000,
+ .ipi_reg_base = 0xFF331000U,
.secure_only = 0,
},
/* PMU2 IPI */
{
.ipi_bit_mask = 0x40000,
- .ipi_reg_base = 0xFF332000,
+ .ipi_reg_base = 0xFF332000U,
.secure_only = IPI_SECURE_MASK,
},
/* PMU3 IPI */
{
.ipi_bit_mask = 0x80000,
- .ipi_reg_base = 0xFF333000,
+ .ipi_reg_base = 0xFF333000U,
.secure_only = IPI_SECURE_MASK,
},
/* PL0 IPI */
{
.ipi_bit_mask = 0x1000000,
- .ipi_reg_base = 0xFF340000,
+ .ipi_reg_base = 0xFF340000U,
.secure_only = 0,
},
/* PL1 IPI */
{
.ipi_bit_mask = 0x2000000,
- .ipi_reg_base = 0xFF350000,
+ .ipi_reg_base = 0xFF350000U,
.secure_only = 0,
},
/* PL2 IPI */
{
.ipi_bit_mask = 0x4000000,
- .ipi_reg_base = 0xFF360000,
+ .ipi_reg_base = 0xFF360000U,
.secure_only = 0,
},
/* PL3 IPI */
{
.ipi_bit_mask = 0x8000000,
- .ipi_reg_base = 0xFF370000,
+ .ipi_reg_base = 0xFF370000U,
.secure_only = 0,
},
};
diff --git a/services/std_svc/rmmd/rmmd.mk b/services/std_svc/rmmd/rmmd.mk
index bac0a9f..bcf54e1 100644
--- a/services/std_svc/rmmd/rmmd.mk
+++ b/services/std_svc/rmmd/rmmd.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -12,7 +12,8 @@
RMMD_SOURCES += $(addprefix services/std_svc/rmmd/, \
${ARCH}/rmmd_helpers.S \
- rmmd_main.c)
+ rmmd_main.c \
+ rmmd_attest.c)
# Let the top-level Makefile know that we intend to include RMM image
NEED_RMM := yes
diff --git a/services/std_svc/rmmd/rmmd_attest.c b/services/std_svc/rmmd/rmmd_attest.c
new file mode 100644
index 0000000..25adf50
--- /dev/null
+++ b/services/std_svc/rmmd/rmmd_attest.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdint.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <lib/spinlock.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include "rmmd_private.h"
+#include <services/rmmd_svc.h>
+
+static spinlock_t lock;
+
+/* For printing Realm attestation token hash */
+#define DIGITS_PER_BYTE 2UL
+#define LENGTH_OF_TERMINATING_ZERO_IN_BYTES 1UL
+#define BYTES_PER_LINE_BASE 4UL
+
+static void print_challenge(uint8_t *hash, size_t hash_size)
+{
+ size_t leftover;
+ /*
+ * bytes_per_line is always a power of two, so it can be used to
+ * construct mask with it when it is necessary to count remainder.
+ *
+ */
+ const size_t bytes_per_line = 1 << BYTES_PER_LINE_BASE;
+ char hash_text[(1 << BYTES_PER_LINE_BASE) * DIGITS_PER_BYTE +
+ LENGTH_OF_TERMINATING_ZERO_IN_BYTES];
+ const char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+ unsigned int i;
+
+ for (i = 0U; i < hash_size; ++i) {
+ hash_text[(i & (bytes_per_line - 1)) * DIGITS_PER_BYTE] =
+ hex_chars[hash[i] >> 4];
+ hash_text[(i & (bytes_per_line - 1)) * DIGITS_PER_BYTE + 1] =
+ hex_chars[hash[i] & 0x0f];
+ if (((i + 1) & (bytes_per_line - 1)) == 0U) {
+ hash_text[bytes_per_line * DIGITS_PER_BYTE] = '\0';
+ VERBOSE("hash part %u = %s\n",
+ (i >> BYTES_PER_LINE_BASE) + 1, hash_text);
+ }
+ }
+
+ leftover = (size_t)i & (bytes_per_line - 1);
+
+ if (leftover != 0UL) {
+ hash_text[leftover * DIGITS_PER_BYTE] = '\0';
+ VERBOSE("hash part %u = %s\n", (i >> BYTES_PER_LINE_BASE) + 1,
+ hash_text);
+ }
+}
+
+/*
+ * Helper function to validate that the buffer base and length are
+ * within range.
+ */
+static int validate_buffer_params(uint64_t buf_pa, uint64_t buf_len)
+{
+ unsigned long shared_buf_page;
+ uintptr_t shared_buf_base;
+
+ (void)plat_rmmd_get_el3_rmm_shared_mem(&shared_buf_base);
+
+ shared_buf_page = shared_buf_base & ~PAGE_SIZE_MASK;
+
+ /* Validate the buffer pointer */
+ if ((buf_pa & ~PAGE_SIZE_MASK) != shared_buf_page) {
+ ERROR("Buffer PA out of range\n");
+ return E_RMM_BAD_ADDR;
+ }
+
+ /* Validate the size of the shared area */
+ if (((buf_pa + buf_len - 1UL) & ~PAGE_SIZE_MASK) != shared_buf_page) {
+ ERROR("Invalid buffer length\n");
+ return E_RMM_INVAL;
+ }
+
+ return 0; /* No error */
+}
+
+int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t c_size)
+{
+ int err;
+ uint8_t temp_buf[SHA512_DIGEST_SIZE];
+
+ err = validate_buffer_params(buf_pa, *buf_size);
+ if (err != 0) {
+ return err;
+ }
+
+ if ((c_size != SHA256_DIGEST_SIZE) &&
+ (c_size != SHA384_DIGEST_SIZE) &&
+ (c_size != SHA512_DIGEST_SIZE)) {
+ ERROR("Invalid hash size: %lu\n", c_size);
+ return E_RMM_INVAL;
+ }
+
+ spin_lock(&lock);
+
+ (void)memcpy(temp_buf, (void *)buf_pa, c_size);
+
+ print_challenge((uint8_t *)temp_buf, c_size);
+
+ /* Get the platform token. */
+ err = plat_rmmd_get_cca_attest_token((uintptr_t)buf_pa,
+ buf_size, (uintptr_t)temp_buf, c_size);
+
+ if (err != 0) {
+ ERROR("Failed to get platform token: %d.\n", err);
+ err = E_RMM_UNK;
+ }
+
+ spin_unlock(&lock);
+
+ return err;
+}
+
+int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t ecc_curve)
+{
+ int err;
+
+ err = validate_buffer_params(buf_pa, *buf_size);
+ if (err != 0) {
+ return err;
+ }
+
+ if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
+ ERROR("Invalid ECC curve specified\n");
+ return E_RMM_INVAL;
+ }
+
+ spin_lock(&lock);
+
+ /* Get the Realm attestation key. */
+ err = plat_rmmd_get_cca_realm_attest_key((uintptr_t)buf_pa, buf_size,
+ (unsigned int)ecc_curve);
+ if (err != 0) {
+ ERROR("Failed to get attestation key: %d.\n", err);
+ err = E_RMM_UNK;
+ }
+
+ spin_unlock(&lock);
+
+ return err;
+}
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 28d0b01..7cb76de 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,8 +26,6 @@
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <services/gtsi_svc.h>
-#include <services/rmi_svc.h>
#include <services/rmmd_svc.h>
#include <smccc_helpers.h>
#include <lib/extensions/sve.h>
@@ -35,6 +33,11 @@
#include "rmmd_private.h"
/*******************************************************************************
+ * RMM boot failure flag
+ ******************************************************************************/
+static bool rmm_boot_failed;
+
+/*******************************************************************************
* RMM context information.
******************************************************************************/
rmmd_rmm_context_t rmm_context[PLATFORM_CORE_COUNT];
@@ -62,10 +65,6 @@
cm_set_context(&(rmm_ctx->cpu_ctx), REALM);
- /* Save the current el1/el2 context before loading realm context. */
- cm_el1_sysregs_context_save(NON_SECURE);
- cm_el2_sysregs_context_save(NON_SECURE);
-
/* Restore the realm context assigned above */
cm_el1_sysregs_context_restore(REALM);
cm_el2_sysregs_context_restore(REALM);
@@ -74,14 +73,15 @@
/* Enter RMM */
rc = rmmd_rmm_enter(&rmm_ctx->c_rt_ctx);
- /* Save realm context */
+ /*
+ * Save realm context. EL1 and EL2 Non-secure
+ * contexts will be restored before exiting to
+ * Non-secure world, therefore there is no need
+ * to clear EL1 and EL2 context registers.
+ */
cm_el1_sysregs_context_save(REALM);
cm_el2_sysregs_context_save(REALM);
- /* Restore the el1/el2 context again. */
- cm_el1_sysregs_context_restore(NON_SECURE);
- cm_el2_sysregs_context_restore(NON_SECURE);
-
return rc;
}
@@ -137,13 +137,10 @@
******************************************************************************/
static int32_t rmm_init(void)
{
-
- uint64_t rc;
-
+ long rc;
rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()];
INFO("RMM init start.\n");
- ctx->state = RMM_STATE_RESET;
/* Enable architecture extensions */
manage_extensions_realm(&ctx->cpu_ctx);
@@ -152,12 +149,13 @@
rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx);
rc = rmmd_rmm_sync_entry(ctx);
- if (rc != 0ULL) {
- ERROR("RMM initialisation failed 0x%" PRIx64 "\n", rc);
- panic();
+ if (rc != E_RMM_BOOT_SUCCESS) {
+ ERROR("RMM init failed: %ld\n", rc);
+ /* Mark the boot as failed for all the CPUs */
+ rmm_boot_failed = true;
+ return 0;
}
- ctx->state = RMM_STATE_IDLE;
INFO("RMM init end.\n");
return 1;
@@ -168,9 +166,13 @@
******************************************************************************/
int rmmd_setup(void)
{
+ size_t shared_buf_size __unused;
+ uintptr_t shared_buf_base;
uint32_t ep_attr;
unsigned int linear_id = plat_my_core_pos();
rmmd_rmm_context_t *rmm_ctx = &rmm_context[linear_id];
+ rmm_manifest_t *manifest;
+ int rc;
/* Make sure RME is supported. */
assert(get_armv9_2_feat_rme_support() != 0U);
@@ -197,6 +199,34 @@
MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
+ shared_buf_size =
+ plat_rmmd_get_el3_rmm_shared_mem(&shared_buf_base);
+
+ assert((shared_buf_size == SZ_4K) &&
+ ((void *)shared_buf_base != NULL));
+
+ /* Load the boot manifest at the beginning of the shared area */
+ manifest = (rmm_manifest_t *)shared_buf_base;
+ rc = plat_rmmd_load_manifest(manifest);
+ if (rc != 0) {
+ ERROR("Error loading RMM Boot Manifest (%i)\n", rc);
+ return rc;
+ }
+ flush_dcache_range((uintptr_t)shared_buf_base, shared_buf_size);
+
+ /*
+ * Prepare coldboot arguments for RMM:
+ * arg0: This CPUID (primary processor).
+ * arg1: Version for this Boot Interface.
+ * arg2: PLATFORM_CORE_COUNT.
+ * arg3: Base address for the EL3 <-> RMM shared area. The boot
+ * manifest will be stored at the beginning of this area.
+ */
+ rmm_ep_info->args.arg0 = linear_id;
+ rmm_ep_info->args.arg1 = RMM_EL3_INTERFACE_VERSION;
+ rmm_ep_info->args.arg2 = PLATFORM_CORE_COUNT;
+ rmm_ep_info->args.arg3 = shared_buf_base;
+
/* Initialise RMM context with this entry point information */
cm_setup_context(&rmm_ctx->cpu_ctx, rmm_ep_info);
@@ -249,15 +279,20 @@
uint64_t x3, uint64_t x4, void *cookie,
void *handle, uint64_t flags)
{
- rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()];
uint32_t src_sec_state;
+ /* If RMM failed to boot, treat any RMI SMC as unknown */
+ if (rmm_boot_failed) {
+ WARN("RMMD: Failed to boot up RMM. Ignoring RMI call\n");
+ SMC_RET1(handle, SMC_UNK);
+ }
+
/* Determine which security state this SMC originated from */
src_sec_state = caller_sec_state(flags);
/* RMI must not be invoked by the Secure world */
if (src_sec_state == SMC_FROM_SECURE) {
- WARN("RMM: RMI invoked by secure world.\n");
+ WARN("RMMD: RMI invoked by secure world.\n");
SMC_RET1(handle, SMC_UNK);
}
@@ -266,25 +301,22 @@
* is.
*/
if (src_sec_state == SMC_FROM_NON_SECURE) {
- VERBOSE("RMM: RMI call from non-secure world.\n");
+ VERBOSE("RMMD: RMI call from non-secure world.\n");
return rmmd_smc_forward(NON_SECURE, REALM, smc_fid,
x1, x2, x3, x4, handle);
}
- assert(src_sec_state == SMC_FROM_REALM);
+ if (src_sec_state != SMC_FROM_REALM) {
+ SMC_RET1(handle, SMC_UNK);
+ }
switch (smc_fid) {
- case RMI_RMM_REQ_COMPLETE:
- if (ctx->state == RMM_STATE_RESET) {
- VERBOSE("RMM: running rmmd_rmm_sync_exit\n");
- rmmd_rmm_sync_exit(x1);
- }
-
+ case RMM_RMI_REQ_COMPLETE:
return rmmd_smc_forward(REALM, NON_SECURE, x1,
x2, x3, x4, 0, handle);
default:
- WARN("RMM: Unsupported RMM call 0x%08x\n", smc_fid);
+ WARN("RMMD: Unsupported RMM call 0x%08x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
}
}
@@ -296,11 +328,26 @@
******************************************************************************/
static void *rmmd_cpu_on_finish_handler(const void *arg)
{
- int32_t rc;
+ long rc;
uint32_t linear_id = plat_my_core_pos();
rmmd_rmm_context_t *ctx = &rmm_context[linear_id];
- ctx->state = RMM_STATE_RESET;
+ if (rmm_boot_failed) {
+ /* RMM Boot failed on a previous CPU. Abort. */
+ ERROR("RMM Failed to initialize. Ignoring for CPU%d\n",
+ linear_id);
+ return NULL;
+ }
+
+ /*
+ * Prepare warmboot arguments for RMM:
+ * arg0: This CPUID.
+ * arg1 to arg3: Not used.
+ */
+ rmm_ep_info->args.arg0 = linear_id;
+ rmm_ep_info->args.arg1 = 0ULL;
+ rmm_ep_info->args.arg2 = 0ULL;
+ rmm_ep_info->args.arg3 = 0ULL;
/* Initialise RMM context with this entry point information */
cm_setup_context(&ctx->cpu_ctx, rmm_ep_info);
@@ -312,60 +359,85 @@
rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx);
rc = rmmd_rmm_sync_entry(ctx);
- if (rc != 0) {
- ERROR("RMM initialisation failed (%d) on CPU%d\n", rc,
- linear_id);
- panic();
+
+ if (rc != E_RMM_BOOT_SUCCESS) {
+ ERROR("RMM init failed on CPU%d: %ld\n", linear_id, rc);
+ /* Mark the boot as failed for any other booting CPU */
+ rmm_boot_failed = true;
}
- ctx->state = RMM_STATE_IDLE;
return NULL;
}
/* Subscribe to PSCI CPU on to initialize RMM on secondary */
SUBSCRIBE_TO_EVENT(psci_cpu_on_finish, rmmd_cpu_on_finish_handler);
+/* Convert GPT lib error to RMMD GTS error */
+static int gpt_to_gts_error(int error, uint32_t smc_fid, uint64_t address)
+{
+ int ret;
+
+ if (error == 0) {
+ return E_RMM_OK;
+ }
+
+ if (error == -EINVAL) {
+ ret = E_RMM_BAD_ADDR;
+ } else {
+ /* This is the only other error code we expect */
+ assert(error == -EPERM);
+ ret = E_RMM_BAD_PAS;
+ }
+
+ ERROR("RMMD: PAS Transition failed. GPT ret = %d, PA: 0x%"PRIx64 ", FID = 0x%x\n",
+ error, address, smc_fid);
+ return ret;
+}
+
/*******************************************************************************
- * This function handles all SMCs in the range reserved for GTF.
+ * This function handles RMM-EL3 interface SMCs
******************************************************************************/
-uint64_t rmmd_gtsi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
+uint64_t rmmd_rmm_el3_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 src_sec_state;
int ret;
+ /* If RMM failed to boot, treat any RMM-EL3 interface SMC as unknown */
+ if (rmm_boot_failed) {
+ WARN("RMMD: Failed to boot up RMM. Ignoring RMM-EL3 call\n");
+ SMC_RET1(handle, SMC_UNK);
+ }
+
/* Determine which security state this SMC originated from */
src_sec_state = caller_sec_state(flags);
if (src_sec_state != SMC_FROM_REALM) {
- WARN("RMM: GTF call originated from secure or normal world\n");
+ WARN("RMMD: RMM-EL3 call originated from secure or normal world\n");
SMC_RET1(handle, SMC_UNK);
}
switch (smc_fid) {
- case SMC_ASC_MARK_REALM:
+ case RMM_GTSI_DELEGATE:
ret = gpt_delegate_pas(x1, PAGE_SIZE_4KB, SMC_FROM_REALM);
- break;
- case SMC_ASC_MARK_NONSECURE:
+ SMC_RET1(handle, gpt_to_gts_error(ret, smc_fid, x1));
+ case RMM_GTSI_UNDELEGATE:
ret = gpt_undelegate_pas(x1, PAGE_SIZE_4KB, SMC_FROM_REALM);
- break;
+ SMC_RET1(handle, gpt_to_gts_error(ret, smc_fid, x1));
+ case RMM_ATTEST_GET_PLAT_TOKEN:
+ ret = rmmd_attest_get_platform_token(x1, &x2, x3);
+ SMC_RET2(handle, ret, x2);
+ case RMM_ATTEST_GET_REALM_KEY:
+ ret = rmmd_attest_get_signing_key(x1, &x2, x3);
+ SMC_RET2(handle, ret, x2);
+
+ case RMM_BOOT_COMPLETE:
+ VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
+ rmmd_rmm_sync_exit(x1);
+
default:
- WARN("RMM: Unsupported GTF call 0x%08x\n", smc_fid);
+ WARN("RMMD: Unsupported RMM-EL3 call 0x%08x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
}
-
- if (ret == -EINVAL) {
- ERROR("[GTSI] Transition failed: invalid %s\n", "address");
- ERROR(" PA: 0x%"PRIx64 ", SRC: %d, PAS: %d\n", x1,
- SMC_FROM_REALM, smc_fid);
- ret = GRAN_TRANS_RET_BAD_ADDR;
- } else if (ret == -EPERM) {
- ERROR("[GTSI] Transition failed: invalid %s\n", "caller/PAS");
- ERROR(" PA: 0x%"PRIx64 ", SRC: %d, PAS: %d\n", x1,
- SMC_FROM_REALM, smc_fid);
- ret = GRAN_TRANS_RET_BAD_PAS;
- }
-
- SMC_RET1(handle, ret);
}
diff --git a/services/std_svc/rmmd/rmmd_private.h b/services/std_svc/rmmd/rmmd_private.h
index d170bcd..4954a43 100644
--- a/services/std_svc/rmmd/rmmd_private.h
+++ b/services/std_svc/rmmd/rmmd_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -31,12 +31,6 @@
#ifndef __ASSEMBLER__
#include <stdint.h>
-#include <services/rmi_svc.h>
-
-typedef enum rmm_state {
- RMM_STATE_RESET = 0,
- RMM_STATE_IDLE
-} rmm_state_t;
/*
* Data structure used by the RMM dispatcher (RMMD) in EL3 to track context of
@@ -45,13 +39,18 @@
typedef struct rmmd_rmm_context {
uint64_t c_rt_ctx;
cpu_context_t cpu_ctx;
- rmm_state_t state;
} rmmd_rmm_context_t;
/* Functions used to enter/exit the RMM synchronously */
uint64_t rmmd_rmm_sync_entry(rmmd_rmm_context_t *ctx);
__dead2 void rmmd_rmm_sync_exit(uint64_t rc);
+/* Functions implementing attestation utilities for RMM */
+int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t c_size);
+int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t ecc_curve);
+
/* Assembly helpers */
uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);
void __dead2 rmmd_rmm_exit(uint64_t c_rt_ctx, uint64_t ret);
diff --git a/services/std_svc/rmmd/trp/trp.mk b/services/std_svc/rmmd/trp/trp.mk
index a4f6e03..44bbf22 100644
--- a/services/std_svc/rmmd/trp/trp.mk
+++ b/services/std_svc/rmmd/trp/trp.mk
@@ -1,11 +1,12 @@
#
-# Copyright (c) 2021 Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022 Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
-RMM_SOURCES += services/std_svc/rmmd/trp/trp_entry.S \
- services/std_svc/rmmd/trp/trp_main.c
+RMM_SOURCES += services/std_svc/rmmd/trp/trp_entry.S \
+ services/std_svc/rmmd/trp/trp_main.c \
+ services/std_svc/rmmd/trp/trp_helpers.c
RMM_LINKERFILE := services/std_svc/rmmd/trp/linker.lds
diff --git a/services/std_svc/rmmd/trp/trp_entry.S b/services/std_svc/rmmd/trp/trp_entry.S
index 5826d75..47c1df1 100644
--- a/services/std_svc/rmmd/trp/trp_entry.S
+++ b/services/std_svc/rmmd/trp/trp_entry.S
@@ -1,12 +1,13 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
-#include <services/gtsi_svc.h>
-#include <services/rmi_svc.h>
+#include <services/rmmd_svc.h>
+
+#include <platform_def.h>
#include "trp_private.h"
.global trp_head
@@ -32,6 +33,28 @@
* ---------------------------------------------
*/
trp_head:
+ /*
+ * Stash arguments from previous boot stage
+ */
+ mov x20, x0
+ mov x21, x1
+ mov x22, x2
+ mov x23, x3
+
+ /*
+ * Validate CPUId before allocating a stack.
+ */
+ cmp x20, #PLATFORM_CORE_COUNT
+ b.lo 1f
+
+ mov_imm x0, RMM_BOOT_COMPLETE
+ mov_imm x1, E_RMM_BOOT_CPU_ID_OUT_OF_RANGE
+ smc #0
+
+ /* EL3 should never return back here, so panic if it does */
+ b trp_panic
+
+1:
bl plat_set_my_stack
/*
@@ -46,7 +69,6 @@
adr x2, cold_boot_flag
str xzr, [x2]
-
/* ---------------------------------------------
* Zero out BSS section
* ---------------------------------------------
@@ -55,15 +77,21 @@
ldr x1, =__BSS_SIZE__
bl zeromem
+ mov x0, x20
+ mov x1, x21
+ mov x2, x22
+ mov x3, x23
bl trp_setup
-
bl trp_main
warm_boot:
- mov_imm x0, RMI_RMM_REQ_COMPLETE
- mov x1, xzr
+ mov_imm x0, RMM_BOOT_COMPLETE
+ mov x1, xzr /* RMM_BOOT_SUCCESS */
smc #0
b trp_handler
+trp_panic:
+ no_ret plat_panic_handler
+
/*
* Flag to mark if it is a cold boot.
* 1: cold boot, 0: warmboot.
diff --git a/services/std_svc/rmmd/trp/trp_helpers.c b/services/std_svc/rmmd/trp/trp_helpers.c
new file mode 100644
index 0000000..159f3a5
--- /dev/null
+++ b/services/std_svc/rmmd/trp/trp_helpers.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <plat/common/platform.h>
+#include <services/rmmd_svc.h>
+#include "trp_private.h"
+
+/*
+ * Per cpu data structure to populate parameters for an SMC in C code and use
+ * a pointer to this structure in assembler code to populate x0-x7
+ */
+static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT];
+
+/*
+ * Set the arguments for SMC call
+ */
+trp_args_t *set_smc_args(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7)
+{
+ uint32_t linear_id;
+ trp_args_t *pcpu_smc_args;
+
+ /*
+ * Return to Secure Monitor by raising an SMC. The results of the
+ * service are passed as an arguments to the SMC
+ */
+ linear_id = plat_my_core_pos();
+ pcpu_smc_args = &trp_smc_args[linear_id];
+ write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0);
+ write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1);
+ write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2);
+ write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3);
+ write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4);
+ write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5);
+ write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6);
+ write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7);
+
+ return pcpu_smc_args;
+}
+
+/*
+ * Abort the boot process with the reason given in err.
+ */
+__dead2 void trp_boot_abort(uint64_t err)
+{
+ (void)trp_smc(set_smc_args(RMM_BOOT_COMPLETE, err, 0, 0, 0, 0, 0, 0));
+ panic();
+}
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 2ab9ecc..5a56af0 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,59 +7,63 @@
#include <common/debug.h>
#include <plat/common/platform.h>
-#include <services/gtsi_svc.h>
-#include <services/rmi_svc.h>
+#include <services/rmm_core_manifest.h>
+#include <services/rmmd_svc.h>
#include <services/trp/platform_trp.h>
+#include <trp_helpers.h>
+#include "trp_private.h"
#include <platform_def.h>
-#include "trp_private.h"
-/*******************************************************************************
- * Per cpu data structure to populate parameters for an SMC in C code and use
- * a pointer to this structure in assembler code to populate x0-x7
- ******************************************************************************/
-static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT];
+/* Parameters received from the previous image */
+static unsigned int trp_boot_abi_version;
+static uintptr_t trp_shared_region_start;
+
+/* Parameters received from boot manifest */
+uint32_t trp_boot_manifest_version;
/*******************************************************************************
- * Set the arguments for SMC call
+ * Setup function for TRP.
******************************************************************************/
-static trp_args_t *set_smc_args(uint64_t arg0,
- uint64_t arg1,
- uint64_t arg2,
- uint64_t arg3,
- uint64_t arg4,
- uint64_t arg5,
- uint64_t arg6,
- uint64_t arg7)
+void trp_setup(uint64_t x0,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3)
{
- uint32_t linear_id;
- trp_args_t *pcpu_smc_args;
-
/*
- * Return to Secure Monitor by raising an SMC. The results of the
- * service are passed as an arguments to the SMC
+ * Validate boot parameters.
+ *
+ * According to the Boot Interface ABI v.0.1, the
+ * parameters recived from EL3 are:
+ * x0: CPUID (verified earlier so not used)
+ * x1: Boot Interface version
+ * x2: PLATFORM_CORE_COUNT
+ * x3: Pointer to the shared memory area.
*/
- linear_id = plat_my_core_pos();
- pcpu_smc_args = &trp_smc_args[linear_id];
- write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0);
- write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1);
- write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2);
- write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3);
- write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4);
- write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5);
- write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6);
- write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7);
- return pcpu_smc_args;
-}
+ (void)x0;
-/*******************************************************************************
- * Setup function for TRP.
- ******************************************************************************/
-void trp_setup(void)
-{
+ if (TRP_RMM_EL3_VERSION_GET_MAJOR(x1) != TRP_RMM_EL3_ABI_VERS_MAJOR) {
+ trp_boot_abort(E_RMM_BOOT_VERSION_MISMATCH);
+ }
+
+ if ((void *)x3 == NULL) {
+ trp_boot_abort(E_RMM_BOOT_INVALID_SHARED_BUFFER);
+ }
+
+ if (x2 > TRP_PLATFORM_CORE_COUNT) {
+ trp_boot_abort(E_RMM_BOOT_CPUS_OUT_OF_RANGE);
+ }
+
+ trp_boot_abi_version = x1;
+ trp_shared_region_start = x3;
+ flush_dcache_range((uintptr_t)&trp_boot_abi_version,
+ sizeof(trp_boot_abi_version));
+ flush_dcache_range((uintptr_t)&trp_shared_region_start,
+ sizeof(trp_shared_region_start));
+
/* Perform early platform-specific setup */
- trp_early_platform_setup();
+ trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start);
}
/* Main function for TRP */
@@ -67,9 +71,19 @@
{
NOTICE("TRP: %s\n", version_string);
NOTICE("TRP: %s\n", build_message);
+ NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
+ TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
+ NOTICE("TRP: Boot Manifest Version : v.%u.%u\n",
+ RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version),
+ RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version));
INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE);
+ INFO("TRP: Base address for the shared region : 0x%lx\n",
+ (unsigned long)trp_shared_region_start);
INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END
- RMM_BASE));
+ INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n",
+ TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version),
+ TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version));
}
/*******************************************************************************
@@ -79,7 +93,7 @@
{
VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
RMI_ABI_VERSION_MINOR);
- return set_smc_args(RMI_RMM_REQ_COMPLETE, RMI_ABI_VERSION,
+ return set_smc_args(RMM_RMI_REQ_COMPLETE, RMI_ABI_VERSION,
0, 0, 0, 0, 0, 0);
}
@@ -91,13 +105,13 @@
unsigned long long ret;
VERBOSE("Delegating granule 0x%llx\n", x1);
- ret = trp_smc(set_smc_args(SMC_ASC_MARK_REALM, x1, 0, 0, 0, 0, 0, 0));
+ ret = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1, 0, 0, 0, 0, 0, 0));
if (ret != 0ULL) {
ERROR("Granule transition from NON-SECURE type to REALM type "
"failed 0x%llx\n", ret);
}
- return set_smc_args(RMI_RMM_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
+ return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
}
/*******************************************************************************
@@ -108,13 +122,13 @@
unsigned long long ret;
VERBOSE("Undelegating granule 0x%llx\n", x1);
- ret = trp_smc(set_smc_args(SMC_ASC_MARK_NONSECURE, x1, 0, 0, 0, 0, 0, 0));
+ ret = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1, 0, 0, 0, 0, 0, 0));
if (ret != 0ULL) {
ERROR("Granule transition from REALM type to NON-SECURE type "
"failed 0x%llx\n", ret);
}
- return set_smc_args(RMI_RMM_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
+ return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
}
/*******************************************************************************
diff --git a/services/std_svc/rmmd/trp/trp_private.h b/services/std_svc/rmmd/trp/trp_private.h
index 9231390..945ae1c 100644
--- a/services/std_svc/rmmd/trp/trp_private.h
+++ b/services/std_svc/rmmd/trp/trp_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,35 +7,39 @@
#ifndef TRP_PRIVATE_H
#define TRP_PRIVATE_H
-/* Definitions to help the assembler access the SMC/ERET args structure */
-#define TRP_ARGS_SIZE TRP_ARGS_END
-#define TRP_ARG0 0x0
-#define TRP_ARG1 0x8
-#define TRP_ARG2 0x10
-#define TRP_ARG3 0x18
-#define TRP_ARG4 0x20
-#define TRP_ARG5 0x28
-#define TRP_ARG6 0x30
-#define TRP_ARG7 0x38
-#define TRP_ARGS_END 0x40
+#include <services/rmmd_svc.h>
+#include <trp_helpers.h>
+
+/* Definitions for RMM-EL3 Interface ABI VERSION */
+#define TRP_RMM_EL3_ABI_VERS_MAJOR RMM_EL3_IFC_VERSION_MAJOR
+#define TRP_RMM_EL3_ABI_VERS_MINOR RMM_EL3_IFC_VERSION_MINOR
+#define TRP_RMM_EL3_ABI_VERS (((TRP_RMM_EL3_ABI_VERS_MAJOR & 0x7FFF) << 16) | \
+ (TRP_RMM_EL3_ABI_VERS_MINOR & 0xFFFF))
+
+#define TRP_PLATFORM_CORE_COUNT PLATFORM_CORE_COUNT
#ifndef __ASSEMBLER__
#include <stdint.h>
-/* Data structure to hold SMC arguments */
-typedef struct trp_args {
- uint64_t regs[TRP_ARGS_END >> 3];
-} __aligned(CACHE_WRITEBACK_GRANULE) trp_args_t;
-
#define write_trp_arg(args, offset, val) (((args)->regs[offset >> 3]) \
= val)
+/* RMI SMC64 FIDs handled by the TRP */
+#define RMI_RMM_REQ_VERSION SMC64_RMI_FID(U(0))
+#define RMI_RMM_GRANULE_DELEGATE SMC64_RMI_FID(U(1))
+#define RMI_RMM_GRANULE_UNDELEGATE SMC64_RMI_FID(U(2))
/* Definitions for RMI VERSION */
#define RMI_ABI_VERSION_MAJOR U(0x0)
#define RMI_ABI_VERSION_MINOR U(0x0)
-#define RMI_ABI_VERSION ((RMI_ABI_VERSION_MAJOR << 16) | \
- RMI_ABI_VERSION_MINOR)
+#define RMI_ABI_VERSION (((RMI_ABI_VERSION_MAJOR & 0x7FFF) \
+ << 16) | \
+ (RMI_ABI_VERSION_MINOR & 0xFFFF))
+
+#define TRP_RMM_EL3_VERSION_GET_MAJOR(x) \
+ RMM_EL3_IFC_VERSION_GET_MAJOR((x))
+#define TRP_RMM_EL3_VERSION_GET_MINOR(x) \
+ RMM_EL3_IFC_VERSION_GET_MAJOR_MINOR((x))
/* Helper to issue SMC calls to BL31 */
uint64_t trp_smc(trp_args_t *);
@@ -44,7 +48,10 @@
void trp_main(void);
/* Setup TRP. Executed only by Primary CPU */
-void trp_setup(void);
+void trp_setup(uint64_t x0,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3);
#endif /* __ASSEMBLER__ */
#endif /* TRP_PRIVATE_H */
diff --git a/services/std_svc/spm_mm/aarch64/spm_mm_helpers.S b/services/std_svc/spm/common/aarch64/spm_helpers.S
similarity index 96%
rename from services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
rename to services/std_svc/spm/common/aarch64/spm_helpers.S
index 2c3aaf7..95e69fb 100644
--- a/services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
+++ b/services/std_svc/spm/common/aarch64/spm_helpers.S
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
-#include "../spm_mm_private.h"
+#include "spm_common.h"
.global spm_secure_partition_enter
.global spm_secure_partition_exit
diff --git a/services/std_svc/spm/common/include/spm_common.h b/services/std_svc/spm/common/include/spm_common.h
new file mode 100644
index 0000000..68805fc
--- /dev/null
+++ b/services/std_svc/spm/common/include/spm_common.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPM_COMMON_H
+#define SPM_COMMON_H
+
+#include <context.h>
+
+/*******************************************************************************
+ * Constants that allow assembler code to preserve callee-saved registers of the
+ * C runtime context while performing a security state switch.
+ ******************************************************************************/
+#define SP_C_RT_CTX_X19 0x0
+#define SP_C_RT_CTX_X20 0x8
+#define SP_C_RT_CTX_X21 0x10
+#define SP_C_RT_CTX_X22 0x18
+#define SP_C_RT_CTX_X23 0x20
+#define SP_C_RT_CTX_X24 0x28
+#define SP_C_RT_CTX_X25 0x30
+#define SP_C_RT_CTX_X26 0x38
+#define SP_C_RT_CTX_X27 0x40
+#define SP_C_RT_CTX_X28 0x48
+#define SP_C_RT_CTX_X29 0x50
+#define SP_C_RT_CTX_X30 0x58
+
+#define SP_C_RT_CTX_SIZE 0x60
+#define SP_C_RT_CTX_ENTRIES (SP_C_RT_CTX_SIZE >> DWORD_SHIFT)
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/* Assembly helpers */
+uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
+void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPM_COMMON_H */
diff --git a/services/std_svc/spm/common/spm.mk b/services/std_svc/spm/common/spm.mk
new file mode 100644
index 0000000..9aa96be
--- /dev/null
+++ b/services/std_svc/spm/common/spm.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch64)
+ $(error "Error: SPM is only supported on aarch64.")
+endif
+
+INCLUDES += -Iservices/std_svc/spm/common/include
+
+SPM_SOURCES := $(addprefix services/std_svc/spm/common/,\
+ ${ARCH}/spm_helpers.S)
+
+# Let the top-level Makefile know that we intend to include a BL32 image
+NEED_BL32 := yes
diff --git a/services/std_svc/spm/el3_spmc/logical_sp.c b/services/std_svc/spm/el3_spmc/logical_sp.c
new file mode 100644
index 0000000..e080832
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/logical_sp.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <services/el3_spmc_logical_sp.h>
+#include <services/ffa_svc.h>
+#include "spmc.h"
+
+/*******************************************************************************
+ * Validate any logical partition descriptors before we initialise.
+ * Initialization of said partitions will be taken care of during SPMC boot.
+ ******************************************************************************/
+int el3_sp_desc_validate(void)
+{
+ struct el3_lp_desc *lp_array;
+
+ /*
+ * Assert the number of descriptors is less than maximum allowed.
+ * This constant should be define on a per platform basis.
+ */
+ assert(EL3_LP_DESCS_COUNT <= MAX_EL3_LP_DESCS_COUNT);
+
+ /* Check the array bounds are valid. */
+ assert(EL3_LP_DESCS_END >= EL3_LP_DESCS_START);
+
+ /* If no logical partitions are implemented then simply bail out. */
+ if (EL3_LP_DESCS_COUNT == 0U) {
+ return 0;
+ }
+
+ lp_array = get_el3_lp_array();
+
+ for (unsigned int index = 0; index < EL3_LP_DESCS_COUNT; index++) {
+ struct el3_lp_desc *lp_desc = &lp_array[index];
+
+ /* Validate our logical partition descriptors. */
+ if (lp_desc == NULL) {
+ ERROR("Invalid Logical SP Descriptor\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Ensure the ID follows the convention to indidate it resides
+ * in the secure world.
+ */
+ if (!ffa_is_secure_world_id(lp_desc->sp_id)) {
+ ERROR("Invalid Logical SP ID (0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+
+ /* Ensure we don't conflict with the SPMC partition ID. */
+ if (lp_desc->sp_id == FFA_SPMC_ID) {
+ ERROR("Logical SP ID clashes with SPMC ID(0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+
+ /* Ensure the UUID is not the NULL UUID. */
+ if (lp_desc->uuid[0] == 0 && lp_desc->uuid[1] == 0 &&
+ lp_desc->uuid[2] == 0 && lp_desc->uuid[3] == 0) {
+ ERROR("Invalid UUID for Logical SP (0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+
+ /* Ensure init function callback is registered. */
+ if (lp_desc->init == NULL) {
+ ERROR("Missing init function for Logical SP(0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+
+ /* Ensure that LP only supports receiving direct requests. */
+ if (lp_desc->properties &
+ ~(FFA_PARTITION_DIRECT_REQ_RECV)) {
+ ERROR("Invalid partition properties (0x%x)\n",
+ lp_desc->properties);
+ return -EINVAL;
+ }
+
+ /* Ensure direct request function callback is registered. */
+ if (lp_desc->direct_req == NULL) {
+ ERROR("No Direct Req handler for Logical SP (0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+
+ /* Ensure that all partition IDs are unique. */
+ for (unsigned int inner_idx = index + 1;
+ inner_idx < EL3_LP_DESCS_COUNT; inner_idx++) {
+ if (lp_desc->sp_id == lp_array[inner_idx].sp_id) {
+ ERROR("Duplicate SP ID Detected (0x%x)\n",
+ lp_desc->sp_id);
+ return -EINVAL;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
new file mode 100644
index 0000000..d62be91
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMC_H
+#define SPMC_H
+
+#include <stdint.h>
+
+#include <lib/psci/psci.h>
+#include <lib/spinlock.h>
+#include <services/el3_spmc_logical_sp.h>
+#include "spm_common.h"
+
+/*
+ * Ranges of FF-A IDs for Normal world and Secure world components. The
+ * convention matches that used by other SPMCs i.e. Hafnium and OP-TEE.
+ */
+#define FFA_NWD_ID_BASE 0x0
+#define FFA_NWD_ID_LIMIT 0x7FFF
+#define FFA_SWD_ID_BASE 0x8000
+#define FFA_SWD_ID_LIMIT SPMD_DIRECT_MSG_ENDPOINT_ID - 1
+#define FFA_SWD_ID_MASK 0x8000
+
+/* ID 0 is reserved for the normal world entity, (Hypervisor or OS Kernel). */
+#define FFA_NWD_ID U(0)
+/* First ID is reserved for the SPMC */
+#define FFA_SPMC_ID U(FFA_SWD_ID_BASE)
+/* SP IDs are allocated after the SPMC ID */
+#define FFA_SP_ID_BASE (FFA_SPMC_ID + 1)
+/* Align with Hafnium implementation */
+#define INV_SP_ID 0x7FFF
+
+/* FF-A Related helper macros. */
+#define FFA_ID_MASK U(0xFFFF)
+#define FFA_PARTITION_ID_SHIFT U(16)
+#define FFA_FEATURES_BIT31_MASK U(0x1u << 31)
+#define FFA_FEATURES_RET_REQ_NS_BIT U(0x1 << 1)
+
+#define FFA_RUN_EP_ID(ep_vcpu_ids) \
+ ((ep_vcpu_ids >> FFA_PARTITION_ID_SHIFT) & FFA_ID_MASK)
+#define FFA_RUN_VCPU_ID(ep_vcpu_ids) \
+ (ep_vcpu_ids & FFA_ID_MASK)
+
+#define FFA_PAGE_SIZE (4096)
+#define FFA_RXTX_PAGE_COUNT_MASK 0x1F
+
+/* Ensure that the page size used by TF-A is 4k aligned. */
+CASSERT((PAGE_SIZE % FFA_PAGE_SIZE) == 0, assert_aligned_page_size);
+
+/*
+ * Defines to allow an SP to subscribe for power management messages
+ */
+#define FFA_PM_MSG_SUB_CPU_OFF U(1 << 0)
+#define FFA_PM_MSG_SUB_CPU_SUSPEND U(1 << 1)
+#define FFA_PM_MSG_SUB_CPU_SUSPEND_RESUME U(1 << 2)
+
+/*
+ * Runtime states of an execution context as per the FF-A v1.1 specification.
+ */
+enum sp_runtime_states {
+ RT_STATE_WAITING,
+ RT_STATE_RUNNING,
+ RT_STATE_PREEMPTED,
+ RT_STATE_BLOCKED
+};
+
+/*
+ * Runtime model of an execution context as per the FF-A v1.1 specification. Its
+ * value is valid only if the execution context is not in the waiting state.
+ */
+enum sp_runtime_model {
+ RT_MODEL_DIR_REQ,
+ RT_MODEL_RUN,
+ RT_MODEL_INIT,
+ RT_MODEL_INTR
+};
+
+enum sp_runtime_el {
+ EL1 = 0,
+ S_EL0,
+ S_EL1
+};
+
+enum sp_execution_state {
+ SP_STATE_AARCH64 = 0,
+ SP_STATE_AARCH32
+};
+
+enum mailbox_state {
+ /* There is no message in the mailbox. */
+ MAILBOX_STATE_EMPTY,
+
+ /* There is a message that has been populated in the mailbox. */
+ MAILBOX_STATE_FULL,
+};
+
+struct mailbox {
+ enum mailbox_state state;
+
+ /* RX/TX Buffers. */
+ void *rx_buffer;
+ const void *tx_buffer;
+
+ /* Size of RX/TX Buffer. */
+ uint32_t rxtx_page_count;
+
+ /* Lock access to mailbox. */
+ spinlock_t lock;
+};
+
+/*
+ * Execution context members for an SP. This is a bit like struct
+ * vcpu in a hypervisor.
+ */
+struct sp_exec_ctx {
+ /*
+ * Store the stack address to restore C runtime context from after
+ * returning from a synchronous entry into the SP.
+ */
+ uint64_t c_rt_ctx;
+
+ /* Space to maintain the architectural state of an SP. */
+ cpu_context_t cpu_ctx;
+
+ /* Track the current runtime state of the SP. */
+ enum sp_runtime_states rt_state;
+
+ /* Track the current runtime model of the SP. */
+ enum sp_runtime_model rt_model;
+};
+
+/*
+ * Structure to describe the cumulative properties of an SP.
+ */
+struct secure_partition_desc {
+ /*
+ * Execution contexts allocated to this endpoint. Ideally,
+ * we need as many contexts as there are physical cpus only
+ * for a S-EL1 SP which is MP-pinned.
+ */
+ struct sp_exec_ctx ec[PLATFORM_CORE_COUNT];
+
+ /* ID of the Secure Partition. */
+ uint16_t sp_id;
+
+ /* Runtime EL. */
+ enum sp_runtime_el runtime_el;
+
+ /* Partition UUID. */
+ uint32_t uuid[4];
+
+ /* Partition Properties. */
+ uint32_t properties;
+
+ /* Supported FF-A Version. */
+ uint32_t ffa_version;
+
+ /* Execution State. */
+ enum sp_execution_state execution_state;
+
+ /* Mailbox tracking. */
+ struct mailbox mailbox;
+
+ /* Secondary entrypoint. Only valid for a S-EL1 SP. */
+ uintptr_t secondary_ep;
+
+ /*
+ * Store whether the SP has subscribed to any power management messages.
+ */
+ uint16_t pwr_mgmt_msgs;
+
+ /*
+ * Store whether the SP has requested the use of the NS bit for memory
+ * management transactions if it is using FF-A v1.0.
+ */
+ bool ns_bit_requested;
+};
+
+/*
+ * This define identifies the only SP that will be initialised and participate
+ * in FF-A communication. The implementation leaves the door open for more SPs
+ * to be managed in future but for now it is reasonable to assume that either a
+ * single S-EL0 or a single S-EL1 SP will be supported. This define will be used
+ * to identify which SP descriptor to initialise and manage during SP runtime.
+ */
+#define ACTIVE_SP_DESC_INDEX 0
+
+/*
+ * Structure to describe the cumulative properties of the Hypervisor and
+ * NS-Endpoints.
+ */
+struct ns_endpoint_desc {
+ /*
+ * ID of the NS-Endpoint or Hypervisor.
+ */
+ uint16_t ns_ep_id;
+
+ /*
+ * Mailbox tracking.
+ */
+ struct mailbox mailbox;
+
+ /*
+ * Supported FF-A Version
+ */
+ uint32_t ffa_version;
+};
+
+/**
+ * Holds information returned for each partition by the FFA_PARTITION_INFO_GET
+ * interface.
+ */
+struct ffa_partition_info_v1_0 {
+ uint16_t ep_id;
+ uint16_t execution_ctx_count;
+ uint32_t properties;
+};
+
+/* Extended structure for v1.1. */
+struct ffa_partition_info_v1_1 {
+ uint16_t ep_id;
+ uint16_t execution_ctx_count;
+ uint32_t properties;
+ uint32_t uuid[4];
+};
+
+/* Reference to power management hooks */
+extern const spd_pm_ops_t spmc_pm;
+
+/* Setup Function for different SP types. */
+void spmc_sp_common_setup(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info,
+ int32_t boot_info_reg);
+void spmc_el1_sp_setup(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info);
+void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info);
+
+/*
+ * Helper function to perform a synchronous entry into a SP.
+ */
+uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec);
+
+/*
+ * Helper function to obtain the descriptor of the current SP on a physical cpu.
+ */
+struct secure_partition_desc *spmc_get_current_sp_ctx(void);
+
+/*
+ * Helper function to obtain the execution context of an SP on a
+ * physical cpu.
+ */
+struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp);
+
+/*
+ * Helper function to obtain the index of the execution context of an SP on a
+ * physical cpu.
+ */
+unsigned int get_ec_index(struct secure_partition_desc *sp);
+
+uint64_t spmc_ffa_error_return(void *handle, int error_code);
+
+/*
+ * Ensure a partition ID does not clash and follows the secure world convention.
+ */
+bool is_ffa_secure_id_valid(uint16_t partition_id);
+
+/*
+ * Helper function to obtain the array storing the EL3
+ * Logical Partition descriptors.
+ */
+struct el3_lp_desc *get_el3_lp_array(void);
+
+/*
+ * Helper function to obtain the RX/TX buffer pair descriptor of the Hypervisor
+ * or OS kernel in the normal world or the last SP that was run.
+ */
+struct mailbox *spmc_get_mbox_desc(bool secure_origin);
+
+/*
+ * Helper function to obtain the context of an SP with a given partition ID.
+ */
+struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id);
+
+/*
+ * Add helper function to obtain the FF-A version of the calling
+ * partition.
+ */
+uint32_t get_partition_ffa_version(bool secure_origin);
+
+
+#endif /* SPMC_H */
diff --git a/services/std_svc/spm/el3_spmc/spmc.mk b/services/std_svc/spm/el3_spmc/spmc.mk
new file mode 100644
index 0000000..c674e71
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc.mk
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch64)
+ $(error "Error: SPMC is only supported on aarch64.")
+endif
+
+SPMC_SOURCES := $(addprefix services/std_svc/spm/el3_spmc/, \
+ spmc_main.c \
+ spmc_setup.c \
+ logical_sp.c \
+ spmc_pm.c \
+ spmc_shared_mem.c)
+
+# Specify platform specific logical partition implementation.
+SPMC_LP_SOURCES := $(addprefix ${PLAT_DIR}/, \
+ ${PLAT}_el3_spmc_logical_sp.c)
+
+
+SPMC_SOURCES += $(SPMC_LP_SOURCES)
+
+# Let the top-level Makefile know that we intend to include a BL32 image
+NEED_BL32 := yes
+
+ifndef BL32
+# The SPMC is paired with a Test Secure Payload source and we intend to
+# build the Test Secure Payload if no other image has been provided
+# for BL32.
+#
+# In cases where an associated Secure Payload lies outside this build
+# system/source tree, the dispatcher Makefile can either invoke an external
+# build command or assume it is pre-built.
+
+BL32_ROOT := bl32/tsp
+
+# Conditionally include SP's Makefile. The assumption is that the TSP's build
+# system is compatible with that of Trusted Firmware, and it'll add and populate
+# necessary build targets and variables.
+
+include ${BL32_ROOT}/tsp.mk
+endif
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
new file mode 100644
index 0000000..9b8621a
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -0,0 +1,1995 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <bl31/ehf.h>
+#include <bl31/interrupt_mgmt.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <common/runtime_svc.h>
+#include <common/uuid.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/smccc.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <libfdt.h>
+#include <plat/common/platform.h>
+#include <services/el3_spmc_logical_sp.h>
+#include <services/ffa_svc.h>
+#include <services/spmc_svc.h>
+#include <services/spmd_svc.h>
+#include "spmc.h"
+#include "spmc_shared_mem.h"
+
+#include <platform_def.h>
+
+/* Declare the maximum number of SPs and El3 LPs. */
+#define MAX_SP_LP_PARTITIONS SECURE_PARTITION_COUNT + MAX_EL3_LP_DESCS_COUNT
+
+/*
+ * Allocate a secure partition descriptor to describe each SP in the system that
+ * does not reside at EL3.
+ */
+static struct secure_partition_desc sp_desc[SECURE_PARTITION_COUNT];
+
+/*
+ * Allocate an NS endpoint descriptor to describe each VM and the Hypervisor in
+ * the system that interacts with a SP. It is used to track the Hypervisor
+ * buffer pair, version and ID for now. It could be extended to track VM
+ * properties when the SPMC supports indirect messaging.
+ */
+static struct ns_endpoint_desc ns_ep_desc[NS_PARTITION_COUNT];
+
+static uint64_t spmc_sp_interrupt_handler(uint32_t id,
+ uint32_t flags,
+ void *handle,
+ void *cookie);
+
+/*
+ * Helper function to obtain the array storing the EL3
+ * Logical Partition descriptors.
+ */
+struct el3_lp_desc *get_el3_lp_array(void)
+{
+ return (struct el3_lp_desc *) EL3_LP_DESCS_START;
+}
+
+/*
+ * Helper function to obtain the descriptor of the last SP to whom control was
+ * handed to on this physical cpu. Currently, we assume there is only one SP.
+ * TODO: Expand to track multiple partitions when required.
+ */
+struct secure_partition_desc *spmc_get_current_sp_ctx(void)
+{
+ return &(sp_desc[ACTIVE_SP_DESC_INDEX]);
+}
+
+/*
+ * Helper function to obtain the execution context of an SP on the
+ * current physical cpu.
+ */
+struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp)
+{
+ return &(sp->ec[get_ec_index(sp)]);
+}
+
+/* Helper function to get pointer to SP context from its ID. */
+struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id)
+{
+ /* Check for Secure World Partitions. */
+ for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) {
+ if (sp_desc[i].sp_id == id) {
+ return &(sp_desc[i]);
+ }
+ }
+ return NULL;
+}
+
+/*
+ * Helper function to obtain the descriptor of the Hypervisor or OS kernel.
+ * We assume that the first descriptor is reserved for this entity.
+ */
+struct ns_endpoint_desc *spmc_get_hyp_ctx(void)
+{
+ return &(ns_ep_desc[0]);
+}
+
+/*
+ * Helper function to obtain the RX/TX buffer pair descriptor of the Hypervisor
+ * or OS kernel in the normal world or the last SP that was run.
+ */
+struct mailbox *spmc_get_mbox_desc(bool secure_origin)
+{
+ /* Obtain the RX/TX buffer pair descriptor. */
+ if (secure_origin) {
+ return &(spmc_get_current_sp_ctx()->mailbox);
+ } else {
+ return &(spmc_get_hyp_ctx()->mailbox);
+ }
+}
+
+/******************************************************************************
+ * This function returns to the place where spmc_sp_synchronous_entry() was
+ * called originally.
+ ******************************************************************************/
+__dead2 void spmc_sp_synchronous_exit(struct sp_exec_ctx *ec, uint64_t rc)
+{
+ /*
+ * The SPM must have initiated the original request through a
+ * synchronous entry into the secure partition. Jump back to the
+ * original C runtime context with the value of rc in x0;
+ */
+ spm_secure_partition_exit(ec->c_rt_ctx, rc);
+
+ panic();
+}
+
+/*******************************************************************************
+ * Return FFA_ERROR with specified error code.
+ ******************************************************************************/
+uint64_t spmc_ffa_error_return(void *handle, int error_code)
+{
+ SMC_RET8(handle, FFA_ERROR,
+ FFA_TARGET_INFO_MBZ, error_code,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ);
+}
+
+/******************************************************************************
+ * Helper function to validate a secure partition ID to ensure it does not
+ * conflict with any other FF-A component and follows the convention to
+ * indicate it resides within the secure world.
+ ******************************************************************************/
+bool is_ffa_secure_id_valid(uint16_t partition_id)
+{
+ struct el3_lp_desc *el3_lp_descs = get_el3_lp_array();
+
+ /* Ensure the ID is not the invalid partition ID. */
+ if (partition_id == INV_SP_ID) {
+ return false;
+ }
+
+ /* Ensure the ID is not the SPMD ID. */
+ if (partition_id == SPMD_DIRECT_MSG_ENDPOINT_ID) {
+ return false;
+ }
+
+ /*
+ * Ensure the ID follows the convention to indicate it resides
+ * in the secure world.
+ */
+ if (!ffa_is_secure_world_id(partition_id)) {
+ return false;
+ }
+
+ /* Ensure we don't conflict with the SPMC partition ID. */
+ if (partition_id == FFA_SPMC_ID) {
+ return false;
+ }
+
+ /* Ensure we do not already have an SP context with this ID. */
+ if (spmc_get_sp_ctx(partition_id)) {
+ return false;
+ }
+
+ /* Ensure we don't clash with any Logical SP's. */
+ for (unsigned int i = 0U; i < EL3_LP_DESCS_COUNT; i++) {
+ if (el3_lp_descs[i].sp_id == partition_id) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*******************************************************************************
+ * This function either forwards the request to the other world or returns
+ * with an ERET depending on the source of the call.
+ * We can assume that the destination is for an entity at a lower exception
+ * level as any messages destined for a logical SP resident in EL3 will have
+ * already been taken care of by the SPMC before entering this function.
+ ******************************************************************************/
+static uint64_t spmc_smc_return(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *handle,
+ void *cookie,
+ uint64_t flags,
+ uint16_t dst_id)
+{
+ /* If the destination is in the normal world always go via the SPMD. */
+ if (ffa_is_normal_world_id(dst_id)) {
+ return spmd_smc_handler(smc_fid, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+ /*
+ * If the caller is secure and we want to return to the secure world,
+ * ERET directly.
+ */
+ else if (secure_origin && ffa_is_secure_world_id(dst_id)) {
+ SMC_RET5(handle, smc_fid, x1, x2, x3, x4);
+ }
+ /* If we originated in the normal world then switch contexts. */
+ else if (!secure_origin && ffa_is_secure_world_id(dst_id)) {
+ return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2,
+ x3, x4, handle);
+ } else {
+ /* Unknown State. */
+ panic();
+ }
+
+ /* Shouldn't be Reached. */
+ return 0;
+}
+
+/*******************************************************************************
+ * FF-A ABI Handlers.
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Helper function to validate arg2 as part of a direct message.
+ ******************************************************************************/
+static inline bool direct_msg_validate_arg2(uint64_t x2)
+{
+ /* Check message type. */
+ if (x2 & FFA_FWK_MSG_BIT) {
+ /* We have a framework message, ensure it is a known message. */
+ if (x2 & ~(FFA_FWK_MSG_MASK | FFA_FWK_MSG_BIT)) {
+ VERBOSE("Invalid message format 0x%lx.\n", x2);
+ return false;
+ }
+ } else {
+ /* We have a partition messages, ensure x2 is not set. */
+ if (x2 != (uint64_t) 0) {
+ VERBOSE("Arg2 MBZ for partition messages. (0x%lx).\n",
+ x2);
+ return false;
+ }
+ }
+ return true;
+}
+
+/*******************************************************************************
+ * Handle direct request messages and route to the appropriate destination.
+ ******************************************************************************/
+static uint64_t direct_req_smc_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ uint16_t dst_id = ffa_endpoint_destination(x1);
+ struct el3_lp_desc *el3_lp_descs;
+ struct secure_partition_desc *sp;
+ unsigned int idx;
+
+ /* Check if arg2 has been populated correctly based on message type. */
+ if (!direct_msg_validate_arg2(x2)) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ el3_lp_descs = get_el3_lp_array();
+
+ /* Check if the request is destined for a Logical Partition. */
+ for (unsigned int i = 0U; i < MAX_EL3_LP_DESCS_COUNT; i++) {
+ if (el3_lp_descs[i].sp_id == dst_id) {
+ return el3_lp_descs[i].direct_req(
+ smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+ }
+
+ /*
+ * If the request was not targeted to a LSP and from the secure world
+ * then it is invalid since a SP cannot call into the Normal world and
+ * there is no other SP to call into. If there are other SPs in future
+ * then the partition runtime model would need to be validated as well.
+ */
+ if (secure_origin) {
+ VERBOSE("Direct request not supported to the Normal World.\n");
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Check if the SP ID is valid. */
+ sp = spmc_get_sp_ctx(dst_id);
+ if (sp == NULL) {
+ VERBOSE("Direct request to unknown partition ID (0x%x).\n",
+ dst_id);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /*
+ * Check that the target execution context is in a waiting state before
+ * forwarding the direct request to it.
+ */
+ idx = get_ec_index(sp);
+ if (sp->ec[idx].rt_state != RT_STATE_WAITING) {
+ VERBOSE("SP context on core%u is not waiting (%u).\n",
+ idx, sp->ec[idx].rt_model);
+ return spmc_ffa_error_return(handle, FFA_ERROR_BUSY);
+ }
+
+ /*
+ * Everything checks out so forward the request to the SP after updating
+ * its state and runtime model.
+ */
+ sp->ec[idx].rt_state = RT_STATE_RUNNING;
+ sp->ec[idx].rt_model = RT_MODEL_DIR_REQ;
+ return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+ handle, cookie, flags, dst_id);
+}
+
+/*******************************************************************************
+ * Handle direct response messages and route to the appropriate destination.
+ ******************************************************************************/
+static uint64_t direct_resp_smc_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ uint16_t dst_id = ffa_endpoint_destination(x1);
+ struct secure_partition_desc *sp;
+ unsigned int idx;
+
+ /* Check if arg2 has been populated correctly based on message type. */
+ if (!direct_msg_validate_arg2(x2)) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Check that the response did not originate from the Normal world. */
+ if (!secure_origin) {
+ VERBOSE("Direct Response not supported from Normal World.\n");
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /*
+ * Check that the response is either targeted to the Normal world or the
+ * SPMC e.g. a PM response.
+ */
+ if ((dst_id != FFA_SPMC_ID) && ffa_is_secure_world_id(dst_id)) {
+ VERBOSE("Direct response to invalid partition ID (0x%x).\n",
+ dst_id);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Obtain the SP descriptor and update its runtime state. */
+ sp = spmc_get_sp_ctx(ffa_endpoint_source(x1));
+ if (sp == NULL) {
+ VERBOSE("Direct response to unknown partition ID (0x%x).\n",
+ dst_id);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Sanity check state is being tracked correctly in the SPMC. */
+ idx = get_ec_index(sp);
+ assert(sp->ec[idx].rt_state == RT_STATE_RUNNING);
+
+ /* Ensure SP execution context was in the right runtime model. */
+ if (sp->ec[idx].rt_model != RT_MODEL_DIR_REQ) {
+ VERBOSE("SP context on core%u not handling direct req (%u).\n",
+ idx, sp->ec[idx].rt_model);
+ return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+ }
+
+ /* Update the state of the SP execution context. */
+ sp->ec[idx].rt_state = RT_STATE_WAITING;
+
+ /*
+ * If the receiver is not the SPMC then forward the response to the
+ * Normal world.
+ */
+ if (dst_id == FFA_SPMC_ID) {
+ spmc_sp_synchronous_exit(&sp->ec[idx], x4);
+ /* Should not get here. */
+ panic();
+ }
+
+ return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+ handle, cookie, flags, dst_id);
+}
+
+/*******************************************************************************
+ * This function handles the FFA_MSG_WAIT SMC to allow an SP to relinquish its
+ * cycles.
+ ******************************************************************************/
+static uint64_t msg_wait_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ struct secure_partition_desc *sp;
+ unsigned int idx;
+
+ /*
+ * Check that the response did not originate from the Normal world as
+ * only the secure world can call this ABI.
+ */
+ if (!secure_origin) {
+ VERBOSE("Normal world cannot call FFA_MSG_WAIT.\n");
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+ }
+
+ /* Get the descriptor of the SP that invoked FFA_MSG_WAIT. */
+ sp = spmc_get_current_sp_ctx();
+ if (sp == NULL) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /*
+ * Get the execution context of the SP that invoked FFA_MSG_WAIT.
+ */
+ idx = get_ec_index(sp);
+
+ /* Ensure SP execution context was in the right runtime model. */
+ if (sp->ec[idx].rt_model == RT_MODEL_DIR_REQ) {
+ return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+ }
+
+ /* Sanity check the state is being tracked correctly in the SPMC. */
+ assert(sp->ec[idx].rt_state == RT_STATE_RUNNING);
+
+ /*
+ * Perform a synchronous exit if the partition was initialising. The
+ * state is updated after the exit.
+ */
+ if (sp->ec[idx].rt_model == RT_MODEL_INIT) {
+ spmc_sp_synchronous_exit(&sp->ec[idx], x4);
+ /* Should not get here */
+ panic();
+ }
+
+ /* Update the state of the SP execution context. */
+ sp->ec[idx].rt_state = RT_STATE_WAITING;
+
+ /* Resume normal world if a secure interrupt was handled. */
+ if (sp->ec[idx].rt_model == RT_MODEL_INTR) {
+ /* FFA_MSG_WAIT can only be called from the secure world. */
+ unsigned int secure_state_in = SECURE;
+ unsigned int secure_state_out = NON_SECURE;
+
+ cm_el1_sysregs_context_save(secure_state_in);
+ cm_el1_sysregs_context_restore(secure_state_out);
+ cm_set_next_eret_context(secure_state_out);
+ SMC_RET0(cm_get_context(secure_state_out));
+ }
+
+ /* Forward the response to the Normal world. */
+ return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
+ handle, cookie, flags, FFA_NWD_ID);
+}
+
+static uint64_t ffa_error_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ struct secure_partition_desc *sp;
+ unsigned int idx;
+
+ /* Check that the response did not originate from the Normal world. */
+ if (!secure_origin) {
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+ }
+
+ /* Get the descriptor of the SP that invoked FFA_ERROR. */
+ sp = spmc_get_current_sp_ctx();
+ if (sp == NULL) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Get the execution context of the SP that invoked FFA_ERROR. */
+ idx = get_ec_index(sp);
+
+ /*
+ * We only expect FFA_ERROR to be received during SP initialisation
+ * otherwise this is an invalid call.
+ */
+ if (sp->ec[idx].rt_model == RT_MODEL_INIT) {
+ ERROR("SP 0x%x failed to initialize.\n", sp->sp_id);
+ spmc_sp_synchronous_exit(&sp->ec[idx], x2);
+ /* Should not get here. */
+ panic();
+ }
+
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+}
+
+static uint64_t ffa_version_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ uint32_t requested_version = x1 & FFA_VERSION_MASK;
+
+ if (requested_version & FFA_VERSION_BIT31_MASK) {
+ /* Invalid encoding, return an error. */
+ SMC_RET1(handle, FFA_ERROR_NOT_SUPPORTED);
+ /* Execution stops here. */
+ }
+
+ /* Determine the caller to store the requested version. */
+ if (secure_origin) {
+ /*
+ * Ensure that the SP is reporting the same version as
+ * specified in its manifest. If these do not match there is
+ * something wrong with the SP.
+ * TODO: Should we abort the SP? For now assert this is not
+ * case.
+ */
+ assert(requested_version ==
+ spmc_get_current_sp_ctx()->ffa_version);
+ } else {
+ /*
+ * If this is called by the normal world, record this
+ * information in its descriptor.
+ */
+ spmc_get_hyp_ctx()->ffa_version = requested_version;
+ }
+
+ SMC_RET1(handle, MAKE_FFA_VERSION(FFA_VERSION_MAJOR,
+ FFA_VERSION_MINOR));
+}
+
+/*******************************************************************************
+ * Helper function to obtain the FF-A version of the calling partition.
+ ******************************************************************************/
+uint32_t get_partition_ffa_version(bool secure_origin)
+{
+ if (secure_origin) {
+ return spmc_get_current_sp_ctx()->ffa_version;
+ } else {
+ return spmc_get_hyp_ctx()->ffa_version;
+ }
+}
+
+static uint64_t rxtx_map_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ int ret;
+ uint32_t error_code;
+ uint32_t mem_atts = secure_origin ? MT_SECURE : MT_NS;
+ struct mailbox *mbox;
+ uintptr_t tx_address = x1;
+ uintptr_t rx_address = x2;
+ uint32_t page_count = x3 & FFA_RXTX_PAGE_COUNT_MASK; /* Bits [5:0] */
+ uint32_t buf_size = page_count * FFA_PAGE_SIZE;
+
+ /*
+ * The SPMC does not support mapping of VM RX/TX pairs to facilitate
+ * indirect messaging with SPs. Check if the Hypervisor has invoked this
+ * ABI on behalf of a VM and reject it if this is the case.
+ */
+ if (tx_address == 0 || rx_address == 0) {
+ WARN("Mapping RX/TX Buffers on behalf of VM not supported.\n");
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Ensure the specified buffers are not the same. */
+ if (tx_address == rx_address) {
+ WARN("TX Buffer must not be the same as RX Buffer.\n");
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Ensure the buffer size is not 0. */
+ if (buf_size == 0U) {
+ WARN("Buffer size must not be 0\n");
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /*
+ * Ensure the buffer size is a multiple of the translation granule size
+ * in TF-A.
+ */
+ if (buf_size % PAGE_SIZE != 0U) {
+ WARN("Buffer size must be aligned to translation granule.\n");
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Obtain the RX/TX buffer pair descriptor. */
+ mbox = spmc_get_mbox_desc(secure_origin);
+
+ spin_lock(&mbox->lock);
+
+ /* Check if buffers have already been mapped. */
+ if (mbox->rx_buffer != 0 || mbox->tx_buffer != 0) {
+ WARN("RX/TX Buffers already mapped (%p/%p)\n",
+ (void *) mbox->rx_buffer, (void *)mbox->tx_buffer);
+ error_code = FFA_ERROR_DENIED;
+ goto err;
+ }
+
+ /* memmap the TX buffer as read only. */
+ ret = mmap_add_dynamic_region(tx_address, /* PA */
+ tx_address, /* VA */
+ buf_size, /* size */
+ mem_atts | MT_RO_DATA); /* attrs */
+ if (ret != 0) {
+ /* Return the correct error code. */
+ error_code = (ret == -ENOMEM) ? FFA_ERROR_NO_MEMORY :
+ FFA_ERROR_INVALID_PARAMETER;
+ WARN("Unable to map TX buffer: %d\n", error_code);
+ goto err;
+ }
+
+ /* memmap the RX buffer as read write. */
+ ret = mmap_add_dynamic_region(rx_address, /* PA */
+ rx_address, /* VA */
+ buf_size, /* size */
+ mem_atts | MT_RW_DATA); /* attrs */
+
+ if (ret != 0) {
+ error_code = (ret == -ENOMEM) ? FFA_ERROR_NO_MEMORY :
+ FFA_ERROR_INVALID_PARAMETER;
+ WARN("Unable to map RX buffer: %d\n", error_code);
+ /* Unmap the TX buffer again. */
+ mmap_remove_dynamic_region(tx_address, buf_size);
+ goto err;
+ }
+
+ mbox->tx_buffer = (void *) tx_address;
+ mbox->rx_buffer = (void *) rx_address;
+ mbox->rxtx_page_count = page_count;
+ spin_unlock(&mbox->lock);
+
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+ /* Execution stops here. */
+err:
+ spin_unlock(&mbox->lock);
+ return spmc_ffa_error_return(handle, error_code);
+}
+
+static uint64_t rxtx_unmap_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
+ uint32_t buf_size = mbox->rxtx_page_count * FFA_PAGE_SIZE;
+
+ /*
+ * The SPMC does not support mapping of VM RX/TX pairs to facilitate
+ * indirect messaging with SPs. Check if the Hypervisor has invoked this
+ * ABI on behalf of a VM and reject it if this is the case.
+ */
+ if (x1 != 0UL) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ spin_lock(&mbox->lock);
+
+ /* Check if buffers are currently mapped. */
+ if (mbox->rx_buffer == 0 || mbox->tx_buffer == 0) {
+ spin_unlock(&mbox->lock);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Unmap RX Buffer */
+ if (mmap_remove_dynamic_region((uintptr_t) mbox->rx_buffer,
+ buf_size) != 0) {
+ WARN("Unable to unmap RX buffer!\n");
+ }
+
+ mbox->rx_buffer = 0;
+
+ /* Unmap TX Buffer */
+ if (mmap_remove_dynamic_region((uintptr_t) mbox->tx_buffer,
+ buf_size) != 0) {
+ WARN("Unable to unmap TX buffer!\n");
+ }
+
+ mbox->tx_buffer = 0;
+ mbox->rxtx_page_count = 0;
+
+ spin_unlock(&mbox->lock);
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+}
+
+/*
+ * Collate the partition information in a v1.1 partition information
+ * descriptor format, this will be converter later if required.
+ */
+static int partition_info_get_handler_v1_1(uint32_t *uuid,
+ struct ffa_partition_info_v1_1
+ *partitions,
+ uint32_t max_partitions,
+ uint32_t *partition_count)
+{
+ uint32_t index;
+ struct ffa_partition_info_v1_1 *desc;
+ bool null_uuid = is_null_uuid(uuid);
+ struct el3_lp_desc *el3_lp_descs = get_el3_lp_array();
+
+ /* Deal with Logical Partitions. */
+ for (index = 0U; index < EL3_LP_DESCS_COUNT; index++) {
+ if (null_uuid || uuid_match(uuid, el3_lp_descs[index].uuid)) {
+ /* Found a matching UUID, populate appropriately. */
+ if (*partition_count >= max_partitions) {
+ return FFA_ERROR_NO_MEMORY;
+ }
+
+ desc = &partitions[*partition_count];
+ desc->ep_id = el3_lp_descs[index].sp_id;
+ desc->execution_ctx_count = PLATFORM_CORE_COUNT;
+ desc->properties = el3_lp_descs[index].properties;
+ if (null_uuid) {
+ copy_uuid(desc->uuid, el3_lp_descs[index].uuid);
+ }
+ (*partition_count)++;
+ }
+ }
+
+ /* Deal with physical SP's. */
+ for (index = 0U; index < SECURE_PARTITION_COUNT; index++) {
+ if (null_uuid || uuid_match(uuid, sp_desc[index].uuid)) {
+ /* Found a matching UUID, populate appropriately. */
+ if (*partition_count >= max_partitions) {
+ return FFA_ERROR_NO_MEMORY;
+ }
+
+ desc = &partitions[*partition_count];
+ desc->ep_id = sp_desc[index].sp_id;
+ /*
+ * Execution context count must match No. cores for
+ * S-EL1 SPs.
+ */
+ desc->execution_ctx_count = PLATFORM_CORE_COUNT;
+ desc->properties = sp_desc[index].properties;
+ if (null_uuid) {
+ copy_uuid(desc->uuid, sp_desc[index].uuid);
+ }
+ (*partition_count)++;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Handle the case where that caller only wants the count of partitions
+ * matching a given UUID and does not want the corresponding descriptors
+ * populated.
+ */
+static uint32_t partition_info_get_handler_count_only(uint32_t *uuid)
+{
+ uint32_t index = 0;
+ uint32_t partition_count = 0;
+ bool null_uuid = is_null_uuid(uuid);
+ struct el3_lp_desc *el3_lp_descs = get_el3_lp_array();
+
+ /* Deal with Logical Partitions. */
+ for (index = 0U; index < EL3_LP_DESCS_COUNT; index++) {
+ if (null_uuid ||
+ uuid_match(uuid, el3_lp_descs[index].uuid)) {
+ (partition_count)++;
+ }
+ }
+
+ /* Deal with physical SP's. */
+ for (index = 0U; index < SECURE_PARTITION_COUNT; index++) {
+ if (null_uuid || uuid_match(uuid, sp_desc[index].uuid)) {
+ (partition_count)++;
+ }
+ }
+ return partition_count;
+}
+
+/*
+ * If the caller of the PARTITION_INFO_GET ABI was a v1.0 caller, populate
+ * the coresponding descriptor format from the v1.1 descriptor array.
+ */
+static uint64_t partition_info_populate_v1_0(struct ffa_partition_info_v1_1
+ *partitions,
+ struct mailbox *mbox,
+ int partition_count)
+{
+ uint32_t index;
+ uint32_t buf_size;
+ uint32_t descriptor_size;
+ struct ffa_partition_info_v1_0 *v1_0_partitions =
+ (struct ffa_partition_info_v1_0 *) mbox->rx_buffer;
+
+ buf_size = mbox->rxtx_page_count * FFA_PAGE_SIZE;
+ descriptor_size = partition_count *
+ sizeof(struct ffa_partition_info_v1_0);
+
+ if (descriptor_size > buf_size) {
+ return FFA_ERROR_NO_MEMORY;
+ }
+
+ for (index = 0U; index < partition_count; index++) {
+ v1_0_partitions[index].ep_id = partitions[index].ep_id;
+ v1_0_partitions[index].execution_ctx_count =
+ partitions[index].execution_ctx_count;
+ v1_0_partitions[index].properties =
+ partitions[index].properties;
+ }
+ return 0;
+}
+
+/*
+ * Main handler for FFA_PARTITION_INFO_GET which supports both FF-A v1.1 and
+ * v1.0 implementations.
+ */
+static uint64_t partition_info_get_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ int ret;
+ uint32_t partition_count = 0;
+ uint32_t size = 0;
+ uint32_t ffa_version = get_partition_ffa_version(secure_origin);
+ struct mailbox *mbox;
+ uint64_t info_get_flags;
+ bool count_only;
+ uint32_t uuid[4];
+
+ uuid[0] = x1;
+ uuid[1] = x2;
+ uuid[2] = x3;
+ uuid[3] = x4;
+
+ /* Determine if the Partition descriptors should be populated. */
+ info_get_flags = SMC_GET_GP(handle, CTX_GPREG_X5);
+ count_only = (info_get_flags & FFA_PARTITION_INFO_GET_COUNT_FLAG_MASK);
+
+ /* Handle the case where we don't need to populate the descriptors. */
+ if (count_only) {
+ partition_count = partition_info_get_handler_count_only(uuid);
+ if (partition_count == 0) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+ } else {
+ struct ffa_partition_info_v1_1 partitions[MAX_SP_LP_PARTITIONS];
+
+ /*
+ * Handle the case where the partition descriptors are required,
+ * check we have the buffers available and populate the
+ * appropriate structure version.
+ */
+
+ /* Obtain the v1.1 format of the descriptors. */
+ ret = partition_info_get_handler_v1_1(uuid, partitions,
+ MAX_SP_LP_PARTITIONS,
+ &partition_count);
+
+ /* Check if an error occurred during discovery. */
+ if (ret != 0) {
+ goto err;
+ }
+
+ /* If we didn't find any matches the UUID is unknown. */
+ if (partition_count == 0) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err;
+ }
+
+ /* Obtain the partition mailbox RX/TX buffer pair descriptor. */
+ mbox = spmc_get_mbox_desc(secure_origin);
+
+ /*
+ * If the caller has not bothered registering its RX/TX pair
+ * then return an error code.
+ */
+ spin_lock(&mbox->lock);
+ if (mbox->rx_buffer == NULL) {
+ ret = FFA_ERROR_BUSY;
+ goto err_unlock;
+ }
+
+ /* Ensure the RX buffer is currently free. */
+ if (mbox->state != MAILBOX_STATE_EMPTY) {
+ ret = FFA_ERROR_BUSY;
+ goto err_unlock;
+ }
+
+ /* Zero the RX buffer before populating. */
+ (void)memset(mbox->rx_buffer, 0,
+ mbox->rxtx_page_count * FFA_PAGE_SIZE);
+
+ /*
+ * Depending on the FF-A version of the requesting partition
+ * we may need to convert to a v1.0 format otherwise we can copy
+ * directly.
+ */
+ if (ffa_version == MAKE_FFA_VERSION(U(1), U(0))) {
+ ret = partition_info_populate_v1_0(partitions,
+ mbox,
+ partition_count);
+ if (ret != 0) {
+ goto err_unlock;
+ }
+ } else {
+ uint32_t buf_size = mbox->rxtx_page_count *
+ FFA_PAGE_SIZE;
+
+ /* Ensure the descriptor will fit in the buffer. */
+ size = sizeof(struct ffa_partition_info_v1_1);
+ if (partition_count * size > buf_size) {
+ ret = FFA_ERROR_NO_MEMORY;
+ goto err_unlock;
+ }
+ memcpy(mbox->rx_buffer, partitions,
+ partition_count * size);
+ }
+
+ mbox->state = MAILBOX_STATE_FULL;
+ spin_unlock(&mbox->lock);
+ }
+ SMC_RET4(handle, FFA_SUCCESS_SMC32, 0, partition_count, size);
+
+err_unlock:
+ spin_unlock(&mbox->lock);
+err:
+ return spmc_ffa_error_return(handle, ret);
+}
+
+static uint64_t ffa_feature_success(void *handle, uint32_t arg2)
+{
+ SMC_RET3(handle, FFA_SUCCESS_SMC32, 0, arg2);
+}
+
+static uint64_t ffa_features_retrieve_request(bool secure_origin,
+ uint32_t input_properties,
+ void *handle)
+{
+ /*
+ * If we're called by the normal world we don't support any
+ * additional features.
+ */
+ if (!secure_origin) {
+ if ((input_properties & FFA_FEATURES_RET_REQ_NS_BIT) != 0U) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_NOT_SUPPORTED);
+ }
+
+ } else {
+ struct secure_partition_desc *sp = spmc_get_current_sp_ctx();
+ /*
+ * If v1.1 the NS bit must be set otherwise it is an invalid
+ * call. If v1.0 check and store whether the SP has requested
+ * the use of the NS bit.
+ */
+ if (sp->ffa_version == MAKE_FFA_VERSION(1, 1)) {
+ if ((input_properties &
+ FFA_FEATURES_RET_REQ_NS_BIT) == 0U) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_NOT_SUPPORTED);
+ }
+ return ffa_feature_success(handle,
+ FFA_FEATURES_RET_REQ_NS_BIT);
+ } else {
+ sp->ns_bit_requested = (input_properties &
+ FFA_FEATURES_RET_REQ_NS_BIT) !=
+ 0U;
+ }
+ if (sp->ns_bit_requested) {
+ return ffa_feature_success(handle,
+ FFA_FEATURES_RET_REQ_NS_BIT);
+ }
+ }
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+}
+
+static uint64_t ffa_features_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ uint32_t function_id = (uint32_t) x1;
+ uint32_t input_properties = (uint32_t) x2;
+
+ /* Check if a Feature ID was requested. */
+ if ((function_id & FFA_FEATURES_BIT31_MASK) == 0U) {
+ /* We currently don't support any additional features. */
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+ }
+
+ /*
+ * Handle the cases where we have separate handlers due to additional
+ * properties.
+ */
+ switch (function_id) {
+ case FFA_MEM_RETRIEVE_REQ_SMC32:
+ case FFA_MEM_RETRIEVE_REQ_SMC64:
+ return ffa_features_retrieve_request(secure_origin,
+ input_properties,
+ handle);
+ }
+
+ /*
+ * We don't currently support additional input properties for these
+ * other ABIs therefore ensure this value is set to 0.
+ */
+ if (input_properties != 0U) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_NOT_SUPPORTED);
+ }
+
+ /* Report if any other FF-A ABI is supported. */
+ switch (function_id) {
+ /* Supported features from both worlds. */
+ case FFA_ERROR:
+ case FFA_SUCCESS_SMC32:
+ case FFA_INTERRUPT:
+ case FFA_SPM_ID_GET:
+ case FFA_ID_GET:
+ case FFA_FEATURES:
+ case FFA_VERSION:
+ case FFA_RX_RELEASE:
+ case FFA_MSG_SEND_DIRECT_REQ_SMC32:
+ case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+ case FFA_PARTITION_INFO_GET:
+ case FFA_RXTX_MAP_SMC32:
+ case FFA_RXTX_MAP_SMC64:
+ case FFA_RXTX_UNMAP:
+ case FFA_MEM_FRAG_TX:
+ case FFA_MSG_RUN:
+
+ /*
+ * We are relying on the fact that the other registers
+ * will be set to 0 as these values align with the
+ * currently implemented features of the SPMC. If this
+ * changes this function must be extended to handle
+ * reporting the additional functionality.
+ */
+
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+ /* Execution stops here. */
+
+ /* Supported ABIs only from the secure world. */
+ case FFA_SECONDARY_EP_REGISTER_SMC64:
+ case FFA_MSG_SEND_DIRECT_RESP_SMC32:
+ case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+ case FFA_MEM_RELINQUISH:
+ case FFA_MSG_WAIT:
+
+ if (!secure_origin) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_NOT_SUPPORTED);
+ }
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+ /* Execution stops here. */
+
+ /* Supported features only from the normal world. */
+ case FFA_MEM_SHARE_SMC32:
+ case FFA_MEM_SHARE_SMC64:
+ case FFA_MEM_LEND_SMC32:
+ case FFA_MEM_LEND_SMC64:
+ case FFA_MEM_RECLAIM:
+ case FFA_MEM_FRAG_RX:
+
+ if (secure_origin) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_NOT_SUPPORTED);
+ }
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+ /* Execution stops here. */
+
+ default:
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_NOT_SUPPORTED);
+ }
+}
+
+static uint64_t ffa_id_get_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ if (secure_origin) {
+ SMC_RET3(handle, FFA_SUCCESS_SMC32, 0x0,
+ spmc_get_current_sp_ctx()->sp_id);
+ } else {
+ SMC_RET3(handle, FFA_SUCCESS_SMC32, 0x0,
+ spmc_get_hyp_ctx()->ns_ep_id);
+ }
+}
+
+/*
+ * Enable an SP to query the ID assigned to the SPMC.
+ */
+static uint64_t ffa_spm_id_get_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ assert(x1 == 0UL);
+ assert(x2 == 0UL);
+ assert(x3 == 0UL);
+ assert(x4 == 0UL);
+ assert(SMC_GET_GP(handle, CTX_GPREG_X5) == 0UL);
+ assert(SMC_GET_GP(handle, CTX_GPREG_X6) == 0UL);
+ assert(SMC_GET_GP(handle, CTX_GPREG_X7) == 0UL);
+
+ SMC_RET3(handle, FFA_SUCCESS_SMC32, 0x0, FFA_SPMC_ID);
+}
+
+static uint64_t ffa_run_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ struct secure_partition_desc *sp;
+ uint16_t target_id = FFA_RUN_EP_ID(x1);
+ uint16_t vcpu_id = FFA_RUN_VCPU_ID(x1);
+ unsigned int idx;
+ unsigned int *rt_state;
+ unsigned int *rt_model;
+
+ /* Can only be called from the normal world. */
+ if (secure_origin) {
+ ERROR("FFA_RUN can only be called from NWd.\n");
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Cannot run a Normal world partition. */
+ if (ffa_is_normal_world_id(target_id)) {
+ ERROR("Cannot run a NWd partition (0x%x).\n", target_id);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Check that the target SP exists. */
+ sp = spmc_get_sp_ctx(target_id);
+ ERROR("Unknown partition ID (0x%x).\n", target_id);
+ if (sp == NULL) {
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ idx = get_ec_index(sp);
+ if (idx != vcpu_id) {
+ ERROR("Cannot run vcpu %d != %d.\n", idx, vcpu_id);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+ rt_state = &((sp->ec[idx]).rt_state);
+ rt_model = &((sp->ec[idx]).rt_model);
+ if (*rt_state == RT_STATE_RUNNING) {
+ ERROR("Partition (0x%x) is already running.\n", target_id);
+ return spmc_ffa_error_return(handle, FFA_ERROR_BUSY);
+ }
+
+ /*
+ * Sanity check that if the execution context was not waiting then it
+ * was either in the direct request or the run partition runtime model.
+ */
+ if (*rt_state == RT_STATE_PREEMPTED || *rt_state == RT_STATE_BLOCKED) {
+ assert(*rt_model == RT_MODEL_RUN ||
+ *rt_model == RT_MODEL_DIR_REQ);
+ }
+
+ /*
+ * If the context was waiting then update the partition runtime model.
+ */
+ if (*rt_state == RT_STATE_WAITING) {
+ *rt_model = RT_MODEL_RUN;
+ }
+
+ /*
+ * Forward the request to the correct SP vCPU after updating
+ * its state.
+ */
+ *rt_state = RT_STATE_RUNNING;
+
+ return spmc_smc_return(smc_fid, secure_origin, x1, 0, 0, 0,
+ handle, cookie, flags, target_id);
+}
+
+static uint64_t rx_release_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
+
+ spin_lock(&mbox->lock);
+
+ if (mbox->state != MAILBOX_STATE_FULL) {
+ spin_unlock(&mbox->lock);
+ return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+ }
+
+ mbox->state = MAILBOX_STATE_EMPTY;
+ spin_unlock(&mbox->lock);
+
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+}
+
+/*
+ * Perform initial validation on the provided secondary entry point.
+ * For now ensure it does not lie within the BL31 Image or the SP's
+ * RX/TX buffers as these are mapped within EL3.
+ * TODO: perform validation for additional invalid memory regions.
+ */
+static int validate_secondary_ep(uintptr_t ep, struct secure_partition_desc *sp)
+{
+ struct mailbox *mb;
+ uintptr_t buffer_size;
+ uintptr_t sp_rx_buffer;
+ uintptr_t sp_tx_buffer;
+ uintptr_t sp_rx_buffer_limit;
+ uintptr_t sp_tx_buffer_limit;
+
+ mb = &sp->mailbox;
+ buffer_size = (uintptr_t) (mb->rxtx_page_count * FFA_PAGE_SIZE);
+ sp_rx_buffer = (uintptr_t) mb->rx_buffer;
+ sp_tx_buffer = (uintptr_t) mb->tx_buffer;
+ sp_rx_buffer_limit = sp_rx_buffer + buffer_size;
+ sp_tx_buffer_limit = sp_tx_buffer + buffer_size;
+
+ /*
+ * Check if the entry point lies within BL31, or the
+ * SP's RX or TX buffer.
+ */
+ if ((ep >= BL31_BASE && ep < BL31_LIMIT) ||
+ (ep >= sp_rx_buffer && ep < sp_rx_buffer_limit) ||
+ (ep >= sp_tx_buffer && ep < sp_tx_buffer_limit)) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*******************************************************************************
+ * This function handles the FFA_SECONDARY_EP_REGISTER SMC to allow an SP to
+ * register an entry point for initialization during a secondary cold boot.
+ ******************************************************************************/
+static uint64_t ffa_sec_ep_register_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ struct secure_partition_desc *sp;
+ struct sp_exec_ctx *sp_ctx;
+
+ /* This request cannot originate from the Normal world. */
+ if (!secure_origin) {
+ WARN("%s: Can only be called from SWd.\n", __func__);
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+ }
+
+ /* Get the context of the current SP. */
+ sp = spmc_get_current_sp_ctx();
+ if (sp == NULL) {
+ WARN("%s: Cannot find SP context.\n", __func__);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /* Only an S-EL1 SP should be invoking this ABI. */
+ if (sp->runtime_el != S_EL1) {
+ WARN("%s: Can only be called for a S-EL1 SP.\n", __func__);
+ return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+ }
+
+ /* Ensure the SP is in its initialization state. */
+ sp_ctx = spmc_get_sp_ec(sp);
+ if (sp_ctx->rt_model != RT_MODEL_INIT) {
+ WARN("%s: Can only be called during SP initialization.\n",
+ __func__);
+ return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+ }
+
+ /* Perform initial validation of the secondary entry point. */
+ if (validate_secondary_ep(x1, sp)) {
+ WARN("%s: Invalid entry point provided (0x%lx).\n",
+ __func__, x1);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /*
+ * Update the secondary entrypoint in SP context.
+ * We don't need a lock here as during partition initialization there
+ * will only be a single core online.
+ */
+ sp->secondary_ep = x1;
+ VERBOSE("%s: 0x%lx\n", __func__, sp->secondary_ep);
+
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+}
+
+/*******************************************************************************
+ * This function will parse the Secure Partition Manifest. From manifest, it
+ * will fetch details for preparing Secure partition image context and secure
+ * partition image boot arguments if any.
+ ******************************************************************************/
+static int sp_manifest_parse(void *sp_manifest, int offset,
+ struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info,
+ int32_t *boot_info_reg)
+{
+ int32_t ret, node;
+ uint32_t config_32;
+
+ /*
+ * Look for the mandatory fields that are expected to be present in
+ * the SP manifests.
+ */
+ node = fdt_path_offset(sp_manifest, "/");
+ if (node < 0) {
+ ERROR("Did not find root node.\n");
+ return node;
+ }
+
+ ret = fdt_read_uint32_array(sp_manifest, node, "uuid",
+ ARRAY_SIZE(sp->uuid), sp->uuid);
+ if (ret != 0) {
+ ERROR("Missing Secure Partition UUID.\n");
+ return ret;
+ }
+
+ ret = fdt_read_uint32(sp_manifest, node, "exception-level", &config_32);
+ if (ret != 0) {
+ ERROR("Missing SP Exception Level information.\n");
+ return ret;
+ }
+
+ sp->runtime_el = config_32;
+
+ ret = fdt_read_uint32(sp_manifest, node, "ffa-version", &config_32);
+ if (ret != 0) {
+ ERROR("Missing Secure Partition FF-A Version.\n");
+ return ret;
+ }
+
+ sp->ffa_version = config_32;
+
+ ret = fdt_read_uint32(sp_manifest, node, "execution-state", &config_32);
+ if (ret != 0) {
+ ERROR("Missing Secure Partition Execution State.\n");
+ return ret;
+ }
+
+ sp->execution_state = config_32;
+
+ ret = fdt_read_uint32(sp_manifest, node,
+ "messaging-method", &config_32);
+ if (ret != 0) {
+ ERROR("Missing Secure Partition messaging method.\n");
+ return ret;
+ }
+
+ /* Validate this entry, we currently only support direct messaging. */
+ if ((config_32 & ~(FFA_PARTITION_DIRECT_REQ_RECV |
+ FFA_PARTITION_DIRECT_REQ_SEND)) != 0U) {
+ WARN("Invalid Secure Partition messaging method (0x%x)\n",
+ config_32);
+ return -EINVAL;
+ }
+
+ sp->properties = config_32;
+
+ ret = fdt_read_uint32(sp_manifest, node,
+ "execution-ctx-count", &config_32);
+
+ if (ret != 0) {
+ ERROR("Missing SP Execution Context Count.\n");
+ return ret;
+ }
+
+ /*
+ * Ensure this field is set correctly in the manifest however
+ * since this is currently a hardcoded value for S-EL1 partitions
+ * we don't need to save it here, just validate.
+ */
+ if (config_32 != PLATFORM_CORE_COUNT) {
+ ERROR("SP Execution Context Count (%u) must be %u.\n",
+ config_32, PLATFORM_CORE_COUNT);
+ return -EINVAL;
+ }
+
+ /*
+ * Look for the optional fields that are expected to be present in
+ * an SP manifest.
+ */
+ ret = fdt_read_uint32(sp_manifest, node, "id", &config_32);
+ if (ret != 0) {
+ WARN("Missing Secure Partition ID.\n");
+ } else {
+ if (!is_ffa_secure_id_valid(config_32)) {
+ ERROR("Invalid Secure Partition ID (0x%x).\n",
+ config_32);
+ return -EINVAL;
+ }
+ sp->sp_id = config_32;
+ }
+
+ ret = fdt_read_uint32(sp_manifest, node,
+ "power-management-messages", &config_32);
+ if (ret != 0) {
+ WARN("Missing Power Management Messages entry.\n");
+ } else {
+ /*
+ * Ensure only the currently supported power messages have
+ * been requested.
+ */
+ if (config_32 & ~(FFA_PM_MSG_SUB_CPU_OFF |
+ FFA_PM_MSG_SUB_CPU_SUSPEND |
+ FFA_PM_MSG_SUB_CPU_SUSPEND_RESUME)) {
+ ERROR("Requested unsupported PM messages (%x)\n",
+ config_32);
+ return -EINVAL;
+ }
+ sp->pwr_mgmt_msgs = config_32;
+ }
+
+ ret = fdt_read_uint32(sp_manifest, node,
+ "gp-register-num", &config_32);
+ if (ret != 0) {
+ WARN("Missing boot information register.\n");
+ } else {
+ /* Check if a register number between 0-3 is specified. */
+ if (config_32 < 4) {
+ *boot_info_reg = config_32;
+ } else {
+ WARN("Incorrect boot information register (%u).\n",
+ config_32);
+ }
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function gets the Secure Partition Manifest base and maps the manifest
+ * region.
+ * Currently only one Secure Partition manifest is considered which is used to
+ * prepare the context for the single Secure Partition.
+ ******************************************************************************/
+static int find_and_prepare_sp_context(void)
+{
+ void *sp_manifest;
+ uintptr_t manifest_base;
+ uintptr_t manifest_base_align;
+ entry_point_info_t *next_image_ep_info;
+ int32_t ret, boot_info_reg = -1;
+ struct secure_partition_desc *sp;
+
+ next_image_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
+ if (next_image_ep_info == NULL) {
+ WARN("No Secure Partition image provided by BL2.\n");
+ return -ENOENT;
+ }
+
+ sp_manifest = (void *)next_image_ep_info->args.arg0;
+ if (sp_manifest == NULL) {
+ WARN("Secure Partition manifest absent.\n");
+ return -ENOENT;
+ }
+
+ manifest_base = (uintptr_t)sp_manifest;
+ manifest_base_align = page_align(manifest_base, DOWN);
+
+ /*
+ * Map the secure partition manifest region in the EL3 translation
+ * regime.
+ * Map an area equal to (2 * PAGE_SIZE) for now. During manifest base
+ * alignment the region of 1 PAGE_SIZE from manifest align base may
+ * not completely accommodate the secure partition manifest region.
+ */
+ ret = mmap_add_dynamic_region((unsigned long long)manifest_base_align,
+ manifest_base_align,
+ PAGE_SIZE * 2,
+ MT_RO_DATA);
+ if (ret != 0) {
+ ERROR("Error while mapping SP manifest (%d).\n", ret);
+ return ret;
+ }
+
+ ret = fdt_node_offset_by_compatible(sp_manifest, -1,
+ "arm,ffa-manifest-1.0");
+ if (ret < 0) {
+ ERROR("Error happened in SP manifest reading.\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Store the size of the manifest so that it can be used later to pass
+ * the manifest as boot information later.
+ */
+ next_image_ep_info->args.arg1 = fdt_totalsize(sp_manifest);
+ INFO("Manifest size = %lu bytes.\n", next_image_ep_info->args.arg1);
+
+ /*
+ * Select an SP descriptor for initialising the partition's execution
+ * context on the primary CPU.
+ */
+ sp = spmc_get_current_sp_ctx();
+
+ /* Initialize entry point information for the SP */
+ SET_PARAM_HEAD(next_image_ep_info, PARAM_EP, VERSION_1,
+ SECURE | EP_ST_ENABLE);
+
+ /* Parse the SP manifest. */
+ ret = sp_manifest_parse(sp_manifest, ret, sp, next_image_ep_info,
+ &boot_info_reg);
+ if (ret != 0) {
+ ERROR("Error in Secure Partition manifest parsing.\n");
+ return ret;
+ }
+
+ /* Check that the runtime EL in the manifest was correct. */
+ if (sp->runtime_el != S_EL1) {
+ ERROR("Unexpected runtime EL: %d\n", sp->runtime_el);
+ return -EINVAL;
+ }
+
+ /* Perform any common initialisation. */
+ spmc_sp_common_setup(sp, next_image_ep_info, boot_info_reg);
+
+ /* Perform any initialisation specific to S-EL1 SPs. */
+ spmc_el1_sp_setup(sp, next_image_ep_info);
+
+ /* Initialize the SP context with the required ep info. */
+ spmc_sp_common_ep_commit(sp, next_image_ep_info);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function takes an SP context pointer and performs a synchronous entry
+ * into it.
+ ******************************************************************************/
+static int32_t logical_sp_init(void)
+{
+ int32_t rc = 0;
+ struct el3_lp_desc *el3_lp_descs;
+
+ /* Perform initial validation of the Logical Partitions. */
+ rc = el3_sp_desc_validate();
+ if (rc != 0) {
+ ERROR("Logical Partition validation failed!\n");
+ return rc;
+ }
+
+ el3_lp_descs = get_el3_lp_array();
+
+ INFO("Logical Secure Partition init start.\n");
+ for (unsigned int i = 0U; i < EL3_LP_DESCS_COUNT; i++) {
+ rc = el3_lp_descs[i].init();
+ if (rc != 0) {
+ ERROR("Logical SP (0x%x) Failed to Initialize\n",
+ el3_lp_descs[i].sp_id);
+ return rc;
+ }
+ VERBOSE("Logical SP (0x%x) Initialized\n",
+ el3_lp_descs[i].sp_id);
+ }
+
+ INFO("Logical Secure Partition init completed.\n");
+
+ return rc;
+}
+
+uint64_t spmc_sp_synchronous_entry(struct sp_exec_ctx *ec)
+{
+ uint64_t rc;
+
+ assert(ec != NULL);
+
+ /* Assign the context of the SP to this CPU */
+ cm_set_context(&(ec->cpu_ctx), SECURE);
+
+ /* Restore the context assigned above */
+ cm_el1_sysregs_context_restore(SECURE);
+ cm_set_next_eret_context(SECURE);
+
+ /* Invalidate TLBs at EL1. */
+ tlbivmalle1();
+ dsbish();
+
+ /* Enter Secure Partition */
+ rc = spm_secure_partition_enter(&ec->c_rt_ctx);
+
+ /* Save secure state */
+ cm_el1_sysregs_context_save(SECURE);
+
+ return rc;
+}
+
+/*******************************************************************************
+ * SPMC Helper Functions.
+ ******************************************************************************/
+static int32_t sp_init(void)
+{
+ uint64_t rc;
+ struct secure_partition_desc *sp;
+ struct sp_exec_ctx *ec;
+
+ sp = spmc_get_current_sp_ctx();
+ ec = spmc_get_sp_ec(sp);
+ ec->rt_model = RT_MODEL_INIT;
+ ec->rt_state = RT_STATE_RUNNING;
+
+ INFO("Secure Partition (0x%x) init start.\n", sp->sp_id);
+
+ rc = spmc_sp_synchronous_entry(ec);
+ if (rc != 0) {
+ /* Indicate SP init was not successful. */
+ ERROR("SP (0x%x) failed to initialize (%lu).\n",
+ sp->sp_id, rc);
+ return 0;
+ }
+
+ ec->rt_state = RT_STATE_WAITING;
+ INFO("Secure Partition initialized.\n");
+
+ return 1;
+}
+
+static void initalize_sp_descs(void)
+{
+ struct secure_partition_desc *sp;
+
+ for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) {
+ sp = &sp_desc[i];
+ sp->sp_id = INV_SP_ID;
+ sp->mailbox.rx_buffer = NULL;
+ sp->mailbox.tx_buffer = NULL;
+ sp->mailbox.state = MAILBOX_STATE_EMPTY;
+ sp->secondary_ep = 0;
+ }
+}
+
+static void initalize_ns_ep_descs(void)
+{
+ struct ns_endpoint_desc *ns_ep;
+
+ for (unsigned int i = 0U; i < NS_PARTITION_COUNT; i++) {
+ ns_ep = &ns_ep_desc[i];
+ /*
+ * Clashes with the Hypervisor ID but will not be a
+ * problem in practice.
+ */
+ ns_ep->ns_ep_id = 0;
+ ns_ep->ffa_version = 0;
+ ns_ep->mailbox.rx_buffer = NULL;
+ ns_ep->mailbox.tx_buffer = NULL;
+ ns_ep->mailbox.state = MAILBOX_STATE_EMPTY;
+ }
+}
+
+/*******************************************************************************
+ * Initialize SPMC attributes for the SPMD.
+ ******************************************************************************/
+void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs)
+{
+ spmc_attrs->major_version = FFA_VERSION_MAJOR;
+ spmc_attrs->minor_version = FFA_VERSION_MINOR;
+ spmc_attrs->exec_state = MODE_RW_64;
+ spmc_attrs->spmc_id = FFA_SPMC_ID;
+}
+
+/*******************************************************************************
+ * Initialize contexts of all Secure Partitions.
+ ******************************************************************************/
+int32_t spmc_setup(void)
+{
+ int32_t ret;
+ uint32_t flags;
+
+ /* Initialize endpoint descriptors */
+ initalize_sp_descs();
+ initalize_ns_ep_descs();
+
+ /*
+ * Retrieve the information of the datastore for tracking shared memory
+ * requests allocated by platform code and zero the region if available.
+ */
+ ret = plat_spmc_shmem_datastore_get(&spmc_shmem_obj_state.data,
+ &spmc_shmem_obj_state.data_size);
+ if (ret != 0) {
+ ERROR("Failed to obtain memory descriptor backing store!\n");
+ return ret;
+ }
+ memset(spmc_shmem_obj_state.data, 0, spmc_shmem_obj_state.data_size);
+
+ /* Setup logical SPs. */
+ ret = logical_sp_init();
+ if (ret != 0) {
+ ERROR("Failed to initialize Logical Partitions.\n");
+ return ret;
+ }
+
+ /* Perform physical SP setup. */
+
+ /* Disable MMU at EL1 (initialized by BL2) */
+ disable_mmu_icache_el1();
+
+ /* Initialize context of the SP */
+ INFO("Secure Partition context setup start.\n");
+
+ ret = find_and_prepare_sp_context();
+ if (ret != 0) {
+ ERROR("Error in SP finding and context preparation.\n");
+ return ret;
+ }
+
+ /* Register power management hooks with PSCI */
+ psci_register_spd_pm_hook(&spmc_pm);
+
+ /*
+ * Register an interrupt handler for S-EL1 interrupts
+ * when generated during code executing in the
+ * non-secure state.
+ */
+ flags = 0;
+ set_interrupt_rm_flag(flags, NON_SECURE);
+ ret = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+ spmc_sp_interrupt_handler,
+ flags);
+ if (ret != 0) {
+ ERROR("Failed to register interrupt handler! (%d)\n", ret);
+ panic();
+ }
+
+ /* Register init function for deferred init. */
+ bl31_register_bl32_init(&sp_init);
+
+ INFO("Secure Partition setup done.\n");
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Secure Partition Manager SMC handler.
+ ******************************************************************************/
+uint64_t spmc_smc_handler(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ switch (smc_fid) {
+
+ case FFA_VERSION:
+ return ffa_version_handler(smc_fid, secure_origin, x1, x2, x3,
+ x4, cookie, handle, flags);
+
+ case FFA_SPM_ID_GET:
+ return ffa_spm_id_get_handler(smc_fid, secure_origin, x1, x2,
+ x3, x4, cookie, handle, flags);
+
+ case FFA_ID_GET:
+ return ffa_id_get_handler(smc_fid, secure_origin, x1, x2, x3,
+ x4, cookie, handle, flags);
+
+ case FFA_FEATURES:
+ return ffa_features_handler(smc_fid, secure_origin, x1, x2, x3,
+ x4, cookie, handle, flags);
+
+ case FFA_SECONDARY_EP_REGISTER_SMC64:
+ return ffa_sec_ep_register_handler(smc_fid, secure_origin, x1,
+ x2, x3, x4, cookie, handle,
+ flags);
+
+ case FFA_MSG_SEND_DIRECT_REQ_SMC32:
+ case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+ return direct_req_smc_handler(smc_fid, secure_origin, x1, x2,
+ x3, x4, cookie, handle, flags);
+
+ case FFA_MSG_SEND_DIRECT_RESP_SMC32:
+ case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+ return direct_resp_smc_handler(smc_fid, secure_origin, x1, x2,
+ x3, x4, cookie, handle, flags);
+
+ case FFA_RXTX_MAP_SMC32:
+ case FFA_RXTX_MAP_SMC64:
+ return rxtx_map_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+
+ case FFA_RXTX_UNMAP:
+ return rxtx_unmap_handler(smc_fid, secure_origin, x1, x2, x3,
+ x4, cookie, handle, flags);
+
+ case FFA_PARTITION_INFO_GET:
+ return partition_info_get_handler(smc_fid, secure_origin, x1,
+ x2, x3, x4, cookie, handle,
+ flags);
+
+ case FFA_RX_RELEASE:
+ return rx_release_handler(smc_fid, secure_origin, x1, x2, x3,
+ x4, cookie, handle, flags);
+
+ case FFA_MSG_WAIT:
+ return msg_wait_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+
+ case FFA_ERROR:
+ return ffa_error_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+
+ case FFA_MSG_RUN:
+ return ffa_run_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+
+ case FFA_MEM_SHARE_SMC32:
+ case FFA_MEM_SHARE_SMC64:
+ case FFA_MEM_LEND_SMC32:
+ case FFA_MEM_LEND_SMC64:
+ return spmc_ffa_mem_send(smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+
+ case FFA_MEM_FRAG_TX:
+ return spmc_ffa_mem_frag_tx(smc_fid, secure_origin, x1, x2, x3,
+ x4, cookie, handle, flags);
+
+ case FFA_MEM_FRAG_RX:
+ return spmc_ffa_mem_frag_rx(smc_fid, secure_origin, x1, x2, x3,
+ x4, cookie, handle, flags);
+
+ case FFA_MEM_RETRIEVE_REQ_SMC32:
+ case FFA_MEM_RETRIEVE_REQ_SMC64:
+ return spmc_ffa_mem_retrieve_req(smc_fid, secure_origin, x1, x2,
+ x3, x4, cookie, handle, flags);
+
+ case FFA_MEM_RELINQUISH:
+ return spmc_ffa_mem_relinquish(smc_fid, secure_origin, x1, x2,
+ x3, x4, cookie, handle, flags);
+
+ case FFA_MEM_RECLAIM:
+ return spmc_ffa_mem_reclaim(smc_fid, secure_origin, x1, x2, x3,
+ x4, cookie, handle, flags);
+
+ default:
+ WARN("Unsupported FF-A call 0x%08x.\n", smc_fid);
+ break;
+ }
+ return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+}
+
+/*******************************************************************************
+ * This function is the handler registered for S-EL1 interrupts by the SPMC. It
+ * validates the interrupt and upon success arranges entry into the SP for
+ * handling the interrupt.
+ ******************************************************************************/
+static uint64_t spmc_sp_interrupt_handler(uint32_t id,
+ uint32_t flags,
+ void *handle,
+ void *cookie)
+{
+ struct secure_partition_desc *sp = spmc_get_current_sp_ctx();
+ struct sp_exec_ctx *ec;
+ uint32_t linear_id = plat_my_core_pos();
+
+ /* Sanity check for a NULL pointer dereference. */
+ assert(sp != NULL);
+
+ /* Check the security state when the exception was generated. */
+ assert(get_interrupt_src_ss(flags) == NON_SECURE);
+
+ /* Panic if not an S-EL1 Partition. */
+ if (sp->runtime_el != S_EL1) {
+ ERROR("Interrupt received for a non S-EL1 SP on core%u.\n",
+ linear_id);
+ panic();
+ }
+
+ /* Obtain a reference to the SP execution context. */
+ ec = spmc_get_sp_ec(sp);
+
+ /* Ensure that the execution context is in waiting state else panic. */
+ if (ec->rt_state != RT_STATE_WAITING) {
+ ERROR("SP EC on core%u is not waiting (%u), it is (%u).\n",
+ linear_id, RT_STATE_WAITING, ec->rt_state);
+ panic();
+ }
+
+ /* Update the runtime model and state of the partition. */
+ ec->rt_model = RT_MODEL_INTR;
+ ec->rt_state = RT_STATE_RUNNING;
+
+ VERBOSE("SP (0x%x) interrupt start on core%u.\n", sp->sp_id, linear_id);
+
+ /*
+ * Forward the interrupt to the S-EL1 SP. The interrupt ID is not
+ * populated as the SP can determine this by itself.
+ */
+ return spmd_smc_switch_state(FFA_INTERRUPT, false,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ handle);
+}
diff --git a/services/std_svc/spm/el3_spmc/spmc_pm.c b/services/std_svc/spm/el3_spmc/spmc_pm.c
new file mode 100644
index 0000000..d25344c
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc_pm.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/spinlock.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+#include <services/ffa_svc.h>
+#include "spmc.h"
+
+#include <platform_def.h>
+
+/*******************************************************************************
+ * spmc_build_pm_message
+ *
+ * Builds an SPMC to SP direct message request.
+ ******************************************************************************/
+static void spmc_build_pm_message(gp_regs_t *gpregs,
+ unsigned long long message,
+ uint8_t pm_msg_type,
+ uint16_t sp_id)
+{
+ write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_MSG_SEND_DIRECT_REQ_SMC32);
+ write_ctx_reg(gpregs, CTX_GPREG_X1,
+ (FFA_SPMC_ID << FFA_DIRECT_MSG_SOURCE_SHIFT) |
+ sp_id);
+ write_ctx_reg(gpregs, CTX_GPREG_X2, FFA_FWK_MSG_BIT |
+ (pm_msg_type & FFA_FWK_MSG_MASK));
+ write_ctx_reg(gpregs, CTX_GPREG_X3, message);
+}
+
+/*******************************************************************************
+ * This CPU has been turned on. Enter the SP to initialise S-EL1.
+ ******************************************************************************/
+static void spmc_cpu_on_finish_handler(u_register_t unused)
+{
+ struct secure_partition_desc *sp = spmc_get_current_sp_ctx();
+ struct sp_exec_ctx *ec;
+ unsigned int linear_id = plat_my_core_pos();
+ entry_point_info_t sec_ec_ep_info = {0};
+ uint64_t rc;
+
+ /* Sanity check for a NULL pointer dereference. */
+ assert(sp != NULL);
+
+ /* Initialize entry point information for the SP. */
+ SET_PARAM_HEAD(&sec_ec_ep_info, PARAM_EP, VERSION_1,
+ SECURE | EP_ST_ENABLE);
+
+ /*
+ * Check if the primary execution context registered an entry point else
+ * bail out early.
+ * TODO: Add support for boot reason in manifest to allow jumping to
+ * entrypoint into the primary execution context.
+ */
+ if (sp->secondary_ep == 0) {
+ WARN("%s: No secondary ep on core%u\n", __func__, linear_id);
+ return;
+ }
+
+ sec_ec_ep_info.pc = sp->secondary_ep;
+
+ /*
+ * Setup and initialise the SP execution context on this physical cpu.
+ */
+ spmc_el1_sp_setup(sp, &sec_ec_ep_info);
+ spmc_sp_common_ep_commit(sp, &sec_ec_ep_info);
+
+ /* Obtain a reference to the SP execution context. */
+ ec = spmc_get_sp_ec(sp);
+
+ /*
+ * TODO: Should we do some PM related state tracking of the SP execution
+ * context here?
+ */
+
+ /* Update the runtime model and state of the partition. */
+ ec->rt_model = RT_MODEL_INIT;
+ ec->rt_state = RT_STATE_RUNNING;
+
+ INFO("SP (0x%x) init start on core%u.\n", sp->sp_id, linear_id);
+
+ rc = spmc_sp_synchronous_entry(ec);
+ if (rc != 0ULL) {
+ ERROR("%s failed (%lu) on CPU%u\n", __func__, rc, linear_id);
+ }
+
+ /* Update the runtime state of the partition. */
+ ec->rt_state = RT_STATE_WAITING;
+
+ VERBOSE("CPU %u on!\n", linear_id);
+}
+/*******************************************************************************
+ * Helper function to send a FF-A power management message to an SP.
+ ******************************************************************************/
+static int32_t spmc_send_pm_msg(uint8_t pm_msg_type,
+ unsigned long long psci_event)
+{
+ struct secure_partition_desc *sp = spmc_get_current_sp_ctx();
+ struct sp_exec_ctx *ec;
+ gp_regs_t *gpregs_ctx;
+ unsigned int linear_id = plat_my_core_pos();
+ u_register_t resp;
+ uint64_t rc;
+
+ /* Obtain a reference to the SP execution context. */
+ ec = spmc_get_sp_ec(sp);
+
+ /*
+ * TODO: Should we do some PM related state tracking of the SP execution
+ * context here?
+ */
+
+ /*
+ * Build an SPMC to SP direct message request.
+ * Note that x4-x6 should be populated with the original PSCI arguments.
+ */
+ spmc_build_pm_message(get_gpregs_ctx(&ec->cpu_ctx),
+ psci_event,
+ pm_msg_type,
+ sp->sp_id);
+
+ /* Sanity check partition state. */
+ assert(ec->rt_state == RT_STATE_WAITING);
+
+ /* Update the runtime model and state of the partition. */
+ ec->rt_model = RT_MODEL_DIR_REQ;
+ ec->rt_state = RT_STATE_RUNNING;
+
+ rc = spmc_sp_synchronous_entry(ec);
+ if (rc != 0ULL) {
+ ERROR("%s failed (%lu) on CPU%u.\n", __func__, rc, linear_id);
+ assert(false);
+ return -EINVAL;
+ }
+
+ /*
+ * Validate we receive an expected response from the SP.
+ * TODO: We don't currently support aborting an SP in the scenario
+ * where it is misbehaving so assert these conditions are not
+ * met for now.
+ */
+ gpregs_ctx = get_gpregs_ctx(&ec->cpu_ctx);
+
+ /* Expect a direct message response from the SP. */
+ resp = read_ctx_reg(gpregs_ctx, CTX_GPREG_X0);
+ if (resp != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
+ ERROR("%s invalid SP response (%lx).\n", __func__, resp);
+ assert(false);
+ return -EINVAL;
+ }
+
+ /* Ensure the sender and receiver are populated correctly. */
+ resp = read_ctx_reg(gpregs_ctx, CTX_GPREG_X1);
+ if (!(ffa_endpoint_source(resp) == sp->sp_id &&
+ ffa_endpoint_destination(resp) == FFA_SPMC_ID)) {
+ ERROR("%s invalid src/dst response (%lx).\n", __func__, resp);
+ assert(false);
+ return -EINVAL;
+ }
+
+ /* Expect a PM message response from the SP. */
+ resp = read_ctx_reg(gpregs_ctx, CTX_GPREG_X2);
+ if ((resp & FFA_FWK_MSG_BIT) == 0U ||
+ ((resp & FFA_FWK_MSG_MASK) != FFA_PM_MSG_PM_RESP)) {
+ ERROR("%s invalid PM response (%lx).\n", __func__, resp);
+ assert(false);
+ return -EINVAL;
+ }
+
+ /* Update the runtime state of the partition. */
+ ec->rt_state = RT_STATE_WAITING;
+
+ /* Return the status code returned by the SP */
+ return read_ctx_reg(gpregs_ctx, CTX_GPREG_X3);
+}
+
+/*******************************************************************************
+ * spmc_cpu_suspend_finish_handler
+ ******************************************************************************/
+static void spmc_cpu_suspend_finish_handler(u_register_t unused)
+{
+ struct secure_partition_desc *sp = spmc_get_current_sp_ctx();
+ unsigned int linear_id = plat_my_core_pos();
+ int32_t rc;
+
+ /* Sanity check for a NULL pointer dereference. */
+ assert(sp != NULL);
+
+ /*
+ * Check if the SP has subscribed for this power management message.
+ * If not then we don't have anything else to do here.
+ */
+ if ((sp->pwr_mgmt_msgs & FFA_PM_MSG_SUB_CPU_SUSPEND_RESUME) == 0U) {
+ goto exit;
+ }
+
+ rc = spmc_send_pm_msg(FFA_PM_MSG_WB_REQ, FFA_WB_TYPE_NOTS2RAM);
+ if (rc < 0) {
+ ERROR("%s failed (%d) on CPU%u\n", __func__, rc, linear_id);
+ return;
+ }
+
+exit:
+ VERBOSE("CPU %u resumed!\n", linear_id);
+}
+
+/*******************************************************************************
+ * spmc_cpu_suspend_handler
+ ******************************************************************************/
+static void spmc_cpu_suspend_handler(u_register_t unused)
+{
+ struct secure_partition_desc *sp = spmc_get_current_sp_ctx();
+ unsigned int linear_id = plat_my_core_pos();
+ int32_t rc;
+
+ /* Sanity check for a NULL pointer dereference. */
+ assert(sp != NULL);
+
+ /*
+ * Check if the SP has subscribed for this power management message.
+ * If not then we don't have anything else to do here.
+ */
+ if ((sp->pwr_mgmt_msgs & FFA_PM_MSG_SUB_CPU_SUSPEND) == 0U) {
+ goto exit;
+ }
+
+ rc = spmc_send_pm_msg(FFA_FWK_MSG_PSCI, PSCI_CPU_SUSPEND_AARCH64);
+ if (rc < 0) {
+ ERROR("%s failed (%d) on CPU%u\n", __func__, rc, linear_id);
+ return;
+ }
+exit:
+ VERBOSE("CPU %u suspend!\n", linear_id);
+}
+
+/*******************************************************************************
+ * spmc_cpu_off_handler
+ ******************************************************************************/
+static int32_t spmc_cpu_off_handler(u_register_t unused)
+{
+ struct secure_partition_desc *sp = spmc_get_current_sp_ctx();
+ unsigned int linear_id = plat_my_core_pos();
+ int32_t ret = 0;
+
+ /* Sanity check for a NULL pointer dereference. */
+ assert(sp != NULL);
+
+ /*
+ * Check if the SP has subscribed for this power management message.
+ * If not then we don't have anything else to do here.
+ */
+ if ((sp->pwr_mgmt_msgs & FFA_PM_MSG_SUB_CPU_OFF) == 0U) {
+ goto exit;
+ }
+
+ ret = spmc_send_pm_msg(FFA_FWK_MSG_PSCI, PSCI_CPU_OFF);
+ if (ret < 0) {
+ ERROR("%s failed (%d) on CPU%u\n", __func__, ret, linear_id);
+ return ret;
+ }
+
+exit:
+ VERBOSE("CPU %u off!\n", linear_id);
+ return ret;
+}
+
+/*******************************************************************************
+ * Structure populated by the SPM Core to perform any bookkeeping before
+ * PSCI executes a power mgmt. operation.
+ ******************************************************************************/
+const spd_pm_ops_t spmc_pm = {
+ .svc_on_finish = spmc_cpu_on_finish_handler,
+ .svc_off = spmc_cpu_off_handler,
+ .svc_suspend = spmc_cpu_suspend_handler,
+ .svc_suspend_finish = spmc_cpu_suspend_finish_handler
+};
diff --git a/services/std_svc/spm/el3_spmc/spmc_setup.c b/services/std_svc/spm/el3_spmc/spmc_setup.c
new file mode 100644
index 0000000..8ebae28
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc_setup.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <libfdt.h>
+#include <plat/common/common_def.h>
+#include <plat/common/platform.h>
+#include <services/ffa_svc.h>
+#include "spm_common.h"
+#include "spmc.h"
+#include <tools_share/firmware_image_package.h>
+
+#include <platform_def.h>
+
+/*
+ * Statically allocate a page of memory for passing boot information to an SP.
+ */
+static uint8_t ffa_boot_info_mem[PAGE_SIZE] __aligned(PAGE_SIZE);
+
+/*
+ * This function creates a initialization descriptor in the memory reserved
+ * for passing boot information to an SP. It then copies the partition manifest
+ * into this region and ensures that its reference in the initialization
+ * descriptor is updated.
+ */
+static void spmc_create_boot_info(entry_point_info_t *ep_info,
+ struct secure_partition_desc *sp)
+{
+ struct ffa_boot_info_header *boot_header;
+ struct ffa_boot_info_desc *boot_descriptor;
+ uintptr_t manifest_addr;
+
+ /*
+ * Calculate the maximum size of the manifest that can be accommodated
+ * in the boot information memory region.
+ */
+ const unsigned int
+ max_manifest_sz = sizeof(ffa_boot_info_mem) -
+ (sizeof(struct ffa_boot_info_header) +
+ sizeof(struct ffa_boot_info_desc));
+
+ /*
+ * The current implementation only supports the FF-A v1.1
+ * implementation of the boot protocol, therefore check
+ * that a v1.0 SP has not requested use of the protocol.
+ */
+ if (sp->ffa_version == MAKE_FFA_VERSION(1, 0)) {
+ ERROR("FF-A boot protocol not supported for v1.0 clients\n");
+ return;
+ }
+
+ /*
+ * Check if the manifest will fit into the boot info memory region else
+ * bail.
+ */
+ if (ep_info->args.arg1 > max_manifest_sz) {
+ WARN("Unable to copy manifest into boot information. ");
+ WARN("Max sz = %u bytes. Manifest sz = %lu bytes\n",
+ max_manifest_sz, ep_info->args.arg1);
+ return;
+ }
+
+ /* Zero the memory region before populating. */
+ memset(ffa_boot_info_mem, 0, PAGE_SIZE);
+
+ /*
+ * Populate the ffa_boot_info_header at the start of the boot info
+ * region.
+ */
+ boot_header = (struct ffa_boot_info_header *) ffa_boot_info_mem;
+
+ /* Position the ffa_boot_info_desc after the ffa_boot_info_header. */
+ boot_header->offset_boot_info_desc =
+ sizeof(struct ffa_boot_info_header);
+ boot_descriptor = (struct ffa_boot_info_desc *)
+ (ffa_boot_info_mem +
+ boot_header->offset_boot_info_desc);
+
+ /*
+ * We must use the FF-A version coresponding to the version implemented
+ * by the SP. Currently this can only be v1.1.
+ */
+ boot_header->version = sp->ffa_version;
+
+ /* Populate the boot information header. */
+ boot_header->size_boot_info_desc = sizeof(struct ffa_boot_info_desc);
+
+ /* Set the signature "0xFFA". */
+ boot_header->signature = FFA_INIT_DESC_SIGNATURE;
+
+ /* Set the count. Currently 1 since only the manifest is specified. */
+ boot_header->count_boot_info_desc = 1;
+
+ /* Populate the boot information descriptor for the manifest. */
+ boot_descriptor->type =
+ FFA_BOOT_INFO_TYPE(FFA_BOOT_INFO_TYPE_STD) |
+ FFA_BOOT_INFO_TYPE_ID(FFA_BOOT_INFO_TYPE_ID_FDT);
+
+ boot_descriptor->flags =
+ FFA_BOOT_INFO_FLAG_NAME(FFA_BOOT_INFO_FLAG_NAME_UUID) |
+ FFA_BOOT_INFO_FLAG_CONTENT(FFA_BOOT_INFO_FLAG_CONTENT_ADR);
+
+ /*
+ * Copy the manifest into boot info region after the boot information
+ * descriptor.
+ */
+ boot_descriptor->size_boot_info = (uint32_t) ep_info->args.arg1;
+
+ manifest_addr = (uintptr_t) (ffa_boot_info_mem +
+ boot_header->offset_boot_info_desc +
+ boot_header->size_boot_info_desc);
+
+ memcpy((void *) manifest_addr, (void *) ep_info->args.arg0,
+ boot_descriptor->size_boot_info);
+
+ boot_descriptor->content = manifest_addr;
+
+ /* Calculate the size of the total boot info blob. */
+ boot_header->size_boot_info_blob = boot_header->offset_boot_info_desc +
+ boot_descriptor->size_boot_info +
+ (boot_header->count_boot_info_desc *
+ boot_header->size_boot_info_desc);
+
+ INFO("SP boot info @ 0x%lx, size: %u bytes.\n",
+ (uintptr_t) ffa_boot_info_mem,
+ boot_header->size_boot_info_blob);
+ INFO("SP manifest @ 0x%lx, size: %u bytes.\n",
+ boot_descriptor->content,
+ boot_descriptor->size_boot_info);
+}
+
+/*
+ * We are assuming that the index of the execution
+ * context used is the linear index of the current physical cpu.
+ */
+unsigned int get_ec_index(struct secure_partition_desc *sp)
+{
+ return plat_my_core_pos();
+}
+
+/* S-EL1 partition specific initialisation. */
+void spmc_el1_sp_setup(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info)
+{
+ /* Sanity check input arguments. */
+ assert(sp != NULL);
+ assert(ep_info != NULL);
+
+ /* Initialise the SPSR for S-EL1 SPs. */
+ ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS);
+
+ /*
+ * TF-A Implementation defined behaviour to provide the linear
+ * core ID in the x4 register.
+ */
+ ep_info->args.arg4 = (uintptr_t) plat_my_core_pos();
+
+ /*
+ * Check whether setup is being performed for the primary or a secondary
+ * execution context. In the latter case, indicate to the SP that this
+ * is a warm boot.
+ * TODO: This check would need to be reworked if the same entry point is
+ * used for both primary and secondary initialisation.
+ */
+ if (sp->secondary_ep != 0U) {
+ /*
+ * Sanity check that the secondary entry point is still what was
+ * originally set.
+ */
+ assert(sp->secondary_ep == ep_info->pc);
+ ep_info->args.arg0 = FFA_WB_TYPE_S2RAM;
+ }
+}
+
+/* Common initialisation for all SPs. */
+void spmc_sp_common_setup(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info,
+ int32_t boot_info_reg)
+{
+ uint16_t sp_id;
+
+ /* Assign FF-A Partition ID if not already assigned. */
+ if (sp->sp_id == INV_SP_ID) {
+ sp_id = FFA_SP_ID_BASE + ACTIVE_SP_DESC_INDEX;
+ /*
+ * Ensure we don't clash with previously assigned partition
+ * IDs.
+ */
+ while (!is_ffa_secure_id_valid(sp_id)) {
+ sp_id++;
+
+ if (sp_id == FFA_SWD_ID_LIMIT) {
+ ERROR("Unable to determine valid SP ID.\n");
+ panic();
+ }
+ }
+ sp->sp_id = sp_id;
+ }
+
+ /*
+ * We currently only support S-EL1 partitions so ensure this is the
+ * case.
+ */
+ assert(sp->runtime_el == S_EL1);
+
+ /* Check if the SP wants to use the FF-A boot protocol. */
+ if (boot_info_reg >= 0) {
+ /*
+ * Create a boot information descriptor and copy the partition
+ * manifest into the reserved memory region for consumption by
+ * the SP.
+ */
+ spmc_create_boot_info(ep_info, sp);
+
+ /*
+ * We have consumed what we need from ep args so we can now
+ * zero them before we start populating with new information
+ * specifically for the SP.
+ */
+ zeromem(&ep_info->args, sizeof(ep_info->args));
+
+ /*
+ * Pass the address of the boot information in the
+ * boot_info_reg.
+ */
+ switch (boot_info_reg) {
+ case 0:
+ ep_info->args.arg0 = (uintptr_t) ffa_boot_info_mem;
+ break;
+ case 1:
+ ep_info->args.arg1 = (uintptr_t) ffa_boot_info_mem;
+ break;
+ case 2:
+ ep_info->args.arg2 = (uintptr_t) ffa_boot_info_mem;
+ break;
+ case 3:
+ ep_info->args.arg3 = (uintptr_t) ffa_boot_info_mem;
+ break;
+ default:
+ ERROR("Invalid value for \"gp-register-num\" %d.\n",
+ boot_info_reg);
+ }
+ } else {
+ /*
+ * We don't need any of the information that was populated
+ * in ep_args so we can clear them.
+ */
+ zeromem(&ep_info->args, sizeof(ep_info->args));
+ }
+}
+
+/*
+ * Initialise the SP context now we have populated the common and EL specific
+ * entrypoint information.
+ */
+void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
+ entry_point_info_t *ep_info)
+{
+ cpu_context_t *cpu_ctx;
+
+ cpu_ctx = &(spmc_get_sp_ec(sp)->cpu_ctx);
+ print_entry_point_info(ep_info);
+ cm_setup_context(cpu_ctx, ep_info);
+}
diff --git a/services/std_svc/spm/el3_spmc/spmc_shared_mem.c b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
new file mode 100644
index 0000000..eab2096
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.c
@@ -0,0 +1,1844 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/object_pool.h>
+#include <lib/spinlock.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <services/ffa_svc.h>
+#include "spmc.h"
+#include "spmc_shared_mem.h"
+
+#include <platform_def.h>
+
+/**
+ * struct spmc_shmem_obj - Shared memory object.
+ * @desc_size: Size of @desc.
+ * @desc_filled: Size of @desc already received.
+ * @in_use: Number of clients that have called ffa_mem_retrieve_req
+ * without a matching ffa_mem_relinquish call.
+ * @desc: FF-A memory region descriptor passed in ffa_mem_share.
+ */
+struct spmc_shmem_obj {
+ size_t desc_size;
+ size_t desc_filled;
+ size_t in_use;
+ struct ffa_mtd desc;
+};
+
+/*
+ * Declare our data structure to store the metadata of memory share requests.
+ * The main datastore is allocated on a per platform basis to ensure enough
+ * storage can be made available.
+ * The address of the data store will be populated by the SPMC during its
+ * initialization.
+ */
+
+struct spmc_shmem_obj_state spmc_shmem_obj_state = {
+ /* Set start value for handle so top 32 bits are needed quickly. */
+ .next_handle = 0xffffffc0U,
+};
+
+/**
+ * spmc_shmem_obj_size - Convert from descriptor size to object size.
+ * @desc_size: Size of struct ffa_memory_region_descriptor object.
+ *
+ * Return: Size of struct spmc_shmem_obj object.
+ */
+static size_t spmc_shmem_obj_size(size_t desc_size)
+{
+ return desc_size + offsetof(struct spmc_shmem_obj, desc);
+}
+
+/**
+ * spmc_shmem_obj_alloc - Allocate struct spmc_shmem_obj.
+ * @state: Global state.
+ * @desc_size: Size of struct ffa_memory_region_descriptor object that
+ * allocated object will hold.
+ *
+ * Return: Pointer to newly allocated object, or %NULL if there not enough space
+ * left. The returned pointer is only valid while @state is locked, to
+ * used it again after unlocking @state, spmc_shmem_obj_lookup must be
+ * called.
+ */
+static struct spmc_shmem_obj *
+spmc_shmem_obj_alloc(struct spmc_shmem_obj_state *state, size_t desc_size)
+{
+ struct spmc_shmem_obj *obj;
+ size_t free = state->data_size - state->allocated;
+
+ if (state->data == NULL) {
+ ERROR("Missing shmem datastore!\n");
+ return NULL;
+ }
+
+ if (spmc_shmem_obj_size(desc_size) > free) {
+ WARN("%s(0x%zx) failed, free 0x%zx\n",
+ __func__, desc_size, free);
+ return NULL;
+ }
+ obj = (struct spmc_shmem_obj *)(state->data + state->allocated);
+ obj->desc = (struct ffa_mtd) {0};
+ obj->desc_size = desc_size;
+ obj->desc_filled = 0;
+ obj->in_use = 0;
+ state->allocated += spmc_shmem_obj_size(desc_size);
+ return obj;
+}
+
+/**
+ * spmc_shmem_obj_free - Free struct spmc_shmem_obj.
+ * @state: Global state.
+ * @obj: Object to free.
+ *
+ * Release memory used by @obj. Other objects may move, so on return all
+ * pointers to struct spmc_shmem_obj object should be considered invalid, not
+ * just @obj.
+ *
+ * The current implementation always compacts the remaining objects to simplify
+ * the allocator and to avoid fragmentation.
+ */
+
+static void spmc_shmem_obj_free(struct spmc_shmem_obj_state *state,
+ struct spmc_shmem_obj *obj)
+{
+ size_t free_size = spmc_shmem_obj_size(obj->desc_size);
+ uint8_t *shift_dest = (uint8_t *)obj;
+ uint8_t *shift_src = shift_dest + free_size;
+ size_t shift_size = state->allocated - (shift_src - state->data);
+
+ if (shift_size != 0U) {
+ memmove(shift_dest, shift_src, shift_size);
+ }
+ state->allocated -= free_size;
+}
+
+/**
+ * spmc_shmem_obj_lookup - Lookup struct spmc_shmem_obj by handle.
+ * @state: Global state.
+ * @handle: Unique handle of object to return.
+ *
+ * Return: struct spmc_shmem_obj_state object with handle matching @handle.
+ * %NULL, if not object in @state->data has a matching handle.
+ */
+static struct spmc_shmem_obj *
+spmc_shmem_obj_lookup(struct spmc_shmem_obj_state *state, uint64_t handle)
+{
+ uint8_t *curr = state->data;
+
+ while (curr - state->data < state->allocated) {
+ struct spmc_shmem_obj *obj = (struct spmc_shmem_obj *)curr;
+
+ if (obj->desc.handle == handle) {
+ return obj;
+ }
+ curr += spmc_shmem_obj_size(obj->desc_size);
+ }
+ return NULL;
+}
+
+/**
+ * spmc_shmem_obj_get_next - Get the next memory object from an offset.
+ * @offset: Offset used to track which objects have previously been
+ * returned.
+ *
+ * Return: the next struct spmc_shmem_obj_state object from the provided
+ * offset.
+ * %NULL, if there are no more objects.
+ */
+static struct spmc_shmem_obj *
+spmc_shmem_obj_get_next(struct spmc_shmem_obj_state *state, size_t *offset)
+{
+ uint8_t *curr = state->data + *offset;
+
+ if (curr - state->data < state->allocated) {
+ struct spmc_shmem_obj *obj = (struct spmc_shmem_obj *)curr;
+
+ *offset += spmc_shmem_obj_size(obj->desc_size);
+
+ return obj;
+ }
+ return NULL;
+}
+
+/*******************************************************************************
+ * FF-A memory descriptor helper functions.
+ ******************************************************************************/
+/**
+ * spmc_shmem_obj_get_emad - Get the emad from a given index depending on the
+ * clients FF-A version.
+ * @desc: The memory transaction descriptor.
+ * @index: The index of the emad element to be accessed.
+ * @ffa_version: FF-A version of the provided structure.
+ * @emad_size: Will be populated with the size of the returned emad
+ * descriptor.
+ * Return: A pointer to the requested emad structure.
+ */
+static void *
+spmc_shmem_obj_get_emad(const struct ffa_mtd *desc, uint32_t index,
+ uint32_t ffa_version, size_t *emad_size)
+{
+ uint8_t *emad;
+ /*
+ * If the caller is using FF-A v1.0 interpret the descriptor as a v1.0
+ * format, otherwise assume it is a v1.1 format.
+ */
+ if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+ /* Cast our descriptor to the v1.0 format. */
+ struct ffa_mtd_v1_0 *mtd_v1_0 =
+ (struct ffa_mtd_v1_0 *) desc;
+ emad = (uint8_t *) &(mtd_v1_0->emad);
+ *emad_size = sizeof(struct ffa_emad_v1_0);
+ } else {
+ if (!is_aligned(desc->emad_offset, 16)) {
+ WARN("Emad offset is not aligned.\n");
+ return NULL;
+ }
+ emad = ((uint8_t *) desc + desc->emad_offset);
+ *emad_size = desc->emad_size;
+ }
+ return (emad + (*emad_size * index));
+}
+
+/**
+ * spmc_shmem_obj_get_comp_mrd - Get comp_mrd from a mtd struct based on the
+ * FF-A version of the descriptor.
+ * @obj: Object containing ffa_memory_region_descriptor.
+ *
+ * Return: struct ffa_comp_mrd object corresponding to the composite memory
+ * region descriptor.
+ */
+static struct ffa_comp_mrd *
+spmc_shmem_obj_get_comp_mrd(struct spmc_shmem_obj *obj, uint32_t ffa_version)
+{
+ size_t emad_size;
+ /*
+ * The comp_mrd_offset field of the emad descriptor remains consistent
+ * between FF-A versions therefore we can use the v1.0 descriptor here
+ * in all cases.
+ */
+ struct ffa_emad_v1_0 *emad = spmc_shmem_obj_get_emad(&obj->desc, 0,
+ ffa_version,
+ &emad_size);
+ /* Ensure the emad array was found. */
+ if (emad == NULL) {
+ return NULL;
+ }
+
+ /* Ensure the composite descriptor offset is aligned. */
+ if (!is_aligned(emad->comp_mrd_offset, 8)) {
+ WARN("Unaligned composite memory region descriptor offset.\n");
+ return NULL;
+ }
+
+ return (struct ffa_comp_mrd *)
+ ((uint8_t *)(&obj->desc) + emad->comp_mrd_offset);
+}
+
+/**
+ * spmc_shmem_obj_ffa_constituent_size - Calculate variable size part of obj.
+ * @obj: Object containing ffa_memory_region_descriptor.
+ *
+ * Return: Size of ffa_constituent_memory_region_descriptors in @obj.
+ */
+static size_t
+spmc_shmem_obj_ffa_constituent_size(struct spmc_shmem_obj *obj,
+ uint32_t ffa_version)
+{
+ struct ffa_comp_mrd *comp_mrd;
+
+ comp_mrd = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
+ if (comp_mrd == NULL) {
+ return 0;
+ }
+ return comp_mrd->address_range_count * sizeof(struct ffa_cons_mrd);
+}
+
+/**
+ * spmc_shmem_obj_validate_id - Validate a partition ID is participating in
+ * a given memory transaction.
+ * @sp_id: Partition ID to validate.
+ * @desc: Descriptor of the memory transaction.
+ *
+ * Return: true if ID is valid, else false.
+ */
+bool spmc_shmem_obj_validate_id(const struct ffa_mtd *desc, uint16_t sp_id)
+{
+ bool found = false;
+
+ /* Validate the partition is a valid participant. */
+ for (unsigned int i = 0U; i < desc->emad_count; i++) {
+ size_t emad_size;
+ struct ffa_emad_v1_0 *emad;
+
+ emad = spmc_shmem_obj_get_emad(desc, i,
+ MAKE_FFA_VERSION(1, 1),
+ &emad_size);
+ if (sp_id == emad->mapd.endpoint_id) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+}
+
+/*
+ * Compare two memory regions to determine if any range overlaps with another
+ * ongoing memory transaction.
+ */
+static bool
+overlapping_memory_regions(struct ffa_comp_mrd *region1,
+ struct ffa_comp_mrd *region2)
+{
+ uint64_t region1_start;
+ uint64_t region1_size;
+ uint64_t region1_end;
+ uint64_t region2_start;
+ uint64_t region2_size;
+ uint64_t region2_end;
+
+ assert(region1 != NULL);
+ assert(region2 != NULL);
+
+ if (region1 == region2) {
+ return true;
+ }
+
+ /*
+ * Check each memory region in the request against existing
+ * transactions.
+ */
+ for (size_t i = 0; i < region1->address_range_count; i++) {
+
+ region1_start = region1->address_range_array[i].address;
+ region1_size =
+ region1->address_range_array[i].page_count *
+ PAGE_SIZE_4KB;
+ region1_end = region1_start + region1_size;
+
+ for (size_t j = 0; j < region2->address_range_count; j++) {
+
+ region2_start = region2->address_range_array[j].address;
+ region2_size =
+ region2->address_range_array[j].page_count *
+ PAGE_SIZE_4KB;
+ region2_end = region2_start + region2_size;
+
+ if ((region1_start >= region2_start &&
+ region1_start < region2_end) ||
+ (region1_end > region2_start
+ && region1_end < region2_end)) {
+ WARN("Overlapping mem regions 0x%lx-0x%lx & 0x%lx-0x%lx\n",
+ region1_start, region1_end,
+ region2_start, region2_end);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/*******************************************************************************
+ * FF-A v1.0 Memory Descriptor Conversion Helpers.
+ ******************************************************************************/
+/**
+ * spmc_shm_get_v1_1_descriptor_size - Calculate the required size for a v1.1
+ * converted descriptor.
+ * @orig: The original v1.0 memory transaction descriptor.
+ * @desc_size: The size of the original v1.0 memory transaction descriptor.
+ *
+ * Return: the size required to store the descriptor store in the v1.1 format.
+ */
+static size_t
+spmc_shm_get_v1_1_descriptor_size(struct ffa_mtd_v1_0 *orig, size_t desc_size)
+{
+ size_t size = 0;
+ struct ffa_comp_mrd *mrd;
+ struct ffa_emad_v1_0 *emad_array = orig->emad;
+
+ /* Get the size of the v1.1 descriptor. */
+ size += sizeof(struct ffa_mtd);
+
+ /* Add the size of the emad descriptors. */
+ size += orig->emad_count * sizeof(struct ffa_emad_v1_0);
+
+ /* Add the size of the composite mrds. */
+ size += sizeof(struct ffa_comp_mrd);
+
+ /* Add the size of the constituent mrds. */
+ mrd = (struct ffa_comp_mrd *) ((uint8_t *) orig +
+ emad_array[0].comp_mrd_offset);
+
+ /* Check the calculated address is within the memory descriptor. */
+ if ((uintptr_t) mrd >= (uintptr_t)((uint8_t *) orig + desc_size)) {
+ return 0;
+ }
+ size += mrd->address_range_count * sizeof(struct ffa_cons_mrd);
+
+ return size;
+}
+
+/**
+ * spmc_shm_get_v1_0_descriptor_size - Calculate the required size for a v1.0
+ * converted descriptor.
+ * @orig: The original v1.1 memory transaction descriptor.
+ * @desc_size: The size of the original v1.1 memory transaction descriptor.
+ *
+ * Return: the size required to store the descriptor store in the v1.0 format.
+ */
+static size_t
+spmc_shm_get_v1_0_descriptor_size(struct ffa_mtd *orig, size_t desc_size)
+{
+ size_t size = 0;
+ struct ffa_comp_mrd *mrd;
+ struct ffa_emad_v1_0 *emad_array = (struct ffa_emad_v1_0 *)
+ ((uint8_t *) orig +
+ orig->emad_offset);
+
+ /* Get the size of the v1.0 descriptor. */
+ size += sizeof(struct ffa_mtd_v1_0);
+
+ /* Add the size of the v1.0 emad descriptors. */
+ size += orig->emad_count * sizeof(struct ffa_emad_v1_0);
+
+ /* Add the size of the composite mrds. */
+ size += sizeof(struct ffa_comp_mrd);
+
+ /* Add the size of the constituent mrds. */
+ mrd = (struct ffa_comp_mrd *) ((uint8_t *) orig +
+ emad_array[0].comp_mrd_offset);
+
+ /* Check the calculated address is within the memory descriptor. */
+ if ((uintptr_t) mrd >= (uintptr_t)((uint8_t *) orig + desc_size)) {
+ return 0;
+ }
+ size += mrd->address_range_count * sizeof(struct ffa_cons_mrd);
+
+ return size;
+}
+
+/**
+ * spmc_shm_convert_shmem_obj_from_v1_0 - Converts a given v1.0 memory object.
+ * @out_obj: The shared memory object to populate the converted descriptor.
+ * @orig: The shared memory object containing the v1.0 descriptor.
+ *
+ * Return: true if the conversion is successful else false.
+ */
+static bool
+spmc_shm_convert_shmem_obj_from_v1_0(struct spmc_shmem_obj *out_obj,
+ struct spmc_shmem_obj *orig)
+{
+ struct ffa_mtd_v1_0 *mtd_orig = (struct ffa_mtd_v1_0 *) &orig->desc;
+ struct ffa_mtd *out = &out_obj->desc;
+ struct ffa_emad_v1_0 *emad_array_in;
+ struct ffa_emad_v1_0 *emad_array_out;
+ struct ffa_comp_mrd *mrd_in;
+ struct ffa_comp_mrd *mrd_out;
+
+ size_t mrd_in_offset;
+ size_t mrd_out_offset;
+ size_t mrd_size = 0;
+
+ /* Populate the new descriptor format from the v1.0 struct. */
+ out->sender_id = mtd_orig->sender_id;
+ out->memory_region_attributes = mtd_orig->memory_region_attributes;
+ out->flags = mtd_orig->flags;
+ out->handle = mtd_orig->handle;
+ out->tag = mtd_orig->tag;
+ out->emad_count = mtd_orig->emad_count;
+ out->emad_size = sizeof(struct ffa_emad_v1_0);
+
+ /*
+ * We will locate the emad descriptors directly after the ffa_mtd
+ * struct. This will be 8-byte aligned.
+ */
+ out->emad_offset = sizeof(struct ffa_mtd);
+
+ emad_array_in = mtd_orig->emad;
+ emad_array_out = (struct ffa_emad_v1_0 *)
+ ((uint8_t *) out + out->emad_offset);
+
+ /* Copy across the emad structs. */
+ for (unsigned int i = 0U; i < out->emad_count; i++) {
+ memcpy(&emad_array_out[i], &emad_array_in[i],
+ sizeof(struct ffa_emad_v1_0));
+ }
+
+ /* Place the mrd descriptors after the end of the emad descriptors.*/
+ mrd_in_offset = emad_array_in->comp_mrd_offset;
+ mrd_out_offset = out->emad_offset + (out->emad_size * out->emad_count);
+ mrd_out = (struct ffa_comp_mrd *) ((uint8_t *) out + mrd_out_offset);
+
+ /* Add the size of the composite memory region descriptor. */
+ mrd_size += sizeof(struct ffa_comp_mrd);
+
+ /* Find the mrd descriptor. */
+ mrd_in = (struct ffa_comp_mrd *) ((uint8_t *) mtd_orig + mrd_in_offset);
+
+ /* Add the size of the constituent memory region descriptors. */
+ mrd_size += mrd_in->address_range_count * sizeof(struct ffa_cons_mrd);
+
+ /*
+ * Update the offset in the emads by the delta between the input and
+ * output addresses.
+ */
+ for (unsigned int i = 0U; i < out->emad_count; i++) {
+ emad_array_out[i].comp_mrd_offset =
+ emad_array_in[i].comp_mrd_offset +
+ (mrd_out_offset - mrd_in_offset);
+ }
+
+ /* Verify that we stay within bound of the memory descriptors. */
+ if ((uintptr_t)((uint8_t *) mrd_in + mrd_size) >
+ (uintptr_t)((uint8_t *) mtd_orig + orig->desc_size) ||
+ ((uintptr_t)((uint8_t *) mrd_out + mrd_size) >
+ (uintptr_t)((uint8_t *) out + out_obj->desc_size))) {
+ ERROR("%s: Invalid mrd structure.\n", __func__);
+ return false;
+ }
+
+ /* Copy the mrd descriptors directly. */
+ memcpy(mrd_out, mrd_in, mrd_size);
+
+ return true;
+}
+
+/**
+ * spmc_shm_convert_mtd_to_v1_0 - Converts a given v1.1 memory object to
+ * v1.0 memory object.
+ * @out_obj: The shared memory object to populate the v1.0 descriptor.
+ * @orig: The shared memory object containing the v1.1 descriptor.
+ *
+ * Return: true if the conversion is successful else false.
+ */
+static bool
+spmc_shm_convert_mtd_to_v1_0(struct spmc_shmem_obj *out_obj,
+ struct spmc_shmem_obj *orig)
+{
+ struct ffa_mtd *mtd_orig = &orig->desc;
+ struct ffa_mtd_v1_0 *out = (struct ffa_mtd_v1_0 *) &out_obj->desc;
+ struct ffa_emad_v1_0 *emad_in;
+ struct ffa_emad_v1_0 *emad_array_in;
+ struct ffa_emad_v1_0 *emad_array_out;
+ struct ffa_comp_mrd *mrd_in;
+ struct ffa_comp_mrd *mrd_out;
+
+ size_t mrd_in_offset;
+ size_t mrd_out_offset;
+ size_t emad_out_array_size;
+ size_t mrd_size = 0;
+
+ /* Populate the v1.0 descriptor format from the v1.1 struct. */
+ out->sender_id = mtd_orig->sender_id;
+ out->memory_region_attributes = mtd_orig->memory_region_attributes;
+ out->flags = mtd_orig->flags;
+ out->handle = mtd_orig->handle;
+ out->tag = mtd_orig->tag;
+ out->emad_count = mtd_orig->emad_count;
+
+ /* Determine the location of the emad array in both descriptors. */
+ emad_array_in = (struct ffa_emad_v1_0 *)
+ ((uint8_t *) mtd_orig + mtd_orig->emad_offset);
+ emad_array_out = out->emad;
+
+ /* Copy across the emad structs. */
+ emad_in = emad_array_in;
+ for (unsigned int i = 0U; i < out->emad_count; i++) {
+ memcpy(&emad_array_out[i], emad_in,
+ sizeof(struct ffa_emad_v1_0));
+
+ emad_in += mtd_orig->emad_size;
+ }
+
+ /* Place the mrd descriptors after the end of the emad descriptors. */
+ emad_out_array_size = sizeof(struct ffa_emad_v1_0) * out->emad_count;
+
+ mrd_out_offset = (uint8_t *) out->emad - (uint8_t *) out +
+ emad_out_array_size;
+
+ mrd_out = (struct ffa_comp_mrd *) ((uint8_t *) out + mrd_out_offset);
+
+ mrd_in_offset = mtd_orig->emad_offset +
+ (mtd_orig->emad_size * mtd_orig->emad_count);
+
+ /* Add the size of the composite memory region descriptor. */
+ mrd_size += sizeof(struct ffa_comp_mrd);
+
+ /* Find the mrd descriptor. */
+ mrd_in = (struct ffa_comp_mrd *) ((uint8_t *) mtd_orig + mrd_in_offset);
+
+ /* Add the size of the constituent memory region descriptors. */
+ mrd_size += mrd_in->address_range_count * sizeof(struct ffa_cons_mrd);
+
+ /*
+ * Update the offset in the emads by the delta between the input and
+ * output addresses.
+ */
+ emad_in = emad_array_in;
+
+ for (unsigned int i = 0U; i < out->emad_count; i++) {
+ emad_array_out[i].comp_mrd_offset = emad_in->comp_mrd_offset +
+ (mrd_out_offset -
+ mrd_in_offset);
+ emad_in += mtd_orig->emad_size;
+ }
+
+ /* Verify that we stay within bound of the memory descriptors. */
+ if ((uintptr_t)((uint8_t *) mrd_in + mrd_size) >
+ (uintptr_t)((uint8_t *) mtd_orig + orig->desc_size) ||
+ ((uintptr_t)((uint8_t *) mrd_out + mrd_size) >
+ (uintptr_t)((uint8_t *) out + out_obj->desc_size))) {
+ ERROR("%s: Invalid mrd structure.\n", __func__);
+ return false;
+ }
+
+ /* Copy the mrd descriptors directly. */
+ memcpy(mrd_out, mrd_in, mrd_size);
+
+ return true;
+}
+
+/**
+ * spmc_populate_ffa_v1_0_descriptor - Converts a given v1.1 memory object to
+ * the v1.0 format and populates the
+ * provided buffer.
+ * @dst: Buffer to populate v1.0 ffa_memory_region_descriptor.
+ * @orig_obj: Object containing v1.1 ffa_memory_region_descriptor.
+ * @buf_size: Size of the buffer to populate.
+ * @offset: The offset of the converted descriptor to copy.
+ * @copy_size: Will be populated with the number of bytes copied.
+ * @out_desc_size: Will be populated with the total size of the v1.0
+ * descriptor.
+ *
+ * Return: 0 if conversion and population succeeded.
+ * Note: This function invalidates the reference to @orig therefore
+ * `spmc_shmem_obj_lookup` must be called if further usage is required.
+ */
+static uint32_t
+spmc_populate_ffa_v1_0_descriptor(void *dst, struct spmc_shmem_obj *orig_obj,
+ size_t buf_size, size_t offset,
+ size_t *copy_size, size_t *v1_0_desc_size)
+{
+ struct spmc_shmem_obj *v1_0_obj;
+
+ /* Calculate the size that the v1.0 descriptor will require. */
+ *v1_0_desc_size = spmc_shm_get_v1_0_descriptor_size(
+ &orig_obj->desc, orig_obj->desc_size);
+
+ if (*v1_0_desc_size == 0) {
+ ERROR("%s: cannot determine size of descriptor.\n",
+ __func__);
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
+
+ /* Get a new obj to store the v1.0 descriptor. */
+ v1_0_obj = spmc_shmem_obj_alloc(&spmc_shmem_obj_state,
+ *v1_0_desc_size);
+
+ if (!v1_0_obj) {
+ return FFA_ERROR_NO_MEMORY;
+ }
+
+ /* Perform the conversion from v1.1 to v1.0. */
+ if (!spmc_shm_convert_mtd_to_v1_0(v1_0_obj, orig_obj)) {
+ spmc_shmem_obj_free(&spmc_shmem_obj_state, v1_0_obj);
+ return FFA_ERROR_INVALID_PARAMETER;
+ }
+
+ *copy_size = MIN(v1_0_obj->desc_size - offset, buf_size);
+ memcpy(dst, (uint8_t *) &v1_0_obj->desc + offset, *copy_size);
+
+ /*
+ * We're finished with the v1.0 descriptor for now so free it.
+ * Note that this will invalidate any references to the v1.1
+ * descriptor.
+ */
+ spmc_shmem_obj_free(&spmc_shmem_obj_state, v1_0_obj);
+
+ return 0;
+}
+
+/**
+ * spmc_shmem_check_obj - Check that counts in descriptor match overall size.
+ * @obj: Object containing ffa_memory_region_descriptor.
+ * @ffa_version: FF-A version of the provided descriptor.
+ *
+ * Return: 0 if object is valid, -EINVAL if constituent_memory_region_descriptor
+ * offset or count is invalid.
+ */
+static int spmc_shmem_check_obj(struct spmc_shmem_obj *obj,
+ uint32_t ffa_version)
+{
+ uint32_t comp_mrd_offset = 0;
+
+ if (obj->desc.emad_count == 0U) {
+ WARN("%s: unsupported attribute desc count %u.\n",
+ __func__, obj->desc.emad_count);
+ return -EINVAL;
+ }
+
+ for (size_t emad_num = 0; emad_num < obj->desc.emad_count; emad_num++) {
+ size_t size;
+ size_t count;
+ size_t expected_size;
+ size_t total_page_count;
+ size_t emad_size;
+ size_t desc_size;
+ size_t header_emad_size;
+ uint32_t offset;
+ struct ffa_comp_mrd *comp;
+ struct ffa_emad_v1_0 *emad;
+
+ emad = spmc_shmem_obj_get_emad(&obj->desc, emad_num,
+ ffa_version, &emad_size);
+ if (emad == NULL) {
+ WARN("%s: invalid emad structure.\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * Validate the calculated emad address resides within the
+ * descriptor.
+ */
+ if ((uintptr_t) emad >=
+ (uintptr_t)((uint8_t *) &obj->desc + obj->desc_size)) {
+ WARN("Invalid emad access.\n");
+ return -EINVAL;
+ }
+
+ offset = emad->comp_mrd_offset;
+
+ if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+ desc_size = sizeof(struct ffa_mtd_v1_0);
+ } else {
+ desc_size = sizeof(struct ffa_mtd);
+ }
+
+ header_emad_size = desc_size +
+ (obj->desc.emad_count * emad_size);
+
+ if (offset < header_emad_size) {
+ WARN("%s: invalid object, offset %u < header + emad %zu\n",
+ __func__, offset, header_emad_size);
+ return -EINVAL;
+ }
+
+ size = obj->desc_size;
+
+ if (offset > size) {
+ WARN("%s: invalid object, offset %u > total size %zu\n",
+ __func__, offset, obj->desc_size);
+ return -EINVAL;
+ }
+ size -= offset;
+
+ if (size < sizeof(struct ffa_comp_mrd)) {
+ WARN("%s: invalid object, offset %u, total size %zu, no header space.\n",
+ __func__, offset, obj->desc_size);
+ return -EINVAL;
+ }
+ size -= sizeof(struct ffa_comp_mrd);
+
+ count = size / sizeof(struct ffa_cons_mrd);
+
+ comp = spmc_shmem_obj_get_comp_mrd(obj, ffa_version);
+
+ if (comp == NULL) {
+ WARN("%s: invalid comp_mrd offset\n", __func__);
+ return -EINVAL;
+ }
+
+ if (comp->address_range_count != count) {
+ WARN("%s: invalid object, desc count %u != %zu\n",
+ __func__, comp->address_range_count, count);
+ return -EINVAL;
+ }
+
+ expected_size = offset + sizeof(*comp) +
+ spmc_shmem_obj_ffa_constituent_size(obj,
+ ffa_version);
+
+ if (expected_size != obj->desc_size) {
+ WARN("%s: invalid object, computed size %zu != size %zu\n",
+ __func__, expected_size, obj->desc_size);
+ return -EINVAL;
+ }
+
+ if (obj->desc_filled < obj->desc_size) {
+ /*
+ * The whole descriptor has not yet been received.
+ * Skip final checks.
+ */
+ return 0;
+ }
+
+ /*
+ * The offset provided to the composite memory region descriptor
+ * should be consistent across endpoint descriptors. Store the
+ * first entry and compare against subsequent entries.
+ */
+ if (comp_mrd_offset == 0) {
+ comp_mrd_offset = offset;
+ } else {
+ if (comp_mrd_offset != offset) {
+ ERROR("%s: mismatching offsets provided, %u != %u\n",
+ __func__, offset, comp_mrd_offset);
+ return -EINVAL;
+ }
+ }
+
+ total_page_count = 0;
+
+ for (size_t i = 0; i < count; i++) {
+ total_page_count +=
+ comp->address_range_array[i].page_count;
+ }
+ if (comp->total_page_count != total_page_count) {
+ WARN("%s: invalid object, desc total_page_count %u != %zu\n",
+ __func__, comp->total_page_count,
+ total_page_count);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+/**
+ * spmc_shmem_check_state_obj - Check if the descriptor describes memory
+ * regions that are currently involved with an
+ * existing memory transactions. This implies that
+ * the memory is not in a valid state for lending.
+ * @obj: Object containing ffa_memory_region_descriptor.
+ *
+ * Return: 0 if object is valid, -EINVAL if invalid memory state.
+ */
+static int spmc_shmem_check_state_obj(struct spmc_shmem_obj *obj,
+ uint32_t ffa_version)
+{
+ size_t obj_offset = 0;
+ struct spmc_shmem_obj *inflight_obj;
+
+ struct ffa_comp_mrd *other_mrd;
+ struct ffa_comp_mrd *requested_mrd = spmc_shmem_obj_get_comp_mrd(obj,
+ ffa_version);
+
+ if (requested_mrd == NULL) {
+ return -EINVAL;
+ }
+
+ inflight_obj = spmc_shmem_obj_get_next(&spmc_shmem_obj_state,
+ &obj_offset);
+
+ while (inflight_obj != NULL) {
+ /*
+ * Don't compare the transaction to itself or to partially
+ * transmitted descriptors.
+ */
+ if ((obj->desc.handle != inflight_obj->desc.handle) &&
+ (obj->desc_size == obj->desc_filled)) {
+ other_mrd = spmc_shmem_obj_get_comp_mrd(inflight_obj,
+ FFA_VERSION_COMPILED);
+ if (other_mrd == NULL) {
+ return -EINVAL;
+ }
+ if (overlapping_memory_regions(requested_mrd,
+ other_mrd)) {
+ return -EINVAL;
+ }
+ }
+
+ inflight_obj = spmc_shmem_obj_get_next(&spmc_shmem_obj_state,
+ &obj_offset);
+ }
+ return 0;
+}
+
+static long spmc_ffa_fill_desc(struct mailbox *mbox,
+ struct spmc_shmem_obj *obj,
+ uint32_t fragment_length,
+ ffa_mtd_flag32_t mtd_flag,
+ uint32_t ffa_version,
+ void *smc_handle)
+{
+ int ret;
+ size_t emad_size;
+ uint32_t handle_low;
+ uint32_t handle_high;
+ struct ffa_emad_v1_0 *emad;
+ struct ffa_emad_v1_0 *other_emad;
+
+ if (mbox->rxtx_page_count == 0U) {
+ WARN("%s: buffer pair not registered.\n", __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_arg;
+ }
+
+ if (fragment_length > mbox->rxtx_page_count * PAGE_SIZE_4KB) {
+ WARN("%s: bad fragment size %u > %u buffer size\n", __func__,
+ fragment_length, mbox->rxtx_page_count * PAGE_SIZE_4KB);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_arg;
+ }
+
+ memcpy((uint8_t *)&obj->desc + obj->desc_filled,
+ (uint8_t *) mbox->tx_buffer, fragment_length);
+
+ if (fragment_length > obj->desc_size - obj->desc_filled) {
+ WARN("%s: bad fragment size %u > %zu remaining\n", __func__,
+ fragment_length, obj->desc_size - obj->desc_filled);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_arg;
+ }
+
+ /* Ensure that the sender ID resides in the normal world. */
+ if (ffa_is_secure_world_id(obj->desc.sender_id)) {
+ WARN("%s: Invalid sender ID 0x%x.\n",
+ __func__, obj->desc.sender_id);
+ ret = FFA_ERROR_DENIED;
+ goto err_arg;
+ }
+
+ /* Ensure the NS bit is set to 0. */
+ if ((obj->desc.memory_region_attributes & FFA_MEM_ATTR_NS_BIT) != 0U) {
+ WARN("%s: NS mem attributes flags MBZ.\n", __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_arg;
+ }
+
+ /*
+ * We don't currently support any optional flags so ensure none are
+ * requested.
+ */
+ if (obj->desc.flags != 0U && mtd_flag != 0U &&
+ (obj->desc.flags != mtd_flag)) {
+ WARN("%s: invalid memory transaction flags %u != %u\n",
+ __func__, obj->desc.flags, mtd_flag);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_arg;
+ }
+
+ if (obj->desc_filled == 0U) {
+ /* First fragment, descriptor header has been copied */
+ obj->desc.handle = spmc_shmem_obj_state.next_handle++;
+ obj->desc.flags |= mtd_flag;
+ }
+
+ obj->desc_filled += fragment_length;
+ ret = spmc_shmem_check_obj(obj, ffa_version);
+ if (ret != 0) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_bad_desc;
+ }
+
+ handle_low = (uint32_t)obj->desc.handle;
+ handle_high = obj->desc.handle >> 32;
+
+ if (obj->desc_filled != obj->desc_size) {
+ SMC_RET8(smc_handle, FFA_MEM_FRAG_RX, handle_low,
+ handle_high, obj->desc_filled,
+ (uint32_t)obj->desc.sender_id << 16, 0, 0, 0);
+ }
+
+ /* The full descriptor has been received, perform any final checks. */
+
+ /*
+ * If a partition ID resides in the secure world validate that the
+ * partition ID is for a known partition. Ignore any partition ID
+ * belonging to the normal world as it is assumed the Hypervisor will
+ * have validated these.
+ */
+ for (size_t i = 0; i < obj->desc.emad_count; i++) {
+ emad = spmc_shmem_obj_get_emad(&obj->desc, i, ffa_version,
+ &emad_size);
+ if (emad == NULL) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_bad_desc;
+ }
+
+ ffa_endpoint_id16_t ep_id = emad->mapd.endpoint_id;
+
+ if (ffa_is_secure_world_id(ep_id)) {
+ if (spmc_get_sp_ctx(ep_id) == NULL) {
+ WARN("%s: Invalid receiver id 0x%x\n",
+ __func__, ep_id);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_bad_desc;
+ }
+ }
+ }
+
+ /* Ensure partition IDs are not duplicated. */
+ for (size_t i = 0; i < obj->desc.emad_count; i++) {
+ emad = spmc_shmem_obj_get_emad(&obj->desc, i, ffa_version,
+ &emad_size);
+ if (emad == NULL) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_bad_desc;
+ }
+ for (size_t j = i + 1; j < obj->desc.emad_count; j++) {
+ other_emad = spmc_shmem_obj_get_emad(&obj->desc, j,
+ ffa_version,
+ &emad_size);
+ if (other_emad == NULL) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_bad_desc;
+ }
+
+ if (emad->mapd.endpoint_id ==
+ other_emad->mapd.endpoint_id) {
+ WARN("%s: Duplicated endpoint id 0x%x\n",
+ __func__, emad->mapd.endpoint_id);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_bad_desc;
+ }
+ }
+ }
+
+ ret = spmc_shmem_check_state_obj(obj, ffa_version);
+ if (ret) {
+ ERROR("%s: invalid memory region descriptor.\n", __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_bad_desc;
+ }
+
+ /*
+ * Everything checks out, if the sender was using FF-A v1.0, convert
+ * the descriptor format to use the v1.1 structures.
+ */
+ if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+ struct spmc_shmem_obj *v1_1_obj;
+ uint64_t mem_handle;
+
+ /* Calculate the size that the v1.1 descriptor will required. */
+ size_t v1_1_desc_size =
+ spmc_shm_get_v1_1_descriptor_size((void *) &obj->desc,
+ fragment_length);
+
+ if (v1_1_desc_size == 0U) {
+ ERROR("%s: cannot determine size of descriptor.\n",
+ __func__);
+ goto err_arg;
+ }
+
+ /* Get a new obj to store the v1.1 descriptor. */
+ v1_1_obj =
+ spmc_shmem_obj_alloc(&spmc_shmem_obj_state, v1_1_desc_size);
+
+ if (!obj) {
+ ret = FFA_ERROR_NO_MEMORY;
+ goto err_arg;
+ }
+
+ /* Perform the conversion from v1.0 to v1.1. */
+ v1_1_obj->desc_size = v1_1_desc_size;
+ v1_1_obj->desc_filled = v1_1_desc_size;
+ if (!spmc_shm_convert_shmem_obj_from_v1_0(v1_1_obj, obj)) {
+ ERROR("%s: Could not convert mtd!\n", __func__);
+ spmc_shmem_obj_free(&spmc_shmem_obj_state, v1_1_obj);
+ goto err_arg;
+ }
+
+ /*
+ * We're finished with the v1.0 descriptor so free it
+ * and continue our checks with the new v1.1 descriptor.
+ */
+ mem_handle = obj->desc.handle;
+ spmc_shmem_obj_free(&spmc_shmem_obj_state, obj);
+ obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle);
+ if (obj == NULL) {
+ ERROR("%s: Failed to find converted descriptor.\n",
+ __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ return spmc_ffa_error_return(smc_handle, ret);
+ }
+ }
+
+ /* Allow for platform specific operations to be performed. */
+ ret = plat_spmc_shmem_begin(&obj->desc);
+ if (ret != 0) {
+ goto err_arg;
+ }
+
+ SMC_RET8(smc_handle, FFA_SUCCESS_SMC32, 0, handle_low, handle_high, 0,
+ 0, 0, 0);
+
+err_bad_desc:
+err_arg:
+ spmc_shmem_obj_free(&spmc_shmem_obj_state, obj);
+ return spmc_ffa_error_return(smc_handle, ret);
+}
+
+/**
+ * spmc_ffa_mem_send - FFA_MEM_SHARE/LEND implementation.
+ * @client: Client state.
+ * @total_length: Total length of shared memory descriptor.
+ * @fragment_length: Length of fragment of shared memory descriptor passed in
+ * this call.
+ * @address: Not supported, must be 0.
+ * @page_count: Not supported, must be 0.
+ * @smc_handle: Handle passed to smc call. Used to return
+ * FFA_MEM_FRAG_RX or SMC_FC_FFA_SUCCESS.
+ *
+ * Implements a subset of the FF-A FFA_MEM_SHARE and FFA_MEM_LEND calls needed
+ * to share or lend memory from non-secure os to secure os (with no stream
+ * endpoints).
+ *
+ * Return: 0 on success, error code on failure.
+ */
+long spmc_ffa_mem_send(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t total_length,
+ uint32_t fragment_length,
+ uint64_t address,
+ uint32_t page_count,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+
+{
+ long ret;
+ struct spmc_shmem_obj *obj;
+ struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
+ ffa_mtd_flag32_t mtd_flag;
+ uint32_t ffa_version = get_partition_ffa_version(secure_origin);
+
+ if (address != 0U || page_count != 0U) {
+ WARN("%s: custom memory region for message not supported.\n",
+ __func__);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ if (secure_origin) {
+ WARN("%s: unsupported share direction.\n", __func__);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ /*
+ * Check if the descriptor is smaller than the v1.0 descriptor. The
+ * descriptor cannot be smaller than this structure.
+ */
+ if (fragment_length < sizeof(struct ffa_mtd_v1_0)) {
+ WARN("%s: bad first fragment size %u < %zu\n",
+ __func__, fragment_length, sizeof(struct ffa_mtd_v1_0));
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ if ((smc_fid & FUNCID_NUM_MASK) == FFA_FNUM_MEM_SHARE) {
+ mtd_flag = FFA_MTD_FLAG_TYPE_SHARE_MEMORY;
+ } else if ((smc_fid & FUNCID_NUM_MASK) == FFA_FNUM_MEM_LEND) {
+ mtd_flag = FFA_MTD_FLAG_TYPE_LEND_MEMORY;
+ } else {
+ WARN("%s: invalid memory management operation.\n", __func__);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ spin_lock(&spmc_shmem_obj_state.lock);
+ obj = spmc_shmem_obj_alloc(&spmc_shmem_obj_state, total_length);
+ if (obj == NULL) {
+ ret = FFA_ERROR_NO_MEMORY;
+ goto err_unlock;
+ }
+
+ spin_lock(&mbox->lock);
+ ret = spmc_ffa_fill_desc(mbox, obj, fragment_length, mtd_flag,
+ ffa_version, handle);
+ spin_unlock(&mbox->lock);
+
+ spin_unlock(&spmc_shmem_obj_state.lock);
+ return ret;
+
+err_unlock:
+ spin_unlock(&spmc_shmem_obj_state.lock);
+ return spmc_ffa_error_return(handle, ret);
+}
+
+/**
+ * spmc_ffa_mem_frag_tx - FFA_MEM_FRAG_TX implementation.
+ * @client: Client state.
+ * @handle_low: Handle_low value returned from FFA_MEM_FRAG_RX.
+ * @handle_high: Handle_high value returned from FFA_MEM_FRAG_RX.
+ * @fragment_length: Length of fragments transmitted.
+ * @sender_id: Vmid of sender in bits [31:16]
+ * @smc_handle: Handle passed to smc call. Used to return
+ * FFA_MEM_FRAG_RX or SMC_FC_FFA_SUCCESS.
+ *
+ * Return: @smc_handle on success, error code on failure.
+ */
+long spmc_ffa_mem_frag_tx(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t handle_low,
+ uint64_t handle_high,
+ uint32_t fragment_length,
+ uint32_t sender_id,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ long ret;
+ uint32_t desc_sender_id;
+ uint32_t ffa_version = get_partition_ffa_version(secure_origin);
+ struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
+
+ struct spmc_shmem_obj *obj;
+ uint64_t mem_handle = handle_low | (((uint64_t)handle_high) << 32);
+
+ spin_lock(&spmc_shmem_obj_state.lock);
+
+ obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle);
+ if (obj == NULL) {
+ WARN("%s: invalid handle, 0x%lx, not a valid handle.\n",
+ __func__, mem_handle);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock;
+ }
+
+ desc_sender_id = (uint32_t)obj->desc.sender_id << 16;
+ if (sender_id != desc_sender_id) {
+ WARN("%s: invalid sender_id 0x%x != 0x%x\n", __func__,
+ sender_id, desc_sender_id);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock;
+ }
+
+ if (obj->desc_filled == obj->desc_size) {
+ WARN("%s: object desc already filled, %zu\n", __func__,
+ obj->desc_filled);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock;
+ }
+
+ spin_lock(&mbox->lock);
+ ret = spmc_ffa_fill_desc(mbox, obj, fragment_length, 0, ffa_version,
+ handle);
+ spin_unlock(&mbox->lock);
+
+ spin_unlock(&spmc_shmem_obj_state.lock);
+ return ret;
+
+err_unlock:
+ spin_unlock(&spmc_shmem_obj_state.lock);
+ return spmc_ffa_error_return(handle, ret);
+}
+
+/**
+ * spmc_ffa_mem_retrieve_set_ns_bit - Set the NS bit in the response descriptor
+ * if the caller implements a version greater
+ * than FF-A 1.0 or if they have requested
+ * the functionality.
+ * TODO: We are assuming that the caller is
+ * an SP. To support retrieval from the
+ * normal world this function will need to be
+ * expanded accordingly.
+ * @resp: Descriptor populated in callers RX buffer.
+ * @sp_ctx: Context of the calling SP.
+ */
+void spmc_ffa_mem_retrieve_set_ns_bit(struct ffa_mtd *resp,
+ struct secure_partition_desc *sp_ctx)
+{
+ if (sp_ctx->ffa_version > MAKE_FFA_VERSION(1, 0) ||
+ sp_ctx->ns_bit_requested) {
+ /*
+ * Currently memory senders must reside in the normal
+ * world, and we do not have the functionlaity to change
+ * the state of memory dynamically. Therefore we can always set
+ * the NS bit to 1.
+ */
+ resp->memory_region_attributes |= FFA_MEM_ATTR_NS_BIT;
+ }
+}
+
+/**
+ * spmc_ffa_mem_retrieve_req - FFA_MEM_RETRIEVE_REQ implementation.
+ * @smc_fid: FID of SMC
+ * @total_length: Total length of retrieve request descriptor if this is
+ * the first call. Otherwise (unsupported) must be 0.
+ * @fragment_length: Length of fragment of retrieve request descriptor passed
+ * in this call. Only @fragment_length == @length is
+ * supported by this implementation.
+ * @address: Not supported, must be 0.
+ * @page_count: Not supported, must be 0.
+ * @smc_handle: Handle passed to smc call. Used to return
+ * FFA_MEM_RETRIEVE_RESP.
+ *
+ * Implements a subset of the FF-A FFA_MEM_RETRIEVE_REQ call.
+ * Used by secure os to retrieve memory already shared by non-secure os.
+ * If the data does not fit in a single FFA_MEM_RETRIEVE_RESP message,
+ * the client must call FFA_MEM_FRAG_RX until the full response has been
+ * received.
+ *
+ * Return: @handle on success, error code on failure.
+ */
+long
+spmc_ffa_mem_retrieve_req(uint32_t smc_fid,
+ bool secure_origin,
+ uint32_t total_length,
+ uint32_t fragment_length,
+ uint64_t address,
+ uint32_t page_count,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ int ret;
+ size_t buf_size;
+ size_t copy_size = 0;
+ size_t min_desc_size;
+ size_t out_desc_size = 0;
+
+ /*
+ * Currently we are only accessing fields that are the same in both the
+ * v1.0 and v1.1 mtd struct therefore we can use a v1.1 struct directly
+ * here. We only need validate against the appropriate struct size.
+ */
+ struct ffa_mtd *resp;
+ const struct ffa_mtd *req;
+ struct spmc_shmem_obj *obj = NULL;
+ struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
+ uint32_t ffa_version = get_partition_ffa_version(secure_origin);
+ struct secure_partition_desc *sp_ctx = spmc_get_current_sp_ctx();
+
+ if (!secure_origin) {
+ WARN("%s: unsupported retrieve req direction.\n", __func__);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ if (address != 0U || page_count != 0U) {
+ WARN("%s: custom memory region not supported.\n", __func__);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ spin_lock(&mbox->lock);
+
+ req = mbox->tx_buffer;
+ resp = mbox->rx_buffer;
+ buf_size = mbox->rxtx_page_count * FFA_PAGE_SIZE;
+
+ if (mbox->rxtx_page_count == 0U) {
+ WARN("%s: buffer pair not registered.\n", __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_mailbox;
+ }
+
+ if (mbox->state != MAILBOX_STATE_EMPTY) {
+ WARN("%s: RX Buffer is full! %d\n", __func__, mbox->state);
+ ret = FFA_ERROR_DENIED;
+ goto err_unlock_mailbox;
+ }
+
+ if (fragment_length != total_length) {
+ WARN("%s: fragmented retrieve request not supported.\n",
+ __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_mailbox;
+ }
+
+ if (req->emad_count == 0U) {
+ WARN("%s: unsupported attribute desc count %u.\n",
+ __func__, obj->desc.emad_count);
+ return -EINVAL;
+ }
+
+ /* Determine the appropriate minimum descriptor size. */
+ if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+ min_desc_size = sizeof(struct ffa_mtd_v1_0);
+ } else {
+ min_desc_size = sizeof(struct ffa_mtd);
+ }
+ if (total_length < min_desc_size) {
+ WARN("%s: invalid length %u < %zu\n", __func__, total_length,
+ min_desc_size);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_mailbox;
+ }
+
+ spin_lock(&spmc_shmem_obj_state.lock);
+
+ obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, req->handle);
+ if (obj == NULL) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ if (obj->desc_filled != obj->desc_size) {
+ WARN("%s: incomplete object desc filled %zu < size %zu\n",
+ __func__, obj->desc_filled, obj->desc_size);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ if (req->emad_count != 0U && req->sender_id != obj->desc.sender_id) {
+ WARN("%s: wrong sender id 0x%x != 0x%x\n",
+ __func__, req->sender_id, obj->desc.sender_id);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ if (req->emad_count != 0U && req->tag != obj->desc.tag) {
+ WARN("%s: wrong tag 0x%lx != 0x%lx\n",
+ __func__, req->tag, obj->desc.tag);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ if (req->emad_count != 0U && req->emad_count != obj->desc.emad_count) {
+ WARN("%s: mistmatch of endpoint counts %u != %u\n",
+ __func__, req->emad_count, obj->desc.emad_count);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ /* Ensure the NS bit is set to 0 in the request. */
+ if ((req->memory_region_attributes & FFA_MEM_ATTR_NS_BIT) != 0U) {
+ WARN("%s: NS mem attributes flags MBZ.\n", __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ if (req->flags != 0U) {
+ if ((req->flags & FFA_MTD_FLAG_TYPE_MASK) !=
+ (obj->desc.flags & FFA_MTD_FLAG_TYPE_MASK)) {
+ /*
+ * If the retrieve request specifies the memory
+ * transaction ensure it matches what we expect.
+ */
+ WARN("%s: wrong mem transaction flags %x != %x\n",
+ __func__, req->flags, obj->desc.flags);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ if (req->flags != FFA_MTD_FLAG_TYPE_SHARE_MEMORY &&
+ req->flags != FFA_MTD_FLAG_TYPE_LEND_MEMORY) {
+ /*
+ * Current implementation does not support donate and
+ * it supports no other flags.
+ */
+ WARN("%s: invalid flags 0x%x\n", __func__, req->flags);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+ }
+
+ /* Validate the caller is a valid participant. */
+ if (!spmc_shmem_obj_validate_id(&obj->desc, sp_ctx->sp_id)) {
+ WARN("%s: Invalid endpoint ID (0x%x).\n",
+ __func__, sp_ctx->sp_id);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ /* Validate that the provided emad offset and structure is valid.*/
+ for (size_t i = 0; i < req->emad_count; i++) {
+ size_t emad_size;
+ struct ffa_emad_v1_0 *emad;
+
+ emad = spmc_shmem_obj_get_emad(req, i, ffa_version,
+ &emad_size);
+ if (emad == NULL) {
+ WARN("%s: invalid emad structure.\n", __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ if ((uintptr_t) emad >= (uintptr_t)
+ ((uint8_t *) req + total_length)) {
+ WARN("Invalid emad access.\n");
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+ }
+
+ /*
+ * Validate all the endpoints match in the case of multiple
+ * borrowers. We don't mandate that the order of the borrowers
+ * must match in the descriptors therefore check to see if the
+ * endpoints match in any order.
+ */
+ for (size_t i = 0; i < req->emad_count; i++) {
+ bool found = false;
+ size_t emad_size;
+ struct ffa_emad_v1_0 *emad;
+ struct ffa_emad_v1_0 *other_emad;
+
+ emad = spmc_shmem_obj_get_emad(req, i, ffa_version,
+ &emad_size);
+ if (emad == NULL) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ for (size_t j = 0; j < obj->desc.emad_count; j++) {
+ other_emad = spmc_shmem_obj_get_emad(
+ &obj->desc, j, MAKE_FFA_VERSION(1, 1),
+ &emad_size);
+
+ if (other_emad == NULL) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ if (req->emad_count &&
+ emad->mapd.endpoint_id ==
+ other_emad->mapd.endpoint_id) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ WARN("%s: invalid receiver id (0x%x).\n",
+ __func__, emad->mapd.endpoint_id);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+ }
+
+ mbox->state = MAILBOX_STATE_FULL;
+
+ if (req->emad_count != 0U) {
+ obj->in_use++;
+ }
+
+ /*
+ * If the caller is v1.0 convert the descriptor, otherwise copy
+ * directly.
+ */
+ if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+ ret = spmc_populate_ffa_v1_0_descriptor(resp, obj, buf_size, 0,
+ ©_size,
+ &out_desc_size);
+ if (ret != 0U) {
+ ERROR("%s: Failed to process descriptor.\n", __func__);
+ goto err_unlock_all;
+ }
+ } else {
+ copy_size = MIN(obj->desc_size, buf_size);
+ out_desc_size = obj->desc_size;
+
+ memcpy(resp, &obj->desc, copy_size);
+ }
+
+ /* Set the NS bit in the response if applicable. */
+ spmc_ffa_mem_retrieve_set_ns_bit(resp, sp_ctx);
+
+ spin_unlock(&spmc_shmem_obj_state.lock);
+ spin_unlock(&mbox->lock);
+
+ SMC_RET8(handle, FFA_MEM_RETRIEVE_RESP, out_desc_size,
+ copy_size, 0, 0, 0, 0, 0);
+
+err_unlock_all:
+ spin_unlock(&spmc_shmem_obj_state.lock);
+err_unlock_mailbox:
+ spin_unlock(&mbox->lock);
+ return spmc_ffa_error_return(handle, ret);
+}
+
+/**
+ * spmc_ffa_mem_frag_rx - FFA_MEM_FRAG_RX implementation.
+ * @client: Client state.
+ * @handle_low: Handle passed to &FFA_MEM_RETRIEVE_REQ. Bit[31:0].
+ * @handle_high: Handle passed to &FFA_MEM_RETRIEVE_REQ. Bit[63:32].
+ * @fragment_offset: Byte offset in descriptor to resume at.
+ * @sender_id: Bit[31:16]: Endpoint id of sender if client is a
+ * hypervisor. 0 otherwise.
+ * @smc_handle: Handle passed to smc call. Used to return
+ * FFA_MEM_FRAG_TX.
+ *
+ * Return: @smc_handle on success, error code on failure.
+ */
+long spmc_ffa_mem_frag_rx(uint32_t smc_fid,
+ bool secure_origin,
+ uint32_t handle_low,
+ uint32_t handle_high,
+ uint32_t fragment_offset,
+ uint32_t sender_id,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ int ret;
+ void *src;
+ size_t buf_size;
+ size_t copy_size;
+ size_t full_copy_size;
+ uint32_t desc_sender_id;
+ struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
+ uint64_t mem_handle = handle_low | (((uint64_t)handle_high) << 32);
+ struct spmc_shmem_obj *obj;
+ uint32_t ffa_version = get_partition_ffa_version(secure_origin);
+
+ if (!secure_origin) {
+ WARN("%s: can only be called from swld.\n",
+ __func__);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ spin_lock(&spmc_shmem_obj_state.lock);
+
+ obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle);
+ if (obj == NULL) {
+ WARN("%s: invalid handle, 0x%lx, not a valid handle.\n",
+ __func__, mem_handle);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_shmem;
+ }
+
+ desc_sender_id = (uint32_t)obj->desc.sender_id << 16;
+ if (sender_id != 0U && sender_id != desc_sender_id) {
+ WARN("%s: invalid sender_id 0x%x != 0x%x\n", __func__,
+ sender_id, desc_sender_id);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_shmem;
+ }
+
+ if (fragment_offset >= obj->desc_size) {
+ WARN("%s: invalid fragment_offset 0x%x >= 0x%zx\n",
+ __func__, fragment_offset, obj->desc_size);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_shmem;
+ }
+
+ spin_lock(&mbox->lock);
+
+ if (mbox->rxtx_page_count == 0U) {
+ WARN("%s: buffer pair not registered.\n", __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ if (mbox->state != MAILBOX_STATE_EMPTY) {
+ WARN("%s: RX Buffer is full!\n", __func__);
+ ret = FFA_ERROR_DENIED;
+ goto err_unlock_all;
+ }
+
+ buf_size = mbox->rxtx_page_count * FFA_PAGE_SIZE;
+
+ mbox->state = MAILBOX_STATE_FULL;
+
+ /*
+ * If the caller is v1.0 convert the descriptor, otherwise copy
+ * directly.
+ */
+ if (ffa_version == MAKE_FFA_VERSION(1, 0)) {
+ size_t out_desc_size;
+
+ ret = spmc_populate_ffa_v1_0_descriptor(mbox->rx_buffer, obj,
+ buf_size,
+ fragment_offset,
+ ©_size,
+ &out_desc_size);
+ if (ret != 0U) {
+ ERROR("%s: Failed to process descriptor.\n", __func__);
+ goto err_unlock_all;
+ }
+ } else {
+ full_copy_size = obj->desc_size - fragment_offset;
+ copy_size = MIN(full_copy_size, buf_size);
+
+ src = &obj->desc;
+
+ memcpy(mbox->rx_buffer, src + fragment_offset, copy_size);
+ }
+
+ spin_unlock(&mbox->lock);
+ spin_unlock(&spmc_shmem_obj_state.lock);
+
+ SMC_RET8(handle, FFA_MEM_FRAG_TX, handle_low, handle_high,
+ copy_size, sender_id, 0, 0, 0);
+
+err_unlock_all:
+ spin_unlock(&mbox->lock);
+err_unlock_shmem:
+ spin_unlock(&spmc_shmem_obj_state.lock);
+ return spmc_ffa_error_return(handle, ret);
+}
+
+/**
+ * spmc_ffa_mem_relinquish - FFA_MEM_RELINQUISH implementation.
+ * @client: Client state.
+ *
+ * Implements a subset of the FF-A FFA_MEM_RELINQUISH call.
+ * Used by secure os release previously shared memory to non-secure os.
+ *
+ * The handle to release must be in the client's (secure os's) transmit buffer.
+ *
+ * Return: 0 on success, error code on failure.
+ */
+int spmc_ffa_mem_relinquish(uint32_t smc_fid,
+ bool secure_origin,
+ uint32_t handle_low,
+ uint32_t handle_high,
+ uint32_t fragment_offset,
+ uint32_t sender_id,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ int ret;
+ struct mailbox *mbox = spmc_get_mbox_desc(secure_origin);
+ struct spmc_shmem_obj *obj;
+ const struct ffa_mem_relinquish_descriptor *req;
+ struct secure_partition_desc *sp_ctx = spmc_get_current_sp_ctx();
+
+ if (!secure_origin) {
+ WARN("%s: unsupported relinquish direction.\n", __func__);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ spin_lock(&mbox->lock);
+
+ if (mbox->rxtx_page_count == 0U) {
+ WARN("%s: buffer pair not registered.\n", __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_mailbox;
+ }
+
+ req = mbox->tx_buffer;
+
+ if (req->flags != 0U) {
+ WARN("%s: unsupported flags 0x%x\n", __func__, req->flags);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_mailbox;
+ }
+
+ if (req->endpoint_count == 0) {
+ WARN("%s: endpoint count cannot be 0.\n", __func__);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_mailbox;
+ }
+
+ spin_lock(&spmc_shmem_obj_state.lock);
+
+ obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, req->handle);
+ if (obj == NULL) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ /*
+ * Validate the endpoint ID was populated correctly. We don't currently
+ * support proxy endpoints so the endpoint count should always be 1.
+ */
+ if (req->endpoint_count != 1U) {
+ WARN("%s: unsupported endpoint count %u != 1\n", __func__,
+ req->endpoint_count);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ /* Validate provided endpoint ID matches the partition ID. */
+ if (req->endpoint_array[0] != sp_ctx->sp_id) {
+ WARN("%s: invalid endpoint ID %u != %u\n", __func__,
+ req->endpoint_array[0], sp_ctx->sp_id);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ /* Validate the caller is a valid participant. */
+ if (!spmc_shmem_obj_validate_id(&obj->desc, sp_ctx->sp_id)) {
+ WARN("%s: Invalid endpoint ID (0x%x).\n",
+ __func__, req->endpoint_array[0]);
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+
+ if (obj->in_use == 0U) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock_all;
+ }
+ obj->in_use--;
+
+ spin_unlock(&spmc_shmem_obj_state.lock);
+ spin_unlock(&mbox->lock);
+
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+
+err_unlock_all:
+ spin_unlock(&spmc_shmem_obj_state.lock);
+err_unlock_mailbox:
+ spin_unlock(&mbox->lock);
+ return spmc_ffa_error_return(handle, ret);
+}
+
+/**
+ * spmc_ffa_mem_reclaim - FFA_MEM_RECLAIM implementation.
+ * @client: Client state.
+ * @handle_low: Unique handle of shared memory object to reclaim. Bit[31:0].
+ * @handle_high: Unique handle of shared memory object to reclaim.
+ * Bit[63:32].
+ * @flags: Unsupported, ignored.
+ *
+ * Implements a subset of the FF-A FFA_MEM_RECLAIM call.
+ * Used by non-secure os reclaim memory previously shared with secure os.
+ *
+ * Return: 0 on success, error code on failure.
+ */
+int spmc_ffa_mem_reclaim(uint32_t smc_fid,
+ bool secure_origin,
+ uint32_t handle_low,
+ uint32_t handle_high,
+ uint32_t mem_flags,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ int ret;
+ struct spmc_shmem_obj *obj;
+ uint64_t mem_handle = handle_low | (((uint64_t)handle_high) << 32);
+
+ if (secure_origin) {
+ WARN("%s: unsupported reclaim direction.\n", __func__);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ if (mem_flags != 0U) {
+ WARN("%s: unsupported flags 0x%x\n", __func__, mem_flags);
+ return spmc_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+
+ spin_lock(&spmc_shmem_obj_state.lock);
+
+ obj = spmc_shmem_obj_lookup(&spmc_shmem_obj_state, mem_handle);
+ if (obj == NULL) {
+ ret = FFA_ERROR_INVALID_PARAMETER;
+ goto err_unlock;
+ }
+ if (obj->in_use != 0U) {
+ ret = FFA_ERROR_DENIED;
+ goto err_unlock;
+ }
+
+ /* Allow for platform specific operations to be performed. */
+ ret = plat_spmc_shmem_reclaim(&obj->desc);
+ if (ret != 0) {
+ goto err_unlock;
+ }
+
+ spmc_shmem_obj_free(&spmc_shmem_obj_state, obj);
+ spin_unlock(&spmc_shmem_obj_state.lock);
+
+ SMC_RET1(handle, FFA_SUCCESS_SMC32);
+
+err_unlock:
+ spin_unlock(&spmc_shmem_obj_state.lock);
+ return spmc_ffa_error_return(handle, ret);
+}
diff --git a/services/std_svc/spm/el3_spmc/spmc_shared_mem.h b/services/std_svc/spm/el3_spmc/spmc_shared_mem.h
new file mode 100644
index 0000000..839f7a1
--- /dev/null
+++ b/services/std_svc/spm/el3_spmc/spmc_shared_mem.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMC_SHARED_MEM_H
+#define SPMC_SHARED_MEM_H
+
+#include <services/el3_spmc_ffa_memory.h>
+
+/**
+ * struct ffa_mem_relinquish_descriptor - Relinquish request descriptor.
+ * @handle:
+ * Id of shared memory object to relinquish.
+ * @flags:
+ * If bit 0 is set clear memory after unmapping from borrower. Must be 0
+ * for share. Bit[1]: Time slicing. Not supported, must be 0. All other
+ * bits are reserved 0.
+ * @endpoint_count:
+ * Number of entries in @endpoint_array.
+ * @endpoint_array:
+ * Array of endpoint ids.
+ */
+struct ffa_mem_relinquish_descriptor {
+ uint64_t handle;
+ uint32_t flags;
+ uint32_t endpoint_count;
+ ffa_endpoint_id16_t endpoint_array[];
+};
+CASSERT(sizeof(struct ffa_mem_relinquish_descriptor) == 16,
+ assert_ffa_mem_relinquish_descriptor_size_mismatch);
+
+/**
+ * struct spmc_shmem_obj_state - Global state.
+ * @data: Backing store for spmc_shmem_obj objects.
+ * @data_size: The size allocated for the backing store.
+ * @allocated: Number of bytes allocated in @data.
+ * @next_handle: Handle used for next allocated object.
+ * @lock: Lock protecting all state in this file.
+ */
+struct spmc_shmem_obj_state {
+ uint8_t *data;
+ size_t data_size;
+ size_t allocated;
+ uint64_t next_handle;
+ spinlock_t lock;
+};
+
+extern struct spmc_shmem_obj_state spmc_shmem_obj_state;
+extern int plat_spmc_shmem_begin(struct ffa_mtd *desc);
+extern int plat_spmc_shmem_reclaim(struct ffa_mtd *desc);
+
+long spmc_ffa_mem_send(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t total_length,
+ uint32_t fragment_length,
+ uint64_t address,
+ uint32_t page_count,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
+
+long spmc_ffa_mem_frag_tx(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t handle_low,
+ uint64_t handle_high,
+ uint32_t fragment_length,
+ uint32_t sender_id,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
+
+long spmc_ffa_mem_retrieve_req(uint32_t smc_fid,
+ bool secure_origin,
+ uint32_t total_length,
+ uint32_t fragment_length,
+ uint64_t address,
+ uint32_t page_count,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
+
+long spmc_ffa_mem_frag_rx(uint32_t smc_fid,
+ bool secure_origin,
+ uint32_t handle_low,
+ uint32_t handle_high,
+ uint32_t fragment_offset,
+ uint32_t sender_id,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
+
+
+int spmc_ffa_mem_relinquish(uint32_t smc_fid,
+ bool secure_origin,
+ uint32_t handle_low,
+ uint32_t handle_high,
+ uint32_t fragment_offset,
+ uint32_t sender_id,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
+
+int spmc_ffa_mem_reclaim(uint32_t smc_fid,
+ bool secure_origin,
+ uint32_t handle_low,
+ uint32_t handle_high,
+ uint32_t mem_flags,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
+
+#endif /* SPMC_SHARED_MEM_H */
diff --git a/services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S b/services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
similarity index 97%
rename from services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S
rename to services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
index be4084c..836f75c 100644
--- a/services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S
+++ b/services/std_svc/spm/spm_mm/aarch64/spm_mm_shim_exceptions.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/services/std_svc/spm_mm/spm_mm.mk b/services/std_svc/spm/spm_mm/spm_mm.mk
similarity index 72%
rename from services/std_svc/spm_mm/spm_mm.mk
rename to services/std_svc/spm/spm_mm/spm_mm.mk
index a87bdd8..f6691c3 100644
--- a/services/std_svc/spm_mm/spm_mm.mk
+++ b/services/std_svc/spm/spm_mm/spm_mm.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -16,12 +16,14 @@
ifeq (${ENABLE_SME_FOR_NS},1)
$(error "Error: SPM_MM is not compatible with ENABLE_SME_FOR_NS")
endif
+ifeq (${CTX_INCLUDE_FPREGS},0)
+ $(warning "Warning: SPM_MM: CTX_INCLUDE_FPREGS is set to 0")
+endif
-SPM_SOURCES := $(addprefix services/std_svc/spm_mm/, \
- ${ARCH}/spm_mm_helpers.S \
+SPM_MM_SOURCES := $(addprefix services/std_svc/spm/spm_mm/, \
${ARCH}/spm_mm_shim_exceptions.S \
- spm_mm_main.c \
- spm_mm_setup.c \
+ spm_mm_main.c \
+ spm_mm_setup.c \
spm_mm_xlat.c)
diff --git a/services/std_svc/spm_mm/spm_mm_main.c b/services/std_svc/spm/spm_mm/spm_mm_main.c
similarity index 94%
rename from services/std_svc/spm_mm/spm_mm_main.c
rename to services/std_svc/spm/spm_mm/spm_mm_main.c
index 14c0038..8525cd2 100644
--- a/services/std_svc/spm_mm/spm_mm_main.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,6 +22,7 @@
#include <services/spm_mm_svc.h>
#include <smccc_helpers.h>
+#include "spm_common.h"
#include "spm_mm_private.h"
/*******************************************************************************
@@ -189,6 +190,14 @@
uint64_t rc;
sp_context_t *sp_ptr = &sp_ctx;
+#if CTX_INCLUDE_FPREGS
+ /*
+ * SP runs to completion, no need to restore FP registers of secure context.
+ * Save FP registers only for non secure context.
+ */
+ fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
+#endif
+
/* Wait until the Secure Partition is idle and set it to busy. */
sp_state_wait_switch(sp_ptr, SP_STATE_IDLE, SP_STATE_BUSY);
@@ -207,6 +216,14 @@
assert(sp_ptr->state == SP_STATE_BUSY);
sp_state_set(sp_ptr, SP_STATE_IDLE);
+#if CTX_INCLUDE_FPREGS
+ /*
+ * SP runs to completion, no need to save FP registers of secure context.
+ * Restore only non secure world FP registers.
+ */
+ fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
+#endif
+
return rc;
}
diff --git a/services/std_svc/spm_mm/spm_mm_private.h b/services/std_svc/spm/spm_mm/spm_mm_private.h
similarity index 88%
rename from services/std_svc/spm_mm/spm_mm_private.h
rename to services/std_svc/spm/spm_mm/spm_mm_private.h
index 45b4789..0eff1c0 100644
--- a/services/std_svc/spm_mm/spm_mm_private.h
+++ b/services/std_svc/spm/spm_mm/spm_mm_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,7 @@
#define SPM_MM_PRIVATE_H
#include <context.h>
+#include "spm_common.h"
/*******************************************************************************
* Constants that allow assembler code to preserve callee-saved registers of the
@@ -51,9 +52,6 @@
spinlock_t state_lock;
} sp_context_t;
-/* Assembly helpers */
-uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
-void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
void spm_sp_setup(sp_context_t *sp_ctx);
diff --git a/services/std_svc/spm_mm/spm_mm_setup.c b/services/std_svc/spm/spm_mm/spm_mm_setup.c
similarity index 98%
rename from services/std_svc/spm_mm/spm_mm_setup.c
rename to services/std_svc/spm/spm_mm/spm_mm_setup.c
index 9d681c2..04dc212 100644
--- a/services/std_svc/spm_mm/spm_mm_setup.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -19,6 +19,7 @@
#include <plat/common/platform.h>
#include <services/spm_mm_partition.h>
+#include "spm_common.h"
#include "spm_mm_private.h"
#include "spm_mm_shim_private.h"
diff --git a/services/std_svc/spm_mm/spm_mm_shim_private.h b/services/std_svc/spm/spm_mm/spm_mm_shim_private.h
similarity index 90%
rename from services/std_svc/spm_mm/spm_mm_shim_private.h
rename to services/std_svc/spm/spm_mm/spm_mm_shim_private.h
index 0c8d894..f69c748 100644
--- a/services/std_svc/spm_mm/spm_mm_shim_private.h
+++ b/services/std_svc/spm/spm_mm/spm_mm_shim_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/services/std_svc/spm_mm/spm_mm_xlat.c b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
similarity index 98%
rename from services/std_svc/spm_mm/spm_mm_xlat.c
rename to services/std_svc/spm/spm_mm/spm_mm_xlat.c
index eae597c..6261016 100644
--- a/services/std_svc/spm_mm/spm_mm_xlat.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_xlat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 27a8382..7e6c89d 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -24,6 +24,7 @@
#include <plat/common/platform.h>
#include <platform_def.h>
#include <services/ffa_svc.h>
+#include <services/spmc_svc.h>
#include <services/spmd_svc.h>
#include <smccc_helpers.h>
#include "spmd_private.h"
@@ -34,7 +35,8 @@
static spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
/*******************************************************************************
- * SPM Core attribute information read from its manifest.
+ * SPM Core attribute information is read from its manifest if the SPMC is not
+ * at EL3. Else, it is populated from the SPMC directly.
******************************************************************************/
static spmc_manifest_attribute_t spmc_attrs;
@@ -88,7 +90,9 @@
uint64_t x2,
uint64_t x3,
uint64_t x4,
- void *handle);
+ void *cookie,
+ void *handle,
+ uint64_t flags);
/******************************************************************************
* Builds an SPMD to SPMC direct message request.
@@ -385,8 +389,23 @@
******************************************************************************/
int spmd_setup(void)
{
- void *spmc_manifest;
int rc;
+ void *spmc_manifest;
+
+ /*
+ * If the SPMC is at EL3, then just initialise it directly. The
+ * shenanigans of when it is at a lower EL are not needed.
+ */
+ if (is_spmc_at_el3()) {
+ /* Allow the SPMC to populate its attributes directly. */
+ spmc_populate_attrs(&spmc_attrs);
+
+ rc = spmc_setup();
+ if (rc != 0) {
+ ERROR("SPMC initialisation failed 0x%x.\n", rc);
+ }
+ return rc;
+ }
spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
if (spmc_ep_info == NULL) {
@@ -417,15 +436,15 @@
}
/*******************************************************************************
- * Forward SMC to the other security state
+ * Forward FF-A SMCs to the other security state.
******************************************************************************/
-static uint64_t spmd_smc_forward(uint32_t smc_fid,
- bool secure_origin,
- uint64_t x1,
- uint64_t x2,
- uint64_t x3,
- uint64_t x4,
- void *handle)
+uint64_t spmd_smc_switch_state(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *handle)
{
unsigned int secure_state_in = (secure_origin) ? SECURE : NON_SECURE;
unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
@@ -458,6 +477,28 @@
}
/*******************************************************************************
+ * Forward SMCs to the other security state.
+ ******************************************************************************/
+static uint64_t spmd_smc_forward(uint32_t smc_fid,
+ bool secure_origin,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ if (is_spmc_at_el3() && !secure_origin) {
+ return spmc_smc_handler(smc_fid, secure_origin, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+ return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2, x3, x4,
+ handle);
+
+}
+
+/*******************************************************************************
* Return FFA_ERROR with specified error code
******************************************************************************/
static uint64_t spmd_ffa_error_return(void *handle, int error_code)
@@ -484,6 +525,10 @@
*****************************************************************************/
static bool spmd_is_spmc_message(unsigned int ep)
{
+ if (is_spmc_at_el3()) {
+ return false;
+ }
+
return ((ffa_endpoint_destination(ep) == SPMD_DIRECT_MSG_ENDPOINT_ID)
&& (ffa_endpoint_source(ep) == spmc_attrs.spmc_id));
}
@@ -502,6 +547,35 @@
}
/*******************************************************************************
+ * This function forwards FF-A SMCs to either the main SPMD handler or the
+ * SPMC at EL3, depending on the origin security state, if enabled.
+ ******************************************************************************/
+uint64_t spmd_ffa_smc_handler(uint32_t smc_fid,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ if (is_spmc_at_el3()) {
+ /*
+ * If we have an SPMC at EL3 allow handling of the SMC first.
+ * The SPMC will call back through to SPMD handler if required.
+ */
+ if (is_caller_secure(flags)) {
+ return spmc_smc_handler(smc_fid,
+ is_caller_secure(flags),
+ x1, x2, x3, x4, cookie,
+ handle, flags);
+ }
+ }
+ return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+ handle, flags);
+}
+
+/*******************************************************************************
* This function handles all SMCs in the range reserved for FFA. Each call is
* either forwarded to the other security state or handled by the SPM dispatcher
******************************************************************************/
@@ -542,7 +616,8 @@
}
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
break; /* not reached */
case FFA_VERSION:
@@ -551,13 +626,27 @@
* If caller is secure and SPMC was initialized,
* return FFA_VERSION of SPMD.
* If caller is non secure and SPMC was initialized,
- * return SPMC's version.
+ * forward to the EL3 SPMC if enabled, otherwise return
+ * the SPMC version if implemented at a lower EL.
* Sanity check to "input_version".
+ * If the EL3 SPMC is enabled, ignore the SPMC state as
+ * this is not used.
*/
if ((input_version & FFA_VERSION_BIT31_MASK) ||
- (ctx->state == SPMC_STATE_RESET)) {
+ (!is_spmc_at_el3() && (ctx->state == SPMC_STATE_RESET))) {
ret = FFA_ERROR_NOT_SUPPORTED;
} else if (!secure_origin) {
+ if (is_spmc_at_el3()) {
+ /*
+ * Forward the call directly to the EL3 SPMC, if
+ * enabled, as we don't need to wrap the call in
+ * a direct request.
+ */
+ return spmd_smc_forward(smc_fid, secure_origin,
+ x1, x2, x3, x4, cookie,
+ handle, flags);
+ }
+
gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
uint64_t rc;
@@ -595,7 +684,7 @@
(SMC_GET_GP(gpregs, CTX_GPREG_X0) !=
FFA_MSG_SEND_DIRECT_RESP_SMC32) ||
(SMC_GET_GP(gpregs, CTX_GPREG_X2) !=
- (SPMD_FWK_MSG_BIT |
+ (FFA_FWK_MSG_BIT |
SPMD_FWK_MSG_FFA_VERSION_RESP))) {
ERROR("Failed to forward FFA_VERSION\n");
ret = FFA_ERROR_NOT_SUPPORTED;
@@ -610,7 +699,8 @@
*/
return spmd_smc_forward(ret, true, FFA_PARAM_MBZ,
FFA_PARAM_MBZ, FFA_PARAM_MBZ,
- FFA_PARAM_MBZ, gpregs);
+ FFA_PARAM_MBZ, cookie, gpregs,
+ flags);
} else {
ret = MAKE_FFA_VERSION(FFA_VERSION_MAJOR,
FFA_VERSION_MINOR);
@@ -630,7 +720,8 @@
/* Forward SMC from Normal world to the SPM Core */
if (!secure_origin) {
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
}
/*
@@ -712,6 +803,14 @@
break; /* not reached */
case FFA_MSG_SEND_DIRECT_REQ_SMC32:
+ case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+ if (!secure_origin) {
+ /* Validate source endpoint is non-secure for non-secure caller. */
+ if (ffa_is_secure_world_id(ffa_endpoint_source(x1))) {
+ return spmd_ffa_error_return(handle,
+ FFA_ERROR_INVALID_PARAMETER);
+ }
+ }
if (secure_origin && spmd_is_spmc_message(x1)) {
ret = spmd_handle_spmc_message(x3, x4,
SMC_GET_GP(handle, CTX_GPREG_X5),
@@ -726,7 +825,8 @@
} else {
/* Forward direct message to the other world */
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
}
break; /* Not reached */
@@ -736,7 +836,8 @@
} else {
/* Forward direct message to the other world */
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
}
break; /* Not reached */
@@ -755,6 +856,7 @@
case FFA_NOTIFICATION_INFO_GET:
case FFA_NOTIFICATION_INFO_GET_SMC64:
case FFA_MSG_SEND2:
+ case FFA_RX_ACQUIRE:
#endif
case FFA_MSG_RUN:
/*
@@ -768,7 +870,6 @@
/* Fall through to forward the call to the other world */
case FFA_MSG_SEND:
- case FFA_MSG_SEND_DIRECT_REQ_SMC64:
case FFA_MSG_SEND_DIRECT_RESP_SMC64:
case FFA_MEM_DONATE_SMC32:
case FFA_MEM_DONATE_SMC64:
@@ -781,6 +882,8 @@
case FFA_MEM_RETRIEVE_RESP:
case FFA_MEM_RELINQUISH:
case FFA_MEM_RECLAIM:
+ case FFA_MEM_FRAG_TX:
+ case FFA_MEM_FRAG_RX:
case FFA_SUCCESS_SMC32:
case FFA_SUCCESS_SMC64:
/*
@@ -791,7 +894,8 @@
*/
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
break; /* not reached */
case FFA_MSG_WAIT:
@@ -814,7 +918,8 @@
}
return spmd_smc_forward(smc_fid, secure_origin,
- x1, x2, x3, x4, handle);
+ x1, x2, x3, x4, cookie,
+ handle, flags);
break; /* not reached */
case FFA_NORMAL_WORLD_RESUME:
diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c
index b719161..a2704dd 100644
--- a/services/std_svc/spmd/spmd_pm.c
+++ b/services/std_svc/spmd/spmd_pm.c
@@ -123,7 +123,7 @@
/* Build an SPMD to SPMC direct message request. */
spmd_build_spmc_message(get_gpregs_ctx(&ctx->cpu_ctx),
- SPMD_FWK_MSG_PSCI, PSCI_CPU_OFF);
+ FFA_FWK_MSG_PSCI, PSCI_CPU_OFF);
rc = spmd_spm_core_sync_entry(ctx);
if (rc != 0ULL) {
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 4cd6a74..07fecb6 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -58,15 +58,7 @@
*/
#define FFA_NS_ENDPOINT_ID U(0)
-/* Mask and shift to check valid secure FF-A Endpoint ID. */
-#define SPMC_SECURE_ID_MASK U(1)
-#define SPMC_SECURE_ID_SHIFT U(15)
-
-#define SPMD_DIRECT_MSG_ENDPOINT_ID U(FFA_ENDPOINT_ID_MAX - 1)
-
/* Define SPMD target function IDs for framework messages to the SPMC */
-#define SPMD_FWK_MSG_BIT BIT(31)
-#define SPMD_FWK_MSG_PSCI U(0)
#define SPMD_FWK_MSG_FFA_VERSION_REQ U(0x8)
#define SPMD_FWK_MSG_FFA_VERSION_RESP U(0x9)
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index eea7e14..b1e3db9 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,12 +13,11 @@
#include <lib/pmf/pmf.h>
#include <lib/psci/psci.h>
#include <lib/runtime_instr.h>
-#include <services/gtsi_svc.h>
#include <services/pci_svc.h>
-#include <services/rmi_svc.h>
#include <services/rmmd_svc.h>
#include <services/sdei.h>
#include <services/spm_mm_svc.h>
+#include <services/spmc_svc.h>
#include <services/spmd_svc.h>
#include <services/std_svc.h>
#include <services/trng_svc.h>
@@ -149,8 +148,8 @@
* dispatcher and return its return value
*/
if (is_ffa_fid(smc_fid)) {
- return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
- handle, flags);
+ return spmd_ffa_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+ handle, flags);
}
#endif
@@ -168,13 +167,10 @@
}
#endif
#if ENABLE_RME
- /*
- * Granule transition service interface functions (GTSI) are allocated
- * from the Std service range. Call the RMM dispatcher to handle calls.
- */
- if (is_gtsi_fid(smc_fid)) {
- return rmmd_gtsi_handler(smc_fid, x1, x2, x3, x4, cookie,
- handle, flags);
+
+ if (is_rmmd_el3_fid(smc_fid)) {
+ return rmmd_rmm_el3_handler(smc_fid, x1, x2, x3, x4, cookie,
+ handle, flags);
}
if (is_rmi_fid(smc_fid)) {
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 77d2007..d951286 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -35,6 +35,8 @@
include src/tbbr/tbbr.mk
else ifeq (${COT},dualroot)
include src/dualroot/cot.mk
+else ifeq (${COT},cca)
+ include src/cca/cot.mk
else
$(error Unknown chain of trust ${COT})
endif
@@ -62,7 +64,14 @@
# Make soft links and include from local directory otherwise wrong headers
# could get pulled in from firmware tree.
INC_DIR += -I ./include -I ${PLAT_INCLUDE} -I ${OPENSSL_DIR}/include
-LIB_DIR := -L ${OPENSSL_DIR}/lib
+
+# Include library directories where OpenSSL library files are located.
+# For a normal installation (i.e.: when ${OPENSSL_DIR} = /usr or
+# /usr/local), binaries are located under the ${OPENSSL_DIR}/lib/
+# directory. However, for a local build of OpenSSL, the built binaries are
+# located under the main project directory (i.e.: ${OPENSSL_DIR}, not
+# ${OPENSSL_DIR}/lib/).
+LIB_DIR := -L ${OPENSSL_DIR}/lib -L ${OPENSSL_DIR}
LIB := -lssl -lcrypto
HOSTCC ?= gcc
diff --git a/tools/cert_create/include/cca/cca_cot.h b/tools/cert_create/include/cca/cca_cot.h
new file mode 100644
index 0000000..56585fb
--- /dev/null
+++ b/tools/cert_create/include/cca/cca_cot.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CCA_COT_H
+#define CCA_COT_H
+
+/* Certificates. */
+enum {
+ /* Certificates owned by the silicon provider. */
+ CCA_CONTENT_CERT,
+ CORE_SWD_KEY_CERT,
+ SPMC_CONTENT_CERT,
+ SIP_SECURE_PARTITION_CONTENT_CERT,
+
+ /* Certificates owned by the platform owner. */
+ PLAT_KEY_CERT,
+ PLAT_SECURE_PARTITION_CONTENT_CERT,
+ NON_TRUSTED_FW_CONTENT_CERT,
+};
+
+/* Certificate extensions. */
+enum {
+ /* Extensions used in certificates owned by the silicon provider. */
+ TRUSTED_FW_NVCOUNTER_EXT,
+ TRUSTED_BOOT_FW_HASH_EXT,
+ TRUSTED_BOOT_FW_CONFIG_HASH_EXT,
+ HW_CONFIG_HASH_EXT,
+ FW_CONFIG_HASH_EXT,
+ SWD_ROT_PK_EXT,
+ CORE_SWD_PK_EXT,
+ SOC_AP_FW_HASH_EXT,
+ SOC_FW_CONFIG_HASH_EXT,
+ RMM_HASH_EXT,
+ TRUSTED_OS_FW_HASH_EXT,
+ TRUSTED_OS_FW_CONFIG_HASH_EXT,
+ SP_PKG1_HASH_EXT,
+ SP_PKG2_HASH_EXT,
+ SP_PKG3_HASH_EXT,
+ SP_PKG4_HASH_EXT,
+
+ /* Extensions used in certificates owned by the platform owner. */
+ PROT_PK_EXT,
+ PLAT_PK_EXT,
+ SP_PKG5_HASH_EXT,
+ SP_PKG6_HASH_EXT,
+ SP_PKG7_HASH_EXT,
+ SP_PKG8_HASH_EXT,
+ NON_TRUSTED_FW_NVCOUNTER_EXT,
+ NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT,
+ NON_TRUSTED_FW_CONFIG_HASH_EXT,
+};
+
+/* Keys. */
+enum {
+ /* Keys owned by the silicon provider. */
+ ROT_KEY,
+ SWD_ROT_KEY,
+ CORE_SWD_KEY,
+
+ /* Keys owned by the platform owner. */
+ PROT_KEY,
+ PLAT_KEY,
+};
+
+#endif /* CCA_COT_H */
diff --git a/tools/cert_create/src/cca/cot.c b/tools/cert_create/src/cca/cot.c
new file mode 100644
index 0000000..5a35ff6
--- /dev/null
+++ b/tools/cert_create/src/cca/cot.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cca/cca_cot.h"
+
+#include <cca_oid.h>
+
+#include "cert.h"
+#include "ext.h"
+#include "key.h"
+
+/*
+ * Certificates used in the chain of trust.
+ *
+ * All certificates are self-signed so the issuer certificate field points to
+ * itself.
+ */
+static cert_t cot_certs[] = {
+ [CCA_CONTENT_CERT] = {
+ .id = CCA_CONTENT_CERT,
+ .opt = "cca-cert",
+ .help_msg = "CCA Content Certificate (output file)",
+ .cn = "CCA Content Certificate",
+ .key = ROT_KEY,
+ .issuer = CCA_CONTENT_CERT,
+ .ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
+ SOC_AP_FW_HASH_EXT,
+ SOC_FW_CONFIG_HASH_EXT,
+ RMM_HASH_EXT,
+ TRUSTED_BOOT_FW_HASH_EXT,
+ TRUSTED_BOOT_FW_CONFIG_HASH_EXT,
+ HW_CONFIG_HASH_EXT,
+ FW_CONFIG_HASH_EXT,
+ },
+ .num_ext = 8
+ },
+
+ [CORE_SWD_KEY_CERT] = {
+ .id = CORE_SWD_KEY_CERT,
+ .opt = "core-swd-cert",
+ .help_msg = "Core Secure World Key Certificate (output file)",
+ .cn = "Core Secure World Key Certificate",
+ .key = SWD_ROT_KEY,
+ .issuer = CORE_SWD_KEY_CERT,
+ .ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
+ SWD_ROT_PK_EXT,
+ CORE_SWD_PK_EXT,
+ },
+ .num_ext = 3
+ },
+
+ [SPMC_CONTENT_CERT] = {
+ .id = SPMC_CONTENT_CERT,
+ .opt = "tos-fw-cert",
+ .help_msg = "SPMC Content Certificate (output file)",
+ .cn = "SPMC Content Certificate",
+ .key = CORE_SWD_KEY,
+ .issuer = SPMC_CONTENT_CERT,
+ .ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
+ TRUSTED_OS_FW_HASH_EXT,
+ TRUSTED_OS_FW_CONFIG_HASH_EXT,
+ },
+ .num_ext = 3
+ },
+
+ [SIP_SECURE_PARTITION_CONTENT_CERT] = {
+ .id = SIP_SECURE_PARTITION_CONTENT_CERT,
+ .opt = "sip-sp-cert",
+ .help_msg = "SiP owned Secure Partition Content Certificate (output file)",
+ .cn = "SiP owned Secure Partition Content Certificate",
+ .key = CORE_SWD_KEY,
+ .issuer = SIP_SECURE_PARTITION_CONTENT_CERT,
+ .ext = {
+ TRUSTED_FW_NVCOUNTER_EXT,
+ SP_PKG1_HASH_EXT,
+ SP_PKG2_HASH_EXT,
+ SP_PKG3_HASH_EXT,
+ SP_PKG4_HASH_EXT,
+ },
+ .num_ext = 5
+ },
+
+ [PLAT_KEY_CERT] = {
+ .id = PLAT_KEY_CERT,
+ .opt = "plat-key-cert",
+ .help_msg = "Platform Key Certificate (output file)",
+ .cn = "Platform Key Certificate",
+ .key = PROT_KEY,
+ .issuer = PLAT_KEY_CERT,
+ .ext = {
+ NON_TRUSTED_FW_NVCOUNTER_EXT,
+ PROT_PK_EXT,
+ PLAT_PK_EXT,
+ },
+ .num_ext = 3
+ },
+
+ [PLAT_SECURE_PARTITION_CONTENT_CERT] = {
+ .id = PLAT_SECURE_PARTITION_CONTENT_CERT,
+ .opt = "plat-sp-cert",
+ .help_msg = "Platform owned Secure Partition Content Certificate (output file)",
+ .cn = "Platform owned Secure Partition Content Certificate",
+ .key = PLAT_KEY,
+ .issuer = PLAT_SECURE_PARTITION_CONTENT_CERT,
+ .ext = {
+ NON_TRUSTED_FW_NVCOUNTER_EXT,
+ SP_PKG5_HASH_EXT,
+ SP_PKG6_HASH_EXT,
+ SP_PKG7_HASH_EXT,
+ SP_PKG8_HASH_EXT,
+ },
+ .num_ext = 5
+ },
+
+ [NON_TRUSTED_FW_CONTENT_CERT] = {
+ .id = NON_TRUSTED_FW_CONTENT_CERT,
+ .opt = "nt-fw-cert",
+ .help_msg = "Non-Trusted Firmware Content Certificate (output file)",
+ .cn = "Non-Trusted Firmware Content Certificate",
+ .key = PLAT_KEY,
+ .issuer = NON_TRUSTED_FW_CONTENT_CERT,
+ .ext = {
+ NON_TRUSTED_FW_NVCOUNTER_EXT,
+ NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT,
+ NON_TRUSTED_FW_CONFIG_HASH_EXT,
+ },
+ .num_ext = 3
+ },
+};
+
+REGISTER_COT(cot_certs);
+
+
+/* Certificate extensions. */
+static ext_t cot_ext[] = {
+ [TRUSTED_FW_NVCOUNTER_EXT] = {
+ .oid = TRUSTED_FW_NVCOUNTER_OID,
+ .opt = "tfw-nvctr",
+ .help_msg = "Trusted Firmware Non-Volatile counter value",
+ .sn = "TrustedWorldNVCounter",
+ .ln = "Trusted World Non-Volatile counter",
+ .asn1_type = V_ASN1_INTEGER,
+ .type = EXT_TYPE_NVCOUNTER,
+ .attr.nvctr_type = NVCTR_TYPE_TFW
+ },
+
+ [TRUSTED_BOOT_FW_HASH_EXT] = {
+ .oid = TRUSTED_BOOT_FW_HASH_OID,
+ .opt = "tb-fw",
+ .help_msg = "Trusted Boot Firmware image file",
+ .sn = "TrustedBootFirmwareHash",
+ .ln = "Trusted Boot Firmware hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH
+ },
+
+ [TRUSTED_BOOT_FW_CONFIG_HASH_EXT] = {
+ .oid = TRUSTED_BOOT_FW_CONFIG_HASH_OID,
+ .opt = "tb-fw-config",
+ .help_msg = "Trusted Boot Firmware Config file",
+ .sn = "TrustedBootFirmwareConfigHash",
+ .ln = "Trusted Boot Firmware Config hash",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+
+ [HW_CONFIG_HASH_EXT] = {
+ .oid = HW_CONFIG_HASH_OID,
+ .opt = "hw-config",
+ .help_msg = "HW Config file",
+ .sn = "HWConfigHash",
+ .ln = "HW Config hash",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+
+ [FW_CONFIG_HASH_EXT] = {
+ .oid = FW_CONFIG_HASH_OID,
+ .opt = "fw-config",
+ .help_msg = "Firmware Config file",
+ .sn = "FirmwareConfigHash",
+ .ln = "Firmware Config hash",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+
+ [SWD_ROT_PK_EXT] = {
+ .oid = SWD_ROT_PK_OID,
+ .sn = "SWDRoTKey",
+ .ln = "Secure World Root of Trust Public Key",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_PKEY,
+ .attr.key = SWD_ROT_KEY
+ },
+
+ [CORE_SWD_PK_EXT] = {
+ .oid = CORE_SWD_PK_OID,
+ .sn = "CORESWDKey",
+ .ln = "Core Secure World Public Key",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_PKEY,
+ .attr.key = CORE_SWD_KEY
+ },
+
+ [SOC_AP_FW_HASH_EXT] = {
+ .oid = SOC_AP_FW_HASH_OID,
+ .opt = "soc-fw",
+ .help_msg = "SoC AP Firmware image file",
+ .sn = "SoCAPFirmwareHash",
+ .ln = "SoC AP Firmware hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH
+ },
+
+ [SOC_FW_CONFIG_HASH_EXT] = {
+ .oid = SOC_FW_CONFIG_HASH_OID,
+ .opt = "soc-fw-config",
+ .help_msg = "SoC Firmware Config file",
+ .sn = "SocFirmwareConfigHash",
+ .ln = "SoC Firmware Config hash",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+
+ [RMM_HASH_EXT] = {
+ .oid = RMM_HASH_OID,
+ .opt = "rmm-fw",
+ .help_msg = "RMM Firmware image file",
+ .sn = "RMMFirmwareHash",
+ .ln = "RMM Firmware hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH
+ },
+
+ [TRUSTED_OS_FW_HASH_EXT] = {
+ .oid = TRUSTED_OS_FW_HASH_OID,
+ .opt = "tos-fw",
+ .help_msg = "Trusted OS image file",
+ .sn = "TrustedOSHash",
+ .ln = "Trusted OS hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH
+ },
+
+ [TRUSTED_OS_FW_CONFIG_HASH_EXT] = {
+ .oid = TRUSTED_OS_FW_CONFIG_HASH_OID,
+ .opt = "tos-fw-config",
+ .help_msg = "Trusted OS Firmware Config file",
+ .sn = "TrustedOSFirmwareConfigHash",
+ .ln = "Trusted OS Firmware Config hash",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+
+ [SP_PKG1_HASH_EXT] = {
+ .oid = SP_PKG1_HASH_OID,
+ .opt = "sp-pkg1",
+ .help_msg = "Secure Partition Package1 file",
+ .sn = "SPPkg1Hash",
+ .ln = "SP Pkg1 hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+ [SP_PKG2_HASH_EXT] = {
+ .oid = SP_PKG2_HASH_OID,
+ .opt = "sp-pkg2",
+ .help_msg = "Secure Partition Package2 file",
+ .sn = "SPPkg2Hash",
+ .ln = "SP Pkg2 hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+ [SP_PKG3_HASH_EXT] = {
+ .oid = SP_PKG3_HASH_OID,
+ .opt = "sp-pkg3",
+ .help_msg = "Secure Partition Package3 file",
+ .sn = "SPPkg3Hash",
+ .ln = "SP Pkg3 hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+ [SP_PKG4_HASH_EXT] = {
+ .oid = SP_PKG4_HASH_OID,
+ .opt = "sp-pkg4",
+ .help_msg = "Secure Partition Package4 file",
+ .sn = "SPPkg4Hash",
+ .ln = "SP Pkg4 hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+
+ [PROT_PK_EXT] = {
+ .oid = PROT_PK_OID,
+ .sn = "PlatformRoTKey",
+ .ln = "Platform Root of Trust Public Key",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_PKEY,
+ .attr.key = PROT_KEY
+ },
+
+ [PLAT_PK_EXT] = {
+ .oid = PLAT_PK_OID,
+ .sn = "PLATKey",
+ .ln = "Platform Public Key",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_PKEY,
+ .attr.key = PLAT_KEY
+ },
+
+ [SP_PKG5_HASH_EXT] = {
+ .oid = SP_PKG5_HASH_OID,
+ .opt = "sp-pkg5",
+ .help_msg = "Secure Partition Package5 file",
+ .sn = "SPPkg5Hash",
+ .ln = "SP Pkg5 hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+ [SP_PKG6_HASH_EXT] = {
+ .oid = SP_PKG6_HASH_OID,
+ .opt = "sp-pkg6",
+ .help_msg = "Secure Partition Package6 file",
+ .sn = "SPPkg6Hash",
+ .ln = "SP Pkg6 hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+ [SP_PKG7_HASH_EXT] = {
+ .oid = SP_PKG7_HASH_OID,
+ .opt = "sp-pkg7",
+ .help_msg = "Secure Partition Package7 file",
+ .sn = "SPPkg7Hash",
+ .ln = "SP Pkg7 hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+ [SP_PKG8_HASH_EXT] = {
+ .oid = SP_PKG8_HASH_OID,
+ .opt = "sp-pkg8",
+ .help_msg = "Secure Partition Package8 file",
+ .sn = "SPPkg8Hash",
+ .ln = "SP Pkg8 hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+
+ [NON_TRUSTED_FW_NVCOUNTER_EXT] = {
+ .oid = NON_TRUSTED_FW_NVCOUNTER_OID,
+ .opt = "ntfw-nvctr",
+ .help_msg = "Non-Trusted Firmware Non-Volatile counter value",
+ .sn = "NormalWorldNVCounter",
+ .ln = "Non-Trusted Firmware Non-Volatile counter",
+ .asn1_type = V_ASN1_INTEGER,
+ .type = EXT_TYPE_NVCOUNTER,
+ .attr.nvctr_type = NVCTR_TYPE_NTFW
+ },
+
+ [NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT] = {
+ .oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID,
+ .opt = "nt-fw",
+ .help_msg = "Non-Trusted World Bootloader image file",
+ .sn = "NonTrustedWorldBootloaderHash",
+ .ln = "Non-Trusted World hash (SHA256)",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH
+ },
+
+ [NON_TRUSTED_FW_CONFIG_HASH_EXT] = {
+ .oid = NON_TRUSTED_FW_CONFIG_HASH_OID,
+ .opt = "nt-fw-config",
+ .help_msg = "Non Trusted OS Firmware Config file",
+ .sn = "NonTrustedOSFirmwareConfigHash",
+ .ln = "Non-Trusted OS Firmware Config hash",
+ .asn1_type = V_ASN1_OCTET_STRING,
+ .type = EXT_TYPE_HASH,
+ .optional = 1
+ },
+};
+
+REGISTER_EXTENSIONS(cot_ext);
+
+/* Keys used to establish the chain of trust. */
+static key_t cot_keys[] = {
+ [ROT_KEY] = {
+ .id = ROT_KEY,
+ .opt = "rot-key",
+ .help_msg = "Root Of Trust key (input/output file)",
+ .desc = "Root Of Trust key"
+ },
+
+ [SWD_ROT_KEY] = {
+ .id = SWD_ROT_KEY,
+ .opt = "swd-rot-key",
+ .help_msg = "Secure World Root of Trust key",
+ .desc = "Secure World Root of Trust key"
+ },
+
+ [CORE_SWD_KEY] = {
+ .id = CORE_SWD_KEY,
+ .opt = "core-swd-key",
+ .help_msg = "Core Secure World key",
+ .desc = "Core Secure World key"
+ },
+
+ [PROT_KEY] = {
+ .id = PROT_KEY,
+ .opt = "prot-key",
+ .help_msg = "Platform Root of Trust key",
+ .desc = "Platform Root of Trust key"
+ },
+
+ [PLAT_KEY] = {
+ .id = PLAT_KEY,
+ .opt = "plat-key",
+ .help_msg = "Platform key",
+ .desc = "Platform key"
+ },
+};
+
+REGISTER_KEYS(cot_keys);
diff --git a/tools/cert_create/src/cca/cot.mk b/tools/cert_create/src/cca/cot.mk
new file mode 100644
index 0000000..d0c80bb
--- /dev/null
+++ b/tools/cert_create/src/cca/cot.mk
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_MSG := Confidential Compute Architecture root of trust
+PLAT_INCLUDE := ../../include/tools_share
+
+OBJECTS += src/cca/cot.o
diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c
index 4b35d73..67ae1d6 100644
--- a/tools/cert_create/src/cert.c
+++ b/tools/cert_create/src/cert.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -39,7 +39,7 @@
if (!btmp)
return 0;
- if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
+ if (!BN_rand(btmp, SERIAL_RAND_BITS, 0, 0))
goto error;
if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
goto error;
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 6435975..2857a3b 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -40,69 +40,25 @@
static int key_create_rsa(key_t *key, int key_bits)
{
- BIGNUM *e;
- RSA *rsa = NULL;
-
- e = BN_new();
- if (e == NULL) {
- printf("Cannot create RSA exponent\n");
- goto err;
- }
-
- if (!BN_set_word(e, RSA_F4)) {
- printf("Cannot assign RSA exponent\n");
- goto err;
- }
-
- rsa = RSA_new();
+ EVP_PKEY *rsa = EVP_RSA_gen(key_bits);
if (rsa == NULL) {
- printf("Cannot create RSA key\n");
- goto err;
- }
-
- if (!RSA_generate_key_ex(rsa, key_bits, e, NULL)) {
printf("Cannot generate RSA key\n");
- goto err;
- }
-
- if (!EVP_PKEY_assign_RSA(key->key, rsa)) {
- printf("Cannot assign RSA key\n");
- goto err;
+ return 0;
}
-
- BN_free(e);
+ key->key = rsa;
return 1;
-err:
- RSA_free(rsa);
- BN_free(e);
- return 0;
}
#ifndef OPENSSL_NO_EC
static int key_create_ecdsa(key_t *key, int key_bits)
{
- EC_KEY *ec;
-
- ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+ EVP_PKEY *ec = EVP_EC_gen("prime256v1");
if (ec == NULL) {
- printf("Cannot create EC key\n");
- goto err;
- }
- if (!EC_KEY_generate_key(ec)) {
printf("Cannot generate EC key\n");
- goto err;
- }
- EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS);
- EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
- if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) {
- printf("Cannot assign EC key\n");
- goto err;
+ return 0;
}
-
+ key->key = ec;
return 1;
-err:
- EC_KEY_free(ec);
- return 0;
}
#endif /* OPENSSL_NO_EC */
diff --git a/tools/cert_create/src/sha.c b/tools/cert_create/src/sha.c
index 3d977fb..06ef360 100644
--- a/tools/cert_create/src/sha.c
+++ b/tools/cert_create/src/sha.c
@@ -1,26 +1,38 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <openssl/sha.h>
#include <stdio.h>
#include "debug.h"
#include "key.h"
+#include <openssl/evp.h>
+#include <openssl/obj_mac.h>
#define BUFFER_SIZE 256
+static int get_algorithm_nid(int hash_alg)
+{
+ int nids[] = {NID_sha256, NID_sha384, NID_sha512};
+ if (hash_alg < 0 || hash_alg >= sizeof(nids) / sizeof(*nids)) {
+ return NID_undef;
+ }
+ return nids[hash_alg];
+}
+
int sha_file(int md_alg, const char *filename, unsigned char *md)
{
FILE *inFile;
- SHA256_CTX shaContext;
- SHA512_CTX sha512Context;
+ EVP_MD_CTX *mdctx;
+ const EVP_MD *md_type;
int bytes;
+ int alg_nid;
+ unsigned int total_bytes;
unsigned char data[BUFFER_SIZE];
if ((filename == NULL) || (md == NULL)) {
- ERROR("%s(): NULL argument\n", __FUNCTION__);
+ ERROR("%s(): NULL argument\n", __func__);
return 0;
}
@@ -30,26 +42,37 @@
return 0;
}
+ mdctx = EVP_MD_CTX_new();
+ if (mdctx == NULL) {
+ fclose(inFile);
+ ERROR("%s(): Could not create EVP MD context\n", __func__);
+ return 0;
+ }
+
- if (md_alg == HASH_ALG_SHA384) {
- SHA384_Init(&sha512Context);
- while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
- SHA384_Update(&sha512Context, data, bytes);
- }
- SHA384_Final(md, &sha512Context);
- } else if (md_alg == HASH_ALG_SHA512) {
- SHA512_Init(&sha512Context);
- while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
- SHA512_Update(&sha512Context, data, bytes);
- }
- SHA512_Final(md, &sha512Context);
- } else {
- SHA256_Init(&shaContext);
- while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
- SHA256_Update(&shaContext, data, bytes);
- }
- SHA256_Final(md, &shaContext);
+ alg_nid = get_algorithm_nid(md_alg);
+ if (alg_nid == NID_undef) {
+ ERROR("%s(): Invalid hash algorithm\n", __func__);
+ goto err;
}
+ md_type = EVP_get_digestbynid(alg_nid);
+ if (EVP_DigestInit_ex(mdctx, md_type, NULL) == 0) {
+ ERROR("%s(): Could not initialize EVP MD digest\n", __func__);
+ goto err;
+ }
+
+ while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+ EVP_DigestUpdate(mdctx, data, bytes);
+ }
+ EVP_DigestFinal_ex(mdctx, md, &total_bytes);
+
fclose(inFile);
+ EVP_MD_CTX_free(mdctx);
return 1;
+
+err:
+ fclose(inFile);
+ EVP_MD_CTX_free(mdctx);
+ return 0;
}
+
diff --git a/tools/conventional-changelog-tf-a/package.json b/tools/conventional-changelog-tf-a/package.json
index 404ef90..0008b53 100644
--- a/tools/conventional-changelog-tf-a/package.json
+++ b/tools/conventional-changelog-tf-a/package.json
@@ -1,6 +1,6 @@
{
"name": "conventional-changelog-tf-a",
- "version": "2.6.0",
+ "version": "2.7.0",
"license": "BSD-3-Clause",
"private": true,
"main": "index.js",
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index 96dff23..60bd8ea 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019-2020, Linaro Limited. All rights reserved.
+# Copyright (c) 2019-2022, Linaro Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -39,7 +39,14 @@
# 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
+
+# Include library directories where OpenSSL library files are located.
+# For a normal installation (i.e.: when ${OPENSSL_DIR} = /usr or
+# /usr/local), binaries are located under the ${OPENSSL_DIR}/lib/
+# directory. However, for a local build of OpenSSL, the built binaries are
+# located under the main project directory (i.e.: ${OPENSSL_DIR}, not
+# ${OPENSSL_DIR}/lib/).
+LIB_DIR := -L ${OPENSSL_DIR}/lib -L ${OPENSSL_DIR}
LIB := -lssl -lcrypto
HOSTCC ?= gcc
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 7c2a083..e6aeba9 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -22,7 +22,14 @@
else
HOSTCCFLAGS += -O2
endif
-LDLIBS := -L${OPENSSL_DIR}/lib -lcrypto
+
+# Include library directories where OpenSSL library files are located.
+# For a normal installation (i.e.: when ${OPENSSL_DIR} = /usr or
+# /usr/local), binaries are located under the ${OPENSSL_DIR}/lib/
+# directory. However, for a local build of OpenSSL, the built binaries are
+# located under the main project directory (i.e.: ${OPENSSL_DIR}, not
+# ${OPENSSL_DIR}/lib/).
+LDLIBS := -L${OPENSSL_DIR}/lib -L${OPENSSL_DIR} -lcrypto
ifeq (${V},0)
Q := @
diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c
index 4998bb2..cdbf389 100644
--- a/tools/fiptool/tbbr_config.c
+++ b/tools/fiptool/tbbr_config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -172,6 +172,21 @@
.cmdline_name = "plat-sp-cert"
},
{
+ .name = "CCA Content Certificate",
+ .uuid = UUID_CCA_CONTENT_CERT,
+ .cmdline_name = "cca-cert"
+ },
+ {
+ .name = "Core Secure World Key Certificate",
+ .uuid = UUID_CORE_SWD_KEY_CERT,
+ .cmdline_name = "core-swd-cert"
+ },
+ {
+ .name = "Platform Key Certificate",
+ .uuid = UUID_PLAT_KEY_CERT,
+ .cmdline_name = "plat-key-cert"
+ },
+ {
.name = NULL,
.uuid = { {0} },
.cmdline_name = NULL,
diff --git a/tools/memory/print_memory_map.py b/tools/memory/print_memory_map.py
index 8a84018..ef53f7e 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-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -17,12 +17,24 @@
blx_symbols = ['__BL1_RAM_START__', '__BL1_RAM_END__',
'__BL2_END__',
'__BL31_END__',
+ '__RO_START__', '__RO_END_UNALIGNED__', '__RO_END__',
'__TEXT_START__', '__TEXT_END__',
+ '__TEXT_RESIDENT_START__', '__TEXT_RESIDENT_END__',
'__RODATA_START__', '__RODATA_END__',
'__DATA_START__', '__DATA_END__',
'__STACKS_START__', '__STACKS_END__',
- '__BSS_END',
+ '__BSS_START__', '__BSS_END__',
'__COHERENT_RAM_START__', '__COHERENT_RAM_END__',
+ '__CPU_OPS_START__', '__CPU_OPS_END__',
+ '__FCONF_POPULATOR_START__', '__FCONF_POPULATOR_END__',
+ '__GOT_START__', '__GOT_END__',
+ '__PARSER_LIB_DESCS_START__', '__PARSER_LIB_DESCS_END__',
+ '__PMF_TIMESTAMP_START__', '__PMF_TIMESTAMP_END__',
+ '__PMF_SVC_DESCS_START__', '__PMF_SVC_DESCS_END__',
+ '__RELA_START__', '__RELA_END__',
+ '__RT_SVC_DESCS_START__', '__RT_SVC_DESCS_END__',
+ '__BASE_XLAT_TABLE_START__', '__BASE_XLAT_TABLE_END__',
+ '__XLAT_TABLE_START__', '__XLAT_TABLE_END__',
]
# Regex to extract address from map file
@@ -40,6 +52,10 @@
else:
build_dir = 'build/fvp/debug'
+max_len = max(len(word) for word in blx_symbols) + 2
+if (max_len % 2) != 0:
+ max_len += 1
+
# Extract all the required symbols from the map files
for image in bl_images:
file_path = os.path.join(build_dir, image, '{}.map'.format(image))
@@ -47,6 +63,7 @@
with open (file_path, 'rt') as mapfile:
for line in mapfile:
for symbol in blx_symbols:
+ skip_symbol = 0
# Regex to find symbol definition
line_pattern = re.compile(r"\b0x\w*\s*" + symbol + "\s= .")
match = line_pattern.search(line)
@@ -54,7 +71,13 @@
# Extract address from line
match = address_pattern.search(line)
if match:
- address_list.append([match.group(0), symbol, image])
+ if '_END__' in symbol:
+ sym_start = symbol.replace('_END__', '_START__')
+ if [match.group(0), sym_start, image] in address_list:
+ address_list.remove([match.group(0), sym_start, image])
+ skip_symbol = 1
+ if skip_symbol == 0:
+ address_list.append([match.group(0), symbol, image])
# Sort by address
address_list.sort(key=operator.itemgetter(0))
@@ -64,16 +87,16 @@
address_list = reversed(address_list)
# Generate memory view
-print('{:-^93}'.format('Memory Map from: ' + build_dir))
+print(('{:-^%d}' % (max_len * 3 + 20 + 7)).format('Memory Map from: ' + build_dir))
for address in address_list:
if "bl1" in address[2]:
- print(address[0], '+{:-^22}+ |{:^22}| |{:^22}|'.format(address[1], '', ''))
+ print(address[0], ('+{:-^%d}+ |{:^%d}| |{:^%d}|' % (max_len, max_len, max_len)).format(address[1], '', ''))
elif "bl2" in address[2]:
- print(address[0], '|{:^22}| +{:-^22}+ |{:^22}|'.format('', address[1], ''))
+ print(address[0], ('|{:^%d}| +{:-^%d}+ |{:^%d}|' % (max_len, max_len, max_len)).format('', address[1], ''))
elif "bl31" in address[2]:
- print(address[0], '|{:^22}| |{:^22}| +{:-^22}+'.format('', '', address[1]))
+ print(address[0], ('|{:^%d}| |{:^%d}| +{:-^%d}+' % (max_len, max_len, max_len)).format('', '', address[1]))
else:
- print(address[0], '|{:^22}| |{:^22}| +{:-^22}+'.format('', '', address[1]))
+ print(address[0], ('|{:^%d}| |{:^%d}| +{:-^%d}+' % (max_len, max_len, max_len)).format('', '', address[1]))
-print('{:^20}{:_^22} {:_^22} {:_^22}'.format('', '', '', ''))
-print('{:^20}{:^22} {:^22} {:^22}'.format('address', 'bl1', 'bl2', 'bl31'))
+print(('{:^20}{:_^%d} {:_^%d} {:_^%d}' % (max_len, max_len, max_len)).format('', '', '', ''))
+print(('{:^20}{:^%d} {:^%d} {:^%d}' % (max_len, max_len, max_len)).format('address', 'bl1', 'bl2', 'bl31'))
diff --git a/tools/nxp/create_pbl/create_pbl.c b/tools/nxp/create_pbl/create_pbl.c
index 244b0fb..9457a00 100644
--- a/tools/nxp/create_pbl/create_pbl.c
+++ b/tools/nxp/create_pbl/create_pbl.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -507,7 +507,9 @@
}
}
- printf("\nBoot Location Pointer= %x\n", BYTE_SWAP_32(pblimg.ep));
+ printf("\nBoot Location Pointer= 0x%x\n",
+ pblimg.chassis == CHASSIS_2 ? BYTE_SWAP_32(pblimg.ep) :
+ pblimg.ep);
ret = SUCCESS;
bootptr_err:
diff --git a/tools/nxp/create_pbl/pbl_ch3.mk b/tools/nxp/create_pbl/pbl_ch3.mk
index e9dbfb0..9283474 100644
--- a/tools/nxp/create_pbl/pbl_ch3.mk
+++ b/tools/nxp/create_pbl/pbl_ch3.mk
@@ -1,5 +1,5 @@
#
-# Copyright 2018-2020 NXP
+# Copyright 2018-2022 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -63,7 +63,7 @@
-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl -f ${BL2_SRC_OFFSET};
# Append the bl2.bin to the RCW image
- @echo "bl2_loc is ${bl2_offset}"
+ @echo "bl2_loc is ${bl2_loc} KB"
dd if=${BUILD_PLAT}/bl2.bin of=${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl bs=1K seek=${bl2_loc}
cd ${CREATE_PBL_TOOL_PATH}; ${MAKE} clean ; cd -;
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
old mode 100755
new mode 100644
index 6b1f204..814d051
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -13,8 +13,9 @@
This script parses the layout file and generates a make file which updates
FDT_SOURCES, FIP_ARGS, CRT_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.
+If the SP entry in the layout file has a "uuid" field the scripts gets the UUID
+from there, otherwise it parses the associated partition manifest and extracts
+the UUID from there.
param1: Generated mk file "sp_gen.mk"
param2: "SP_LAYOUT_FILE", json file containing platform provided information
@@ -37,113 +38,195 @@
"SP2" : {
"image": "sp2.bin",
- "pm": "test/sp2.dts"
+ "pm": "test/sp2.dts",
+ "uuid": "1b1820fe-48f7-4175-8999-d51da00b7c9f"
}
...
}
"""
-
-import getopt
import json
import os
import re
import sys
import uuid
+from spactions import SpSetupActions
-with open(sys.argv[2],'r') as in_file:
- data = json.load(in_file)
-json_file = os.path.abspath(sys.argv[2])
-json_dir = os.path.dirname(json_file)
-gen_file = os.path.abspath(sys.argv[1])
-out_dir = os.path.abspath(sys.argv[3])
-dtb_dir = out_dir + "/fdts/"
MAX_SP = 8
-dualroot = sys.argv[4].lower() == "dualroot"
-split = int(MAX_SP / 2)
-print(dtb_dir)
-platform_count = 1
-sip_count = 1
+UUID_LEN = 4
+
+# Some helper functions to access args propagated to the action functions in
+# SpSetupActions framework.
+def check_sp_mk_gen(args :dict):
+ if "sp_gen_mk" not in args.keys():
+ raise Exception(f"Path to file sp_gen.mk needs to be in 'args'.")
+
+def check_out_dir(args :dict):
+ if "out_dir" not in args.keys() or not os.path.isdir(args["out_dir"]):
+ raise Exception("Define output folder with \'out_dir\' key.")
+
+def check_sp_layout_dir(args :dict):
+ if "sp_layout_dir" not in args.keys() or not os.path.isdir(args["sp_layout_dir"]):
+ raise Exception("Define output folder with \'sp_layout_dir\' key.")
-with open(gen_file, 'w') as out_file:
- for idx, key in enumerate(data.keys()):
+def write_to_sp_mk_gen(content, args :dict):
+ check_sp_mk_gen(args)
+ with open(args["sp_gen_mk"], "a") as f:
+ f.write(f"{content}\n")
- pkg_num = idx + 1
+def get_sp_manifest_full_path(sp_node, args :dict):
+ check_sp_layout_dir(args)
+ return os.path.join(args["sp_layout_dir"], get_file_from_layout(sp_node["pm"]))
- if (pkg_num > MAX_SP):
- print("WARNING: Too many secure partitions\n")
- exit(-1)
+def get_sp_img_full_path(sp_node, args :dict):
+ check_sp_layout_dir(args)
+ return os.path.join(args["sp_layout_dir"], get_file_from_layout(sp_node["image"]))
- if dualroot:
- owner = data[key].get('owner')
- if owner == "Plat":
- if (platform_count > split):
- print("WARNING: Maximum Secure partitions by Plat " +
- "have been exceeded (" + str(split) + ")\n")
- exit(-1)
- pkg_num = split + platform_count
- platform_count += 1
- elif (sip_count > split):
- print("WARNING: Maximum Secure partitions by SiP " +
- "have been exceeded (" + str(split) + ")\n")
- exit(-1)
- else:
- pkg_num = sip_count
- sip_count += 1
+def get_sp_pkg(sp, args :dict):
+ check_out_dir(args)
+ return os.path.join(args["out_dir"], f"{sp}.pkg")
- """
- Append FDT_SOURCES
- """
- dts = os.path.join(json_dir, data[key]['pm'])
- dtb = dtb_dir + os.path.basename(data[key]['pm'][:-1] + "b")
- out_file.write("FDT_SOURCES += " + dts + "\n")
+def is_line_in_sp_gen(line, args :dict):
+ with open(args["sp_gen_mk"], "r") as f:
+ sppkg_rule = [l for l in f if line in l]
+ return len(sppkg_rule) is not 0
- """
- Update SPTOOL_ARGS
- """
- dst = out_dir + "/" + key + ".pkg"
- src = [ json_dir + "/" + data[key]['image'] , dtb ]
- out_file.write("SPTOOL_ARGS += -i " + ":".join(src) + " -o " + dst + "\n")
+def get_file_from_layout(node):
+ ''' Helper to fetch a file path from sp_layout.json. '''
+ if type(node) is dict and "file" in node.keys():
+ return node["file"]
+ return node
- """
- Extract uuid from partition manifest
- """
- pm_file = open(dts)
- for line in pm_file:
- if "uuid" in line:
- # re.findall returns a list of string tuples.
- # uuid_hex is the first item in this list representing the four
- # uuid hex integers from the manifest uuid field. The heading
- # '0x' of the hexadecimal representation is stripped out.
- # e.g. uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
- # uuid_hex = ('1e67b5b4', 'e14f904a', '13fb1fb8', 'cbdae1da')
- uuid_hex = re.findall(r'0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+)', line)[0];
+def get_offset_from_layout(node):
+ ''' Helper to fetch an offset from sp_layout.json. '''
+ if type(node) is dict and "offset" in node.keys():
+ return int(node["offset"], 0)
+ return None
- # uuid_hex is a list of four hex string values
- if len(uuid_hex) != 4:
- print("ERROR: malformed UUID")
- exit(-1)
+def get_image_offset(node):
+ ''' Helper to fetch image offset from sp_layout.json '''
+ return get_offset_from_layout(node["image"])
+def get_pm_offset(node):
+ ''' Helper to fetch pm offset from sp_layout.json '''
+ return get_offset_from_layout(node["pm"])
+
+@SpSetupActions.sp_action(global_action=True)
+def check_max_sps(sp_layout, _, args :dict):
+ ''' Check validate the maximum number of SPs is respected. '''
+ if len(sp_layout.keys()) > MAX_SP:
+ raise Exception(f"Too many SPs in SP layout file. Max: {MAX_SP}")
+ return args
+
+@SpSetupActions.sp_action
+def gen_fdt_sources(sp_layout, sp, args :dict):
+ ''' Generate FDT_SOURCES values for a given SP. '''
+ manifest_path = get_sp_manifest_full_path(sp_layout[sp], args)
+ write_to_sp_mk_gen(f"FDT_SOURCES += {manifest_path}", args)
+ return args
+
+@SpSetupActions.sp_action
+def gen_sptool_args(sp_layout, sp, args :dict):
+ ''' Generate Sp Pkgs rules. '''
+ sp_pkg = get_sp_pkg(sp, args)
+ sp_dtb_name = os.path.basename(get_file_from_layout(sp_layout[sp]["pm"]))[:-1] + "b"
+ sp_dtb = os.path.join(args["out_dir"], f"fdts/{sp_dtb_name}")
+
+ # Do not generate rule if already there.
+ if is_line_in_sp_gen(f'{sp_pkg}:', args):
+ return args
+ write_to_sp_mk_gen(f"SP_PKGS += {sp_pkg}\n", args)
+
+ sptool_args = f" -i {get_sp_img_full_path(sp_layout[sp], args)}:{sp_dtb}"
+ pm_offset = get_pm_offset(sp_layout[sp])
+ sptool_args += f" --pm-offset {pm_offset}" if pm_offset is not None else ""
+ image_offset = get_image_offset(sp_layout[sp])
+ sptool_args += f" --img-offset {image_offset}" if image_offset is not None else ""
+ sptool_args += f" -o {sp_pkg}"
+ sppkg_rule = f'''
+{sp_pkg}: {sp_dtb}
+\t$(Q)echo Generating {sp_pkg}
+\t$(Q)$(PYTHON) $(SPTOOL) {sptool_args}
+'''
+ write_to_sp_mk_gen(sppkg_rule, args)
+ return args
+
+@SpSetupActions.sp_action(global_action=True, exec_order=1)
+def check_dualroot(sp_layout, _, args :dict):
+ ''' Validate the amount of SPs from SiP and Platform owners. '''
+ if not args.get("dualroot"):
+ return args
+ args["split"] = int(MAX_SP / 2)
+ owners = [sp_layout[sp].get("owner") for sp in sp_layout]
+ args["plat_max_count"] = owners.count("Plat")
+ # If it is owned by the platform owner, it is assigned to the SiP.
+ args["sip_max_count"] = len(sp_layout.keys()) - args["plat_max_count"]
+ if args["sip_max_count"] > args["split"] or args["sip_max_count"] > args["split"]:
+ print(f"WARN: SiP Secure Partitions should not be more than {args['split']}")
+ # Counters for gen_crt_args.
+ args["sip_count"] = 1
+ args["plat_count"] = 1
+ return args
+
+@SpSetupActions.sp_action
+def gen_crt_args(sp_layout, sp, args :dict):
+ ''' Append CRT_ARGS. '''
+ # If "dualroot" is configured, 'sp_pkg_idx' depends on whether the SP is owned
+ # by the "SiP" or the "Plat".
+ if args.get("dualroot"):
+ # If the owner is not specified as "Plat", default to "SiP".
+ if sp_layout[sp].get("owner") == "Plat":
+ if args["plat_count"] > args["plat_max_count"]:
+ raise ValueError("plat_count can't surpass plat_max_count in args.")
+ sp_pkg_idx = args["plat_count"] + args["split"]
+ args["plat_count"] += 1
+ else:
+ if args["sip_count"] > args["sip_max_count"]:
+ raise ValueError("sip_count can't surpass sip_max_count in args.")
+ sp_pkg_idx = args["sip_count"]
+ args["sip_count"] += 1
+ else:
+ sp_pkg_idx = [k for k in sp_layout.keys()].index(sp) + 1
+ write_to_sp_mk_gen(f"CRT_ARGS += --sp-pkg{sp_pkg_idx} {get_sp_pkg(sp, args)}\n", args)
+ return args
+
+@SpSetupActions.sp_action
+def gen_fiptool_args(sp_layout, sp, args :dict):
+ ''' Generate arguments for the FIP Tool. '''
+ if "uuid" in sp_layout[sp]:
+ # Extract the UUID from the JSON file if the SP entry has a 'uuid' field
+ uuid_std = uuid.UUID(data[key]['uuid'])
+ else:
+ with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
+ uuid_lines = [l for l in pm_f if 'uuid' in l]
+ assert(len(uuid_lines) is 1)
# The uuid field in SP manifest is the little endian representation
# mapped to arguments as described in SMCCC section 5.3.
# Convert each unsigned integer value to a big endian representation
# required by fiptool.
- y=list(map(bytearray.fromhex, uuid_hex))
- z=(int.from_bytes(y[0], byteorder='little', signed=False),
- int.from_bytes(y[1], byteorder='little', signed=False),
- int.from_bytes(y[2], byteorder='little', signed=False),
- int.from_bytes(y[3], byteorder='little', signed=False))
+ uuid_parsed = re.findall("0x([0-9a-f]+)", uuid_lines[0])
+ y = list(map(bytearray.fromhex, uuid_parsed))
+ z = [int.from_bytes(i, byteorder='little', signed=False) for i in y]
uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}')
+ write_to_sp_mk_gen(f"FIP_ARGS += --blob uuid={str(uuid_std)},file={get_sp_pkg(sp, args)}\n", args)
+ return args
- """
- Append FIP_ARGS
- """
- out_file.write("FIP_ARGS += --blob uuid=" + str(uuid_std) + ",file=" + dst + "\n")
-
- """
- Append CRT_ARGS
- """
+def init_sp_actions(sys):
+ sp_layout_file = os.path.abspath(sys.argv[2])
+ with open(sp_layout_file) as json_file:
+ sp_layout = json.load(json_file)
+ # Initialize arguments for the SP actions framework
+ args = {}
+ args["sp_gen_mk"] = os.path.abspath(sys.argv[1])
+ args["sp_layout_dir"] = os.path.dirname(sp_layout_file)
+ args["out_dir"] = os.path.abspath(sys.argv[3])
+ args["dualroot"] = sys.argv[4] == "dualroot"
+ #Clear content of file "sp_gen.mk".
+ with open(args["sp_gen_mk"], "w"):
+ None
+ return args, sp_layout
- out_file.write("CRT_ARGS += --sp-pkg" + str(pkg_num) + " " + dst + "\n")
- out_file.write("\n")
+if __name__ == "__main__":
+ args, sp_layout = init_sp_actions(sys)
+ SpSetupActions.run_actions(sp_layout, args)
diff --git a/tools/sptool/spactions.py b/tools/sptool/spactions.py
new file mode 100644
index 0000000..ff28ebb
--- /dev/null
+++ b/tools/sptool/spactions.py
@@ -0,0 +1,155 @@
+#!/usr/bin/python3
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+'''
+This is a python module for defining and executing SP setup actions, targeting
+a system deploying an SPM implementation.
+Each action consists of a function, that processes the SP layout json file and
+other provided arguments.
+At the core of this is the SpSetupActions which provides a means to register
+the functions into a table of actions, and execute them all when invoking
+SpSetupActions.run_actions.
+Registering the function is done by using the decorator '@SpSetupActions.sp_action'
+at function definition.
+
+Functions can be called:
+- once only, or per SP defined in the SP layout file;
+- following an order, from lowest to highest of their execution order.
+More information in the doc comments below.
+'''
+import bisect
+
+DEFAULT_ACTION_ORDER = 100
+
+class _ConfiguredAction:
+ """
+ Wraps action function with its configuration.
+ """
+ def __init__(self, action, exec_order=DEFAULT_ACTION_ORDER, global_action=True, log_calls = False):
+ self.exec_order = exec_order
+ self.__name__ = action.__name__
+ def logged_action(action):
+ def inner_logged_action(sp_layout, sp, args :dict):
+ print(f"Calling {action.__name__} -> {sp}")
+ return action(sp_layout, sp, args)
+ return inner_logged_action
+ self.action = logged_action(action) if log_calls is True else action
+ self.global_action = global_action
+
+ def __lt__(self, other):
+ """
+ To allow for ordered inserts in a list of actions.
+ """
+ return self.exec_order < other.exec_order
+
+ def __call__(self, sp_layout, sp, args :dict):
+ """
+ Calls action function.
+ """
+ return self.action(sp_layout, sp, args)
+
+ def __repr__(self) -> str:
+ """
+ Pretty format to show debug information about the action.
+ """
+ return f"func: {self.__name__}; global:{self.global_action}; exec_order: {self.exec_order}"
+
+class SpSetupActions:
+ actions = []
+
+ def sp_action(in_action = None, global_action = False, log_calls=False, exec_order=DEFAULT_ACTION_ORDER):
+ """
+ Function decorator that registers and configures action.
+
+ :param in_action - function to register
+ :param global_action - make the function global, i.e. make it be
+ only called once.
+ :param log_calls - at every call to action, a useful log will be printed.
+ :param exec_order - action's calling order.
+ """
+ def append_action(action):
+ action = _ConfiguredAction(action, exec_order, global_action, log_calls)
+ bisect.insort(SpSetupActions.actions, action)
+ return action
+ if in_action is not None:
+ return append_action(in_action)
+ return append_action
+
+ def run_actions(sp_layout: dict, args: dict, verbose=False):
+ """
+ Executes all actions in accordance to their registering configuration:
+ - If set as "global" it will be called once.
+ - Actions are called respecting the order established by their "exec_order" field.
+
+ :param sp_layout - dictionary containing the SP layout information.
+ :param args - arguments to be propagated through the call of actions.
+ :param verbose - prints actions information in order of execution.
+ """
+ args["called"] = [] # for debug purposes
+ def append_called(action, sp, args :dict):
+ args["called"].append(f"{action.__name__} -> {sp}")
+ return args
+
+ for action in SpSetupActions.actions:
+ if verbose:
+ print(f"Calling {action}")
+ if action.global_action:
+ scope = "global"
+ args = action(sp_layout, scope, args)
+ args = append_called(action, scope, args)
+ else:
+ # Functions that are not global called for each SP defined in
+ # the SP layout.
+ for sp in sp_layout.keys():
+ args = action(sp_layout, sp, args)
+ args = append_called(action, sp, args)
+
+if __name__ == "__main__":
+ # Executing this module will have the following test code/playground executed
+ sp_layout = {
+ "partition1" : {
+ "boot-info": True,
+ "image": {
+ "file": "partition.bin",
+ "offset":"0x2000"
+ },
+ "pm": {
+ "file": "cactus.dts",
+ "offset":"0x1000"
+ },
+ "owner": "SiP"
+ },
+ "partition2" : {
+ "image": "partition.bin",
+ "pm": "cactus-secondary.dts",
+ "owner": "Plat"
+ },
+ "partition3" : {
+ "image": "partition.bin",
+ "pm": "cactus-tertiary.dts",
+ "owner": "Plat"
+ },
+ "partition4" : {
+ "image": "ivy.bin",
+ "pm": "ivy.dts",
+ "owner": "Plat"
+ }
+ }
+
+ #Example of how to use this module
+ @SpSetupActions.sp_action(global_action=True)
+ def my_action1(sp_layout, _, args :dict):
+ print(f"inside function my_action1{sp_layout}\n\n args:{args})")
+ return args # Always return args in action function.
+ @SpSetupActions.sp_action(exec_order=1)
+ def my_action2(sp_layout, sp_name, args :dict):
+ print(f"inside function my_action2; SP: {sp_name} {sp_layout} args:{args}")
+ return args
+
+ # Example arguments to be propagated through the functions.
+ # 'args' can be extended in the action functions.
+ args = dict()
+ args["arg1"] = 0xEEE
+ args["arg2"] = 0xFF
+ SpSetupActions.run_actions(sp_layout, args)
diff --git a/tools/sptool/sptool.c b/tools/sptool/sptool.c
deleted file mode 100644
index 38baa2c..0000000
--- a/tools/sptool/sptool.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "sptool.h"
-
-#define PAGE_SIZE 4096
-
-/*
- * Entry describing Secure Partition package.
- */
-struct sp_pkg_info {
- /* Location of the files in the host's RAM. */
- void *img_data, *pm_data;
-
- /* Size of the files. */
- uint32_t img_size, pm_size;
-
- /* Location of the binary files inside the package output file */
- uint32_t img_offset, pm_offset;
-};
-
-/*
- * List of input provided by user
- */
-struct arg_list {
- char *usr_input;
- struct arg_list *next;
-};
-
-/* Align an address to a power-of-two boundary. */
-static unsigned int align_to(unsigned int address, unsigned int boundary)
-{
- unsigned int mask = boundary - 1U;
-
- if ((address & mask) != 0U)
- return (address + boundary) & ~mask;
- else
- return address;
-}
-
-/* Allocate a memory area of 'size' bytes and zero it. */
-static void *xzalloc(size_t size, const char *msg)
-{
- void *d;
-
- d = malloc(size);
- if (d == NULL) {
- fprintf(stderr, "error: malloc: %s\n", msg);
- exit(1);
- }
-
- memset(d, 0, size);
-
- return d;
-}
-
-/*
- * Write 'size' bytes from 'buf' into the specified file stream.
- * Exit the program on error.
- */
-static void xfwrite(void *buf, size_t size, FILE *fp)
-{
- if (fwrite(buf, 1, size, fp) != size) {
- fprintf(stderr, "error: Failed to write to output file.\n");
- exit(1);
- }
-}
-
-/*
- * Set the file position indicator for the specified file stream.
- * Exit the program on error.
- */
-static void xfseek(FILE *fp, long offset, int whence)
-{
- if (fseek(fp, offset, whence) != 0) {
- fprintf(stderr, "error: Failed to set file to offset 0x%lx (%d).\n",
- offset, whence);
- perror(NULL);
- exit(1);
- }
-}
-
-/*
- * Free SP package structure
- */
-static void cleanup(struct sp_pkg_info *sp)
-{
-
- if (sp != NULL) {
- if (sp->img_data != NULL) {
- free(sp->img_data);
- }
-
- if (sp->pm_data != NULL) {
- free(sp->pm_data);
- }
-
- free(sp);
-
- }
-}
-
-/*
- * Free argument list structure
- */
-static void freelist(struct arg_list *head)
-{
- struct arg_list *tmp;
-
- while (head != NULL) {
- tmp = head;
- head = head->next;
- free(tmp);
- }
-}
-
-/*
- * Append user inputs in argument list structure
- */
-static void append_user_input(struct arg_list **head, char *args)
-{
- struct arg_list *tmp = *head;
-
- if (tmp == NULL) {
- tmp = xzalloc(sizeof(struct arg_list),
- "Failed to allocate arg_list struct");
- tmp->usr_input = args;
- *head = tmp;
- } else {
- while (tmp->next != NULL) {
- tmp = tmp->next;
- }
- tmp->next = xzalloc(sizeof(struct arg_list),
- "Failed to allocate arg_list struct");
- tmp = tmp->next;
- tmp->usr_input = args;
- }
-}
-
-/*
- * Allocate a buffer big enough to store the content of the specified file and
- * load the file into it. Fill 'size' with the file size. Exit the program on
- * error.
- */
-static void load_file(const char *path, void **ptr, uint32_t *size)
-{
- FILE *f = fopen(path, "rb");
- if (f == NULL) {
- fprintf(stderr, "error: %s couldn't be opened.\n", path);
- exit(1);
- }
-
- xfseek(f, 0, SEEK_END);
- *size = ftell(f);
- if (*size == 0) {
- fprintf(stderr, "error: Size of %s is 0\n", path);
- exit(1);
- }
-
- rewind(f);
-
- *ptr = malloc(*size);
- if (*ptr == NULL) {
- fprintf(stderr, "error: Not enough memory to load %s\n", path);
- exit(1);
- }
-
- if (fread(*ptr, *size, 1, f) != 1) {
- fprintf(stderr, "error: Couldn't read %s\n", path);
- exit(1);
- }
-
- fclose(f);
-}
-
-/*
- * Parse the string containing input payloads and fill in the
- * SP Package data structure.
- */
-static void load_sp_pm(char *path, struct sp_pkg_info **sp_out)
-{
- struct sp_pkg_info *sp_pkg;
-
- char *split_mark = strstr(path, ":");
-
- *split_mark = '\0';
-
- char *sp_path = path;
- char *pm_path = split_mark + 1;
-
- sp_pkg = xzalloc(sizeof(struct sp_pkg_info),
- "Failed to allocate sp_pkg_info struct");
-
- load_file(pm_path, &sp_pkg->pm_data, &sp_pkg->pm_size);
- printf("\nLoaded SP Manifest file %s (%u bytes)\n", pm_path, sp_pkg->pm_size);
-
- load_file(sp_path, &sp_pkg->img_data, &sp_pkg->img_size);
- printf("Loaded SP Image file %s (%u bytes)\n", sp_path, sp_pkg->img_size);
-
- *sp_out = sp_pkg;
-}
-
-/*
- * Write SP package data structure into output file.
- */
-static void output_write(const char *path, struct sp_pkg_info *sp, bool header)
-{
- struct sp_pkg_header sp_header_info;
- unsigned int file_ptr = 0;
-
- FILE *f = fopen(path, "wb");
- if (f == NULL) {
- fprintf(stderr, "error: Failed to open %s\n", path);
- exit(1);
- }
-
- /* Reserve Header size */
- if (header) {
- file_ptr = sizeof(struct sp_pkg_header);
- }
-
- /* Save partition manifest */
- xfseek(f, file_ptr, SEEK_SET);
- printf("Writing SP Manifest at offset 0x%x (%u bytes)\n",
- file_ptr, sp->pm_size);
-
- sp->pm_offset = file_ptr;
- xfwrite(sp->pm_data, sp->pm_size, f);
-
- /* Save partition image aligned to Page size */
- file_ptr = align_to((sp->pm_offset + sp->pm_size), PAGE_SIZE);
- xfseek(f, file_ptr, SEEK_SET);
- printf("Writing SP Image at offset 0x%x (%u bytes)\n",
- file_ptr, sp->img_size);
-
- sp->img_offset = file_ptr;
- xfwrite(sp->img_data, sp->img_size, f);
-
- /* Finally, write header, if needed */
- if (header) {
- sp_header_info.magic = SECURE_PARTITION_MAGIC;
- sp_header_info.version = 0x1;
- sp_header_info.img_offset = sp->img_offset;
- sp_header_info.img_size = sp->img_size;
- sp_header_info.pm_offset = sp->pm_offset;
- sp_header_info.pm_size = sp->pm_size;
-
- xfseek(f, 0, SEEK_SET);
-
- printf("Writing package header\n");
-
- xfwrite(&sp_header_info, sizeof(struct sp_pkg_header), f);
- }
-
- /* All information has been written now */
- printf("\nsptool: Built Secure Partition blob %s\n", path);
-
- fclose(f);
-}
-
-static void usage(void)
-{
- printf("usage: sptool ");
-#ifdef VERSION
- printf(VERSION);
-#else
- /* If built from sptool directory, VERSION is not set. */
- printf("version unknown");
-#endif
- printf(" [<args>]\n\n");
-
- printf("This tool takes as input set of image binary files and the\n"
- "partition manifest blobs as input and generates set of\n"
- "output package files\n"
- "Usage example: sptool -i sp1.bin:sp1.dtb -o sp1.pkg\n"
- " -i sp2.bin:sp2.dtb -o sp2.pkg ...\n\n");
- printf("Commands supported:\n");
- printf(" -o <path> Set output file path.\n");
- printf(" -i <sp_path:pm_path> Add Secure Partition image and\n"
- " Manifest blob (specified in two paths\n"
- " separated by a colon).\n");
- printf(" -n Generate package without header\n");
- printf(" -h Show this message.\n");
- exit(1);
-}
-
-int main(int argc, char *argv[])
-{
- struct sp_pkg_info *sp_pkg = NULL;
- struct arg_list *in_head = NULL;
- struct arg_list *out_head = NULL;
- struct arg_list *in_list = NULL;
- struct arg_list *out_list = NULL;
- unsigned int match_counter = 0;
- bool need_header = true;
-
- int ch;
-
- if (argc <= 1) {
- fprintf(stderr, "error: File paths must be provided.\n\n");
- usage();
- return 1;
- }
-
- while ((ch = getopt(argc, argv, "hni:o:")) != -1) {
- switch (ch) {
- case 'i':
- append_user_input(&in_head, optarg);
- match_counter++;
- break;
- case 'o':
- append_user_input(&out_head, optarg);
- match_counter--;
- break;
- case 'n':
- need_header = false;
- break;
- case 'h':
- default:
- usage();
- }
- }
-
- if (match_counter) {
- fprintf(stderr, "error: Input/Output count mismatch.\n\n");
- freelist(in_head);
- freelist(out_head);
- usage();
- return 1;
- }
-
- in_list = in_head;
- out_list = out_head;
- while (in_list != NULL) {
- load_sp_pm(in_list->usr_input, &sp_pkg);
- output_write(out_list->usr_input, sp_pkg, need_header);
- in_list = in_list->next;
- out_list = out_list->next;
- }
-
- argc -= optind;
- argv += optind;
-
- cleanup(sp_pkg);
- freelist(in_head);
- freelist(out_head);
-
- return 0;
-}
diff --git a/tools/sptool/sptool.py b/tools/sptool/sptool.py
new file mode 100755
index 0000000..ae7df92
--- /dev/null
+++ b/tools/sptool/sptool.py
@@ -0,0 +1,145 @@
+#!/usr/bin/python3
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+#
+# Copyright 2022 The Hafnium Authors.
+#
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/BSD-3-Clause.
+
+"""
+Script which generates a Secure Partition package.
+https://trustedfirmware-a.readthedocs.io/en/latest/components/secure-partition-manager.html#secure-partition-packages
+"""
+
+import argparse
+from collections import namedtuple
+import sys
+from shutil import copyfileobj
+import os
+
+HF_PAGE_SIZE = 0x1000 # bytes
+HEADER_ELEMENT_BYTES = 4 # bytes
+MANIFEST_IMAGE_SPLITTER=':'
+PM_OFFSET_DEFAULT = "0x1000"
+IMG_OFFSET_DEFAULT = "0x4000"
+
+def split_dtb_bin(i : str):
+ return i.split(MANIFEST_IMAGE_SPLITTER)
+
+def align_to_page(n):
+ return HF_PAGE_SIZE * \
+ (round(n / HF_PAGE_SIZE) + \
+ (1 if n % HF_PAGE_SIZE else 0))
+
+def to_bytes(value):
+ return int(value).to_bytes(HEADER_ELEMENT_BYTES, 'little')
+
+class SpPkg:
+ def __init__(self, pm_path : str, img_path : str, pm_offset: int,
+ img_offset: int):
+ if not os.path.isfile(pm_path) or not os.path.isfile(img_path):
+ raise Exception(f"Parameters should be path. \
+ manifest: {pm_path}; img: {img_path}")
+ self.pm_path = pm_path
+ self.img_path = img_path
+ self._SpPkgHeader = namedtuple("SpPkgHeader",
+ ("magic", "version",
+ "pm_offset", "pm_size",
+ "img_offset", "img_size"))
+
+ if pm_offset >= img_offset:
+ raise ValueError("pm_offset must be smaller than img_offset")
+
+ is_hfpage_aligned = lambda val : val % HF_PAGE_SIZE == 0
+ if not is_hfpage_aligned(pm_offset) or not is_hfpage_aligned(img_offset):
+ raise ValueError(f"Offsets provided need to be page aligned: pm-{pm_offset}, img-{img_offset}")
+
+ if img_offset - pm_offset < self.pm_size:
+ raise ValueError(f"pm_offset and img_offset do not fit the specified file:{pm_path})")
+
+ self.pm_offset = pm_offset
+ self.img_offset = img_offset
+
+ def __str__(self):
+ return \
+ f'''--SP package Info--
+ header:{self.header}
+ pm: {self.pm_path}
+ img: {self.img_path}
+ '''
+
+ @property
+ def magic(self):
+ return "SPKG".encode()
+
+ @property
+ def version(self):
+ return 0x2
+
+ @property
+ def pm_size(self):
+ return os.path.getsize(self.pm_path)
+
+ @property
+ def img_size(self):
+ return os.path.getsize(self.img_path)
+
+ @property
+ def header(self):
+ return self._SpPkgHeader(
+ self.magic,
+ self.version,
+ self.pm_offset,
+ self.pm_size,
+ self.img_offset,
+ self.img_size)
+
+ @property
+ def header_size(self):
+ return len(self._SpPkgHeader._fields)
+
+ def generate(self, f_out : str):
+ with open(f_out, "wb+") as output:
+ for h in self.header:
+ to_write = h if type(h) is bytes else to_bytes(h)
+ output.write(to_write)
+ output.seek(self.pm_offset)
+ with open(self.pm_path, "rb") as pm:
+ copyfileobj(pm, output)
+ output.seek(self.img_offset)
+ with open(self.img_path, "rb") as img:
+ copyfileobj(img, output)
+
+def Main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-i", required=True,
+ help="path to partition's image and manifest separated by a colon.")
+ parser.add_argument("--pm-offset", required=False, default=PM_OFFSET_DEFAULT,
+ help="set partitition manifest offset.")
+ parser.add_argument("--img-offset", required=False, default=IMG_OFFSET_DEFAULT,
+ help="set partition image offset.")
+ parser.add_argument("-o", required=True, help="set output file path.")
+ parser.add_argument("-v", required=False, action="store_true",
+ help="print package information.")
+ args = parser.parse_args()
+
+ if not os.path.exists(os.path.dirname(args.o)):
+ raise Exception("Provide a valid output file path!\n")
+
+ image_path, manifest_path = split_dtb_bin(args.i)
+ pm_offset = int(args.pm_offset, 0)
+ img_offset = int(args.img_offset, 0)
+ pkg = SpPkg(manifest_path, image_path, pm_offset, img_offset)
+ pkg.generate(args.o)
+
+ if args.v is True:
+ print(pkg)
+
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(Main())
diff --git a/tools/stm32image/stm32image.c b/tools/stm32image/stm32image.c
index fb1dee0..bd4720c 100644
--- a/tools/stm32image/stm32image.c
+++ b/tools/stm32image/stm32image.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,16 +22,16 @@
#define VER_MINOR 1
#define VER_VARIANT 0
#define HEADER_VERSION_V1 0x1
-#define TF_BINARY_TYPE 0x10
+#define HEADER_VERSION_V2 0x2
+#define PADDING_HEADER_MAGIC __be32_to_cpu(0x5354FFFF)
+#define PADDING_HEADER_FLAG (1 << 31)
+#define PADDING_HEADER_LENGTH 0x180
-/* Default option : bit0 => no signature */
-#define HEADER_DEFAULT_OPTION (__cpu_to_le32(0x00000001))
-
-struct stm32_header {
+struct stm32_header_v1 {
uint32_t magic_number;
uint8_t image_signature[64];
uint32_t image_checksum;
- uint8_t header_version[4];
+ uint8_t header_version[4];
uint32_t image_length;
uint32_t image_entry_point;
uint32_t reserved1;
@@ -45,31 +45,50 @@
uint8_t binary_type;
};
-static void stm32image_default_header(struct stm32_header *ptr)
+struct stm32_header_v2 {
+ uint32_t magic_number;
+ uint8_t image_signature[64];
+ uint32_t image_checksum;
+ uint8_t header_version[4];
+ uint32_t image_length;
+ uint32_t image_entry_point;
+ uint32_t reserved1;
+ uint32_t load_address;
+ uint32_t reserved2;
+ uint32_t version_number;
+ uint32_t extension_flags;
+ uint32_t extension_headers_length;
+ uint32_t binary_type;
+ uint8_t padding[16];
+ uint32_t extension_header_type;
+ uint32_t extension_header_length;
+ uint8_t extension_padding[376];
+};
+
+static void stm32image_default_header(void *ptr)
{
- if (!ptr) {
+ struct stm32_header_v1 *header = (struct stm32_header_v1 *)ptr;
+
+ if (!header) {
return;
}
- ptr->magic_number = HEADER_MAGIC;
- ptr->option_flags = HEADER_DEFAULT_OPTION;
- ptr->ecdsa_algorithm = __cpu_to_le32(1);
- ptr->version_number = __cpu_to_le32(0);
- ptr->binary_type = TF_BINARY_TYPE;
+ header->magic_number = HEADER_MAGIC;
+ header->version_number = __cpu_to_le32(0);
}
-static uint32_t stm32image_checksum(void *start, uint32_t len)
+static uint32_t stm32image_checksum(void *start, uint32_t len,
+ uint32_t header_size)
{
uint32_t csum = 0;
- uint32_t hdr_len = sizeof(struct stm32_header);
uint8_t *p;
- if (len < hdr_len) {
+ if (len < header_size) {
return 0;
}
- p = (unsigned char *)start + hdr_len;
- len -= hdr_len;
+ p = (unsigned char *)start + header_size;
+ len -= header_size;
while (len > 0) {
csum += *p;
@@ -82,7 +101,8 @@
static void stm32image_print_header(const void *ptr)
{
- struct stm32_header *stm32hdr = (struct stm32_header *)ptr;
+ struct stm32_header_v1 *stm32hdr = (struct stm32_header_v1 *)ptr;
+ struct stm32_header_v2 *stm32hdr_v2 = (struct stm32_header_v2 *)ptr;
printf("Image Type : ST Microelectronics STM32 V%d.%d\n",
stm32hdr->header_version[VER_MAJOR],
@@ -95,40 +115,87 @@
__le32_to_cpu(stm32hdr->image_entry_point));
printf("Checksum : 0x%08x\n",
__le32_to_cpu(stm32hdr->image_checksum));
- printf("Option : 0x%08x\n",
- __le32_to_cpu(stm32hdr->option_flags));
- printf("Version : 0x%08x\n",
+
+ switch (stm32hdr->header_version[VER_MAJOR]) {
+ case HEADER_VERSION_V1:
+ printf("Option : 0x%08x\n",
+ __le32_to_cpu(stm32hdr->option_flags));
+ break;
+
+ case HEADER_VERSION_V2:
+ printf("Extension : 0x%08x\n",
+ __le32_to_cpu(stm32hdr_v2->extension_flags));
+ break;
+
+ default:
+ printf("Incorrect header version\n");
+ }
+
+ printf("Version : 0x%08x\n",
__le32_to_cpu(stm32hdr->version_number));
}
-static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd,
- uint32_t loadaddr, uint32_t ep, uint32_t ver,
- uint32_t major, uint32_t minor)
+static int stm32image_set_header(void *ptr, struct stat *sbuf, int ifd,
+ uint32_t loadaddr, uint32_t ep, uint32_t ver,
+ uint32_t major, uint32_t minor,
+ uint32_t binary_type, uint32_t header_size)
{
- struct stm32_header *stm32hdr = (struct stm32_header *)ptr;
+ struct stm32_header_v1 *stm32hdr = (struct stm32_header_v1 *)ptr;
+ struct stm32_header_v2 *stm32hdr_v2 = (struct stm32_header_v2 *)ptr;
+ uint32_t ext_size = 0U;
+ uint32_t ext_flags = 0U;
- stm32image_default_header(stm32hdr);
+ stm32image_default_header(ptr);
stm32hdr->header_version[VER_MAJOR] = major;
stm32hdr->header_version[VER_MINOR] = minor;
stm32hdr->load_address = __cpu_to_le32(loadaddr);
stm32hdr->image_entry_point = __cpu_to_le32(ep);
stm32hdr->image_length = __cpu_to_le32((uint32_t)sbuf->st_size -
- sizeof(struct stm32_header));
+ header_size);
stm32hdr->image_checksum =
- __cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size));
+ __cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size,
+ header_size));
+
+ switch (stm32hdr->header_version[VER_MAJOR]) {
+ case HEADER_VERSION_V1:
+ /* Default option for header v1 : bit0 => no signature */
+ stm32hdr->option_flags = __cpu_to_le32(0x00000001);
+ stm32hdr->ecdsa_algorithm = __cpu_to_le32(1);
+ stm32hdr->binary_type = (uint8_t)binary_type;
+ break;
+
+ case HEADER_VERSION_V2:
+ stm32hdr_v2->binary_type = binary_type;
+ ext_size += PADDING_HEADER_LENGTH;
+ ext_flags |= PADDING_HEADER_FLAG;
+ stm32hdr_v2->extension_flags =
+ __cpu_to_le32(ext_flags);
+ stm32hdr_v2->extension_headers_length =
+ __cpu_to_le32(ext_size);
+ stm32hdr_v2->extension_header_type = PADDING_HEADER_MAGIC;
+ stm32hdr_v2->extension_header_length =
+ __cpu_to_le32(PADDING_HEADER_LENGTH);
+ break;
+
+ default:
+ return -1;
+ }
+
stm32hdr->version_number = __cpu_to_le32(ver);
+
+ return 0;
}
static int stm32image_create_header_file(char *srcname, char *destname,
uint32_t loadaddr, uint32_t entry,
uint32_t version, uint32_t major,
- uint32_t minor)
+ uint32_t minor, uint32_t binary_type)
{
- int src_fd, dest_fd;
+ int src_fd, dest_fd, header_size;
struct stat sbuf;
unsigned char *ptr;
- struct stm32_header stm32image_header;
+ void *stm32image_header;
dest_fd = open(destname, O_RDWR | O_CREAT | O_TRUNC | O_APPEND, 0666);
if (dest_fd == -1) {
@@ -154,15 +221,32 @@
return -1;
}
+ switch (major) {
+ case HEADER_VERSION_V1:
+ stm32image_header = malloc(sizeof(struct stm32_header_v1));
+ header_size = sizeof(struct stm32_header_v1);
+ break;
+
+ case HEADER_VERSION_V2:
+ stm32image_header = malloc(sizeof(struct stm32_header_v2));
+ header_size = sizeof(struct stm32_header_v2);
+ break;
+
- memset(&stm32image_header, 0, sizeof(struct stm32_header));
+ default:
+ return -1;
+ }
- if (write(dest_fd, &stm32image_header, sizeof(struct stm32_header)) !=
- sizeof(struct stm32_header)) {
+ memset(stm32image_header, 0, header_size);
+ if (write(dest_fd, stm32image_header, header_size) !=
+ header_size) {
fprintf(stderr, "Write error %s: %s\n", destname,
strerror(errno));
+ free(stm32image_header);
return -1;
}
+ free(stm32image_header);
+
if (write(dest_fd, ptr, sbuf.st_size) != sbuf.st_size) {
fprintf(stderr, "Write error on %s: %s\n", destname,
strerror(errno));
@@ -184,8 +268,11 @@
return -1;
}
- stm32image_set_header(ptr, &sbuf, dest_fd, loadaddr, entry, version,
- major, minor);
+ if (stm32image_set_header(ptr, &sbuf, dest_fd, loadaddr,
+ entry, version, major, minor,
+ binary_type, header_size) != 0) {
+ return -1;
+ }
stm32image_print_header(ptr);
@@ -196,13 +283,22 @@
int main(int argc, char *argv[])
{
- int opt, loadaddr = -1, entry = -1, err = 0, version = 0;
- int major = HEADER_VERSION_V1;
+ int opt;
+ int loadaddr = -1;
+ int entry = -1;
+ int err = 0;
+ int version = 0;
+ int binary_type = -1;
+ int major = HEADER_VERSION_V2;
int minor = 0;
- char *dest = NULL, *src = NULL;
+ char *dest = NULL;
+ char *src = NULL;
- while ((opt = getopt(argc, argv, ":s:d:l:e:v:m:n:")) != -1) {
+ while ((opt = getopt(argc, argv, ":b:s:d:l:e:v:m:n:")) != -1) {
switch (opt) {
+ case 'b':
+ binary_type = strtol(optarg, NULL, 0);
+ break;
case 's':
src = optarg;
break;
@@ -226,7 +322,7 @@
break;
default:
fprintf(stderr,
- "Usage : %s [-s srcfile] [-d destfile] [-l loadaddr] [-e entry_point] [-m major] [-n minor]\n",
+ "Usage : %s [-s srcfile] [-d destfile] [-l loadaddr] [-e entry_point] [-m major] [-n minor] [-b binary_type]\n",
argv[0]);
return -1;
}
@@ -252,8 +348,14 @@
return -1;
}
+ if (binary_type == -1) {
+ fprintf(stderr, "Missing -b option\n");
+ return -1;
+ }
+
err = stm32image_create_header_file(src, dest, loadaddr,
- entry, version, major, minor);
+ entry, version, major, minor,
+ binary_type);
return err;
}