diff --git a/recipes-security/optee/optee-os-stm32mp-archiver.inc b/recipes-security/optee/optee-os-stm32mp-archiver.inc index 44c262c..32d8a11 100644 --- a/recipes-security/optee/optee-os-stm32mp-archiver.inc +++ b/recipes-security/optee/optee-os-stm32mp-archiver.inc @@ -12,44 +12,82 @@ inherit archiver_stm32mp_clean archiver_create_makefile_for_sdk() { mkdir -p ${ARCHIVER_OUTDIR} - #remove default variable - echo "LDFLAGS=" > ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "CFLAGS=" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "CPPFLAGS=" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + cat << EOF > ${ARCHIVER_OUTDIR}/Makefile.sdk +# Set default path +SRC_PATH ?= \$(PWD) +BLD_PATH ?= \$(SRC_PATH)/../build +DEPLOYDIR ?= \$(SRC_PATH)/../deploy - echo "LOCAL_PATH=\$(PWD)" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk +# Set default optee-os config +CFG_EMBED_DTB_SOURCE_FILE ?= ${OPTEE_CONF} - #set default CONFIGURATION with configured OPTEE_CONF - if [ -n "${OPTEE_CONF}" ]; then - echo "PLATFORM ?= ${MACHINE}" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "CFG_EMBED_DTB_SOURCE_FILE ?= ${OPTEE_CONF}" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - fi +# Configure default optee-os features +ENABLE_FIP ?= ${@bb.utils.contains('MACHINE_FEATURES','fip','1','',d)} - echo -n "EXTRA_OEMAKE=" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "${EXTRA_OEMAKE}" | sed "s|LIBGCC_LOCATE_CFLAGS=[^ ]* |LIBGCC_LOCATE_CFLAGS=\$(OECORE_NATIVE_SYSROOTK) |;s|comp-cflagscore='[^']*'|comp-cflagscore='\$(KCFLAGS)'|" >> ${ARCHIVER_OUTDIR}/Makefile.sdk +# Remove default variables +LDFLAGS = +CFLAGS = +CPPFLAGS = +# Define default make options +EXTRA_OEMAKE = $(echo "${EXTRA_OEMAKE}" | sed "s|LIBGCC_LOCATE_CFLAGS=[^ ]* |LIBGCC_LOCATE_CFLAGS=\$(KCFLAGS) |;s|comp-cflagscore='[^']*'|comp-cflagscore='\$(KCFLAGS)'|") +EXTRA_OEMAKE += \$(if \$(ENABLE_FIP),,CFG_STM32MP15x_STM32IMAGE=y) - echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "all:" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " if test -n \"\$(CFG_EMBED_DTB_SOURCE_FILE)\" ; then \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " for dt in \$(CFG_EMBED_DTB_SOURCE_FILE) ; do \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " \$(MAKE) \$(EXTRA_OEMAKE) -C \$(LOCAL_PATH) PREFIX=\$(SDKTARGETSYSROOT) O=\$(LOCAL_PATH)/../build/\$\$dt CFG_EMBED_DTB_SOURCE_FILE=\$\$dt.dts ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - # Copy binary files with explicit name - echo " cp ../build/\$\$dt/core/${OPTEE_HEADER}.${OPTEE_SUFFIX} ../build/${OPTEE_HEADER}-\$\$dt-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " cp ../build/\$\$dt/core/${OPTEE_PAGER}.${OPTEE_SUFFIX} ../build/${OPTEE_PAGER}-\$\$dt-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " cp ../build/\$\$dt/core/${OPTEE_PAGEABLE}.${OPTEE_SUFFIX} ../build/${OPTEE_PAGEABLE}-\$\$dt-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " done ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " else \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " \$(MAKE) \$(EXTRA_OEMAKE) -C \$(LOCAL_PATH) PREFIX=\$(SDKTARGETSYSROOT) O=\$(LOCAL_PATH)/../build/ ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - # Copy binary files with explicit name - echo " cp ../build/core/${OPTEE_HEADER}.${OPTEE_SUFFIX} ../build/${OPTEE_HEADER}-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " cp ../build/core/${OPTEE_PAGER}.${OPTEE_SUFFIX} ../build/${OPTEE_PAGER}-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " cp ../build/core/${OPTEE_PAGEABLE}.${OPTEE_SUFFIX} ../build/${OPTEE_PAGEABLE}-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} ; \\" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " fi" >> ${ARCHIVER_OUTDIR}/Makefile.sdk +# Configure default optee-os features +OPTEE_SUFFIX ?= \$(if \$(ENABLE_FIP),bin,stm32) - echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo "clean:" >> ${ARCHIVER_OUTDIR}/Makefile.sdk - echo " rm -rf \$(LOCAL_PATH)/../build" >> ${ARCHIVER_OUTDIR}/Makefile.sdk +help: + @echo + @echo "OPTEE-OS configuration:" + @echo " CFG_EMBED_DTB_SOURCE_FILE = \$(CFG_EMBED_DTB_SOURCE_FILE)" + @echo + @echo "OPTEE-OS folder configuration:" + @echo " SRC_PATH = \$(SRC_PATH)" + @echo " BLD_PATH = \$(BLD_PATH)" + @echo " DEPLOYDIR = \$(DEPLOYDIR)" + @echo + @echo "FIP configuration:" + @echo " ENABLE_FIP = \$(ENABLE_FIP) ('1' to generate fip binary)" +ifeq (\$(ENABLE_FIP),1) + @echo " Do not forget to set FIP deploydir folders (such as FIP_DEPLOYDIR_ROOT) to provide path to needed binaries" +endif + @echo + @echo "Available targets:" + @echo " all : build OPTEE-OS binaries for defined config(s)" + @echo " clean : clean build directories from generated files" + @echo + +all: optee \$(if \$(ENABLE_FIP),fip) + +optee: + @mkdir -p \$(DEPLOYDIR) + @mkdir -p \$(DEPLOYDIR)/debug + @if test -n "\$(CFG_EMBED_DTB_SOURCE_FILE)" ; then \\ + for dt in \$(CFG_EMBED_DTB_SOURCE_FILE) ; do \\ + \$(MAKE) \$(EXTRA_OEMAKE) -C \$(SRC_PATH) PREFIX=\$(SDKTARGETSYSROOT) O=\$(BLD_PATH)/\$\$dt CFG_EMBED_DTB_SOURCE_FILE=\$\$dt.dts ; \\ + # Copy binary files with explicit name \\ + cp \$(BLD_PATH)/\$\$dt/core/${OPTEE_HEADER}.\$(OPTEE_SUFFIX) \$(DEPLOYDIR)/${OPTEE_HEADER}-\$\$dt.\$(OPTEE_SUFFIX) ; \\ + cp \$(BLD_PATH)/\$\$dt/core/${OPTEE_PAGER}.\$(OPTEE_SUFFIX) \$(DEPLOYDIR)/${OPTEE_PAGER}-\$\$dt.\$(OPTEE_SUFFIX) ; \\ + cp \$(BLD_PATH)/\$\$dt/core/${OPTEE_PAGEABLE}.\$(OPTEE_SUFFIX) \$(DEPLOYDIR)/${OPTEE_PAGEABLE}-\$\$dt.\$(OPTEE_SUFFIX) ; \\ + cp \$(BLD_PATH)/\$\$dt/core/${OPTEE_ELF}.${OPTEE_ELF_SUFFIX} \$(DEPLOYDIR)/debug/${OPTEE_ELF}-\$\$dt.${OPTEE_ELF_SUFFIX} ; \\ + done ; \\ + else \\ + \$(MAKE) \$(EXTRA_OEMAKE) -C \$(SRC_PATH) PREFIX=\$(SDKTARGETSYSROOT) O=\$(BLD_PATH)/ ; \\ + # Copy binary files with explicit name \\ + cp \$(BLD_PATH)/core/${OPTEE_HEADER}.\$(OPTEE_SUFFIX) \$(DEPLOYDIR)/ ; \\ + cp \$(BLD_PATH)/core/${OPTEE_PAGER}.\$(OPTEE_SUFFIX) \$(DEPLOYDIR)/ ; \\ + cp \$(BLD_PATH)/core/${OPTEE_PAGEABLE}.\$(OPTEE_SUFFIX) \$(DEPLOYDIR)/ ; \\ + cp \$(BLD_PATH)/core/${OPTEE_ELF}.${OPTEE_ELF_SUFFIX} \$(DEPLOYDIR)/debug/ ; \\ + fi + +fip: optee + FIP_DEPLOYDIR_OPTEE=\$(DEPLOYDIR) FIP_DEVICETREE="\$(CFG_EMBED_DTB_SOURCE_FILE)" fiptool-stm32mp + +clean: + @echo "Removing \$(BLD_PATH) ..." + @rm -rf \$(BLD_PATH) + @echo "Removing \$(DEPLOYDIR) ..." + @rm -rf \$(DEPLOYDIR) + @echo +EOF } do_ar_original[prefuncs] += "archiver_create_makefile_for_sdk" diff --git a/recipes-security/optee/optee-os-stm32mp-common.inc b/recipes-security/optee/optee-os-stm32mp-common.inc index 3f9d6ec..ed30659 100644 --- a/recipes-security/optee/optee-os-stm32mp-common.inc +++ b/recipes-security/optee/optee-os-stm32mp-common.inc @@ -16,18 +16,17 @@ inherit deploy python3native OPTEEMACHINE ?= "${MACHINE}" OPTEEOUTPUTMACHINE ?= "${MACHINE}" -EXTRA_OEMAKE = "PLATFORM=${OPTEEMACHINE} \ - CROSS_COMPILE_core=${HOST_PREFIX} \ - CROSS_COMPILE_ta_arm64=${HOST_PREFIX} \ - ${@bb.utils.contains('TUNE_FEATURES', 'aarch64', 'CFG_ARM64_core=y ta-targets=ta_arm64', 'CFG_ARM32_core=y CROSS_COMPILE_ta_arm32=${HOST_PREFIX}', d)} \ - NOWERROR=1 \ - LDFLAGS= \ - LIBGCC_LOCATE_CFLAGS=--sysroot=${STAGING_DIR_HOST} \ - " - +EXTRA_OEMAKE = "PLATFORM=${OPTEEMACHINE}" +EXTRA_OEMAKE += "CROSS_COMPILE_core=${HOST_PREFIX}" +EXTRA_OEMAKE += "CROSS_COMPILE_ta_arm64=${HOST_PREFIX}" +EXTRA_OEMAKE += "${@bb.utils.contains('TUNE_FEATURES', 'aarch64', 'CFG_ARM64_core=y ta-targets=ta_arm64', 'CFG_ARM32_core=y CROSS_COMPILE_ta_arm32=${HOST_PREFIX}', d)}" +EXTRA_OEMAKE += "NOWERROR=1" +EXTRA_OEMAKE += "LDFLAGS=" +EXTRA_OEMAKE += "LIBGCC_LOCATE_CFLAGS=--sysroot=${STAGING_DIR_TARGET}" EXTRA_OEMAKE += "CFG_TEE_CORE_LOG_LEVEL=2" EXTRA_OEMAKE += "CFG_TEE_CORE_DEBUG=n" EXTRA_OEMAKE += "comp-cflagscore='--sysroot=${STAGING_DIR_TARGET}'" +EXTRA_OEMAKE += "${@bb.utils.contains('MACHINE_FEATURES', 'fip', '', 'CFG_STM32MP15x_STM32IMAGE=y', d)}" OPTEE_ARCH_armv7a = "arm32" OPTEE_ARCH_armv7ve = "arm32" @@ -62,11 +61,10 @@ do_install() { } # Configure optee binaries -OPTEE_BOOTCHAIN = "optee" OPTEE_HEADER = "tee-header_v2" OPTEE_PAGEABLE = "tee-pageable_v2" OPTEE_PAGER = "tee-pager_v2" -OPTEE_SUFFIX = "stm32" +OPTEE_SUFFIX = "${@bb.utils.contains('MACHINE_FEATURES','fip','bin','stm32',d)}" # Output the ELF generated ELF_DEBUG_ENABLE ?= "" OPTEE_ELF = "tee" @@ -74,22 +72,22 @@ OPTEE_ELF_SUFFIX = "elf" do_deploy[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}/optee" do_deploy() { - install -d ${DEPLOYDIR} + install -d ${DEPLOYDIR}/debug if [ -n "${OPTEE_CONF}" ]; then for conf in ${OPTEE_CONF}; do - install -m 644 ${B}/${conf}/core/${OPTEE_HEADER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_HEADER}-${conf}-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} - install -m 644 ${B}/${conf}/core/${OPTEE_PAGER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGER}-${conf}-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} - install -m 644 ${B}/${conf}/core/${OPTEE_PAGEABLE}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGEABLE}-${conf}-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} + install -m 644 ${B}/${conf}/core/${OPTEE_HEADER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_HEADER}-${conf}.${OPTEE_SUFFIX} + install -m 644 ${B}/${conf}/core/${OPTEE_PAGER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGER}-${conf}.${OPTEE_SUFFIX} + install -m 644 ${B}/${conf}/core/${OPTEE_PAGEABLE}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGEABLE}-${conf}.${OPTEE_SUFFIX} if [ -n "${ELF_DEBUG_ENABLE}" ]; then - install -m 644 ${B}/${conf}/core/${OPTEE_ELF}.${OPTEE_ELF_SUFFIX} ${DEPLOYDIR}/${OPTEE_ELF}-${conf}-${OPTEE_BOOTCHAIN}.${OPTEE_ELF_SUFFIX} + install -m 644 ${B}/${conf}/core/${OPTEE_ELF}.${OPTEE_ELF_SUFFIX} ${DEPLOYDIR}/debug/${OPTEE_ELF}-${conf}.${OPTEE_ELF_SUFFIX} fi done else - install -m 644 ${B}/core/${OPTEE_HEADER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_HEADER}-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} - install -m 644 ${B}/core/${OPTEE_PAGER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGER}-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} - install -m 644 ${B}/core/${OPTEE_PAGEABLE}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGEABLE}-${OPTEE_BOOTCHAIN}.${OPTEE_SUFFIX} + install -m 644 ${B}/core/${OPTEE_HEADER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_HEADER}.${OPTEE_SUFFIX} + install -m 644 ${B}/core/${OPTEE_PAGER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGER}.${OPTEE_SUFFIX} + install -m 644 ${B}/core/${OPTEE_PAGEABLE}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGEABLE}.${OPTEE_SUFFIX} if [ -n "${ELF_DEBUG_ENABLE}" ]; then - install -m 644 ${B}/core/${OPTEE_ELF}.${OPTEE_ELF_SUFFIX} ${DEPLOYDIR}/${OPTEE_ELF}-${OPTEE_BOOTCHAIN}.${OPTEE_ELF_SUFFIX} + install -m 644 ${B}/core/${OPTEE_ELF}.${OPTEE_ELF_SUFFIX} ${DEPLOYDIR}/debug/${OPTEE_ELF}.${OPTEE_ELF_SUFFIX} fi fi } diff --git a/recipes-security/optee/optee-os-stm32mp_3.9.0.bb b/recipes-security/optee/optee-os-stm32mp_3.12.0.bb similarity index 80% rename from recipes-security/optee/optee-os-stm32mp_3.9.0.bb rename to recipes-security/optee/optee-os-stm32mp_3.12.0.bb index 0e945a8..8b74349 100644 --- a/recipes-security/optee/optee-os-stm32mp_3.9.0.bb +++ b/recipes-security/optee/optee-os-stm32mp_3.12.0.bb @@ -2,16 +2,15 @@ SUMMARY = "OPTEE TA development kit for stm32mp" LICENSE = "BSD-2-Clause & BSD-3-Clause" LIC_FILES_CHKSUM = "file://LICENSE;md5=c1f21c4f72f372ef38a5a4aee55ec173" -SRC_URI = "git://github.com/OP-TEE/optee_os.git;protocol=https" -SRCREV = "af141c61fe7a2430f3b4bb89661d8414117013b3" +SRC_URI = "git://github.com/OP-TEE/optee_os.git;protocol=https;name=os" +SRCREV = "3d47a131bca1d9ed511bfd516aa5e70269e12c1d" SRC_URI += " \ - file://0001-3.9.0-stm32mp-r1.patch \ - file://0002-3.9.0-stm32mp-r2.patch \ + file://0001-3.12.0-stm32mp-r1.patch \ " -OPTEE_VERSION = "3.9.0" -PV = "${OPTEE_VERSION}.r2" +OPTEE_VERSION = "3.12.0" +PV = "${OPTEE_VERSION}.r1" S = "${WORKDIR}/git" @@ -40,7 +39,7 @@ include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'optee-os-stm3 BBCLASSEXTEND = "devupstream:target" SRC_URI_class-devupstream = "git://github.com/STMicroelectronics/optee_os.git;protocol=https;branch=${OPTEE_VERSION}-stm32mp" -SRCREV_class-devupstream = "6a3dd87a133bee8a18409969380dbb1fc289f803" +SRCREV_class-devupstream = "0bd33404e9581d00514034b7b05a2cbe8649c1fd" # --------------------------------- # Configure default preference to manage dynamic selection between tarball and github diff --git a/recipes-security/optee/optee-os/0001-3.9.0-stm32mp-r1.patch b/recipes-security/optee/optee-os/0001-3.12.0-stm32mp-r1.patch similarity index 65% rename from recipes-security/optee/optee-os/0001-3.9.0-stm32mp-r1.patch rename to recipes-security/optee/optee-os/0001-3.12.0-stm32mp-r1.patch index 7794ac3..e7a14f0 100644 --- a/recipes-security/optee/optee-os/0001-3.9.0-stm32mp-r1.patch +++ b/recipes-security/optee/optee-os/0001-3.12.0-stm32mp-r1.patch @@ -1,98 +1,132 @@ -From 053c918ec81e85d5dd13087b056a294f69383661 Mon Sep 17 00:00:00 2001 +From c85389468d5ee9f06de67f10783bc015117caf67 Mon Sep 17 00:00:00 2001 From: Romuald JEANNE -Date: Fri, 5 Jun 2020 13:58:23 +0200 -Subject: [PATCH] 3.9.0-stm32mp-r1 +Date: Mon, 15 Mar 2021 17:27:07 +0100 +Subject: [PATCH] 3.12.0-stm32mp-r1 +Signed-off-by: Romuald JEANNE --- - CONTRIBUTING.md | 30 + - core/arch/arm/dts/stm32mp15-pinctrl.dtsi | 914 +------------- - core/arch/arm/dts/stm32mp151.dtsi | 1327 +++----------------- - core/arch/arm/dts/stm32mp153.dtsi | 31 +- - core/arch/arm/dts/stm32mp157.dtsi | 24 - - core/arch/arm/dts/stm32mp157a-dk1.dts | 29 +- - core/arch/arm/dts/stm32mp157a-ed1.dts | 46 + - core/arch/arm/dts/stm32mp157a-ev1.dts | 23 + - core/arch/arm/dts/stm32mp157c-dk2.dts | 95 +- - core/arch/arm/dts/stm32mp157c-ed1.dts | 373 +----- - core/arch/arm/dts/stm32mp157c-ev1.dts | 350 +----- - core/arch/arm/dts/stm32mp157d-dk1.dts | 49 + - core/arch/arm/dts/stm32mp157d-ed1.dts | 46 + - core/arch/arm/dts/stm32mp157d-ev1.dts | 22 + - core/arch/arm/dts/stm32mp157f-dk2.dts | 55 + - core/arch/arm/dts/stm32mp157f-ed1.dts | 51 + - core/arch/arm/dts/stm32mp157f-ev1.dts | 22 + - core/arch/arm/dts/stm32mp15xa.dtsi | 13 + - core/arch/arm/dts/stm32mp15xc.dtsi | 3 + - core/arch/arm/dts/stm32mp15xd.dtsi | 19 + - core/arch/arm/dts/stm32mp15xf.dtsi | 21 + - core/arch/arm/dts/stm32mp15xx-dkx.dtsi | 692 ++++------ - core/arch/arm/dts/stm32mp15xx-edx.dtsi | 478 +++++++ - core/arch/arm/dts/stm32mp15xx-evx.dtsi | 71 ++ - core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi | 3 +- - core/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi | 2 +- - core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi | 3 +- - core/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi | 2 +- - core/arch/arm/include/arm32.h | 11 +- - core/arch/arm/include/mm/core_mmu.h | 3 + - core/arch/arm/include/sm/pm.h | 4 + - core/arch/arm/mm/core_mmu.c | 18 +- - core/arch/arm/mm/mobj.c | 5 +- - core/arch/arm/plat-stm32mp1/boot_api.h | 2 + - core/arch/arm/plat-stm32mp1/conf.mk | 59 +- - .../arm/plat-stm32mp1/drivers/stm32mp1_calib.c | 501 ++++++++ - core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c | 1268 ++++++++++++++++++- - .../arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.c | 469 +++++++ - .../arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.h | 219 ++++ - core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h | 31 +- - core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h | 35 +- - core/arch/arm/plat-stm32mp1/drivers/sub.mk | 2 + - core/arch/arm/plat-stm32mp1/main.c | 316 ++++- - .../arm/plat-stm32mp1/nsec-service/low_power_svc.c | 152 +++ - .../arm/plat-stm32mp1/nsec-service/low_power_svc.h | 55 + - core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.c | 89 ++ - core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.h | 22 + - core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c | 195 +++ - core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.h | 30 + - .../arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h | 196 ++- - .../nsec-service/stm32mp1_svc_setup.c | 79 +- - core/arch/arm/plat-stm32mp1/nsec-service/sub.mk | 3 + - core/arch/arm/plat-stm32mp1/platform_config.h | 131 +- - core/arch/arm/plat-stm32mp1/pm/context.c | 521 ++++++++ - core/arch/arm/plat-stm32mp1/pm/context.h | 102 ++ - .../arm/plat-stm32mp1/pm/context_asm_defines.c | 28 + - core/arch/arm/plat-stm32mp1/pm/low_power.c | 609 +++++++++ - core/arch/arm/plat-stm32mp1/pm/pm_helpers.S | 740 +++++++++++ - core/arch/arm/plat-stm32mp1/pm/power.h | 27 + - core/arch/arm/plat-stm32mp1/pm/power_config.c | 252 ++++ - core/arch/arm/plat-stm32mp1/pm/psci.c | 224 +++- - core/arch/arm/plat-stm32mp1/pm/sub.mk | 6 + - core/arch/arm/plat-stm32mp1/reset.S | 30 +- - core/arch/arm/plat-stm32mp1/scmi_server.c | 81 +- - core/arch/arm/plat-stm32mp1/shared_resources.c | 31 +- - core/arch/arm/plat-stm32mp1/stm32_util.h | 54 + - core/arch/arm/plat-stm32mp1/stm32mp_pm.h | 21 + - core/arch/arm/sm/pm_a32.S | 83 +- - core/arch/arm/tee/entry_std.c | 2 +- - core/drivers/gic.c | 225 +++- - core/drivers/stm32_bsec.c | 130 +- - core/drivers/stm32_iwdg.c | 313 +++++ - core/drivers/stm32_rtc.c | 445 +++++++ - core/drivers/stm32_tim.c | 286 +++++ - core/drivers/sub.mk | 3 + - core/include/drivers/gic.h | 24 + - core/include/drivers/stm32_bsec.h | 16 + - core/include/drivers/stm32_iwdg.h | 17 + - core/include/drivers/stm32_rtc.h | 60 + - core/include/drivers/stm32_tim.h | 25 + - core/include/dt-bindings/clock/stm32mp1-clksrc.h | 284 +++++ - core/include/dt-bindings/power/stm32mp1-power.h | 19 + - core/include/dt-bindings/soc/st,stm32-etzpc.h | 107 ++ - core/include/kernel/interrupt.h | 15 + - core/include/kernel/panic.h | 6 + - core/kernel/interrupt.c | 10 + - core/kernel/panic.c | 23 +- - mk/config.mk | 2 +- - 88 files changed, 10040 insertions(+), 3470 deletions(-) + CONTRIBUTING.md | 30 + + core/arch/arm/dts/stm32mp15-pinctrl.dtsi | 957 ++---------- + core/arch/arm/dts/stm32mp151.dtsi | 1368 +++-------------- + core/arch/arm/dts/stm32mp153.dtsi | 31 +- + core/arch/arm/dts/stm32mp157.dtsi | 24 - + core/arch/arm/dts/stm32mp157a-dk1.dts | 29 +- + core/arch/arm/dts/stm32mp157a-ed1.dts | 38 + + core/arch/arm/dts/stm32mp157a-ev1.dts | 24 + + core/arch/arm/dts/stm32mp157c-dk2.dts | 95 +- + core/arch/arm/dts/stm32mp157c-ed1.dts | 377 +---- + core/arch/arm/dts/stm32mp157c-ev1.dts | 349 +---- + core/arch/arm/dts/stm32mp157d-dk1.dts | 45 + + core/arch/arm/dts/stm32mp157d-ed1.dts | 39 + + core/arch/arm/dts/stm32mp157d-ev1.dts | 23 + + core/arch/arm/dts/stm32mp157f-dk2.dts | 51 + + core/arch/arm/dts/stm32mp157f-ed1.dts | 43 + + core/arch/arm/dts/stm32mp157f-ev1.dts | 23 + + core/arch/arm/dts/stm32mp15xa.dtsi | 13 + + core/arch/arm/dts/stm32mp15xc.dtsi | 3 + + core/arch/arm/dts/stm32mp15xd.dtsi | 19 + + core/arch/arm/dts/stm32mp15xf.dtsi | 21 + + core/arch/arm/dts/stm32mp15xx-dkx.dtsi | 708 ++++----- + core/arch/arm/dts/stm32mp15xx-edx.dtsi | 517 +++++++ + core/arch/arm/dts/stm32mp15xx-evx.dtsi | 73 + + core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi | 1 + + core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi | 1 + + core/arch/arm/include/arm32.h | 11 +- + core/arch/arm/include/kernel/tlb_helpers.h | 9 +- + core/arch/arm/include/mm/core_mmu.h | 15 + + core/arch/arm/include/mm/pgt_cache.h | 5 +- + core/arch/arm/include/sm/pm.h | 4 + + core/arch/arm/mm/core_mmu.c | 35 +- + core/arch/arm/mm/mobj.c | 5 +- + core/arch/arm/mm/pgt_cache.c | 56 +- + core/arch/arm/plat-stm32mp1/boot_api.h | 2 + + core/arch/arm/plat-stm32mp1/conf.mk | 74 +- + .../plat-stm32mp1/drivers/stm32mp1_calib.c | 507 ++++++ + .../arm/plat-stm32mp1/drivers/stm32mp1_ddrc.c | 469 ++++++ + .../arm/plat-stm32mp1/drivers/stm32mp1_ddrc.h | 219 +++ + .../arm/plat-stm32mp1/drivers/stm32mp1_pmic.c | 50 +- + .../arm/plat-stm32mp1/drivers/stm32mp1_pmic.h | 8 +- + .../arm/plat-stm32mp1/drivers/stm32mp1_pwr.h | 33 +- + .../plat-stm32mp1/drivers/stm32mp1_syscfg.c | 14 +- + core/arch/arm/plat-stm32mp1/drivers/sub.mk | 3 +- + core/arch/arm/plat-stm32mp1/link.mk | 2 + + core/arch/arm/plat-stm32mp1/main.c | 354 ++++- + .../nsec-service/low_power_svc.c | 152 ++ + .../nsec-service/low_power_svc.h | 55 + + .../arm/plat-stm32mp1/nsec-service/pwr_svc.c | 89 ++ + .../arm/plat-stm32mp1/nsec-service/pwr_svc.h | 22 + + .../arm/plat-stm32mp1/nsec-service/rcc_svc.c | 139 ++ + .../arm/plat-stm32mp1/nsec-service/rcc_svc.h | 30 + + .../plat-stm32mp1/nsec-service/stm32mp1_smc.h | 196 ++- + .../nsec-service/stm32mp1_svc_setup.c | 79 +- + .../arm/plat-stm32mp1/nsec-service/sub.mk | 3 + + core/arch/arm/plat-stm32mp1/plat_tzc400.c | 52 +- + core/arch/arm/plat-stm32mp1/platform_config.h | 139 +- + core/arch/arm/plat-stm32mp1/pm/context.c | 522 +++++++ + core/arch/arm/plat-stm32mp1/pm/context.h | 102 ++ + .../plat-stm32mp1/pm/context_asm_defines.c | 28 + + core/arch/arm/plat-stm32mp1/pm/low_power.c | 626 ++++++++ + core/arch/arm/plat-stm32mp1/pm/pm_helpers.S | 729 +++++++++ + core/arch/arm/plat-stm32mp1/pm/power.h | 27 + + core/arch/arm/plat-stm32mp1/pm/power_config.c | 252 +++ + core/arch/arm/plat-stm32mp1/pm/psci.c | 234 ++- + core/arch/arm/plat-stm32mp1/pm/sub.mk | 6 + + core/arch/arm/plat-stm32mp1/remoteproc_pta.c | 528 +++++++ + core/arch/arm/plat-stm32mp1/reset.S | 28 +- + core/arch/arm/plat-stm32mp1/rproc_pub_key.h | 16 + + core/arch/arm/plat-stm32mp1/scmi_server.c | 96 +- + .../arch/arm/plat-stm32mp1/shared_resources.c | 156 +- + core/arch/arm/plat-stm32mp1/stm32_util.h | 77 +- + core/arch/arm/plat-stm32mp1/stm32mp_pm.h | 21 + + core/arch/arm/plat-stm32mp1/sub.mk | 9 + + core/arch/arm/sm/pm_a32.S | 83 +- + core/arch/arm/tee/entry_std.c | 2 +- + .../clk/clk-stm32mp15.c} | 1345 +++++++++++++++- + core/drivers/clk/clk.c | 58 + + core/drivers/clk/sub.mk | 2 + + core/drivers/gic.c | 225 ++- + core/drivers/scmi-msg/clock.c | 4 +- + core/drivers/stm32_bsec.c | 111 +- + core/drivers/stm32_etzpc.c | 47 + + core/drivers/stm32_gpio.c | 23 +- + core/drivers/stm32_i2c.c | 37 +- + core/drivers/stm32_iwdg.c | 314 ++++ + core/drivers/stm32_rng.c | 7 +- + core/drivers/stm32_rtc.c | 446 ++++++ + core/drivers/stm32_tim.c | 298 ++++ + core/drivers/sub.mk | 4 + + core/include/drivers/clk.h | 35 + + core/include/drivers/gic.h | 24 + + core/include/drivers/stm32_bsec.h | 16 + + core/include/drivers/stm32_iwdg.h | 17 + + core/include/drivers/stm32_rtc.h | 60 + + core/include/drivers/stm32_tim.h | 25 + + .../drivers/stm32mp1_rcc.h | 38 +- + .../dt-bindings/clock/stm32mp1-clksrc.h | 284 ++++ + .../dt-bindings/power/stm32mp1-power.h | 19 + + .../dt-bindings/soc/st,stm32-etzpc.h} | 35 +- + core/include/kernel/interrupt.h | 15 + + core/include/kernel/panic.h | 6 + + core/kernel/interrupt.c | 10 + + core/kernel/panic.c | 23 +- + core/mm/vm.c | 42 +- + core/sub.mk | 7 +- + keys/default_rproc.pem | 27 + + lib/libutee/include/remoteproc_pta.h | 157 ++ + mk/config.mk | 4 + + mk/gcc.mk | 6 +- + scripts/sign_rproc_fw.py | 416 +++++ + ta/remoteproc/Makefile | 18 + + ta/remoteproc/elf_parser.c | 186 +++ + ta/remoteproc/include/elf32.h | 243 +++ + ta/remoteproc/include/elf_common.h | 1014 ++++++++++++ + ta/remoteproc/include/elf_parser.h | 59 + + ta/remoteproc/include/ta_remoteproc.h | 65 + + .../include/user_ta_header_defines.h | 29 + + ta/remoteproc/remoteproc_core.c | 781 ++++++++++ + ta/remoteproc/sub.mk | 3 + + ta/remoteproc/user_ta.mk | 1 + + 121 files changed, 14243 insertions(+), 3618 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 core/arch/arm/dts/stm32mp157a-ed1.dts create mode 100644 core/arch/arm/dts/stm32mp157a-ev1.dts @@ -123,20 +157,40 @@ Subject: [PATCH] 3.9.0-stm32mp-r1 create mode 100644 core/arch/arm/plat-stm32mp1/pm/pm_helpers.S create mode 100644 core/arch/arm/plat-stm32mp1/pm/power.h create mode 100644 core/arch/arm/plat-stm32mp1/pm/power_config.c + create mode 100644 core/arch/arm/plat-stm32mp1/remoteproc_pta.c + create mode 100644 core/arch/arm/plat-stm32mp1/rproc_pub_key.h create mode 100644 core/arch/arm/plat-stm32mp1/stm32mp_pm.h + rename core/{arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c => drivers/clk/clk-stm32mp15.c} (50%) + create mode 100644 core/drivers/clk/clk.c + create mode 100644 core/drivers/clk/sub.mk create mode 100644 core/drivers/stm32_iwdg.c create mode 100644 core/drivers/stm32_rtc.c create mode 100644 core/drivers/stm32_tim.c + create mode 100644 core/include/drivers/clk.h create mode 100644 core/include/drivers/stm32_iwdg.h create mode 100644 core/include/drivers/stm32_rtc.h create mode 100644 core/include/drivers/stm32_tim.h + rename core/{arch/arm/plat-stm32mp1 => include}/drivers/stm32mp1_rcc.h (95%) create mode 100644 core/include/dt-bindings/clock/stm32mp1-clksrc.h create mode 100644 core/include/dt-bindings/power/stm32mp1-power.h - create mode 100644 core/include/dt-bindings/soc/st,stm32-etzpc.h + rename core/{arch/arm/plat-stm32mp1/drivers/stm32mp1_etzpc.h => include/dt-bindings/soc/st,stm32-etzpc.h} (83%) + create mode 100644 keys/default_rproc.pem + create mode 100644 lib/libutee/include/remoteproc_pta.h + create mode 100755 scripts/sign_rproc_fw.py + create mode 100644 ta/remoteproc/Makefile + create mode 100644 ta/remoteproc/elf_parser.c + create mode 100644 ta/remoteproc/include/elf32.h + create mode 100644 ta/remoteproc/include/elf_common.h + create mode 100644 ta/remoteproc/include/elf_parser.h + create mode 100644 ta/remoteproc/include/ta_remoteproc.h + create mode 100644 ta/remoteproc/include/user_ta_header_defines.h + create mode 100644 ta/remoteproc/remoteproc_core.c + create mode 100644 ta/remoteproc/sub.mk + create mode 100644 ta/remoteproc/user_ta.mk diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 -index 0000000..3d1bacd +index 000000000..3d1bacd78 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,30 @@ @@ -171,7 +225,7 @@ index 0000000..3d1bacd + +Merge will not be done directly in GitHub but it will need first to follow internal integration process before public deliver in a standard release. The Pull request will stay open until it is merged and delivered. diff --git a/core/arch/arm/dts/stm32mp15-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15-pinctrl.dtsi -index 0237d4d..d3d1744 100644 +index 0237d4dda..16c40cbff 100644 --- a/core/arch/arm/dts/stm32mp15-pinctrl.dtsi +++ b/core/arch/arm/dts/stm32mp15-pinctrl.dtsi @@ -6,162 +6,6 @@ @@ -927,24 +981,28 @@ index 0237d4d..d3d1744 100644 sdmmc2_b4_pins_a: sdmmc2-b4-0 { pins1 { pinmux = , /* SDMMC2_D0 */ -@@ -834,41 +135,6 @@ +@@ -834,230 +135,220 @@ }; }; - sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 { -- pins1 { -- pinmux = , /* SDMMC2_D0 */ -- , /* SDMMC2_D1 */ -- , /* SDMMC2_D2 */ ++ sdmmc2_b4_pins_b: sdmmc2-b4-1 { + pins1 { + pinmux = , /* SDMMC2_D0 */ + , /* SDMMC2_D1 */ + , /* SDMMC2_D2 */ - ; /* SDMMC2_D3 */ -- slew-rate = <1>; -- drive-push-pull; ++ , /* SDMMC2_D3 */ ++ ; /* SDMMC2_CMD */ + slew-rate = <1>; + drive-push-pull; - bias-pull-up; -- }; -- pins2 { -- pinmux = ; /* SDMMC2_CK */ -- slew-rate = <2>; -- drive-push-pull; ++ bias-disable; + }; + pins2 { + pinmux = ; /* SDMMC2_CK */ + slew-rate = <2>; + drive-push-pull; - bias-pull-up; - }; - pins3 { @@ -952,55 +1010,102 @@ index 0237d4d..d3d1744 100644 - slew-rate = <1>; - drive-open-drain; - bias-pull-up; -- }; -- }; -- ++ bias-disable; + }; + }; + - sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 { -- pins { ++ sdmmc2_d47_pins_a: sdmmc2-d47-0 { + pins { - pinmux = , /* SDMMC2_D0 */ - , /* SDMMC2_D1 */ - , /* SDMMC2_D2 */ - , /* SDMMC2_D3 */ - , /* SDMMC2_CK */ - ; /* SDMMC2_CMD */ -- }; -- }; -- - sdmmc2_b4_pins_b: sdmmc2-b4-1 { ++ pinmux = , /* SDMMC2_D4 */ ++ , /* SDMMC2_D5 */ ++ , /* SDMMC2_D6 */ ++ ; /* SDMMC2_D7 */ ++ slew-rate = <1>; ++ drive-push-pull; ++ bias-pull-up; + }; + }; + +- sdmmc2_b4_pins_b: sdmmc2-b4-1 { ++ uart4_pins_a: uart4-0 { pins1 { - pinmux = , /* SDMMC2_D0 */ -@@ -888,30 +154,6 @@ +- pinmux = , /* SDMMC2_D0 */ +- , /* SDMMC2_D1 */ +- , /* SDMMC2_D2 */ +- , /* SDMMC2_D3 */ +- ; /* SDMMC2_CMD */ +- slew-rate = <1>; +- drive-push-pull; ++ pinmux = ; /* UART4_TX */ + bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; + }; + pins2 { +- pinmux = ; /* SDMMC2_CK */ +- slew-rate = <2>; +- drive-push-pull; ++ pinmux = ; /* UART4_RX */ + bias-disable; }; }; - sdmmc2_b4_od_pins_b: sdmmc2-b4-od-1 { -- pins1 { ++ uart4_pins_b: uart4-1 { + pins1 { - pinmux = , /* SDMMC2_D0 */ - , /* SDMMC2_D1 */ - , /* SDMMC2_D2 */ - ; /* SDMMC2_D3 */ - slew-rate = <1>; - drive-push-pull; -- bias-disable; ++ pinmux = ; /* UART4_TX */ + bias-disable; - }; - pins2 { - pinmux = ; /* SDMMC2_CK */ - slew-rate = <2>; -- drive-push-pull; + drive-push-pull; - bias-disable; -- }; ++ slew-rate = <0>; + }; - pins3 { - pinmux = ; /* SDMMC2_CMD */ - slew-rate = <1>; - drive-open-drain; -- bias-disable; -- }; -- }; -- - sdmmc2_d47_pins_a: sdmmc2-d47-0 { - pins { - pinmux = , /* SDMMC2_D4 */ -@@ -924,140 +166,120 @@ ++ pins2 { ++ pinmux = ; /* UART4_RX */ + bias-disable; + }; + }; + +- sdmmc2_d47_pins_a: sdmmc2-d47-0 { +- pins { +- pinmux = , /* SDMMC2_D4 */ +- , /* SDMMC2_D5 */ +- , /* SDMMC2_D6 */ +- ; /* SDMMC2_D7 */ +- slew-rate = <1>; ++ uart7_pins_a: uart7-0 { ++ pins1 { ++ pinmux = ; /* UART7_TX */ ++ bias-disable; + drive-push-pull; +- bias-pull-up; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = , /* UART7_RX */ ++ , /* UART7_CTS */ ++ ; /* UART7_RTS */ ++ bias-disable; }; }; @@ -1010,11 +1115,21 @@ index 0237d4d..d3d1744 100644 - , /* SDMMC2_D5 */ - , /* SDMMC2_D6 */ - ; /* SDMMC2_D7 */ -- }; -- }; -- ++ uart7_pins_b: uart7-1 { ++ pins1 { ++ pinmux = ; /* UART7_TX */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = ; /* UART7_RX */ ++ bias-disable; + }; + }; + - sdmmc3_b4_pins_a: sdmmc3-b4-0 { -+ uart4_pins_a: uart4-0 { ++ uart7_pins_c: uart7-2 { pins1 { - pinmux = , /* SDMMC3_D0 */ - , /* SDMMC3_D1 */ @@ -1022,7 +1137,7 @@ index 0237d4d..d3d1744 100644 - , /* SDMMC3_D3 */ - ; /* SDMMC3_CMD */ - slew-rate = <1>; -+ pinmux = ; /* UART4_TX */ ++ pinmux = ; /* UART7_TX */ + bias-disable; drive-push-pull; - bias-pull-up; @@ -1032,21 +1147,20 @@ index 0237d4d..d3d1744 100644 - pinmux = ; /* SDMMC3_CK */ - slew-rate = <2>; - drive-push-pull; -- bias-pull-up; -+ pinmux = ; /* UART4_RX */ -+ bias-disable; ++ pinmux = ; /* UART7_RX */ + bias-pull-up; }; }; - sdmmc3_b4_od_pins_a: sdmmc3-b4-od-0 { -+ uart4_pins_b: uart4-1 { ++ uart8_pins_a: uart8-0 { pins1 { - pinmux = , /* SDMMC3_D0 */ - , /* SDMMC3_D1 */ - , /* SDMMC3_D2 */ - ; /* SDMMC3_D3 */ - slew-rate = <1>; -+ pinmux = ; /* UART4_TX */ ++ pinmux = ; /* UART8_TX */ + bias-disable; drive-push-pull; - bias-pull-up; @@ -1063,7 +1177,7 @@ index 0237d4d..d3d1744 100644 - slew-rate = <1>; - drive-open-drain; - bias-pull-up; -+ pinmux = ; /* UART4_RX */ ++ pinmux = ; /* UART8_RX */ + bias-disable; }; }; @@ -1076,22 +1190,35 @@ index 0237d4d..d3d1744 100644 - , /* SDMMC3_D3 */ - , /* SDMMC3_CK */ - ; /* SDMMC3_CMD */ -+ uart7_pins_a: uart7-0 { ++ usart2_pins_a: usart2-0 { + pins1 { -+ pinmux = ; /* UART4_TX */ ++ pinmux = , /* USART2_TX */ ++ ; /* USART2_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; ++ }; ++ pins2 { ++ pinmux = , /* USART2_RX */ ++ ; /* USART2_CTS_NSS */ ++ bias-disable; }; -- }; -- + }; + - spdifrx_pins_a: spdifrx-0 { - pins { - pinmux = ; /* SPDIF_IN1 */ ++ usart2_pins_b: usart2-1 { ++ pins1 { ++ pinmux = , /* USART2_TX */ ++ ; /* USART2_RTS */ ++ bias-disable; ++ drive-push-pull; ++ slew-rate = <0>; ++ }; + pins2 { -+ pinmux = , /* UART4_RX */ -+ , /* UART4_CTS */ -+ ; /* UART4_RTS */ ++ pinmux = , /* USART2_RX */ ++ ; /* USART2_CTS_NSS */ bias-disable; }; }; @@ -1099,40 +1226,39 @@ index 0237d4d..d3d1744 100644 - spdifrx_sleep_pins_a: spdifrx-1 { - pins { - pinmux = ; /* SPDIF_IN1 */ -+ uart7_pins_b: uart7-1 { ++ usart2_pins_c: usart2-2 { + pins1 { -+ pinmux = ; /* USART7_TX */ ++ pinmux = , /* USART2_TX */ ++ ; /* USART2_RTS */ + bias-disable; + drive-push-pull; -+ slew-rate = <0>; ++ slew-rate = <3>; + }; + pins2 { -+ pinmux = ; /* USART7_RX */ ++ pinmux = , /* USART2_RX */ ++ ; /* USART2_CTS_NSS */ + bias-disable; }; }; - uart4_pins_a: uart4-0 { -+ usart2_pins_a: usart2-0 { ++ usart3_pins_a: usart3-0 { pins1 { - pinmux = ; /* UART4_TX */ -+ pinmux = , /* USART2_TX */ -+ ; /* USART2_RTS */ ++ pinmux = ; /* USART3_TX */ bias-disable; drive-push-pull; -- slew-rate = <0>; -+ slew-rate = <3>; + slew-rate = <0>; }; pins2 { - pinmux = ; /* UART4_RX */ -+ pinmux = , /* USART2_RX */ -+ ; /* USART2_CTS_NSS */ ++ pinmux = ; /* USART3_RX */ bias-disable; }; }; - uart4_pins_b: uart4-1 { -+ usart3_pins_a: usart3-0 { ++ usart3_pins_b: usart3-1 { pins1 { - pinmux = ; /* UART4_TX */ + pinmux = , /* USART3_TX */ @@ -1150,7 +1276,7 @@ index 0237d4d..d3d1744 100644 }; - uart7_pins_a: uart7-0 { -+ usart3_pins_b: usart3-1 { ++ usart3_pins_c: usart3-2 { pins1 { - pinmux = ; /* UART4_TX */ + pinmux = , /* USART3_TX */ @@ -1163,16 +1289,17 @@ index 0237d4d..d3d1744 100644 - pinmux = , /* UART4_RX */ - , /* UART4_CTS */ - ; /* UART4_RTS */ +- bias-disable; + pinmux = , /* USART3_RX */ + ; /* USART3_CTS_NSS */ - bias-disable; ++ bias-pull-up; }; }; -}; -&pinctrl_z { - i2c2_pins_b2: i2c2-0 { -+ usbotg_hs_pins_a: usbotg_hs-0 { ++ usbotg_hs_pins_a: usbotg-hs-0 { pins { - pinmux = ; /* I2C2_SCL */ - bias-disable; @@ -1196,7 +1323,7 @@ index 0237d4d..d3d1744 100644 i2c4_pins_a: i2c4-0 { pins { pinmux = , /* I2C4_SCL */ -@@ -1067,26 +289,4 @@ +@@ -1067,26 +358,4 @@ slew-rate = <0>; }; }; @@ -1224,10 +1351,10 @@ index 0237d4d..d3d1744 100644 - }; }; diff --git a/core/arch/arm/dts/stm32mp151.dtsi b/core/arch/arm/dts/stm32mp151.dtsi -index d8ac702..6e6dff4 100644 +index d8ac70292..714d94710 100644 --- a/core/arch/arm/dts/stm32mp151.dtsi +++ b/core/arch/arm/dts/stm32mp151.dtsi -@@ -19,9 +19,39 @@ +@@ -19,9 +19,41 @@ compatible = "arm,cortex-a7"; device_type = "cpu"; reg = <0>; @@ -1253,7 +1380,8 @@ index d8ac702..6e6dff4 100644 + <&nand_otp>, + <&uid_otp>, + <&package_otp>, -+ <&hw2_otp>; ++ <&hw2_otp>, ++ <&pkh_otp>; + + nvmem-cell-names = "cfg0_otp", + "part_number_otp", @@ -1261,13 +1389,14 @@ index d8ac702..6e6dff4 100644 + "nand_otp", + "uid_otp", + "package_otp", -+ "hw2_otp"; ++ "hw2_otp", ++ "pkh_otp"; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; -@@ -35,15 +65,6 @@ +@@ -35,15 +67,6 @@ <0xa0022000 0x2000>; }; @@ -1283,7 +1412,7 @@ index d8ac702..6e6dff4 100644 clocks { clk_hse: clk-hse { #clock-cells = <0>; -@@ -76,37 +97,6 @@ +@@ -76,37 +99,6 @@ }; }; @@ -1321,7 +1450,7 @@ index d8ac702..6e6dff4 100644 soc { compatible = "simple-bus"; #address-cells = <1>; -@@ -114,175 +104,6 @@ +@@ -114,175 +106,6 @@ interrupt-parent = <&intc>; ranges; @@ -1497,7 +1626,7 @@ index d8ac702..6e6dff4 100644 timers12: timer@40006000 { #address-cells = <1>; #size-cells = <0>; -@@ -291,152 +112,7 @@ +@@ -291,152 +114,7 @@ clocks = <&rcc TIM12_K>; clock-names = "int"; status = "disabled"; @@ -1651,7 +1780,7 @@ index d8ac702..6e6dff4 100644 }; usart2: serial@4000e000 { -@@ -444,6 +120,7 @@ +@@ -444,6 +122,7 @@ reg = <0x4000e000 0x400>; interrupts = ; clocks = <&rcc USART2_K>; @@ -1659,7 +1788,7 @@ index d8ac702..6e6dff4 100644 status = "disabled"; }; -@@ -452,14 +129,17 @@ +@@ -452,14 +131,17 @@ reg = <0x4000f000 0x400>; interrupts = ; clocks = <&rcc USART3_K>; @@ -1678,7 +1807,7 @@ index d8ac702..6e6dff4 100644 status = "disabled"; }; -@@ -468,99 +148,16 @@ +@@ -468,99 +150,16 @@ reg = <0x40011000 0x400>; interrupts = ; clocks = <&rcc UART5_K>; @@ -1780,7 +1909,7 @@ index d8ac702..6e6dff4 100644 status = "disabled"; }; -@@ -569,125 +166,16 @@ +@@ -569,125 +168,16 @@ reg = <0x40019000 0x400>; interrupts = ; clocks = <&rcc UART8_K>; @@ -1908,7 +2037,7 @@ index d8ac702..6e6dff4 100644 status = "disabled"; }; -@@ -698,401 +186,42 @@ +@@ -698,401 +188,42 @@ reg = <0x44006000 0x400>; clocks = <&rcc TIM15_K>; clock-names = "int"; @@ -2258,7 +2387,7 @@ index d8ac702..6e6dff4 100644 usbotg_hs: usb-otg@49000000 { - compatible = "snps,dwc2"; -+ compatible = "st,stm32mp1-hsotg", "snps,dwc2"; ++ compatible = "st,stm32mp15-hsotg", "snps,dwc2"; reg = <0x49000000 0x10000>; clocks = <&rcc USBO_K>; clock-names = "otg"; @@ -2303,7 +2432,8 @@ index d8ac702..6e6dff4 100644 }; rcc: rcc@50000000 { - compatible = "st,stm32mp1-rcc", "syscon"; +- compatible = "st,stm32mp1-rcc", "syscon"; ++ compatible = "st,stm32mp1-rcc-secure", "st,stm32mp1-rcc", "syscon"; reg = <0x50000000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; @@ -2321,12 +2451,12 @@ index d8ac702..6e6dff4 100644 reg11: reg11 { regulator-name = "reg11"; -@@ -1113,11 +242,35 @@ +@@ -1113,11 +244,35 @@ }; }; + pwr_mcu: pwr_mcu@50001014 { -+ compatible = "syscon"; ++ compatible = "st,stm32mp151-pwr-mcu", "syscon"; + reg = <0x50001014 0x4>; + }; + @@ -2357,7 +2487,7 @@ index d8ac702..6e6dff4 100644 }; syscfg: syscon@50020000 { -@@ -1126,143 +279,14 @@ +@@ -1126,143 +281,14 @@ clocks = <&rcc SYSCFG>; }; @@ -2502,12 +2632,13 @@ index d8ac702..6e6dff4 100644 }; rng1: rng@54003000 { -@@ -1271,16 +295,7 @@ +@@ -1271,35 +297,37 @@ clocks = <&rcc RNG1_K>; resets = <&rcc RNG1_R>; status = "disabled"; -- }; -- ++ secure-status = "disabled"; + }; + - mdma1: dma-controller@58000000 { - compatible = "st,stm32h7-mdma"; - reg = <0x58000000 0x1000>; @@ -2516,22 +2647,54 @@ index d8ac702..6e6dff4 100644 - #dma-cells = <5>; - dma-channels = <32>; - dma-requests = <48>; -+ secure-status = "disabled"; - }; - - fmc: nand-controller@58002000 { -@@ -1293,10 +308,6 @@ - <0x89010000 0x1000>, - <0x89020000 0x1000>; - interrupts = ; +- }; +- +- fmc: nand-controller@58002000 { +- compatible = "st,stm32mp15-fmc2"; +- reg = <0x58002000 0x1000>, +- <0x80000000 0x1000>, +- <0x88010000 0x1000>, +- <0x88020000 0x1000>, +- <0x81000000 0x1000>, +- <0x89010000 0x1000>, +- <0x89020000 0x1000>; +- interrupts = ; - dmas = <&mdma1 20 0x10 0x12000a02 0x0 0x0>, - <&mdma1 20 0x10 0x12000a08 0x0 0x0>, - <&mdma1 21 0x10 0x12000a0a 0x0 0x0>; - dma-names = "tx", "rx", "ecc"; ++ 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"; -@@ -1307,18 +318,15 @@ ++ ++ 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 = ; ++ status = "disabled"; ++ }; + }; + + qspi: spi@58003000 { +@@ -1307,18 +335,17 @@ reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; reg-names = "qspi", "qspi_mm"; interrupts = ; @@ -2540,6 +2703,8 @@ index d8ac702..6e6dff4 100644 - dma-names = "tx", "rx"; clocks = <&rcc QSPI_K>; resets = <&rcc QSPI_R>; ++ #address-cells = <1>; ++ #size-cells = <0>; status = "disabled"; }; @@ -2553,7 +2718,7 @@ index d8ac702..6e6dff4 100644 interrupts = ; interrupt-names = "cmd_irq"; clocks = <&rcc SDMMC1_K>; -@@ -1331,9 +339,9 @@ +@@ -1331,9 +358,9 @@ }; sdmmc2: sdmmc@58007000 { @@ -2566,7 +2731,7 @@ index d8ac702..6e6dff4 100644 interrupts = ; interrupt-names = "cmd_irq"; clocks = <&rcc SDMMC2_K>; -@@ -1345,87 +353,26 @@ +@@ -1345,87 +372,26 @@ status = "disabled"; }; @@ -2659,7 +2824,7 @@ index d8ac702..6e6dff4 100644 status = "disabled"; usbphyc_port0: usb-phy@0 { -@@ -1446,6 +393,7 @@ +@@ -1446,6 +412,7 @@ clocks = <&rcc USART1_K>; resets = <&rcc USART1_R>; status = "disabled"; @@ -2667,7 +2832,7 @@ index d8ac702..6e6dff4 100644 }; spi6: spi@5c001000 { -@@ -1456,22 +404,34 @@ +@@ -1456,22 +423,34 @@ interrupts = ; clocks = <&rcc SPI6_K>; resets = <&rcc SPI6_R>; @@ -2708,7 +2873,7 @@ index d8ac702..6e6dff4 100644 }; rtc: rtc@5c004000 { -@@ -1479,21 +439,47 @@ +@@ -1479,8 +458,9 @@ reg = <0x5c004000 0x400>; clocks = <&rcc RTCAPB>, <&rcc RTC>; clock-names = "pclk", "rtc_ck"; @@ -2718,9 +2883,8 @@ index d8ac702..6e6dff4 100644 + secure-status = "disabled"; }; -- bsec: efuse@5c005000 { -+ bsec: nvmem@5c005000 { - compatible = "st,stm32mp15-bsec"; + bsec: efuse@5c005000 { +@@ -1488,13 +468,38 @@ reg = <0x5c005000 0x400>; #address-cells = <1>; #size-cells = <1>; @@ -2752,13 +2916,15 @@ index d8ac702..6e6dff4 100644 ts_cal2: calib@5e { reg = <0x5e 0x2>; }; +- mac_addr: mac_addr@e4 { + pkh_otp: pkh_otp@60 { + reg = <0x60 0x20>; + }; - mac_addr: mac_addr@e4 { ++ ethernet_mac_address: mac@e4 { reg = <0xe4 0x8>; st,non-secure-otp; -@@ -1508,17 +494,32 @@ + }; +@@ -1508,17 +513,32 @@ secure-status = "okay"; }; @@ -2794,7 +2960,7 @@ index d8ac702..6e6dff4 100644 }; /* -@@ -1675,28 +676,8 @@ +@@ -1675,28 +695,8 @@ st,bank-name = "GPIOZ"; st,bank-ioport = <11>; status = "disabled"; @@ -2825,7 +2991,7 @@ index d8ac702..6e6dff4 100644 - }; }; diff --git a/core/arch/arm/dts/stm32mp153.dtsi b/core/arch/arm/dts/stm32mp153.dtsi -index 2d759fc..617380a 100644 +index 2d759fc60..617380a52 100644 --- a/core/arch/arm/dts/stm32mp153.dtsi +++ b/core/arch/arm/dts/stm32mp153.dtsi @@ -12,34 +12,9 @@ @@ -2867,7 +3033,7 @@ index 2d759fc..617380a 100644 }; }; diff --git a/core/arch/arm/dts/stm32mp157.dtsi b/core/arch/arm/dts/stm32mp157.dtsi -index 3f0a4a9..c834029 100644 +index 3f0a4a91c..c83402907 100644 --- a/core/arch/arm/dts/stm32mp157.dtsi +++ b/core/arch/arm/dts/stm32mp157.dtsi @@ -5,27 +5,3 @@ @@ -2899,7 +3065,7 @@ index 3f0a4a9..c834029 100644 - }; -}; diff --git a/core/arch/arm/dts/stm32mp157a-dk1.dts b/core/arch/arm/dts/stm32mp157a-dk1.dts -index bc9ee69..4d506bc 100644 +index bc9ee69e6..5d5c0a5f7 100644 --- a/core/arch/arm/dts/stm32mp157a-dk1.dts +++ b/core/arch/arm/dts/stm32mp157a-dk1.dts @@ -7,17 +7,20 @@ @@ -2946,8 +3112,8 @@ index bc9ee69..4d506bc 100644 + DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) @@ -2955,10 +3121,10 @@ index bc9ee69..4d506bc 100644 }; diff --git a/core/arch/arm/dts/stm32mp157a-ed1.dts b/core/arch/arm/dts/stm32mp157a-ed1.dts new file mode 100644 -index 0000000..4f84ec6 +index 000000000..1527b642a --- /dev/null +++ b/core/arch/arm/dts/stm32mp157a-ed1.dts -@@ -0,0 +1,46 @@ +@@ -0,0 +1,38 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -2980,14 +3146,6 @@ index 0000000..4f84ec6 + chosen { + stdout-path = "serial0:115200n8"; + }; -+ -+ aliases { -+ serial0 = &uart4; -+ }; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vddcore>; +}; + +&etzpc { @@ -2998,8 +3156,8 @@ index 0000000..4f84ec6 + DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) @@ -3007,10 +3165,10 @@ index 0000000..4f84ec6 +}; diff --git a/core/arch/arm/dts/stm32mp157a-ev1.dts b/core/arch/arm/dts/stm32mp157a-ev1.dts new file mode 100644 -index 0000000..c577a90 +index 000000000..3cb35698a --- /dev/null +++ b/core/arch/arm/dts/stm32mp157a-ev1.dts -@@ -0,0 +1,23 @@ +@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -3030,12 +3188,13 @@ index 0000000..c577a90 + }; + + aliases { ++ serial0 = &uart4; + serial1 = &usart3; + }; +}; + diff --git a/core/arch/arm/dts/stm32mp157c-dk2.dts b/core/arch/arm/dts/stm32mp157c-dk2.dts -index c5b226d..436a159 100644 +index c5b226de6..ff5c4509f 100644 --- a/core/arch/arm/dts/stm32mp157c-dk2.dts +++ b/core/arch/arm/dts/stm32mp157c-dk2.dts @@ -11,14 +11,17 @@ @@ -3148,15 +3307,15 @@ index c5b226d..436a159 100644 + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) + >; }; diff --git a/core/arch/arm/dts/stm32mp157c-ed1.dts b/core/arch/arm/dts/stm32mp157c-ed1.dts -index ea301c5..5aadb1f 100644 +index ea301c550..8d8014751 100644 --- a/core/arch/arm/dts/stm32mp157c-ed1.dts +++ b/core/arch/arm/dts/stm32mp157c-ed1.dts @@ -1,7 +1,7 @@ @@ -3180,10 +3339,11 @@ index ea301c5..5aadb1f 100644 / { model = "STMicroelectronics STM32MP157C eval daughter"; -@@ -20,361 +20,32 @@ +@@ -19,362 +19,25 @@ + chosen { stdout-path = "serial0:115200n8"; }; - +- - memory@c0000000 { - device_type = "memory"; - reg = <0xC0000000 0x40000000>; @@ -3236,9 +3396,9 @@ index ea301c5..5aadb1f 100644 - }; - }; - - aliases { - serial0 = &uart4; - }; +- aliases { +- serial0 = &uart4; +- }; - - sd_switch: regulator-sd_switch { - compatible = "regulator-gpio"; @@ -3438,20 +3598,17 @@ index ea301c5..5aadb1f 100644 - status = "disabled"; - }; - }; - }; - +-}; +- -&ipcc { - status = "okay"; -+&cpu1 { -+ cpu-supply = <&vddcore>; - }; - +-}; +- -&iwdg2 { - timeout-sec = <32>; -+&cryp1 { - status = "okay"; - }; - +- status = "okay"; +-}; +- -&m4_rproc { - memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, - <&vdev0vring1>, <&vdev0buffer>; @@ -3469,12 +3626,13 @@ index ea301c5..5aadb1f 100644 - -&rng1 { - status = "okay"; --}; -- + }; + -&rtc { -- status = "okay"; --}; -- ++&cryp1 { + status = "okay"; + }; + -&sdmmc1 { - pinctrl-names = "default", "opendrain", "sleep"; - pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; @@ -3553,15 +3711,15 @@ index ea301c5..5aadb1f 100644 + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) + >; }; diff --git a/core/arch/arm/dts/stm32mp157c-ev1.dts b/core/arch/arm/dts/stm32mp157c-ev1.dts -index fd8c958..dd7da41 100644 +index fd8c958b0..d12d30093 100644 --- a/core/arch/arm/dts/stm32mp157c-ev1.dts +++ b/core/arch/arm/dts/stm32mp157c-ev1.dts @@ -1,13 +1,12 @@ @@ -3581,11 +3739,10 @@ index fd8c958..dd7da41 100644 / { model = "STMicroelectronics STM32MP157C eval daughter on eval mother"; -@@ -18,347 +17,6 @@ - }; +@@ -19,346 +18,6 @@ aliases { -- serial0 = &uart4; + serial0 = &uart4; - ethernet0 = ðernet0; + serial1 = &usart3; }; @@ -3932,10 +4089,10 @@ index fd8c958..dd7da41 100644 }; diff --git a/core/arch/arm/dts/stm32mp157d-dk1.dts b/core/arch/arm/dts/stm32mp157d-dk1.dts new file mode 100644 -index 0000000..d320f99 +index 000000000..79297b831 --- /dev/null +++ b/core/arch/arm/dts/stm32mp157d-dk1.dts -@@ -0,0 +1,49 @@ +@@ -0,0 +1,45 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -3966,10 +4123,6 @@ index 0000000..d320f99 + }; +}; + -+&cpu1 { -+ cpu-supply = <&vddcore>; -+}; -+ +&etzpc { + st,decprot = < + DECPROT(STM32MP1_ETZPC_USART1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) @@ -3978,8 +4131,8 @@ index 0000000..d320f99 + DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) @@ -3987,10 +4140,10 @@ index 0000000..d320f99 +}; diff --git a/core/arch/arm/dts/stm32mp157d-ed1.dts b/core/arch/arm/dts/stm32mp157d-ed1.dts new file mode 100644 -index 0000000..76f0614 +index 000000000..2c67ec0ac --- /dev/null +++ b/core/arch/arm/dts/stm32mp157d-ed1.dts -@@ -0,0 +1,46 @@ +@@ -0,0 +1,39 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -4012,15 +4165,8 @@ index 0000000..76f0614 + chosen { + stdout-path = "serial0:115200n8"; + }; -+ -+ aliases { -+ serial0 = &uart4; -+ }; +}; + -+&cpu1 { -+ cpu-supply = <&vddcore>; -+}; + +&etzpc { + st,decprot = < @@ -4030,8 +4176,8 @@ index 0000000..76f0614 + DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) @@ -4039,10 +4185,10 @@ index 0000000..76f0614 +}; diff --git a/core/arch/arm/dts/stm32mp157d-ev1.dts b/core/arch/arm/dts/stm32mp157d-ev1.dts new file mode 100644 -index 0000000..47d962b +index 000000000..4a40f5fe5 --- /dev/null +++ b/core/arch/arm/dts/stm32mp157d-ev1.dts -@@ -0,0 +1,22 @@ +@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -4062,15 +4208,16 @@ index 0000000..47d962b + }; + + aliases { ++ serial0 = &uart4; + serial1 = &usart3; + }; +}; diff --git a/core/arch/arm/dts/stm32mp157f-dk2.dts b/core/arch/arm/dts/stm32mp157f-dk2.dts new file mode 100644 -index 0000000..9c79bfb +index 000000000..680ca0f6e --- /dev/null +++ b/core/arch/arm/dts/stm32mp157f-dk2.dts -@@ -0,0 +1,55 @@ +@@ -0,0 +1,51 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -4102,10 +4249,6 @@ index 0000000..9c79bfb + }; +}; + -+&cpu1 { -+ cpu-supply = <&vddcore>; -+}; -+ +&cryp1 { + status = "okay"; +}; @@ -4119,8 +4262,8 @@ index 0000000..9c79bfb + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) @@ -4128,10 +4271,10 @@ index 0000000..9c79bfb +}; diff --git a/core/arch/arm/dts/stm32mp157f-ed1.dts b/core/arch/arm/dts/stm32mp157f-ed1.dts new file mode 100644 -index 0000000..a659cf8 +index 000000000..1aa26cdbb --- /dev/null +++ b/core/arch/arm/dts/stm32mp157f-ed1.dts -@@ -0,0 +1,51 @@ +@@ -0,0 +1,43 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -4153,14 +4296,6 @@ index 0000000..a659cf8 + chosen { + stdout-path = "serial0:115200n8"; + }; -+ -+ aliases { -+ serial0 = &uart4; -+ }; -+}; -+ -+&cpu1{ -+ cpu-supply = <&vddcore>; +}; + +&cryp1 { @@ -4176,8 +4311,8 @@ index 0000000..a659cf8 + DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) + DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) ++ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) + DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) @@ -4185,10 +4320,10 @@ index 0000000..a659cf8 +}; diff --git a/core/arch/arm/dts/stm32mp157f-ev1.dts b/core/arch/arm/dts/stm32mp157f-ev1.dts new file mode 100644 -index 0000000..c8598ce +index 000000000..caf5dfe11 --- /dev/null +++ b/core/arch/arm/dts/stm32mp157f-ev1.dts -@@ -0,0 +1,22 @@ +@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved @@ -4208,12 +4343,13 @@ index 0000000..c8598ce + }; + + aliases { ++ serial0 = &uart4; + serial1 = &usart3; + }; +}; diff --git a/core/arch/arm/dts/stm32mp15xa.dtsi b/core/arch/arm/dts/stm32mp15xa.dtsi new file mode 100644 -index 0000000..5ed7e59 +index 000000000..5ed7e594f --- /dev/null +++ b/core/arch/arm/dts/stm32mp15xa.dtsi @@ -0,0 +1,13 @@ @@ -4231,7 +4367,7 @@ index 0000000..5ed7e59 + }; +}; diff --git a/core/arch/arm/dts/stm32mp15xc.dtsi b/core/arch/arm/dts/stm32mp15xc.dtsi -index b06a55a..68d822d 100644 +index b06a55a2f..68d822d8c 100644 --- a/core/arch/arm/dts/stm32mp15xc.dtsi +++ b/core/arch/arm/dts/stm32mp15xc.dtsi @@ -4,6 +4,8 @@ @@ -4253,7 +4389,7 @@ index b06a55a..68d822d 100644 }; diff --git a/core/arch/arm/dts/stm32mp15xd.dtsi b/core/arch/arm/dts/stm32mp15xd.dtsi new file mode 100644 -index 0000000..18b05ee +index 000000000..18b05ee38 --- /dev/null +++ b/core/arch/arm/dts/stm32mp15xd.dtsi @@ -0,0 +1,19 @@ @@ -4278,7 +4414,7 @@ index 0000000..18b05ee +}; diff --git a/core/arch/arm/dts/stm32mp15xf.dtsi b/core/arch/arm/dts/stm32mp15xf.dtsi new file mode 100644 -index 0000000..526a162 +index 000000000..526a1627c --- /dev/null +++ b/core/arch/arm/dts/stm32mp15xf.dtsi @@ -0,0 +1,21 @@ @@ -4304,7 +4440,7 @@ index 0000000..526a162 + }; +}; diff --git a/core/arch/arm/dts/stm32mp15xx-dkx.dtsi b/core/arch/arm/dts/stm32mp15xx-dkx.dtsi -index f6672e8..7254f9a 100644 +index f6672e87a..236cff932 100644 --- a/core/arch/arm/dts/stm32mp15xx-dkx.dtsi +++ b/core/arch/arm/dts/stm32mp15xx-dkx.dtsi @@ -4,8 +4,8 @@ @@ -4580,132 +4716,29 @@ index f6672e8..7254f9a 100644 pwr_sw1-supply = <&bst_out>; pwr_sw2-supply = <&bst_out>; -@@ -248,6 +87,16 @@ - regulator-always-on; - regulator-initial-mode = <0>; - regulator-over-current-protection; -+ lp-stop { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1200000>; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - vdd_ddr: buck2 { -@@ -257,6 +106,17 @@ - regulator-always-on; - regulator-initial-mode = <0>; - regulator-over-current-protection; -+ lp-stop { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - vdd: buck3 { -@@ -267,6 +127,18 @@ - st,mask-reset; - regulator-initial-mode = <0>; - regulator-over-current-protection; -+ lp-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; - }; - - v3v3: buck4 { -@@ -276,6 +148,16 @@ - regulator-always-on; - regulator-over-current-protection; - regulator-initial-mode = <0>; -+ lp-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; - - v1v8_audio: ldo1 { -@@ -283,7 +165,12 @@ +@@ -283,7 +122,6 @@ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-always-on; - interrupts = ; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; }; v3v3_hdmi: ldo2 { -@@ -291,7 +178,12 @@ +@@ -291,7 +129,6 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-always-on; - interrupts = ; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; }; vtt_ddr: ldo3 { -@@ -300,21 +192,41 @@ - regulator-max-microvolt = <750000>; - regulator-always-on; - regulator-over-current-protection; -+ lp-stop { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; - }; +@@ -304,16 +141,12 @@ vdd_usb: ldo4 { regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; - interrupts = ; -+ regulator-always-on; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; }; vdda: ldo5 { @@ -4714,41 +4747,18 @@ index f6672e8..7254f9a 100644 regulator-max-microvolt = <2900000>; - interrupts = ; regulator-boot-on; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; }; - v1v2_hdmi: ldo6 { -@@ -322,265 +234,200 @@ +@@ -322,7 +155,6 @@ regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; regulator-always-on; - interrupts = ; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; }; vref_ddr: vref_ddr { - regulator-name = "vref_ddr"; - regulator-always-on; +@@ -331,295 +163,339 @@ regulator-over-current-protection; -+ lp-stop { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; }; - bst_out: boost { @@ -4783,62 +4793,33 @@ index f6672e8..7254f9a 100644 - watchdog { - compatible = "st,stpmic1-wdt"; - status = "disabled"; -- }; -- }; --}; -- ++ }; + }; + }; + }; + -&i2s2 { - clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc PLL3_Q>, <&rcc PLL3_R>; - clock-names = "pclk", "i2sclk", "x8k", "x11k"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&i2s2_pins_a>; - pinctrl-1 = <&i2s2_pins_sleep_a>; -- status = "okay"; ++&iwdg2 { ++ timeout-sec = <32>; ++ secure-timeout-sec = <5>; + status = "okay"; - - i2s2_port: port { - i2s2_endpoint: endpoint { - remote-endpoint = <&sii9022_tx_endpoint>; - format = "i2s"; - mclk-fs = <256>; -+ }; - }; - }; - }; - --&ipcc { -- status = "okay"; --}; -- - &iwdg2 { - timeout-sec = <32>; - status = "okay"; +- }; +- }; + secure-status = "okay"; }; --<dc { -- pinctrl-names = "default", "sleep"; -- pinctrl-0 = <<dc_pins_a>; -- pinctrl-1 = <<dc_pins_sleep_a>; -- status = "okay"; -- -- port { -- #address-cells = <1>; -- #size-cells = <0>; -- -- ltdc_ep0_out: endpoint@0 { -- reg = <0>; -- remote-endpoint = <&sii9022_in>; -- }; -- }; --}; -- --&m4_rproc { -- memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, -- <&vdev0vring1>, <&vdev0buffer>; -- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; -- mbox-names = "vq0", "vq1", "shutdown"; -- interrupt-parent = <&exti>; -- interrupts = <68 1>; +-&ipcc { - status = "okay"; +&nvmem_layout { + nvmem-cells = <&cfg0_otp>, @@ -4862,17 +4843,25 @@ index f6672e8..7254f9a 100644 + "board_id"; }; - &pwr_regulators { +-&iwdg2 { +- timeout-sec = <32>; +- status = "okay"; ++&pwr_regulators { + system_suspend_supported_soc_modes = < + STM32_PM_CSLEEP_RUN + STM32_PM_CSTOP_ALLOW_LP_STOP + STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR + >; + system_off_soc_mode = ; - vdd-supply = <&vdd>; - vdd_3v3_usbfs-supply = <&vdd_usb>; ++ vdd-supply = <&vdd>; ++ vdd_3v3_usbfs-supply = <&vdd_usb>; }; +-<dc { +- pinctrl-names = "default", "sleep"; +- pinctrl-0 = <<dc_pins_a>; +- pinctrl-1 = <<dc_pins_sleep_a>; +- status = "okay"; +&rcc { + st,hsi-cal; + st,csi-cal; @@ -4948,7 +4937,10 @@ index f6672e8..7254f9a 100644 + cfg = <2 65 1 0 0 PQR(1,1,1)>; + frac = <0x1400>; + }; -+ + +- port { +- #address-cells = <1>; +- #size-cells = <0>; + /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ + pll3: st,pll@2 { + compatible = "st,stm32mp1-pll"; @@ -4956,32 +4948,70 @@ index f6672e8..7254f9a 100644 + cfg = <1 33 1 16 36 PQR(1,1,1)>; + frac = <0x1a04>; + }; -+ + +- ltdc_ep0_out: endpoint@0 { +- reg = <0>; +- remote-endpoint = <&sii9022_in>; +- }; + /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ + pll4: st,pll@3 { + compatible = "st,stm32mp1-pll"; + reg = <3>; + cfg = <3 98 5 7 7 PQR(1,1,1)>; -+ }; -+}; -+ - &rng1 { + }; + }; + +-&m4_rproc { +- memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, +- <&vdev0vring1>, <&vdev0buffer>; +- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; +- mbox-names = "vq0", "vq1", "shutdown"; +- interrupt-parent = <&exti>; +- interrupts = <68 1>; ++&rng1 { status = "okay"; + secure-status = "okay"; }; - &rtc { +-&pwr_regulators { +- vdd-supply = <&vdd>; +- vdd_3v3_usbfs-supply = <&vdd_usb>; ++&rtc { ++ status = "okay"; ++ secure-status = "okay"; + }; + +-&rng1 { ++&sdmmc1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc1_b4_pins_a>; ++ disable-wp; ++ st,neg-edge; ++ bus-width = <4>; ++ vmmc-supply = <&v3v3>; status = "okay"; --}; -- + }; + +-&rtc { +- status = "okay"; ++&timers15 { ++ secure-status = "okay"; ++ st,hsi-cal-input = <7>; ++ st,csi-cal-input = <8>; + }; + -&sai2 { - clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>; - clock-names = "pclk", "x8k", "x11k"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>; - pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>; -- status = "okay"; -- ++&uart4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_pins_a>; + status = "okay"; ++}; + - sai2a: audio-controller@4400b004 { - #clock-cells = <0>; - dma-names = "tx"; @@ -4999,14 +5029,25 @@ index f6672e8..7254f9a 100644 - }; - }; - }; -- ++&uart7 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart7_pins_c>; ++ status = "disabled"; ++}; + - sai2b: audio-controller@4400b024 { - dma-names = "rx"; - st,sync = <&sai2a 2>; - clocks = <&rcc SAI2_K>, <&sai2a>; - clock-names = "sai_ck", "MCLK"; - status = "okay"; -- ++&usart3 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usart3_pins_c>; ++ uart-has-rtscts; ++ status = "disabled"; ++}; + - sai2b_port: port { - sai2b_endpoint: endpoint { - remote-endpoint = <&cs42l51_rx_endpoint>; @@ -5017,20 +5058,23 @@ index f6672e8..7254f9a 100644 - }; - }; - }; -+ secure-status = "okay"; ++&usbotg_hs { ++ phys = <&usbphyc_port1 0>; ++ phy-names = "usb2-phy"; ++ usb-role-switch; ++ status = "okay"; }; - &sdmmc1 { +-&sdmmc1 { - pinctrl-names = "default", "opendrain", "sleep"; -+ pinctrl-names = "default"; - pinctrl-0 = <&sdmmc1_b4_pins_a>; +- pinctrl-0 = <&sdmmc1_b4_pins_a>; - pinctrl-1 = <&sdmmc1_b4_od_pins_a>; - pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; - broken-cd; -+ disable-wp; - st,neg-edge; - bus-width = <4>; - vmmc-supply = <&v3v3>; +- st,neg-edge; +- bus-width = <4>; +- vmmc-supply = <&v3v3>; ++&usbphyc { status = "okay"; }; @@ -5044,8 +5088,10 @@ index f6672e8..7254f9a 100644 - bus-width = <4>; - vmmc-supply = <&v3v3>; - status = "disabled"; --}; -- ++&usbphyc_port0 { ++ phy-supply = <&vdd_usb>; + }; + -&timers1 { - /* spare dmas for other usage */ - /delete-property/dmas; @@ -5060,8 +5106,10 @@ index f6672e8..7254f9a 100644 - timer@0 { - status = "okay"; - }; --}; -- ++&usbphyc_port1 { ++ phy-supply = <&vdd_usb>; + }; + -&timers3 { - /delete-property/dmas; - /delete-property/dma-names; @@ -5071,12 +5119,18 @@ index f6672e8..7254f9a 100644 - pinctrl-1 = <&pwm3_sleep_pins_a>; - pinctrl-names = "default", "sleep"; - status = "okay"; -- }; ++/* Low-power states of regulators */ ++&v1v2_hdmi { ++ standby-ddr-sr { ++ regulator-off-in-suspend; + }; - timer@2 { - status = "okay"; -- }; --}; -- ++ standby-ddr-off { ++ regulator-off-in-suspend; + }; + }; + -&timers4 { - /delete-property/dmas; - /delete-property/dma-names; @@ -5086,12 +5140,17 @@ index f6672e8..7254f9a 100644 - pinctrl-1 = <&pwm4_sleep_pins_a &pwm4_sleep_pins_b>; - pinctrl-names = "default", "sleep"; - status = "okay"; -- }; ++&v1v8_audio { ++ standby-ddr-sr { ++ regulator-off-in-suspend; + }; - timer@3 { - status = "okay"; -- }; --}; -- ++ standby-ddr-off { ++ regulator-off-in-suspend; + }; + }; + -&timers5 { - /delete-property/dmas; - /delete-property/dma-names; @@ -5101,10 +5160,16 @@ index f6672e8..7254f9a 100644 - pinctrl-1 = <&pwm5_sleep_pins_a>; - pinctrl-names = "default", "sleep"; - status = "okay"; -- }; ++&v3v3 { ++ lp-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; + }; - timer@4 { - status = "okay"; -- }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; + }; -}; - -&timers6 { @@ -5113,9 +5178,11 @@ index f6672e8..7254f9a 100644 - status = "disabled"; - timer@5 { - status = "okay"; -- }; --}; -- ++ standby-ddr-off { ++ regulator-off-in-suspend; + }; + }; + -&timers12 { - /delete-property/dmas; - /delete-property/dma-names; @@ -5125,71 +5192,133 @@ index f6672e8..7254f9a 100644 - pinctrl-1 = <&pwm12_sleep_pins_a>; - pinctrl-names = "default", "sleep"; - status = "okay"; -- }; ++&v3v3_hdmi { ++ standby-ddr-sr { ++ regulator-off-in-suspend; + }; - timer@11 { - status = "okay"; -- }; -+&timers15 { -+ secure-status = "okay"; -+ st,hsi-cal-input = <7>; -+ st,csi-cal-input = <8>; ++ standby-ddr-off { ++ regulator-off-in-suspend; + }; }; - &uart4 { -@@ -589,15 +436,23 @@ - status = "okay"; +-&uart4 { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart4_pins_a>; +- status = "okay"; ++&vdd { ++ lp-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; }; -&usbh_ehci { - phys = <&usbphyc_port0>; - status = "okay"; -+&uart7 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart7_pins_b>; -+ status = "disabled"; -+}; -+ -+&usart3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usart3_pins_b>; -+ uart-has-rtscts; -+ status = "disabled"; ++&vdda { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; }; - &usbotg_hs { +-&usbotg_hs { - dr_mode = "peripheral"; - phys = <&usbphyc_port1 0>; - phy-names = "usb2-phy"; -+ usb-role-switch; - status = "okay"; +- phys = <&usbphyc_port1 0>; +- phy-names = "usb2-phy"; +- status = "okay"; ++&vddcore { ++ lp-stop { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1200000>; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; }; -@@ -607,19 +462,8 @@ - - &usbphyc_port0 { - phy-supply = <&vdd_usb>; -- vdda1v1-supply = <®11>; -- vdda1v8-supply = <®18>; +-&usbphyc { +- status = "okay"; ++&vdd_ddr { ++ lp-stop { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; }; - &usbphyc_port1 { - phy-supply = <&vdd_usb>; +-&usbphyc_port0 { +- phy-supply = <&vdd_usb>; - vdda1v1-supply = <®11>; - vdda1v8-supply = <®18>; --}; -- ++&vdd_usb { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; + }; + +-&usbphyc_port1 { +- phy-supply = <&vdd_usb>; +- vdda1v1-supply = <®11>; +- vdda1v8-supply = <®18>; ++&vref_ddr { ++ lp-stop { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; + }; + -&vrefbuf { - regulator-min-microvolt = <2500000>; - regulator-max-microvolt = <2500000>; - vdda-supply = <&vdd>; - status = "okay"; ++&vtt_ddr { ++ lp-stop { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; }; diff --git a/core/arch/arm/dts/stm32mp15xx-edx.dtsi b/core/arch/arm/dts/stm32mp15xx-edx.dtsi new file mode 100644 -index 0000000..b7683a6 +index 000000000..ef51b00af --- /dev/null +++ b/core/arch/arm/dts/stm32mp15xx-edx.dtsi -@@ -0,0 +1,478 @@ +@@ -0,0 +1,517 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2017 - All Rights Reserved @@ -5205,6 +5334,10 @@ index 0000000..b7683a6 + reg = <0xC0000000 0x40000000>; + }; + ++ aliases { ++ serial0 = &uart4; ++ }; ++ + vin: vin { + compatible = "regulator-fixed"; + regulator-name = "vin"; @@ -5229,6 +5362,10 @@ index 0000000..b7683a6 + cpu-supply = <&vddcore>; +}; + ++&cpu1{ ++ cpu-supply = <&vddcore>; ++}; ++ +&hash1 { + status = "okay"; +}; @@ -5275,20 +5412,6 @@ index 0000000..b7683a6 + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; -+ lp-stop { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1200000>; -+ }; -+ lplv-stop { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vdd_ddr: buck2 { @@ -5298,21 +5421,6 @@ index 0000000..b7683a6 + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; -+ lp-stop { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ lplv-stop { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vdd: buck3 { @@ -5323,22 +5431,6 @@ index 0000000..b7683a6 + st,mask-reset; + regulator-initial-mode = <0>; + regulator-over-current-protection; -+ lp-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ lplv-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; + }; + + v3v3: buck4 { @@ -5348,36 +5440,18 @@ index 0000000..b7683a6 + regulator-always-on; + regulator-over-current-protection; + regulator-initial-mode = <0>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vdda: ldo1 { + regulator-name = "vdda"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + v2v8: ldo2 { + regulator-name = "v2v8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vtt_ddr: ldo3 { @@ -5386,31 +5460,10 @@ index 0000000..b7683a6 + regulator-max-microvolt = <750000>; + regulator-always-on; + regulator-over-current-protection; -+ lp-stop { -+ regulator-off-in-suspend; -+ }; -+ lplv-stop { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vdd_usb: ldo4 { + regulator-name = "vdd_usb"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vdd_sd: ldo5 { @@ -5418,42 +5471,18 @@ index 0000000..b7683a6 + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + regulator-boot-on; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + v1v8: ldo6 { + regulator-name = "v1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + vref_ddr: vref_ddr { + regulator-name = "vref_ddr"; + regulator-always-on; + regulator-over-current-protection; -+ lp-stop { -+ regulator-on-in-suspend; -+ }; -+ lplv-stop { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; + }; + + bst_out: boost { @@ -5474,6 +5503,7 @@ index 0000000..b7683a6 + +&iwdg2 { + timeout-sec = <32>; ++ secure-timeout-sec = <5>; + status = "okay"; + secure-status = "okay"; +}; @@ -5627,7 +5657,6 @@ index 0000000..b7683a6 + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-ddr50; -+ sd-uhs-sdr104; + status = "okay"; +}; + @@ -5668,12 +5697,151 @@ index 0000000..b7683a6 +&usbphyc_port1 { + phy-supply = <&vdd_usb>; +}; ++ ++/* Low-power states of regulators */ ++&v1v8 { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v2v8 { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v3v3 { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd { ++ lp-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ lplv-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++}; ++ ++&vdda { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vddcore { ++ lp-stop { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1200000>; ++ }; ++ lplv-stop { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_ddr { ++ lp-stop { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ lplv-stop { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_sd { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_usb { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vref_ddr { ++ lp-stop { ++ regulator-on-in-suspend; ++ }; ++ lplv-stop { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vtt_ddr { ++ lp-stop { ++ regulator-off-in-suspend; ++ }; ++ lplv-stop { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; diff --git a/core/arch/arm/dts/stm32mp15xx-evx.dtsi b/core/arch/arm/dts/stm32mp15xx-evx.dtsi new file mode 100644 -index 0000000..fee2bac +index 000000000..ce1982d45 --- /dev/null +++ b/core/arch/arm/dts/stm32mp15xx-evx.dtsi -@@ -0,0 +1,71 @@ +@@ -0,0 +1,73 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2017 - All Rights Reserved @@ -5684,14 +5852,16 @@ index 0000000..fee2bac + pinctrl-names = "default"; + pinctrl-0 = <&fmc_pins_a>; + status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; + -+ nand@0 { -+ reg = <0>; -+ nand-on-flash-bbt; -+ #address-cells = <1>; -+ #size-cells = <1>; ++ nand-controller@4,0 { ++ status = "okay"; ++ ++ nand@0 { ++ reg = <0>; ++ nand-on-flash-bbt; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; + }; +}; + @@ -5729,7 +5899,7 @@ index 0000000..fee2bac + +&usart3 { + pinctrl-names = "default"; -+ pinctrl-0 = <&usart3_pins_a>; ++ pinctrl-0 = <&usart3_pins_b>; + uart-has-rtscts; + status = "disabled"; +}; @@ -5746,18 +5916,9 @@ index 0000000..fee2bac + status = "okay"; +}; diff --git a/core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi -index 04f7a43..341529b 100644 +index 04f7a43ad..4f4130eff 100644 --- a/core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi +++ b/core/arch/arm/dts/stm32mp15xxaa-pinctrl.dtsi -@@ -1,7 +1,7 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* - * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -- * Author: Alexandre Torgue for STMicroelectronics. -+ * Author: Alexandre Torgue - */ - - &pinctrl { @@ -79,6 +79,7 @@ gpioz: gpio@54004000 { @@ -5766,32 +5927,10 @@ index 04f7a43..341529b 100644 ngpios = <8>; gpio-ranges = <&pinctrl_z 0 400 8>; }; -diff --git a/core/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi -index 328dad1..d29af89 100644 ---- a/core/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi -+++ b/core/arch/arm/dts/stm32mp15xxab-pinctrl.dtsi -@@ -1,7 +1,7 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* - * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -- * Author: Alexandre Torgue for STMicroelectronics. -+ * Author: Alexandre Torgue - */ - - &pinctrl { diff --git a/core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi -index 7eaa245..02070bb 100644 +index 7eaa245f4..866c050da 100644 --- a/core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi +++ b/core/arch/arm/dts/stm32mp15xxac-pinctrl.dtsi -@@ -1,7 +1,7 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* - * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -- * Author: Alexandre Torgue for STMicroelectronics. -+ * Author: Alexandre Torgue - */ - - &pinctrl { @@ -67,6 +67,7 @@ gpioz: gpio@54004000 { @@ -5800,21 +5939,8 @@ index 7eaa245..02070bb 100644 ngpios = <8>; gpio-ranges = <&pinctrl_z 0 400 8>; }; -diff --git a/core/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi -index b63e207..023f540 100644 ---- a/core/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi -+++ b/core/arch/arm/dts/stm32mp15xxad-pinctrl.dtsi -@@ -1,7 +1,7 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* - * Copyright (C) STMicroelectronics 2019 - All Rights Reserved -- * Author: Alexandre Torgue for STMicroelectronics. -+ * Author: Alexandre Torgue - */ - - &pinctrl { diff --git a/core/arch/arm/include/arm32.h b/core/arch/arm/include/arm32.h -index 286f4e7..4a6f7a2 100644 +index f28b73fda..2f67cc762 100644 --- a/core/arch/arm/include/arm32.h +++ b/core/arch/arm/include/arm32.h @@ -1,6 +1,6 @@ @@ -5825,7 +5951,7 @@ index 286f4e7..4a6f7a2 100644 * Copyright (c) 2014, STMicroelectronics International N.V. */ -@@ -162,6 +162,15 @@ +@@ -163,6 +163,15 @@ #define IDPFR1_GENTIMER_SHIFT 16 #define IDPFR1_GENTIMER_MASK (0xF << IDPFR1_GENTIMER_SHIFT) @@ -5841,11 +5967,41 @@ index 286f4e7..4a6f7a2 100644 #ifndef __ASSEMBLER__ #include #ifdef CFG_ARM_GICV3 +diff --git a/core/arch/arm/include/kernel/tlb_helpers.h b/core/arch/arm/include/kernel/tlb_helpers.h +index d33dd5c01..2dbcbcf08 100644 +--- a/core/arch/arm/include/kernel/tlb_helpers.h ++++ b/core/arch/arm/include/kernel/tlb_helpers.h +@@ -25,11 +25,10 @@ static inline void tlbi_mva_allasid_nosync(vaddr_t va) + #endif + } + +-static inline void tlbi_mva_asid(vaddr_t va, uint32_t asid) ++static inline void tlbi_mva_asid_nosync(vaddr_t va, uint32_t asid) + { + uint32_t a = asid & TLBI_ASID_MASK; + +- dsb_ishst(); + #ifdef ARM64 + tlbi_vale1is((va >> TLBI_MVA_SHIFT) | SHIFT_U64(a, TLBI_ASID_SHIFT)); + tlbi_vale1is((va >> TLBI_MVA_SHIFT) | +@@ -38,6 +37,12 @@ static inline void tlbi_mva_asid(vaddr_t va, uint32_t asid) + write_tlbimvais((va & ~(BIT32(TLBI_MVA_SHIFT) - 1)) | a); + write_tlbimvais((va & ~(BIT32(TLBI_MVA_SHIFT) - 1)) | a | 1); + #endif ++} ++ ++static inline void tlbi_mva_asid(vaddr_t va, uint32_t asid) ++{ ++ dsb_ishst(); ++ tlbi_mva_asid_nosync(va, asid); + dsb_ish(); + isb(); + } diff --git a/core/arch/arm/include/mm/core_mmu.h b/core/arch/arm/include/mm/core_mmu.h -index a3dbdc0..05db229 100644 +index 33ee2ebd7..bf8e68607 100644 --- a/core/arch/arm/include/mm/core_mmu.h +++ b/core/arch/arm/include/mm/core_mmu.h -@@ -96,6 +96,7 @@ +@@ -97,6 +97,7 @@ * MEM_AREA_NSEC_SHM: NonSecure shared RAM between NSec and TEE. * MEM_AREA_RAM_NSEC: NonSecure RAM storing data * MEM_AREA_RAM_SEC: Secure RAM storing some secrets @@ -5853,7 +6009,7 @@ index a3dbdc0..05db229 100644 * MEM_AREA_IO_NSEC: NonSecure HW mapped registers * MEM_AREA_IO_SEC: Secure HW mapped registers * MEM_AREA_EXT_DT: Memory loads external device tree -@@ -120,6 +121,7 @@ enum teecore_memtypes { +@@ -121,6 +122,7 @@ enum teecore_memtypes { MEM_AREA_NSEC_SHM, MEM_AREA_RAM_NSEC, MEM_AREA_RAM_SEC, @@ -5861,7 +6017,7 @@ index a3dbdc0..05db229 100644 MEM_AREA_IO_NSEC, MEM_AREA_IO_SEC, MEM_AREA_EXT_DT, -@@ -149,6 +151,7 @@ static inline const char *teecore_memtype_name(enum teecore_memtypes type) +@@ -150,6 +152,7 @@ static inline const char *teecore_memtype_name(enum teecore_memtypes type) [MEM_AREA_NSEC_SHM] = "NSEC_SHM", [MEM_AREA_RAM_NSEC] = "RAM_NSEC", [MEM_AREA_RAM_SEC] = "RAM_SEC", @@ -5869,8 +6025,58 @@ index a3dbdc0..05db229 100644 [MEM_AREA_IO_NSEC] = "IO_NSEC", [MEM_AREA_IO_SEC] = "IO_SEC", [MEM_AREA_EXT_DT] = "EXT_DT", +@@ -629,6 +632,18 @@ enum teecore_tlb_op { + /* TLB invalidation for a range of virtual address */ + void tlbi_mva_range(vaddr_t va, size_t size, size_t granule); + ++/* ++ * tlbi_mva_range_asid() - Invalidate TLB for virtual address range for ++ * a specific ASID ++ * @va: start virtual address, must be a multiple of @granule ++ * @len: length in bytes of range, must be a multiple of @granule ++ * @granule: granularity of mapping, supported values are ++ * CORE_MMU_PGDIR_SIZE or SMALL_PAGE_SIZE. This value must ++ * match the actual mappings. ++ * @asid: Address space identifier ++ */ ++void tlbi_mva_range_asid(vaddr_t va, size_t len, size_t granule, uint32_t asid); ++ + /* deprecated: please call straight tlbi_all() and friends */ + int core_tlb_maintenance(int op, unsigned long a) __deprecated; + +diff --git a/core/arch/arm/include/mm/pgt_cache.h b/core/arch/arm/include/mm/pgt_cache.h +index d19414e48..433dc3920 100644 +--- a/core/arch/arm/include/mm/pgt_cache.h ++++ b/core/arch/arm/include/mm/pgt_cache.h +@@ -23,8 +23,8 @@ struct ts_ctx; + + struct pgt { + void *tbl; +-#if defined(CFG_PAGED_USER_TA) + vaddr_t vabase; ++#if defined(CFG_PAGED_USER_TA) + struct ts_ctx *ctx; + size_t num_used_entries; + #endif +@@ -61,6 +61,8 @@ void pgt_alloc(struct pgt_cache *pgt_cache, struct ts_ctx *owning_ctx, + vaddr_t begin, vaddr_t last); + void pgt_free(struct pgt_cache *pgt_cache, bool save_ctx); + ++void pgt_clear_ctx_range(struct pgt_cache *pgt_cache, struct ts_ctx *ctx, ++ vaddr_t begin, vaddr_t end); + #ifdef CFG_PAGED_USER_TA + void pgt_flush_ctx_range(struct pgt_cache *pgt_cache, struct ts_ctx *ctx, + vaddr_t begin, vaddr_t last); +@@ -73,6 +75,7 @@ static inline void pgt_flush_ctx_range(struct pgt_cache *pgt_cache __unused, + } + #endif + ++ + void pgt_init(void); + + #if defined(CFG_PAGED_USER_TA) diff --git a/core/arch/arm/include/sm/pm.h b/core/arch/arm/include/sm/pm.h -index 939f966..90f031a 100644 +index 939f966e8..90f031a2b 100644 --- a/core/arch/arm/include/sm/pm.h +++ b/core/arch/arm/include/sm/pm.h @@ -34,7 +34,11 @@ @@ -5886,10 +6092,18 @@ index 939f966..90f031a 100644 /* suspend/resume core functions */ diff --git a/core/arch/arm/mm/core_mmu.c b/core/arch/arm/mm/core_mmu.c -index fced2df..2131d0b 100644 +index 4f27b2499..489dae220 100644 --- a/core/arch/arm/mm/core_mmu.c +++ b/core/arch/arm/mm/core_mmu.c -@@ -510,7 +510,6 @@ static bool pbuf_is_sdp_mem(paddr_t pbuf __unused, size_t len __unused) +@@ -388,6 +388,7 @@ void core_mmu_set_discovered_nsec_ddr(struct core_mmu_phys_mem *start, + carve_out_phys_mem(&m, &num_elems, map->pa, map->size); + break; + case MEM_AREA_EXT_DT: ++ case MEM_AREA_RAM_NSEC: + case MEM_AREA_RES_VASPACE: + case MEM_AREA_SHM_VASPACE: + case MEM_AREA_TA_VASPACE: +@@ -490,7 +491,6 @@ static bool pbuf_is_sdp_mem(paddr_t pbuf __unused, size_t len __unused) /* Check special memories comply with registered memories */ static void verify_special_mem_areas(struct tee_mmap_region *mem_map, @@ -5897,7 +6111,7 @@ index fced2df..2131d0b 100644 const struct core_mmu_phys_mem *start, const struct core_mmu_phys_mem *end, const char *area_name __maybe_unused) -@@ -518,7 +517,6 @@ static void verify_special_mem_areas(struct tee_mmap_region *mem_map, +@@ -498,7 +498,6 @@ static void verify_special_mem_areas(struct tee_mmap_region *mem_map, const struct core_mmu_phys_mem *mem; const struct core_mmu_phys_mem *mem2; struct tee_mmap_region *mmap; @@ -5905,28 +6119,27 @@ index fced2df..2131d0b 100644 if (start == end) { DMSG("No %s memory area defined", area_name); -@@ -545,15 +543,16 @@ static void verify_special_mem_areas(struct tee_mmap_region *mem_map, +@@ -524,9 +523,18 @@ static void verify_special_mem_areas(struct tee_mmap_region *mem_map, + /* * Check memories do not intersect any mapped memory. * This is called before reserved VA space is loaded in mem_map. - * -- * Only exception is with MEM_AREA_RAM_NSEC and MEM_AREA_NSEC_SHM, ++ * + * Exceptions are the memory areas that maps with the same attributes + * as for example MEM_AREA_RAM_NSEC and MEM_AREA_NSEC_SHM - * which may overlap since they are used for the same purpose - * except that MEM_AREA_NSEC_SHM is always mapped and - * MEM_AREA_RAM_NSEC only uses a dynamic mapping. ++ * which may overlap since they are used for the same purpose ++ * except that MEM_AREA_NSEC_SHM is always mapped and ++ * MEM_AREA_RAM_NSEC only uses a dynamic mapping. */ for (mem = start; mem < end; mem++) { - for (mmap = mem_map, n = 0; n < len; mmap++, n++) { -- if (mem->type == MEM_AREA_RAM_NSEC && -- mmap->type == MEM_AREA_NSEC_SHM) + for (mmap = mem_map; mmap->type != MEM_AREA_END; mmap++) { + if (core_mmu_type_to_attr(mem->type) == + core_mmu_type_to_attr(mmap->type)) - continue; ++ continue; if (core_is_buffer_intersect(mem->addr, mem->size, mmap->pa, mmap->size)) { -@@ -678,6 +677,8 @@ uint32_t core_mmu_type_to_attr(enum teecore_memtypes t) + MSG_MEM_INSTERSECT(mem->addr, mem->size, +@@ -650,6 +658,8 @@ uint32_t core_mmu_type_to_attr(enum teecore_memtypes t) case MEM_AREA_RAM_SEC: case MEM_AREA_SEC_RAM_OVERALL: return attr | TEE_MATTR_SECURE | TEE_MATTR_PRW | cached; @@ -5935,23 +6148,17 @@ index fced2df..2131d0b 100644 case MEM_AREA_RES_VASPACE: case MEM_AREA_SHM_VASPACE: return 0; -@@ -869,13 +870,13 @@ static size_t collect_mem_ranges(struct tee_mmap_region *memory_map, +@@ -841,8 +851,7 @@ static size_t collect_mem_ranges(struct tee_mmap_region *memory_map, } - #ifdef CFG_SECURE_DATA_PATH -- verify_special_mem_areas(memory_map, num_elems, phys_sdp_mem_begin, -+ verify_special_mem_areas(memory_map, phys_sdp_mem_begin, - phys_sdp_mem_end, "SDP"); - - check_sdp_intersection_with_nsec_ddr(); - #endif - -- verify_special_mem_areas(memory_map, num_elems, phys_nsec_ddr_begin, -+ verify_special_mem_areas(memory_map, phys_nsec_ddr_begin, - phys_nsec_ddr_end, "NSEC DDR"); + if (IS_ENABLED(CFG_SECURE_DATA_PATH)) +- verify_special_mem_areas(memory_map, num_elems, +- phys_sdp_mem_begin, ++ verify_special_mem_areas(memory_map, phys_sdp_mem_begin, + phys_sdp_mem_end, "SDP"); add_va_space(memory_map, num_elems, MEM_AREA_RES_VASPACE, -@@ -1176,6 +1177,7 @@ static void check_mem_map(struct tee_mmap_region *map) +@@ -1145,6 +1154,7 @@ static void check_mem_map(struct tee_mmap_region *map) case MEM_AREA_IO_NSEC: case MEM_AREA_EXT_DT: case MEM_AREA_RAM_SEC: @@ -5959,8 +6166,30 @@ index fced2df..2131d0b 100644 case MEM_AREA_RAM_NSEC: case MEM_AREA_RES_VASPACE: case MEM_AREA_SHM_VASPACE: +@@ -1395,6 +1405,21 @@ void tlbi_mva_range(vaddr_t va, size_t size, size_t granule) + isb(); + } + ++void tlbi_mva_range_asid(vaddr_t va, size_t len, size_t granule, uint32_t asid) ++{ ++ assert(granule == CORE_MMU_PGDIR_SIZE || granule == SMALL_PAGE_SIZE); ++ assert(!(va & (granule - 1)) && !(len & (granule - 1))); ++ ++ dsb_ishst(); ++ while (len) { ++ tlbi_mva_asid_nosync(va, asid); ++ len -= granule; ++ va += granule; ++ } ++ dsb_ish(); ++ isb(); ++} ++ + TEE_Result cache_op_inner(enum cache_op op, void *va, size_t len) + { + switch (op) { diff --git a/core/arch/arm/mm/mobj.c b/core/arch/arm/mm/mobj.c -index 65ab033..d1bbf32 100644 +index 7a129cf5a..b14e93939 100644 --- a/core/arch/arm/mm/mobj.c +++ b/core/arch/arm/mm/mobj.c @@ -49,6 +49,7 @@ static void *mobj_phys_get_va(struct mobj *mobj, size_t offset) @@ -5986,8 +6215,80 @@ index 65ab033..d1bbf32 100644 -driver_init_late(mobj_init); +service_init(mobj_init); +diff --git a/core/arch/arm/mm/pgt_cache.c b/core/arch/arm/mm/pgt_cache.c +index 3e854934d..988c1a351 100644 +--- a/core/arch/arm/mm/pgt_cache.c ++++ b/core/arch/arm/mm/pgt_cache.c +@@ -413,13 +413,65 @@ static void pgt_free_unlocked(struct pgt_cache *pgt_cache, + } + } + +-static struct pgt *pop_from_some_list(vaddr_t vabase __unused, ++static struct pgt *pop_from_some_list(vaddr_t vabase, + struct ts_ctx *ctx __unused) + { +- return pop_from_free_list(); ++ struct pgt *p = pop_from_free_list(); ++ ++ if (p) ++ p->vabase = vabase; ++ ++ return p; + } + #endif /*!CFG_PAGED_USER_TA*/ + ++static void clear_ctx_range_from_list(struct pgt_cache *pgt_cache, ++ void *ctx __maybe_unused, ++ vaddr_t begin, vaddr_t end) ++{ ++ struct pgt *p = NULL; ++#ifdef CFG_WITH_LPAE ++ uint64_t *tbl = NULL; ++#else ++ uint32_t *tbl = NULL; ++#endif ++ unsigned int idx = 0; ++ unsigned int n = 0; ++ ++ SLIST_FOREACH(p, pgt_cache, link) { ++ vaddr_t b = MAX(p->vabase, begin); ++ vaddr_t e = MIN(p->vabase + CORE_MMU_PGDIR_SIZE, end); ++ ++#ifdef CFG_PAGED_USER_TA ++ if (p->ctx != ctx) ++ continue; ++#endif ++ if (b >= e) ++ continue; ++ ++ tbl = p->tbl; ++ idx = (b - p->vabase) / SMALL_PAGE_SIZE; ++ n = (e - b) / SMALL_PAGE_SIZE; ++ memset(tbl + idx, 0, n * sizeof(*tbl)); ++ } ++} ++ ++void pgt_clear_ctx_range(struct pgt_cache *pgt_cache, struct ts_ctx *ctx, ++ vaddr_t begin, vaddr_t end) ++{ ++ mutex_lock(&pgt_mu); ++ ++ if (pgt_cache) ++ clear_ctx_range_from_list(pgt_cache, ctx, begin, end); ++#ifdef CFG_PAGED_USER_TA ++ clear_ctx_range_from_list(&pgt_cache_list, ctx, begin, end); ++#endif ++ ++ mutex_unlock(&pgt_mu); ++} ++ ++ ++ + static bool pgt_alloc_unlocked(struct pgt_cache *pgt_cache, struct ts_ctx *ctx, + vaddr_t begin, vaddr_t last) + { diff --git a/core/arch/arm/plat-stm32mp1/boot_api.h b/core/arch/arm/plat-stm32mp1/boot_api.h -index 62e38b5..a7daffd 100644 +index 62e38b588..a7daffd44 100644 --- a/core/arch/arm/plat-stm32mp1/boot_api.h +++ b/core/arch/arm/plat-stm32mp1/boot_api.h @@ -14,7 +14,9 @@ @@ -6001,7 +6302,7 @@ index 62e38b5..a7daffd 100644 /* Backup register #5: physical address of core1 entry at boot up */ #define BCKR_CORE1_BRANCH_ADDRESS 5 diff --git a/core/arch/arm/plat-stm32mp1/conf.mk b/core/arch/arm/plat-stm32mp1/conf.mk -index e82d2b9..8a449b5 100644 +index baf3fe49a..b1d41c92a 100644 --- a/core/arch/arm/plat-stm32mp1/conf.mk +++ b/core/arch/arm/plat-stm32mp1/conf.mk @@ -1,22 +1,41 @@ @@ -6051,27 +6352,44 @@ index e82d2b9..8a449b5 100644 ifneq ($(PLATFORM_FLAVOR),) ifeq ($(flavor_dts_file-$(PLATFORM_FLAVOR)),) -@@ -31,10 +50,13 @@ endif +@@ -31,9 +50,14 @@ endif include core/arch/arm/cpu/cortex-a7.mk ++$(call force,CFG_CLK_DRIVER,y) +$(call force,CFG_ARM_GIC_PM,y) $(call force,CFG_BOOT_SECONDARY_REQUEST,y) - $(call force,CFG_GENERIC_BOOT,y) $(call force,CFG_GIC,y) $(call force,CFG_INIT_CNTVOFF,y) +$(call force,CFG_PM,y) +$(call force,CFG_PM_ARM32,y) - $(call force,CFG_PM_STUBS,y) ++$(call force,CFG_PM_STUBS,y) $(call force,CFG_PSCI_ARM32,y) $(call force,CFG_SCMI_MSG_DRIVERS,y) -@@ -67,24 +89,36 @@ CFG_TEE_CORE_NB_CORE ?= 2 + $(call force,CFG_SCMI_MSG_CLOCK,y) +@@ -52,6 +76,8 @@ CFG_SHMEM_START ?= 0xdfe00000 + CFG_DRAM_SIZE ?= 0x20000000 + endif + ++CFG_DTB_MAX_SIZE ?= 0x20000 ++ + CFG_TZSRAM_START ?= 0x2ffc0000 + CFG_TZSRAM_SIZE ?= 0x0003f000 + CFG_STM32MP1_SCMI_SHM_BASE ?= 0x2ffff000 +@@ -65,23 +91,45 @@ CFG_DRAM_SIZE ?= 0x40000000 + CFG_TEE_CORE_NB_CORE ?= 2 CFG_WITH_PAGER ?= y CFG_WITH_LPAE ?= y - CFG_WITH_STACK_CANARIES ?= y -CFG_MMAP_REGIONS ?= 23 -+CFG_MMAP_REGIONS ?= 25 ++CFG_MMAP_REGIONS ?= 30 +CFG_CORE_HEAP_SIZE ?= 49152 ++CFG_DTB_MAX_SIZE = 0x20000 ++ ++# Disable early TA compression to limit HEAP size ++CFG_EARLY_TA_COMPRESS ?= n ++ ++# Embed public part of this key in OP-TEE OS ++CFG_RPROC_SIGN_KEY ?= keys/default_rproc.pem ifeq ($(CFG_EMBED_DTB_SOURCE_FILE),) # Some drivers mandate DT support @@ -6082,6 +6400,7 @@ index e82d2b9..8a449b5 100644 $(call force,CFG_STPMIC1,n) endif ++CFG_RPROC_PTA ?= n CFG_STM32_BSEC ?= y +CFG_STM32_CLKCALIB ?= y +CFG_STM32_CRYP ?= y @@ -6090,10 +6409,10 @@ index e82d2b9..8a449b5 100644 CFG_STM32_I2C ?= y +CFG_STM32_IWDG ?= y CFG_STM32_RNG ?= y --CFG_STM32_RNG ?= y +CFG_STM32_RTC ?= y +CFG_STM32_TIM ?= y CFG_STM32_UART ?= y ++CFG_STM32MP15_CLK ?= y CFG_STPMIC1 ?= y CFG_TZC400 ?= y @@ -6104,7 +6423,7 @@ index e82d2b9..8a449b5 100644 ifeq ($(CFG_STPMIC1),y) $(call force,CFG_STM32_I2C,y) $(call force,CFG_STM32_GPIO,y) -@@ -95,12 +129,23 @@ CFG_STM32MP_PANIC_ON_TZC_PERM_VIOLATION ?= y +@@ -92,12 +140,23 @@ CFG_STM32MP_PANIC_ON_TZC_PERM_VIOLATION ?= y # SiP/OEM service for non-secure world CFG_STM32_BSEC_SIP ?= y @@ -6128,18 +6447,26 @@ index e82d2b9..8a449b5 100644 CFG_TEE_CORE_DEBUG ?= n CFG_UNWIND ?= n CFG_LOCKDEP ?= n +@@ -108,3 +167,6 @@ CFG_WITH_NSEC_GPIOS ?= y + CFG_WITH_NSEC_UARTS ?= y + # UART instance used for early console (0 disables early console) + CFG_STM32_EARLY_CONSOLE_UART ?= 4 ++ ++# Generate the STM32 files ++CFG_STM32MP15x_STM32IMAGE ?= n diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c new file mode 100644 -index 0000000..b1b9f43 +index 000000000..d52f638eb --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c -@@ -0,0 +1,501 @@ +@@ -0,0 +1,507 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* -+ * Copyright (c) 2018, STMicroelectronics ++ * Copyright (c) 2018-2020, STMicroelectronics + */ + +#include ++#include +#include +#include +#include @@ -6147,9 +6474,9 @@ index 0000000..b1b9f43 +#include +#include +#include ++#include +#include +#include -+#include +#include +#include +#include @@ -6472,6 +6799,11 @@ index 0000000..b1b9f43 +{ + timer_val = period_sec * read_cntfrq(); + ++ if (timer_val > INT32_MAX) ++ timer_val = INT32_MAX; ++ ++ DMSG("Calibration timeout set to %"PRIu32, timer_val / read_cntfrq()); ++ + arm_timer(); +} + @@ -6570,7 +6902,7 @@ index 0000000..b1b9f43 + return -1; + } + -+ hsi_calib->ref_freq = stm32_clock_get_rate(CK_HSI); ++ hsi_calib->ref_freq = clk_get_rate(CK_HSI); + + hsi_calib->cal_ref = (io_read32(stm32_rcc_base() + RCC_HSICFGR) & + RCC_HSICFGR_HSICAL_MASK) >> @@ -6597,7 +6929,7 @@ index 0000000..b1b9f43 + return -1; + } + -+ csi_calib->ref_freq = stm32_clock_get_rate(CK_CSI); ++ csi_calib->ref_freq = clk_get_rate(CK_CSI); + + csi_calib->cal_ref = (io_read32(stm32_rcc_base() + RCC_CSICFGR) & + RCC_CSICFGR_CSICAL_MASK) >> @@ -6635,1400 +6967,9 @@ index 0000000..b1b9f43 + return TEE_SUCCESS; +} +driver_init(init_stm32mp1_calib); -diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c -index 47240ab..7912948 100644 ---- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c -+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c -@@ -6,20 +6,41 @@ - #include - #include - #include -+#include - #include - #include - #include -+#include - #include - #include - #include -+#include - #include - #include - #include - #include - #include -+#include - #include - #include - -+#define DT_OPP_COMPAT "operating-points-v2" -+ -+/* PLL settings computation related definitions */ -+#define POST_DIVM_MIN 8000000 -+#define POST_DIVM_MAX 16000000 -+#define DIVM_MIN 0 -+#define DIVM_MAX 63 -+#define DIVN_MIN 24 -+#define DIVN_MAX 99 -+#define DIVP_MIN 0 -+#define DIVP_MAX 127 -+#define FRAC_MAX 8192 -+#define VCO_MIN 800000000 -+#define VCO_MAX 1600000000 -+ -+#define PLL1_SETTINGS_VALID_ID 0x504C4C31 /* "PLL1" */ -+ - /* Identifiers for root oscillators */ - enum stm32mp_osc_id { - _HSI = 0, -@@ -85,11 +106,14 @@ enum stm32mp1_parent_sel { - _UART24_SEL, - _UART35_SEL, - _UART78_SEL, -+ _SDMMC12_SEL, -+ _SDMMC3_SEL, - _AXISS_SEL, - _MCUSS_SEL, - _USBPHY_SEL, - _USBO_SEL, - _RTC_SEL, -+ _MPU_SEL, - _PARENT_SEL_NB, - _UNKNOWN_SEL = 0xff, - }; -@@ -160,6 +184,16 @@ enum stm32mp1_div_id { - _DIV_NB, - }; - -+enum stm32mp1_pllcfg { -+ PLLCFG_M, -+ PLLCFG_N, -+ PLLCFG_P, -+ PLLCFG_Q, -+ PLLCFG_R, -+ PLLCFG_O, -+ PLLCFG_NB -+}; -+ - enum stm32mp1_plltype { - PLL_800, - PLL_1600, -@@ -212,6 +246,21 @@ struct stm32mp1_clk_pll { - enum stm32mp_osc_id refclk[REFCLK_SIZE]; - }; - -+struct stm32mp1_pll { -+ uint8_t refclk_min; -+ uint8_t refclk_max; -+ uint8_t divn_max; -+}; -+ -+/* Compact structure of 32bit cells, copied raw when suspending */ -+struct stm32mp1_pll_settings { -+ uint32_t valid_id; -+ uint32_t freq[PLAT_MAX_OPP_NB]; -+ uint32_t volt[PLAT_MAX_OPP_NB]; -+ uint32_t cfg[PLAT_MAX_OPP_NB][PLAT_MAX_PLLCFG_NB]; -+ uint32_t frac[PLAT_MAX_OPP_NB]; -+}; -+ - #define N_S 0 /* Non-secure can access RCC interface */ - #define SEC 1 /* RCC[TZEN] protects RCC interface */ - -@@ -380,6 +429,18 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { - _CLK_SC_FIXED(N_S, RCC_MP_APB3ENSETR, 11, SYSCFG, _UNKNOWN_ID), - _CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 8, DDRPERFM, _UNKNOWN_SEL), - _CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL), -+#ifdef STM32MP1_USE_MPU0_RESET -+ _CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 0, LTDC_PX, _UNKNOWN_SEL), -+ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 0, DMA1, _UNKNOWN_SEL), -+ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 1, DMA2, _UNKNOWN_SEL), -+ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 8, USBO_K, _USBO_SEL), -+ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL), -+ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 5, GPU, _UNKNOWN_SEL), -+ _CLK_SC_FIXED(N_S, RCC_MP_AHB6ENSETR, 10, ETHMAC, _ACLK), -+ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 16, SDMMC1_K, _SDMMC12_SEL), -+ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL), -+ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL), -+#endif - - _CLK_SELEC(N_S, RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL), - }; -@@ -406,6 +467,10 @@ static const uint8_t rng1_parents[] = { - _CSI, _PLL4_R, _LSE, _LSI - }; - -+static const uint8_t mpu_parents[] = { -+ _HSI, _HSE, _PLL1_P, _PLL1_P /* specific div */ -+}; -+ - /* Parents for (some) non-secure clocks */ - #ifdef CFG_WITH_NSEC_UARTS - static const uint8_t uart6_parents[] = { -@@ -429,6 +494,24 @@ static const uint8_t rtc_parents[] = { - _UNKNOWN_ID, _LSE, _LSI, _HSE - }; - -+#ifdef STM32MP1_USE_MPU0_RESET -+static const uint8_t usbphy_parents[] = { -+ _HSE_KER, _PLL4_R, _HSE_KER_DIV2 -+}; -+ -+static const uint8_t usbo_parents[] = { -+ _PLL4_R, _USB_PHY_48 -+}; -+ -+static const uint8_t sdmmc12_parents[] = { -+ _HCLK6, _PLL3_R, _PLL4_P, _HSI_KER -+}; -+ -+static const uint8_t sdmmc3_parents[] = { -+ _HCLK2, _PLL3_R, _PLL4_P, _HSI_KER -+}; -+#endif -+ - static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { - /* Secure aware clocks */ - _CLK_PARENT(_STGEN_SEL, RCC_STGENCKSELR, 0, 0x3, stgen_parents), -@@ -437,6 +520,9 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { - _CLK_PARENT(_USART1_SEL, RCC_UART1CKSELR, 0, 0x7, usart1_parents), - _CLK_PARENT(_RNG1_SEL, RCC_RNG1CKSELR, 0, 0x3, rng1_parents), - _CLK_PARENT(_RTC_SEL, RCC_BDCR, 0, 0x3, rtc_parents), -+ _CLK_PARENT(_MPU_SEL, RCC_MPCKSELR, 0, 0x3, mpu_parents), -+ _CLK_PARENT(_AXISS_SEL, RCC_ASSCKSELR, 0, 0x3, axiss_parents), -+ _CLK_PARENT(_MCUSS_SEL, RCC_MSSCKSELR, 0, 0x3, mcuss_parents), - /* Always non-secure clocks (maybe used in some way in secure world) */ - #ifdef CFG_WITH_NSEC_UARTS - _CLK_PARENT(_UART6_SEL, RCC_UART6CKSELR, 0, 0x7, uart6_parents), -@@ -444,8 +530,26 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { - _CLK_PARENT(_UART35_SEL, RCC_UART35CKSELR, 0, 0x7, uart234578_parents), - _CLK_PARENT(_UART78_SEL, RCC_UART78CKSELR, 0, 0x7, uart234578_parents), - #endif -- _CLK_PARENT(_AXISS_SEL, RCC_ASSCKSELR, 0, 0x3, axiss_parents), -- _CLK_PARENT(_MCUSS_SEL, RCC_MSSCKSELR, 0, 0x3, mcuss_parents), -+#ifdef STM32MP1_USE_MPU0_RESET -+ _CLK_PARENT(_SDMMC12_SEL, RCC_SDMMC12CKSELR, 0, 0x7, sdmmc12_parents), -+ _CLK_PARENT(_SDMMC3_SEL, RCC_SDMMC3CKSELR, 0, 0x7, sdmmc3_parents), -+ _CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents), -+ _CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents), -+#endif -+}; -+ -+/* Define characteristics of PLL according type */ -+static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = { -+ [PLL_800] = { -+ .refclk_min = 4, -+ .refclk_max = 16, -+ .divn_max = 99, -+ }, -+ [PLL_1600] = { -+ .refclk_min = 8, -+ .refclk_max = 16, -+ .divn_max = 199, -+ }, - }; - - /* PLLNCFGR2 register divider by output */ -@@ -549,6 +653,10 @@ static unsigned long osc_frequency(enum stm32mp_osc_id idx) - static unsigned int gate_refcounts[NB_GATES]; - static unsigned int refcount_lock; - -+/* Storage of the precomputed SoC settings for PLL1 various OPPs */ -+static struct stm32mp1_pll_settings pll1_settings; -+static uint32_t current_opp_khz; -+ - static const struct stm32mp1_clk_gate *gate_ref(unsigned int idx) - { - return &stm32mp1_clk_gate[idx]; -@@ -701,6 +809,152 @@ static unsigned long stm32mp1_read_pll_freq(enum stm32mp1_pll_id pll_id, - return dfout; - } - -+static void pll_start(enum stm32mp1_pll_id pll_id) -+{ -+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); -+ uint32_t pllxcr = stm32_rcc_base() + pll->pllxcr; -+ -+ if (io_read32(pllxcr) & RCC_PLLNCR_PLLON) -+ return; -+ -+ io_clrsetbits32(pllxcr, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | -+ RCC_PLLNCR_DIVREN, RCC_PLLNCR_PLLON); -+} -+ -+#define PLLRDY_TIMEOUT_US (200 * 1000) -+ -+static int pll_output(enum stm32mp1_pll_id pll_id, uint32_t output) -+{ -+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); -+ uint32_t pllxcr = stm32_rcc_base() + pll->pllxcr; -+ uint64_t start = 0; -+ -+ start = timeout_init_us(PLLRDY_TIMEOUT_US); -+ /* Wait PLL lock */ -+ while (!(io_read32(pllxcr) & RCC_PLLNCR_PLLRDY)) -+ if (timeout_elapsed(start)) { -+ EMSG("PLL%d start failed @ 0x%"PRIx32": 0x%"PRIx32, -+ pll_id, pllxcr, io_read32(pllxcr)); -+ return -1; -+ } -+ -+ /* Start the requested output */ -+ io_setbits32(pllxcr, output << RCC_PLLNCR_DIVEN_SHIFT); -+ -+ return 0; -+} -+ -+static int pll_stop(enum stm32mp1_pll_id pll_id) -+{ -+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); -+ uint32_t pllxcr = stm32_rcc_base() + pll->pllxcr; -+ uint64_t start = 0; -+ -+ /* Stop all output */ -+ io_clrbits32(pllxcr, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | -+ RCC_PLLNCR_DIVREN); -+ -+ /* Stop PLL */ -+ io_clrbits32(pllxcr, RCC_PLLNCR_PLLON); -+ -+ start = timeout_init_us(PLLRDY_TIMEOUT_US); -+ /* Wait PLL stopped */ -+ while (!(io_read32(pllxcr) & RCC_PLLNCR_PLLRDY)) -+ if (timeout_elapsed(start)) { -+ EMSG("PLL%d stop failed @ 0x%"PRIx32": 0x%"PRIx32, -+ pll_id, pllxcr, io_read32(pllxcr)); -+ -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static uint32_t pll_compute_pllxcfgr2(uint32_t *pllcfg) -+{ -+ uint32_t value = 0; -+ -+ value = (pllcfg[PLLCFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) & -+ RCC_PLLNCFGR2_DIVP_MASK; -+ value |= (pllcfg[PLLCFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) & -+ RCC_PLLNCFGR2_DIVQ_MASK; -+ value |= (pllcfg[PLLCFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) & -+ RCC_PLLNCFGR2_DIVR_MASK; -+ -+ return value; -+} -+ -+static void pll_config_output(enum stm32mp1_pll_id pll_id, uint32_t *pllcfg) -+{ -+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); -+ uintptr_t rcc_base = stm32_rcc_base(); -+ uint32_t value = 0; -+ -+ value = pll_compute_pllxcfgr2(pllcfg); -+ -+ io_write32(rcc_base + pll->pllxcfgr2, value); -+} -+ -+static int pll_compute_pllxcfgr1(const struct stm32mp1_clk_pll *pll, -+ uint32_t *pllcfg, uint32_t *cfgr1) -+{ -+ uint32_t rcc_base = stm32_rcc_base(); -+ enum stm32mp1_plltype type = pll->plltype; -+ unsigned long refclk = 0; -+ uint32_t ifrge = 0; -+ uint32_t src = 0; -+ -+ src = io_read32(rcc_base + pll->rckxselr) & -+ RCC_SELR_REFCLK_SRC_MASK; -+ -+ refclk = osc_frequency(pll->refclk[src]) / -+ (pllcfg[PLLCFG_M] + 1U); -+ -+ if ((refclk < (stm32mp1_pll[type].refclk_min * 1000000U)) || -+ (refclk > (stm32mp1_pll[type].refclk_max * 1000000U))) -+ return -1; -+ -+ if ((type == PLL_800) && (refclk >= 8000000U)) -+ ifrge = 1U; -+ -+ *cfgr1 = (pllcfg[PLLCFG_N] << RCC_PLLNCFGR1_DIVN_SHIFT) & -+ RCC_PLLNCFGR1_DIVN_MASK; -+ *cfgr1 |= (pllcfg[PLLCFG_M] << RCC_PLLNCFGR1_DIVM_SHIFT) & -+ RCC_PLLNCFGR1_DIVM_MASK; -+ *cfgr1 |= (ifrge << RCC_PLLNCFGR1_IFRGE_SHIFT) & -+ RCC_PLLNCFGR1_IFRGE_MASK; -+ -+ return 0; -+} -+ -+static int pll_config(enum stm32mp1_pll_id pll_id, uint32_t *pllcfg, -+ uint32_t fracv) -+{ -+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); -+ uint32_t rcc_base = stm32_rcc_base(); -+ uint32_t value = 0; -+ int ret = 0; -+ -+ ret = pll_compute_pllxcfgr1(pll, pllcfg, &value); -+ if (ret) -+ return ret; -+ -+ io_write32(rcc_base + pll->pllxcfgr1, value); -+ -+ /* Fractional configuration */ -+ io_write32(rcc_base + pll->pllxfracr, value); -+ -+ /* Frac must be enabled only once its configuration is loaded */ -+ value = fracv << RCC_PLLNFRACR_FRACV_SHIFT; -+ io_write32(rcc_base + pll->pllxfracr, value); -+ value = io_read32(rcc_base + pll->pllxfracr); -+ io_write32(rcc_base + pll->pllxfracr, value | RCC_PLLNFRACR_FRACLE); -+ -+ pll_config_output(pll_id, pllcfg); -+ -+ return 0; -+} -+ - static unsigned long get_clock_rate(int p) - { - uint32_t reg = 0; -@@ -1214,7 +1468,7 @@ void stm32mp_register_clock_parents_secure(unsigned long clock_id) - - if (parent_id < 0) { - DMSG("No parent for clock %lu", clock_id); -- panic(); -+ return; - } - - secure_parent_clocks(parent_id); -@@ -1299,7 +1553,7 @@ static void enable_static_secure_clocks(void) - stm32_clock_enable(RTCAPB); - } - --static TEE_Result stm32mp1_clk_early_init(void) -+static void stm32mp1_clk_early_init(void) - { - void *fdt = NULL; - int node = 0; -@@ -1360,11 +1614,1011 @@ static TEE_Result stm32mp1_clk_early_init(void) - - if (ignored != 0) - IMSG("DT clock tree configurations were ignored"); -+} - -- enable_static_secure_clocks(); -+/* -+ * Gets OPP parameters (frequency in KHz and voltage in mV) from an OPP table -+ * subnode. Platform HW support capabilities are also checked. -+ */ -+static int get_opp_freqvolt_from_dt_subnode(void *fdt, int subnode, -+ uint32_t *freq_khz, -+ uint32_t *voltage_mv) -+{ -+ const fdt64_t *cuint64 = NULL; -+ const fdt32_t *cuint32 = NULL; -+ uint64_t read_freq_64 = 0; -+ uint32_t read_voltage_32 = 0; -+ -+ assert(freq_khz); -+ assert(voltage_mv); -+ -+ cuint32 = fdt_getprop(fdt, subnode, "opp-supported-hw", NULL); -+ if (cuint32) -+ if (!stm32mp_supports_cpu_opp(fdt32_to_cpu(*cuint32))) { -+ DMSG("Invalid opp-supported-hw 0x%"PRIx32, -+ fdt32_to_cpu(*cuint32)); -+ return -FDT_ERR_BADVALUE; -+ } - -- return TEE_SUCCESS; -+ cuint64 = fdt_getprop(fdt, subnode, "opp-hz", NULL); -+ if (!cuint64) { -+ DMSG("Missing opp-hz"); -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ /* Frequency value expressed in KHz must fit on 32 bits */ -+ read_freq_64 = fdt64_to_cpu(*cuint64) / 1000ULL; -+ if (read_freq_64 > (uint64_t)UINT32_MAX) { -+ DMSG("Invalid opp-hz %"PRIu64, read_freq_64); -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ cuint32 = fdt_getprop(fdt, subnode, "opp-microvolt", NULL); -+ if (!cuint32) { -+ DMSG("Missing opp-microvolt"); -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ /* Millivolt value must fit on 16 bits */ -+ read_voltage_32 = fdt32_to_cpu(*cuint32) / 1000U; -+ if (read_voltage_32 > UINT16_MAX) { -+ DMSG("Invalid opp-microvolt %"PRIu32, read_voltage_32); -+ return -FDT_ERR_BADVALUE; -+ } -+ -+ *freq_khz = (uint32_t)read_freq_64; -+ -+ *voltage_mv = read_voltage_32; -+ -+ return 0; -+} -+ -+/* -+ * Parses OPP table in DT and finds all parameters supported by the HW -+ * platform. If found, the corresponding frequency and voltage values are -+ * respectively stored in @pll1_settings structure. -+ * Note that @*count has to be set by caller to the effective size allocated -+ * for both tables. Its value is then replaced by the number of filled elements. -+ */ -+static int get_all_opp_freqvolt_from_dt(uint32_t *count) -+{ -+ void *fdt = NULL; -+ int node = 0; -+ int subnode = 0; -+ uint32_t idx = 0; -+ -+ assert(count); -+ -+ fdt = get_embedded_dt(); -+ node = fdt_node_offset_by_compatible(fdt, -1, DT_OPP_COMPAT); -+ if (node < 0) -+ return node; -+ -+ fdt_for_each_subnode(subnode, fdt, node) { -+ uint32_t read_freq = 0; -+ uint32_t read_voltage = 0; -+ -+ if (get_opp_freqvolt_from_dt_subnode(fdt, subnode, &read_freq, -+ &read_voltage)) -+ continue; -+ -+ if (idx >= *count) -+ return -FDT_ERR_NOSPACE; -+ -+ pll1_settings.freq[idx] = read_freq; -+ pll1_settings.volt[idx] = read_voltage; -+ idx++; -+ } -+ -+ if (!idx) -+ return -FDT_ERR_NOTFOUND; -+ -+ *count = idx; -+ -+ return 0; -+} -+ -+static int clk_compute_pll1_settings(unsigned long input_freq, int idx) -+{ -+ unsigned long post_divm = 0; -+ unsigned long long output_freq = pll1_settings.freq[idx] * 1000U; -+ unsigned long long freq = 0; -+ unsigned long long vco = 0; -+ int divm = 0; -+ int divn = 0; -+ int divp = 0; -+ int frac = 0; -+ int i = 0; -+ unsigned int diff = 0; -+ unsigned int best_diff = UINT_MAX; -+ -+ /* Following parameters have always the same value */ -+ pll1_settings.cfg[idx][PLLCFG_Q] = 0; -+ pll1_settings.cfg[idx][PLLCFG_R] = 0; -+ pll1_settings.cfg[idx][PLLCFG_O] = PQR(1, 0, 0); -+ -+ for (divm = DIVM_MAX; divm >= DIVM_MIN; divm--) { -+ post_divm = input_freq / (unsigned long)(divm + 1); -+ -+ if ((post_divm < POST_DIVM_MIN) || -+ (post_divm > POST_DIVM_MAX)) -+ continue; -+ -+ for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) { -+ -+ freq = output_freq * (divm + 1) * (divp + 1); -+ -+ divn = (int)((freq / input_freq) - 1); -+ if ((divn < DIVN_MIN) || (divn > DIVN_MAX)) -+ continue; -+ -+ frac = (int)(((freq * FRAC_MAX) / input_freq) - -+ ((divn + 1) * FRAC_MAX)); -+ -+ /* 2 loops to refine the fractional part */ -+ for (i = 2; i != 0; i--) { -+ if (frac > FRAC_MAX) -+ break; -+ -+ vco = (post_divm * (divn + 1)) + -+ ((post_divm * (unsigned long long)frac) / -+ FRAC_MAX); -+ -+ if ((vco < (VCO_MIN / 2)) || -+ (vco > (VCO_MAX / 2))) { -+ frac++; -+ continue; -+ } -+ -+ freq = vco / (divp + 1); -+ if (output_freq < freq) -+ diff = (unsigned int)(freq - -+ output_freq); -+ else -+ diff = (unsigned int)(output_freq - -+ freq); -+ -+ if (diff < best_diff) { -+ pll1_settings.cfg[idx][PLLCFG_M] = divm; -+ pll1_settings.cfg[idx][PLLCFG_N] = divn; -+ pll1_settings.cfg[idx][PLLCFG_P] = divp; -+ pll1_settings.frac[idx] = frac; -+ -+ if (!diff) -+ return 0; -+ -+ best_diff = diff; -+ } -+ -+ frac++; -+ } -+ } -+ } -+ -+ if (best_diff == UINT_MAX) { -+ pll1_settings.cfg[idx][PLLCFG_O] = 0; -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int clk_get_pll1_settings(uint32_t clksrc, int index) -+{ -+ unsigned long input_freq = 0; -+ unsigned int i = 0; -+ -+ for (i = 0; i < PLAT_MAX_OPP_NB; i++) -+ if (pll1_settings.freq[i] == pll1_settings.freq[index]) -+ break; -+ -+ if (((i == PLAT_MAX_OPP_NB) && -+ !stm32mp1_clk_pll1_settings_are_valid()) || -+ ((i < PLAT_MAX_OPP_NB) && !pll1_settings.cfg[i][PLLCFG_O])) { -+ /* -+ * Either PLL1 settings structure is completely empty, -+ * or these settings are not yet computed: do it. -+ */ -+ switch (clksrc) { -+ case CLK_PLL12_HSI: -+ input_freq = stm32_clock_get_rate(CK_HSI); -+ break; -+ case CLK_PLL12_HSE: -+ input_freq = stm32_clock_get_rate(CK_HSE); -+ break; -+ default: -+ panic(); -+ } -+ -+ return clk_compute_pll1_settings(input_freq, index); -+ } -+ -+ if (i < PLAT_MAX_OPP_NB) { -+ if (pll1_settings.cfg[i][PLLCFG_O]) -+ return 0; -+ -+ /* -+ * Index is in range and PLL1 settings are computed: -+ * use content to answer to the request. -+ */ -+ memcpy(&pll1_settings.cfg[index][0], &pll1_settings.cfg[i][0], -+ sizeof(uint32_t) * PLAT_MAX_PLLCFG_NB); -+ pll1_settings.frac[index] = pll1_settings.frac[i]; -+ -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int clk_save_current_pll1_settings(uint32_t buck1_voltage) -+{ -+ const struct stm32mp1_clk_pll *pll = pll_ref(_PLL1); -+ uint32_t rcc_base = stm32_rcc_base(); -+ uint32_t freq = 0; -+ unsigned int i = 0; -+ -+ freq = UDIV_ROUND_NEAREST(stm32_clock_get_rate(CK_MPU), 1000L); -+ -+ for (i = 0; i < PLAT_MAX_OPP_NB; i++) -+ if (pll1_settings.freq[i] == freq) -+ break; -+ -+ if ((i == PLAT_MAX_OPP_NB) || -+ ((pll1_settings.volt[i] != buck1_voltage) && buck1_voltage)) -+ return -1; -+ -+ pll1_settings.cfg[i][PLLCFG_M] = (io_read32(rcc_base + pll->pllxcfgr1) & -+ RCC_PLLNCFGR1_DIVM_MASK) >> -+ RCC_PLLNCFGR1_DIVM_SHIFT; -+ -+ pll1_settings.cfg[i][PLLCFG_N] = (io_read32(rcc_base + pll->pllxcfgr1) & -+ RCC_PLLNCFGR1_DIVN_MASK) >> -+ RCC_PLLNCFGR1_DIVN_SHIFT; -+ -+ pll1_settings.cfg[i][PLLCFG_P] = (io_read32(rcc_base + pll->pllxcfgr2) & -+ RCC_PLLNCFGR2_DIVP_MASK) >> -+ RCC_PLLNCFGR2_DIVP_SHIFT; -+ -+ pll1_settings.cfg[i][PLLCFG_Q] = (io_read32(rcc_base + pll->pllxcfgr2) & -+ RCC_PLLNCFGR2_DIVQ_MASK) >> -+ RCC_PLLNCFGR2_DIVQ_SHIFT; -+ -+ pll1_settings.cfg[i][PLLCFG_R] = (io_read32(rcc_base + pll->pllxcfgr2) & -+ RCC_PLLNCFGR2_DIVR_MASK) >> -+ RCC_PLLNCFGR2_DIVR_SHIFT; -+ -+ pll1_settings.cfg[i][PLLCFG_O] = io_read32(rcc_base + pll->pllxcr) >> -+ RCC_PLLNCR_DIVEN_SHIFT; -+ -+ pll1_settings.frac[i] = (io_read32(rcc_base + pll->pllxfracr) & -+ RCC_PLLNFRACR_FRACV_MASK) >> -+ RCC_PLLNFRACR_FRACV_SHIFT; -+ -+ return i; -+} -+ -+static uint32_t stm32mp1_clk_get_pll1_current_clksrc(void) -+{ -+ uint32_t value = 0; -+ const struct stm32mp1_clk_pll *pll = pll_ref(_PLL1); -+ uint32_t rcc_base = stm32_rcc_base(); -+ -+ value = io_read32(rcc_base + pll->rckxselr); -+ -+ switch (value & RCC_SELR_REFCLK_SRC_MASK) { -+ case 0: -+ return CLK_PLL12_HSI; -+ case 1: -+ return CLK_PLL12_HSE; -+ default: -+ panic(); -+ } -+} -+ -+int stm32mp1_clk_compute_all_pll1_settings(uint32_t buck1_voltage) -+{ -+ unsigned int i = 0; -+ int ret = 0; -+ int index = 0; -+ uint32_t count = PLAT_MAX_OPP_NB; -+ uint32_t clksrc = 0; -+ -+ ret = get_all_opp_freqvolt_from_dt(&count); -+ switch (ret) { -+ case 0: -+ break; -+ case -FDT_ERR_NOTFOUND: -+ DMSG("Cannot find all OPP info in DT: use default settings."); -+ return 0; -+ default: -+ EMSG("Inconsistent OPP settings found in DT, ignored."); -+ return 0; -+ } -+ -+ index = clk_save_current_pll1_settings(buck1_voltage); -+ -+ clksrc = stm32mp1_clk_get_pll1_current_clksrc(); -+ -+ for (i = 0; i < count; i++) { -+ if (index >= 0 && i == (unsigned int)index) -+ continue; -+ -+ ret = clk_get_pll1_settings(clksrc, i); -+ if (ret != 0) -+ return ret; -+ } -+ -+ pll1_settings.valid_id = PLL1_SETTINGS_VALID_ID; -+ -+ return 0; -+} -+ -+void stm32mp1_clk_lp_save_opp_pll1_settings(uint8_t *data, size_t size) -+{ -+ if ((size != sizeof(pll1_settings)) || -+ !stm32mp1_clk_pll1_settings_are_valid()) -+ panic(); -+ -+ memcpy(data, &pll1_settings, size); -+} -+ -+bool stm32mp1_clk_pll1_settings_are_valid(void) -+{ -+ return pll1_settings.valid_id == PLL1_SETTINGS_VALID_ID; -+} -+#else -+static void stm32mp1_clk_early_init(void) -+{ -+ vaddr_t rcc_base = stm32_rcc_base(); -+ -+ /* Expect booting from a secure setup */ -+ if ((io_read32(rcc_base + RCC_TZCR) & RCC_TZCR_TZEN) == 0) -+ panic("RCC TZC[TZEN]"); -+} -+ -+int stm32mp1_clk_compute_all_pll1_settings(uint32_t buck1_voltage __unused) -+{ -+ return 0; -+} -+ -+void stm32mp1_clk_lp_save_opp_pll1_settings(uint8_t *data __unused, -+ size_t size __unused) -+{ -+} -+ -+bool stm32mp1_clk_pll1_settings_are_valid(void) -+{ -+ return false; - } - --service_init(stm32mp1_clk_early_init); -+static void enable_static_secure_clocks(void) -+{ -+} - #endif /*CFG_EMBED_DTB*/ -+ -+/* Start PMU OPP */ -+#define CLKSRC_TIMEOUT_US (200 * 1000) -+#define CLKDIV_TIMEOUT_US (200 * 1000) -+#define CLK_MPU_PLL1P 0x00000202 -+#define CLK_MPU_PLL1P_DIV 0x00000203 -+ -+static int stm32mp1_set_clksrc(unsigned int clksrc) -+{ -+ uintptr_t address = stm32_rcc_base() + (clksrc >> 4); -+ uint64_t timeout_ref = 0; -+ -+ io_clrsetbits32(address, RCC_SELR_SRC_MASK, clksrc & RCC_SELR_SRC_MASK); -+ -+ timeout_ref = timeout_init_us(CLKSRC_TIMEOUT_US); -+ while ((io_read32(address) & RCC_SELR_SRCRDY) == 0U) { -+ if (timeout_elapsed(timeout_ref)) { -+ EMSG("CLKSRC %u start failed @ 0x%"PRIxPTR": 0x%"PRIx32, -+ clksrc, address, io_read32(address)); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+static int stm32mp1_set_clkdiv(unsigned int clkdiv, uintptr_t address) -+{ -+ uint64_t timeout_ref = 0; -+ -+ io_clrsetbits32(address, RCC_DIVR_DIV_MASK, clkdiv & RCC_DIVR_DIV_MASK); -+ -+ timeout_ref = timeout_init_us(CLKDIV_TIMEOUT_US); -+ while ((io_read32(address) & RCC_DIVR_DIVRDY) == 0U) { -+ if (timeout_elapsed(timeout_ref)) { -+ EMSG("CLKDIV 0x%x start failed @ 0x%"PRIxPTR": 0x%"PRIx32, -+ clkdiv, address, io_read32(address)); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+/* -+ * Check if PLL1 can be configured on the fly. -+ * @result (-1) => config on the fly is not possible. -+ * (0) => config on the fly is possible. -+ * (+1) => same parameters as those in place, no need to reconfig. -+ * Return value is 0 if no error. -+ */ -+static int is_pll_config_on_the_fly(enum stm32mp1_pll_id pll_id, -+ uint32_t *pllcfg, uint32_t fracv, -+ int *result) -+{ -+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); -+ uintptr_t rcc_base = stm32_rcc_base(); -+ uint32_t fracr = 0; -+ uint32_t value = 0; -+ int ret = 0; -+ -+ ret = pll_compute_pllxcfgr1(pll, pllcfg, &value); -+ if (ret) -+ return ret; -+ -+ if (io_read32(rcc_base + pll->pllxcfgr1) != value) { -+ /* Different DIVN/DIVM, can't config on the fly */ -+ *result = -1; -+ return 0; -+ } -+ -+ *result = true; -+ -+ fracr = fracv << RCC_PLLNFRACR_FRACV_SHIFT; -+ fracr |= RCC_PLLNFRACR_FRACLE; -+ value = pll_compute_pllxcfgr2(pllcfg); -+ -+ if ((io_read32(rcc_base + pll->pllxfracr) == fracr) && -+ (io_read32(rcc_base + pll->pllxcfgr2) == value)) -+ /* Same parameters, no need to config */ -+ *result = 1; -+ else -+ *result = 0; -+ -+ return 0; -+} -+ -+static int stm32mp1_get_mpu_div(uint32_t freq_khz) -+{ -+ unsigned long freq_pll1_p; -+ unsigned long div; -+ -+ freq_pll1_p = get_clock_rate(_PLL1_P) / 1000UL; -+ if ((freq_pll1_p % freq_khz) != 0U) -+ return -1; -+ -+ div = freq_pll1_p / freq_khz; -+ -+ switch (div) { -+ case 1UL: -+ case 2UL: -+ case 4UL: -+ case 8UL: -+ case 16UL: -+ return __builtin_ffs(div) - 1; -+ default: -+ return -1; -+ } -+} -+ -+/* Configure PLL1 from input frequency OPP parameters */ -+static int pll1_config_from_opp_khz(uint32_t freq_khz) -+{ -+ unsigned int idx = 0; -+ int ret = 0; -+ int div = 0; -+ int config_on_the_fly = -1; -+ -+ for (idx = 0; idx < PLAT_MAX_OPP_NB; idx++) -+ if (pll1_settings.freq[idx] == freq_khz) -+ break; -+ -+ if (idx == PLAT_MAX_OPP_NB) -+ return -1; -+ -+ div = stm32mp1_get_mpu_div(freq_khz); -+ switch (div) { -+ case -1: -+ break; -+ case 0: -+ return stm32mp1_set_clksrc(CLK_MPU_PLL1P); -+ default: -+ ret = stm32mp1_set_clkdiv(div, stm32_rcc_base() + -+ RCC_MPCKDIVR); -+ if (ret == 0) -+ ret = stm32mp1_set_clksrc(CLK_MPU_PLL1P_DIV); -+ -+ return ret; -+ } -+ -+ ret = is_pll_config_on_the_fly(_PLL1, &pll1_settings.cfg[idx][0], -+ pll1_settings.frac[idx], -+ &config_on_the_fly); -+ if (ret) -+ return ret; -+ -+ if (config_on_the_fly == 1) -+ return 0; -+ -+ if (config_on_the_fly == -1) { -+ /* Switch to HSI and stop PLL1 before reconfiguration */ -+ ret = stm32mp1_set_clksrc(CLK_MPU_HSI); -+ if (ret) -+ return ret; -+ -+ ret = pll_stop(_PLL1); -+ if (ret) -+ return ret; -+ } -+ -+ ret = pll_config(_PLL1, &pll1_settings.cfg[idx][0], -+ pll1_settings.frac[idx]); -+ if (ret) -+ return ret; -+ -+ if (config_on_the_fly == -1) { -+ /* Start PLL1 and switch back to after reconfiguration */ -+ pll_start(_PLL1); -+ -+ ret = pll_output(_PLL1, pll1_settings.cfg[idx][PLLCFG_O]); -+ if (ret) -+ return ret; -+ -+ ret = stm32mp1_set_clksrc(CLK_MPU_PLL1P); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void save_current_opp(void) -+{ -+ unsigned long freq_khz = UDIV_ROUND_NEAREST(stm32_clock_get_rate(CK_MPU), -+ 1000UL); -+ if (freq_khz > (unsigned long)UINT32_MAX) -+ panic(); -+ -+ current_opp_khz = (uint32_t)freq_khz; -+} -+ -+int stm32mp1_set_opp_khz(uint32_t freq_khz) -+{ -+ uint32_t mpu_src = 0; -+ -+ if (freq_khz == current_opp_khz) -+ return 0; -+ -+ if (!stm32mp1_clk_pll1_settings_are_valid()) { -+ /* -+ * No OPP table in DT or an error occurred during PLL1 -+ * settings computation, system can only work on current -+ * operating point so return error. -+ */ -+ return -1; -+ } -+ -+ /* Check that PLL1 is MPU clock source */ -+ mpu_src = io_read32(stm32_rcc_base() + RCC_MPCKSELR) & -+ RCC_SELR_SRC_MASK; -+ if ((mpu_src != RCC_MPCKSELR_PLL) && -+ (mpu_src != RCC_MPCKSELR_PLL_MPUDIV)) -+ return -1; -+ -+ if (pll1_config_from_opp_khz(freq_khz)) { -+ /* Restore original value */ -+ if (pll1_config_from_opp_khz(current_opp_khz)) { -+ EMSG("No CPU operating point can be set"); -+ panic(); -+ } -+ -+ return -1; -+ } -+ -+ current_opp_khz = freq_khz; -+ -+ return 0; -+} -+ -+int stm32mp1_round_opp_khz(uint32_t *freq_khz) -+{ -+ unsigned int i = 0; -+ uint32_t round_opp = 0; -+ -+ if (!stm32mp1_clk_pll1_settings_are_valid()) { -+ /* -+ * No OPP table in DT, or an error occurred during PLL1 -+ * settings computation, system can only work on current -+ * operating point, so return current CPU frequency. -+ */ -+ *freq_khz = current_opp_khz; -+ -+ return 0; -+ } -+ -+ for (i = 0; i < PLAT_MAX_OPP_NB; i++) -+ if ((pll1_settings.freq[i] <= *freq_khz) && -+ (pll1_settings.freq[i] > round_opp)) -+ round_opp = pll1_settings.freq[i]; -+ -+ *freq_khz = round_opp; -+ -+ return 0; -+} -+/* End PMU OPP */ -+ -+#ifdef CFG_PM -+struct soc_stop_context { -+ uint32_t pll3cr; -+ uint32_t pll4cr; -+ uint32_t mssckselr; -+ uint32_t mcudivr; -+}; -+ -+static struct soc_stop_context soc_stop_ctx; -+ -+static void save_pll34_state(void) -+{ -+ uintptr_t rcc_base = stm32_rcc_base(); -+ struct soc_stop_context *ctx = &soc_stop_ctx; -+ -+ ctx->pll3cr = io_read32(rcc_base + RCC_PLL3CR); -+ ctx->pll4cr = io_read32(rcc_base + RCC_PLL4CR); -+} -+ -+static void save_mcu_subsys_clocks(void) -+{ -+ uintptr_t rcc_base = stm32_rcc_base(); -+ struct soc_stop_context *ctx = &soc_stop_ctx; -+ -+ ctx->mssckselr = io_read32(rcc_base + RCC_MSSCKSELR); -+ ctx->mcudivr = io_read32(rcc_base + RCC_MCUDIVR) & -+ RCC_MCUDIV_MASK; -+} -+ -+static void restore_pll34_state(void) -+{ -+ struct soc_stop_context *ctx = &soc_stop_ctx; -+ -+ /* Let PLL4 start while we're starting and waiting for PLL3 */ -+ if (ctx->pll4cr & RCC_PLLNCR_PLLON) -+ pll_start(_PLL4); -+ -+ if (ctx->pll3cr & RCC_PLLNCR_PLLON) { -+ pll_start(_PLL3); -+ if (pll_output(_PLL3, ctx->pll3cr >> RCC_PLLNCR_DIVEN_SHIFT)) { -+ EMSG("Failed to restore PLL3"); -+ panic(); -+ } -+ } -+ -+ if (ctx->pll4cr & RCC_PLLNCR_PLLON) { -+ if (pll_output(_PLL4, ctx->pll4cr >> RCC_PLLNCR_DIVEN_SHIFT)) { -+ EMSG("Failed to restore PLL4"); -+ panic(); -+ } -+ } -+} -+ -+static void restore_mcu_subsys_clocks(void) -+{ -+ uintptr_t rcc_base = stm32_rcc_base(); -+ struct soc_stop_context *ctx = &soc_stop_ctx; -+ -+ io_write32(rcc_base + RCC_MSSCKSELR, ctx->mssckselr); -+ -+ if (stm32mp1_set_clkdiv(ctx->mcudivr, rcc_base + RCC_MCUDIVR)) { -+ EMSG("Failed to restore MCUDIVR"); -+ panic(); -+ } -+} -+ -+/* -+ * Sequence to save/restore the non-secure configuration. -+ * Restoring clocks and muxes need IPs to run on kernel clock -+ * hence on configuration is restored at resume, kernel clock -+ * should be disable: this mandates secure access. -+ * -+ * backup_mux*_cfg for the clock muxes. -+ * backup_clock_sc_cfg for the set/clear clock gating registers -+ * backup_clock_cfg for the regular full write registers -+ */ -+ -+struct backup_mux_cfg { -+ uint16_t offset; -+ uint8_t value; -+ uint8_t bit_len; -+}; -+ -+#define MUXCFG(_offset, _bit_len) \ -+ { .offset = (_offset), .bit_len = (_bit_len) } -+ -+struct backup_mux_cfg backup_mux0_cfg[] = { -+ MUXCFG(RCC_SDMMC12CKSELR, 3), -+ MUXCFG(RCC_SPI2S23CKSELR, 3), -+ MUXCFG(RCC_SPI45CKSELR, 3), -+ MUXCFG(RCC_I2C12CKSELR, 3), -+ MUXCFG(RCC_I2C35CKSELR, 3), -+ MUXCFG(RCC_LPTIM23CKSELR, 3), -+ MUXCFG(RCC_LPTIM45CKSELR, 3), -+ MUXCFG(RCC_UART24CKSELR, 3), -+ MUXCFG(RCC_UART35CKSELR, 3), -+ MUXCFG(RCC_UART78CKSELR, 3), -+ MUXCFG(RCC_SAI1CKSELR, 3), -+ MUXCFG(RCC_ETHCKSELR, 2), -+ MUXCFG(RCC_I2C46CKSELR, 3), -+ MUXCFG(RCC_RNG2CKSELR, 2), -+ MUXCFG(RCC_SDMMC3CKSELR, 3), -+ MUXCFG(RCC_FMCCKSELR, 2), -+ MUXCFG(RCC_QSPICKSELR, 2), -+ MUXCFG(RCC_USBCKSELR, 2), -+ MUXCFG(RCC_SPDIFCKSELR, 2), -+ MUXCFG(RCC_SPI2S1CKSELR, 3), -+ MUXCFG(RCC_CECCKSELR, 2), -+ MUXCFG(RCC_LPTIM1CKSELR, 3), -+ MUXCFG(RCC_UART6CKSELR, 3), -+ MUXCFG(RCC_FDCANCKSELR, 2), -+ MUXCFG(RCC_SAI2CKSELR, 3), -+ MUXCFG(RCC_SAI3CKSELR, 3), -+ MUXCFG(RCC_SAI4CKSELR, 3), -+ MUXCFG(RCC_ADCCKSELR, 2), -+ MUXCFG(RCC_DSICKSELR, 1), -+ MUXCFG(RCC_CPERCKSELR, 2), -+ MUXCFG(RCC_RNG1CKSELR, 2), -+ MUXCFG(RCC_STGENCKSELR, 2), -+ MUXCFG(RCC_UART1CKSELR, 3), -+ MUXCFG(RCC_SPI6CKSELR, 3), -+}; -+ -+struct backup_mux_cfg backup_mux4_cfg[] = { -+ MUXCFG(RCC_USBCKSELR, 1), -+}; -+ -+static void backup_mux_cfg(void) -+{ -+ struct backup_mux_cfg *cfg = backup_mux0_cfg; -+ size_t count = ARRAY_SIZE(backup_mux0_cfg); -+ size_t i = 0; -+ uintptr_t base = stm32_rcc_base(); -+ -+ for (i = 0; i < count; i++) -+ cfg[i].value = io_read32(base + cfg[i].offset) & -+ GENMASK_32(cfg[i].bit_len - 1, 0); -+ -+ cfg = backup_mux4_cfg; -+ count = ARRAY_SIZE(backup_mux4_cfg); -+ -+ for (i = 0; i < count; i++) -+ cfg[i].value = io_read32(base + cfg[i].offset) & -+ GENMASK_32(4 + cfg[i].bit_len - 1, 4); -+} -+ -+static void restore_mux_cfg(void) -+{ -+ struct backup_mux_cfg *cfg = backup_mux0_cfg; -+ size_t count = ARRAY_SIZE(backup_mux0_cfg); -+ size_t i = 0; -+ uintptr_t base = stm32_rcc_base(); -+ -+ for (i = 0; i < count; i++) -+ io_clrsetbits32(base + cfg[i].offset, -+ GENMASK_32(cfg[i].bit_len - 1, 0), -+ cfg[i].value); -+ -+ cfg = backup_mux4_cfg; -+ count = ARRAY_SIZE(backup_mux4_cfg); -+ -+ for (i = 0; i < count; i++) -+ io_clrsetbits32(base + cfg[i].offset, -+ GENMASK_32(4 + cfg[i].bit_len - 1, 4), -+ cfg[i].value); -+} -+ -+/* Structure is used for set/clear registers and for regular registers */ -+struct backup_clock_cfg { -+ uint32_t offset; -+ uint32_t value; -+}; -+ -+static struct backup_clock_cfg backup_clock_sc_cfg[] = { -+ { .offset = RCC_MP_APB1ENSETR }, -+ { .offset = RCC_MP_APB2ENSETR }, -+ { .offset = RCC_MP_APB3ENSETR }, -+ { .offset = RCC_MP_APB4ENSETR }, -+ { .offset = RCC_MP_APB5ENSETR }, -+ { .offset = RCC_MP_AHB2ENSETR }, -+ { .offset = RCC_MP_AHB3ENSETR }, -+ { .offset = RCC_MP_AHB4ENSETR }, -+ { .offset = RCC_MP_AHB5ENSETR }, -+ { .offset = RCC_MP_AHB6ENSETR }, -+ { .offset = RCC_MP_MLAHBENSETR }, -+}; -+ -+static struct backup_clock_cfg backup_clock_cfg[] = { -+ { .offset = RCC_MCO1CFGR }, -+ { .offset = RCC_MCO2CFGR }, -+ { .offset = RCC_PLL3CR }, -+ { .offset = RCC_PLL4CR }, -+ { .offset = RCC_PLL4CFGR2 }, -+ { .offset = RCC_MCUDIVR }, -+ { .offset = RCC_MSSCKSELR }, -+}; -+ -+static void backup_sc_cfg(void) -+{ -+ struct backup_clock_cfg *cfg = backup_clock_sc_cfg; -+ size_t count = ARRAY_SIZE(backup_clock_sc_cfg); -+ size_t i = 0; -+ uintptr_t base = stm32_rcc_base(); -+ -+ for (i = 0; i < count; i++) -+ cfg[i].value = io_read32(base + cfg[i].offset); -+} -+ -+static void restore_sc_cfg(void) -+{ -+ struct backup_clock_cfg *cfg = backup_clock_sc_cfg; -+ size_t count = ARRAY_SIZE(backup_clock_sc_cfg); -+ size_t i = 0; -+ uintptr_t base = stm32_rcc_base(); -+ -+ for (i = 0; i < count; i++) { -+ io_write32(base + cfg[i].offset, cfg[i].value); -+ io_write32(base + cfg[i].offset + RCC_MP_ENCLRR_OFFSET, -+ ~cfg[i].value); -+ } -+} -+ -+static void backup_regular_cfg(void) -+{ -+ struct backup_clock_cfg *cfg = backup_clock_cfg; -+ size_t count = ARRAY_SIZE(backup_clock_cfg); -+ size_t i = 0; -+ uintptr_t base = stm32_rcc_base(); -+ -+ for (i = 0; i < count; i++) -+ cfg[i].value = io_read32(base + cfg[i].offset); -+} -+ -+static void restore_regular_cfg(void) -+{ -+ struct backup_clock_cfg *cfg = backup_clock_cfg; -+ size_t count = ARRAY_SIZE(backup_clock_cfg); -+ size_t i = 0; -+ uintptr_t base = stm32_rcc_base(); -+ -+ for (i = 0; i < count; i++) -+ io_write32(base + cfg[i].offset, cfg[i].value); -+} -+ -+static void disable_kernel_clocks(void) -+{ -+ const uint32_t ker_mask = RCC_OCENR_HSIKERON | -+ RCC_OCENR_CSIKERON | -+ RCC_OCENR_HSEKERON; -+ -+ /* Disable all ck_xxx_ker clocks */ -+ io_write32(stm32_rcc_base() + RCC_OCENCLRR, ker_mask); -+} -+ -+static void enable_kernel_clocks(void) -+{ -+ uintptr_t rcc_base = stm32_rcc_base(); -+ uint32_t reg = 0; -+ const uint32_t ker_mask = RCC_OCENR_HSIKERON | -+ RCC_OCENR_CSIKERON | -+ RCC_OCENR_HSEKERON; -+ -+ /* Enable ck_xxx_ker clocks if ck_xxx was on */ -+ reg = io_read32(rcc_base + RCC_OCENSETR) << 1; -+ io_write32(rcc_base + RCC_OCENSETR, reg & ker_mask); -+} -+ -+static void clear_rcc_reset_status(void) -+{ -+ /* Clear reset status fields */ -+ io_write32(stm32_rcc_base() + RCC_MP_RSTSCLRR, 0); -+} -+ -+void stm32mp1_clk_save_context_for_stop(void) -+{ -+ enable_kernel_clocks(); -+ save_mcu_subsys_clocks(); -+ save_pll34_state(); -+} -+ -+void stm32mp1_clk_restore_context_for_stop(void) -+{ -+ restore_pll34_state(); -+ /* Restore MCU clock source after PLL3 is ready */ -+ restore_mcu_subsys_clocks(); -+ disable_kernel_clocks(); -+} -+ -+static void stm32_clock_suspend(void) -+{ -+ backup_regular_cfg(); -+ backup_sc_cfg(); -+ backup_mux_cfg(); -+ save_pll34_state(); -+ -+ enable_kernel_clocks(); -+ clear_rcc_reset_status(); -+} -+ -+static void stm32_clock_resume(void) -+{ -+ unsigned int idx = 0; -+ -+ restore_pll34_state(); -+ restore_mux_cfg(); -+ restore_sc_cfg(); -+ restore_regular_cfg(); -+ -+ /* Sync secure and shared clocks physical state on functional state */ -+ for (idx = 0; idx < NB_GATES; idx++) { -+ struct stm32mp1_clk_gate const *gate = gate_ref(idx); -+ -+ if (gate_is_non_secure(gate)) -+ continue; -+ -+ if (gate_refcounts[idx]) { -+ DMSG("Force clock %d enable", gate->clock_id); -+ __clk_enable(gate); -+ } else { -+ DMSG("Force clock %d disable", gate->clock_id); -+ __clk_disable(gate); -+ } -+ } -+ -+ disable_kernel_clocks(); -+} -+ -+static TEE_Result stm32_clock_pm(enum pm_op op, unsigned int pm_hint __unused, -+ const struct pm_callback_handle *hdl __unused) -+{ -+ if (op == PM_OP_SUSPEND) -+ stm32_clock_suspend(); -+ else -+ stm32_clock_resume(); -+ -+ return TEE_SUCCESS; -+} -+DECLARE_KEEP_PAGER(stm32_clock_pm); -+#else -+static TEE_Result stm32_clock_pm(enum pm_op op __unused, -+ unsigned int pm_hint __unused, -+ const struct pm_callback_handle *hdl __unused) -+{ -+ return TEE_ERROR_SECURITY; -+} -+#endif /*CFG_PM*/ -+ -+static void init_non_secure_rcc(void) -+{ -+ uintptr_t rcc_base = stm32_rcc_base(); -+ -+ /* Clear all interrupt flags and core stop requests */ -+ io_write32(rcc_base + RCC_MP_CIFR, 0x110F1F); -+ io_write32(rcc_base + RCC_MP_SREQCLRR, 0x3); -+} -+ -+static TEE_Result stm32_clk_probe(void) -+{ -+ assert(PLLCFG_NB == PLAT_MAX_PLLCFG_NB); -+ -+ stm32mp1_clk_early_init(); -+ enable_static_secure_clocks(); -+ save_current_opp(); -+ init_non_secure_rcc(); -+ register_pm_core_service_cb(stm32_clock_pm, NULL); -+ -+ return TEE_SUCCESS; -+} -+/* Setup clock support before driver initialization */ -+service_init(stm32_clk_probe); diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.c new file mode 100644 -index 0000000..1c2d9b2 +index 000000000..1c2d9b2c8 --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.c @@ -0,0 +1,469 @@ @@ -8503,7 +7444,7 @@ index 0000000..1c2d9b2 +} diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.h b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.h new file mode 100644 -index 0000000..e2d809b +index 000000000..e2d809bcd --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_ddrc.h @@ -0,0 +1,219 @@ @@ -8726,19 +7667,128 @@ index 0000000..e2d809b +int ddr_standby_sr_exit(void); + +#endif /*__STM32MP1_DDRC_H__*/ +diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c +index 8d18ff94b..a7d755a0c 100644 +--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c ++++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: BSD-3-Clause + /* +- * Copyright (c) 2017-2020, STMicroelectronics ++ * Copyright (c) 2017-2021, STMicroelectronics + */ + + #include +@@ -36,6 +36,8 @@ static uint32_t pmic_i2c_addr; + + /* CPU voltage supplier if found */ + static char cpu_supply_name[PMIC_REGU_SUPPLY_NAME_LEN]; ++/* USB voltage supplier if found */ ++static char *usb_supply_name; + + bool stm32mp_with_pmic(void) + { +@@ -372,6 +374,49 @@ const char *stm32mp_pmic_get_cpu_supply_name(void) + return cpu_supply_name; + } + ++/* Return a libfdt compliant status value */ ++static int save_usb_supply_name(void) ++{ ++ void *fdt = NULL; ++ int node = 0; ++ int subnode = 0; ++ const fdt32_t *cuint = NULL; ++ const char *name = NULL; ++ ++ fdt = get_embedded_dt(); ++ if (!fdt) ++ panic(); ++ ++ node = fdt_node_offset_by_compatible(fdt, -1, "st,stm32mp1-usbphyc"); ++ if (node < 0) ++ return -FDT_ERR_NOTFOUND; ++ ++ fdt_for_each_subnode(subnode, fdt, node) { ++ cuint = fdt_getprop(fdt, subnode, "phy-supply", NULL); ++ if (cuint) ++ break; ++ } ++ if (!cuint) ++ return -FDT_ERR_NOTFOUND; ++ ++ node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); ++ if (node < 0) ++ return -FDT_ERR_NOTFOUND; ++ ++ name = fdt_get_name(fdt, node, NULL); ++ assert(name); ++ usb_supply_name = strdup(name); ++ if (!usb_supply_name) ++ panic(); ++ ++ return 0; ++} ++ ++const char *stm32mp_pmic_get_usb_supply_name(void) ++{ ++ return usb_supply_name; ++} ++ + /* Preallocate not that much regu references */ + static char *nsec_access_regu_name[PMIC_REGU_COUNT]; + +@@ -452,6 +497,9 @@ static void parse_regulator_fdt_nodes(void) + + if (save_cpu_supply_name()) + DMSG("No CPU supply provided"); ++ ++ if (save_usb_supply_name()) ++ DMSG("No USB supply provided"); + } + + /* +diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.h b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.h +index 4625af125..f91654733 100644 +--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.h ++++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: BSD-3-Clause */ + /* +- * Copyright (c) 2017-2020, STMicroelectronics ++ * Copyright (c) 2017-2021, STMicroelectronics + */ + + #ifndef __STM32MP1_PMIC_H__ +@@ -15,6 +15,7 @@ void stm32mp_get_pmic(void); + void stm32mp_put_pmic(void); + int stm32mp_dt_pmic_status(void); + const char *stm32mp_pmic_get_cpu_supply_name(void); ++const char *stm32mp_pmic_get_usb_supply_name(void); + #else + static inline void stm32mp_pmic_apply_boot_on_config(void) + { +@@ -43,6 +44,11 @@ static inline const char *stm32mp_pmic_get_cpu_supply_name(void) + { + return NULL; + } ++ ++static inline const char *stm32mp_pmic_get_usb_supply_name(void) ++{ ++ return NULL; ++} + #endif + + #endif /*__STM32MP1_PMIC_H__*/ diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h -index 9ba95df..41a8469 100644 +index 9cedd9321..5783a5ca9 100644 --- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h +++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.h -@@ -6,6 +6,7 @@ - #ifndef __STM32MP1_PWR_H - #define __STM32MP1_PWR_H - -+#include - #include - - #define PWR_CR1_OFF 0x00 -@@ -15,7 +16,35 @@ +@@ -13,10 +13,41 @@ + #define PWR_CR2_OFF 0x08 + #define PWR_CR3_OFF 0x0c + #define PWR_MPUCR_OFF 0x10 ++#define PWR_MCUCR_OFF 0x14 #define PWR_WKUPCR_OFF 0x20 #define PWR_MPUWKUPENR_OFF 0x28 @@ -8768,150 +7818,134 @@ index 9ba95df..41a8469 100644 +#define PWR_MPUCR_CSTDBYDIS BIT(3) +#define PWR_MPUCR_CSSF BIT(9) + ++#define PWR_MCUCR_PDDS BIT(0) ++ +#define PWR_WKUPCR_MASK (GENMASK_32(27, 16) | \ + GENMASK_32(13, 8) | GENMASK_32(5, 0)) + +#define PWR_MPUWKUPENR_MASK GENMASK_32(5, 0) - vaddr_t stm32_pwr_base(void); + enum pwr_regulator { + PWR_REG11 = 0, +diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_syscfg.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_syscfg.c +index 37d2cb0dc..345a19807 100644 +--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_syscfg.c ++++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_syscfg.c +@@ -5,6 +5,7 @@ -diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h -index 95aefcf..3498022 100644 ---- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h -+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h -@@ -6,8 +6,6 @@ - #ifndef __STM32MP1_RCC_H__ - #define __STM32MP1_RCC_H__ + #include + #include ++#include + #include + #include + #include +@@ -17,6 +18,7 @@ + */ + #define SYSCFG_CMPCR 0x20U + #define SYSCFG_CMPENSETR 0x24U ++#define SYSCFG_CMPENCLRR 0x28U --#include --#include - #include + /* + * SYSCFG_CMPCR Register +@@ -47,8 +49,8 @@ void stm32mp_syscfg_enable_io_compensation(void) + vaddr_t syscfg_base = get_syscfg_base(); + uint64_t timeout_ref = 0; - #define RCC_TZCR 0x00 -@@ -392,7 +390,8 @@ - #define RCC_HSICFGR_HSITRIM_SHIFT 8 - #define RCC_HSICFGR_HSITRIM_MASK GENMASK_32(14, 8) - #define RCC_HSICFGR_HSICAL_SHIFT 16 --#define RCC_HSICFGR_HSICAL_MASK GENMASK_32(27, 16) -+#define RCC_HSICFGR_HSICAL_MASK GENMASK_32(24, 16) -+#define RCC_HSICFGR_HSICAL_TEMP_MASK GENMASK_32(27, 25) +- stm32_clock_enable(CK_CSI); +- stm32_clock_enable(SYSCFG); ++ clk_enable(CK_CSI); ++ clk_enable(SYSCFG); - /* Fields of RCC_CSICFGR register */ - #define RCC_CSICFGR_CSITRIM_SHIFT 8 -@@ -455,6 +454,9 @@ - #define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0) - #define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1) + io_setbits32(syscfg_base + SYSCFG_CMPENSETR, SYSCFG_CMPENSETR_MPU_EN); -+/* Global Control Register */ -+#define RCC_MP_GCR_BOOT_MCU BIT(0) +@@ -71,6 +73,9 @@ void stm32mp_syscfg_disable_io_compensation(void) + vaddr_t syscfg_base = get_syscfg_base(); + uint32_t value = 0; + ++ /* No refcount balance needed on non-secure SYSCFG clock */ ++ clk_enable(SYSCFG); + - /* RCC_MP_APB5RST(SET|CLR)R bit fields */ - #define RCC_APB5RSTSETR_SPI6RST BIT(0) - #define RCC_APB5RSTSETR_I2C4RST BIT(2) -@@ -508,6 +510,9 @@ - #define RCC_AHB5RSTSETR_RNG1RST BIT(6) - #define RCC_AHB5RSTSETR_AXIMCRST BIT(16) + value = io_read32(syscfg_base + SYSCFG_CMPCR) >> + SYSCFG_CMPCR_ANSRC_SHIFT; -+/* RCC_MP_AHB6RST(SET|CLR)R bit fields */ -+#define RCC_AHB6RSTSETR_GPURST BIT(5) -+ - /* RCC_MP_AHB5EN(SET|CLR)R bit fields */ - #define RCC_MP_AHB5ENSETR_GPIOZEN_POS 0 - #define RCC_MP_AHB5ENSETR_CRYP1EN_POS 4 -@@ -531,8 +536,9 @@ - #define RCC_MP_AHB5LPENSETR_BKPSRAMLPEN BIT(8) +@@ -84,10 +89,9 @@ void stm32mp_syscfg_disable_io_compensation(void) - /* RCC_MP_TZAHB6EN(SET|CLR)R bit fields */ --#define RCC_MP_TZAHB6ENSETR_MDMA_POS 0 --#define RCC_MP_TZAHB6ENSETR_MDMA BIT(RCC_MP_TZAHB6ENSETR_MDMA_POS) -+#define RCC_MP_TZAHB6ENSETR_MDMA_POS 0 -+#define RCC_MP_TZAHB6ENSETR_MDMA \ -+ BIT(RCC_MP_TZAHB6ENSETR_MDMA_POS) + DMSG("SYSCFG.cmpcr = %#"PRIx32, io_read32(syscfg_base + SYSCFG_CMPCR)); - /* RCC_MP_IWDGFZ(SET|CLR)R bit fields */ - #define RCC_MP_IWDGFZSETR_IWDG1 BIT(0) -@@ -541,16 +547,31 @@ - #define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc" +- io_clrbits32(syscfg_base + SYSCFG_CMPENSETR, SYSCFG_CMPENSETR_MPU_EN); ++ io_setbits32(syscfg_base + SYSCFG_CMPENCLRR, SYSCFG_CMPENSETR_MPU_EN); - #ifndef __ASSEMBLER__ -+#include -+#include -+#include -+ - vaddr_t stm32_rcc_base(void); - - static inline bool stm32_rcc_is_secure(void) - { -- return io_read32(stm32_rcc_base() + RCC_TZCR) & RCC_TZCR_TZEN; -+ static int state = -1; -+ -+ if (state < 0) -+ state = io_read32(stm32_rcc_base() + RCC_TZCR) & RCC_TZCR_TZEN; -+ -+ return state; +- stm32_clock_disable(SYSCFG); +- stm32_clock_disable(CK_CSI); ++ clk_disable(CK_CSI); } - static inline bool stm32_rcc_is_mckprot(void) - { -- return io_read32(stm32_rcc_base() + RCC_TZCR) & RCC_TZCR_MCKPROT; -+ const uint32_t mask = RCC_TZCR_TZEN | RCC_TZCR_MCKPROT; -+ static int state = -1; -+ -+ if (state < 0) -+ state = (io_read32(stm32_rcc_base() + RCC_TZCR) & mask) == mask; -+ -+ return state; - } - #endif /*__ASSEMBLER__*/ - + static TEE_Result stm32mp1_iocomp(void) diff --git a/core/arch/arm/plat-stm32mp1/drivers/sub.mk b/core/arch/arm/plat-stm32mp1/drivers/sub.mk -index 42b6893..1718bd6 100644 +index 42b6893f0..0b814a410 100644 --- a/core/arch/arm/plat-stm32mp1/drivers/sub.mk +++ b/core/arch/arm/plat-stm32mp1/drivers/sub.mk -@@ -1,4 +1,6 @@ +@@ -1,4 +1,5 @@ +-srcs-y += stm32mp1_clk.c +srcs-$(CFG_STM32_CLKCALIB) += stm32mp1_calib.c - srcs-y += stm32mp1_clk.c +srcs-y += stm32mp1_ddrc.c srcs-$(CFG_STPMIC1) += stm32mp1_pmic.c srcs-y += stm32mp1_pwr.c srcs-y += stm32mp1_rcc.c +diff --git a/core/arch/arm/plat-stm32mp1/link.mk b/core/arch/arm/plat-stm32mp1/link.mk +index 01a9b8ed5..fa1465a45 100644 +--- a/core/arch/arm/plat-stm32mp1/link.mk ++++ b/core/arch/arm/plat-stm32mp1/link.mk +@@ -1,5 +1,6 @@ + include core/arch/arm/kernel/link.mk + ++ifeq ($(CFG_STM32MP15x_STM32IMAGE),y) + # Create stm32 formatted images from the native binary images + + define stm32image_cmd +@@ -22,3 +23,4 @@ all: $(link-out-dir)/tee-pageable_v2.stm32 + cleanfiles += $(link-out-dir)/tee-pageable_v2.stm32 + $(link-out-dir)/tee-pageable_v2.stm32: $(link-out-dir)/tee-pageable_v2.bin + $(stm32image_cmd) --source $< --dest $@ --bintype 0x22 ++endif diff --git a/core/arch/arm/plat-stm32mp1/main.c b/core/arch/arm/plat-stm32mp1/main.c -index 9947e71..40e4263 100644 +index 9dca331c7..bf2e394fb 100644 --- a/core/arch/arm/plat-stm32mp1/main.c +++ b/core/arch/arm/plat-stm32mp1/main.c -@@ -1,6 +1,6 @@ +@@ -1,23 +1,30 @@ // SPDX-License-Identifier: BSD-2-Clause /* - * Copyright (c) 2017-2018, STMicroelectronics -+ * Copyright (c) 2017-2020, STMicroelectronics * Copyright (c) 2016-2018, Linaro Limited ++ * Copyright (c) 2017-2021, STMicroelectronics */ -@@ -9,9 +9,14 @@ + #include + #include #include ++#include #include #include -#include +#include #include -+#include +#include +#include +#include #include ++#include +#include + #include #include - #include #include -@@ -19,6 +24,7 @@ + #include #include - #include #include +#include #include #include #include -@@ -32,7 +38,10 @@ register_phys_mem_pgdir(MEM_AREA_IO_NSEC, GPIOS_NSEC_BASE, GPIOS_NSEC_SIZE); +@@ -29,7 +36,10 @@ register_phys_mem_pgdir(MEM_AREA_IO_NSEC, GPIOS_NSEC_BASE, GPIOS_NSEC_SIZE); #endif register_phys_mem_pgdir(MEM_AREA_IO_NSEC, I2C4_BASE, SMALL_PAGE_SIZE); register_phys_mem_pgdir(MEM_AREA_IO_NSEC, I2C6_BASE, SMALL_PAGE_SIZE); @@ -8922,7 +7956,7 @@ index 9947e71..40e4263 100644 #ifdef CFG_WITH_NSEC_UARTS register_phys_mem_pgdir(MEM_AREA_IO_NSEC, USART1_BASE, SMALL_PAGE_SIZE); register_phys_mem_pgdir(MEM_AREA_IO_NSEC, USART2_BASE, SMALL_PAGE_SIZE); -@@ -44,17 +53,38 @@ register_phys_mem_pgdir(MEM_AREA_IO_NSEC, UART7_BASE, SMALL_PAGE_SIZE); +@@ -41,17 +51,38 @@ register_phys_mem_pgdir(MEM_AREA_IO_NSEC, UART7_BASE, SMALL_PAGE_SIZE); register_phys_mem_pgdir(MEM_AREA_IO_NSEC, UART8_BASE, SMALL_PAGE_SIZE); #endif @@ -8961,20 +7995,28 @@ index 9947e71..40e4263 100644 register_phys_mem_pgdir(MEM_AREA_IO_SEC, TZC_BASE, SMALL_PAGE_SIZE); register_phys_mem_pgdir(MEM_AREA_IO_SEC, USART1_BASE, SMALL_PAGE_SIZE); -@@ -69,6 +99,12 @@ register_dynamic_shm(DDR_BASE, CFG_TZDRAM_START - DDR_BASE); +@@ -66,6 +97,20 @@ register_dynamic_shm(DDR_BASE, CFG_TZDRAM_START - DDR_BASE); register_dynamic_shm(TZDRAM_END, DRAM_END - TZDRAM_END); #endif +/* Map non-secure DDR bottom for the low power sequence */ +register_phys_mem(MEM_AREA_RAM_NSEC, DDR_BASE, SMALL_PAGE_SIZE); + ++#ifdef CFG_RPROC_PTA ++/* Map MCU RETRAM as read write for Cortex-M4 firmware management */ ++register_phys_mem(MEM_AREA_IO_SEC, RETRAM_BASE, RETRAM_SIZE); ++ ++/* Map MCU SRAM as read write for Cortex-M4 firmware management */ ++register_phys_mem(MEM_AREA_IO_SEC, MCUSRAM_BASE, MCUSRAM_SIZE); ++#endif ++ +/* Map TEE physical RAM as read-only for content storage when suspending */ +register_phys_mem(MEM_AREA_ROM_SEC, TEE_RAM_START, TEE_RAM_PH_SIZE); + - static const struct thread_handlers handlers = { - .cpu_on = pm_panic, - .cpu_off = pm_panic, -@@ -185,8 +221,86 @@ static TEE_Result init_console_from_dt(void) + #define _ID2STR(id) (#id) + #define ID2STR(id) _ID2STR(id) + +@@ -168,8 +213,106 @@ static TEE_Result init_console_from_dt(void) /* Probe console from DT once clock inits (service init level) are completed */ service_init_late(init_console_from_dt); @@ -9009,6 +8051,26 @@ index 9947e71..40e4263 100644 +/* Compute PLL1 settings once PMIC init is completed */ +driver_init_late(initialize_pll1_settings); + ++static TEE_Result disable_usb_phy_regulator(void) ++{ ++ if (stm32mp_dt_pmic_status() > 0) { ++ const char *name = stm32mp_pmic_get_usb_supply_name(); ++ ++ if (!name) ++ return TEE_SUCCESS; ++ ++ stm32mp_get_pmic(); ++ if (stpmic1_regulator_disable(name)) ++ panic(); ++ ++ stm32mp_put_pmic(); ++ } ++ ++ return TEE_SUCCESS; ++} ++ ++/* Disable USB regulator to avoid initialization issues */ ++boot_final(disable_usb_phy_regulator); #endif +static uintptr_t stm32_dbgmcu_base(void) @@ -9061,21 +8123,7 @@ index 9947e71..40e4263 100644 /* * GIC init, used also for primary/secondary boot core wake completion */ -@@ -211,6 +325,13 @@ void main_secondary_init_gic(void) - { - gic_cpu_init(&gic_data); - -+#if CFG_TEE_CORE_NB_CORE == 2 -+ /* Secondary core release constraint on APB5 clock */ -+ io_write32(stm32mp_bkpreg(BCKR_CORE1_MAGIC_NUMBER), -+ BOOT_API_A7_RESET_MAGIC_NUMBER); -+ stm32_clock_disable(RTCAPB); -+#endif -+ - stm32mp_register_online_cpu(); - } - -@@ -229,7 +350,11 @@ static TEE_Result init_stm32mp1_drivers(void) +@@ -212,7 +355,11 @@ static TEE_Result init_stm32mp1_drivers(void) (SYSRAM_SEC_SIZE >= CFG_TZSRAM_SIZE))); etzpc_configure_tzma(1, SYSRAM_SEC_SIZE >> SMALL_PAGE_SHIFT); @@ -9087,7 +8135,7 @@ index 9947e71..40e4263 100644 return TEE_SUCCESS; } -@@ -258,12 +383,20 @@ void stm32mp_get_bsec_static_cfg(struct stm32_bsec_static_cfg *cfg) +@@ -241,12 +388,20 @@ void stm32mp_get_bsec_static_cfg(struct stm32_bsec_static_cfg *cfg) bool stm32mp_is_closed_device(void) { @@ -9111,7 +8159,7 @@ index 9947e71..40e4263 100644 return false; return true; -@@ -307,6 +440,20 @@ vaddr_t stm32mp_bkpreg(unsigned int idx) +@@ -290,6 +445,20 @@ vaddr_t stm32mp_bkpreg(unsigned int idx) return bkpreg_base() + (idx * sizeof(uint32_t)); } @@ -9132,7 +8180,7 @@ index 9947e71..40e4263 100644 vaddr_t stm32_get_gpio_bank_base(unsigned int bank) { static struct io_pa_va gpios_nsec_base = { .pa = GPIOS_NSEC_BASE }; -@@ -339,3 +486,162 @@ unsigned int stm32_get_gpio_bank_clock(unsigned int bank) +@@ -322,3 +491,178 @@ unsigned int stm32_get_gpio_bank_clock(unsigned int bank) assert(bank <= GPIO_BANK_K); return GPIOA + bank; } @@ -9199,6 +8247,22 @@ index 9947e71..40e4263 100644 + } +} + ++enum etzpc_decprot_attributes stm32mp_etzpc_binding2decprot(uint32_t mode) ++{ ++ switch (mode) { ++ case DECPROT_S_RW: ++ return ETZPC_DECPROT_S_RW; ++ case DECPROT_NS_R_S_W: ++ return ETZPC_DECPROT_NS_R_S_W; ++ case DECPROT_MCU_ISOLATION: ++ return ETZPC_DECPROT_MCU_ISOLATION; ++ case DECPROT_NS_RW: ++ return ETZPC_DECPROT_NS_RW; ++ default: ++ panic(); ++ } ++} ++ +unsigned int stm32mp_iwdg_irq2instance(size_t irq) +{ + int id = irq - STM32MP1_IRQ_IWDG1; @@ -9275,13 +8339,13 @@ index 9947e71..40e4263 100644 + switch ((io_read32(rcc_base + RCC_BDCR) & + RCC_BDCR_RTCSRC_MASK) >> RCC_BDCR_RTCSRC_SHIFT) { + case 1: -+ rtc_freq = stm32_clock_get_rate(CK_LSE); ++ rtc_freq = clk_get_rate(CK_LSE); + break; + case 2: -+ rtc_freq = stm32_clock_get_rate(CK_LSI); ++ rtc_freq = clk_get_rate(CK_LSI); + break; + case 3: -+ rtc_freq = stm32_clock_get_rate(CK_HSE); ++ rtc_freq = clk_get_rate(CK_HSE); + rtc_freq /= (io_read32(rcc_base + RCC_RTCDIVR) & + RCC_DIVR_DIV_MASK) + 1U; + break; @@ -9290,14 +8354,14 @@ index 9947e71..40e4263 100644 + } + + apb1_div = io_read32(rcc_base + RCC_APB1DIVR) & RCC_APBXDIV_MASK; -+ apb1_freq = stm32_clock_get_rate(CK_MCU) >> apb1_div; ++ apb1_freq = clk_get_rate(CK_MCU) >> apb1_div; + + return apb1_freq < (rtc_freq * 7U); +} +#endif diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.c b/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.c new file mode 100644 -index 0000000..d99ee32 +index 000000000..486977baa --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.c @@ -0,0 +1,152 @@ @@ -9310,8 +8374,8 @@ index 0000000..d99ee32 +#include +#include +#include ++#include +#include -+#include +#include +#include +#include @@ -9455,7 +8519,7 @@ index 0000000..d99ee32 +#endif diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.h b/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.h new file mode 100644 -index 0000000..3d7d247 +index 000000000..3d7d247d9 --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/nsec-service/low_power_svc.h @@ -0,0 +1,55 @@ @@ -9516,7 +8580,7 @@ index 0000000..3d7d247 +#endif /* LOW_POWER_SVC_H */ diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.c b/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.c new file mode 100644 -index 0000000..6c78d82 +index 000000000..6c78d8203 --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.c @@ -0,0 +1,89 @@ @@ -9611,7 +8675,7 @@ index 0000000..6c78d82 +} diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.h b/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.h new file mode 100644 -index 0000000..429d620 +index 000000000..429d62071 --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/nsec-service/pwr_svc.h @@ -0,0 +1,22 @@ @@ -9639,10 +8703,10 @@ index 0000000..429d620 +#endif /* __PWR_SVC_H__*/ diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c b/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c new file mode 100644 -index 0000000..362e6d6 +index 000000000..b4307b065 --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c -@@ -0,0 +1,195 @@ +@@ -0,0 +1,139 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2017-2019, STMicroelectronics @@ -9651,7 +8715,6 @@ index 0000000..362e6d6 +#include +#include +#include -+#include +#include +#include +#include @@ -9661,29 +8724,10 @@ index 0000000..362e6d6 +#include "rcc_svc.h" +#include "stm32mp1_smc.h" + -+#undef FULL_RCC_ACCESS -+ +static bool offset_is_clear_register(uint32_t __maybe_unused offset) +{ -+#ifdef FULL_RCC_ACCESS -+ switch (offset) { -+ case RCC_OCENCLRR: -+ case RCC_MP_SREQCLRR: -+ case RCC_APB5RSTCLRR: -+ case RCC_AHB5RSTCLRR: -+ case RCC_MP_APB5ENCLRR: -+ case RCC_MP_AHB5ENCLRR: -+ case RCC_MP_APB5LPENCLRR: -+ case RCC_MP_AHB5LPENCLRR: -+ case RCC_MP_IWDGFZCLRR: -+ return true; -+ default: -+ return false; -+ } -+#else + /* All allowed registers are non set/clear registers */ + return false; -+#endif +} + +static void access_allowed_mask(uint32_t request, uint32_t offset, @@ -9730,8 +8774,8 @@ index 0000000..362e6d6 + } +} + -+static void raw_allowed_access_request(uint32_t request, -+ uint32_t offset, uint32_t value) ++static uint32_t raw_allowed_access_request(uint32_t request, ++ uint32_t offset, uint32_t value) +{ + uint32_t allowed_mask = 0; + @@ -9743,47 +8787,13 @@ index 0000000..362e6d6 + case RCC_MP_GCR: + allowed_mask = RCC_MP_GCR_BOOT_MCU; + break; -+ -+#ifdef FULL_RCC_ACCESS -+ case RCC_OCENSETR: -+ case RCC_OCENCLRR: -+ case RCC_HSICFGR: -+ case RCC_CSICFGR: -+ case RCC_MP_BOOTCR: /* Allowed MPU/MCU reboot cfg */ -+ case RCC_MP_GCR: /* Allowed MPU/MCU reboot cfg */ -+ case RCC_MP_GRSTCSETR: /* Allowed MCU and system reset */ -+ case RCC_BR_RSTSCLRR: /* Allowed system reset status */ -+ case RCC_MC_RSTSCLRR: /* Allowed system reset status */ -+ case RCC_MP_RSTSCLRR: /* Allowed system reset status */ -+ case RCC_BDCR: -+ case RCC_RDLSICR: -+ case RCC_APB5RSTSETR: -+ case RCC_APB5RSTCLRR: -+ case RCC_MP_APB5ENSETR: -+ case RCC_MP_APB5ENCLRR: -+ case RCC_MP_APB5LPENSETR: -+ case RCC_MP_APB5LPENCLRR: -+ case RCC_AHB5RSTSETR: -+ case RCC_AHB5RSTCLRR: -+ case RCC_MP_AHB5ENSETR: -+ case RCC_MP_AHB5ENCLRR: -+ case RCC_MP_AHB5LPENSETR: -+ case RCC_MP_AHB5LPENCLRR: -+ case RCC_RTCDIVR: -+ case RCC_I2C46CKSELR: -+ case RCC_SPI6CKSELR: -+ case RCC_UART1CKSELR: -+ case RCC_RNG1CKSELR: -+ case RCC_MP_IWDGFZSETR: -+ case RCC_MP_IWDGFZCLRR: -+ allowed_mask = UINT32_MAX; -+ break; -+#endif + default: -+ panic(); ++ return STM32_SIP_SVC_INVALID_PARAMS; + } + + access_allowed_mask(request, offset, value, allowed_mask); ++ ++ return STM32_SIP_SVC_OK; +} + +uint32_t rcc_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3) @@ -9808,9 +8818,7 @@ index 0000000..362e6d6 + request == STM32_SIP_SVC_REG_SET ? "set" : "clear", + value, offset); + -+ raw_allowed_access_request(request, offset, value); -+ -+ return STM32_SIP_SVC_OK; ++ return raw_allowed_access_request(request, offset, value); +} + +uint32_t rcc_opp_scv_handler(uint32_t x1, uint32_t x2, uint32_t *res) @@ -9840,7 +8848,7 @@ index 0000000..362e6d6 +} diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.h b/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.h new file mode 100644 -index 0000000..873458f +index 000000000..873458f49 --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.h @@ -0,0 +1,30 @@ @@ -9875,7 +8883,7 @@ index 0000000..873458f + +#endif /*RCC_SVC_H*/ diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h b/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h -index 7f16160..86deb59 100644 +index 3fbde31fe..a1f0e5859 100644 --- a/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h +++ b/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h @@ -14,7 +14,7 @@ @@ -9887,10 +8895,11 @@ index 7f16160..86deb59 100644 /* STM32 SIP service generic return codes */ #define STM32_SIP_SVC_OK 0x0 -@@ -72,6 +72,51 @@ +@@ -71,6 +71,51 @@ + */ #define STM32_SIP_SVC_FUNC_VERSION 0xff03 - /* ++/* + * SIP function STM32_SIP_SVC_FUNC_RCC + * + * Argument a0: (input) SMCC ID @@ -9935,14 +8944,14 @@ index 7f16160..86deb59 100644 +#define STM32_SIP_SVC_REG_SET 0x2 +#define STM32_SIP_SVC_REG_CLEAR 0x3 + -+/* + /* * SIP functions STM32_SIP_SVC_FUNC_BSEC * - * Argument a0: (input) SMCCC function ID -@@ -91,6 +136,91 @@ - #define STM32_SIP_SVC_BSEC_WRLOCK_OTP 0x5 +@@ -92,6 +137,91 @@ + /* reserved for STM32_SIP_SVC_SMC_WRITE_ALL 0x6 */ + #define STM32_SIP_SVC_BSEC_WRLOCK_OTP 0x7 - /* ++/* + * SIP functions STM32_SIP_FUNC_SR_MODE + * + * Argument a0: (input) SMCC ID @@ -10027,11 +9036,10 @@ index 7f16160..86deb59 100644 +#define STM32_SIP_SVC_RCC_OPP_SET 0x0 +#define STM32_SIP_SVC_RCC_OPP_ROUND 0x1 + -+/* + /* * SIP function STM32_SIP_SVC_FUNC_SCMI_AGENT0 * SIP function STM32_SIP_SVC_FUNC_SCMI_AGENT1 - * -@@ -101,4 +231,68 @@ +@@ -103,4 +233,68 @@ #define STM32_SIP_SVC_FUNC_SCMI_AGENT0 0x2000 #define STM32_SIP_SVC_FUNC_SCMI_AGENT1 0x2001 @@ -10101,7 +9109,7 @@ index 7f16160..86deb59 100644 + #endif /* __STM32MP1_SMC_H__*/ diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_svc_setup.c b/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_svc_setup.c -index 49d23ff..f5f131d 100644 +index 49d23ff02..f5f131df6 100644 --- a/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_svc_setup.c +++ b/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_svc_setup.c @@ -7,11 +7,32 @@ @@ -10209,7 +9217,7 @@ index 49d23ff..f5f131d 100644 return SM_HANDLER_PENDING_SMC; } diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/sub.mk b/core/arch/arm/plat-stm32mp1/nsec-service/sub.mk -index 6e1abcb..acccda1 100644 +index 6e1abcb4a..acccda16a 100644 --- a/core/arch/arm/plat-stm32mp1/nsec-service/sub.mk +++ b/core/arch/arm/plat-stm32mp1/nsec-service/sub.mk @@ -2,3 +2,6 @@ global-incdirs-y += . @@ -10219,11 +9227,103 @@ index 6e1abcb..acccda1 100644 +srcs-$(CFG_STM32_LOWPOWER_SIP) += low_power_svc.c +srcs-$(CFG_STM32_PWR_SIP) += pwr_svc.c +srcs-$(CFG_STM32_RCC_SIP) += rcc_svc.c +diff --git a/core/arch/arm/plat-stm32mp1/plat_tzc400.c b/core/arch/arm/plat-stm32mp1/plat_tzc400.c +index bce923711..23c7170e5 100644 +--- a/core/arch/arm/plat-stm32mp1/plat_tzc400.c ++++ b/core/arch/arm/plat-stm32mp1/plat_tzc400.c +@@ -33,39 +33,45 @@ static struct itr_handler tzc_itr_handler = { + }; + DECLARE_KEEP_PAGER(tzc_itr_handler); + +-static bool tzc_region_is_non_secure(unsigned int i, vaddr_t base, size_t size) ++static bool tzc_find_region(vaddr_t base, size_t size, struct tzc_region_config *region_cfg) ++{ ++ uint8_t i = 1; ++ ++ while (true) { ++ if (tzc_get_region_config(i++, region_cfg) != TEE_SUCCESS) ++ return false; ++ ++ if (region_cfg->base <= base && region_cfg->top >= (base + size - 1)) ++ return true; ++ } ++} ++ ++static bool tzc_region_is_non_secure(vaddr_t base, size_t size) + { + struct tzc_region_config region_cfg = { }; + uint32_t ns_cpu_mask = TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID); + uint32_t filters_mask = GENMASK_32(1, 0); + +- if (tzc_get_region_config(i, ®ion_cfg)) +- panic(); +- +- return region_cfg.base == base && region_cfg.top == (base + size - 1) && +- region_cfg.sec_attr == TZC_REGION_S_NONE && +- (region_cfg.ns_device_access & ns_cpu_mask) == ns_cpu_mask && +- region_cfg.filters == filters_mask; ++ return tzc_find_region(base, size, ®ion_cfg) && ++ region_cfg.sec_attr == TZC_REGION_S_NONE && ++ (region_cfg.ns_device_access & ns_cpu_mask) == ns_cpu_mask && ++ region_cfg.filters == filters_mask; + } + +-static bool tzc_region_is_secure(unsigned int i, vaddr_t base, size_t size) ++static bool tzc_region_is_secure(vaddr_t base, size_t size) + { + struct tzc_region_config region_cfg = { }; + uint32_t filters_mask = GENMASK_32(1, 0); + +- if (tzc_get_region_config(i, ®ion_cfg)) +- panic(); +- +- return region_cfg.base == base && region_cfg.top == (base + size - 1) && +- region_cfg.sec_attr == TZC_REGION_S_RDWR && +- region_cfg.ns_device_access == 0 && +- region_cfg.filters == filters_mask; ++ return tzc_find_region(base, size, ®ion_cfg) && ++ region_cfg.sec_attr == TZC_REGION_S_RDWR && ++ region_cfg.ns_device_access == 0 && ++ region_cfg.filters == filters_mask; + } + + static TEE_Result init_stm32mp1_tzc(void) + { + void *base = phys_to_virt(TZC_BASE, MEM_AREA_IO_SEC); +- unsigned int region_index = 1; + const uint64_t dram_start = DDR_BASE; + const uint64_t dram_end = dram_start + CFG_DRAM_SIZE; + const uint64_t tzdram_start = CFG_TZDRAM_START; +@@ -83,21 +89,15 @@ static TEE_Result init_stm32mp1_tzc(void) + * expectations. + */ + if (dram_start < tzdram_start) { +- if (!tzc_region_is_non_secure(region_index, dram_start, +- tzdram_start - dram_start)) ++ if (!tzc_region_is_non_secure(dram_start, tzdram_start - dram_start)) + panic("Unexpected TZC area on non-secure region"); +- +- region_index++; + } + +- if (!tzc_region_is_secure(region_index, tzdram_start, tzdram_size)) ++ if (!tzc_region_is_secure(tzdram_start, tzdram_size)) + panic("Unexpected TZC configuration on secure region"); + + if (tzdram_end < dram_end) { +- region_index++; +- +- if (!tzc_region_is_non_secure(region_index, tzdram_end, +- dram_end - tzdram_end)) ++ if (!tzc_region_is_non_secure(tzdram_end, dram_end - tzdram_end)) + panic("Unexpected TZC area on non-secure region"); + } + diff --git a/core/arch/arm/plat-stm32mp1/platform_config.h b/core/arch/arm/plat-stm32mp1/platform_config.h -index cf68f45..2b4bd95 100644 +index cf68f4510..0ea5efc32 100644 --- a/core/arch/arm/plat-stm32mp1/platform_config.h +++ b/core/arch/arm/plat-stm32mp1/platform_config.h -@@ -8,14 +8,45 @@ +@@ -8,14 +8,47 @@ #include @@ -10258,6 +9358,8 @@ index cf68f45..2b4bd95 100644 +#endif /*CFG_WITH_PAGER*/ + /* SoC interface registers base address */ ++#define MCUSRAM_BASE 0x30000000ul ++#define RETRAM_BASE 0x38000000ul +#define BKPSRAM_BASE 0x54000000 #define BSEC_BASE 0x5c005000 #define ETZPC_BASE 0x5c007000 @@ -10269,7 +9371,7 @@ index cf68f45..2b4bd95 100644 #define GIC_BASE 0xa0021000ul #define GPIOA_BASE 0x50002000 #define GPIOB_BASE 0x50003000 -@@ -39,9 +70,24 @@ +@@ -39,9 +72,24 @@ #define RNG1_BASE 0x54003000 #define RTC_BASE 0x5c004000 #define SPI6_BASE 0x5c001000 @@ -10294,7 +9396,7 @@ index cf68f45..2b4bd95 100644 #define TZC_BASE 0x5c006000 #define UART1_BASE 0x5c000000 #define UART2_BASE 0x4000e000 -@@ -52,6 +98,9 @@ +@@ -52,6 +100,9 @@ #define UART7_BASE 0x40018000 #define UART8_BASE 0x40019000 @@ -10304,7 +9406,7 @@ index cf68f45..2b4bd95 100644 /* Console configuration */ #define STM32MP1_DEBUG_USART_BASE UART4_BASE #define GIC_SPI_UART4 84 -@@ -65,16 +114,21 @@ +@@ -65,16 +116,21 @@ #define OTP_MAX_SIZE (STM32MP1_OTP_MAX_ID + 1U) @@ -10318,13 +9420,13 @@ index cf68f45..2b4bd95 100644 -#define HW2_OTP 18 +#define CFG0_OTP "cfg0_otp" +#define CFG0_OTP_SECURED_POS 6 - --#define DATA0_OTP_SECURED_POS 6 ++ +#define HW2_OTP "hw2_otp" +#define HW2_OTP_IWDG_HW_ENABLE_SHIFT 3 +#define HW2_OTP_IWDG_FZ_STOP_SHIFT 5 +#define HW2_OTP_IWDG_FZ_STANDBY_SHIFT 7 -+ + +-#define DATA0_OTP_SECURED_POS 6 +#define PART_NUMBER_OTP "part_number_otp" +#define PART_NUMBER_OTP_PART_MASK GENMASK_32(7, 0) +#define PART_NUMBER_OTP_PART_SHIFT 0 @@ -10335,7 +9437,7 @@ index cf68f45..2b4bd95 100644 /* GIC resources */ #define GIC_SIZE 0x2000 -@@ -84,11 +138,14 @@ +@@ -84,11 +140,14 @@ #define GIC_NON_SEC_SGI_0 0 #define GIC_SEC_SGI_0 8 #define GIC_SEC_SGI_1 9 @@ -10350,7 +9452,7 @@ index cf68f45..2b4bd95 100644 /* * GPIO banks: 11 non secure banks (A to K) and 1 secure bank (Z) * Bank register's base address is computed from the bank ID listed here. -@@ -116,6 +173,16 @@ +@@ -116,6 +175,16 @@ #define GPIO_BANK_K 10U #define GPIO_BANK_Z 25U @@ -10367,7 +9469,7 @@ index cf68f45..2b4bd95 100644 /* TAMP resources */ #define TAMP_BKP_REGISTER_OFF 0x100 -@@ -140,6 +207,24 @@ +@@ -140,6 +209,24 @@ #define USART3_BASE UART3_BASE #define USART6_BASE UART6_BASE @@ -10392,10 +9494,16 @@ index cf68f45..2b4bd95 100644 /* SYSRAM layout */ #define SYSRAM_SIZE 0x40000 #define SYSRAM_NS_SIZE (SYSRAM_SIZE - SYSRAM_SEC_SIZE) -@@ -153,4 +238,32 @@ +@@ -153,4 +240,38 @@ #define SYSRAM_SEC_SIZE SYSRAM_SIZE #endif ++/* RETRAM layout */ ++#define RETRAM_SIZE 0x10000 ++ ++/* MCUSRAM layout */ ++#define MCUSRAM_SIZE 0x60000 ++ +/* SoC part numbers and revisions */ +#define STM32MP1_CHIP_ID 0x500 + @@ -10427,18 +9535,19 @@ index cf68f45..2b4bd95 100644 #endif /*PLATFORM_CONFIG_H*/ diff --git a/core/arch/arm/plat-stm32mp1/pm/context.c b/core/arch/arm/plat-stm32mp1/pm/context.c new file mode 100644 -index 0000000..7a518a3 +index 000000000..8dddb0c02 --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/pm/context.c -@@ -0,0 +1,521 @@ +@@ -0,0 +1,522 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* -+ * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + */ + +#include +#include ++#include +#include +#include +#include @@ -10555,15 +9664,15 @@ index 0000000..7a518a3 + struct pm_mailbox *mailbox = get_pm_mailbox(); + struct retram_resume_ctx *ctx = get_retram_resume_ctx(); + -+ stm32_clock_enable(RTCAPB); ++ clk_enable(RTCAPB); + + DMSG("Backup registers: address 0x%" PRIx32 ", magic 0x%" PRIx32, + *(uint32_t *)stm32mp_bkpreg(BCKR_CORE1_BRANCH_ADDRESS), + *(uint32_t *)stm32mp_bkpreg(BCKR_CORE1_MAGIC_NUMBER)); + -+ stm32_clock_disable(RTCAPB); ++ clk_disable(RTCAPB); + -+ stm32_clock_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + DMSG("BKPSRAM mailbox: 0x%" PRIx32 ", zd 0x%" PRIx32 ", ep 0x%" PRIx32, + mailbox->magic, mailbox->zq0cr0_zdata, @@ -10572,7 +9681,7 @@ index 0000000..7a518a3 + DMSG("BKPSRAM context: teeram backup @%" PRIx32 ", resume @0x%" PRIx32, + ctx->teeram_bkp_pa, ctx->resume_pa); + -+ stm32_clock_disable(BKPSRAM); ++ clk_disable(BKPSRAM); +} +#else +static void __maybe_unused dump_context(void) @@ -10592,7 +9701,7 @@ index 0000000..7a518a3 + if (plat_ctx.stgen_cnt_l < 10) + plat_ctx.stgen_cnt_h = io_read32(stgen + CNTCVU_OFFSET); + -+ stm32_clock_enable(RTC); ++ clk_enable(RTC); + stm32_rtc_get_calendar(&plat_ctx.rtc); +} + @@ -10602,13 +9711,13 @@ index 0000000..7a518a3 + vaddr_t stgen = stm32mp_stgen_base(); + struct retram_resume_ctx *ctx = get_retram_resume_ctx(); + -+ stm32_clock_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + DMSG("CCM decryption duration %llums", + ((unsigned long long)ctx->stgen_cnt * 1000) / + io_read32(stgen + CNTFID_OFFSET)); + -+ stm32_clock_enable(BKPSRAM); ++ clk_enable(BKPSRAM); +} +#else +static void print_ccm_decryption_duration(void) @@ -10637,7 +9746,7 @@ index 0000000..7a518a3 + io_setbits32(stgen + CNTCR_OFFSET, CNTCR_EN); + + /* Balance clock enable(RTC) at save_time() */ -+ stm32_clock_disable(RTC); ++ clk_disable(RTC); + + print_ccm_decryption_duration(); +} @@ -10674,12 +9783,12 @@ index 0000000..7a518a3 + struct retram_resume_ctx *ctx = get_retram_resume_ctx(); + struct pm_mailbox *mailbox = get_pm_mailbox(); + -+ stm32_clock_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + + memset(ctx, 0xa5, sizeof(*ctx)); + memset(mailbox, 0xa5, sizeof(*mailbox)); + -+ stm32_clock_disable(BKPSRAM); ++ clk_disable(BKPSRAM); +} + +static struct mobj *teeram_bkp_mobj; @@ -10706,9 +9815,9 @@ index 0000000..7a518a3 + assert((mobj_get_va(teeram_bkp_mobj, 0) != NULL) && + (mobj_get_pa(teeram_bkp_mobj, 0, 0, &pa) == 0)); + -+ stm32_clock_enable(BKPSRAM); ++ clk_enable(BKPSRAM); + memset(ctx, 0, sizeof(*ctx)); -+ stm32_clock_disable(BKPSRAM); ++ clk_disable(BKPSRAM); +} + +/* @@ -10751,7 +9860,7 @@ index 0000000..7a518a3 + COMPILE_TIME_ASSERT(sizeof(struct pm_mailbox) < + BKPSRAM_PM_MAILBOX_SIZE); + -+ assert(stm32_clock_is_enabled(BKPSRAM)); ++ assert(clk_is_enabled(BKPSRAM)); + + memset(mailbox, 0, sizeof(*mailbox)); + @@ -10790,8 +9899,8 @@ index 0000000..7a518a3 + COMPILE_TIME_ASSERT(PM_CTX_CCM_CTR0_SIZE == sizeof(ccm->ctr0)); + COMPILE_TIME_ASSERT(PM_CTX_CCM_TAG_SIZE == sizeof(ccm->tag)); + -+ assert(stm32_clock_is_enabled(BKPSRAM) && -+ stm32_clock_is_enabled(CRYP1)); ++ assert(clk_is_enabled(BKPSRAM) && ++ clk_is_enabled(CRYP1)); + + memcpy(ctx->resume_sequence, + (void *)(vaddr_t)stm32mp_bkpsram_resume, size); @@ -10852,8 +9961,8 @@ index 0000000..7a518a3 + uint32_t magic = 0; + uint32_t hint = 0; + -+ assert(stm32_clock_is_enabled(BKPSRAM) && -+ stm32_clock_is_enabled(RTCAPB)); ++ assert(clk_is_enabled(BKPSRAM) && ++ clk_is_enabled(RTCAPB)); + + if (suspend) { + magic = BOOT_API_A7_CORE0_MAGIC_NUMBER; @@ -10876,18 +9985,18 @@ index 0000000..7a518a3 + + if (enable) { + assert(!clocks_enabled); -+ stm32_clock_enable(BKPSRAM); -+ stm32_clock_enable(RTCAPB); -+ stm32_clock_enable(CRYP1); ++ clk_enable(BKPSRAM); ++ clk_enable(RTCAPB); ++ clk_enable(CRYP1); + clocks_enabled = true; + return; + } + + /* Suspended TEE RAM state left the clocks enabled */ + if (clocks_enabled) { -+ stm32_clock_disable(BKPSRAM); -+ stm32_clock_disable(RTCAPB); -+ stm32_clock_disable(CRYP1); ++ clk_disable(BKPSRAM); ++ clk_disable(RTCAPB); ++ clk_disable(CRYP1); + clocks_enabled = false; + } +} @@ -10954,7 +10063,7 @@ index 0000000..7a518a3 +driver_init(init_pm_support); diff --git a/core/arch/arm/plat-stm32mp1/pm/context.h b/core/arch/arm/plat-stm32mp1/pm/context.h new file mode 100644 -index 0000000..a806d68 +index 000000000..a806d685b --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/pm/context.h @@ -0,0 +1,102 @@ @@ -11062,7 +10171,7 @@ index 0000000..a806d68 +#endif /*__STM32MP_PM_CONTEXT_H__*/ diff --git a/core/arch/arm/plat-stm32mp1/pm/context_asm_defines.c b/core/arch/arm/plat-stm32mp1/pm/context_asm_defines.c new file mode 100644 -index 0000000..34c797f +index 000000000..34c797f52 --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/pm/context_asm_defines.c @@ -0,0 +1,28 @@ @@ -11096,10 +10205,10 @@ index 0000000..34c797f +} diff --git a/core/arch/arm/plat-stm32mp1/pm/low_power.c b/core/arch/arm/plat-stm32mp1/pm/low_power.c new file mode 100644 -index 0000000..0a9a166 +index 000000000..f06d8273d --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/pm/low_power.c -@@ -0,0 +1,609 @@ +@@ -0,0 +1,626 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved @@ -11141,6 +10250,8 @@ index 0000000..0a9a166 + +#define TIMEOUT_US_1MS 1000 + ++#define PWRLP_TEMPO_5_HSI 5 ++ +static uint8_t gicd_rcc_wakeup; +static uint8_t gicc_pmr; + @@ -11670,6 +10781,7 @@ index 0000000..0a9a166 +static TEE_Result init_low_power(void) +{ + vaddr_t pwr_base = stm32_pwr_base(); ++ vaddr_t rcc_base = stm32_rcc_base(); + + itr_add(&rcc_wakeup_handler); + itr_enable(rcc_wakeup_handler.it); @@ -11681,6 +10793,20 @@ index 0000000..0a9a166 + io_mask32(pwr_base + PWR_CR2_OFF, + PWR_CR2_BREN | PWR_CR2_RREN, PWR_CR2_BREN | PWR_CR2_RREN); + ++ /* ++ * Configure Standby mode available for MCU by default ++ * and allow to switch in standby SoC in all case ++ */ ++ io_setbits32(pwr_base + PWR_MCUCR_OFF, PWR_MCUCR_PDDS); ++ ++ /* Disable STOP request */ ++ io_setbits32(rcc_base + RCC_MP_SREQCLRR, ++ RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1); ++ ++ /* Wait 5 HSI periods before re-enabling PLLs after STOP modes */ ++ io_clrsetbits32(rcc_base + RCC_PWRLPDLYCR, RCC_PWRLPDLYCR_PWRLP_DLY_MASK, ++ PWRLP_TEMPO_5_HSI); ++ + return TEE_SUCCESS; +} +service_init(init_low_power); @@ -11711,10 +10837,10 @@ index 0000000..0a9a166 +} diff --git a/core/arch/arm/plat-stm32mp1/pm/pm_helpers.S b/core/arch/arm/plat-stm32mp1/pm/pm_helpers.S new file mode 100644 -index 0000000..cd8e48c +index 000000000..63142a08e --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/pm/pm_helpers.S -@@ -0,0 +1,740 @@ +@@ -0,0 +1,729 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2018, STMicroelectronics @@ -11731,7 +10857,6 @@ index 0000000..cd8e48c +#include +#include +#include -+#include +#include +#include +#include @@ -11825,7 +10950,6 @@ index 0000000..cd8e48c + * point in TEE_RAM. This function and its resources shall execute in place. + */ +FUNC stm32mp_bkpsram_resume , : -+UNWIND( .fnstart) +UNWIND( .cantunwind) + + PRINT_CHAR r0, r1, '0' @@ -12313,14 +11437,12 @@ index 0000000..cd8e48c +stm32mp_bkpsram_image_end: + nop + -+UNWIND( .fnend) +END_FUNC stm32mp_bkpsram_resume + +/* + * int stm32mp_ccm_encrypt_teeram(ctx, dst, src, len) + */ +FUNC stm32mp_ccm_encrypt_teeram , : -+UNWIND( .fnstart) + push {r4-r12, lr} +UNWIND( .save {r4-r12, lr}) + mov r11, r0 @@ -12334,14 +11456,12 @@ index 0000000..cd8e48c + bl stm32mp_ccm_teeram + bl _save_resume_time + pop {r4-r12, pc} -+UNWIND( .fnend) +END_FUNC stm32mp_ccm_encrypt_teeram + +/* + * int stm32mp_ccm_decrypt_teeram(ctx, cryp_base, dst, src) + */ +FUNC stm32mp_ccm_decrypt_teeram , : -+UNWIND( .fnstart) + push {r4-r12, lr} +UNWIND( .save {r4-r12, lr}) + mov r11, r0 @@ -12355,7 +11475,6 @@ index 0000000..cd8e48c + bl stm32mp_ccm_teeram + bl _save_resume_time + pop {r4-r12, pc} -+UNWIND( .fnend) +END_FUNC stm32mp_ccm_decrypt_teeram + +/* @@ -12370,7 +11489,6 @@ index 0000000..cd8e48c + * sm_pm_cpu_resume(). + */ +FUNC stm32mp_sysram_resume, : -+UNWIND( .fnstart) +UNWIND( .cantunwind) + /* Invalidate the data cache */ + @@ -12424,7 +11542,6 @@ index 0000000..cd8e48c + + blx plat_cpu_reset_early + b sm_pm_cpu_resume -+UNWIND( .fnend) +END_FUNC stm32mp_sysram_resume + +/* @@ -12434,7 +11551,6 @@ index 0000000..cd8e48c + * Preserve the execution mode in CPSR. + */ +FUNC stm32mp_cpu_reset_state, : -+UNWIND( .fnstart) + push {r12, lr} +UNWIND( .save {r12, lr}) + @@ -12453,11 +11569,10 @@ index 0000000..cd8e48c + isb + + pop {r12, pc} -+UNWIND( .fnend) +END_FUNC stm32mp_cpu_reset_state diff --git a/core/arch/arm/plat-stm32mp1/pm/power.h b/core/arch/arm/plat-stm32mp1/pm/power.h new file mode 100644 -index 0000000..4a5578c +index 000000000..4a5578c63 --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/pm/power.h @@ -0,0 +1,27 @@ @@ -12490,7 +11605,7 @@ index 0000000..4a5578c +#endif /*__STM32MP_PM_POWER_H__*/ diff --git a/core/arch/arm/plat-stm32mp1/pm/power_config.c b/core/arch/arm/plat-stm32mp1/pm/power_config.c new file mode 100644 -index 0000000..246c92e +index 000000000..61e4f6800 --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/pm/power_config.c @@ -0,0 +1,252 @@ @@ -12502,7 +11617,7 @@ index 0000000..246c92e +#include +#include +#include -+#include ++#include +#include +#include +#include @@ -12747,29 +11862,35 @@ index 0000000..246c92e +#endif +service_init(stm32mp1_init_lp_states); diff --git a/core/arch/arm/plat-stm32mp1/pm/psci.c b/core/arch/arm/plat-stm32mp1/pm/psci.c -index 740b13b..ff7b966 100644 +index 9c472c796..65f583d2e 100644 --- a/core/arch/arm/plat-stm32mp1/pm/psci.c +++ b/core/arch/arm/plat-stm32mp1/pm/psci.c -@@ -5,11 +5,18 @@ +@@ -1,16 +1,23 @@ + // SPDX-License-Identifier: BSD-2-Clause + /* +- * Copyright (c) 2017-2018, STMicroelectronics ++ * Copyright (c) 2017-2020, STMicroelectronics + */ #include #include +#include #include ++#include +#include +#include #include #include #include -+#include + #include +#include +#include #include +#include #include #include - #include -@@ -19,10 +26,17 @@ + #include +@@ -20,10 +27,17 @@ #include #include #include @@ -12787,7 +11908,7 @@ index 740b13b..ff7b966 100644 #define CONSOLE_FLUSH_DELAY_MS 10 -@@ -56,10 +70,9 @@ int psci_affinity_info(uint32_t affinity, uint32_t lowest_affinity_level) +@@ -57,10 +71,9 @@ int psci_affinity_info(uint32_t affinity, uint32_t lowest_affinity_level) DMSG("core %zu, state %u", pos, core_state[pos]); @@ -12800,7 +11921,7 @@ index 740b13b..ff7b966 100644 switch (core_state[pos]) { case CORE_OFF: -@@ -81,35 +94,24 @@ int psci_affinity_info(uint32_t affinity, uint32_t lowest_affinity_level) +@@ -82,38 +95,33 @@ int psci_affinity_info(uint32_t affinity, uint32_t lowest_affinity_level) */ void stm32mp_register_online_cpu(void) { @@ -12840,30 +11961,41 @@ index 740b13b..ff7b966 100644 + stm32_pm_cpu_power_down_wfi(); panic(); } +- stm32_clock_disable(RTCAPB); ++ ++ /* Clear hold in pen flag */ ++ io_write32(stm32mp_bkpreg(BCKR_CORE1_MAGIC_NUMBER), ++ BOOT_API_A7_RESET_MAGIC_NUMBER); ++ ++ /* Balance BKPREG clock gating */ ++ clk_disable(RTCAPB); } -@@ -132,11 +134,15 @@ static void release_secondary_early_hpen(size_t __unused pos) + + core_state[pos] = CORE_ON; +@@ -134,11 +142,16 @@ static void release_secondary_early_hpen(size_t __unused pos) raise_sgi0_as_secure(); udelay(20); -+ stm32_clock_enable(RTCAPB); ++ clk_enable(RTCAPB); + io_write32(stm32mp_bkpreg(BCKR_CORE1_BRANCH_ADDRESS), TEE_LOAD_ADDR); io_write32(stm32mp_bkpreg(BCKR_CORE1_MAGIC_NUMBER), BOOT_API_A7_CORE1_MAGIC_NUMBER); -+ stm32_clock_disable(RTCAPB); ++ dsb_ishst(); ++ clk_disable(RTCAPB); + dsb_ishst(); itr_raise_sgi(GIC_SEC_SGI_0, TARGET_CPU1_GIC_MASK); } -@@ -204,42 +210,189 @@ int psci_cpu_off(void) - +@@ -207,44 +220,188 @@ int psci_cpu_off(void) unlock_state_access(exceptions); -+ /* Enable BKPREG access for the disabled CPU */ -+ stm32_clock_enable(RTCAPB); -+ + /* Enable BKPREG access for the disabled CPU */ +- stm32_clock_enable(RTCAPB); ++ clk_enable(RTCAPB); + thread_mask_exceptions(THREAD_EXCP_ALL); - stm32_pm_cpu_power_down_wfi(); + if (IS_ENABLED(CFG_PM)) @@ -12932,17 +12064,17 @@ index 740b13b..ff7b966 100644 + + stm32mp_pm_restore_context(soc_mode); +} -+ + +- if (TRACE_LEVEL >= TRACE_DEBUG) { +- console_flush(); +- mdelay(CONSOLE_FLUSH_DELAY_MS); +static bool plat_can_suspend(void) +{ + size_t pos = get_core_pos(); + size_t n = 0; + uint32_t exceptions = 0; + bool rc = true; - -- if (TRACE_LEVEL >= TRACE_DEBUG) { -- console_flush(); -- mdelay(CONSOLE_FLUSH_DELAY_MS); ++ + if (!IS_ENABLED(CFG_STM32_RNG)) + return false; + @@ -12962,12 +12094,8 @@ index 740b13b..ff7b966 100644 + + if (core_state[n] != CORE_OFF) + rc = false; - } - -- if (stm32mp_with_pmic()) { -- stm32mp_get_pmic(); -- stpmic1_switch_off(); -- udelay(100); ++ } ++ + unlock_state_access(exceptions); + + return rc; @@ -13001,7 +12129,10 @@ index 740b13b..ff7b966 100644 + break; } -- panic(); +- if (stm32mp_with_pmic()) { +- stm32mp_get_pmic(); +- stpmic1_switch_off(); +- udelay(100); + assert(cpu_mmu_enabled() && core_state[pos] == CORE_ON); + + if (need_to_backup_cpu_context(soc_mode)) { @@ -13024,8 +12155,9 @@ index 740b13b..ff7b966 100644 + } + } else { + ret = plat_suspend((uint32_t)soc_mode); -+ } -+ + } + +- panic(); + if (ret == 0) { + nsec->mon_lr = (uint32_t)entry; + IMSG("Resumed"); @@ -13063,7 +12195,7 @@ index 740b13b..ff7b966 100644 /* Override default psci_cpu_on() with platform supported features */ int psci_features(uint32_t psci_fid) -@@ -256,6 +409,7 @@ int psci_features(uint32_t psci_fid) +@@ -261,6 +418,7 @@ int psci_features(uint32_t psci_fid) return PSCI_RET_SUCCESS; return PSCI_RET_NOT_SUPPORTED; case PSCI_SYSTEM_OFF: @@ -13072,7 +12204,7 @@ index 740b13b..ff7b966 100644 return PSCI_RET_SUCCESS; return PSCI_RET_NOT_SUPPORTED; diff --git a/core/arch/arm/plat-stm32mp1/pm/sub.mk b/core/arch/arm/plat-stm32mp1/pm/sub.mk -index c8ae8f9..d652958 100644 +index c8ae8f915..d652958e3 100644 --- a/core/arch/arm/plat-stm32mp1/pm/sub.mk +++ b/core/arch/arm/plat-stm32mp1/pm/sub.mk @@ -1 +1,7 @@ @@ -13083,8 +12215,542 @@ index c8ae8f9..d652958 100644 +srcs-$(CFG_PM) += pm_helpers.S +srcs-$(CFG_PM) += power_config.c srcs-$(CFG_PSCI_ARM32) += psci.c +diff --git a/core/arch/arm/plat-stm32mp1/remoteproc_pta.c b/core/arch/arm/plat-stm32mp1/remoteproc_pta.c +new file mode 100644 +index 000000000..27b0dfa07 +--- /dev/null ++++ b/core/arch/arm/plat-stm32mp1/remoteproc_pta.c +@@ -0,0 +1,528 @@ ++ // SPDX-License-Identifier: BSD-2-Clause ++ /* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PTA_NAME "remoteproc.pta" ++ ++#define STM32_M4_FW_ID 0 ++ ++/* Firmware states */ ++enum rproc_load_state { ++ REMOTEPROC_OFF = 0, ++ REMOTEPROC_ON, ++}; ++ ++/* ++ * struct rproc_ta_etzpc_rams - memory protection strategy table ++ * @pa - Memory physical base address from current CPU space ++ * @size - Memory region byte size ++ * @etzpc_id - associated ETZPC identifier. ++ * @attr - memory access permission according to @etzpc_decprot_attributes ++ */ ++struct rproc_ta_etzpc_rams { ++ paddr_t pa; ++ size_t size; ++ uint32_t etzpc_id; ++ enum etzpc_decprot_attributes attr; ++}; ++ ++/* ++ * struct rproc_ta_memory_region - Represent a remote processor memory mapping ++ * @pa - Memory physical base address from current CPU space ++ * @da - Memory physical base address from remote processor space ++ * @size - Memory region byte size ++ */ ++struct rproc_ta_memory_region { ++ paddr_t pa; ++ paddr_t da; ++ size_t size; ++}; ++ ++static const struct rproc_ta_etzpc_rams rproc_ta_mp1_m4_rams[] = { ++ /* MCU SRAM 1*/ ++ { ++ .pa = MCUSRAM_BASE, ++ .size = 0x20000, ++ .etzpc_id = STM32MP1_ETZPC_SRAM1_ID, ++ .attr = ETZPC_DECPROT_MCU_ISOLATION, ++ }, ++ /* MCU SRAM 2*/ ++ { ++ .pa = MCUSRAM_BASE + 0x20000, ++ .size = 0x20000, ++ .etzpc_id = STM32MP1_ETZPC_SRAM2_ID, ++ .attr = ETZPC_DECPROT_MCU_ISOLATION, ++ }, ++ ++ /* MCU SRAM 3*/ ++ { ++ /* Used as shared memory between the NS and the coprocessor */ ++ .pa = MCUSRAM_BASE + 0x40000, ++ .size = 0x10000, ++ .etzpc_id = STM32MP1_ETZPC_SRAM3_ID, ++ .attr = ETZPC_DECPROT_NS_RW, ++ }, ++ /* MCU SRAM 4*/ ++ /* Not used reserved by NS for MDMA */ ++ { ++ .pa = MCUSRAM_BASE + 0x50000, ++ .size = 0x10000, ++ .etzpc_id = STM32MP1_ETZPC_SRAM4_ID, ++ .attr = ETZPC_DECPROT_NS_RW, ++ }, ++ ++ /* MCU RETRAM */ ++ { ++ .pa = RETRAM_BASE, ++ .size = RETRAM_SIZE, ++ .etzpc_id = STM32MP1_ETZPC_RETRAM_ID, ++ .attr = ETZPC_DECPROT_MCU_ISOLATION, ++ }, ++}; ++ ++static const struct rproc_ta_memory_region rproc_ta_mp1_m4_mems[] = { ++ /* MCU SRAM */ ++ { .pa = MCUSRAM_BASE, .da = 0x10000000, .size = MCUSRAM_SIZE }, ++ /* Alias of the MCU SRAM */ ++ { .pa = MCUSRAM_BASE, .da = 0x30000000, .size = MCUSRAM_SIZE }, ++ /* RETRAM */ ++ { .pa = RETRAM_BASE, .da = 0x00000000, .size = RETRAM_SIZE }, ++}; ++ ++static enum rproc_load_state rproc_ta_state; ++ ++static TEE_Result rproc_pta_capabilities(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_OUTPUT, ++ TEE_PARAM_TYPE_VALUE_OUTPUT, ++ TEE_PARAM_TYPE_NONE); ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ /* Support only ELF format */ ++ params[1].value.a = PTA_REMOTEPROC_ELF_FMT; ++ ++ /* ++ * Due to stm32mp1 pager, secure memory is too expensive. Support hash ++ * protected image only, so that firmware image can be loaded from ++ * non-secure memory. ++ */ ++ params[2].value.a = PTA_REMOTEPROC_FW_WITH_HASH_TABLE; ++ ++ return TEE_SUCCESS; ++} ++ ++static TEE_Result da_to_pa(paddr_t da, size_t size, paddr_t *pa) ++{ ++ const struct rproc_ta_memory_region *mems = rproc_ta_mp1_m4_mems; ++ size_t i = 0; ++ ++ DMSG("da addr: %#"PRIxPA" size: %zu", da, size); ++ ++ for (i = 0; i < ARRAY_SIZE(rproc_ta_mp1_m4_mems); i++) { ++ if (da >= mems[i].da && ++ (da + size) <= (mems[i].da + mems[i].size)) { ++ *pa = da - mems[i].da + mems[i].pa; ++ DMSG("da %#"PRIxPA" to pa %#"PRIxPA, da, *pa); ++ ++ return TEE_SUCCESS; ++ } ++ } ++ ++ return TEE_ERROR_ACCESS_DENIED; ++} ++ ++static TEE_Result rproc_pta_load_segment(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT); ++ TEE_Result res = TEE_ERROR_GENERIC; ++ paddr_t pa = 0; ++ uint8_t *dst = 0; ++ uint8_t *src = params[1].memref.buffer; ++ size_t size = params[1].memref.size; ++ uint8_t *hash = params[3].memref.buffer; ++ paddr_t da = (paddr_t)reg_pair_to_64(params[2].value.b, ++ params[2].value.a); ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ if (!hash || params[3].memref.size != TEE_SHA256_HASH_SIZE) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ /* Only STM32_M4_FW_ID supported */ ++ if (params[0].value.a != STM32_M4_FW_ID) { ++ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); ++ return TEE_ERROR_NOT_SUPPORTED; ++ } ++ ++ if (rproc_ta_state != REMOTEPROC_OFF) ++ return TEE_ERROR_BAD_STATE; ++ ++ /* Get the physical address in A7 mapping */ ++ res = da_to_pa(da, size, &pa); ++ if (res) ++ return res; ++ ++ /* Get the associated va */ ++ dst = (void *)core_mmu_get_va(pa, MEM_AREA_IO_SEC); ++ ++ /* Copy the segment to the remote processor memory*/ ++ memcpy(dst, src, size); ++ ++ /* Verify that loaded segment is valid */ ++ res = hash_sha256_check(hash, dst, size); ++ if (res) ++ memset(dst, 0, size); ++ ++ return res; ++} ++ ++static TEE_Result rproc_pta_set_memory(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT); ++ TEE_Result res = TEE_ERROR_GENERIC; ++ paddr_t pa = 0; ++ vaddr_t dst = 0; ++ paddr_t da = params[1].value.a; ++ size_t size = params[2].value.a; ++ char value = (char)params[3].value.a; ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ /* Only STM32_M4_FW_ID supported */ ++ if (params[0].value.a != STM32_M4_FW_ID) { ++ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); ++ return TEE_ERROR_NOT_SUPPORTED; ++ } ++ ++ if (rproc_ta_state != REMOTEPROC_OFF) ++ return TEE_ERROR_BAD_STATE; ++ ++ /* Get the physical address in CPU mapping */ ++ res = da_to_pa(da, size, &pa); ++ if (res) ++ return res; ++ ++ dst = core_mmu_get_va(pa, MEM_AREA_IO_SEC); ++ ++ memset((void *)dst, value, size); ++ ++ return TEE_SUCCESS; ++} ++ ++static TEE_Result rproc_pta_da_to_pa(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_OUTPUT); ++ TEE_Result res = TEE_ERROR_GENERIC; ++ paddr_t da = params[1].value.a; ++ size_t size = params[2].value.a; ++ paddr_t pa = 0; ++ ++ DMSG("Conversion for address %#"PRIxPA" size %zu", da, size); ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ /* Only STM32_M4_FW_ID supported */ ++ if (params[0].value.a != STM32_M4_FW_ID) { ++ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); ++ return TEE_ERROR_NOT_SUPPORTED; ++ } ++ ++ /* Target address is expected 32bit, ensure 32bit MSB are zero */ ++ if (params[1].value.b || params[2].value.b) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ res = da_to_pa(da, size, &pa); ++ if (res) ++ return res; ++ ++ reg_pair_from_64((uint64_t)pa, ¶ms[3].value.b, ¶ms[3].value.a); ++ ++ return TEE_SUCCESS; ++} ++ ++static void rproc_pta_mem_protect(bool secure_access) ++{ ++ unsigned int i = 0; ++ const struct rproc_ta_etzpc_rams *ram = NULL; ++ ++ /* ++ * MCU RAM banks access permissions for MCU memories depending on ++ * rproc_ta_mp1_m4_rams[]. ++ * If memory bank is declared as MCU isolated: ++ * if secure_access then set to secure world read/write permission ++ * else set to MCU isolated ++ * else apply memory permission as defined in rproc_ta_mp1_m4_rams[]. ++ */ ++ for (i = 0; i < ARRAY_SIZE(rproc_ta_mp1_m4_rams); i++) { ++ enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX; ++ ++ ram = &rproc_ta_mp1_m4_rams[i]; ++ attr = ram->attr; ++ ++ if (secure_access && attr == ETZPC_DECPROT_MCU_ISOLATION) ++ attr = ETZPC_DECPROT_S_RW; ++ ++ etzpc_configure_decprot(ram->etzpc_id, attr); ++ } ++} ++ ++static TEE_Result rproc_pta_start(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_NONE, ++ TEE_PARAM_TYPE_NONE, ++ TEE_PARAM_TYPE_NONE); ++ vaddr_t rcc_base = stm32_rcc_base(); ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ /* Only STM32_M4_FW_ID supported */ ++ if (params[0].value.a != STM32_M4_FW_ID) { ++ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); ++ return TEE_ERROR_NOT_SUPPORTED; ++ } ++ ++ if (rproc_ta_state != REMOTEPROC_OFF) ++ return TEE_ERROR_BAD_STATE; ++ ++ clk_enable(CK_MCU); ++ ++ /* Configure the Cortex-M4 RAMs as expected to run the firmware */ ++ rproc_pta_mem_protect(false); ++ ++ /* ++ * The firmware is started by deasserting the hold boot and ++ * asserting back to avoid auto restart on a crash. ++ * No need to release the MCU reset as it is automatically released by ++ * the hardware. ++ */ ++ io_setbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); ++ io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); ++ ++ rproc_ta_state = REMOTEPROC_ON; ++ ++ return TEE_SUCCESS; ++} ++ ++static TEE_Result rproc_pta_stop(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_NONE, ++ TEE_PARAM_TYPE_NONE, ++ TEE_PARAM_TYPE_NONE); ++ const struct rproc_ta_etzpc_rams *ram = NULL; ++ vaddr_t rcc_base = stm32_rcc_base(); ++ unsigned int i = 0; ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ /* Only STM32_M4_FW_ID supported */ ++ if (params[0].value.a != STM32_M4_FW_ID) { ++ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); ++ return TEE_ERROR_NOT_SUPPORTED; ++ } ++ ++ if (rproc_ta_state != REMOTEPROC_ON) ++ return TEE_ERROR_BAD_STATE; ++ ++ /* The firmware is stopped (reset with holdboot is active) */ ++ io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); ++ ++ stm32_reset_set(MCU_R); ++ ++ clk_disable(CK_MCU); ++ ++ /* ++ * Cortex-M4 memories are cleaned and access rights restored for the ++ * secure context. ++ */ ++ rproc_pta_mem_protect(true); ++ for (i = 0; i < ARRAY_SIZE(rproc_ta_mp1_m4_rams); i++) { ++ ram = &rproc_ta_mp1_m4_rams[i]; ++ if (ram->attr == ETZPC_DECPROT_MCU_ISOLATION) { ++ memset((void *)core_mmu_get_va(ram->pa, ++ MEM_AREA_IO_SEC), ++ 0, ram->size); ++ } ++ } ++ rproc_ta_state = REMOTEPROC_OFF; ++ ++ return TEE_SUCCESS; ++} ++ ++static TEE_Result rproc_pta_verify_rsa_signature(TEE_Param *hash, ++ TEE_Param *sig, uint32_t algo) ++{ ++ struct rsa_public_key key = { }; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ uint32_t e = TEE_U32_TO_BIG_ENDIAN(rproc_pub_key_exponent); ++ size_t hash_size = (size_t)hash->memref.size; ++ size_t sig_size = (size_t)sig->memref.size; ++ ++ res = crypto_acipher_alloc_rsa_public_key(&key, sig_size); ++ if (res) ++ return TEE_ERROR_SECURITY; ++ ++ res = crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key.e); ++ if (res) ++ goto out; ++ ++ res = crypto_bignum_bin2bn(rproc_pub_key_modulus, ++ rproc_pub_key_modulus_size, key.n); ++ if (res) ++ goto out; ++ ++ res = crypto_acipher_rsassa_verify(algo, &key, hash_size, ++ hash->memref.buffer, hash_size, ++ sig->memref.buffer, sig_size); ++ ++out: ++ crypto_acipher_free_rsa_public_key(&key); ++ ++ return res; ++} ++ ++static TEE_Result rproc_pta_verify_digest(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ struct rproc_pta_key_info *keyinfo = NULL; ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT); ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ /* Only STM32_M4_FW_ID supported */ ++ if (params[0].value.a != STM32_M4_FW_ID) { ++ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); ++ return TEE_ERROR_NOT_SUPPORTED; ++ } ++ ++ if (rproc_ta_state != REMOTEPROC_OFF) ++ return TEE_ERROR_BAD_STATE; ++ ++ keyinfo = params[1].memref.buffer; ++ ++ if (!keyinfo || ++ RPROC_PTA_GET_KEYINFO_SIZE(keyinfo) != params[1].memref.size) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ if (keyinfo->algo != TEE_ALG_RSASSA_PKCS1_V1_5_SHA256) ++ return TEE_ERROR_NOT_SUPPORTED; ++ ++ return rproc_pta_verify_rsa_signature(¶ms[2], ¶ms[3], ++ keyinfo->algo); ++} ++ ++static TEE_Result rproc_pta_invoke_command(void *pSessionContext __unused, ++ uint32_t cmd_id, ++ uint32_t param_types, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ switch (cmd_id) { ++ case PTA_REMOTEPROC_HW_CAPABILITIES: ++ return rproc_pta_capabilities(param_types, params); ++ case PTA_REMOTEPROC_LOAD_SEGMENT_SHA256: ++ return rproc_pta_load_segment(param_types, params); ++ case PTA_REMOTEPROC_SET_MEMORY: ++ return rproc_pta_set_memory(param_types, params); ++ case PTA_REMOTEPROC_FIRMWARE_START: ++ return rproc_pta_start(param_types, params); ++ case PTA_REMOTEPROC_FIRMWARE_STOP: ++ return rproc_pta_stop(param_types, params); ++ case PTA_REMOTEPROC_FIRMWARE_DA_TO_PA: ++ return rproc_pta_da_to_pa(param_types, params); ++ case PTA_REMOTEPROC_VERIFY_DIGEST: ++ return rproc_pta_verify_digest(param_types, params); ++ default: ++ break; ++ } ++ ++ return TEE_ERROR_NOT_IMPLEMENTED; ++} ++ ++/* ++ * Trusted Application entry points ++ */ ++static TEE_Result ++ rproc_pta_open_session(uint32_t param_types __unused, ++ TEE_Param params[TEE_NUM_PARAMS] __unused, ++ void **sess_ctx __unused) ++{ ++ struct tee_ta_session *s = tee_ta_get_calling_session(); ++ ++ /* Check that we're called from a user TA */ ++ if (!s) ++ return TEE_ERROR_ACCESS_DENIED; ++ ++ if (!is_user_ta_ctx(s->ctx)) ++ return TEE_ERROR_ACCESS_DENIED; ++ ++ return TEE_SUCCESS; ++} ++ ++static TEE_Result rproc_pta_init(void) ++{ ++ vaddr_t rcc_base = stm32_rcc_base(); ++ ++ /* Configure the Cortex-M4 rams access right for secure context only */ ++ rproc_pta_mem_protect(true); ++ ++ /* Initialise the context */ ++ rproc_ta_state = REMOTEPROC_OFF; ++ ++ /* Ensure that the MCU is HOLD */ ++ io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); ++ stm32_reset_set(MCU_R); ++ ++ return TEE_SUCCESS; ++} ++service_init_late(rproc_pta_init); ++ ++pseudo_ta_register(.uuid = PTA_REMOTEPROC_UUID, .name = PTA_NAME, ++ .flags = PTA_DEFAULT_FLAGS, ++ .invoke_command_entry_point = rproc_pta_invoke_command, ++ .open_session_entry_point = rproc_pta_open_session); diff --git a/core/arch/arm/plat-stm32mp1/reset.S b/core/arch/arm/plat-stm32mp1/reset.S -index 69ab151..6a8ac06 100644 +index 8a1ab6494..0a11d915a 100644 --- a/core/arch/arm/plat-stm32mp1/reset.S +++ b/core/arch/arm/plat-stm32mp1/reset.S @@ -3,7 +3,7 @@ @@ -13095,8 +12761,8 @@ index 69ab151..6a8ac06 100644 +#include #include #include - #include -@@ -23,8 +23,34 @@ UNWIND( .fnstart) + +@@ -21,7 +21,33 @@ FUNC plat_cpu_reset_early , : mov_imm r1, STM32MP1_NSACR_PRESERVE_MASK and r0, r0, r1 write_nsacr r0 @@ -13125,33 +12791,67 @@ index 69ab151..6a8ac06 100644 + write_scr r2 isb -- bx lr + msr cpsr, r1 + isb + -+ bx lr - UNWIND( .fnend) + bx lr END_FUNC plat_cpu_reset_early +diff --git a/core/arch/arm/plat-stm32mp1/rproc_pub_key.h b/core/arch/arm/plat-stm32mp1/rproc_pub_key.h +new file mode 100644 +index 000000000..9b1db4271 +--- /dev/null ++++ b/core/arch/arm/plat-stm32mp1/rproc_pub_key.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: BSD-2-Clause */ ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#ifndef RPROC_PUB_KEY_H ++#define RPROC_PUB_KEY_H ++ ++#include ++ ++extern const uint32_t rproc_pub_key_exponent; ++extern const uint8_t rproc_pub_key_modulus[]; ++extern const size_t rproc_pub_key_modulus_size; ++ ++#endif /*RPROC_PUB_KEY_H*/ ++ diff --git a/core/arch/arm/plat-stm32mp1/scmi_server.c b/core/arch/arm/plat-stm32mp1/scmi_server.c -index ddc19ca..5116b89 100644 +index dce8c169e..169e69ee7 100644 --- a/core/arch/arm/plat-stm32mp1/scmi_server.c +++ b/core/arch/arm/plat-stm32mp1/scmi_server.c -@@ -9,6 +9,7 @@ - #include +@@ -1,9 +1,10 @@ + // SPDX-License-Identifier: BSD-2-Clause + /* +- * Copyright (c) 2019, STMicroelectronics ++ * Copyright (c) 2019-2020, STMicroelectronics + */ + #include + #include ++#include + #include + #include + #include +@@ -13,6 +14,7 @@ + #include #include #include +#include #include #include #include -@@ -276,8 +277,21 @@ const char *plat_scmi_clock_get_name(unsigned int agent_id, +@@ -312,9 +314,22 @@ const char *plat_scmi_clock_get_name(unsigned int agent_id, return clock->name; } -int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, -- unsigned long *array, size_t *nb_elts) +- size_t start_index, unsigned long *array, +- size_t *nb_elts) +int32_t plat_scmi_clock_rates_array(unsigned int agent_id __unused, + unsigned int scmi_id __unused, ++ size_t start_index __unused, + unsigned long *array __unused, + size_t *nb_elts __unused) +{ @@ -13168,16 +12868,13 @@ index ddc19ca..5116b89 100644 { struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); -@@ -287,12 +301,48 @@ int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, +@@ -324,16 +339,48 @@ int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, if (!stm32mp_nsec_can_access_clock(clock->clock_id)) return SCMI_DENIED; -- if (!array) -- *nb_elts = 1; -- else if (*nb_elts == 1) -- *array = stm32_clock_get_rate(clock->clock_id); -- else -- return SCMI_GENERIC_ERROR; +- /* Exposed clocks are currently fixed rate clocks */ +- if (start_index) +- return SCMI_INVALID_PARAMETERS; + switch (scmi_id) { + case CK_SCMI0_MPU: + /* @@ -13189,12 +12886,18 @@ index ddc19ca..5116b89 100644 + array[2] = 1U; + break; + default: -+ array[0] = stm32_clock_get_rate(clock->clock_id); ++ array[0] = clk_get_rate(clock->clock_id); + array[1] = array[0]; + array[2] = 0U; + break; + } -+ + +- if (!array) +- *nb_elts = 1; +- else if (*nb_elts == 1) +- *array = stm32_clock_get_rate(clock->clock_id); +- else +- return SCMI_GENERIC_ERROR; + return SCMI_SUCCESS; +} + @@ -13216,14 +12919,39 @@ index ddc19ca..5116b89 100644 + return SCMI_INVALID_PARAMETERS; + break; + default: -+ if (rate != stm32_clock_get_rate(clock->clock_id)) ++ if (rate != clk_get_rate(clock->clock_id)) + return SCMI_INVALID_PARAMETERS; + break; + } return SCMI_SUCCESS; } -@@ -432,6 +482,19 @@ int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id, +@@ -346,7 +393,7 @@ unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, + if (!clock || !stm32mp_nsec_can_access_clock(clock->clock_id)) + return 0; + +- return stm32_clock_get_rate(clock->clock_id); ++ return clk_get_rate(clock->clock_id); + } + + int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id) +@@ -373,13 +420,13 @@ int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, + if (enable_not_disable) { + if (!clock->enabled) { + DMSG("SCMI clock %u enable", scmi_id); +- stm32_clock_enable(clock->clock_id); ++ clk_enable(clock->clock_id); + clock->enabled = true; + } + } else { + if (clock->enabled) { + DMSG("SCMI clock %u disable", scmi_id); +- stm32_clock_disable(clock->clock_id); ++ clk_disable(clock->clock_id); + clock->enabled = false; + } + } +@@ -483,6 +530,19 @@ int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id, return SCMI_SUCCESS; } @@ -13241,9 +12969,9 @@ index ddc19ca..5116b89 100644 +DECLARE_KEEP_PAGER(stm32_scmi_pm); + /* - * Initialize platform SCMI resources + * Platform SCMI voltage domains */ -@@ -440,6 +503,8 @@ static TEE_Result stm32mp1_init_scmi_server(void) +@@ -810,6 +870,8 @@ static TEE_Result stm32mp1_init_scmi_server(void) size_t i = 0; size_t j = 0; @@ -13252,11 +12980,183 @@ index ddc19ca..5116b89 100644 for (i = 0; i < ARRAY_SIZE(scmi_channel); i++) { struct scmi_msg_channel *chan = &scmi_channel[i]; +@@ -834,7 +896,7 @@ static TEE_Result stm32mp1_init_scmi_server(void) + /* Sync SCMI clocks with their targeted initial state */ + if (clk->enabled && + stm32mp_nsec_can_access_clock(clk->clock_id)) +- stm32_clock_enable(clk->clock_id); ++ clk_enable(clk->clock_id); + } + + for (j = 0; j < res->rd_count; j++) { diff --git a/core/arch/arm/plat-stm32mp1/shared_resources.c b/core/arch/arm/plat-stm32mp1/shared_resources.c -index e321ec8..08aa9a3 100644 +index 3d1609353..7ad3d7b9c 100644 --- a/core/arch/arm/plat-stm32mp1/shared_resources.c +++ b/core/arch/arm/plat-stm32mp1/shared_resources.c -@@ -650,27 +650,36 @@ static void check_rcc_secure_configuration(void) +@@ -1,14 +1,14 @@ + // SPDX-License-Identifier: BSD-3-Clause + /* +- * Copyright (c) 2017-2019, STMicroelectronics ++ * Copyright (c) 2017-2020, STMicroelectronics + */ + + #include + #include +-#include + #include + #include + #include ++#include + #include + #include + #include +@@ -147,6 +147,9 @@ static const char __maybe_unused *shres2str_id_tbl[STM32MP1_SHRES_COUNT] = { + + static __maybe_unused const char *shres2str_id(enum stm32mp_shres id) + { ++ if (id >= ARRAY_SIZE(shres2str_id_tbl)) ++ panic("Invalid shared resource ID"); ++ + return shres2str_id_tbl[id]; + } + +@@ -407,6 +410,91 @@ void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin) + } + } + ++#ifdef CFG_STM32_ETZPC ++struct shres2decprot { ++ enum stm32mp_shres shres_id; ++ unsigned int decprot_id; ++}; ++ ++#define SHRES2DECPROT(shres, decprot) { \ ++ .shres_id = shres, \ ++ .decprot_id = decprot, \ ++ } ++ ++static const struct shres2decprot shres2decprot_tbl[] = { ++ SHRES2DECPROT(STM32MP1_SHRES_IWDG1, STM32MP1_ETZPC_IWDG1_ID), ++ SHRES2DECPROT(STM32MP1_SHRES_USART1, STM32MP1_ETZPC_USART1_ID), ++ SHRES2DECPROT(STM32MP1_SHRES_SPI6, STM32MP1_ETZPC_SPI6_ID), ++ SHRES2DECPROT(STM32MP1_SHRES_I2C4, STM32MP1_ETZPC_I2C4_ID), ++ SHRES2DECPROT(STM32MP1_SHRES_RNG1, STM32MP1_ETZPC_RNG1_ID), ++ SHRES2DECPROT(STM32MP1_SHRES_HASH1, STM32MP1_ETZPC_HASH1_ID), ++ SHRES2DECPROT(STM32MP1_SHRES_CRYP1, STM32MP1_ETZPC_CRYP1_ID), ++ SHRES2DECPROT(STM32MP1_SHRES_I2C6, STM32MP1_ETZPC_I2C6_ID), ++}; ++ ++static enum stm32mp_shres decprot2shres(unsigned int decprot_id) ++{ ++ size_t i = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(shres2decprot_tbl); i++) ++ if (shres2decprot_tbl[i].decprot_id == decprot_id) ++ return shres2decprot_tbl[i].shres_id; ++ ++ DMSG("No shared resource for DECPROT ID %u", decprot_id); ++ return STM32MP1_SHRES_COUNT; ++} ++ ++void stm32mp_register_etzpc_decprot(unsigned int id, ++ enum etzpc_decprot_attributes attr) ++{ ++ enum shres_state state = SHRES_SECURE; ++ bool write_secure = false; ++ unsigned int id_shres = STM32MP1_SHRES_COUNT; ++ ++ switch (attr) { ++ case ETZPC_DECPROT_S_RW: ++ state = SHRES_SECURE; ++ break; ++ case ETZPC_DECPROT_NS_R_S_W: ++ case ETZPC_DECPROT_MCU_ISOLATION: ++ case ETZPC_DECPROT_NS_RW: ++ state = SHRES_NON_SECURE; ++ break; ++ default: ++ panic(); ++ } ++ ++ write_secure = attr == ETZPC_DECPROT_NS_R_S_W || ++ attr == ETZPC_DECPROT_S_RW; ++ ++ switch (id) { ++ case STM32MP1_ETZPC_STGENC_ID: ++ case STM32MP1_ETZPC_BKPSRAM_ID: ++ if (state != SHRES_SECURE) ++ panic("ETZPC: STGEN & BKSRAM should be secure"); ++ break; ++ case STM32MP1_ETZPC_DDRCTRL_ID: ++ case STM32MP1_ETZPC_DDRPHYC_ID: ++ /* We assume these must always be write-only to secure world */ ++ if (!write_secure) ++ panic("ETZPC: DDRCTRL & DDRPHY should be write secure"); ++ break; ++ default: ++ id_shres = decprot2shres(id); ++ if (id_shres >= STM32MP1_SHRES_COUNT) { ++ if (write_secure) { ++ DMSG("ETZPC: cannot secure DECPROT %s", ++ shres2str_id(id_shres)); ++ panic(); ++ } ++ } else { ++ register_periph(id_shres, state); ++ } ++ break; ++ } ++} ++#endif /*CFG_STM32_ETZPC*/ ++ + static void lock_registering(void) + { + registering_locked = true; +@@ -614,13 +702,39 @@ static void config_lock_decprot(uint32_t decprot_id, + etzpc_lock_decprot(decprot_id); + } + ++static bool decprot_is_write_secure(uint32_t decprot_id) ++{ ++ enum etzpc_decprot_attributes attr = etzpc_get_decprot(decprot_id); ++ ++ return attr == ETZPC_DECPROT_S_RW || ++ attr == ETZPC_DECPROT_NS_R_S_W; ++} ++ ++static bool decprot_is_secure(uint32_t decprot_id) ++{ ++ enum etzpc_decprot_attributes attr = etzpc_get_decprot(decprot_id); ++ ++ return attr == ETZPC_DECPROT_S_RW; ++} ++ + static void set_etzpc_secure_configuration(void) + { + /* Some peripherals shall be secure */ +- config_lock_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW); +- config_lock_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW); +- config_lock_decprot(STM32MP1_ETZPC_DDRCTRL_ID, ETZPC_DECPROT_S_RW); +- config_lock_decprot(STM32MP1_ETZPC_DDRPHYC_ID, ETZPC_DECPROT_S_RW); ++ if (!decprot_is_secure(STM32MP1_ETZPC_STGENC_ID)) ++ config_lock_decprot(STM32MP1_ETZPC_STGENC_ID, ++ ETZPC_DECPROT_S_RW); ++ ++ if (!decprot_is_secure(STM32MP1_ETZPC_BKPSRAM_ID)) ++ config_lock_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ++ ETZPC_DECPROT_S_RW); ++ ++ if (!decprot_is_write_secure(STM32MP1_ETZPC_DDRCTRL_ID)) ++ config_lock_decprot(STM32MP1_ETZPC_DDRCTRL_ID, ++ ETZPC_DECPROT_NS_R_S_W); ++ ++ if (!decprot_is_write_secure(STM32MP1_ETZPC_DDRPHYC_ID)) ++ config_lock_decprot(STM32MP1_ETZPC_DDRPHYC_ID, ++ ETZPC_DECPROT_NS_R_S_W); + + /* Configure ETZPC with peripheral registering */ + config_lock_decprot(STM32MP1_ETZPC_IWDG1_ID, +@@ -651,27 +765,35 @@ static void check_rcc_secure_configuration(void) { bool secure = stm32_rcc_is_secure(); bool mckprot = stm32_rcc_is_mckprot(); @@ -13299,15 +13199,22 @@ index e321ec8..08aa9a3 100644 + if (need_secure && !secure) panic(); + -+ if (need_mckprot) -+ io_setbits32(stm32_rcc_base() + RCC_TZCR, RCC_TZCR_MCKPROT); ++ stm32mp1_clk_mcuss_protect(need_mckprot); } static void set_gpio_secure_configuration(void) diff --git a/core/arch/arm/plat-stm32mp1/stm32_util.h b/core/arch/arm/plat-stm32mp1/stm32_util.h -index 5572dae..9c86cd2 100644 +index 6e4ac7499..efb364998 100644 --- a/core/arch/arm/plat-stm32mp1/stm32_util.h +++ b/core/arch/arm/plat-stm32mp1/stm32_util.h +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: BSD-3-Clause */ + /* +- * Copyright (c) 2018-2019, STMicroelectronics ++ * Copyright (c) 2018-2020, STMicroelectronics + */ + + #ifndef __STM32_UTIL_H__ @@ -9,11 +9,23 @@ #include #include @@ -13359,14 +13266,33 @@ index 5572dae..9c86cd2 100644 /* Platform util for PMIC support */ bool stm32mp_with_pmic(void); -@@ -74,6 +99,19 @@ bool stm32_clock_is_enabled(unsigned long id); +@@ -62,15 +87,6 @@ static inline void stm32mp_register_online_cpu(void) + uint32_t may_spin_lock(unsigned int *lock); + void may_spin_unlock(unsigned int *lock, uint32_t exceptions); + +-/* +- * Util for clock gating and to get clock rate for stm32 and platform drivers +- * @id: Target clock ID, ID used in clock DT bindings +- */ +-void stm32_clock_enable(unsigned long id); +-void stm32_clock_disable(unsigned long id); +-unsigned long stm32_clock_get_rate(unsigned long id); +-bool stm32_clock_is_enabled(unsigned long id); +- /* Return true if @clock_id is shared by secure and non-secure worlds */ bool stm32mp_nsec_can_access_clock(unsigned long clock_id); +@@ -84,6 +100,22 @@ static inline bool stm32mp_nsec_can_access_pmic_regu(const char *name __unused) + } + #endif + +/* PM sequences specific to SoC STOP mode support */ +void stm32mp1_clk_save_context_for_stop(void); +void stm32mp1_clk_restore_context_for_stop(void); + ++/* Protect the MCU clock subsytem */ ++void stm32mp1_clk_mcuss_protect(bool enable); ++ +/* + * Util for PLL1 settings management based on DT OPP table content. + */ @@ -13379,7 +13305,7 @@ index 5572dae..9c86cd2 100644 /* * Util for reset signal assertion/desassertion for stm32 and platform drivers * @id: Target peripheral ID, ID used in reset DT bindings -@@ -110,6 +148,22 @@ struct stm32_bsec_static_cfg { +@@ -123,6 +155,27 @@ struct stm32_bsec_static_cfg { void stm32mp_get_bsec_static_cfg(struct stm32_bsec_static_cfg *cfg); @@ -13398,13 +13324,27 @@ index 5572dae..9c86cd2 100644 + +/* Platform util for the RTC driver */ +bool stm32_rtc_get_read_twice(void); ++ ++/* Platform util for the ETZPC driver */ ++ ++/* Convert a ETZPC mode from DT binding to ETZPC DECPROT configuration */ ++enum etzpc_decprot_attributes stm32mp_etzpc_binding2decprot(uint32_t mode); + /* * Return true if platform is in closed_device mode */ +@@ -294,4 +347,8 @@ bool stm32mp_gpio_bank_is_non_secure(unsigned int bank); + /* Register parent clocks of @clock (ID used in clock DT bindings) as secure */ + void stm32mp_register_clock_parents_secure(unsigned long clock_id); + ++/* Register a resource identified by a ETZPC DECPROT identifier */ ++void stm32mp_register_etzpc_decprot(unsigned int id, ++ enum etzpc_decprot_attributes attr); ++ + #endif /*__STM32_UTIL_H__*/ diff --git a/core/arch/arm/plat-stm32mp1/stm32mp_pm.h b/core/arch/arm/plat-stm32mp1/stm32mp_pm.h new file mode 100644 -index 0000000..4265db9 +index 000000000..4265db9dd --- /dev/null +++ b/core/arch/arm/plat-stm32mp1/stm32mp_pm.h @@ -0,0 +1,21 @@ @@ -13429,11 +13369,31 @@ index 0000000..4265db9 + +#endif /*__STM32MP_PM_H__*/ + +diff --git a/core/arch/arm/plat-stm32mp1/sub.mk b/core/arch/arm/plat-stm32mp1/sub.mk +index 69df1ced5..ae2041741 100644 +--- a/core/arch/arm/plat-stm32mp1/sub.mk ++++ b/core/arch/arm/plat-stm32mp1/sub.mk +@@ -6,6 +6,15 @@ srcs-$(CFG_STM32_RNG) += rng_seed.c + srcs-y += scmi_server.c + srcs-y += shared_resources.c + srcs-$(CFG_TZC400) += plat_tzc400.c ++srcs-$(CFG_RPROC_PTA) += remoteproc_pta.c ++ ++ifeq ($(CFG_RPROC_PTA),y) ++gensrcs-y += rproc_pub_key ++produce-rproc_pub_key = rproc_pub_key.c ++depends-rproc_pub_key = $(CFG_RPROC_SIGN_KEY) scripts/pem_to_pub_c.py ++recipe-rproc_pub_key = $(PYTHON3) scripts/pem_to_pub_c.py --prefix rproc_pub_key \ ++ --key $(CFG_RPROC_SIGN_KEY) --out $(sub-dir-out)/rproc_pub_key.c ++endif + + subdirs-y += drivers + subdirs-y += nsec-service diff --git a/core/arch/arm/sm/pm_a32.S b/core/arch/arm/sm/pm_a32.S -index 9421b2d..8a59cd2 100644 +index a927b1e77..3e0080af4 100644 --- a/core/arch/arm/sm/pm_a32.S +++ b/core/arch/arm/sm/pm_a32.S -@@ -69,25 +69,30 @@ a9_suspend: +@@ -65,25 +65,30 @@ a9_suspend: a7_suspend: read_fcseidr r4 read_tpidruro r5 @@ -13479,8 +13439,8 @@ index 9421b2d..8a59cd2 100644 + pop {r4 - r11} bx lr - UNWIND( .fnend) -@@ -154,50 +159,50 @@ UNWIND( .cantunwind) + END_FUNC sm_pm_cpu_do_suspend +@@ -146,50 +151,50 @@ UNWIND( .cantunwind) cmp r5, r4 beq a7_resume @@ -13553,19 +13513,1642 @@ index 9421b2d..8a59cd2 100644 + mov r0, #0 b suspend_return - UNWIND( .fnend) + END_FUNC sm_pm_cpu_do_resume diff --git a/core/arch/arm/tee/entry_std.c b/core/arch/arm/tee/entry_std.c -index 5c1e8c2..60aed6c 100644 +index 424c4c677..92db391d4 100644 --- a/core/arch/arm/tee/entry_std.c +++ b/core/arch/arm/tee/entry_std.c -@@ -535,4 +535,4 @@ static TEE_Result default_mobj_init(void) +@@ -588,4 +588,4 @@ static TEE_Result default_mobj_init(void) return TEE_SUCCESS; } -driver_init_late(default_mobj_init); +service_init(default_mobj_init); +diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c b/core/drivers/clk/clk-stm32mp15.c +similarity index 50% +rename from core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c +rename to core/drivers/clk/clk-stm32mp15.c +index c8dbbb7ae..794fd5e75 100644 +--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_clk.c ++++ b/core/drivers/clk/clk-stm32mp15.c +@@ -1,25 +1,47 @@ + // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0+) + /* +- * Copyright (C) 2018-2019, STMicroelectronics ++ * Copyright (C) 2018-2020, STMicroelectronics + */ + + #include ++#include + #include + #include ++#include + #include + #include + #include ++#include + #include + #include + #include ++#include + #include + #include + #include + #include + #include ++#include + #include + #include + ++#define DT_OPP_COMPAT "operating-points-v2" ++ ++/* PLL settings computation related definitions */ ++#define POST_DIVM_MIN 8000000 ++#define POST_DIVM_MAX 16000000 ++#define DIVM_MIN 0 ++#define DIVM_MAX 63 ++#define DIVN_MIN 24 ++#define DIVN_MAX 99 ++#define DIVP_MIN 0 ++#define DIVP_MAX 127 ++#define FRAC_MAX 8192 ++#define VCO_MIN 800000000 ++#define VCO_MAX 1600000000 ++ ++#define PLL1_SETTINGS_VALID_ID 0x504C4C31 /* "PLL1" */ ++ + /* Identifiers for root oscillators */ + enum stm32mp_osc_id { + _HSI = 0, +@@ -85,11 +107,14 @@ enum stm32mp1_parent_sel { + _UART24_SEL, + _UART35_SEL, + _UART78_SEL, ++ _SDMMC12_SEL, ++ _SDMMC3_SEL, + _AXISS_SEL, + _MCUSS_SEL, + _USBPHY_SEL, + _USBO_SEL, + _RTC_SEL, ++ _MPU_SEL, + _PARENT_SEL_NB, + _UNKNOWN_SEL = 0xff, + }; +@@ -160,6 +185,16 @@ enum stm32mp1_div_id { + _DIV_NB, + }; + ++enum stm32mp1_pllcfg { ++ PLLCFG_M, ++ PLLCFG_N, ++ PLLCFG_P, ++ PLLCFG_Q, ++ PLLCFG_R, ++ PLLCFG_O, ++ PLLCFG_NB ++}; ++ + enum stm32mp1_plltype { + PLL_800, + PLL_1600, +@@ -212,6 +247,21 @@ struct stm32mp1_clk_pll { + enum stm32mp_osc_id refclk[REFCLK_SIZE]; + }; + ++struct stm32mp1_pll { ++ uint8_t refclk_min; ++ uint8_t refclk_max; ++ uint8_t divn_max; ++}; ++ ++/* Compact structure of 32bit cells, copied raw when suspending */ ++struct stm32mp1_pll_settings { ++ uint32_t valid_id; ++ uint32_t freq[PLAT_MAX_OPP_NB]; ++ uint32_t volt[PLAT_MAX_OPP_NB]; ++ uint32_t cfg[PLAT_MAX_OPP_NB][PLAT_MAX_PLLCFG_NB]; ++ uint32_t frac[PLAT_MAX_OPP_NB]; ++}; ++ + #define N_S 0 /* Non-secure can access RCC interface */ + #define SEC 1 /* RCC[TZEN] protects RCC interface */ + +@@ -380,6 +430,18 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { + _CLK_SC_FIXED(N_S, RCC_MP_APB3ENSETR, 11, SYSCFG, _UNKNOWN_ID), + _CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 8, DDRPERFM, _UNKNOWN_SEL), + _CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL), ++#ifdef STM32MP1_USE_MPU0_RESET ++ _CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 0, LTDC_PX, _UNKNOWN_SEL), ++ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 0, DMA1, _UNKNOWN_SEL), ++ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 1, DMA2, _UNKNOWN_SEL), ++ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 8, USBO_K, _USBO_SEL), ++ _CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL), ++ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 5, GPU, _UNKNOWN_SEL), ++ _CLK_SC_FIXED(N_S, RCC_MP_AHB6ENSETR, 10, ETHMAC, _ACLK), ++ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 16, SDMMC1_K, _SDMMC12_SEL), ++ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL), ++ _CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL), ++#endif + + _CLK_SELEC(N_S, RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL), + }; +@@ -406,6 +468,10 @@ static const uint8_t rng1_parents[] = { + _CSI, _PLL4_R, _LSE, _LSI + }; + ++static const uint8_t mpu_parents[] = { ++ _HSI, _HSE, _PLL1_P, _PLL1_P /* specific div */ ++}; ++ + /* Parents for (some) non-secure clocks */ + #ifdef CFG_WITH_NSEC_UARTS + static const uint8_t uart6_parents[] = { +@@ -429,6 +495,24 @@ static const uint8_t rtc_parents[] = { + _UNKNOWN_ID, _LSE, _LSI, _HSE + }; + ++#ifdef STM32MP1_USE_MPU0_RESET ++static const uint8_t usbphy_parents[] = { ++ _HSE_KER, _PLL4_R, _HSE_KER_DIV2 ++}; ++ ++static const uint8_t usbo_parents[] = { ++ _PLL4_R, _USB_PHY_48 ++}; ++ ++static const uint8_t sdmmc12_parents[] = { ++ _HCLK6, _PLL3_R, _PLL4_P, _HSI_KER ++}; ++ ++static const uint8_t sdmmc3_parents[] = { ++ _HCLK2, _PLL3_R, _PLL4_P, _HSI_KER ++}; ++#endif ++ + static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { + /* Secure aware clocks */ + _CLK_PARENT(_STGEN_SEL, RCC_STGENCKSELR, 0, 0x3, stgen_parents), +@@ -437,6 +521,9 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { + _CLK_PARENT(_USART1_SEL, RCC_UART1CKSELR, 0, 0x7, usart1_parents), + _CLK_PARENT(_RNG1_SEL, RCC_RNG1CKSELR, 0, 0x3, rng1_parents), + _CLK_PARENT(_RTC_SEL, RCC_BDCR, 0, 0x3, rtc_parents), ++ _CLK_PARENT(_MPU_SEL, RCC_MPCKSELR, 0, 0x3, mpu_parents), ++ _CLK_PARENT(_AXISS_SEL, RCC_ASSCKSELR, 0, 0x3, axiss_parents), ++ _CLK_PARENT(_MCUSS_SEL, RCC_MSSCKSELR, 0, 0x3, mcuss_parents), + /* Always non-secure clocks (maybe used in some way in secure world) */ + #ifdef CFG_WITH_NSEC_UARTS + _CLK_PARENT(_UART6_SEL, RCC_UART6CKSELR, 0, 0x7, uart6_parents), +@@ -444,8 +531,26 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { + _CLK_PARENT(_UART35_SEL, RCC_UART35CKSELR, 0, 0x7, uart234578_parents), + _CLK_PARENT(_UART78_SEL, RCC_UART78CKSELR, 0, 0x7, uart234578_parents), + #endif +- _CLK_PARENT(_AXISS_SEL, RCC_ASSCKSELR, 0, 0x3, axiss_parents), +- _CLK_PARENT(_MCUSS_SEL, RCC_MSSCKSELR, 0, 0x3, mcuss_parents), ++#ifdef STM32MP1_USE_MPU0_RESET ++ _CLK_PARENT(_SDMMC12_SEL, RCC_SDMMC12CKSELR, 0, 0x7, sdmmc12_parents), ++ _CLK_PARENT(_SDMMC3_SEL, RCC_SDMMC3CKSELR, 0, 0x7, sdmmc3_parents), ++ _CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents), ++ _CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents), ++#endif ++}; ++ ++/* Define characteristics of PLL according type */ ++static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = { ++ [PLL_800] = { ++ .refclk_min = 4, ++ .refclk_max = 16, ++ .divn_max = 99, ++ }, ++ [PLL_1600] = { ++ .refclk_min = 8, ++ .refclk_max = 16, ++ .divn_max = 199, ++ }, + }; + + /* PLLNCFGR2 register divider by output */ +@@ -549,6 +654,10 @@ static unsigned long osc_frequency(enum stm32mp_osc_id idx) + static unsigned int gate_refcounts[NB_GATES]; + static unsigned int refcount_lock; + ++/* Storage of the precomputed SoC settings for PLL1 various OPPs */ ++static struct stm32mp1_pll_settings pll1_settings; ++static uint32_t current_opp_khz; ++ + static const struct stm32mp1_clk_gate *gate_ref(unsigned int idx) + { + return &stm32mp1_clk_gate[idx]; +@@ -591,7 +700,7 @@ static enum stm32mp1_parent_id stm32mp1_clk_get_fixed_parent(int i) + return (enum stm32mp1_parent_id)gate_ref(i)->fixed; + } + +-static int stm32mp1_clk_get_parent(unsigned long id) ++static int __clk_get_parent(unsigned long id) + { + const struct stm32mp1_clk_sel *sel = NULL; + enum stm32mp1_parent_id parent_id = 0; +@@ -701,7 +810,153 @@ static unsigned long stm32mp1_read_pll_freq(enum stm32mp1_pll_id pll_id, + return dfout; + } + +-static unsigned long get_clock_rate(int p) ++static void pll_start(enum stm32mp1_pll_id pll_id) ++{ ++ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); ++ uint32_t pllxcr = stm32_rcc_base() + pll->pllxcr; ++ ++ if (io_read32(pllxcr) & RCC_PLLNCR_PLLON) ++ return; ++ ++ io_clrsetbits32(pllxcr, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | ++ RCC_PLLNCR_DIVREN, RCC_PLLNCR_PLLON); ++} ++ ++#define PLLRDY_TIMEOUT_US (200 * 1000) ++ ++static int pll_output(enum stm32mp1_pll_id pll_id, uint32_t output) ++{ ++ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); ++ uint32_t pllxcr = stm32_rcc_base() + pll->pllxcr; ++ uint64_t start = 0; ++ ++ start = timeout_init_us(PLLRDY_TIMEOUT_US); ++ /* Wait PLL lock */ ++ while (!(io_read32(pllxcr) & RCC_PLLNCR_PLLRDY)) ++ if (timeout_elapsed(start)) { ++ EMSG("PLL%d start failed @ 0x%"PRIx32": 0x%"PRIx32, ++ pll_id, pllxcr, io_read32(pllxcr)); ++ return -1; ++ } ++ ++ /* Start the requested output */ ++ io_setbits32(pllxcr, output << RCC_PLLNCR_DIVEN_SHIFT); ++ ++ return 0; ++} ++ ++static int pll_stop(enum stm32mp1_pll_id pll_id) ++{ ++ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); ++ uint32_t pllxcr = stm32_rcc_base() + pll->pllxcr; ++ uint64_t start = 0; ++ ++ /* Stop all output */ ++ io_clrbits32(pllxcr, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | ++ RCC_PLLNCR_DIVREN); ++ ++ /* Stop PLL */ ++ io_clrbits32(pllxcr, RCC_PLLNCR_PLLON); ++ ++ start = timeout_init_us(PLLRDY_TIMEOUT_US); ++ /* Wait PLL stopped */ ++ while (!(io_read32(pllxcr) & RCC_PLLNCR_PLLRDY)) ++ if (timeout_elapsed(start)) { ++ EMSG("PLL%d stop failed @ 0x%"PRIx32": 0x%"PRIx32, ++ pll_id, pllxcr, io_read32(pllxcr)); ++ ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static uint32_t pll_compute_pllxcfgr2(uint32_t *pllcfg) ++{ ++ uint32_t value = 0; ++ ++ value = (pllcfg[PLLCFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) & ++ RCC_PLLNCFGR2_DIVP_MASK; ++ value |= (pllcfg[PLLCFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) & ++ RCC_PLLNCFGR2_DIVQ_MASK; ++ value |= (pllcfg[PLLCFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) & ++ RCC_PLLNCFGR2_DIVR_MASK; ++ ++ return value; ++} ++ ++static void pll_config_output(enum stm32mp1_pll_id pll_id, uint32_t *pllcfg) ++{ ++ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); ++ uintptr_t rcc_base = stm32_rcc_base(); ++ uint32_t value = 0; ++ ++ value = pll_compute_pllxcfgr2(pllcfg); ++ ++ io_write32(rcc_base + pll->pllxcfgr2, value); ++} ++ ++static int pll_compute_pllxcfgr1(const struct stm32mp1_clk_pll *pll, ++ uint32_t *pllcfg, uint32_t *cfgr1) ++{ ++ uint32_t rcc_base = stm32_rcc_base(); ++ enum stm32mp1_plltype type = pll->plltype; ++ unsigned long refclk = 0; ++ uint32_t ifrge = 0; ++ uint32_t src = 0; ++ ++ src = io_read32(rcc_base + pll->rckxselr) & ++ RCC_SELR_REFCLK_SRC_MASK; ++ ++ refclk = osc_frequency(pll->refclk[src]) / ++ (pllcfg[PLLCFG_M] + 1U); ++ ++ if ((refclk < (stm32mp1_pll[type].refclk_min * 1000000U)) || ++ (refclk > (stm32mp1_pll[type].refclk_max * 1000000U))) ++ return -1; ++ ++ if ((type == PLL_800) && (refclk >= 8000000U)) ++ ifrge = 1U; ++ ++ *cfgr1 = (pllcfg[PLLCFG_N] << RCC_PLLNCFGR1_DIVN_SHIFT) & ++ RCC_PLLNCFGR1_DIVN_MASK; ++ *cfgr1 |= (pllcfg[PLLCFG_M] << RCC_PLLNCFGR1_DIVM_SHIFT) & ++ RCC_PLLNCFGR1_DIVM_MASK; ++ *cfgr1 |= (ifrge << RCC_PLLNCFGR1_IFRGE_SHIFT) & ++ RCC_PLLNCFGR1_IFRGE_MASK; ++ ++ return 0; ++} ++ ++static int pll_config(enum stm32mp1_pll_id pll_id, uint32_t *pllcfg, ++ uint32_t fracv) ++{ ++ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); ++ uint32_t rcc_base = stm32_rcc_base(); ++ uint32_t value = 0; ++ int ret = 0; ++ ++ ret = pll_compute_pllxcfgr1(pll, pllcfg, &value); ++ if (ret) ++ return ret; ++ ++ io_write32(rcc_base + pll->pllxcfgr1, value); ++ ++ /* Fractional configuration */ ++ io_write32(rcc_base + pll->pllxfracr, value); ++ ++ /* Frac must be enabled only once its configuration is loaded */ ++ value = fracv << RCC_PLLNFRACR_FRACV_SHIFT; ++ io_write32(rcc_base + pll->pllxfracr, value); ++ value = io_read32(rcc_base + pll->pllxfracr); ++ io_write32(rcc_base + pll->pllxfracr, value | RCC_PLLNFRACR_FRACLE); ++ ++ pll_config_output(pll_id, pllcfg); ++ ++ return 0; ++} ++ ++static unsigned long __clk_get_parent_rate(enum stm32mp1_parent_id p) + { + uint32_t reg = 0; + unsigned long clock = 0; +@@ -964,7 +1219,7 @@ static bool clock_is_always_on(unsigned long id) + } + } + +-bool stm32_clock_is_enabled(unsigned long id) ++static bool clk_stm32_is_enabled(unsigned long id) + { + int i = 0; + +@@ -978,13 +1233,13 @@ bool stm32_clock_is_enabled(unsigned long id) + return __clk_is_enabled(gate_ref(i)); + } + +-void stm32_clock_enable(unsigned long id) ++static TEE_Result clk_stm32_enable(unsigned long id) + { + int i = 0; + uint32_t exceptions = 0; + + if (clock_is_always_on(id)) +- return; ++ return TEE_SUCCESS; + + i = stm32mp1_clk_get_gated_id(id); + if (i < 0) { +@@ -995,7 +1250,7 @@ void stm32_clock_enable(unsigned long id) + if (gate_is_non_secure(gate_ref(i))) { + /* Enable non-secure clock w/o any refcounting */ + __clk_enable(gate_ref(i)); +- return; ++ return TEE_SUCCESS; + } + + exceptions = may_spin_lock(&refcount_lock); +@@ -1006,9 +1261,11 @@ void stm32_clock_enable(unsigned long id) + gate_refcounts[i]++; + + may_spin_unlock(&refcount_lock, exceptions); ++ ++ return TEE_SUCCESS; + } + +-void stm32_clock_disable(unsigned long id) ++static void clk_stm32_disable(unsigned long id) + { + int i = 0; + uint32_t exceptions = 0; +@@ -1067,16 +1324,16 @@ static long get_timer_rate(long parent_rate, unsigned int apb_bus) + return parent_rate * (timgxpre + 1) * 2; + } + +-unsigned long stm32_clock_get_rate(unsigned long id) ++static unsigned long clk_stm32_get_rate(unsigned long id) + { +- int p = 0; ++ enum stm32mp1_parent_id p = _UNKNOWN_ID; + unsigned long rate = 0; + +- p = stm32mp1_clk_get_parent(id); ++ p = __clk_get_parent(id); + if (p < 0) + return 0; + +- rate = get_clock_rate(p); ++ rate = __clk_get_parent_rate(p); + + if ((id >= TIM2_K) && (id <= TIM14_K)) + rate = get_timer_rate(rate, 1); +@@ -1210,7 +1467,7 @@ static void secure_parent_clocks(unsigned long parent_id) + + void stm32mp_register_clock_parents_secure(unsigned long clock_id) + { +- int parent_id = stm32mp1_clk_get_parent(clock_id); ++ enum stm32mp1_parent_id parent_id = __clk_get_parent(clock_id); + + if (parent_id < 0) { + DMSG("No parent for clock %lu", clock_id); +@@ -1220,6 +1477,14 @@ void stm32mp_register_clock_parents_secure(unsigned long clock_id) + secure_parent_clocks(parent_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, ++}; ++DECLARE_KEEP_PAGER(stm32mp_clk_ops); ++ + #ifdef CFG_EMBED_DTB + static const char *stm32mp_osc_node_label[NB_OSC] = { + [_LSI] = "clk-lsi", +@@ -1291,15 +1556,15 @@ static void enable_static_secure_clocks(void) + }; + + for (idx = 0; idx < ARRAY_SIZE(secure_enable); idx++) { +- stm32_clock_enable(secure_enable[idx]); ++ clk_stm32_enable(secure_enable[idx]); + stm32mp_register_clock_parents_secure(secure_enable[idx]); + } + + if (CFG_TEE_CORE_NB_CORE > 1) +- stm32_clock_enable(RTCAPB); ++ clk_stm32_enable(RTCAPB); + } + +-static TEE_Result stm32mp1_clk_early_init(void) ++static void stm32mp1_clk_early_init(void) + { + void *fdt = NULL; + int node = 0; +@@ -1308,18 +1573,21 @@ static TEE_Result stm32mp1_clk_early_init(void) + int ignored = 0; + + fdt = get_embedded_dt(); +- node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); +- +- if (node < 0 || _fdt_reg_base_address(fdt, node) != RCC_BASE) +- panic(); +- +- if (_fdt_get_status(fdt, node) & DT_STATUS_OK_SEC) { +- io_setbits32(stm32_rcc_base() + RCC_TZCR, RCC_TZCR_TZEN); ++ node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_SEC_CLK_COMPAT); ++ ++ if (node < 0 || _fdt_reg_base_address(fdt, node) != RCC_BASE) { ++ /* Check non secure compatible */ ++ node = fdt_node_offset_by_compatible(fdt, -1, ++ DT_RCC_CLK_COMPAT); ++ if (node < 0 || _fdt_reg_base_address(fdt, node) != RCC_BASE) { ++ panic(); ++ } else { ++ io_clrbits32(stm32_rcc_base() + RCC_TZCR, ++ RCC_TZCR_TZEN); ++ IMSG("RCC is non secure"); ++ } + } else { +- if (io_read32(stm32_rcc_base() + RCC_TZCR) & RCC_TZCR_TZEN) +- panic("Refuse to release RCC[TZEN]"); +- +- IMSG("RCC is non-secure"); ++ io_setbits32(stm32_rcc_base() + RCC_TZCR, RCC_TZCR_TZEN); + } + + get_osc_freq_from_dt(fdt); +@@ -1360,11 +1628,1024 @@ static TEE_Result stm32mp1_clk_early_init(void) + + if (ignored != 0) + IMSG("DT clock tree configurations were ignored"); ++} + +- enable_static_secure_clocks(); ++/* ++ * Gets OPP parameters (frequency in KHz and voltage in mV) from an OPP table ++ * subnode. Platform HW support capabilities are also checked. ++ */ ++static int get_opp_freqvolt_from_dt_subnode(void *fdt, int subnode, ++ uint32_t *freq_khz, ++ uint32_t *voltage_mv) ++{ ++ const fdt64_t *cuint64 = NULL; ++ const fdt32_t *cuint32 = NULL; ++ uint64_t read_freq_64 = 0; ++ uint32_t read_voltage_32 = 0; ++ ++ assert(freq_khz); ++ assert(voltage_mv); ++ ++ cuint32 = fdt_getprop(fdt, subnode, "opp-supported-hw", NULL); ++ if (cuint32) ++ if (!stm32mp_supports_cpu_opp(fdt32_to_cpu(*cuint32))) { ++ DMSG("Invalid opp-supported-hw 0x%"PRIx32, ++ fdt32_to_cpu(*cuint32)); ++ return -FDT_ERR_BADVALUE; ++ } + +- return TEE_SUCCESS; ++ cuint64 = fdt_getprop(fdt, subnode, "opp-hz", NULL); ++ if (!cuint64) { ++ DMSG("Missing opp-hz"); ++ return -FDT_ERR_NOTFOUND; ++ } ++ ++ /* Frequency value expressed in KHz must fit on 32 bits */ ++ read_freq_64 = fdt64_to_cpu(*cuint64) / 1000ULL; ++ if (read_freq_64 > (uint64_t)UINT32_MAX) { ++ DMSG("Invalid opp-hz %"PRIu64, read_freq_64); ++ return -FDT_ERR_BADVALUE; ++ } ++ ++ cuint32 = fdt_getprop(fdt, subnode, "opp-microvolt", NULL); ++ if (!cuint32) { ++ DMSG("Missing opp-microvolt"); ++ return -FDT_ERR_NOTFOUND; ++ } ++ ++ /* Millivolt value must fit on 16 bits */ ++ read_voltage_32 = fdt32_to_cpu(*cuint32) / 1000U; ++ if (read_voltage_32 > UINT16_MAX) { ++ DMSG("Invalid opp-microvolt %"PRIu32, read_voltage_32); ++ return -FDT_ERR_BADVALUE; ++ } ++ ++ *freq_khz = (uint32_t)read_freq_64; ++ ++ *voltage_mv = read_voltage_32; ++ ++ return 0; ++} ++ ++/* ++ * Parses OPP table in DT and finds all parameters supported by the HW ++ * platform. If found, the corresponding frequency and voltage values are ++ * respectively stored in @pll1_settings structure. ++ * Note that @*count has to be set by caller to the effective size allocated ++ * for both tables. Its value is then replaced by the number of filled elements. ++ */ ++static int get_all_opp_freqvolt_from_dt(uint32_t *count) ++{ ++ void *fdt = NULL; ++ int node = 0; ++ int subnode = 0; ++ uint32_t idx = 0; ++ ++ assert(count); ++ ++ fdt = get_embedded_dt(); ++ node = fdt_node_offset_by_compatible(fdt, -1, DT_OPP_COMPAT); ++ if (node < 0) ++ return node; ++ ++ fdt_for_each_subnode(subnode, fdt, node) { ++ uint32_t read_freq = 0; ++ uint32_t read_voltage = 0; ++ ++ if (get_opp_freqvolt_from_dt_subnode(fdt, subnode, &read_freq, ++ &read_voltage)) ++ continue; ++ ++ if (idx >= *count) ++ return -FDT_ERR_NOSPACE; ++ ++ pll1_settings.freq[idx] = read_freq; ++ pll1_settings.volt[idx] = read_voltage; ++ idx++; ++ } ++ ++ if (!idx) ++ return -FDT_ERR_NOTFOUND; ++ ++ *count = idx; ++ ++ return 0; ++} ++ ++static int clk_compute_pll1_settings(unsigned long input_freq, int idx) ++{ ++ unsigned long post_divm = 0; ++ unsigned long long output_freq = pll1_settings.freq[idx] * 1000U; ++ unsigned long long freq = 0; ++ unsigned long long vco = 0; ++ int divm = 0; ++ int divn = 0; ++ int divp = 0; ++ int frac = 0; ++ int i = 0; ++ unsigned int diff = 0; ++ unsigned int best_diff = UINT_MAX; ++ ++ /* Following parameters have always the same value */ ++ pll1_settings.cfg[idx][PLLCFG_Q] = 0; ++ pll1_settings.cfg[idx][PLLCFG_R] = 0; ++ pll1_settings.cfg[idx][PLLCFG_O] = PQR(1, 0, 0); ++ ++ for (divm = DIVM_MAX; divm >= DIVM_MIN; divm--) { ++ post_divm = input_freq / (unsigned long)(divm + 1); ++ ++ if ((post_divm < POST_DIVM_MIN) || ++ (post_divm > POST_DIVM_MAX)) ++ continue; ++ ++ for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) { ++ ++ freq = output_freq * (divm + 1) * (divp + 1); ++ ++ divn = (int)((freq / input_freq) - 1); ++ if ((divn < DIVN_MIN) || (divn > DIVN_MAX)) ++ continue; ++ ++ frac = (int)(((freq * FRAC_MAX) / input_freq) - ++ ((divn + 1) * FRAC_MAX)); ++ ++ /* 2 loops to refine the fractional part */ ++ for (i = 2; i != 0; i--) { ++ if (frac > FRAC_MAX) ++ break; ++ ++ vco = (post_divm * (divn + 1)) + ++ ((post_divm * (unsigned long long)frac) / ++ FRAC_MAX); ++ ++ if ((vco < (VCO_MIN / 2)) || ++ (vco > (VCO_MAX / 2))) { ++ frac++; ++ continue; ++ } ++ ++ freq = vco / (divp + 1); ++ if (output_freq < freq) ++ diff = (unsigned int)(freq - ++ output_freq); ++ else ++ diff = (unsigned int)(output_freq - ++ freq); ++ ++ if (diff < best_diff) { ++ pll1_settings.cfg[idx][PLLCFG_M] = divm; ++ pll1_settings.cfg[idx][PLLCFG_N] = divn; ++ pll1_settings.cfg[idx][PLLCFG_P] = divp; ++ pll1_settings.frac[idx] = frac; ++ ++ if (!diff) ++ return 0; ++ ++ best_diff = diff; ++ } ++ ++ frac++; ++ } ++ } ++ } ++ ++ if (best_diff == UINT_MAX) { ++ pll1_settings.cfg[idx][PLLCFG_O] = 0; ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int clk_get_pll1_settings(uint32_t clksrc, int index) ++{ ++ unsigned long input_freq = 0; ++ unsigned int i = 0; ++ ++ for (i = 0; i < PLAT_MAX_OPP_NB; i++) ++ if (pll1_settings.freq[i] == pll1_settings.freq[index]) ++ break; ++ ++ if (((i == PLAT_MAX_OPP_NB) && ++ !stm32mp1_clk_pll1_settings_are_valid()) || ++ ((i < PLAT_MAX_OPP_NB) && !pll1_settings.cfg[i][PLLCFG_O])) { ++ /* ++ * Either PLL1 settings structure is completely empty, ++ * or these settings are not yet computed: do it. ++ */ ++ switch (clksrc) { ++ case CLK_PLL12_HSI: ++ input_freq = clk_stm32_get_rate(CK_HSI); ++ break; ++ case CLK_PLL12_HSE: ++ input_freq = clk_stm32_get_rate(CK_HSE); ++ break; ++ default: ++ panic(); ++ } ++ ++ return clk_compute_pll1_settings(input_freq, index); ++ } ++ ++ if (i < PLAT_MAX_OPP_NB) { ++ if (pll1_settings.cfg[i][PLLCFG_O]) ++ return 0; ++ ++ /* ++ * Index is in range and PLL1 settings are computed: ++ * use content to answer to the request. ++ */ ++ memcpy(&pll1_settings.cfg[index][0], &pll1_settings.cfg[i][0], ++ sizeof(uint32_t) * PLAT_MAX_PLLCFG_NB); ++ pll1_settings.frac[index] = pll1_settings.frac[i]; ++ ++ return 0; ++ } ++ ++ return -1; ++} ++ ++static int clk_save_current_pll1_settings(uint32_t buck1_voltage) ++{ ++ const struct stm32mp1_clk_pll *pll = pll_ref(_PLL1); ++ uint32_t rcc_base = stm32_rcc_base(); ++ uint32_t freq = 0; ++ unsigned int i = 0; ++ ++ freq = UDIV_ROUND_NEAREST(clk_stm32_get_rate(CK_MPU), 1000L); ++ ++ for (i = 0; i < PLAT_MAX_OPP_NB; i++) ++ if (pll1_settings.freq[i] == freq) ++ break; ++ ++ if ((i == PLAT_MAX_OPP_NB) || ++ ((pll1_settings.volt[i] != buck1_voltage) && buck1_voltage)) ++ return -1; ++ ++ pll1_settings.cfg[i][PLLCFG_M] = (io_read32(rcc_base + pll->pllxcfgr1) & ++ RCC_PLLNCFGR1_DIVM_MASK) >> ++ RCC_PLLNCFGR1_DIVM_SHIFT; ++ ++ pll1_settings.cfg[i][PLLCFG_N] = (io_read32(rcc_base + pll->pllxcfgr1) & ++ RCC_PLLNCFGR1_DIVN_MASK) >> ++ RCC_PLLNCFGR1_DIVN_SHIFT; ++ ++ pll1_settings.cfg[i][PLLCFG_P] = (io_read32(rcc_base + pll->pllxcfgr2) & ++ RCC_PLLNCFGR2_DIVP_MASK) >> ++ RCC_PLLNCFGR2_DIVP_SHIFT; ++ ++ pll1_settings.cfg[i][PLLCFG_Q] = (io_read32(rcc_base + pll->pllxcfgr2) & ++ RCC_PLLNCFGR2_DIVQ_MASK) >> ++ RCC_PLLNCFGR2_DIVQ_SHIFT; ++ ++ pll1_settings.cfg[i][PLLCFG_R] = (io_read32(rcc_base + pll->pllxcfgr2) & ++ RCC_PLLNCFGR2_DIVR_MASK) >> ++ RCC_PLLNCFGR2_DIVR_SHIFT; ++ ++ pll1_settings.cfg[i][PLLCFG_O] = io_read32(rcc_base + pll->pllxcr) >> ++ RCC_PLLNCR_DIVEN_SHIFT; ++ ++ pll1_settings.frac[i] = (io_read32(rcc_base + pll->pllxfracr) & ++ RCC_PLLNFRACR_FRACV_MASK) >> ++ RCC_PLLNFRACR_FRACV_SHIFT; ++ ++ return i; ++} ++ ++static uint32_t stm32mp1_clk_get_pll1_current_clksrc(void) ++{ ++ uint32_t value = 0; ++ const struct stm32mp1_clk_pll *pll = pll_ref(_PLL1); ++ uint32_t rcc_base = stm32_rcc_base(); ++ ++ value = io_read32(rcc_base + pll->rckxselr); ++ ++ switch (value & RCC_SELR_REFCLK_SRC_MASK) { ++ case 0: ++ return CLK_PLL12_HSI; ++ case 1: ++ return CLK_PLL12_HSE; ++ default: ++ panic(); ++ } ++} ++ ++int stm32mp1_clk_compute_all_pll1_settings(uint32_t buck1_voltage) ++{ ++ unsigned int i = 0; ++ int ret = 0; ++ int index = 0; ++ uint32_t count = PLAT_MAX_OPP_NB; ++ uint32_t clksrc = 0; ++ ++ ret = get_all_opp_freqvolt_from_dt(&count); ++ switch (ret) { ++ case 0: ++ break; ++ case -FDT_ERR_NOTFOUND: ++ DMSG("Cannot find all OPP info in DT: use default settings."); ++ return 0; ++ default: ++ EMSG("Inconsistent OPP settings found in DT, ignored."); ++ return 0; ++ } ++ ++ index = clk_save_current_pll1_settings(buck1_voltage); ++ ++ clksrc = stm32mp1_clk_get_pll1_current_clksrc(); ++ ++ for (i = 0; i < count; i++) { ++ if (index >= 0 && i == (unsigned int)index) ++ continue; ++ ++ ret = clk_get_pll1_settings(clksrc, i); ++ if (ret != 0) ++ return ret; ++ } ++ ++ pll1_settings.valid_id = PLL1_SETTINGS_VALID_ID; ++ ++ return 0; ++} ++ ++void stm32mp1_clk_lp_save_opp_pll1_settings(uint8_t *data, size_t size) ++{ ++ if ((size != sizeof(pll1_settings)) || ++ !stm32mp1_clk_pll1_settings_are_valid()) ++ panic(); ++ ++ memcpy(data, &pll1_settings, size); ++} ++ ++bool stm32mp1_clk_pll1_settings_are_valid(void) ++{ ++ return pll1_settings.valid_id == PLL1_SETTINGS_VALID_ID; ++} ++#else ++static void stm32mp1_clk_early_init(void) ++{ ++ vaddr_t rcc_base = stm32_rcc_base(); ++ ++ /* Expect booting from a secure setup */ ++ if ((io_read32(rcc_base + RCC_TZCR) & RCC_TZCR_TZEN) == 0) ++ panic("RCC TZC[TZEN]"); ++} ++ ++int stm32mp1_clk_compute_all_pll1_settings(uint32_t buck1_voltage __unused) ++{ ++ return 0; ++} ++ ++void stm32mp1_clk_lp_save_opp_pll1_settings(uint8_t *data __unused, ++ size_t size __unused) ++{ ++} ++ ++bool stm32mp1_clk_pll1_settings_are_valid(void) ++{ ++ return false; + } + +-service_init(stm32mp1_clk_early_init); ++static void enable_static_secure_clocks(void) ++{ ++} + #endif /*CFG_EMBED_DTB*/ ++ ++/* Start MPU OPP */ ++#define CLKSRC_TIMEOUT_US (200 * 1000) ++#define CLKDIV_TIMEOUT_US (200 * 1000) ++#define CLK_MPU_PLL1P 0x00000202 ++#define CLK_MPU_PLL1P_DIV 0x00000203 ++ ++static int stm32mp1_set_clksrc(unsigned int clksrc) ++{ ++ uintptr_t address = stm32_rcc_base() + (clksrc >> 4); ++ uint64_t timeout_ref = 0; ++ ++ io_clrsetbits32(address, RCC_SELR_SRC_MASK, clksrc & RCC_SELR_SRC_MASK); ++ ++ timeout_ref = timeout_init_us(CLKSRC_TIMEOUT_US); ++ while ((io_read32(address) & RCC_SELR_SRCRDY) == 0U) { ++ if (timeout_elapsed(timeout_ref)) { ++ EMSG("CLKSRC %u start failed @ 0x%"PRIxPTR": 0x%"PRIx32, ++ clksrc, address, io_read32(address)); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++static int stm32mp1_set_clkdiv(unsigned int clkdiv, uintptr_t address) ++{ ++ uint64_t timeout_ref = 0; ++ ++ io_clrsetbits32(address, RCC_DIVR_DIV_MASK, clkdiv & RCC_DIVR_DIV_MASK); ++ ++ timeout_ref = timeout_init_us(CLKDIV_TIMEOUT_US); ++ while ((io_read32(address) & RCC_DIVR_DIVRDY) == 0U) { ++ if (timeout_elapsed(timeout_ref)) { ++ EMSG("CLKDIV 0x%x start failed @ 0x%"PRIxPTR": 0x%"PRIx32, ++ clkdiv, address, io_read32(address)); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++/* ++ * Check if PLL1 can be configured on the fly. ++ * @result (-1) => config on the fly is not possible. ++ * (0) => config on the fly is possible. ++ * (+1) => same parameters as those in place, no need to reconfig. ++ * Return value is 0 if no error. ++ */ ++static int is_pll_config_on_the_fly(enum stm32mp1_pll_id pll_id, ++ uint32_t *pllcfg, uint32_t fracv, ++ int *result) ++{ ++ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); ++ uintptr_t rcc_base = stm32_rcc_base(); ++ uint32_t fracr = 0; ++ uint32_t value = 0; ++ int ret = 0; ++ ++ ret = pll_compute_pllxcfgr1(pll, pllcfg, &value); ++ if (ret) ++ return ret; ++ ++ if (io_read32(rcc_base + pll->pllxcfgr1) != value) { ++ /* Different DIVN/DIVM, can't config on the fly */ ++ *result = -1; ++ return 0; ++ } ++ ++ *result = true; ++ ++ fracr = fracv << RCC_PLLNFRACR_FRACV_SHIFT; ++ fracr |= RCC_PLLNFRACR_FRACLE; ++ value = pll_compute_pllxcfgr2(pllcfg); ++ ++ if ((io_read32(rcc_base + pll->pllxfracr) == fracr) && ++ (io_read32(rcc_base + pll->pllxcfgr2) == value)) ++ /* Same parameters, no need to config */ ++ *result = 1; ++ else ++ *result = 0; ++ ++ return 0; ++} ++ ++static int stm32mp1_get_mpu_div(uint32_t freq_khz) ++{ ++ unsigned long freq_pll1_p; ++ unsigned long div; ++ ++ freq_pll1_p = __clk_get_parent_rate(_PLL1_P) / 1000UL; ++ if ((freq_pll1_p % freq_khz) != 0U) ++ return -1; ++ ++ div = freq_pll1_p / freq_khz; ++ ++ switch (div) { ++ case 1UL: ++ case 2UL: ++ case 4UL: ++ case 8UL: ++ case 16UL: ++ return __builtin_ffs(div) - 1; ++ default: ++ return -1; ++ } ++} ++ ++/* Configure PLL1 from input frequency OPP parameters */ ++static int pll1_config_from_opp_khz(uint32_t freq_khz) ++{ ++ unsigned int idx = 0; ++ int ret = 0; ++ int div = 0; ++ int config_on_the_fly = -1; ++ ++ for (idx = 0; idx < PLAT_MAX_OPP_NB; idx++) ++ if (pll1_settings.freq[idx] == freq_khz) ++ break; ++ ++ if (idx == PLAT_MAX_OPP_NB) ++ return -1; ++ ++ div = stm32mp1_get_mpu_div(freq_khz); ++ switch (div) { ++ case -1: ++ break; ++ case 0: ++ return stm32mp1_set_clksrc(CLK_MPU_PLL1P); ++ default: ++ ret = stm32mp1_set_clkdiv(div, stm32_rcc_base() + ++ RCC_MPCKDIVR); ++ if (ret == 0) ++ ret = stm32mp1_set_clksrc(CLK_MPU_PLL1P_DIV); ++ ++ return ret; ++ } ++ ++ ret = is_pll_config_on_the_fly(_PLL1, &pll1_settings.cfg[idx][0], ++ pll1_settings.frac[idx], ++ &config_on_the_fly); ++ if (ret) ++ return ret; ++ ++ if (config_on_the_fly == 1) ++ return 0; ++ ++ if (config_on_the_fly == -1) { ++ /* Switch to HSI and stop PLL1 before reconfiguration */ ++ ret = stm32mp1_set_clksrc(CLK_MPU_HSI); ++ if (ret) ++ return ret; ++ ++ ret = pll_stop(_PLL1); ++ if (ret) ++ return ret; ++ } ++ ++ ret = pll_config(_PLL1, &pll1_settings.cfg[idx][0], ++ pll1_settings.frac[idx]); ++ if (ret) ++ return ret; ++ ++ if (config_on_the_fly == -1) { ++ /* Start PLL1 and switch back to after reconfiguration */ ++ pll_start(_PLL1); ++ ++ ret = pll_output(_PLL1, pll1_settings.cfg[idx][PLLCFG_O]); ++ if (ret) ++ return ret; ++ ++ ret = stm32mp1_set_clksrc(CLK_MPU_PLL1P); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void save_current_opp(void) ++{ ++ unsigned long freq_khz = UDIV_ROUND_NEAREST(clk_stm32_get_rate(CK_MPU), ++ 1000UL); ++ if (freq_khz > (unsigned long)UINT32_MAX) ++ panic(); ++ ++ current_opp_khz = (uint32_t)freq_khz; ++} ++ ++int stm32mp1_set_opp_khz(uint32_t freq_khz) ++{ ++ uint32_t mpu_src = 0; ++ ++ if (freq_khz == current_opp_khz) ++ return 0; ++ ++ if (!stm32mp1_clk_pll1_settings_are_valid()) { ++ /* ++ * No OPP table in DT or an error occurred during PLL1 ++ * settings computation, system can only work on current ++ * operating point so return error. ++ */ ++ return -1; ++ } ++ ++ /* Check that PLL1 is MPU clock source */ ++ mpu_src = io_read32(stm32_rcc_base() + RCC_MPCKSELR) & ++ RCC_SELR_SRC_MASK; ++ if ((mpu_src != RCC_MPCKSELR_PLL) && ++ (mpu_src != RCC_MPCKSELR_PLL_MPUDIV)) ++ return -1; ++ ++ if (pll1_config_from_opp_khz(freq_khz)) { ++ /* Restore original value */ ++ if (pll1_config_from_opp_khz(current_opp_khz)) { ++ EMSG("No CPU operating point can be set"); ++ panic(); ++ } ++ ++ return -1; ++ } ++ ++ current_opp_khz = freq_khz; ++ ++ return 0; ++} ++ ++int stm32mp1_round_opp_khz(uint32_t *freq_khz) ++{ ++ unsigned int i = 0; ++ uint32_t round_opp = 0; ++ ++ if (!stm32mp1_clk_pll1_settings_are_valid()) { ++ /* ++ * No OPP table in DT, or an error occurred during PLL1 ++ * settings computation, system can only work on current ++ * operating point, so return current CPU frequency. ++ */ ++ *freq_khz = current_opp_khz; ++ ++ return 0; ++ } ++ ++ for (i = 0; i < PLAT_MAX_OPP_NB; i++) ++ if ((pll1_settings.freq[i] <= *freq_khz) && ++ (pll1_settings.freq[i] > round_opp)) ++ round_opp = pll1_settings.freq[i]; ++ ++ *freq_khz = round_opp; ++ ++ return 0; ++} ++/* End PMU OPP */ ++ ++#ifdef CFG_PM ++struct soc_stop_context { ++ uint32_t pll3cr; ++ uint32_t pll4cr; ++ uint32_t mssckselr; ++ uint32_t mcudivr; ++}; ++ ++static struct soc_stop_context soc_stop_ctx; ++ ++static void save_pll34_state(void) ++{ ++ uintptr_t rcc_base = stm32_rcc_base(); ++ struct soc_stop_context *ctx = &soc_stop_ctx; ++ ++ ctx->pll3cr = io_read32(rcc_base + RCC_PLL3CR); ++ ctx->pll4cr = io_read32(rcc_base + RCC_PLL4CR); ++} ++ ++static void save_mcu_subsys_clocks(void) ++{ ++ uintptr_t rcc_base = stm32_rcc_base(); ++ struct soc_stop_context *ctx = &soc_stop_ctx; ++ ++ ctx->mssckselr = io_read32(rcc_base + RCC_MSSCKSELR); ++ ctx->mcudivr = io_read32(rcc_base + RCC_MCUDIVR) & ++ RCC_MCUDIV_MASK; ++} ++ ++static void restore_pll34_state(void) ++{ ++ struct soc_stop_context *ctx = &soc_stop_ctx; ++ ++ /* Let PLL4 start while we're starting and waiting for PLL3 */ ++ if (ctx->pll4cr & RCC_PLLNCR_PLLON) ++ pll_start(_PLL4); ++ ++ if (ctx->pll3cr & RCC_PLLNCR_PLLON) { ++ pll_start(_PLL3); ++ if (pll_output(_PLL3, ctx->pll3cr >> RCC_PLLNCR_DIVEN_SHIFT)) { ++ EMSG("Failed to restore PLL3"); ++ panic(); ++ } ++ } ++ ++ if (ctx->pll4cr & RCC_PLLNCR_PLLON) { ++ if (pll_output(_PLL4, ctx->pll4cr >> RCC_PLLNCR_DIVEN_SHIFT)) { ++ EMSG("Failed to restore PLL4"); ++ panic(); ++ } ++ } ++} ++ ++static void restore_mcu_subsys_clocks(void) ++{ ++ uintptr_t rcc_base = stm32_rcc_base(); ++ struct soc_stop_context *ctx = &soc_stop_ctx; ++ ++ io_write32(rcc_base + RCC_MSSCKSELR, ctx->mssckselr); ++ ++ if (stm32mp1_set_clkdiv(ctx->mcudivr, rcc_base + RCC_MCUDIVR)) { ++ EMSG("Failed to restore MCUDIVR"); ++ panic(); ++ } ++} ++ ++/* ++ * Sequence to save/restore the non-secure configuration. ++ * Restoring clocks and muxes need IPs to run on kernel clock ++ * hence on configuration is restored at resume, kernel clock ++ * should be disable: this mandates secure access. ++ * ++ * backup_mux*_cfg for the clock muxes. ++ * backup_clock_sc_cfg for the set/clear clock gating registers ++ * backup_clock_cfg for the regular full write registers ++ */ ++ ++struct backup_mux_cfg { ++ uint16_t offset; ++ uint8_t value; ++ uint8_t bit_len; ++}; ++ ++#define MUXCFG(_offset, _bit_len) \ ++ { .offset = (_offset), .bit_len = (_bit_len) } ++ ++struct backup_mux_cfg backup_mux0_cfg[] = { ++ MUXCFG(RCC_SDMMC12CKSELR, 3), ++ MUXCFG(RCC_SPI2S23CKSELR, 3), ++ MUXCFG(RCC_SPI45CKSELR, 3), ++ MUXCFG(RCC_I2C12CKSELR, 3), ++ MUXCFG(RCC_I2C35CKSELR, 3), ++ MUXCFG(RCC_LPTIM23CKSELR, 3), ++ MUXCFG(RCC_LPTIM45CKSELR, 3), ++ MUXCFG(RCC_UART24CKSELR, 3), ++ MUXCFG(RCC_UART35CKSELR, 3), ++ MUXCFG(RCC_UART78CKSELR, 3), ++ MUXCFG(RCC_SAI1CKSELR, 3), ++ MUXCFG(RCC_ETHCKSELR, 2), ++ MUXCFG(RCC_I2C46CKSELR, 3), ++ MUXCFG(RCC_RNG2CKSELR, 2), ++ MUXCFG(RCC_SDMMC3CKSELR, 3), ++ MUXCFG(RCC_FMCCKSELR, 2), ++ MUXCFG(RCC_QSPICKSELR, 2), ++ MUXCFG(RCC_USBCKSELR, 2), ++ MUXCFG(RCC_SPDIFCKSELR, 2), ++ MUXCFG(RCC_SPI2S1CKSELR, 3), ++ MUXCFG(RCC_CECCKSELR, 2), ++ MUXCFG(RCC_LPTIM1CKSELR, 3), ++ MUXCFG(RCC_UART6CKSELR, 3), ++ MUXCFG(RCC_FDCANCKSELR, 2), ++ MUXCFG(RCC_SAI2CKSELR, 3), ++ MUXCFG(RCC_SAI3CKSELR, 3), ++ MUXCFG(RCC_SAI4CKSELR, 3), ++ MUXCFG(RCC_ADCCKSELR, 2), ++ MUXCFG(RCC_DSICKSELR, 1), ++ MUXCFG(RCC_CPERCKSELR, 2), ++ MUXCFG(RCC_RNG1CKSELR, 2), ++ MUXCFG(RCC_STGENCKSELR, 2), ++ MUXCFG(RCC_UART1CKSELR, 3), ++ MUXCFG(RCC_SPI6CKSELR, 3), ++}; ++ ++struct backup_mux_cfg backup_mux4_cfg[] = { ++ MUXCFG(RCC_USBCKSELR, 1), ++}; ++ ++static void backup_mux_cfg(void) ++{ ++ struct backup_mux_cfg *cfg = backup_mux0_cfg; ++ size_t count = ARRAY_SIZE(backup_mux0_cfg); ++ size_t i = 0; ++ uintptr_t base = stm32_rcc_base(); ++ ++ for (i = 0; i < count; i++) ++ cfg[i].value = io_read32(base + cfg[i].offset) & ++ GENMASK_32(cfg[i].bit_len - 1, 0); ++ ++ cfg = backup_mux4_cfg; ++ count = ARRAY_SIZE(backup_mux4_cfg); ++ ++ for (i = 0; i < count; i++) ++ cfg[i].value = io_read32(base + cfg[i].offset) & ++ GENMASK_32(4 + cfg[i].bit_len - 1, 4); ++} ++ ++static void restore_mux_cfg(void) ++{ ++ struct backup_mux_cfg *cfg = backup_mux0_cfg; ++ size_t count = ARRAY_SIZE(backup_mux0_cfg); ++ size_t i = 0; ++ uintptr_t base = stm32_rcc_base(); ++ ++ for (i = 0; i < count; i++) ++ io_clrsetbits32(base + cfg[i].offset, ++ GENMASK_32(cfg[i].bit_len - 1, 0), ++ cfg[i].value); ++ ++ cfg = backup_mux4_cfg; ++ count = ARRAY_SIZE(backup_mux4_cfg); ++ ++ for (i = 0; i < count; i++) ++ io_clrsetbits32(base + cfg[i].offset, ++ GENMASK_32(4 + cfg[i].bit_len - 1, 4), ++ cfg[i].value); ++} ++ ++/* Structure is used for set/clear registers and for regular registers */ ++struct backup_clock_cfg { ++ uint32_t offset; ++ uint32_t value; ++}; ++ ++static struct backup_clock_cfg backup_clock_sc_cfg[] = { ++ { .offset = RCC_MP_APB1ENSETR }, ++ { .offset = RCC_MP_APB2ENSETR }, ++ { .offset = RCC_MP_APB3ENSETR }, ++ { .offset = RCC_MP_APB4ENSETR }, ++ { .offset = RCC_MP_APB5ENSETR }, ++ { .offset = RCC_MP_AHB2ENSETR }, ++ { .offset = RCC_MP_AHB3ENSETR }, ++ { .offset = RCC_MP_AHB4ENSETR }, ++ { .offset = RCC_MP_AHB5ENSETR }, ++ { .offset = RCC_MP_AHB6ENSETR }, ++ { .offset = RCC_MP_MLAHBENSETR }, ++}; ++ ++static struct backup_clock_cfg backup_clock_cfg[] = { ++ { .offset = RCC_TZCR}, ++ { .offset = RCC_MCO1CFGR }, ++ { .offset = RCC_MCO2CFGR }, ++ { .offset = RCC_PLL3CR }, ++ { .offset = RCC_PLL4CR }, ++ { .offset = RCC_PLL4CFGR2 }, ++ { .offset = RCC_MCUDIVR }, ++ { .offset = RCC_MSSCKSELR }, ++}; ++ ++static void backup_sc_cfg(void) ++{ ++ struct backup_clock_cfg *cfg = backup_clock_sc_cfg; ++ size_t count = ARRAY_SIZE(backup_clock_sc_cfg); ++ size_t i = 0; ++ uintptr_t base = stm32_rcc_base(); ++ ++ for (i = 0; i < count; i++) ++ cfg[i].value = io_read32(base + cfg[i].offset); ++} ++ ++static void restore_sc_cfg(void) ++{ ++ struct backup_clock_cfg *cfg = backup_clock_sc_cfg; ++ size_t count = ARRAY_SIZE(backup_clock_sc_cfg); ++ size_t i = 0; ++ uintptr_t base = stm32_rcc_base(); ++ ++ for (i = 0; i < count; i++) { ++ io_write32(base + cfg[i].offset, cfg[i].value); ++ io_write32(base + cfg[i].offset + RCC_MP_ENCLRR_OFFSET, ++ ~cfg[i].value); ++ } ++} ++ ++static void backup_regular_cfg(void) ++{ ++ struct backup_clock_cfg *cfg = backup_clock_cfg; ++ size_t count = ARRAY_SIZE(backup_clock_cfg); ++ size_t i = 0; ++ uintptr_t base = stm32_rcc_base(); ++ ++ for (i = 0; i < count; i++) ++ cfg[i].value = io_read32(base + cfg[i].offset); ++} ++ ++static void restore_regular_cfg(void) ++{ ++ struct backup_clock_cfg *cfg = backup_clock_cfg; ++ size_t count = ARRAY_SIZE(backup_clock_cfg); ++ size_t i = 0; ++ uintptr_t base = stm32_rcc_base(); ++ ++ for (i = 0; i < count; i++) ++ io_write32(base + cfg[i].offset, cfg[i].value); ++} ++ ++static void disable_kernel_clocks(void) ++{ ++ const uint32_t ker_mask = RCC_OCENR_HSIKERON | ++ RCC_OCENR_CSIKERON | ++ RCC_OCENR_HSEKERON; ++ ++ /* Disable all ck_xxx_ker clocks */ ++ io_write32(stm32_rcc_base() + RCC_OCENCLRR, ker_mask); ++} ++ ++static void enable_kernel_clocks(void) ++{ ++ uintptr_t rcc_base = stm32_rcc_base(); ++ uint32_t reg = 0; ++ const uint32_t ker_mask = RCC_OCENR_HSIKERON | ++ RCC_OCENR_CSIKERON | ++ RCC_OCENR_HSEKERON; ++ ++ /* Enable ck_xxx_ker clocks if ck_xxx was on */ ++ reg = io_read32(rcc_base + RCC_OCENSETR) << 1; ++ io_write32(rcc_base + RCC_OCENSETR, reg & ker_mask); ++} ++ ++static void clear_rcc_reset_status(void) ++{ ++ /* Clear reset status fields */ ++ io_write32(stm32_rcc_base() + RCC_MP_RSTSCLRR, 0); ++} ++ ++void stm32mp1_clk_save_context_for_stop(void) ++{ ++ enable_kernel_clocks(); ++ save_mcu_subsys_clocks(); ++ save_pll34_state(); ++} ++ ++void stm32mp1_clk_restore_context_for_stop(void) ++{ ++ restore_pll34_state(); ++ /* Restore MCU clock source after PLL3 is ready */ ++ restore_mcu_subsys_clocks(); ++ disable_kernel_clocks(); ++} ++ ++void stm32mp1_clk_mcuss_protect(bool enable) ++{ ++ uintptr_t rcc_base = stm32_rcc_base(); ++ ++ if (enable) ++ io_setbits32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT); ++ else ++ io_clrbits32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT); ++} ++ ++static void stm32_clock_suspend(void) ++{ ++ backup_regular_cfg(); ++ backup_sc_cfg(); ++ backup_mux_cfg(); ++ save_pll34_state(); ++ ++ enable_kernel_clocks(); ++ clear_rcc_reset_status(); ++} ++ ++static void stm32_clock_resume(void) ++{ ++ unsigned int idx = 0; ++ ++ restore_pll34_state(); ++ restore_mux_cfg(); ++ restore_sc_cfg(); ++ restore_regular_cfg(); ++ ++ /* Sync secure and shared clocks physical state on functional state */ ++ for (idx = 0; idx < NB_GATES; idx++) { ++ struct stm32mp1_clk_gate const *gate = gate_ref(idx); ++ ++ if (gate_is_non_secure(gate)) ++ continue; ++ ++ if (gate_refcounts[idx]) { ++ DMSG("Force clock %d enable", gate->clock_id); ++ __clk_enable(gate); ++ } else { ++ DMSG("Force clock %d disable", gate->clock_id); ++ __clk_disable(gate); ++ } ++ } ++ ++ disable_kernel_clocks(); ++} ++ ++static TEE_Result stm32_clock_pm(enum pm_op op, unsigned int pm_hint __unused, ++ const struct pm_callback_handle *hdl __unused) ++{ ++ if (op == PM_OP_SUSPEND) ++ stm32_clock_suspend(); ++ else ++ stm32_clock_resume(); ++ ++ return TEE_SUCCESS; ++} ++DECLARE_KEEP_PAGER(stm32_clock_pm); ++#else ++static TEE_Result stm32_clock_pm(enum pm_op op __unused, ++ unsigned int pm_hint __unused, ++ const struct pm_callback_handle *hdl __unused) ++{ ++ return TEE_ERROR_SECURITY; ++} ++#endif /*CFG_PM*/ ++ ++static void init_non_secure_rcc(void) ++{ ++ uintptr_t rcc_base = stm32_rcc_base(); ++ ++ /* Clear all interrupt flags and core stop requests */ ++ io_write32(rcc_base + RCC_MP_CIFR, 0x110F1F); ++ io_write32(rcc_base + RCC_MP_SREQCLRR, 0x3); ++} ++ ++static TEE_Result stm32_clk_probe(void) ++{ ++ assert(PLLCFG_NB == PLAT_MAX_PLLCFG_NB); ++ ++ stm32mp1_clk_early_init(); ++ enable_static_secure_clocks(); ++ save_current_opp(); ++ init_non_secure_rcc(); ++ register_pm_core_service_cb(stm32_clock_pm, NULL); ++ ++ clk_provider_register(&stm32mp_clk_ops); ++ ++ return TEE_SUCCESS; ++} ++/* Setup clock support before driver initialization */ ++service_init(stm32_clk_probe); +diff --git a/core/drivers/clk/clk.c b/core/drivers/clk/clk.c +new file mode 100644 +index 000000000..f6e5d8ecf +--- /dev/null ++++ b/core/drivers/clk/clk.c +@@ -0,0 +1,58 @@ ++// SPDX-License-Identifier: BSD-2-Clause ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ * Author(s): Ludovic Barre, for STMicroelectronics. ++ */ ++ ++#include ++#include ++#include ++ ++static const struct clk_ops *ops; ++ ++TEE_Result clk_enable(unsigned long id) ++{ ++ assert(ops && ops->enable); ++ ++ return ops->enable(id); ++} ++ ++void clk_disable(unsigned long id) ++{ ++ assert(ops && ops->disable); ++ ++ ops->disable(id); ++} ++ ++unsigned long clk_get_rate(unsigned long id) ++{ ++ assert(ops && ops->get_rate); ++ ++ return ops->get_rate(id); ++} ++ ++unsigned long clk_get_parent(unsigned long id) ++{ ++ assert(ops); ++ ++ if (ops->get_parent) ++ return ops->get_parent(id); ++ ++ return CLK_UNKNOWN_ID; ++} ++ ++bool clk_is_enabled(unsigned long id) ++{ ++ assert(ops && ops->is_enabled); ++ ++ return ops->is_enabled(id); ++} ++ ++void clk_provider_register(const struct clk_ops *ops_ptr) ++{ ++ assert(!ops && ops_ptr && ops_ptr->enable && ++ ops_ptr->disable && ops_ptr->get_rate && ++ ops_ptr->is_enabled); ++ ++ ops = ops_ptr; ++} +diff --git a/core/drivers/clk/sub.mk b/core/drivers/clk/sub.mk +new file mode 100644 +index 000000000..4caed574b +--- /dev/null ++++ b/core/drivers/clk/sub.mk +@@ -0,0 +1,2 @@ ++srcs-$(CFG_CLK_DRIVER) += clk.c ++srcs-$(CFG_STM32MP15_CLK) += clk-stm32mp15.c diff --git a/core/drivers/gic.c b/core/drivers/gic.c -index 0bad974..3f1a606 100644 +index 0bad97486..3f1a606ed 100644 --- a/core/drivers/gic.c +++ b/core/drivers/gic.c @@ -7,12 +7,15 @@ @@ -13910,8 +15493,30 @@ index 0bad974..3f1a606 100644 + register_pm_core_service_cb(gic_pm, gd); +} +#endif /*CFG_ARM_GIC_PM*/ +diff --git a/core/drivers/scmi-msg/clock.c b/core/drivers/scmi-msg/clock.c +index 6fe62477e..0361f8828 100644 +--- a/core/drivers/scmi-msg/clock.c ++++ b/core/drivers/scmi-msg/clock.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, Linaro Limited ++ * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + */ + #include + #include +@@ -357,7 +357,7 @@ static const scmi_msg_handler_t scmi_clock_handler_table[] = { + [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]; diff --git a/core/drivers/stm32_bsec.c b/core/drivers/stm32_bsec.c -index 546ba91..a563f79 100644 +index 2b1584ff5..7d389a061 100644 --- a/core/drivers/stm32_bsec.c +++ b/core/drivers/stm32_bsec.c @@ -91,10 +91,6 @@ @@ -13925,52 +15530,10 @@ index 546ba91..a563f79 100644 #define BSEC_DEN_ALL_MSK GENMASK_32(10, 0) /* -@@ -138,6 +134,11 @@ static uint32_t otp_max_id(void) - return bsec_dev.max_id; +@@ -546,6 +542,40 @@ bool stm32_bsec_nsec_can_access_otp(uint32_t otp_id) + nsec_access_granted(otp_id - otp_upper_base()); } -+static uint32_t otp_upper_base(void) -+{ -+ return bsec_dev.upper_base; -+} -+ - static uint32_t otp_bank_offset(uint32_t otp_id) - { - assert(otp_id <= otp_max_id()); -@@ -363,12 +364,12 @@ TEE_Result stm32_bsec_permanent_lock_otp(uint32_t otp_id) - uint32_t addr = 0; - uint32_t exceptions = 0; - vaddr_t base = bsec_base(); -- uint64_t timeout_ref; -+ uint64_t timeout_ref = 0; - - if (otp_id > otp_max_id()) - return TEE_ERROR_BAD_PARAMETERS; - -- if (otp_id < bsec_dev.upper_base) { -+ if (otp_id < otp_upper_base()) { - addr = otp_id >> ADDR_LOWER_OTP_PERLOCK_SHIFT; - data = DATA_LOWER_OTP_PERLOCK_BIT << - ((otp_id & DATA_LOWER_OTP_PERLOCK_MASK) << 1U); -@@ -521,7 +522,7 @@ TEE_Result stm32_bsec_otp_lock(uint32_t service) - - static size_t nsec_access_array_size(void) - { -- size_t upper_count = otp_max_id() - bsec_dev.upper_base + 1; -+ size_t upper_count = otp_max_id() - otp_upper_base() + 1; - - return ROUNDUP(upper_count, BITS_PER_WORD) / BITS_PER_WORD; - } -@@ -537,16 +538,50 @@ static bool nsec_access_granted(unsigned int index) - - bool stm32_bsec_nsec_can_access_otp(uint32_t otp_id) - { -- return otp_id < bsec_dev.upper_base || -- nsec_access_granted(otp_id - bsec_dev.upper_base); -+ return otp_id < otp_upper_base() || -+ nsec_access_granted(otp_id - otp_upper_base()); -+} -+ +struct nvmem_layout { + char *name; + uint32_t otp_id; @@ -14003,20 +15566,12 @@ index 546ba91..a563f79 100644 + } + + return TEE_ERROR_ITEM_NOT_FOUND; - } - ++} ++ #ifdef CFG_DT static void enable_nsec_access(unsigned int otp_id) { -- unsigned int idx = (otp_id - bsec_dev.upper_base) / BITS_PER_WORD; -+ unsigned int idx = (otp_id - otp_upper_base()) / BITS_PER_WORD; - -- if (otp_id < bsec_dev.upper_base) -+ if (otp_id < otp_upper_base()) - return; - - if (otp_id > otp_max_id() || stm32_bsec_shadow_register(otp_id)) -@@ -619,6 +654,77 @@ static void bsec_dt_otp_nsec_access(void *fdt, int bsec_node) +@@ -624,6 +654,77 @@ static void bsec_dt_otp_nsec_access(void *fdt, int bsec_node) } } @@ -14094,7 +15649,7 @@ index 546ba91..a563f79 100644 static void initialize_bsec_from_dt(void) { void *fdt = NULL; -@@ -637,6 +743,8 @@ static void initialize_bsec_from_dt(void) +@@ -642,6 +743,8 @@ static void initialize_bsec_from_dt(void) panic(); bsec_dt_otp_nsec_access(fdt, node); @@ -14103,24 +15658,376 @@ index 546ba91..a563f79 100644 } #else static void initialize_bsec_from_dt(void) +diff --git a/core/drivers/stm32_etzpc.c b/core/drivers/stm32_etzpc.c +index 3482f3431..5573503a1 100644 +--- a/core/drivers/stm32_etzpc.c ++++ b/core/drivers/stm32_etzpc.c +@@ -26,10 +26,16 @@ + #include + #include + #include ++#include + #include + + /* Devicetree compatibility */ + #define ETZPC_COMPAT "st,stm32-etzpc" ++#define ETZPC_LOCK_MASK BIT(0) ++#define ETZPC_MODE_SHIFT 8 ++#define ETZPC_MODE_MASK GENMASK_32(1, 0) ++#define ETZPC_ID_SHIFT 16 ++#define ETZPC_ID_MASK GENMASK_32(7, 0) + + /* ID Registers */ + #define ETZPC_TZMA0_SIZE 0x000U +@@ -316,6 +322,45 @@ void stm32_etzpc_init(paddr_t base) + } + + #ifdef CFG_DT ++struct dt_id_attr { ++ /* The effective size of the array is meaningless here */ ++ fdt32_t id_attr[1]; ++}; ++ ++static void etzpc_dt_conf_decprot(void *fdt, int node) ++{ ++ const struct dt_id_attr *conf_list = NULL; ++ size_t i = 0; ++ int len = 0; ++ ++ conf_list = (const struct dt_id_attr *)fdt_getprop(fdt, node, ++ "st,decprot", &len); ++ if (conf_list == NULL) { ++ DMSG("No ETZPC DECPROT configuration in DT"); ++ return; ++ } ++ ++ for (i = 0; i < len / sizeof(uint32_t); i++) { ++ uint32_t value = fdt32_to_cpu(conf_list->id_attr[i]); ++ uint32_t id = (value >> ETZPC_ID_SHIFT) & ETZPC_ID_MASK; ++ uint32_t mode = (value >> ETZPC_MODE_SHIFT) & ETZPC_MODE_MASK; ++ bool lock = value & ETZPC_LOCK_MASK; ++ enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX; ++ ++ if (!valid_decprot_id(id)) { ++ DMSG("Invalid DECPROT %"PRIu32, id); ++ panic(); ++ } ++ ++ attr = stm32mp_etzpc_binding2decprot(mode); ++ stm32mp_register_etzpc_decprot(id, attr); ++ etzpc_configure_decprot(id, attr); ++ ++ if (lock) ++ etzpc_lock_decprot(id); ++ } ++} ++ + static TEE_Result init_etzpc_from_dt(void) + { + void *fdt = get_embedded_dt(); +@@ -339,6 +384,8 @@ static TEE_Result init_etzpc_from_dt(void) + + init_device_from_hw_config(&etzpc_dev, pbase); + ++ etzpc_dt_conf_decprot(fdt, node); ++ + return TEE_SUCCESS; + } + +diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c +index 8f7927d90..83c7b8b4e 100644 +--- a/core/drivers/stm32_gpio.c ++++ b/core/drivers/stm32_gpio.c +@@ -1,12 +1,13 @@ + // SPDX-License-Identifier: BSD-3-Clause + /* +- * Copyright (c) 2017-2019, STMicroelectronics ++ * Copyright (c) 2017-2020, STMicroelectronics + * + * STM32 GPIO driver is used as pin controller for stm32mp SoCs. + * The driver API is defined in header file stm32_gpio.h. + */ + + #include ++#include + #include + #include + #include +@@ -54,7 +55,7 @@ static void get_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg) + vaddr_t base = stm32_get_gpio_bank_base(bank); + unsigned int clock = stm32_get_gpio_bank_clock(bank); + +- stm32_clock_enable(clock); ++ clk_enable(clock); + + /* + * Save GPIO configuration bits spread over the few bank registers. +@@ -84,7 +85,7 @@ static void get_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg) + ((pin - GPIO_ALT_LOWER_LIMIT) << 2)) & + GPIO_ALTERNATE_MASK; + +- stm32_clock_disable(clock); ++ clk_disable(clock); + } + + /* Apply GPIO (@bank/@pin) configuration described by @cfg */ +@@ -94,7 +95,7 @@ static void set_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg) + unsigned int clock = stm32_get_gpio_bank_clock(bank); + uint32_t exceptions = cpu_spin_lock_xsave(&gpio_lock); + +- stm32_clock_enable(clock); ++ clk_enable(clock); + + /* Load GPIO MODE value, 2bit value shifted by twice the pin number */ + io_clrsetbits32(base + GPIO_MODER_OFFSET, +@@ -129,7 +130,7 @@ static void set_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg) + /* Load GPIO Output direction confuguration, 1bit */ + io_clrsetbits32(base + GPIO_ODR_OFFSET, BIT(pin), cfg->od << pin); + +- stm32_clock_disable(clock); ++ clk_disable(clock); + cpu_spin_unlock_xrestore(&gpio_lock, exceptions); + } + +@@ -395,12 +396,12 @@ int stm32_gpio_get_input_level(unsigned int bank, unsigned int pin) + + assert(valid_gpio_config(bank, pin, true)); + +- stm32_clock_enable(clock); ++ clk_enable(clock); + + if (io_read32(base + GPIO_IDR_OFFSET) == BIT(pin)) + rc = 1; + +- stm32_clock_disable(clock); ++ clk_disable(clock); + + return rc; + } +@@ -412,14 +413,14 @@ void stm32_gpio_set_output_level(unsigned int bank, unsigned int pin, int level) + + assert(valid_gpio_config(bank, pin, false)); + +- stm32_clock_enable(clock); ++ clk_enable(clock); + + if (level) + io_write32(base + GPIO_BSRR_OFFSET, BIT(pin)); + else + io_write32(base + GPIO_BSRR_OFFSET, BIT(pin + 16)); + +- stm32_clock_disable(clock); ++ clk_disable(clock); + } + + void stm32_gpio_set_secure_cfg(unsigned int bank, unsigned int pin, bool secure) +@@ -428,13 +429,13 @@ void stm32_gpio_set_secure_cfg(unsigned int bank, unsigned int pin, bool secure) + unsigned int clock = stm32_get_gpio_bank_clock(bank); + uint32_t exceptions = cpu_spin_lock_xsave(&gpio_lock); + +- stm32_clock_enable(clock); ++ clk_enable(clock); + + if (secure) + io_setbits32(base + GPIO_SECR_OFFSET, BIT(pin)); + else + io_clrbits32(base + GPIO_SECR_OFFSET, BIT(pin)); + +- stm32_clock_disable(clock); ++ clk_disable(clock); + cpu_spin_unlock_xrestore(&gpio_lock, exceptions); + } +diff --git a/core/drivers/stm32_i2c.c b/core/drivers/stm32_i2c.c +index 790a5cab6..2807cc42a 100644 +--- a/core/drivers/stm32_i2c.c ++++ b/core/drivers/stm32_i2c.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) + /* +- * Copyright (c) 2017-2019, STMicroelectronics ++ * Copyright (c) 2017-2020, STMicroelectronics + * + * The driver API is defined in header file stm32_i2c.h. + * +@@ -10,6 +10,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -313,7 +314,7 @@ static void save_cfg(struct i2c_handle_s *hi2c, struct i2c_cfg *cfg) + { + vaddr_t base = get_base(hi2c); + +- stm32_clock_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + + cfg->cr1 = io_read32(base + I2C_CR1); + cfg->cr2 = io_read32(base + I2C_CR2); +@@ -321,14 +322,14 @@ static void save_cfg(struct i2c_handle_s *hi2c, struct i2c_cfg *cfg) + cfg->oar2 = io_read32(base + I2C_OAR2); + cfg->timingr = io_read32(base + I2C_TIMINGR); + +- stm32_clock_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + } + + static void restore_cfg(struct i2c_handle_s *hi2c, struct i2c_cfg *cfg) + { + vaddr_t base = get_base(hi2c); + +- stm32_clock_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + + io_clrbits32(base + I2C_CR1, I2C_CR1_PE); + io_write32(base + I2C_TIMINGR, cfg->timingr & TIMINGR_CLEAR_MASK); +@@ -338,7 +339,7 @@ static void restore_cfg(struct i2c_handle_s *hi2c, struct i2c_cfg *cfg) + io_write32(base + I2C_CR1, cfg->cr1 & ~I2C_CR1_PE); + io_setbits32(base + I2C_CR1, cfg->cr1 & I2C_CR1_PE); + +- stm32_clock_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + } + + static void __maybe_unused dump_cfg(struct i2c_cfg *cfg __maybe_unused) +@@ -354,7 +355,7 @@ static void __maybe_unused dump_i2c(struct i2c_handle_s *hi2c) + { + vaddr_t __maybe_unused base = get_base(hi2c); + +- stm32_clock_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + + DMSG("CR1: %#"PRIx32, io_read32(base + I2C_CR1)); + DMSG("CR2: %#"PRIx32, io_read32(base + I2C_CR2)); +@@ -362,7 +363,7 @@ static void __maybe_unused dump_i2c(struct i2c_handle_s *hi2c) + DMSG("OAR2: %#"PRIx32, io_read32(base + I2C_OAR2)); + DMSG("TIM: %#"PRIx32, io_read32(base + I2C_TIMINGR)); + +- stm32_clock_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + } + + /* +@@ -597,7 +598,7 @@ static int i2c_setup_timing(struct i2c_handle_s *hi2c, + + assert(i2c_specs_is_consistent()); + +- clock_src = stm32_clock_get_rate(hi2c->clock); ++ clock_src = clk_get_rate(hi2c->clock); + if (!clock_src) { + DMSG("Null I2C clock rate"); + return -1; +@@ -759,7 +760,7 @@ int stm32_i2c_init(struct i2c_handle_s *hi2c, + if (rc) + return rc; + +- stm32_clock_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + base = get_base(hi2c); + hi2c->i2c_state = I2C_STATE_BUSY; + +@@ -819,7 +820,7 @@ int stm32_i2c_init(struct i2c_handle_s *hi2c, + if (rc) + DMSG("I2C analog filter error %d", rc); + +- stm32_clock_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + + return rc; + } +@@ -1074,7 +1075,7 @@ static int i2c_write(struct i2c_handle_s *hi2c, struct i2c_request *request, + if (!p_data || !size) + return -1; + +- stm32_clock_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + + timeout_ref = timeout_init_us(I2C_TIMEOUT_BUSY_MS * 1000); + if (wait_isr_event(hi2c, I2C_ISR_BUSY, 0, timeout_ref)) +@@ -1161,7 +1162,7 @@ static int i2c_write(struct i2c_handle_s *hi2c, struct i2c_request *request, + rc = 0; + + bail: +- stm32_clock_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + + return rc; + } +@@ -1207,7 +1208,7 @@ int stm32_i2c_read_write_membyte(struct i2c_handle_s *hi2c, uint16_t dev_addr, + if (hi2c->i2c_state != I2C_STATE_READY || !p_data) + return -1; + +- stm32_clock_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + + timeout_ref = timeout_init_us(I2C_TIMEOUT_BUSY_US); + if (wait_isr_event(hi2c, I2C_ISR_BUSY, 0, timeout_ref)) +@@ -1264,7 +1265,7 @@ int stm32_i2c_read_write_membyte(struct i2c_handle_s *hi2c, uint16_t dev_addr, + rc = 0; + + bail: +- stm32_clock_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + + return rc; + } +@@ -1297,7 +1298,7 @@ static int i2c_read(struct i2c_handle_s *hi2c, struct i2c_request *request, + if (!p_data || !size) + return -1; + +- stm32_clock_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + + timeout_ref = timeout_init_us(I2C_TIMEOUT_BUSY_MS * 1000); + if (wait_isr_event(hi2c, I2C_ISR_BUSY, 0, timeout_ref)) +@@ -1374,7 +1375,7 @@ static int i2c_read(struct i2c_handle_s *hi2c, struct i2c_request *request, + rc = 0; + + bail: +- stm32_clock_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + + return rc; + } +@@ -1417,7 +1418,7 @@ bool stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c, uint32_t dev_addr, + if (hi2c->i2c_state != I2C_STATE_READY) + return rc; + +- stm32_clock_enable(hi2c->clock); ++ clk_enable(hi2c->clock); + + if (io_read32(base + I2C_ISR) & I2C_ISR_BUSY) + goto bail; +@@ -1489,7 +1490,7 @@ bool stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c, uint32_t dev_addr, + notif_i2c_timeout(hi2c); + + bail: +- stm32_clock_disable(hi2c->clock); ++ clk_disable(hi2c->clock); + + return rc; + } diff --git a/core/drivers/stm32_iwdg.c b/core/drivers/stm32_iwdg.c new file mode 100644 -index 0000000..5073663 +index 000000000..335d1a2cb --- /dev/null +++ b/core/drivers/stm32_iwdg.c -@@ -0,0 +1,313 @@ +@@ -0,0 +1,314 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + */ + +#include ++#include +#include +#include +#include ++#include +#include +#include -+#include +#include +#include +#include @@ -14214,11 +16121,11 @@ index 0000000..5073663 + + stm32_iwdg_refresh(instance); + -+ stm32_clock_enable(iwdg->clock); ++ clk_enable(iwdg->clock); + + io_setbits32(iwdg_base + IWDG_EWCR_OFFSET, IWDG_EWCR_EWIC); + -+ stm32_clock_disable(iwdg->clock); ++ clk_disable(iwdg->clock); + +#ifdef CFG_PM + /* @@ -14292,10 +16199,10 @@ index 0000000..5073663 + + /* Prescaler fix to 256 */ + reload_ll = (unsigned long long)dt_secure_timeout * -+ stm32_clock_get_rate(id_lsi); ++ clk_get_rate(id_lsi); + reload = ((uint32_t)(reload_ll >> 8) - 1) & IWDG_EWCR_EWIT_MASK; + -+ stm32_clock_enable(iwdg->clock); ++ clk_enable(iwdg->clock); + + io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_START_KEY); + io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_ACCESS_KEY); @@ -14308,7 +16215,7 @@ index 0000000..5073663 + break; + + status = io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_EWU; -+ stm32_clock_disable(iwdg->clock); ++ clk_disable(iwdg->clock); + if (status) + return TEE_ERROR_GENERIC; + @@ -14331,11 +16238,11 @@ index 0000000..5073663 + if (!iwdg) + return; + -+ stm32_clock_enable(iwdg->clock); ++ clk_enable(iwdg->clock); + + io_write32(get_base(iwdg) + IWDG_KR_OFFSET, IWDG_KR_RELOAD_KEY); + -+ stm32_clock_disable(iwdg->clock); ++ clk_disable(iwdg->clock); +} + +static TEE_Result iwdg_init(void) @@ -14422,24 +16329,59 @@ index 0000000..5073663 + return TEE_SUCCESS; +} +driver_init(iwdg_init); +diff --git a/core/drivers/stm32_rng.c b/core/drivers/stm32_rng.c +index d55f28f19..e95bde8ad 100644 +--- a/core/drivers/stm32_rng.c ++++ b/core/drivers/stm32_rng.c +@@ -1,9 +1,10 @@ + // SPDX-License-Identifier: BSD-3-Clause + /* +- * Copyright (c) 2018-2019, STMicroelectronics ++ * Copyright (c) 2018-2020, STMicroelectronics + */ + + #include ++#include + #include + #include + #include +@@ -129,7 +130,7 @@ static void gate_rng(bool enable, struct stm32_rng_instance *dev) + if (enable) { + /* incr_refcnt return non zero if resource shall be enabled */ + if (incr_refcnt(&dev->refcount)) { +- stm32_clock_enable(dev->clock); ++ clk_enable(dev->clock); + io_write32(rng_cr, 0); + io_write32(rng_cr, RNG_CR_RNGEN | RNG_CR_CED); + } +@@ -137,7 +138,7 @@ static void gate_rng(bool enable, struct stm32_rng_instance *dev) + /* decr_refcnt return non zero if resource shall be disabled */ + if (decr_refcnt(&dev->refcount)) { + io_write32(rng_cr, 0); +- stm32_clock_disable(dev->clock); ++ clk_disable(dev->clock); + } + } + diff --git a/core/drivers/stm32_rtc.c b/core/drivers/stm32_rtc.c new file mode 100644 -index 0000000..1abeaab +index 000000000..79ab627e6 --- /dev/null +++ b/core/drivers/stm32_rtc.c -@@ -0,0 +1,445 @@ +@@ -0,0 +1,446 @@ ++// SPDX-License-Identifier: BSD-3-Clause +/* -+ * Copyright (c) 2018, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved + * -+ * SPDX-License-Identifier: BSD-3-Clause + */ + +#include ++#include +#include +#include +#include ++#include +#include -+#include +#include +#include +#include @@ -14625,7 +16567,7 @@ index 0000000..1abeaab + +void stm32_rtc_get_calendar(struct stm32_rtc_calendar *calendar) +{ -+ stm32_clock_enable(rtc_dev.clock); ++ clk_enable(rtc_dev.clock); + + stm32_rtc_read_calendar(calendar); + @@ -14639,7 +16581,7 @@ index 0000000..1abeaab + stm32_rtc_read_calendar(calendar); + } + -+ stm32_clock_disable(rtc_dev.clock); ++ clk_disable(rtc_dev.clock); +} + +/* Return difference in milliseconds on second fraction */ @@ -14772,7 +16714,7 @@ index 0000000..1abeaab +{ + vaddr_t rtc_base = get_base(); + -+ stm32_clock_enable(rtc_dev.clock); ++ clk_enable(rtc_dev.clock); + + if (io_read32(rtc_base + RTC_SR) & RTC_SR_TSF) { + /* Timestamp for tamper event */ @@ -14784,14 +16726,14 @@ index 0000000..1abeaab + io_setbits32(rtc_base + RTC_SCR, RTC_SCR_CTSOVF); + } + -+ stm32_clock_disable(rtc_dev.clock); ++ clk_disable(rtc_dev.clock); +} + +void stm32_rtc_set_tamper_timestamp(void) +{ + vaddr_t rtc_base = get_base(); + -+ stm32_clock_enable(rtc_dev.clock); ++ clk_enable(rtc_dev.clock); + + stm32_rtc_write_unprotect(); + @@ -14803,18 +16745,18 @@ index 0000000..1abeaab + + stm32_rtc_write_protect(); + -+ stm32_clock_disable(rtc_dev.clock); ++ clk_disable(rtc_dev.clock); +} + +bool stm32_rtc_is_timestamp_enable(void) +{ + bool ret = false; + -+ stm32_clock_enable(rtc_dev.clock); ++ clk_enable(rtc_dev.clock); + + ret = io_read32(get_base() + RTC_CR) & RTC_CR_TAMPTS; + -+ stm32_clock_disable(rtc_dev.clock); ++ clk_disable(rtc_dev.clock); + + return ret; +} @@ -14857,7 +16799,7 @@ index 0000000..1abeaab + rtc_dev.base.va = (vaddr_t)phys_to_virt(rtc_dev.base.pa, + MEM_AREA_IO_SEC); + /* Unbalanced clock enable: keep RTC running */ -+ stm32_clock_enable(get_second_clock(fdt, node)); ++ clk_enable(get_second_clock(fdt, node)); + } else { + stm32mp_register_non_secure_periph_iomem(rtc_dev.base.pa); + rtc_dev.base.va = (vaddr_t)phys_to_virt(rtc_dev.base.pa, @@ -14875,24 +16817,25 @@ index 0000000..1abeaab +#endif diff --git a/core/drivers/stm32_tim.c b/core/drivers/stm32_tim.c new file mode 100644 -index 0000000..612fbbc +index 000000000..635e13824 --- /dev/null +++ b/core/drivers/stm32_tim.c -@@ -0,0 +1,286 @@ +@@ -0,0 +1,298 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* -+ * Copyright (c) 2018, STMicroelectronics ++ * Copyright (c) 2018-2020, STMicroelectronics + */ + +#include ++#include +#include +#include +#include +#include +#include ++#include +#include +#include -+#include +#include +#include +#include @@ -14944,6 +16887,7 @@ index 0000000..612fbbc +#define TIM_PRESCAL_HSI 10 +#define TIM_PRESCAL_CSI 7 +#define TIM_MIN_FREQ_CALIB 50000000U ++#define TIM_THRESHOLD 1U + +struct stm32_tim_instance { + struct io_pa_va base; @@ -14977,12 +16921,12 @@ index 0000000..612fbbc +{ + vaddr_t base = timer_base(timer); + -+ stm32_clock_enable(timer->clk); ++ clk_enable(timer->clk); + -+ timer->freq = stm32_clock_get_rate(timer->clk); ++ timer->freq = clk_get_rate(timer->clk); + if (timer->freq < TIM_MIN_FREQ_CALIB) { + EMSG("Calibration: timer not accurate enough"); -+ stm32_clock_disable(timer->clk); ++ clk_disable(timer->clk); + return -1; + } + @@ -15005,7 +16949,7 @@ index 0000000..612fbbc + io_setbits32(base + TIM_CCER, TIM_CCER_CC1E); + } + -+ stm32_clock_disable(timer->clk); ++ clk_disable(timer->clk); + + return 0; +} @@ -15013,19 +16957,19 @@ index 0000000..612fbbc +static uint32_t timer_start_capture(struct stm32_tim_instance *timer) +{ + uint64_t timeout_ref = 0; ++ uint64_t timeout_conv = 0; + uint32_t counter = 0; + uint32_t old_counter = 0; -+ int twice = 0; + vaddr_t base = timer_base(timer); + + if (timer_config(timer)) + return 0; + -+ stm32_clock_enable(timer->clk); ++ clk_enable(timer->clk); + + io_write32(base + TIM_SR, 0); + -+ timeout_ref = timeout_init_us(TIM_TIMEOUT_US); ++ timeout_ref = timeout_init_us(TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US); + + while (!timeout_elapsed(timeout_ref)) + if (io_read32(base + TIM_SR) & TIM_SR_UIF) @@ -15035,11 +16979,20 @@ index 0000000..612fbbc + + io_write32(base + TIM_SR, 0); + -+ for (twice = 0; (twice < 2) || (counter != old_counter); twice++) { -+ timeout_ref = timeout_init_us(TIM_TIMEOUT_US); ++ timeout_conv = timeout_init_us(TIM_TIMEOUT_US); ++ ++ do { ++ if (timeout_elapsed(timeout_conv)) { ++ counter = 0; ++ goto bail; ++ } ++ ++ timeout_ref = timeout_init_us(TIM_TIMEOUT_US / ++ TIM_TIMEOUT_STEP_US); + while (!timeout_elapsed(timeout_ref)) + if (io_read32(base + TIM_SR) & TIM_SR_CC1IF) + break; ++ + if (!(io_read32(base + TIM_SR) & TIM_SR_CC1IF)) { + counter = 0; + goto bail; @@ -15047,10 +17000,11 @@ index 0000000..612fbbc + + old_counter = counter; + counter = io_read32(base + TIM_CCR1); -+ } ++ } while (MAX(counter, old_counter) - MIN(counter, old_counter) > ++ TIM_THRESHOLD); + +bail: -+ stm32_clock_disable(timer->clk); ++ clk_disable(timer->clk); + + return counter; +} @@ -15113,7 +17067,7 @@ index 0000000..612fbbc + timer = &stm32_tim[HSI_CAL]; + timer->base.pa = dt_timer.reg; + timer->clk = dt_timer.clock; -+ timer->freq = stm32_clock_get_rate(timer->clk); ++ timer->freq = clk_get_rate(timer->clk); + timer->cal_input = fdt32_to_cpu(*cuint); + if (timer_config(timer)) { + timer->base.pa = 0; @@ -15126,7 +17080,7 @@ index 0000000..612fbbc + timer = &stm32_tim[CSI_CAL]; + timer->base.pa = dt_timer.reg; + timer->clk = dt_timer.clock; -+ timer->freq = stm32_clock_get_rate(timer->clk); ++ timer->freq = clk_get_rate(timer->clk); + timer->cal_input = fdt32_to_cpu(*cuint); + if (timer_config(timer)) { + timer->base.pa = 0; @@ -15166,10 +17120,10 @@ index 0000000..612fbbc +} +driver_init(init_stm32_tim); diff --git a/core/drivers/sub.mk b/core/drivers/sub.mk -index f9e03b5..2216b63 100644 +index 25d69eea8..0d3b81e21 100644 --- a/core/drivers/sub.mk +++ b/core/drivers/sub.mk -@@ -25,7 +25,10 @@ srcs-$(CFG_STM32_BSEC) += stm32_bsec.c +@@ -26,13 +26,17 @@ srcs-$(CFG_STM32_BSEC) += stm32_bsec.c srcs-$(CFG_STM32_ETZPC) += stm32_etzpc.c srcs-$(CFG_STM32_GPIO) += stm32_gpio.c srcs-$(CFG_STM32_I2C) += stm32_i2c.c @@ -15180,8 +17134,56 @@ index f9e03b5..2216b63 100644 srcs-$(CFG_STM32_UART) += stm32_uart.c srcs-$(CFG_STPMIC1) += stpmic1.c srcs-$(CFG_BCM_HWRNG) += bcm_hwrng.c + srcs-$(CFG_BCM_SOTP) += bcm_sotp.c + srcs-$(CFG_BCM_GPIO) += bcm_gpio.c + ++subdirs-y += clk + subdirs-y += crypto + subdirs-$(CFG_BNXT_FW) += bnxt + subdirs-$(CFG_SCMI_MSG_DRIVERS) += scmi-msg +diff --git a/core/include/drivers/clk.h b/core/include/drivers/clk.h +new file mode 100644 +index 000000000..8c0c44b34 +--- /dev/null ++++ b/core/include/drivers/clk.h +@@ -0,0 +1,35 @@ ++/* SPDX-License-Identifier: BSD-2-Clause */ ++/* ++ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#ifndef CLK_H ++#define CLK_H ++ ++#include ++#include ++ ++#define CLK_UNKNOWN_ID ULONG_MAX ++ ++/* ++ * Minimal generic clock framework where platform is expected implement a ++ * single clock provider and each individual clock identified with a unique ++ * unsigned long identifier. ++ */ ++struct clk_ops { ++ TEE_Result (*enable)(unsigned long id); ++ void (*disable)(unsigned long id); ++ unsigned long (*get_rate)(unsigned long id); ++ unsigned long (*get_parent)(unsigned long id); ++ bool (*is_enabled)(unsigned long id); ++}; ++ ++TEE_Result clk_enable(unsigned long id); ++void clk_disable(unsigned long id); ++unsigned long clk_get_rate(unsigned long id); ++bool clk_is_enabled(unsigned long id); ++unsigned long clk_get_parent(unsigned long id); ++ ++void clk_provider_register(const struct clk_ops *ops); ++ ++#endif /* CLK_H */ diff --git a/core/include/drivers/gic.h b/core/include/drivers/gic.h -index f9bb28e..c8da6d8 100644 +index f9bb28ec1..c8da6d849 100644 --- a/core/include/drivers/gic.h +++ b/core/include/drivers/gic.h @@ -9,17 +9,38 @@ @@ -15234,7 +17236,7 @@ index f9bb28e..c8da6d8 100644 void gic_cpu_init(struct gic_data *gd); diff --git a/core/include/drivers/stm32_bsec.h b/core/include/drivers/stm32_bsec.h -index dfb0d47..d284eea 100644 +index b6afbf8c4..9fe85bc98 100644 --- a/core/include/drivers/stm32_bsec.h +++ b/core/include/drivers/stm32_bsec.h @@ -10,6 +10,12 @@ @@ -15250,7 +17252,7 @@ index dfb0d47..d284eea 100644 /* * Load OTP from SAFMEM and provide its value * @value: Output read value -@@ -155,4 +161,14 @@ TEE_Result stm32_bsec_otp_lock(uint32_t service); +@@ -147,4 +153,14 @@ TEE_Result stm32_bsec_otp_lock(uint32_t service); */ bool stm32_bsec_nsec_can_access_otp(uint32_t otp_id); @@ -15267,7 +17269,7 @@ index dfb0d47..d284eea 100644 #endif /*__STM32_BSEC_H*/ diff --git a/core/include/drivers/stm32_iwdg.h b/core/include/drivers/stm32_iwdg.h new file mode 100644 -index 0000000..f063258 +index 000000000..f06325812 --- /dev/null +++ b/core/include/drivers/stm32_iwdg.h @@ -0,0 +1,17 @@ @@ -15290,7 +17292,7 @@ index 0000000..f063258 +#endif /*__STM32_IWDG_H__*/ diff --git a/core/include/drivers/stm32_rtc.h b/core/include/drivers/stm32_rtc.h new file mode 100644 -index 0000000..b0f4ef8 +index 000000000..b0f4ef858 --- /dev/null +++ b/core/include/drivers/stm32_rtc.h @@ -0,0 +1,60 @@ @@ -15356,7 +17358,7 @@ index 0000000..b0f4ef8 +#endif /* __PLAT_RTC_H__ */ diff --git a/core/include/drivers/stm32_tim.h b/core/include/drivers/stm32_tim.h new file mode 100644 -index 0000000..2373561 +index 000000000..2373561a3 --- /dev/null +++ b/core/include/drivers/stm32_tim.h @@ -0,0 +1,25 @@ @@ -15385,9 +17387,109 @@ index 0000000..2373561 + enum stm32_tim_cal type); + +#endif /* STM32_TIM_H */ +diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h b/core/include/drivers/stm32mp1_rcc.h +similarity index 95% +rename from core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h +rename to core/include/drivers/stm32mp1_rcc.h +index 4dedbad27..6c92257b6 100644 +--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.h ++++ b/core/include/drivers/stm32mp1_rcc.h +@@ -1,13 +1,11 @@ + /* SPDX-License-Identifier: BSD-3-Clause */ + /* +- * Copyright (c) 2017-2018, STMicroelectronics ++ * Copyright (c) 2017-2020, STMicroelectronics + */ + + #ifndef __STM32MP1_RCC_H__ + #define __STM32MP1_RCC_H__ + +-#include +-#include + #include + + #define RCC_TZCR 0x00 +@@ -392,7 +390,8 @@ + #define RCC_HSICFGR_HSITRIM_SHIFT 8 + #define RCC_HSICFGR_HSITRIM_MASK GENMASK_32(14, 8) + #define RCC_HSICFGR_HSICAL_SHIFT 16 +-#define RCC_HSICFGR_HSICAL_MASK GENMASK_32(27, 16) ++#define RCC_HSICFGR_HSICAL_MASK GENMASK_32(24, 16) ++#define RCC_HSICFGR_HSICAL_TEMP_MASK GENMASK_32(27, 25) + + /* Fields of RCC_CSICFGR register */ + #define RCC_CSICFGR_CSITRIM_SHIFT 8 +@@ -455,6 +454,9 @@ + #define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0) + #define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1) + ++/* Values of RCC_PWRLPDLYCR register */ ++#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK_32(21, 0) ++ + /* Global Control Register */ + #define RCC_MP_GCR_BOOT_MCU BIT(0) + +@@ -511,6 +513,9 @@ + #define RCC_AHB5RSTSETR_RNG1RST BIT(6) + #define RCC_AHB5RSTSETR_AXIMCRST BIT(16) + ++/* RCC_MP_AHB6RST(SET|CLR)R bit fields */ ++#define RCC_AHB6RSTSETR_GPURST BIT(5) ++ + /* RCC_MP_AHB5EN(SET|CLR)R bit fields */ + #define RCC_MP_AHB5ENSETR_GPIOZEN_POS 0 + #define RCC_MP_AHB5ENSETR_CRYP1EN_POS 4 +@@ -534,26 +539,43 @@ + #define RCC_MP_AHB5LPENSETR_BKPSRAMLPEN BIT(8) + + /* RCC_MP_TZAHB6EN(SET|CLR)R bit fields */ +-#define RCC_MP_TZAHB6ENSETR_MDMA_POS 0 +-#define RCC_MP_TZAHB6ENSETR_MDMA BIT(RCC_MP_TZAHB6ENSETR_MDMA_POS) ++#define RCC_MP_TZAHB6ENSETR_MDMA_POS 0 ++#define RCC_MP_TZAHB6ENSETR_MDMA \ ++ BIT(RCC_MP_TZAHB6ENSETR_MDMA_POS) + + /* RCC_MP_IWDGFZ(SET|CLR)R bit fields */ + #define RCC_MP_IWDGFZSETR_IWDG1 BIT(0) + #define RCC_MP_IWDGFZSETR_IWDG2 BIT(1) + + #define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc" ++#define DT_RCC_SEC_CLK_COMPAT "st,stm32mp1-rcc-secure" + + #ifndef __ASSEMBLER__ ++#include ++#include ++#include ++ + vaddr_t stm32_rcc_base(void); + + static inline bool stm32_rcc_is_secure(void) + { +- return io_read32(stm32_rcc_base() + RCC_TZCR) & RCC_TZCR_TZEN; ++ static int state = -1; ++ ++ if (state < 0) ++ state = io_read32(stm32_rcc_base() + RCC_TZCR) & RCC_TZCR_TZEN; ++ ++ return state; + } + + static inline bool stm32_rcc_is_mckprot(void) + { +- return io_read32(stm32_rcc_base() + RCC_TZCR) & RCC_TZCR_MCKPROT; ++ const uint32_t mask = RCC_TZCR_TZEN | RCC_TZCR_MCKPROT; ++ static int state = -1; ++ ++ if (state < 0) ++ state = (io_read32(stm32_rcc_base() + RCC_TZCR) & mask) == mask; ++ ++ return state; + } + #endif /*__ASSEMBLER__*/ + diff --git a/core/include/dt-bindings/clock/stm32mp1-clksrc.h b/core/include/dt-bindings/clock/stm32mp1-clksrc.h new file mode 100644 -index 0000000..de7d160 +index 000000000..de7d1604c --- /dev/null +++ b/core/include/dt-bindings/clock/stm32mp1-clksrc.h @@ -0,0 +1,284 @@ @@ -15677,7 +17779,7 @@ index 0000000..de7d160 +#endif diff --git a/core/include/dt-bindings/power/stm32mp1-power.h b/core/include/dt-bindings/power/stm32mp1-power.h new file mode 100644 -index 0000000..bfb7f78 +index 000000000..bfb7f785e --- /dev/null +++ b/core/include/dt-bindings/power/stm32mp1-power.h @@ -0,0 +1,19 @@ @@ -15700,21 +17802,28 @@ index 0000000..bfb7f78 +#define STM32_PM_MAX_SOC_MODE 7 + +#endif /* DT_BINDINGS_STM32MP1_POWER_H */ -diff --git a/core/include/dt-bindings/soc/st,stm32-etzpc.h b/core/include/dt-bindings/soc/st,stm32-etzpc.h -new file mode 100644 -index 0000000..6678b8e ---- /dev/null +diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_etzpc.h b/core/include/dt-bindings/soc/st,stm32-etzpc.h +similarity index 83% +rename from core/arch/arm/plat-stm32mp1/drivers/stm32mp1_etzpc.h +rename to core/include/dt-bindings/soc/st,stm32-etzpc.h +index 338a39283..6678b8e66 100644 +--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_etzpc.h +++ b/core/include/dt-bindings/soc/st,stm32-etzpc.h -@@ -0,0 +1,107 @@ -+/* +@@ -1,26 +1,35 @@ +-/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ + /* +- * Copyright (C) 2018-2019, STMicroelectronics + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause -+ */ -+ + */ + +-#ifndef __STM32MP1_ETZPC_H +-#define __STM32MP1_ETZPC_H +#ifndef _DT_BINDINGS_STM32_ETZPC_H +#define _DT_BINDINGS_STM32_ETZPC_H -+ + +-/* Define DECPROT IDs for stm32mp1 familly */ +/* define DECPROT modes */ +#define DECPROT_S_RW 0x0 +#define DECPROT_NS_R_S_W 0x1 @@ -15726,95 +17835,67 @@ index 0000000..6678b8e +#define DECPROT_LOCK 0x1 + +/* define ETZPC ID */ -+#define STM32MP1_ETZPC_STGENC_ID 0 -+#define STM32MP1_ETZPC_BKPSRAM_ID 1 -+#define STM32MP1_ETZPC_IWDG1_ID 2 -+#define STM32MP1_ETZPC_USART1_ID 3 -+#define STM32MP1_ETZPC_SPI6_ID 4 -+#define STM32MP1_ETZPC_I2C4_ID 5 -+#define STM32MP1_ETZPC_RNG1_ID 7 -+#define STM32MP1_ETZPC_HASH1_ID 8 -+#define STM32MP1_ETZPC_CRYP1_ID 9 -+#define STM32MP1_ETZPC_DDRCTRL_ID 10 -+#define STM32MP1_ETZPC_DDRPHYC_ID 11 -+#define STM32MP1_ETZPC_I2C6_ID 12 -+#define STM32MP1_ETZPC_TIM2_ID 16 -+#define STM32MP1_ETZPC_TIM3_ID 17 -+#define STM32MP1_ETZPC_TIM4_ID 18 -+#define STM32MP1_ETZPC_TIM5_ID 19 -+#define STM32MP1_ETZPC_TIM6_ID 20 -+#define STM32MP1_ETZPC_TIM7_ID 21 -+#define STM32MP1_ETZPC_TIM12_ID 22 -+#define STM32MP1_ETZPC_TIM13_ID 23 -+#define STM32MP1_ETZPC_TIM14_ID 24 -+#define STM32MP1_ETZPC_LPTIM1_ID 25 -+#define STM32MP1_ETZPC_WWDG1_ID 26 -+#define STM32MP1_ETZPC_SPI2_ID 27 -+#define STM32MP1_ETZPC_SPI3_ID 28 -+#define STM32MP1_ETZPC_SPDIFRX_ID 29 -+#define STM32MP1_ETZPC_USART2_ID 30 -+#define STM32MP1_ETZPC_USART3_ID 31 -+#define STM32MP1_ETZPC_UART4_ID 32 -+#define STM32MP1_ETZPC_UART5_ID 33 -+#define STM32MP1_ETZPC_I2C1_ID 34 -+#define STM32MP1_ETZPC_I2C2_ID 35 -+#define STM32MP1_ETZPC_I2C3_ID 36 -+#define STM32MP1_ETZPC_I2C5_ID 37 -+#define STM32MP1_ETZPC_CEC_ID 38 -+#define STM32MP1_ETZPC_DAC_ID 39 -+#define STM32MP1_ETZPC_UART7_ID 40 -+#define STM32MP1_ETZPC_UART8_ID 41 -+#define STM32MP1_ETZPC_MDIOS_ID 44 -+#define STM32MP1_ETZPC_TIM1_ID 48 -+#define STM32MP1_ETZPC_TIM8_ID 49 -+#define STM32MP1_ETZPC_USART6_ID 51 -+#define STM32MP1_ETZPC_SPI1_ID 52 -+#define STM32MP1_ETZPC_SPI4_ID 53 -+#define STM32MP1_ETZPC_TIM15_ID 54 -+#define STM32MP1_ETZPC_TIM16_ID 55 -+#define STM32MP1_ETZPC_TIM17_ID 56 -+#define STM32MP1_ETZPC_SPI5_ID 57 -+#define STM32MP1_ETZPC_SAI1_ID 58 -+#define STM32MP1_ETZPC_SAI2_ID 59 -+#define STM32MP1_ETZPC_SAI3_ID 60 -+#define STM32MP1_ETZPC_DFSDM_ID 61 -+#define STM32MP1_ETZPC_TT_FDCAN_ID 62 -+#define STM32MP1_ETZPC_LPTIM2_ID 64 -+#define STM32MP1_ETZPC_LPTIM3_ID 65 -+#define STM32MP1_ETZPC_LPTIM4_ID 66 -+#define STM32MP1_ETZPC_LPTIM5_ID 67 -+#define STM32MP1_ETZPC_SAI4_ID 68 -+#define STM32MP1_ETZPC_VREFBUF_ID 69 -+#define STM32MP1_ETZPC_DCMI_ID 70 -+#define STM32MP1_ETZPC_CRC2_ID 71 -+#define STM32MP1_ETZPC_ADC_ID 72 -+#define STM32MP1_ETZPC_HASH2_ID 73 -+#define STM32MP1_ETZPC_RNG2_ID 74 -+#define STM32MP1_ETZPC_CRYP2_ID 75 -+#define STM32MP1_ETZPC_SRAM1_ID 80 -+#define STM32MP1_ETZPC_SRAM2_ID 81 -+#define STM32MP1_ETZPC_SRAM3_ID 82 -+#define STM32MP1_ETZPC_SRAM4_ID 83 -+#define STM32MP1_ETZPC_RETRAM_ID 84 -+#define STM32MP1_ETZPC_OTG_ID 85 -+#define STM32MP1_ETZPC_SDMMC3_ID 86 -+#define STM32MP1_ETZPC_DLYBSD3_ID 87 -+#define STM32MP1_ETZPC_DMA1_ID 88 -+#define STM32MP1_ETZPC_DMA2_ID 89 -+#define STM32MP1_ETZPC_DMAMUX_ID 90 -+#define STM32MP1_ETZPC_FMC_ID 91 -+#define STM32MP1_ETZPC_QSPI_ID 92 -+#define STM32MP1_ETZPC_DLYBQ_ID 93 -+#define STM32MP1_ETZPC_ETH_ID 94 -+ -+#define STM32MP1_ETZPC_MAX_ID 96 + #define STM32MP1_ETZPC_STGENC_ID 0 + #define STM32MP1_ETZPC_BKPSRAM_ID 1 + #define STM32MP1_ETZPC_IWDG1_ID 2 + #define STM32MP1_ETZPC_USART1_ID 3 + #define STM32MP1_ETZPC_SPI6_ID 4 + #define STM32MP1_ETZPC_I2C4_ID 5 +-#define STM32MP1_ETZPC_GPIOZ_ID 6 + #define STM32MP1_ETZPC_RNG1_ID 7 + #define STM32MP1_ETZPC_HASH1_ID 8 + #define STM32MP1_ETZPC_CRYP1_ID 9 + #define STM32MP1_ETZPC_DDRCTRL_ID 10 + #define STM32MP1_ETZPC_DDRPHYC_ID 11 + #define STM32MP1_ETZPC_I2C6_ID 12 +-/* 13-15 Reserved */ + #define STM32MP1_ETZPC_TIM2_ID 16 + #define STM32MP1_ETZPC_TIM3_ID 17 + #define STM32MP1_ETZPC_TIM4_ID 18 +@@ -47,12 +56,9 @@ + #define STM32MP1_ETZPC_DAC_ID 39 + #define STM32MP1_ETZPC_UART7_ID 40 + #define STM32MP1_ETZPC_UART8_ID 41 +-/* 42-43 Reserved */ + #define STM32MP1_ETZPC_MDIOS_ID 44 +-/* 45-47 Reserved */ + #define STM32MP1_ETZPC_TIM1_ID 48 + #define STM32MP1_ETZPC_TIM8_ID 49 +-/* 50 Reserved */ + #define STM32MP1_ETZPC_USART6_ID 51 + #define STM32MP1_ETZPC_SPI1_ID 52 + #define STM32MP1_ETZPC_SPI4_ID 53 +@@ -65,7 +71,6 @@ + #define STM32MP1_ETZPC_SAI3_ID 60 + #define STM32MP1_ETZPC_DFSDM_ID 61 + #define STM32MP1_ETZPC_TT_FDCAN_ID 62 +-/* 63 Reserved */ + #define STM32MP1_ETZPC_LPTIM2_ID 64 + #define STM32MP1_ETZPC_LPTIM3_ID 65 + #define STM32MP1_ETZPC_LPTIM4_ID 66 +@@ -78,7 +83,6 @@ + #define STM32MP1_ETZPC_HASH2_ID 73 + #define STM32MP1_ETZPC_RNG2_ID 74 + #define STM32MP1_ETZPC_CRYP2_ID 75 +-/* 76-79 Reserved */ + #define STM32MP1_ETZPC_SRAM1_ID 80 + #define STM32MP1_ETZPC_SRAM2_ID 81 + #define STM32MP1_ETZPC_SRAM3_ID 82 +@@ -94,7 +98,10 @@ + #define STM32MP1_ETZPC_QSPI_ID 92 + #define STM32MP1_ETZPC_DLYBQ_ID 93 + #define STM32MP1_ETZPC_ETH_ID 94 +-/* 95 Reserved */ + + #define STM32MP1_ETZPC_MAX_ID 96 + +-#endif /*__STM32MP1_ETZPC_H*/ +#define DECPROT(id, mode, lock) (((id) << 16) | ((mode) << 8) | (lock)) + +#endif /* _DT_BINDINGS_STM32_ETZPC_H */ + diff --git a/core/include/kernel/interrupt.h b/core/include/kernel/interrupt.h -index 849e987..796eded 100644 +index 849e987f9..796eded29 100644 --- a/core/include/kernel/interrupt.h +++ b/core/include/kernel/interrupt.h @@ -25,6 +25,11 @@ struct itr_ops { @@ -15845,7 +17926,7 @@ index 849e987..796eded 100644 + #endif /*__KERNEL_INTERRUPT_H*/ diff --git a/core/include/kernel/panic.h b/core/include/kernel/panic.h -index b9a56dc..0f0d079 100644 +index b9a56dc2c..0f0d0794e 100644 --- a/core/include/kernel/panic.h +++ b/core/include/kernel/panic.h @@ -8,6 +8,12 @@ @@ -15862,7 +17943,7 @@ index b9a56dc..0f0d079 100644 #if defined(CFG_TEE_CORE_DEBUG) #define __panic(str) __do_panic(__FILE__, __LINE__, __func__, str) diff --git a/core/kernel/interrupt.c b/core/kernel/interrupt.c -index 961ce6b..3760125 100644 +index 961ce6be3..376012556 100644 --- a/core/kernel/interrupt.c +++ b/core/kernel/interrupt.c @@ -88,3 +88,13 @@ void __weak __noreturn itr_core_handler(void) @@ -15880,13 +17961,13 @@ index 961ce6b..3760125 100644 + return itr_chip->ops->set_ipriority(itr_chip, it, mask); +} diff --git a/core/kernel/panic.c b/core/kernel/panic.c -index 37e30a8..460ef90 100644 +index f30c6ffe7..023f4be5d 100644 --- a/core/kernel/panic.c +++ b/core/kernel/panic.c -@@ -6,8 +6,21 @@ - +@@ -7,8 +7,21 @@ #include #include + #include +#include #include @@ -15905,7 +17986,7 @@ index 37e30a8..460ef90 100644 void __do_panic(const char *file __maybe_unused, const int line __maybe_unused, const char *func __maybe_unused, -@@ -16,8 +29,6 @@ void __do_panic(const char *file __maybe_unused, +@@ -17,8 +30,6 @@ void __do_panic(const char *file __maybe_unused, /* disable prehemption */ (void)thread_mask_exceptions(THREAD_EXCP_ALL); @@ -15914,10 +17995,10 @@ index 37e30a8..460ef90 100644 /* trace: Panic ['panic-string-message' ]at FILE:LINE []" */ if (!file && !func && !msg) EMSG_RAW("Panic"); -@@ -28,7 +39,9 @@ void __do_panic(const char *file __maybe_unused, +@@ -29,7 +40,9 @@ void __do_panic(const char *file __maybe_unused, func ? "<" : "", func ? func : "", func ? ">" : ""); - EPRINT_STACK(); + print_kernel_stack(); - /* abort current execution */ - while (1) - ; @@ -15927,19 +18008,3248 @@ index 37e30a8..460ef90 100644 + EMSG("platform failed to abord execution"); + stall_cpu(); } +diff --git a/core/mm/vm.c b/core/mm/vm.c +index 27ffa18af..95080a700 100644 +--- a/core/mm/vm.c ++++ b/core/mm/vm.c +@@ -162,14 +162,26 @@ static TEE_Result alloc_pgt(struct user_mode_ctx *uctx) + return TEE_SUCCESS; + } + +-static void maybe_free_pgt(struct user_mode_ctx *uctx, struct vm_region *r) ++static void rem_um_region(struct user_mode_ctx *uctx, struct vm_region *r) + { +- struct thread_specific_data *tsd = NULL; ++ struct thread_specific_data *tsd = thread_get_tsd(); + struct pgt_cache *pgt_cache = NULL; + vaddr_t begin = ROUNDDOWN(r->va, CORE_MMU_PGDIR_SIZE); + vaddr_t last = ROUNDUP(r->va + r->size, CORE_MMU_PGDIR_SIZE); + struct vm_region *r2 = NULL; + ++ if (uctx->ts_ctx == tsd->ctx) ++ pgt_cache = &tsd->pgt_cache; ++ ++ if (mobj_is_paged(r->mobj)) { ++ tee_pager_rem_um_region(uctx, r->va, r->size); ++ } else { ++ pgt_clear_ctx_range(pgt_cache, uctx->ts_ctx, r->va, ++ r->va + r->size); ++ tlbi_mva_range_asid(r->va, r->size, SMALL_PAGE_SIZE, ++ uctx->vm_info.asid); ++ } ++ + r2 = TAILQ_NEXT(r, link); + if (r2) + last = MIN(last, ROUNDDOWN(r2->va, CORE_MMU_PGDIR_SIZE)); +@@ -183,10 +195,6 @@ static void maybe_free_pgt(struct user_mode_ctx *uctx, struct vm_region *r) + if (begin >= last) + return; + +- tsd = thread_get_tsd(); +- if (uctx->ts_ctx == tsd->ctx) +- pgt_cache = &tsd->pgt_cache; +- + pgt_flush_ctx_range(pgt_cache, uctx->ts_ctx, r->va, r->va + r->size); + } + +@@ -539,9 +547,7 @@ TEE_Result vm_remap(struct user_mode_ctx *uctx, vaddr_t *new_va, vaddr_t old_va, + if (r->va + r->size > old_va + len) + break; + r_next = TAILQ_NEXT(r, link); +- if (fobj) +- tee_pager_rem_um_region(uctx, r->va, r->size); +- maybe_free_pgt(uctx, r); ++ rem_um_region(uctx, r); + TAILQ_REMOVE(&uctx->vm_info.regions, r, link); + TAILQ_INSERT_TAIL(®s, r, link); + } +@@ -774,21 +780,13 @@ TEE_Result vm_unmap(struct user_mode_ctx *uctx, vaddr_t va, size_t len) + while (true) { + r_next = TAILQ_NEXT(r, link); + unmap_end_va = r->va + r->size; +- if (mobj_is_paged(r->mobj)) +- tee_pager_rem_um_region(uctx, r->va, r->size); +- maybe_free_pgt(uctx, r); ++ rem_um_region(uctx, r); + umap_remove_region(&uctx->vm_info, r); + if (!r_next || unmap_end_va == end_va) + break; + r = r_next; + } + +- /* +- * Synchronize change to translation tables. Even though the pager +- * case unmaps immediately we may still free a translation table. +- */ +- vm_set_ctx(uctx->ts_ctx); +- + return TEE_SUCCESS; + } + +@@ -843,9 +841,7 @@ void vm_clean_param(struct user_mode_ctx *uctx) + + TAILQ_FOREACH_SAFE(r, &uctx->vm_info.regions, link, next_r) { + if (r->flags & VM_FLAG_EPHEMERAL) { +- if (mobj_is_paged(r->mobj)) +- tee_pager_rem_um_region(uctx, r->va, r->size); +- maybe_free_pgt(uctx, r); ++ rem_um_region(uctx, r); + umap_remove_region(&uctx->vm_info, r); + } + } +@@ -1055,9 +1051,7 @@ void vm_rem_rwmem(struct user_mode_ctx *uctx, struct mobj *mobj, vaddr_t va) + + TAILQ_FOREACH(r, &uctx->vm_info.regions, link) { + if (r->mobj == mobj && r->va == va) { +- if (mobj_is_paged(r->mobj)) +- tee_pager_rem_um_region(uctx, r->va, r->size); +- maybe_free_pgt(uctx, r); ++ rem_um_region(uctx, r); + umap_remove_region(&uctx->vm_info, r); + return; + } +diff --git a/core/sub.mk b/core/sub.mk +index 5a17cd923..faaf21c74 100644 +--- a/core/sub.mk ++++ b/core/sub.mk +@@ -20,13 +20,16 @@ recipe-ldelf = $(PYTHON3) scripts/gen_ldelf_hex.py --input $(out-dir)/ldelf/ldel + endif + + ifeq ($(CFG_WITH_USER_TA)-$(CFG_EARLY_TA),y-y) ++ifeq ($(CFG_EARLY_TA_COMPRESS),y) ++early-ta-compress = --compress ++endif + define process_early_ta + early-ta-$1-uuid := $(firstword $(subst ., ,$(notdir $1))) + gensrcs-y += early-ta-$1 + produce-early-ta-$1 = early_ta_$$(early-ta-$1-uuid).c + depends-early-ta-$1 = $1 scripts/ts_bin_to_c.py +-recipe-early-ta-$1 = $(PYTHON3) scripts/ts_bin_to_c.py --compress --ta $1 \ +- --out $(sub-dir-out)/early_ta_$$(early-ta-$1-uuid).c ++recipe-early-ta-$1 = $(PYTHON3) scripts/ts_bin_to_c.py $(early-ta-compress) \ ++ --ta $1 --out $(sub-dir-out)/early_ta_$$(early-ta-$1-uuid).c + endef + $(foreach f, $(EARLY_TA_PATHS), $(eval $(call process_early_ta,$(f)))) + $(foreach f, $(CFG_IN_TREE_EARLY_TAS), $(eval $(call \ +diff --git a/keys/default_rproc.pem b/keys/default_rproc.pem +new file mode 100644 +index 000000000..d54476f35 +--- /dev/null ++++ b/keys/default_rproc.pem +@@ -0,0 +1,27 @@ ++-----BEGIN RSA PRIVATE KEY----- ++MIIEpAIBAAKCAQEA1TD3AMwyJhzsliOhEStPrCrgnG9Gy8z+OCtialVngW/rkqQB ++cb/oOdiMPjfLoSio8zaUA86mTHo6DINZIopTZvs9pysnpvrOwbjCVRXTcIhgM/YZ ++GyN9c+Qo5fCbOlCsxD0PG40hP4O0dktWyzmWQfjy0+9BDAyMoW59lPeYZcJAKSWT ++M10V5h3JTabA4dqVroeztuTow3ftNImNuzMFYDqGDUcJy0EdluRsBfhOOKXE7ZaQ ++RXnwY9CTCGqgsuNKwE1g8evkseaLcJk4/JpVFOgZp4fUgsxU6EBRD2i+C+Jq9KXg ++qBcK0QwXNr2IwG3i76QmLzGGkpW7bKPn/QhGMQIDAQABAoIBAQCHBnAqzSmmAgPG ++Q+KroSbhAHcqHUBVrAwHP1Mhzd20mVI2mjFf/g/zMzf/4A7Uj5ASGqs8jhG9tlw1 ++uKsnuTyBqPavfiGrHIb/IynSAfTc/UMRJflYuu2mDQfqOq3WDWqfD50V8hjwxVXy ++5lyecma8ehQyLwKfwwL+66AWTYr0Rx+OdXkGdGj1SXbJU39nv7UH8ZggpICFhUXO ++r7NgJr2UOyhEje4stTGSb86SrvxHRm07JG1WSOJ2GV0EBhWNqbRtsnvH1NKNm03m ++yM+zMbqvtdg1Wkfcfxtx6h7MGHhUUIHwotDoKgZ1lz1EdVWk8clmlKCLFEBxcwIp ++sdbrodnBAoGBAPFQ1J7B+3eDBJjgrEFu9soygrjulhiA2+3qrra95RyuIE0wE8CO ++DPjAGHOnxAoUt8H+TEGF2Wo2HVQauz2ElPOlIxQctr3w2Xpi1DibKEdooQLRlaSS ++LHWAxTLZj9EI3NuYhdRvFHUW2ExEqCADOKY4+1xRSXuIbIkaLMaah8R9AoGBAOIq ++BEiqoaQM/EA4z+m7RuOjc1PtA0qo9DJIEb4Mj92gEGzSHCdNN+eDCKbqyd8BGo/w ++Pf6N8+dotjYvzlz3MqwfV1aczvQqbfkivzahO7GlK2KmwwLG3Vm8dZAZCZKEglOg ++ex6h/L8gOgqSP+C4OmdEU4jdA24BSHr+1ZArHPrFAoGBAL27l/DbBCSLVun8fHNW ++E6QW4sEUld7eMg12H7h+xc0u+ya1TlJvXbOXFaKZnYFvmKtmjf5WhwMDWTvvaJiN ++za9jf5kommXtIJEhc0quc5TxpubYcpfadipM/L9mX7UzCrN90Hueeq81LwuIT8gb ++wEaxNrD3GJeQRAXoFpxwk57hAoGAaeqLfwyKDq4WJG120VtnY4xUomVJOVnOow2l ++YX+4kG45wvzTOoSrPbzb/G/QgqOdsPMt1VzdcO5VByN0XY1XKcyztlhRg3+raRWg ++vxDbR+K2Ysj+YvqHB1N/KzDOjtOHxWpOvpXWLBwHkpPTXoZos5wIEvyOcqIfM5rM ++oWvPcpECgYBCtncnPQQJfYcFebw3+rzm9OodF/s6G9afOrzqgEk/0Z6mi20x1c23 ++dzcZUpLl9p7fCFg0iz9NwLUYR9tZ/4zy+J4ZET7PduxoLG3m1TVzxSJM+dU+GtQi ++fBcdQuC6od9K9MJD2egwmes/I+aWhrIAatrG2iMtrOTG5N0mUMUc+w== ++-----END RSA PRIVATE KEY----- +diff --git a/lib/libutee/include/remoteproc_pta.h b/lib/libutee/include/remoteproc_pta.h +new file mode 100644 +index 000000000..cede192eb +--- /dev/null ++++ b/lib/libutee/include/remoteproc_pta.h +@@ -0,0 +1,157 @@ ++/* SPDX-License-Identifier: BSD-2-Clause */ ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#ifndef __REMOTEPROC_PTA_H ++#define __REMOTEPROC_PTA_H ++ ++#include ++ ++/* ++ * Interface to the pseudo TA which provides platform implementation ++ * of the remote processor management ++ */ ++ ++#define PTA_REMOTEPROC_UUID { 0x54af4a68, 0x19be, 0x40d7, \ ++ { 0xbb, 0xe6, 0x89, 0x50, 0x35, 0x0a, 0x87, 0x44 } } ++ ++/* Firmware format */ ++#define PTA_REMOTEPROC_PROPRIETARY_FMT BIT32(0) ++#define PTA_REMOTEPROC_ELF_FMT BIT32(1) ++ ++/* Firmware image protection */ ++/* The platorm supports copy of the input firmware image in secure memory */ ++#define PTA_REMOTEPROC_FW_SECURE_COPY BIT32(0) ++/* The platorm supports load of segment with hash protection */ ++#define PTA_REMOTEPROC_FW_WITH_HASH_TABLE BIT32(1) ++/* The platorm is able to change access to secure the firmware input image */ ++#define PTA_REMOTEPROC_FW_MEMORY_PROTECTION BIT32(2) ++ ++/** ++ * struct rproc_pta_key_info - public key information ++ * @algo: Algorithm, defined by public key algorithms TEE_ALG_* ++ * from TEE Internal API specification ++ * @info_size: Byte size of the @info ++ * @info: Append key information data ++ */ ++struct rproc_pta_key_info { ++ uint32_t algo; ++ uint32_t info_size; ++ char info[]; ++}; ++ ++static inline size_t ++ rproc_pta_get_keyinfo_size(struct rproc_pta_key_info *keyinf) ++{ ++ size_t s = 0; ++ ++ if (!keyinf || ADD_OVERFLOW(sizeof(*keyinf), keyinf->info_size, &s)) ++ return 0; ++ ++ return s; ++} ++ ++#define RPROC_PTA_GET_KEYINFO_SIZE(x) rproc_pta_get_keyinfo_size((x)) ++ ++/* ++ * Platform capabilities. ++ * ++ * Get Platform firmware loader service capabilities. ++ * ++ * [in] params[0].value.a: Unique 32bit firmware identifier ++ * [out] params[1].value.a: Firmware format (PTA_REMOTEPROC_*_FMT) ++ * [out] params[2].value.a: Image protection method (PTA_REMOTEPROC_FW_*) ++ */ ++#define PTA_REMOTEPROC_HW_CAPABILITIES 1 ++ ++/* ++ * Firmware loading. ++ * ++ * Optional service to implement only in case of proprietary format. ++ * ++ * [in] params[0].value.a: Unique 32bit firmware identifier ++ * [in] params[1].memref: Loadable firmware image ++ */ ++#define PTA_REMOTEPROC_FIRMWARE_LOAD 2 ++ ++/* ++ * Load a segment with a SHA256 hash. ++ * ++ * This command is used when the platform secure memory is too expensive to ++ * save the whole firmware image in secure memory. Upon segment load, a ++ * successful completion ensures the loaded image complies with the provided ++ * hash. ++ * ++ * [in] params[0].value.a: Unique 32bit firmware identifier ++ * [in] params[1].memref: Section data to load ++ * [in] params[2].value.a: 32bit LSB load device segment address ++ * [in] params[2].value.b: 32bit MSB load device segment address ++ * [in] params[3].memref: Expected hash (SHA256) of the payload ++ */ ++#define PTA_REMOTEPROC_LOAD_SEGMENT_SHA256 3 ++ ++/* ++ * Memory set. ++ * ++ * Fill a remote device memory with requested value. this is use for instance ++ * to clear a memory on the remote firmware load. ++ * ++ * [in] params[0].value.a: Unique 32bit firmware identifier ++ * [in] params[1].value.a: 32bit LSB device memory address ++ * [in] params[1].value.b: 32bit MSB device memory address ++ * [in] params[2].value.a: 32bit LSB device memory size ++ * [in] params[2].value.b: 32bit MSB device memory size ++ * [in] params[3].value.a: Byte value to be set ++ */ ++#define PTA_REMOTEPROC_SET_MEMORY 4 ++ ++/* ++ * Firmware start. ++ * ++ * Start up a successfully remote processor firmware. ++ * ++ * [in] params[0].value.a: Unique 32bit firmware identifier ++ */ ++#define PTA_REMOTEPROC_FIRMWARE_START 5 ++ ++/* ++ * Firmware stop. ++ * ++ * Stop of the remote processor firmware and release/clean resources. ++ * After the command successful completion, remote processor firmware must be ++ * reloaded prior being started again. ++ * ++ * [in] params[0].value.a: Unique 32bit firmware identifier ++ */ ++#define PTA_REMOTEPROC_FIRMWARE_STOP 6 ++ ++/* ++ * Firmware device to physical address conversion. ++ * ++ * Return the physical address corresponding to an address got from the ++ * firmware address layout. ++ * ++ * [in] params[0].value.a: Unique 32bit firmware identifier ++ * [in] params[1].value.a: 32bit LSB Device memory address ++ * [in] params[1].value.b: 32bit MSB Device memory address ++ * [in] params[2].value.a: 32bit LSB Device memory size ++ * [in] params[2].value.b: 32bit MSB Device memory size ++ * [out] params[3].value.a: 32bit LSB converted physical address ++ * [out] params[3].value.b: 32bit MSB converted physical address ++ */ ++#define PTA_REMOTEPROC_FIRMWARE_DA_TO_PA 7 ++ ++/* ++ * Verify the firmware digest against a signature ++ * ++ * Return TEE_SUCCESS if the signature is verified, else an error ++ * ++ * [in] params[0].value.a: Unique 32bit firmware identifier ++ * [in] params[1].memref: Key information (refer to @rproc_pta_key_info) ++ * [in] params[2].memref: Digest of the firmware authenticated data ++ * [in] params[3].memref: Signature of the firmware authenticated data ++ */ ++#define PTA_REMOTEPROC_VERIFY_DIGEST 8 ++ ++#endif /* __REMOTEPROC_PTA_H */ diff --git a/mk/config.mk b/mk/config.mk -index c00a146..bc49f83 100644 +index 72f13fba4..a14c4f832 100644 --- a/mk/config.mk +++ b/mk/config.mk -@@ -116,7 +116,7 @@ endif - # with limited depth not including any tag, so there is really no guarantee - # that TEE_IMPL_VERSION contains the major and minor revision numbers. - CFG_OPTEE_REVISION_MAJOR ?= 3 --CFG_OPTEE_REVISION_MINOR ?= 8 -+CFG_OPTEE_REVISION_MINOR ?= 9 +@@ -306,6 +306,9 @@ $(eval $(call cfg-depends-all,CFG_REE_FS_TA_BUFFERED,CFG_REE_FS_TA)) + # in-tree TAs. CFG_IN_TREE_EARLY_TAS is formatted as: + # / + # for instance avb/023f8f1a-292a-432b-8fc4-de8471358067 ++# ++# By default the early TAs are compressed in the TEE binary, it is possible to ++# not compress them with CFG_EARLY_TA_COMPRESS=n + ifneq ($(EARLY_TA_PATHS)$(CFG_IN_TREE_EARLY_TAS),) + $(call force,CFG_EARLY_TA,y) + $(call force,CFG_EMBEDDED_TS,y) +@@ -323,6 +326,7 @@ endif + ifeq ($(CFG_EMBEDDED_TS),y) + $(call force,CFG_ZLIB,y) + endif ++CFG_EARLY_TA_COMPRESS ?= y - # Trusted OS implementation manufacturer name - CFG_TEE_MANUFACTURER ?= LINARO + # Enable paging, requires SRAM, can't be enabled by default + CFG_WITH_PAGER ?= n +diff --git a/mk/gcc.mk b/mk/gcc.mk +index adc77a24f..81bfa78ad 100644 +--- a/mk/gcc.mk ++++ b/mk/gcc.mk +@@ -13,11 +13,11 @@ nostdinc$(sm) := -nostdinc -isystem $(shell $(CC$(sm)) \ + -print-file-name=include 2> /dev/null) + + # Get location of libgcc from gcc +-libgcc$(sm) := $(shell $(CC$(sm)) $(CFLAGS$(arch-bits-$(sm))) \ ++libgcc$(sm) := $(shell $(CC$(sm)) $(LIBGCC_LOCATE_CFLAGS) $(CFLAGS$(arch-bits-$(sm))) \ + -print-libgcc-file-name 2> /dev/null) +-libstdc++$(sm) := $(shell $(CXX$(sm)) $(CXXFLAGS$(arch-bits-$(sm))) $(comp-cxxflags$(sm)) \ ++libstdc++$(sm) := $(shell $(CXX$(sm)) $(LIBGCC_LOCATE_CFLAGS) $(CXXFLAGS$(arch-bits-$(sm))) $(comp-cxxflags$(sm)) \ + -print-file-name=libstdc++.a 2> /dev/null) +-libgcc_eh$(sm) := $(shell $(CXX$(sm)) $(CXXFLAGS$(arch-bits-$(sm))) $(comp-cxxflags$(sm)) \ ++libgcc_eh$(sm) := $(shell $(CXX$(sm)) $(LIBGCC_LOCATE_CFLAGS) $(CXXFLAGS$(arch-bits-$(sm))) $(comp-cxxflags$(sm)) \ + -print-file-name=libgcc_eh.a 2> /dev/null) + + # Define these to something to discover accidental use +diff --git a/scripts/sign_rproc_fw.py b/scripts/sign_rproc_fw.py +new file mode 100755 +index 000000000..4248ed280 +--- /dev/null ++++ b/scripts/sign_rproc_fw.py +@@ -0,0 +1,416 @@ ++#!/usr/bin/env python3 ++# SPDX-License-Identifier: BSD-2-Clause ++# ++# Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++# ++ ++try: ++ from elftools.elf.elffile import ELFFile ++ from elftools.elf.sections import SymbolTableSection ++ from elftools.elf.enums import ENUM_P_TYPE_BASE ++ from elftools.elf.enums import * ++except ImportError: ++ print(""" ++*** ++ERROR: pyelftools python module is not installed or version < 0.25. ++*** ++""") ++ raise ++ ++from Cryptodome.Hash import SHA256 ++from Cryptodome.Signature import pkcs1_15 ++from Cryptodome.PublicKey import RSA ++from Cryptodome.Signature import DSS ++from Cryptodome.PublicKey import ECC ++import os ++import sys ++import struct ++import logging ++import binascii ++ ++ ++logging.basicConfig(stream=sys.stderr, level=logging.INFO) ++ ++ENUM_HASH_TYPE = dict( ++ SHA256=1, ++) ++ ++ENUM_SIGNATURE_TYPE = dict( ++ RSA=1, ++ ECC=2, ++) ++ ++ENUM_BINARY_TYPE = dict( ++ ELF=1, ++) ++ ++ ++def dump_buffer(buf, step=16, name="", logger=logging.info, indent=""): ++ logger("%s%s:" % (indent, name)) ++ for i in range(0, len(buf), step): ++ logger("%s " % (indent) + " ". ++ join(["%02X" % c for c in buf[i:i+step]])) ++ logger("\n") ++ ++ ++class RSA_Signature(object): ++ ++ def __init__(self, key): ++ self._hasher = SHA256.new() ++ self.signer = pkcs1_15.new(key) ++ ++ def hash_compute(self, segment): ++ self._hasher.update(segment) ++ ++ def sign(self): ++ return self.signer.sign(self._hasher) ++ ++ ++class ECC_Signature(object): ++ ++ def __init__(self, key): ++ self._hasher = SHA256.new() ++ self.signer = DSS.new(key, 'fips-186-3') ++ ++ def hash_compute(self, segment): ++ self._hasher.update(segment) ++ ++ def sign(self): ++ return self.signer.sign(self._hasher) ++ ++ ++Signature = { ++ 1: RSA_Signature, ++ 2: ECC_Signature, ++} ++ ++ ++class SegmentHashStruct: ++ pass ++ ++ ++class SegmentHash(object): ++ ''' ++ Hash table based on Elf program segments ++ ''' ++ def __init__(self, img): ++ self._num_segments = img.num_segments() ++ self._pack_fmt = '<%dL' % 8 ++ self.img = img ++ self.hashProgTable = bytes() ++ self._offset = 0 ++ ++ def get_table(self): ++ ''' ++ Create a segment hash table containing for each segment: ++ - the segments header ++ - a hash of the segment ++ ''' ++ h = SHA256.new() ++ seg = SegmentHashStruct() ++ self.size = (h.digest_size + 32) * self._num_segments ++ logging.debug("hash section size %d" % self.size) ++ del h ++ self.buf = bytearray(self.size) ++ self._bufview_ = memoryview(self.buf) ++ ++ for i in range(self._num_segments): ++ h = SHA256.new() ++ segment = self.img.get_segment(i) ++ seg.header = self.img.get_segment(i).header ++ logging.debug("compute hash for segment offset %s" % seg.header) ++ h.update(segment.data()) ++ seg.hash = h.digest() ++ logging.debug("hash computed: %s" % seg.hash) ++ del h ++ struct.pack_into('.sig') ++ ++ parsed = parser.parse_args() ++ ++ # Set defaults for optional arguments. ++ ++ if parsed.outf is None: ++ parsed.outf = str(parsed.inf)+'.sig' ++ ++ return parsed ++ ++ ++def rsa_key(keyf): ++ return RSA.importKey(open(keyf).read()) ++ ++ ++def ecc_key(keyf): ++ return ECC.import_key(open(keyf).read()) ++ ++ ++key_type = { ++ 1: rsa_key, ++ 2: ecc_key, ++} ++ ++ ++def rsa_sig_size(key): ++ return key.size_in_bytes() ++ ++ ++def ecc_sig_size(key): ++ # to be improve... ++ # DSA size is N/4 so 64 for DSA (L,N) = (2048, 256) ++ return 64 ++ ++ ++sig_size_type = { ++ 1: rsa_sig_size, ++ 2: ecc_sig_size, ++} ++ ++ ++def main(): ++ from Cryptodome.Signature import pss ++ from Cryptodome.Hash import SHA256 ++ from Cryptodome.PublicKey import RSA ++ import base64 ++ import logging ++ import struct ++ ++ logging.basicConfig() ++ logger = logging.getLogger(os.path.basename(__file__)) ++ ++ args = get_args(logger) ++ ++ # Initialise the header */ ++ s_header = ImageHeader() ++ ++ get_key = key_type.get(ENUM_SIGNATURE_TYPE[args.key_type], ++ lambda: "Invalid sign type") ++ key = get_key(args.keyf) ++ ++ if not key.has_private(): ++ logger.error('Provided key cannot be used for signing, ' + ++ 'please use offline-signing mode.') ++ sys.exit(1) ++ ++ # Firmware image ++ input_file = open(args.inf, 'rb') ++ img = ELFFile(input_file) ++ ++ # need to reopen the file to get the raw data ++ with open(args.inf, 'rb') as f: ++ bin_img = f.read() ++ img_size = len(bin_img) ++ logging.debug("image size %d" % img_size) ++ s_header.img_length = img_size ++ s_header.img_type = ENUM_BINARY_TYPE['ELF'] ++ ++ # Hash table chunk ++ h = SHA256.new() ++ ++ # Compute the hash table ++ hash_table = SegmentHash(img) ++ hash = hash_table.get_table() ++ ++ s_header.hash_offset = s_header.size ++ s_header.hash_length = hash_table.size ++ s_header.hash_type = ENUM_HASH_TYPE['SHA256'] ++ # Get padding to align on 64 bytes ++ hash_align = s_header.hash_length % 8 ++ ++ # Key information chunk ++ if args.key_infof: ++ with open(args.key_infof, 'rb') as f: ++ key_info = f.read() ++ s_header.key_length = sys.getsizeof(key_info) ++ s_header.key_offset = s_header.hash_offset + s_header.hash_length + \ ++ hash_align ++ # Get padding to align on 64 bytes ++ key_info_align = s_header.key_length % 8 ++ else: ++ key_info_align = 0 ++ ++ # Signature chunk ++ s_header.sign_type = ENUM_SIGNATURE_TYPE[args.key_type] ++ ++ sign_size = sig_size_type.get(ENUM_SIGNATURE_TYPE[args.key_type], ++ lambda: "Invalid sign type")(key) ++ s_header.sign_length = sign_size ++ ++ if args.key_infof: ++ s_header.sign_offset = s_header.key_offset + s_header.key_length + \ ++ key_info_align ++ else: ++ s_header.sign_offset = s_header.hash_offset + s_header.hash_length + \ ++ hash_align ++ ++ s_header.img_offset = s_header.sign_offset + sign_size ++ ++ s_header.length = s_header.size + s_header.hash_length + hash_align + \ ++ s_header.key_length + key_info_align + s_header.sign_length ++ ++ header = s_header.get_packed() ++ ++ # Generate signature ++ signer = Signature.get(ENUM_SIGNATURE_TYPE[args.key_type])(key) ++ ++ signer.hash_compute(header) ++ signer.hash_compute(bytes(hash)) ++ if args.key_infof: ++ signer.hash_compute(key_info) ++ ++ signature = signer.sign() ++ if len(signature) != sign_size: ++ raise Exception(("Actual signature length is not equal to ", ++ "the computed one: {} != {}". ++ format(len(signature), sign_size))) ++ ++ s_header.dump() ++ ++ with open(args.outf, 'wb') as f: ++ f.write(header) ++ f.write(hash) ++ if hash_align: ++ f.write(bytearray(hash_align)) ++ if args.key_infof: ++ if key_info_align: ++ f.write(key_info) ++ f.write(bytearray(key_info_align)) ++ f.write(signature) ++ f.write(bytearray(sign_size - s_header.sign_length)) ++ f.write(bin_img) ++ ++ ++if __name__ == "__main__": ++ main() +diff --git a/ta/remoteproc/Makefile b/ta/remoteproc/Makefile +new file mode 100644 +index 000000000..0d1a5010c +--- /dev/null ++++ b/ta/remoteproc/Makefile +@@ -0,0 +1,18 @@ ++# The UUID for the Trusted Application ++BINARY=80a4c275-0a47-4905-8285-1486a9771a08 ++ ++ifdef TA_CROSS_COMPILE ++CROSS_COMPILE ?= $(TA_CROSS_COMPILE) ++endif ++export CROSS_COMPILE ++ ++CFG_TEE_TA_LOG_LEVEL ?= 2 ++CPPFLAGS += -DCFG_TEE_TA_LOG_LEVEL=$(CFG_TEE_TA_LOG_LEVEL) ++ ++-include $(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk ++ ++ifeq ($(wildcard $(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk), ) ++clean: ++ @echo 'Note: $$(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk not found, cannot clean TA' ++ @echo 'Note: TA_DEV_KIT_DIR=$(TA_DEV_KIT_DIR)' ++endif +diff --git a/ta/remoteproc/elf_parser.c b/ta/remoteproc/elf_parser.c +new file mode 100644 +index 000000000..da3e6f4ae +--- /dev/null ++++ b/ta/remoteproc/elf_parser.c +@@ -0,0 +1,186 @@ ++ // SPDX-License-Identifier: BSD-2-Clause ++ /* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static bool va_in_fwm_image_range(void *va, uint8_t *fw, size_t fw_size) ++{ ++ uint8_t *vaddr = va; ++ ++ assert(fw + fw_size >= fw); ++ return vaddr >= fw && vaddr < fw + fw_size; ++} ++ ++/* ++ * e32_parse_ehdr() - Check and parse the ELF header ++ * ++ * fw: Firmware ELF file image ++ * size: Byte size of firmware ELF file image ++ */ ++TEE_Result e32_parse_ehdr(uint8_t *fw, size_t size) ++{ ++ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(void *)fw; ++ ++ if (!fw || !ALIGNMENT_IS_OK(fw, uint32_t)) { ++ EMSG("Invalid fw address %p", fw); ++ return TEE_ERROR_BAD_PARAMETERS; ++ } ++ ++ if (size < sizeof(Elf32_Ehdr) || ++ size < (ehdr->e_shoff + sizeof(Elf32_Shdr))) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ if (!IS_ELF(*ehdr) || ++ ehdr->e_ident[EI_VERSION] != EV_CURRENT || ++ ehdr->e_ident[EI_CLASS] != ELFCLASS32 || ++ ehdr->e_phentsize != sizeof(Elf32_Phdr) || ++ ehdr->e_shentsize != sizeof(Elf32_Shdr)) { ++ EMSG("Invalid header"); ++ ++ return TEE_ERROR_BAD_FORMAT; ++ } ++ ++ if (ehdr->e_phnum == 0) { ++ EMSG("No loadable segment found"); ++ return TEE_ERROR_BAD_FORMAT; ++ } ++ ++ return TEE_SUCCESS; ++} ++ ++/* ++ * e32_parser_load_elf_image - simple ELF loader ++ * fw: Firmware ELF file image ++ * fw_size: Firmware ELF file image byte size ++ * load_seg: Callback for loading a firmware image segment into device memory ++ * priv_data: Private data passed to @load_seg callback. ++ */ ++TEE_Result e32_parser_load_elf_image(uint8_t *fw, size_t fw_size, ++ TEE_Result (*load_seg)(uint8_t *src, ++ uint32_t size, ++ uint32_t da, ++ uint32_t mem_size, ++ void *priv), ++ void *priv_data) ++{ ++ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(void *)fw; ++ Elf32_Phdr *phdr = (void *)((int8_t *)ehdr + ehdr->e_phoff); ++ TEE_Result res = TEE_SUCCESS; ++ unsigned int i = 0; ++ ++ if (!load_seg) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ if (!ALIGNMENT_IS_OK(phdr, uint32_t) || ++ !va_in_fwm_image_range(phdr, fw, fw_size)) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ for (i = 0; i < ehdr->e_phnum; i++, phdr++) { ++ uint32_t dst = phdr->p_paddr; ++ uint8_t *src = NULL; ++ ++ if (!va_in_fwm_image_range((void *)((vaddr_t)(phdr + 1) - 1), ++ fw, fw_size)) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ if (phdr->p_type != PT_LOAD) ++ continue; ++ ++ src = (uint8_t *)fw + phdr->p_offset; ++ ++ if (!va_in_fwm_image_range(src, fw, fw_size) || ++ !va_in_fwm_image_range(src + phdr->p_filesz, fw, fw_size)) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ res = load_seg(src, phdr->p_filesz, dst, phdr->p_memsz, ++ priv_data); ++ if (res) ++ return res; ++ } ++ ++ return TEE_SUCCESS; ++} ++ ++/* Helper to find resource table in an ELF image */ ++int e32_parser_find_rsc_table(uint8_t *fw, size_t fw_size, ++ Elf32_Addr *rsc_addr, Elf32_Word *rsc_size) ++{ ++ Elf32_Shdr *shdr = NULL; ++ int i = 0; ++ char *name_table = NULL; ++ struct resource_table *table = NULL; ++ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(void *)fw; ++ uint8_t *elf_data = fw; ++ ++ shdr = (void *)(fw + ehdr->e_shoff); ++ if (!ALIGNMENT_IS_OK(shdr, uint32_t) || ++ !va_in_fwm_image_range(shdr, fw, fw_size)) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ name_table = (char *)elf_data + shdr[ehdr->e_shstrndx].sh_offset; ++ if (!va_in_fwm_image_range(name_table, fw, fw_size)) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ for (i = 0; i < ehdr->e_shnum; i++, shdr++) { ++ size_t size = shdr->sh_size; ++ size_t offset = shdr->sh_offset; ++ ++ if (!va_in_fwm_image_range(shdr, fw, fw_size)) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ if (strcmp(name_table + shdr->sh_name, ".resource_table")) ++ continue; ++ ++ if (!shdr->sh_size) { ++ IMSG("Ignore empty resource table section"); ++ return TEE_ERROR_NO_DATA; ++ } ++ ++ if (offset + size > fw_size || offset + size < size) { ++ EMSG("Resource table truncated"); ++ return TEE_ERROR_BAD_FORMAT; ++ } ++ ++ if (sizeof(struct resource_table) > size) { ++ EMSG("No header found in resource table"); ++ return TEE_ERROR_BAD_FORMAT; ++ } ++ ++ table = (struct resource_table *)(void *)(elf_data + offset); ++ if (!ALIGNMENT_IS_OK(table, uint32_t)) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ if (table->ver != 1) { ++ EMSG("Unsupported fw version %"PRId32, table->ver); ++ return TEE_ERROR_BAD_FORMAT; ++ } ++ ++ if (table->reserved[0] || table->reserved[1]) { ++ EMSG("Non zero reserved bytes"); ++ return TEE_ERROR_BAD_FORMAT; ++ } ++ ++ if (table->num * sizeof(*table->offset) + ++ sizeof(struct resource_table) > size) { ++ EMSG("Resource table incomplete"); ++ return TEE_ERROR_BAD_FORMAT; ++ } ++ ++ DMSG("Resource table address %#"PRIx32", size %"PRIu32, ++ shdr->sh_addr, shdr->sh_size); ++ ++ *rsc_addr = shdr->sh_addr; ++ *rsc_size = shdr->sh_size; ++ ++ return TEE_SUCCESS; ++ } ++ ++ return TEE_ERROR_NO_DATA; ++} +diff --git a/ta/remoteproc/include/elf32.h b/ta/remoteproc/include/elf32.h +new file mode 100644 +index 000000000..2806c615d +--- /dev/null ++++ b/ta/remoteproc/include/elf32.h +@@ -0,0 +1,243 @@ ++/* SPDX-License-Identifier: BSD-2-Clause */ ++/*- ++ * Copyright (c) 1996-1998 John D. Polstra. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * $FreeBSD$ ++ */ ++ ++#ifndef _SYS_ELF32_H_ ++#define _SYS_ELF32_H_ 1 ++ ++#include ++#include ++ ++/* ++ * ELF definitions common to all 32-bit architectures. ++ */ ++ ++typedef uint32_t Elf32_Addr; ++typedef uint16_t Elf32_Half; ++typedef uint32_t Elf32_Off; ++typedef int32_t Elf32_Sword; ++typedef uint32_t Elf32_Word; ++typedef uint64_t Elf32_Lword; ++ ++typedef Elf32_Word Elf32_Hashelt; ++ ++/* Non-standard class-dependent datatype used for abstraction. */ ++typedef Elf32_Word Elf32_Size; ++typedef Elf32_Sword Elf32_Ssize; ++ ++/* ++ * ELF header. ++ */ ++ ++typedef struct { ++ unsigned char e_ident[EI_NIDENT]; /* File identification. */ ++ Elf32_Half e_type; /* File type. */ ++ Elf32_Half e_machine; /* Machine architecture. */ ++ Elf32_Word e_version; /* ELF format version. */ ++ Elf32_Addr e_entry; /* Entry point. */ ++ Elf32_Off e_phoff; /* Program header file offset. */ ++ Elf32_Off e_shoff; /* Section header file offset. */ ++ Elf32_Word e_flags; /* Architecture-specific flags. */ ++ Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ ++ Elf32_Half e_phentsize; /* Size of program header entry. */ ++ Elf32_Half e_phnum; /* Number of program header entries. */ ++ Elf32_Half e_shentsize; /* Size of section header entry. */ ++ Elf32_Half e_shnum; /* Number of section header entries. */ ++ Elf32_Half e_shstrndx; /* Section name strings section. */ ++} Elf32_Ehdr; ++ ++/* ++ * Section header. ++ */ ++ ++typedef struct { ++ Elf32_Word sh_name; /* Section name (index into the ++ section header string table). */ ++ Elf32_Word sh_type; /* Section type. */ ++ Elf32_Word sh_flags; /* Section flags. */ ++ Elf32_Addr sh_addr; /* Address in memory image. */ ++ Elf32_Off sh_offset; /* Offset in file. */ ++ Elf32_Word sh_size; /* Size in bytes. */ ++ Elf32_Word sh_link; /* Index of a related section. */ ++ Elf32_Word sh_info; /* Depends on section type. */ ++ Elf32_Word sh_addralign; /* Alignment in bytes. */ ++ Elf32_Word sh_entsize; /* Size of each entry in section. */ ++} Elf32_Shdr; ++ ++/* ++ * Program header. ++ */ ++ ++typedef struct { ++ Elf32_Word p_type; /* Entry type. */ ++ Elf32_Off p_offset; /* File offset of contents. */ ++ Elf32_Addr p_vaddr; /* Virtual address in memory image. */ ++ Elf32_Addr p_paddr; /* Physical address (not used). */ ++ Elf32_Word p_filesz; /* Size of contents in file. */ ++ Elf32_Word p_memsz; /* Size of contents in memory. */ ++ Elf32_Word p_flags; /* Access permission flags. */ ++ Elf32_Word p_align; /* Alignment in memory and file. */ ++} Elf32_Phdr; ++ ++/* ++ * Dynamic structure. The ".dynamic" section contains an array of them. ++ */ ++ ++typedef struct { ++ Elf32_Sword d_tag; /* Entry type. */ ++ union { ++ Elf32_Word d_val; /* Integer value. */ ++ Elf32_Addr d_ptr; /* Address value. */ ++ } d_un; ++} Elf32_Dyn; ++ ++/* ++ * Relocation entries. ++ */ ++ ++/* Relocations that don't need an addend field. */ ++typedef struct { ++ Elf32_Addr r_offset; /* Location to be relocated. */ ++ Elf32_Word r_info; /* Relocation type and symbol index. */ ++} Elf32_Rel; ++ ++/* Relocations that need an addend field. */ ++typedef struct { ++ Elf32_Addr r_offset; /* Location to be relocated. */ ++ Elf32_Word r_info; /* Relocation type and symbol index. */ ++ Elf32_Sword r_addend; /* Addend. */ ++} Elf32_Rela; ++ ++/* Macros for accessing the fields of r_info. */ ++#define ELF32_R_SYM(info) ((info) >> 8) ++#define ELF32_R_TYPE(info) ((unsigned char)(info)) ++ ++/* Macro for constructing r_info from field values. */ ++#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) ++ ++/* ++ * Note entry header ++ */ ++typedef Elf_Note Elf32_Nhdr; ++ ++/* ++ * Move entry ++ */ ++typedef struct { ++ Elf32_Lword m_value; /* symbol value */ ++ Elf32_Word m_info; /* size + index */ ++ Elf32_Word m_poffset; /* symbol offset */ ++ Elf32_Half m_repeat; /* repeat count */ ++ Elf32_Half m_stride; /* stride info */ ++} Elf32_Move; ++ ++/* ++ * The macros compose and decompose values for Move.r_info ++ * ++ * sym = ELF32_M_SYM(M.m_info) ++ * size = ELF32_M_SIZE(M.m_info) ++ * M.m_info = ELF32_M_INFO(sym, size) ++ */ ++#define ELF32_M_SYM(info) ((info)>>8) ++#define ELF32_M_SIZE(info) ((unsigned char)(info)) ++#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) ++ ++/* ++ * Hardware/Software capabilities entry ++ */ ++typedef struct { ++ Elf32_Word c_tag; /* how to interpret value */ ++ union { ++ Elf32_Word c_val; ++ Elf32_Addr c_ptr; ++ } c_un; ++} Elf32_Cap; ++ ++/* ++ * Symbol table entries. ++ */ ++ ++typedef struct { ++ Elf32_Word st_name; /* String table index of name. */ ++ Elf32_Addr st_value; /* Symbol value. */ ++ Elf32_Word st_size; /* Size of associated object. */ ++ unsigned char st_info; /* Type and binding information. */ ++ unsigned char st_other; /* Reserved (not used). */ ++ Elf32_Half st_shndx; /* Section index of symbol. */ ++} Elf32_Sym; ++ ++/* Macros for accessing the fields of st_info. */ ++#define ELF32_ST_BIND(info) ((info) >> 4) ++#define ELF32_ST_TYPE(info) ((info) & 0xf) ++ ++/* Macro for constructing st_info from field values. */ ++#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) ++ ++/* Macro for accessing the fields of st_other. */ ++#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3) ++ ++/* Structures used by Sun & GNU symbol versioning. */ ++typedef struct { ++ Elf32_Half vd_version; ++ Elf32_Half vd_flags; ++ Elf32_Half vd_ndx; ++ Elf32_Half vd_cnt; ++ Elf32_Word vd_hash; ++ Elf32_Word vd_aux; ++ Elf32_Word vd_next; ++} Elf32_Verdef; ++ ++typedef struct { ++ Elf32_Word vda_name; ++ Elf32_Word vda_next; ++} Elf32_Verdaux; ++ ++typedef struct { ++ Elf32_Half vn_version; ++ Elf32_Half vn_cnt; ++ Elf32_Word vn_file; ++ Elf32_Word vn_aux; ++ Elf32_Word vn_next; ++} Elf32_Verneed; ++ ++typedef struct { ++ Elf32_Word vna_hash; ++ Elf32_Half vna_flags; ++ Elf32_Half vna_other; ++ Elf32_Word vna_name; ++ Elf32_Word vna_next; ++} Elf32_Vernaux; ++ ++typedef Elf32_Half Elf32_Versym; ++ ++typedef struct { ++ Elf32_Half si_boundto; /* direct bindings - symbol bound to */ ++ Elf32_Half si_flags; /* per symbol flags */ ++} Elf32_Syminfo; ++ ++#endif /* !_SYS_ELF32_H_ */ +diff --git a/ta/remoteproc/include/elf_common.h b/ta/remoteproc/include/elf_common.h +new file mode 100644 +index 000000000..a1da0ef80 +--- /dev/null ++++ b/ta/remoteproc/include/elf_common.h +@@ -0,0 +1,1014 @@ ++/* SPDX-License-Identifier: BSD-2-Clause */ ++/*- ++ * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien ++ * Copyright (c) 1998 John D. Polstra. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * $FreeBSD$ ++ */ ++ ++#ifndef _SYS_ELF_COMMON_H_ ++#define _SYS_ELF_COMMON_H_ 1 ++ ++#include ++ ++/* ++ * ELF definitions that are independent of architecture or word size. ++ */ ++ ++#ifndef __ASSEMBLER__ ++/* ++ * Note header. The ".note" section contains an array of notes. Each ++ * begins with this header, aligned to a word boundary. Immediately ++ * following the note header is n_namesz bytes of name, padded to the ++ * next word boundary. Then comes n_descsz bytes of descriptor, again ++ * padded to a word boundary. The values of n_namesz and n_descsz do ++ * not include the padding. ++ */ ++ ++typedef struct { ++ uint32_t n_namesz; /* Length of name. */ ++ uint32_t n_descsz; /* Length of descriptor. */ ++ uint32_t n_type; /* Type of this note. */ ++} Elf_Note; ++ ++/* ++ * The header for GNU-style hash sections. ++ */ ++ ++typedef struct { ++ uint32_t gh_nbuckets; /* Number of hash buckets. */ ++ uint32_t gh_symndx; /* First visible symbol in .dynsym. */ ++ uint32_t gh_maskwords; /* #maskwords used in bloom filter. */ ++ uint32_t gh_shift2; /* Bloom filter shift count. */ ++} Elf_GNU_Hash_Header; ++#endif /*__ASSEMBLER__*/ ++ ++/* Indexes into the e_ident array. Keep synced with ++ http://www.sco.com/developers/gabi/latest/ch4.eheader.html */ ++#define EI_MAG0 0 /* Magic number, byte 0. */ ++#define EI_MAG1 1 /* Magic number, byte 1. */ ++#define EI_MAG2 2 /* Magic number, byte 2. */ ++#define EI_MAG3 3 /* Magic number, byte 3. */ ++#define EI_CLASS 4 /* Class of machine. */ ++#define EI_DATA 5 /* Data format. */ ++#define EI_VERSION 6 /* ELF format version. */ ++#define EI_OSABI 7 /* Operating system / ABI identification */ ++#define EI_ABIVERSION 8 /* ABI version */ ++#define OLD_EI_BRAND 8 /* Start of architecture identification. */ ++#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ ++#define EI_NIDENT 16 /* Size of e_ident array. */ ++ ++/* Values for the magic number bytes. */ ++#define ELFMAG0 0x7f ++#define ELFMAG1 'E' ++#define ELFMAG2 'L' ++#define ELFMAG3 'F' ++#define ELFMAG "\177ELF" /* magic string */ ++#define SELFMAG 4 /* magic string size */ ++ ++/* Values for e_ident[EI_VERSION] and e_version. */ ++#define EV_NONE 0 ++#define EV_CURRENT 1 ++ ++/* Values for e_ident[EI_CLASS]. */ ++#define ELFCLASSNONE 0 /* Unknown class. */ ++#define ELFCLASS32 1 /* 32-bit architecture. */ ++#define ELFCLASS64 2 /* 64-bit architecture. */ ++ ++/* Values for e_ident[EI_DATA]. */ ++#define ELFDATANONE 0 /* Unknown data format. */ ++#define ELFDATA2LSB 1 /* 2's complement little-endian. */ ++#define ELFDATA2MSB 2 /* 2's complement big-endian. */ ++ ++/* Values for e_ident[EI_OSABI]. */ ++#define ELFOSABI_NONE 0 /* UNIX System V ABI */ ++#define ELFOSABI_HPUX 1 /* HP-UX operating system */ ++#define ELFOSABI_NETBSD 2 /* NetBSD */ ++#define ELFOSABI_LINUX 3 /* GNU/Linux */ ++#define ELFOSABI_HURD 4 /* GNU/Hurd */ ++#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ ++#define ELFOSABI_SOLARIS 6 /* Solaris */ ++#define ELFOSABI_AIX 7 /* AIX */ ++#define ELFOSABI_IRIX 8 /* IRIX */ ++#define ELFOSABI_FREEBSD 9 /* FreeBSD */ ++#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ ++#define ELFOSABI_MODESTO 11 /* Novell Modesto */ ++#define ELFOSABI_OPENBSD 12 /* OpenBSD */ ++#define ELFOSABI_OPENVMS 13 /* Open VMS */ ++#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ ++#define ELFOSABI_AROS 15 /* Amiga Research OS */ ++#define ELFOSABI_ARM 97 /* ARM */ ++#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ ++ ++#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */ ++#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */ ++ ++/* e_ident */ ++#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ ++ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ ++ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ ++ (ehdr).e_ident[EI_MAG3] == ELFMAG3) ++ ++/* Values for e_type. */ ++#define ET_NONE 0 /* Unknown type. */ ++#define ET_REL 1 /* Relocatable. */ ++#define ET_EXEC 2 /* Executable. */ ++#define ET_DYN 3 /* Shared object. */ ++#define ET_CORE 4 /* Core file. */ ++#define ET_LOOS 0xfe00 /* First operating system specific. */ ++#define ET_HIOS 0xfeff /* Last operating system-specific. */ ++#define ET_LOPROC 0xff00 /* First processor-specific. */ ++#define ET_HIPROC 0xffff /* Last processor-specific. */ ++ ++/* Values for e_machine. */ ++#define EM_NONE 0 /* Unknown machine. */ ++#define EM_M32 1 /* AT&T WE32100. */ ++#define EM_SPARC 2 /* Sun SPARC. */ ++#define EM_386 3 /* Intel i386. */ ++#define EM_68K 4 /* Motorola 68000. */ ++#define EM_88K 5 /* Motorola 88000. */ ++#define EM_860 7 /* Intel i860. */ ++#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */ ++#define EM_S370 9 /* IBM System/370. */ ++#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */ ++#define EM_PARISC 15 /* HP PA-RISC. */ ++#define EM_VPP500 17 /* Fujitsu VPP500. */ ++#define EM_SPARC32PLUS 18 /* SPARC v8plus. */ ++#define EM_960 19 /* Intel 80960. */ ++#define EM_PPC 20 /* PowerPC 32-bit. */ ++#define EM_PPC64 21 /* PowerPC 64-bit. */ ++#define EM_S390 22 /* IBM System/390. */ ++#define EM_V800 36 /* NEC V800. */ ++#define EM_FR20 37 /* Fujitsu FR20. */ ++#define EM_RH32 38 /* TRW RH-32. */ ++#define EM_RCE 39 /* Motorola RCE. */ ++#define EM_ARM 40 /* ARM. */ ++#define EM_SH 42 /* Hitachi SH. */ ++#define EM_SPARCV9 43 /* SPARC v9 64-bit. */ ++#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */ ++#define EM_ARC 45 /* Argonaut RISC Core. */ ++#define EM_H8_300 46 /* Hitachi H8/300. */ ++#define EM_H8_300H 47 /* Hitachi H8/300H. */ ++#define EM_H8S 48 /* Hitachi H8S. */ ++#define EM_H8_500 49 /* Hitachi H8/500. */ ++#define EM_IA_64 50 /* Intel IA-64 Processor. */ ++#define EM_MIPS_X 51 /* Stanford MIPS-X. */ ++#define EM_COLDFIRE 52 /* Motorola ColdFire. */ ++#define EM_68HC12 53 /* Motorola M68HC12. */ ++#define EM_MMA 54 /* Fujitsu MMA. */ ++#define EM_PCP 55 /* Siemens PCP. */ ++#define EM_NCPU 56 /* Sony nCPU. */ ++#define EM_NDR1 57 /* Denso NDR1 microprocessor. */ ++#define EM_STARCORE 58 /* Motorola Star*Core processor. */ ++#define EM_ME16 59 /* Toyota ME16 processor. */ ++#define EM_ST100 60 /* STMicroelectronics ST100 processor. */ ++#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */ ++#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ ++#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */ ++#define EM_PDSP 63 /* Sony DSP Processor. */ ++#define EM_FX66 66 /* Siemens FX66 microcontroller. */ ++#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 ++ microcontroller. */ ++#define EM_ST7 68 /* STmicroelectronics ST7 8-bit ++ microcontroller. */ ++#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller. */ ++#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller. */ ++#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller. */ ++#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller. */ ++#define EM_SVX 73 /* Silicon Graphics SVx. */ ++#define EM_ST19 74 /* STMicroelectronics ST19 8-bit mc. */ ++#define EM_VAX 75 /* Digital VAX. */ ++#define EM_CRIS 76 /* Axis Communications 32-bit embedded ++ processor. */ ++#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded ++ processor. */ ++#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor. */ ++#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor. */ ++#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc. */ ++#define EM_HUANY 81 /* Harvard University machine-independent ++ object files. */ ++#define EM_PRISM 82 /* SiTera Prism. */ ++#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller. */ ++#define EM_FR30 84 /* Fujitsu FR30. */ ++#define EM_D10V 85 /* Mitsubishi D10V. */ ++#define EM_D30V 86 /* Mitsubishi D30V. */ ++#define EM_V850 87 /* NEC v850. */ ++#define EM_M32R 88 /* Mitsubishi M32R. */ ++#define EM_MN10300 89 /* Matsushita MN10300. */ ++#define EM_MN10200 90 /* Matsushita MN10200. */ ++#define EM_PJ 91 /* picoJava. */ ++#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor. */ ++#define EM_ARC_A5 93 /* ARC Cores Tangent-A5. */ ++#define EM_XTENSA 94 /* Tensilica Xtensa Architecture. */ ++#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor. */ ++#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose ++ Processor. */ ++#define EM_NS32K 97 /* National Semiconductor 32000 series. */ ++#define EM_TPC 98 /* Tenor Network TPC processor. */ ++#define EM_SNP1K 99 /* Trebia SNP 1000 processor. */ ++#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller. */ ++#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family. */ ++#define EM_MAX 102 /* MAX Processor. */ ++#define EM_CR 103 /* National Semiconductor CompactRISC ++ microprocessor. */ ++#define EM_F2MC16 104 /* Fujitsu F2MC16. */ ++#define EM_MSP430 105 /* Texas Instruments embedded microcontroller ++ msp430. */ ++#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor. */ ++#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors. */ ++#define EM_SEP 108 /* Sharp embedded microprocessor. */ ++#define EM_ARCA 109 /* Arca RISC Microprocessor. */ ++#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd. ++ and MPRC of Peking University */ ++#define EM_AARCH64 183 /* AArch64 (64-bit ARM) */ ++ ++/* Non-standard or deprecated. */ ++#define EM_486 6 /* Intel i486. */ ++#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ ++#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */ ++#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */ ++ ++/* e_flags for EM_ARM */ ++#define EF_ARM_ABI_VERSION 0x05000000 /* ABI version 5 */ ++#define EF_ARM_ABIMASK 0xFF000000 ++#define EF_ARM_BE8 0x00800000 ++#define EF_ARM_ABI_FLOAT_HARD 0x00000400 /* ABI version 5 and later */ ++#define EF_ARM_ABI_FLOAT_SOFT 0x00000200 /* ABI version 5 and later */ ++ ++/* Special section indexes. */ ++#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ ++#define SHN_LORESERVE 0xff00 /* First of reserved range. */ ++#define SHN_LOPROC 0xff00 /* First processor-specific. */ ++#define SHN_HIPROC 0xff1f /* Last processor-specific. */ ++#define SHN_LOOS 0xff20 /* First operating system-specific. */ ++#define SHN_HIOS 0xff3f /* Last operating system-specific. */ ++#define SHN_ABS 0xfff1 /* Absolute values. */ ++#define SHN_COMMON 0xfff2 /* Common data. */ ++#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */ ++#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ ++ ++/* sh_type */ ++#define SHT_NULL 0 /* inactive */ ++#define SHT_PROGBITS 1 /* program defined information */ ++#define SHT_SYMTAB 2 /* symbol table section */ ++#define SHT_STRTAB 3 /* string table section */ ++#define SHT_RELA 4 /* relocation section with addends */ ++#define SHT_HASH 5 /* symbol hash table section */ ++#define SHT_DYNAMIC 6 /* dynamic section */ ++#define SHT_NOTE 7 /* note section */ ++#define SHT_NOBITS 8 /* no space section */ ++#define SHT_REL 9 /* relocation section - no addends */ ++#define SHT_SHLIB 10 /* reserved - purpose unknown */ ++#define SHT_DYNSYM 11 /* dynamic symbol table section */ ++#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */ ++#define SHT_FINI_ARRAY 15 /* Termination function pointers. */ ++#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */ ++#define SHT_GROUP 17 /* Section group. */ ++#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */ ++#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ ++#define SHT_LOSUNW 0x6ffffff4 ++#define SHT_SUNW_dof 0x6ffffff4 ++#define SHT_SUNW_cap 0x6ffffff5 ++#define SHT_SUNW_SIGNATURE 0x6ffffff6 ++#define SHT_GNU_HASH 0x6ffffff6 ++#define SHT_GNU_LIBLIST 0x6ffffff7 ++#define SHT_SUNW_ANNOTATE 0x6ffffff7 ++#define SHT_SUNW_DEBUGSTR 0x6ffffff8 ++#define SHT_SUNW_DEBUG 0x6ffffff9 ++#define SHT_SUNW_move 0x6ffffffa ++#define SHT_SUNW_COMDAT 0x6ffffffb ++#define SHT_SUNW_syminfo 0x6ffffffc ++#define SHT_SUNW_verdef 0x6ffffffd ++#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */ ++#define SHT_SUNW_verneed 0x6ffffffe ++#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */ ++#define SHT_SUNW_versym 0x6fffffff ++#define SHT_GNU_versym 0x6fffffff /* Symbol version table */ ++#define SHT_HISUNW 0x6fffffff ++#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ ++#define SHT_LOPROC 0x70000000 /* reserved range for processor */ ++#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */ ++#define SHT_ARM_EXIDX 0x70000001 /* Exception index table. */ ++#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking ++ pre-emption map. */ ++#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility ++ attributes. */ ++#define SHT_ARM_DEBUGOVERLAY 0x70000004 /* See DBGOVL for details. */ ++#define SHT_ARM_OVERLAYSECTION 0x70000005 /* See DBGOVL for details. */ ++#define SHT_MIPS_REGINFO 0x70000006 ++#define SHT_MIPS_OPTIONS 0x7000000d ++#define SHT_MIPS_DWARF 0x7000001e /* MIPS gcc uses MIPS_DWARF */ ++#define SHT_HIPROC 0x7fffffff /* specific section header types */ ++#define SHT_LOUSER 0x80000000 /* reserved range for application */ ++#define SHT_HIUSER 0xffffffff /* specific indexes */ ++ ++/* Flags for sh_flags. */ ++#define SHF_WRITE 0x1 /* Section contains writable data. */ ++#define SHF_ALLOC 0x2 /* Section occupies memory. */ ++#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ ++#define SHF_MERGE 0x10 /* Section may be merged. */ ++#define SHF_STRINGS 0x20 /* Section contains strings. */ ++#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */ ++#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */ ++#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */ ++#define SHF_GROUP 0x200 /* Member of section group. */ ++#define SHF_TLS 0x400 /* Section contains TLS data. */ ++#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */ ++#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */ ++ ++/* Values for p_type. */ ++#define PT_NULL 0 /* Unused entry. */ ++#define PT_LOAD 1 /* Loadable segment. */ ++#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ ++#define PT_INTERP 3 /* Pathname of interpreter. */ ++#define PT_NOTE 4 /* Auxiliary information. */ ++#define PT_SHLIB 5 /* Reserved (not used). */ ++#define PT_PHDR 6 /* Location of program header itself. */ ++#define PT_TLS 7 /* Thread local storage segment */ ++#define PT_LOOS 0x60000000 /* First OS-specific. */ ++#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */ ++#define PT_GNU_EH_FRAME 0x6474e550 ++#define PT_GNU_STACK 0x6474e551 ++#define PT_GNU_RELRO 0x6474e552 ++#define PT_LOSUNW 0x6ffffffa ++#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ ++#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */ ++#define PT_SUNWDTRACE 0x6ffffffc /* private */ ++#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */ ++#define PT_HISUNW 0x6fffffff ++#define PT_HIOS 0x6fffffff /* Last OS-specific. */ ++#define PT_LOPROC 0x70000000 /* First processor-specific type. */ ++#define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */ ++#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ ++ ++/* Values for p_flags. */ ++#define PF_X 0x1 /* Executable. */ ++#define PF_W 0x2 /* Writable. */ ++#define PF_R 0x4 /* Readable. */ ++#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */ ++#define PF_MASKPROC 0xf0000000 /* Processor-specific. */ ++ ++/* Extended program header index. */ ++#define PN_XNUM 0xffff ++ ++/* Values for d_tag. */ ++#define DT_NULL 0 /* Terminating entry. */ ++#define DT_NEEDED 1 /* String table offset of a needed shared ++ library. */ ++#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ ++#define DT_PLTGOT 3 /* Processor-dependent address. */ ++#define DT_HASH 4 /* Address of symbol hash table. */ ++#define DT_STRTAB 5 /* Address of string table. */ ++#define DT_SYMTAB 6 /* Address of symbol table. */ ++#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ ++#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ ++#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ ++#define DT_STRSZ 10 /* Size of string table. */ ++#define DT_SYMENT 11 /* Size of each symbol table entry. */ ++#define DT_INIT 12 /* Address of initialization function. */ ++#define DT_FINI 13 /* Address of finalization function. */ ++#define DT_SONAME 14 /* String table offset of shared object ++ name. */ ++#define DT_RPATH 15 /* String table offset of library path. [sup] */ ++#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ ++#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ ++#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ ++#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ ++#define DT_PLTREL 20 /* Type of relocation used for PLT. */ ++#define DT_DEBUG 21 /* Reserved (not used). */ ++#define DT_TEXTREL 22 /* Indicates there may be relocations in ++ non-writable segments. [sup] */ ++#define DT_JMPREL 23 /* Address of PLT relocations. */ ++#define DT_BIND_NOW 24 /* [sup] */ ++#define DT_INIT_ARRAY 25 /* Address of the array of pointers to ++ initialization functions */ ++#define DT_FINI_ARRAY 26 /* Address of the array of pointers to ++ termination functions */ ++#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of ++ initialization functions. */ ++#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of ++ termination functions. */ ++#define DT_RUNPATH 29 /* String table offset of a null-terminated ++ library search path string. */ ++#define DT_FLAGS 30 /* Object specific flag values. */ ++#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING ++ and less than DT_LOOS follow the rules for ++ the interpretation of the d_un union ++ as follows: even == 'd_ptr', odd == 'd_val' ++ or none */ ++#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to ++ pre-initialization functions. */ ++#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of ++ pre-initialization functions. */ ++#define DT_MAXPOSTAGS 34 /* number of positive tags */ ++#define DT_LOOS 0x6000000d /* First OS-specific */ ++#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */ ++#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */ ++#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */ ++#define DT_SUNW_CAP 0x60000010 /* hardware/software */ ++#define DT_HIOS 0x6ffff000 /* Last OS-specific */ ++ ++/* ++ * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the ++ * Dyn.d_un.d_val field of the Elf*_Dyn structure. ++ */ ++#define DT_VALRNGLO 0x6ffffd00 ++#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */ ++#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */ ++#define DT_MOVEENT 0x6ffffdfa /* move table entry size */ ++#define DT_MOVESZ 0x6ffffdfb /* move table size */ ++#define DT_FEATURE_1 0x6ffffdfc /* feature holder */ ++#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */ ++ /* the following DT_* entry. */ ++ /* See DF_P1_* definitions */ ++#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */ ++#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */ ++#define DT_VALRNGHI 0x6ffffdff ++ ++/* ++ * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the ++ * Dyn.d_un.d_ptr field of the Elf*_Dyn structure. ++ * ++ * If any adjustment is made to the ELF object after it has been ++ * built, these entries will need to be adjusted. ++ */ ++#define DT_ADDRRNGLO 0x6ffffe00 ++#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table */ ++#define DT_CONFIG 0x6ffffefa /* configuration information */ ++#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */ ++#define DT_AUDIT 0x6ffffefc /* object auditing */ ++#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */ ++#define DT_MOVETAB 0x6ffffefe /* move table */ ++#define DT_SYMINFO 0x6ffffeff /* syminfo table */ ++#define DT_ADDRRNGHI 0x6ffffeff ++ ++#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */ ++#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */ ++#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */ ++#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */ ++#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */ ++#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */ ++#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */ ++#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */ ++ ++#define DT_LOPROC 0x70000000 /* First processor-specific type. */ ++#define DT_DEPRECATED_SPARC_REGISTER 0x7000001 ++#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */ ++#define DT_USED 0x7ffffffe /* ignored - same as needed */ ++#define DT_FILTER 0x7fffffff /* shared library filter name */ ++#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ ++ ++/* Values for DT_FLAGS */ ++#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may ++ make reference to the $ORIGIN substitution ++ string */ ++#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ ++#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in ++ non-writable segments. */ ++#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should ++ process all relocations for the object ++ containing this entry before transferring ++ control to the program. */ ++#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or ++ executable contains code using a static ++ thread-local storage scheme. */ ++ ++/* Values for DT_FLAGS_1 */ ++#define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */ ++#define DF_1_GLOBAL 0x00000002 /* Set the RTLD_GLOBAL for object */ ++#define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */ ++#define DF_1_LOADFLTR 0x00000010 /* Immediate loading of filtees */ ++#define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */ ++#define DF_1_ORIGIN 0x00000080 /* Process $ORIGIN */ ++#define DF_1_INTERPOSE 0x00000400 /* Interpose all objects but main */ ++#define DF_1_NODEFLIB 0x00000800 /* Do not search default paths */ ++ ++/* Values for n_type. Used in core files. */ ++#define NT_PRSTATUS 1 /* Process status. */ ++#define NT_FPREGSET 2 /* Floating point registers. */ ++#define NT_PRPSINFO 3 /* Process state info. */ ++#define NT_THRMISC 7 /* Thread miscellaneous info. */ ++#define NT_PROCSTAT_PROC 8 /* Procstat proc data. */ ++#define NT_PROCSTAT_FILES 9 /* Procstat files data. */ ++#define NT_PROCSTAT_VMMAP 10 /* Procstat vmmap data. */ ++#define NT_PROCSTAT_GROUPS 11 /* Procstat groups data. */ ++#define NT_PROCSTAT_UMASK 12 /* Procstat umask data. */ ++#define NT_PROCSTAT_RLIMIT 13 /* Procstat rlimit data. */ ++#define NT_PROCSTAT_OSREL 14 /* Procstat osreldate data. */ ++#define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */ ++#define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */ ++ ++/* Symbol Binding - ELFNN_ST_BIND - st_info */ ++#define STB_LOCAL 0 /* Local symbol */ ++#define STB_GLOBAL 1 /* Global symbol */ ++#define STB_WEAK 2 /* like global - lower precedence */ ++#define STB_LOOS 10 /* Reserved range for operating system */ ++#define STB_HIOS 12 /* specific semantics. */ ++#define STB_LOPROC 13 /* reserved range for processor */ ++#define STB_HIPROC 15 /* specific semantics. */ ++ ++/* Symbol type - ELFNN_ST_TYPE - st_info */ ++#define STT_NOTYPE 0 /* Unspecified type. */ ++#define STT_OBJECT 1 /* Data object. */ ++#define STT_FUNC 2 /* Function. */ ++#define STT_SECTION 3 /* Section. */ ++#define STT_FILE 4 /* Source file. */ ++#define STT_COMMON 5 /* Uninitialized common block. */ ++#define STT_TLS 6 /* TLS object. */ ++#define STT_NUM 7 ++#define STT_LOOS 10 /* Reserved range for operating system */ ++#define STT_GNU_IFUNC 10 ++#define STT_HIOS 12 /* specific semantics. */ ++#define STT_LOPROC 13 /* reserved range for processor */ ++#define STT_HIPROC 15 /* specific semantics. */ ++ ++/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ ++#define STV_DEFAULT 0x0 /* Default visibility (see binding). */ ++#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */ ++#define STV_HIDDEN 0x2 /* Not visible. */ ++#define STV_PROTECTED 0x3 /* Visible but not preemptible. */ ++#define STV_EXPORTED 0x4 ++#define STV_SINGLETON 0x5 ++#define STV_ELIMINATE 0x6 ++ ++/* Special symbol table indexes. */ ++#define STN_UNDEF 0 /* Undefined symbol index. */ ++ ++/* Symbol versioning flags. */ ++#define VER_DEF_CURRENT 1 ++#define VER_DEF_IDX(x) VER_NDX(x) ++ ++#define VER_FLG_BASE 0x01 ++#define VER_FLG_WEAK 0x02 ++ ++#define VER_NEED_CURRENT 1 ++#define VER_NEED_WEAK (1u << 15) ++#define VER_NEED_HIDDEN VER_NDX_HIDDEN ++#define VER_NEED_IDX(x) VER_NDX(x) ++ ++#define VER_NDX_LOCAL 0 ++#define VER_NDX_GLOBAL 1 ++#define VER_NDX_GIVEN 2 ++ ++#define VER_NDX_HIDDEN (1u << 15) ++#define VER_NDX(x) ((x) & ~(1u << 15)) ++ ++#define CA_SUNW_NULL 0 ++#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */ ++#define CA_SUNW_SF_1 2 /* first software capabilities entry */ ++ ++/* ++ * Syminfo flag values ++ */ ++#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */ ++ /* to object containing defn. */ ++#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */ ++#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */ ++#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */ ++ /* lazily-loaded */ ++#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */ ++ /* object containing defn. */ ++#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */ ++ /* directly bind to this symbol */ ++#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */ ++#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */ ++ ++/* ++ * Syminfo.si_boundto values. ++ */ ++#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */ ++#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */ ++#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */ ++#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */ ++#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */ ++ ++/* ++ * Syminfo version values. ++ */ ++#define SYMINFO_NONE 0 /* Syminfo version */ ++#define SYMINFO_CURRENT 1 ++#define SYMINFO_NUM 2 ++ ++/* ++ * Relocation types. ++ * ++ * All machine architectures are defined here to allow tools on one to ++ * handle others. ++ */ ++ ++#define R_386_NONE 0 /* No relocation. */ ++#define R_386_32 1 /* Add symbol value. */ ++#define R_386_PC32 2 /* Add PC-relative symbol value. */ ++#define R_386_GOT32 3 /* Add PC-relative GOT offset. */ ++#define R_386_PLT32 4 /* Add PC-relative PLT offset. */ ++#define R_386_COPY 5 /* Copy data from shared object. */ ++#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ ++#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ ++#define R_386_RELATIVE 8 /* Add load address of shared object. */ ++#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ ++#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ ++#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ ++#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ ++#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ ++#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ ++#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ ++#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ ++#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ ++#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ ++#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ ++#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ ++#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ ++#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ ++#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ ++#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ ++#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ ++#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ ++#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ ++#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ ++#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ ++#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ ++#define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */ ++ ++#define R_AARCH64_ABS64 257 ++#define R_AARCH64_GLOB_DAT 1025 /* Set GOT entry to data address. */ ++#define R_AARCH64_JUMP_SLOT 1026 /* Set GOT entry to code address. */ ++#define R_AARCH64_RELATIVE 1027 ++ ++#define R_ARM_NONE 0 /* No relocation. */ ++#define R_ARM_PC24 1 ++#define R_ARM_ABS32 2 ++#define R_ARM_REL32 3 ++#define R_ARM_PC13 4 ++#define R_ARM_ABS16 5 ++#define R_ARM_ABS12 6 ++#define R_ARM_THM_ABS5 7 ++#define R_ARM_ABS8 8 ++#define R_ARM_SBREL32 9 ++#define R_ARM_THM_PC22 10 ++#define R_ARM_THM_PC8 11 ++#define R_ARM_AMP_VCALL9 12 ++#define R_ARM_SWI24 13 ++#define R_ARM_THM_SWI8 14 ++#define R_ARM_XPC25 15 ++#define R_ARM_THM_XPC22 16 ++/* TLS relocations */ ++#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ ++#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ ++#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ ++#define R_ARM_COPY 20 /* Copy data from shared object. */ ++#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */ ++#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */ ++#define R_ARM_RELATIVE 23 /* Add load address of shared object. */ ++#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */ ++#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */ ++#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */ ++#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ ++#define R_ARM_GNU_VTENTRY 100 ++#define R_ARM_GNU_VTINHERIT 101 ++#define R_ARM_RSBREL32 250 ++#define R_ARM_THM_RPC22 251 ++#define R_ARM_RREL32 252 ++#define R_ARM_RABS32 253 ++#define R_ARM_RPC24 254 ++#define R_ARM_RBASE 255 ++ ++/* Name Value Field Calculation */ ++#define R_IA_64_NONE 0 /* None */ ++#define R_IA_64_IMM14 0x21 /* immediate14 S + A */ ++#define R_IA_64_IMM22 0x22 /* immediate22 S + A */ ++#define R_IA_64_IMM64 0x23 /* immediate64 S + A */ ++#define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */ ++#define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */ ++#define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */ ++#define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */ ++#define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */ ++#define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */ ++#define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */ ++#define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */ ++#define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */ ++#define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */ ++#define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */ ++#define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */ ++#define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */ ++#define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */ ++#define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */ ++#define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */ ++#define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */ ++#define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */ ++#define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */ ++#define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */ ++#define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */ ++#define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */ ++#define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */ ++#define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */ ++#define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */ ++#define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */ ++#define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */ ++#define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */ ++#define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */ ++#define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */ ++#define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */ ++#define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */ ++#define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */ ++#define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */ ++#define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */ ++#define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */ ++#define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */ ++#define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */ ++#define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */ ++#define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */ ++#define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */ ++#define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */ ++#define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */ ++#define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */ ++#define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */ ++#define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */ ++#define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */ ++#define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */ ++#define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */ ++#define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */ ++#define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */ ++#define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */ ++#define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */ ++#define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */ ++#define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */ ++#define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */ ++#define R_IA_64_SUB 0x85 /* immediate64 A - S */ ++#define R_IA_64_LTOFF22X 0x86 /* immediate22 special */ ++#define R_IA_64_LDXMOV 0x87 /* immediate22 special */ ++#define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */ ++#define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */ ++#define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */ ++#define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */ ++#define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */ ++#define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */ ++#define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */ ++#define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */ ++#define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */ ++#define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */ ++#define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */ ++#define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */ ++#define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */ ++#define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */ ++#define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */ ++#define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */ ++#define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */ ++ ++#define R_MIPS_NONE 0 /* No reloc */ ++#define R_MIPS_16 1 /* Direct 16 bit */ ++#define R_MIPS_32 2 /* Direct 32 bit */ ++#define R_MIPS_REL32 3 /* PC relative 32 bit */ ++#define R_MIPS_26 4 /* Direct 26 bit shifted */ ++#define R_MIPS_HI16 5 /* High 16 bit */ ++#define R_MIPS_LO16 6 /* Low 16 bit */ ++#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ ++#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ ++#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ ++#define R_MIPS_PC16 10 /* PC relative 16 bit */ ++#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ ++#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ ++#define R_MIPS_64 18 /* Direct 64 bit */ ++#define R_MIPS_GOTHI16 21 /* GOT HI 16 bit */ ++#define R_MIPS_GOTLO16 22 /* GOT LO 16 bit */ ++#define R_MIPS_CALLHI16 30 /* upper 16 bit GOT entry for function */ ++#define R_MIPS_CALLLO16 31 /* lower 16 bit GOT entry for function */ ++ ++#define R_PPC_NONE 0 /* No relocation. */ ++#define R_PPC_ADDR32 1 ++#define R_PPC_ADDR24 2 ++#define R_PPC_ADDR16 3 ++#define R_PPC_ADDR16_LO 4 ++#define R_PPC_ADDR16_HI 5 ++#define R_PPC_ADDR16_HA 6 ++#define R_PPC_ADDR14 7 ++#define R_PPC_ADDR14_BRTAKEN 8 ++#define R_PPC_ADDR14_BRNTAKEN 9 ++#define R_PPC_REL24 10 ++#define R_PPC_REL14 11 ++#define R_PPC_REL14_BRTAKEN 12 ++#define R_PPC_REL14_BRNTAKEN 13 ++#define R_PPC_GOT16 14 ++#define R_PPC_GOT16_LO 15 ++#define R_PPC_GOT16_HI 16 ++#define R_PPC_GOT16_HA 17 ++#define R_PPC_PLTREL24 18 ++#define R_PPC_COPY 19 ++#define R_PPC_GLOB_DAT 20 ++#define R_PPC_JMP_SLOT 21 ++#define R_PPC_RELATIVE 22 ++#define R_PPC_LOCAL24PC 23 ++#define R_PPC_UADDR32 24 ++#define R_PPC_UADDR16 25 ++#define R_PPC_REL32 26 ++#define R_PPC_PLT32 27 ++#define R_PPC_PLTREL32 28 ++#define R_PPC_PLT16_LO 29 ++#define R_PPC_PLT16_HI 30 ++#define R_PPC_PLT16_HA 31 ++#define R_PPC_SDAREL16 32 ++#define R_PPC_SECTOFF 33 ++#define R_PPC_SECTOFF_LO 34 ++#define R_PPC_SECTOFF_HI 35 ++#define R_PPC_SECTOFF_HA 36 ++ ++/* ++ * 64-bit relocations ++ */ ++#define R_PPC64_ADDR64 38 ++#define R_PPC64_ADDR16_HIGHER 39 ++#define R_PPC64_ADDR16_HIGHERA 40 ++#define R_PPC64_ADDR16_HIGHEST 41 ++#define R_PPC64_ADDR16_HIGHESTA 42 ++#define R_PPC64_UADDR64 43 ++#define R_PPC64_REL64 44 ++#define R_PPC64_PLT64 45 ++#define R_PPC64_PLTREL64 46 ++#define R_PPC64_TOC16 47 ++#define R_PPC64_TOC16_LO 48 ++#define R_PPC64_TOC16_HI 49 ++#define R_PPC64_TOC16_HA 50 ++#define R_PPC64_TOC 51 ++#define R_PPC64_DTPMOD64 68 ++#define R_PPC64_TPREL64 73 ++#define R_PPC64_DTPREL64 78 ++ ++/* ++ * TLS relocations ++ */ ++#define R_PPC_TLS 67 ++#define R_PPC_DTPMOD32 68 ++#define R_PPC_TPREL16 69 ++#define R_PPC_TPREL16_LO 70 ++#define R_PPC_TPREL16_HI 71 ++#define R_PPC_TPREL16_HA 72 ++#define R_PPC_TPREL32 73 ++#define R_PPC_DTPREL16 74 ++#define R_PPC_DTPREL16_LO 75 ++#define R_PPC_DTPREL16_HI 76 ++#define R_PPC_DTPREL16_HA 77 ++#define R_PPC_DTPREL32 78 ++#define R_PPC_GOT_TLSGD16 79 ++#define R_PPC_GOT_TLSGD16_LO 80 ++#define R_PPC_GOT_TLSGD16_HI 81 ++#define R_PPC_GOT_TLSGD16_HA 82 ++#define R_PPC_GOT_TLSLD16 83 ++#define R_PPC_GOT_TLSLD16_LO 84 ++#define R_PPC_GOT_TLSLD16_HI 85 ++#define R_PPC_GOT_TLSLD16_HA 86 ++#define R_PPC_GOT_TPREL16 87 ++#define R_PPC_GOT_TPREL16_LO 88 ++#define R_PPC_GOT_TPREL16_HI 89 ++#define R_PPC_GOT_TPREL16_HA 90 ++ ++/* ++ * The remaining relocs are from the Embedded ELF ABI, and are not in the ++ * SVR4 ELF ABI. ++ */ ++ ++#define R_PPC_EMB_NADDR32 101 ++#define R_PPC_EMB_NADDR16 102 ++#define R_PPC_EMB_NADDR16_LO 103 ++#define R_PPC_EMB_NADDR16_HI 104 ++#define R_PPC_EMB_NADDR16_HA 105 ++#define R_PPC_EMB_SDAI16 106 ++#define R_PPC_EMB_SDA2I16 107 ++#define R_PPC_EMB_SDA2REL 108 ++#define R_PPC_EMB_SDA21 109 ++#define R_PPC_EMB_MRKREF 110 ++#define R_PPC_EMB_RELSEC16 111 ++#define R_PPC_EMB_RELST_LO 112 ++#define R_PPC_EMB_RELST_HI 113 ++#define R_PPC_EMB_RELST_HA 114 ++#define R_PPC_EMB_BIT_FLD 115 ++#define R_PPC_EMB_RELSDA 116 ++ ++#define R_SPARC_NONE 0 ++#define R_SPARC_8 1 ++#define R_SPARC_16 2 ++#define R_SPARC_32 3 ++#define R_SPARC_DISP8 4 ++#define R_SPARC_DISP16 5 ++#define R_SPARC_DISP32 6 ++#define R_SPARC_WDISP30 7 ++#define R_SPARC_WDISP22 8 ++#define R_SPARC_HI22 9 ++#define R_SPARC_22 10 ++#define R_SPARC_13 11 ++#define R_SPARC_LO10 12 ++#define R_SPARC_GOT10 13 ++#define R_SPARC_GOT13 14 ++#define R_SPARC_GOT22 15 ++#define R_SPARC_PC10 16 ++#define R_SPARC_PC22 17 ++#define R_SPARC_WPLT30 18 ++#define R_SPARC_COPY 19 ++#define R_SPARC_GLOB_DAT 20 ++#define R_SPARC_JMP_SLOT 21 ++#define R_SPARC_RELATIVE 22 ++#define R_SPARC_UA32 23 ++#define R_SPARC_PLT32 24 ++#define R_SPARC_HIPLT22 25 ++#define R_SPARC_LOPLT10 26 ++#define R_SPARC_PCPLT32 27 ++#define R_SPARC_PCPLT22 28 ++#define R_SPARC_PCPLT10 29 ++#define R_SPARC_10 30 ++#define R_SPARC_11 31 ++#define R_SPARC_64 32 ++#define R_SPARC_OLO10 33 ++#define R_SPARC_HH22 34 ++#define R_SPARC_HM10 35 ++#define R_SPARC_LM22 36 ++#define R_SPARC_PC_HH22 37 ++#define R_SPARC_PC_HM10 38 ++#define R_SPARC_PC_LM22 39 ++#define R_SPARC_WDISP16 40 ++#define R_SPARC_WDISP19 41 ++#define R_SPARC_GLOB_JMP 42 ++#define R_SPARC_7 43 ++#define R_SPARC_5 44 ++#define R_SPARC_6 45 ++#define R_SPARC_DISP64 46 ++#define R_SPARC_PLT64 47 ++#define R_SPARC_HIX22 48 ++#define R_SPARC_LOX10 49 ++#define R_SPARC_H44 50 ++#define R_SPARC_M44 51 ++#define R_SPARC_L44 52 ++#define R_SPARC_REGISTER 53 ++#define R_SPARC_UA64 54 ++#define R_SPARC_UA16 55 ++#define R_SPARC_TLS_GD_HI22 56 ++#define R_SPARC_TLS_GD_LO10 57 ++#define R_SPARC_TLS_GD_ADD 58 ++#define R_SPARC_TLS_GD_CALL 59 ++#define R_SPARC_TLS_LDM_HI22 60 ++#define R_SPARC_TLS_LDM_LO10 61 ++#define R_SPARC_TLS_LDM_ADD 62 ++#define R_SPARC_TLS_LDM_CALL 63 ++#define R_SPARC_TLS_LDO_HIX22 64 ++#define R_SPARC_TLS_LDO_LOX10 65 ++#define R_SPARC_TLS_LDO_ADD 66 ++#define R_SPARC_TLS_IE_HI22 67 ++#define R_SPARC_TLS_IE_LO10 68 ++#define R_SPARC_TLS_IE_LD 69 ++#define R_SPARC_TLS_IE_LDX 70 ++#define R_SPARC_TLS_IE_ADD 71 ++#define R_SPARC_TLS_LE_HIX22 72 ++#define R_SPARC_TLS_LE_LOX10 73 ++#define R_SPARC_TLS_DTPMOD32 74 ++#define R_SPARC_TLS_DTPMOD64 75 ++#define R_SPARC_TLS_DTPOFF32 76 ++#define R_SPARC_TLS_DTPOFF64 77 ++#define R_SPARC_TLS_TPOFF32 78 ++#define R_SPARC_TLS_TPOFF64 79 ++ ++#define R_X86_64_NONE 0 /* No relocation. */ ++#define R_X86_64_64 1 /* Add 64 bit symbol value. */ ++#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */ ++#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */ ++#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */ ++#define R_X86_64_COPY 5 /* Copy data from shared object. */ ++#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */ ++#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */ ++#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */ ++#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */ ++#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */ ++#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */ ++#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */ ++#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */ ++#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */ ++#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */ ++#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ ++#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */ ++#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */ ++#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */ ++#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */ ++#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ ++#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ ++#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ ++#define R_X86_64_IRELATIVE 37 ++ ++#endif /* !_SYS_ELF_COMMON_H_ */ +diff --git a/ta/remoteproc/include/elf_parser.h b/ta/remoteproc/include/elf_parser.h +new file mode 100644 +index 000000000..5950db971 +--- /dev/null ++++ b/ta/remoteproc/include/elf_parser.h +@@ -0,0 +1,59 @@ ++/* SPDX-License-Identifier: BSD-2-Clause */ ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#ifndef ELF_PARSER ++#define ELF_PARSER ++ ++#include ++#include ++#include ++ ++/** ++ * struct resource_table - firmware resource table header ++ * @ver: version number ++ * @num: number of resource entries ++ * @reserved: reserved (must be zero) ++ * @offset: array of offsets pointing at the various resource entries ++ * ++ * A resource table is essentially a list of system resources required ++ * by the remote processor. It may also include configuration entries. ++ * If needed, the remote processor firmware should contain this table ++ * as a dedicated ".resource_table" ELF section. ++ * ++ * This structure shall be consistent with the Linux kernel structure ++ * definition from include/linux/remoteproc.h. ++ */ ++struct resource_table { ++ uint32_t ver; ++ uint32_t num; ++ uint32_t reserved[2]; ++ uint32_t offset[]; ++} __packed; ++ ++struct fw_elf32 { ++ uintptr_t e_entry; ++ uintptr_t e_phoff; ++ uintptr_t e_shoff; ++ uint32_t e_phnum; ++ uint32_t e_shnum; ++ uint32_t e_phentsize; ++ uint32_t e_shentsize; ++ ++ Elf32_Phdr *phdr; ++ Elf32_Shdr *shdr; ++}; ++ ++TEE_Result e32_parse_ehdr(uint8_t *fw, size_t size); ++TEE_Result e32_parser_load_elf_image(uint8_t *fw, size_t fw_size, ++ TEE_Result (*load_seg)(uint8_t *src, ++ uint32_t size, ++ uint32_t da, ++ uint32_t mem_size, ++ void *priv), ++ void *priv_data); ++int e32_parser_find_rsc_table(uint8_t *fw, size_t fw_size, Elf32_Addr *rsc_addr, ++ Elf32_Word *rsc_size); ++ ++#endif /*ELF_PARSER*/ +diff --git a/ta/remoteproc/include/ta_remoteproc.h b/ta/remoteproc/include/ta_remoteproc.h +new file mode 100644 +index 000000000..a51ba5f70 +--- /dev/null ++++ b/ta/remoteproc/include/ta_remoteproc.h +@@ -0,0 +1,65 @@ ++/* SPDX-License-Identifier: BSD-2-Clause */ ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#ifndef TA_RPROC_FW_H ++#define TA_RPROC_FW_H ++ ++/* ++ * This UUID is generated with uuidgen ++ * the ITU-T UUID generator at http://www.itu.int/ITU-T/asn1/uuid.html ++ */ ++#define TA_REMOTEPROC_UUID \ ++ { 0x80a4c275, 0x0a47, 0x4905, \ ++ { 0x82, 0x85, 0x14, 0x86, 0xa9, 0x77, 0x1a, 0x08} } ++ ++/* The function IDs implemented in this TA */ ++ ++/* ++ * Authentication of the firmware and load in the remote processor memory. ++ * ++ * [in] params[0].value.a: unique 32bit identifier of the firmware ++ * [in] params[1].memref: buffer containing the image of the firmware ++ */ ++#define TA_RPROC_FW_CMD_LOAD_FW 1 ++ ++/* ++ * Start the remote processor. ++ * ++ * [in] params[0].value.a: unique 32bit identifier of the firmware ++ */ ++#define TA_RPROC_FW_CMD_START_FW 2 ++ ++/* ++ * Stop the remote processor. ++ * ++ * [in] params[0].value.a: unique 32bit identifier of the firmware ++ */ ++#define TA_RPROC_FW_CMD_STOP_FW 3 ++ ++/* ++ * Return the physical address of the resource table, or 0 if not found ++ * No check is done to verify that the address returned is accessible by the ++ * non secure world. If the resource table is loaded in a protected memory, ++ * then accesses from non-secure world will likely fail. ++ * ++ * [in] params[0].value.a: unique 32bit identifier of the firmware ++ * [out] params[1].value.a: 32bit LSB resource table memory address ++ * [out] params[1].value.b: 32bit MSB resource table memory address ++ * [out] params[2].value.a: 32bit LSB resource table memory size ++ * [out] params[2].value.b: 32bit MSB resource table memory size ++ */ ++#define TA_RPROC_FW_CMD_GET_RSC_TABLE 4 ++ ++/* ++ * Get remote processor firmware core dump. If found, return either ++ * TEE_SUCCESS on successful completion or TEE_ERROR_SHORT_BUFFER if output ++ * buffer is too short to store the core dump. ++ * ++ * [in] params[0].value.a: unique 32bit identifier of the firmware ++ * [out] params[1].memref: Core dump, if found ++ */ ++#define TA_RPROC_FW_CMD_GET_COREDUMP 5 ++ ++#endif /*TA_RPROC_FW_H*/ +diff --git a/ta/remoteproc/include/user_ta_header_defines.h b/ta/remoteproc/include/user_ta_header_defines.h +new file mode 100644 +index 000000000..c2ef1b21b +--- /dev/null ++++ b/ta/remoteproc/include/user_ta_header_defines.h +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: BSD-2-Clause */ ++/* ++ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved ++ */ ++ ++#ifndef USER_TA_HEADER_DEFINES_H ++#define USER_TA_HEADER_DEFINES_H ++ ++#include ++ ++#define TA_UUID TA_REMOTEPROC_UUID ++ ++#define TA_FLAGS (TA_FLAG_DEVICE_ENUM | \ ++ TA_FLAG_SINGLE_INSTANCE | \ ++ TA_FLAG_INSTANCE_KEEP_ALIVE) ++ ++/* Provisioned stack size */ ++#define TA_STACK_SIZE (4 * 1024) ++ ++/* Provisioned heap size for TEE_Malloc() and friends */ ++#define TA_DATA_SIZE (4 * 1024) ++ ++/* The gpd.ta.version property */ ++#define TA_VERSION "1.0" ++ ++/* The gpd.ta.description property */ ++#define TA_DESCRIPTION "remote processor firmware management" ++ ++#endif /* USER_TA_HEADER_DEFINES_H */ +diff --git a/ta/remoteproc/remoteproc_core.c b/ta/remoteproc/remoteproc_core.c +new file mode 100644 +index 000000000..454edf2fb +--- /dev/null ++++ b/ta/remoteproc/remoteproc_core.c +@@ -0,0 +1,781 @@ ++ // SPDX-License-Identifier: BSD-2-Clause ++ /* ++ * Copyright (C) 2020-2021, STMicroelectronics - All Rights Reserved ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Firmware state */ ++enum remoteproc_state { ++ REMOTEPROC_OFF, ++ REMOTEPROC_LOADED, ++ REMOTEPROC_STARTED, ++}; ++ ++#define RPROC_HDR_MAGIC 0x3543A468 /*random value */ ++#define HEADER_VERSION 1 ++ ++/* Supported signature algorithm */ ++enum remoteproc_sign_type { ++ RPROC_RSASSA_PKCS1_v1_5_SHA256 = 1, ++ RPROC_ECDSA_SHA256 = 2, ++}; ++ ++/* ++ * struct remoteproc_segment - program header with hash structure ++ * @phdr: program header ++ * @hash: hash associated to the program segment. ++ */ ++struct remoteproc_segment { ++ Elf32_Phdr phdr; ++ unsigned char hash[TEE_SHA256_HASH_SIZE]; ++}; ++ ++/* ++ * struct remoteproc_fw_hdr - firmware header ++ * @magic: Magic number, must be equal to RPROC_HDR_MAGIC ++ * @version: Version of the header (must be 1) ++ * @hdr_length: Total header byte length including chunks ++ * @sign_length: Signature chunk byte length ++ * @sign_offset: Signature chunk byte offset from header start ++ * @sign_type: Signature type ++ * @phhdr_length: Program header with hashes byte size, possibly 0 ++ * @phhdr_offset: Program header with hashes byte offset, 0 if not used ++ * @phhdr_type: Program header with hash type or 0 if not used ++ * @key_length: Authentication key info byte length, possibly 0 ++ * @key_offset: Authentication key info byte offset, 0 if not used ++ * @img_length: Firmware image chunk byte length ++ * @img_offset: Firmware image chunk byte offset ++ * @img_type: Firmware image type ++ */ ++struct remoteproc_fw_hdr { ++ uint32_t magic; ++ uint32_t version; ++ uint32_t hdr_length; ++ uint32_t sign_length; ++ uint32_t sign_offset; ++ uint32_t sign_type; ++ uint32_t phhdr_length; ++ uint32_t phhdr_offset; ++ uint32_t phhdr_type; ++ uint32_t key_length; ++ uint32_t key_offset; ++ uint32_t img_length; ++ uint32_t img_offset; ++ uint32_t img_type; ++}; ++ ++/* ++ * struct remoteproc_sig_algo - signature algorithm information ++ * @sign_type: Header signature type ++ * @id: Signature algorigthm identifier TEE_ALG_* ++ * @hash_len: Signature hash length ++ */ ++struct remoteproc_sig_algo { ++ enum remoteproc_sign_type sign_type; ++ uint32_t id; ++ size_t hash_len; ++}; ++ ++/* ++ * struct remoteproc_context - firmware context ++ * @fw_id: Unique Id of the firmware ++ * @hdr: Location of a secure copy of the firmware header ++ * @fw_img: Firmware image ++ * @fw_img_size: Byte size of the firmware image ++ * @rsc_pa: Physical address of the firmware resource table ++ * @rsc_size: Byte size of the firmware resource table ++ * @state: Remote-processor state ++ * @hw_fmt: Image format capabilities of the remoteproc PTA ++ * @hw_img_prot: Image protection capabilities of the remoteproc PTA ++ * @link: Linked list element ++ */ ++struct remoteproc_context { ++ uint32_t fw_id; ++ struct remoteproc_fw_hdr *hdr; ++ uint8_t *fw_img; ++ size_t fw_img_size; ++ paddr_t rsc_pa; ++ uint32_t rsc_size; ++ enum remoteproc_state state; ++ uint32_t hw_fmt; ++ uint32_t hw_img_prot; ++ TAILQ_ENTRY(remoteproc_context) link; ++}; ++ ++TAILQ_HEAD(remoteproc_firmware_head, remoteproc_context); ++ ++static struct remoteproc_firmware_head firmware_head = ++ TAILQ_HEAD_INITIALIZER(firmware_head); ++ ++static const struct remoteproc_sig_algo rproc_ta_sign_algo[] = { ++ { ++ .sign_type = RPROC_RSASSA_PKCS1_v1_5_SHA256, ++ .id = TEE_ALG_RSASSA_PKCS1_V1_5_SHA256, ++ .hash_len = TEE_SHA256_HASH_SIZE, ++ }, ++ { ++ .sign_type = RPROC_ECDSA_SHA256, ++ .id = TEE_ALG_ECDSA_P256, ++ .hash_len = TEE_SHA256_HASH_SIZE, ++ }, ++}; ++ ++static size_t session_refcount; ++static TEE_TASessionHandle pta_session; ++ ++static void remoteproc_header_dump(struct remoteproc_fw_hdr __maybe_unused *hdr) ++{ ++ DMSG("magic :\t%#"PRIx32, hdr->magic); ++ DMSG("version :\t%#"PRIx32, hdr->version); ++ DMSG("hdr_length :\t%#"PRIx32, hdr->hdr_length); ++ DMSG("sign_length :\t%#"PRIx32, hdr->sign_length); ++ DMSG("sign_offset :\t%#"PRIx32, hdr->sign_offset); ++ DMSG("sign_type :\t%#"PRIx32, hdr->sign_type); ++ DMSG("phhdr_length :\t%#"PRIx32, hdr->phhdr_length); ++ DMSG("phhdr_offset :\t%#"PRIx32, hdr->phhdr_offset); ++ DMSG("phhdr_type :\t%#"PRIx32, hdr->phhdr_type); ++ DMSG("key_length :\t%#"PRIx32, hdr->key_length); ++ DMSG("key_offset :\t%#"PRIx32, hdr->key_offset); ++ DMSG("img_length :\t%#"PRIx32, hdr->img_length); ++ DMSG("img_offset :\t%#"PRIx32, hdr->img_offset); ++ DMSG("img_type :\t%#"PRIx32, hdr->img_type); ++} ++ ++static struct remoteproc_context *remoteproc_find_firmware(uint32_t fw_id) ++{ ++ struct remoteproc_context *ctx = NULL; ++ ++ TAILQ_FOREACH(ctx, &firmware_head, link) { ++ if (ctx->fw_id == fw_id) ++ return ctx; ++ } ++ ++ return NULL; ++} ++ ++static struct remoteproc_context *remoteproc_add_firmware(uint32_t fw_id) ++{ ++ struct remoteproc_context *ctx = NULL; ++ ++ ctx = TEE_Malloc(sizeof(*ctx), TEE_MALLOC_FILL_ZERO); ++ if (!ctx) ++ return NULL; ++ ++ ctx->fw_id = fw_id; ++ ++ TAILQ_INSERT_TAIL(&firmware_head, ctx, link); ++ ++ return ctx; ++} ++ ++static const struct remoteproc_sig_algo *remoteproc_get_algo(uint32_t sign_type) ++{ ++ unsigned int i = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(rproc_ta_sign_algo); i++) ++ if (sign_type == rproc_ta_sign_algo[i].sign_type) ++ return &rproc_ta_sign_algo[i]; ++ ++ return NULL; ++} ++ ++static TEE_Result remoteproc_pta_verify(struct remoteproc_context *ctx, ++ const struct remoteproc_sig_algo *algo, ++ char *hash, uint32_t hash_len) ++{ ++ TEE_Result res = TEE_ERROR_GENERIC; ++ struct remoteproc_fw_hdr *hdr = ctx->hdr; ++ struct rproc_pta_key_info *keyinfo = NULL; ++ uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT); ++ TEE_Param params[TEE_NUM_PARAMS] = { }; ++ ++ keyinfo = TEE_Malloc(sizeof(*keyinfo) + hdr->key_length, 0); ++ if (!keyinfo) ++ return TEE_ERROR_OUT_OF_MEMORY; ++ ++ keyinfo->algo = algo->id; ++ keyinfo->info_size = hdr->key_length; ++ memcpy(keyinfo->info, (uint8_t *)hdr + hdr->key_offset, ++ hdr->key_length); ++ ++ params[0].value.a = ctx->fw_id; ++ params[1].memref.buffer = keyinfo; ++ params[1].memref.size = RPROC_PTA_GET_KEYINFO_SIZE(keyinfo); ++ params[2].memref.buffer = hash; ++ params[2].memref.size = hash_len; ++ params[3].memref.buffer = (uint8_t *)hdr + hdr->sign_offset; ++ params[3].memref.size = hdr->sign_length; ++ ++ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, ++ PTA_REMOTEPROC_VERIFY_DIGEST, ++ param_types, params, NULL); ++ if (res != TEE_SUCCESS) ++ EMSG("Failed to verify signature, res = %#"PRIx32, res); ++ ++ TEE_Free(keyinfo); ++ ++ return res; ++} ++ ++static TEE_Result remoteproc_save_fw_header(struct remoteproc_context *ctx, ++ void *fw_orig, ++ uint32_t fw_orig_size) ++{ ++ struct remoteproc_fw_hdr *hdr = fw_orig; ++ ++ remoteproc_header_dump(hdr); ++ ++ if (fw_orig_size <= sizeof(*hdr) || fw_orig_size <= hdr->hdr_length) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ ctx->hdr = TEE_Malloc(hdr->hdr_length, TEE_MALLOC_FILL_ZERO); ++ if (!ctx->hdr) ++ return TEE_ERROR_OUT_OF_MEMORY; ++ ++ memcpy(ctx->hdr, fw_orig, hdr->hdr_length); ++ ++ return TEE_SUCCESS; ++} ++ ++static TEE_Result remoteproc_verify_signature(struct remoteproc_context *ctx) ++{ ++ TEE_OperationHandle op = TEE_HANDLE_NULL; ++ struct remoteproc_fw_hdr *hdr = ctx->hdr; ++ const struct remoteproc_sig_algo *algo = NULL; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ char *hash = NULL; ++ uint32_t hash_len = 0; ++ ++ algo = remoteproc_get_algo(hdr->sign_type); ++ if (!algo) { ++ EMSG("Unsupported signature type %d", hdr->sign_type); ++ return TEE_ERROR_NOT_SUPPORTED; ++ } ++ ++ /* Compute the header hash */ ++ hash_len = algo->hash_len; ++ hash = TEE_Malloc(hash_len, 0); ++ if (!hash) ++ return TEE_ERROR_OUT_OF_MEMORY; ++ ++ res = TEE_AllocateOperation(&op, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0); ++ if (res != TEE_SUCCESS) ++ goto free_hash; ++ ++ res = TEE_DigestDoFinal(op, hdr, hdr->sign_offset, hash, &hash_len); ++ if (res != TEE_SUCCESS) ++ goto out; ++ ++ /* ++ * TODO: ++ * Provide alternative to verify the signature in the TA. This could ++ * be done for instance by getting the key object from secure storage. ++ */ ++ ++ /* By default ask the pta to verify the signature. */ ++ res = remoteproc_pta_verify(ctx, algo, hash, hash_len); ++ ++out: ++ TEE_FreeOperation(op); ++free_hash: ++ TEE_Free(hash); ++ ++ return res; ++} ++ ++static TEE_Result remoteproc_verify_header(struct remoteproc_context *ctx) ++{ ++ struct remoteproc_fw_hdr *hdr = ctx->hdr; ++ uint32_t hdr_size = 0; ++ uint32_t chunk_size = 0; ++ uint32_t alignment = 0; ++ ++ if (hdr->magic != RPROC_HDR_MAGIC) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ if (hdr->version != HEADER_VERSION) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ /* ++ * The offsets are aligned to 64 bits format. The hdr_length takes into ++ * account these alignments while the length of each chunks are the ++ * effective length,excluding the alignment padding bytes. ++ */ ++ alignment = hdr->sign_length % sizeof(uint64_t) + ++ hdr->phhdr_length % sizeof(uint64_t) + ++ hdr->key_length % sizeof(uint64_t); ++ ++ if (ADD_OVERFLOW(sizeof(*hdr), hdr->sign_length, &hdr_size) || ++ ADD_OVERFLOW(hdr_size, hdr->phhdr_length, &hdr_size) || ++ ADD_OVERFLOW(hdr_size, hdr->key_length, &hdr_size) || ++ ADD_OVERFLOW(hdr_size, alignment, &hdr_size) || ++ hdr->hdr_length != hdr_size) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ if (ADD_OVERFLOW(hdr->sign_offset, hdr->sign_length, &chunk_size) || ++ chunk_size > hdr_size || ++ ADD_OVERFLOW(hdr->key_offset, hdr->key_length, &chunk_size) || ++ chunk_size > hdr_size || ++ ADD_OVERFLOW(hdr->phhdr_offset, hdr->phhdr_length, &chunk_size) || ++ chunk_size > hdr_size) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ if (hdr->phhdr_length % sizeof(struct remoteproc_segment)) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ return remoteproc_verify_signature(ctx); ++} ++ ++static TEE_Result get_rproc_pta_capabilities(struct remoteproc_context *ctx) ++{ ++ uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_OUTPUT, ++ TEE_PARAM_TYPE_VALUE_OUTPUT, ++ TEE_PARAM_TYPE_NONE); ++ TEE_Param params[TEE_NUM_PARAMS] = { }; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ ++ params[0].value.a = ctx->fw_id; ++ ++ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, ++ PTA_REMOTEPROC_HW_CAPABILITIES, ++ param_types, params, NULL); ++ if (res) ++ return res; ++ ++ ctx->hw_fmt = params[1].value.a; ++ ctx->hw_img_prot = params[2].value.a; ++ ++ return TEE_SUCCESS; ++} ++ ++static TEE_Result remoteproc_verify_firmware(struct remoteproc_context *ctx, ++ uint8_t *fw_orig, ++ uint32_t fw_orig_size) ++{ ++ struct remoteproc_fw_hdr *hdr = NULL; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ ++ res = get_rproc_pta_capabilities(ctx); ++ if (res) ++ return res; ++ ++ /* Secure the firmware image depending on strategy */ ++ if (!(ctx->hw_img_prot & PTA_REMOTEPROC_FW_WITH_HASH_TABLE) || ++ ctx->hw_fmt != PTA_REMOTEPROC_ELF_FMT) { ++ /* ++ * Only hash table for ELF format support implemented ++ * in a first step. ++ */ ++ return TEE_ERROR_NOT_IMPLEMENTED; ++ } ++ ++ res = remoteproc_save_fw_header(ctx, fw_orig, fw_orig_size); ++ if (res) ++ return res; ++ ++ res = remoteproc_verify_header(ctx); ++ if (res) ++ goto free_hdr; ++ ++ /* Store location of the loadable binary in non-secure memory */ ++ hdr = ctx->hdr; ++ ctx->fw_img_size = hdr->img_length; ++ ctx->fw_img = fw_orig + hdr->img_offset; ++ ++ DMSG("Firmware image addr: %p size: %zu", ctx->fw_img, ++ ctx->fw_img_size); ++ ++free_hdr: ++ TEE_Free(ctx->hdr); ++ ++ return res; ++} ++ ++static paddr_t remoteproc_da_to_pa(uint32_t da, uint32_t size, void *priv) ++{ ++ struct remoteproc_context *ctx = priv; ++ uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_OUTPUT); ++ TEE_Param params[TEE_NUM_PARAMS] = { }; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ ++ params[0].value.a = ctx->fw_id; ++ params[1].value.a = da; ++ params[2].value.a = size; ++ ++ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, ++ PTA_REMOTEPROC_FIRMWARE_DA_TO_PA, ++ param_types, params, NULL); ++ if (res != TEE_SUCCESS) { ++ EMSG("Failed to translate device address %#"PRIx32, da); ++ return 0; ++ } ++ ++ return (paddr_t)reg_pair_to_64(params[3].value.b, params[3].value.a); ++} ++ ++static TEE_Result remoteproc_parse_rsc_table(struct remoteproc_context *ctx) ++{ ++ uint32_t da = 0; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ ++ res = e32_parser_find_rsc_table(ctx->fw_img, ctx->fw_img_size, ++ &da, &ctx->rsc_size); ++ if (res == TEE_ERROR_NO_DATA) { ++ /* Firmware without resource table */ ++ ctx->rsc_size = 0; ++ ctx->rsc_pa = 0; ++ return TEE_SUCCESS; ++ } ++ if (res) ++ return res; ++ ++ if (da) { ++ DMSG("Resource table device address %#"PRIx32" size %zu", ++ da, ctx->rsc_size); ++ ++ ctx->rsc_pa = remoteproc_da_to_pa(da, ctx->rsc_size, ctx); ++ if (!ctx->rsc_pa) ++ return TEE_ERROR_ACCESS_DENIED; ++ } ++ ++ return TEE_SUCCESS; ++} ++ ++static TEE_Result get_segment_hash(struct remoteproc_context *ctx, uint8_t *src, ++ uint32_t size, uint32_t da, ++ uint32_t mem_size, unsigned char **hash) ++{ ++ struct remoteproc_fw_hdr *hdr = ctx->hdr; ++ struct remoteproc_segment *peh = NULL; ++ unsigned int i = 0; ++ unsigned int nb_entry = hdr->phhdr_length / sizeof(*peh); ++ ++ peh = (void *)((uint8_t *)hdr + hdr->phhdr_offset); ++ ++ for (i = 0; i < nb_entry; peh++, i++) { ++ if (peh->phdr.p_paddr != da) ++ continue; ++ ++ /* ++ * Segment is read from a non secure memory. Crosscheck it using ++ * the hash table to verify that the segment has not been ++ * corrupted. ++ */ ++ if (peh->phdr.p_type != PT_LOAD) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ if (peh->phdr.p_filesz != size || peh->phdr.p_memsz != mem_size) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ if ((Elf32_Off)(src - ctx->fw_img) != peh->phdr.p_offset) ++ return TEE_ERROR_CORRUPT_OBJECT; ++ ++ *hash = peh->hash; ++ ++ return TEE_SUCCESS; ++ } ++ ++ return TEE_ERROR_NO_DATA; ++} ++ ++static TEE_Result remoteproc_load_segment(uint8_t *src, uint32_t size, ++ uint32_t da, uint32_t mem_size, ++ void *priv) ++{ ++ struct remoteproc_context *ctx = priv; ++ uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT); ++ TEE_Param params[TEE_NUM_PARAMS] = { }; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ unsigned char *hash = NULL; ++ ++ /* ++ * Invoke platform remoteproc PTA to load the segment in remote ++ * processor memory which is not mapped in the TA space. ++ */ ++ ++ DMSG("Load segment %#"PRIx32" size %"PRIu32" (%"PRIu32")", da, size, ++ mem_size); ++ ++ res = get_segment_hash(ctx, src, size, da, mem_size, &hash); ++ if (res) ++ return res; ++ ++ params[0].value.a = ctx->fw_id; ++ params[1].memref.buffer = src; ++ params[1].memref.size = size; ++ params[2].value.a = da; ++ params[3].memref.buffer = hash; ++ params[3].memref.size = TEE_SHA256_HASH_SIZE; ++ ++ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, ++ PTA_REMOTEPROC_LOAD_SEGMENT_SHA256, ++ param_types, params, NULL); ++ if (res != TEE_SUCCESS) { ++ EMSG("Fails to load segment, res = 0x%x", res); ++ return res; ++ } ++ ++ /* Fill the rest of the memory with 0 */ ++ if (size < mem_size) { ++ param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_INPUT); ++ params[1].value.a = da + size; ++ params[2].value.a = mem_size - size; ++ params[3].value.a = 0; ++ ++ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, ++ PTA_REMOTEPROC_SET_MEMORY, ++ param_types, params, NULL); ++ if (res != TEE_SUCCESS) ++ EMSG("Fails to clear segment, res = 0x%x", res); ++ } ++ ++ return res; ++} ++ ++static TEE_Result remoteproc_load_elf(struct remoteproc_context *ctx) ++{ ++ TEE_Result res = TEE_ERROR_GENERIC; ++ ++ res = e32_parse_ehdr(ctx->fw_img, ctx->fw_img_size); ++ if (res) { ++ EMSG("Failed to parse firmware, res = %#"PRIx32, res); ++ return res; ++ } ++ ++ return e32_parser_load_elf_image(ctx->fw_img, ctx->fw_img_size, ++ remoteproc_load_segment, ctx); ++} ++ ++static TEE_Result remoteproc_load_fw(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_MEMREF_INPUT, ++ TEE_PARAM_TYPE_NONE, ++ TEE_PARAM_TYPE_NONE); ++ struct remoteproc_context *ctx = NULL; ++ uint32_t fw_id = params[0].value.a; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ ctx = remoteproc_find_firmware(fw_id); ++ if (!ctx) ++ ctx = remoteproc_add_firmware(fw_id); ++ if (!ctx) ++ return TEE_ERROR_OUT_OF_MEMORY; ++ ++ if (ctx->state != REMOTEPROC_OFF) ++ return TEE_ERROR_BAD_STATE; ++ ++ if (!params[1].memref.buffer || !params[1].memref.size) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ DMSG("Got base addr: %p size %zu", params[1].memref.buffer, ++ params[1].memref.size); ++ ++ res = remoteproc_verify_firmware(ctx, params[1].memref.buffer, ++ params[1].memref.size); ++ if (res) { ++ EMSG("Can't Authenticate the firmware, res = %#"PRIx32, res); ++ goto out; ++ } ++ ++ res = remoteproc_load_elf(ctx); ++ if (res) ++ goto out; ++ ++ /* Take opportunity to get the resource table address */ ++ res = remoteproc_parse_rsc_table(ctx); ++ if (res == TEE_SUCCESS) ++ ctx->state = REMOTEPROC_LOADED; ++ ++out: ++ /* Clear reference to firmware image from shared memory */ ++ ctx->fw_img = NULL; ++ ctx->fw_img_size = 0; ++ ++ return res; ++} ++ ++static TEE_Result remoteproc_start_fw(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_NONE, ++ TEE_PARAM_TYPE_NONE, ++ TEE_PARAM_TYPE_NONE); ++ struct remoteproc_context *ctx = NULL; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ ctx = remoteproc_find_firmware(params[0].value.a); ++ if (!ctx) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ switch (ctx->state) { ++ case REMOTEPROC_OFF: ++ res = TEE_ERROR_BAD_STATE; ++ break; ++ case REMOTEPROC_STARTED: ++ res = TEE_SUCCESS; ++ break; ++ case REMOTEPROC_LOADED: ++ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, ++ PTA_REMOTEPROC_FIRMWARE_START, ++ pt, params, NULL); ++ if (res == TEE_SUCCESS) ++ ctx->state = REMOTEPROC_STARTED; ++ break; ++ default: ++ res = TEE_ERROR_BAD_STATE; ++ } ++ ++ return res; ++} ++ ++static TEE_Result remoteproc_stop_fw(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_NONE, ++ TEE_PARAM_TYPE_NONE, ++ TEE_PARAM_TYPE_NONE); ++ struct remoteproc_context *ctx = NULL; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ ctx = remoteproc_find_firmware(params[0].value.a); ++ if (!ctx) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ switch (ctx->state) { ++ case REMOTEPROC_LOADED: ++ res = TEE_ERROR_BAD_STATE; ++ break; ++ case REMOTEPROC_OFF: ++ res = TEE_SUCCESS; ++ break; ++ case REMOTEPROC_STARTED: ++ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, ++ PTA_REMOTEPROC_FIRMWARE_STOP, ++ pt, params, NULL); ++ if (res == TEE_SUCCESS) ++ ctx->state = REMOTEPROC_OFF; ++ break; ++ default: ++ res = TEE_ERROR_BAD_STATE; ++ } ++ ++ return res; ++} ++ ++static TEE_Result remoteproc_get_rsc_table(uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, ++ TEE_PARAM_TYPE_VALUE_OUTPUT, ++ TEE_PARAM_TYPE_VALUE_OUTPUT, ++ TEE_PARAM_TYPE_NONE); ++ struct remoteproc_context *ctx = NULL; ++ ++ if (pt != exp_pt) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ ctx = remoteproc_find_firmware(params[0].value.a); ++ if (!ctx) ++ return TEE_ERROR_BAD_PARAMETERS; ++ ++ if (ctx->state == REMOTEPROC_OFF) ++ return TEE_ERROR_BAD_STATE; ++ ++ reg_pair_from_64((uint64_t)ctx->rsc_pa, ++ ¶ms[1].value.b, ¶ms[1].value.a); ++ reg_pair_from_64((uint64_t)ctx->rsc_size, ++ ¶ms[2].value.b, ¶ms[2].value.a); ++ ++ return TEE_SUCCESS; ++} ++ ++TEE_Result TA_CreateEntryPoint(void) ++{ ++ return TEE_SUCCESS; ++} ++ ++void TA_DestroyEntryPoint(void) ++{ ++} ++ ++TEE_Result TA_OpenSessionEntryPoint(uint32_t pt __unused, ++ TEE_Param params[TEE_NUM_PARAMS] __unused, ++ void **sess __unused) ++{ ++ static const TEE_UUID uuid = PTA_REMOTEPROC_UUID; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ ++ if (!session_refcount) { ++ res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE, 0, NULL, ++ &pta_session, NULL); ++ if (res) ++ return res; ++ } ++ ++ session_refcount++; ++ ++ return TEE_SUCCESS; ++} ++ ++void TA_CloseSessionEntryPoint(void *sess __unused) ++{ ++ session_refcount--; ++ ++ if (!session_refcount) ++ TEE_CloseTASession(pta_session); ++} ++ ++TEE_Result TA_InvokeCommandEntryPoint(void *sess __unused, uint32_t cmd_id, ++ uint32_t pt, ++ TEE_Param params[TEE_NUM_PARAMS]) ++{ ++ switch (cmd_id) { ++ case TA_RPROC_FW_CMD_LOAD_FW: ++ return remoteproc_load_fw(pt, params); ++ case TA_RPROC_FW_CMD_START_FW: ++ return remoteproc_start_fw(pt, params); ++ case TA_RPROC_FW_CMD_STOP_FW: ++ return remoteproc_stop_fw(pt, params); ++ case TA_RPROC_FW_CMD_GET_RSC_TABLE: ++ return remoteproc_get_rsc_table(pt, params); ++ case TA_RPROC_FW_CMD_GET_COREDUMP: ++ return TEE_ERROR_NOT_IMPLEMENTED; ++ default: ++ return TEE_ERROR_BAD_PARAMETERS; ++ } ++} +diff --git a/ta/remoteproc/sub.mk b/ta/remoteproc/sub.mk +new file mode 100644 +index 000000000..caca5901a +--- /dev/null ++++ b/ta/remoteproc/sub.mk +@@ -0,0 +1,3 @@ ++global-incdirs-y += include ++srcs-y += remoteproc_core.c ++srcs-y += elf_parser.c +diff --git a/ta/remoteproc/user_ta.mk b/ta/remoteproc/user_ta.mk +new file mode 100644 +index 000000000..6db23f705 +--- /dev/null ++++ b/ta/remoteproc/user_ta.mk +@@ -0,0 +1 @@ ++user-ta-uuid := 80a4c275-0a47-4905-8285-1486a9771a08 +\ No newline at end of file -- -2.7.4 +2.17.1 diff --git a/recipes-security/optee/optee-os/0002-3.9.0-stm32mp-r2.patch b/recipes-security/optee/optee-os/0002-3.9.0-stm32mp-r2.patch deleted file mode 100644 index bca1d8e..0000000 --- a/recipes-security/optee/optee-os/0002-3.9.0-stm32mp-r2.patch +++ /dev/null @@ -1,4765 +0,0 @@ -From 755a68e59924e2437b9fb46c8ae1bfe690db1343 Mon Sep 17 00:00:00 2001 -From: Christophe Priouzeau -Date: Tue, 27 Oct 2020 12:01:30 +0100 -Subject: [PATCH 2/2] 3.9.0-stm32mp-r2 - ---- - core/arch/arm/dts/stm32mp157a-dk1.dts | 4 +- - core/arch/arm/dts/stm32mp157a-ed1.dts | 4 +- - core/arch/arm/dts/stm32mp157c-dk2.dts | 4 +- - core/arch/arm/dts/stm32mp157c-ed1.dts | 4 +- - core/arch/arm/dts/stm32mp157d-dk1.dts | 4 +- - core/arch/arm/dts/stm32mp157d-ed1.dts | 4 +- - core/arch/arm/dts/stm32mp157f-dk2.dts | 4 +- - core/arch/arm/dts/stm32mp157f-ed1.dts | 4 +- - core/arch/arm/dts/stm32mp15xx-dkx.dtsi | 2 +- - core/arch/arm/dts/stm32mp15xx-edx.dtsi | 2 +- - core/arch/arm/plat-stm32mp1/conf.mk | 9 +- - .../plat-stm32mp1/drivers/stm32mp1_calib.c | 5 + - .../plat-stm32mp1/drivers/stm32mp1_etzpc.h | 100 -- - .../arm/plat-stm32mp1/drivers/stm32mp1_rcc.c | 17 + - core/arch/arm/plat-stm32mp1/main.c | 26 +- - .../arm/plat-stm32mp1/nsec-service/rcc_svc.c | 71 +- - .../plat-stm32mp1/nsec-service/stm32mp1_smc.h | 4 +- - core/arch/arm/plat-stm32mp1/platform_config.h | 8 + - core/arch/arm/plat-stm32mp1/remoteproc_pta.c | 528 +++++++++ - core/arch/arm/plat-stm32mp1/rproc_pub_key.h | 16 + - core/arch/arm/plat-stm32mp1/scmi_server.c | 12 + - .../arch/arm/plat-stm32mp1/shared_resources.c | 125 +- - core/arch/arm/plat-stm32mp1/stm32_util.h | 12 + - core/arch/arm/plat-stm32mp1/sub.mk | 9 + - core/drivers/stm32_bsec.c | 2 +- - core/drivers/stm32_etzpc.c | 55 +- - core/drivers/stm32_gpio.c | 2 +- - core/drivers/stm32_tim.c | 21 +- - core/include/drivers/stm32_bsec.h | 8 - - .../dt-bindings/reset/stm32mp1-resets.h | 2 + - core/sub.mk | 7 +- - keys/default_rproc.pem | 27 + - lib/libutee/include/remoteproc_pta.h | 157 +++ - mk/config.mk | 4 + - scripts/sign_rproc_fw.py | 400 +++++++ - ta/remoteproc/Makefile | 18 + - ta/remoteproc/elf_parser.c | 181 +++ - ta/remoteproc/include/elf32.h | 243 ++++ - ta/remoteproc/include/elf_common.h | 1014 +++++++++++++++++ - ta/remoteproc/include/elf_parser.h | 59 + - ta/remoteproc/include/ta_remoteproc.h | 65 ++ - .../include/user_ta_header_defines.h | 29 + - ta/remoteproc/remoteproc_core.c | 781 +++++++++++++ - ta/remoteproc/sub.mk | 3 + - ta/remoteproc/user_ta.mk | 1 + - 45 files changed, 3845 insertions(+), 212 deletions(-) - delete mode 100644 core/arch/arm/plat-stm32mp1/drivers/stm32mp1_etzpc.h - create mode 100644 core/arch/arm/plat-stm32mp1/remoteproc_pta.c - create mode 100644 core/arch/arm/plat-stm32mp1/rproc_pub_key.h - create mode 100644 keys/default_rproc.pem - create mode 100644 lib/libutee/include/remoteproc_pta.h - create mode 100755 scripts/sign_rproc_fw.py - create mode 100644 ta/remoteproc/Makefile - create mode 100644 ta/remoteproc/elf_parser.c - create mode 100644 ta/remoteproc/include/elf32.h - create mode 100644 ta/remoteproc/include/elf_common.h - create mode 100644 ta/remoteproc/include/elf_parser.h - create mode 100644 ta/remoteproc/include/ta_remoteproc.h - create mode 100644 ta/remoteproc/include/user_ta_header_defines.h - create mode 100644 ta/remoteproc/remoteproc_core.c - create mode 100644 ta/remoteproc/sub.mk - create mode 100644 ta/remoteproc/user_ta.mk - -diff --git a/core/arch/arm/dts/stm32mp157a-dk1.dts b/core/arch/arm/dts/stm32mp157a-dk1.dts -index 4d506bce5..5d5c0a5f7 100644 ---- a/core/arch/arm/dts/stm32mp157a-dk1.dts -+++ b/core/arch/arm/dts/stm32mp157a-dk1.dts -@@ -36,8 +36,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/core/arch/arm/dts/stm32mp157a-ed1.dts b/core/arch/arm/dts/stm32mp157a-ed1.dts -index 4f84ec623..9da3e307e 100644 ---- a/core/arch/arm/dts/stm32mp157a-ed1.dts -+++ b/core/arch/arm/dts/stm32mp157a-ed1.dts -@@ -37,8 +37,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/core/arch/arm/dts/stm32mp157c-dk2.dts b/core/arch/arm/dts/stm32mp157c-dk2.dts -index 436a15970..ff5c4509f 100644 ---- a/core/arch/arm/dts/stm32mp157c-dk2.dts -+++ b/core/arch/arm/dts/stm32mp157c-dk2.dts -@@ -42,8 +42,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/core/arch/arm/dts/stm32mp157c-ed1.dts b/core/arch/arm/dts/stm32mp157c-ed1.dts -index 5aadb1ff0..a1e72f816 100644 ---- a/core/arch/arm/dts/stm32mp157c-ed1.dts -+++ b/core/arch/arm/dts/stm32mp157c-ed1.dts -@@ -42,8 +42,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/core/arch/arm/dts/stm32mp157d-dk1.dts b/core/arch/arm/dts/stm32mp157d-dk1.dts -index d320f993e..078bc717b 100644 ---- a/core/arch/arm/dts/stm32mp157d-dk1.dts -+++ b/core/arch/arm/dts/stm32mp157d-dk1.dts -@@ -40,8 +40,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/core/arch/arm/dts/stm32mp157d-ed1.dts b/core/arch/arm/dts/stm32mp157d-ed1.dts -index 76f0614d6..961e43d6a 100644 ---- a/core/arch/arm/dts/stm32mp157d-ed1.dts -+++ b/core/arch/arm/dts/stm32mp157d-ed1.dts -@@ -37,8 +37,8 @@ - DECPROT(STM32MP1_ETZPC_I2C6_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/core/arch/arm/dts/stm32mp157f-dk2.dts b/core/arch/arm/dts/stm32mp157f-dk2.dts -index 9c79bfb43..a8ed842e4 100644 ---- a/core/arch/arm/dts/stm32mp157f-dk2.dts -+++ b/core/arch/arm/dts/stm32mp157f-dk2.dts -@@ -46,8 +46,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/core/arch/arm/dts/stm32mp157f-ed1.dts b/core/arch/arm/dts/stm32mp157f-ed1.dts -index a659cf84d..729dae8af 100644 ---- a/core/arch/arm/dts/stm32mp157f-ed1.dts -+++ b/core/arch/arm/dts/stm32mp157f-ed1.dts -@@ -42,8 +42,8 @@ - DECPROT(STM32MP1_ETZPC_RNG1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_HASH1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) - DECPROT(STM32MP1_ETZPC_CRYP1_ID, DECPROT_NS_RW, DECPROT_UNLOCK) -- DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_S_RW, DECPROT_LOCK) -- DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_S_RW, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRCTRL_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) -+ DECPROT(STM32MP1_ETZPC_DDRPHYC_ID, DECPROT_NS_R_S_W, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_STGENC_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_BKPSRAM_ID, DECPROT_S_RW, DECPROT_LOCK) - DECPROT(STM32MP1_ETZPC_IWDG1_ID, DECPROT_S_RW, DECPROT_LOCK) -diff --git a/core/arch/arm/dts/stm32mp15xx-dkx.dtsi b/core/arch/arm/dts/stm32mp15xx-dkx.dtsi -index 7254f9a54..37a5525f3 100644 ---- a/core/arch/arm/dts/stm32mp15xx-dkx.dtsi -+++ b/core/arch/arm/dts/stm32mp15xx-dkx.dtsi -@@ -209,7 +209,7 @@ - regulator-max-microvolt = <3300000>; - regulator-always-on; - standby-ddr-sr { -- regulator-on-in-suspend; -+ regulator-off-in-suspend; - }; - standby-ddr-off { - regulator-off-in-suspend; -diff --git a/core/arch/arm/dts/stm32mp15xx-edx.dtsi b/core/arch/arm/dts/stm32mp15xx-edx.dtsi -index b7683a69a..4946f0cd0 100644 ---- a/core/arch/arm/dts/stm32mp15xx-edx.dtsi -+++ b/core/arch/arm/dts/stm32mp15xx-edx.dtsi -@@ -214,7 +214,7 @@ - regulator-max-microvolt = <3300000>; - regulator-always-on; - standby-ddr-sr { -- regulator-on-in-suspend; -+ regulator-off-in-suspend; - }; - standby-ddr-off { - regulator-off-in-suspend; -diff --git a/core/arch/arm/plat-stm32mp1/conf.mk b/core/arch/arm/plat-stm32mp1/conf.mk -index 8a449b521..6beef4635 100644 ---- a/core/arch/arm/plat-stm32mp1/conf.mk -+++ b/core/arch/arm/plat-stm32mp1/conf.mk -@@ -89,9 +89,15 @@ CFG_TEE_CORE_NB_CORE ?= 2 - CFG_WITH_PAGER ?= y - CFG_WITH_LPAE ?= y - CFG_WITH_STACK_CANARIES ?= y --CFG_MMAP_REGIONS ?= 25 -+CFG_MMAP_REGIONS ?= 30 - CFG_CORE_HEAP_SIZE ?= 49152 - -+# Disable early TA compression to limit HEAP size -+CFG_EARLY_TA_COMPRESS ?= n -+ -+# Embed public part of this key in OP-TEE OS -+CFG_RPROC_SIGN_KEY ?= keys/default_rproc.pem -+ - ifeq ($(CFG_EMBED_DTB_SOURCE_FILE),) - # Some drivers mandate DT support - $(call force,CFG_STM32_CLKCALIB,n) -@@ -101,6 +107,7 @@ $(call force,CFG_STM32_TIM,n) - $(call force,CFG_STPMIC1,n) - endif - -+CFG_RPROC_PTA ?= n - CFG_STM32_BSEC ?= y - CFG_STM32_CLKCALIB ?= y - CFG_STM32_CRYP ?= y -diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c -index b1b9f4366..15ea71519 100644 ---- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c -+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_calib.c -@@ -336,6 +336,11 @@ static void arm_timer_with_period(uint32_t period_sec) - { - timer_val = period_sec * read_cntfrq(); - -+ if (timer_val > INT32_MAX) -+ timer_val = INT32_MAX; -+ -+ DMSG("Calibration timeout set to %"PRIu32, timer_val / read_cntfrq()); -+ - arm_timer(); - } - -diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_etzpc.h b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_etzpc.h -deleted file mode 100644 -index 338a39283..000000000 ---- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_etzpc.h -+++ /dev/null -@@ -1,100 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ --/* -- * Copyright (C) 2018-2019, STMicroelectronics -- */ -- --#ifndef __STM32MP1_ETZPC_H --#define __STM32MP1_ETZPC_H -- --/* Define DECPROT IDs for stm32mp1 familly */ --#define STM32MP1_ETZPC_STGENC_ID 0 --#define STM32MP1_ETZPC_BKPSRAM_ID 1 --#define STM32MP1_ETZPC_IWDG1_ID 2 --#define STM32MP1_ETZPC_USART1_ID 3 --#define STM32MP1_ETZPC_SPI6_ID 4 --#define STM32MP1_ETZPC_I2C4_ID 5 --#define STM32MP1_ETZPC_GPIOZ_ID 6 --#define STM32MP1_ETZPC_RNG1_ID 7 --#define STM32MP1_ETZPC_HASH1_ID 8 --#define STM32MP1_ETZPC_CRYP1_ID 9 --#define STM32MP1_ETZPC_DDRCTRL_ID 10 --#define STM32MP1_ETZPC_DDRPHYC_ID 11 --#define STM32MP1_ETZPC_I2C6_ID 12 --/* 13-15 Reserved */ --#define STM32MP1_ETZPC_TIM2_ID 16 --#define STM32MP1_ETZPC_TIM3_ID 17 --#define STM32MP1_ETZPC_TIM4_ID 18 --#define STM32MP1_ETZPC_TIM5_ID 19 --#define STM32MP1_ETZPC_TIM6_ID 20 --#define STM32MP1_ETZPC_TIM7_ID 21 --#define STM32MP1_ETZPC_TIM12_ID 22 --#define STM32MP1_ETZPC_TIM13_ID 23 --#define STM32MP1_ETZPC_TIM14_ID 24 --#define STM32MP1_ETZPC_LPTIM1_ID 25 --#define STM32MP1_ETZPC_WWDG1_ID 26 --#define STM32MP1_ETZPC_SPI2_ID 27 --#define STM32MP1_ETZPC_SPI3_ID 28 --#define STM32MP1_ETZPC_SPDIFRX_ID 29 --#define STM32MP1_ETZPC_USART2_ID 30 --#define STM32MP1_ETZPC_USART3_ID 31 --#define STM32MP1_ETZPC_UART4_ID 32 --#define STM32MP1_ETZPC_UART5_ID 33 --#define STM32MP1_ETZPC_I2C1_ID 34 --#define STM32MP1_ETZPC_I2C2_ID 35 --#define STM32MP1_ETZPC_I2C3_ID 36 --#define STM32MP1_ETZPC_I2C5_ID 37 --#define STM32MP1_ETZPC_CEC_ID 38 --#define STM32MP1_ETZPC_DAC_ID 39 --#define STM32MP1_ETZPC_UART7_ID 40 --#define STM32MP1_ETZPC_UART8_ID 41 --/* 42-43 Reserved */ --#define STM32MP1_ETZPC_MDIOS_ID 44 --/* 45-47 Reserved */ --#define STM32MP1_ETZPC_TIM1_ID 48 --#define STM32MP1_ETZPC_TIM8_ID 49 --/* 50 Reserved */ --#define STM32MP1_ETZPC_USART6_ID 51 --#define STM32MP1_ETZPC_SPI1_ID 52 --#define STM32MP1_ETZPC_SPI4_ID 53 --#define STM32MP1_ETZPC_TIM15_ID 54 --#define STM32MP1_ETZPC_TIM16_ID 55 --#define STM32MP1_ETZPC_TIM17_ID 56 --#define STM32MP1_ETZPC_SPI5_ID 57 --#define STM32MP1_ETZPC_SAI1_ID 58 --#define STM32MP1_ETZPC_SAI2_ID 59 --#define STM32MP1_ETZPC_SAI3_ID 60 --#define STM32MP1_ETZPC_DFSDM_ID 61 --#define STM32MP1_ETZPC_TT_FDCAN_ID 62 --/* 63 Reserved */ --#define STM32MP1_ETZPC_LPTIM2_ID 64 --#define STM32MP1_ETZPC_LPTIM3_ID 65 --#define STM32MP1_ETZPC_LPTIM4_ID 66 --#define STM32MP1_ETZPC_LPTIM5_ID 67 --#define STM32MP1_ETZPC_SAI4_ID 68 --#define STM32MP1_ETZPC_VREFBUF_ID 69 --#define STM32MP1_ETZPC_DCMI_ID 70 --#define STM32MP1_ETZPC_CRC2_ID 71 --#define STM32MP1_ETZPC_ADC_ID 72 --#define STM32MP1_ETZPC_HASH2_ID 73 --#define STM32MP1_ETZPC_RNG2_ID 74 --#define STM32MP1_ETZPC_CRYP2_ID 75 --/* 76-79 Reserved */ --#define STM32MP1_ETZPC_SRAM1_ID 80 --#define STM32MP1_ETZPC_SRAM2_ID 81 --#define STM32MP1_ETZPC_SRAM3_ID 82 --#define STM32MP1_ETZPC_SRAM4_ID 83 --#define STM32MP1_ETZPC_RETRAM_ID 84 --#define STM32MP1_ETZPC_OTG_ID 85 --#define STM32MP1_ETZPC_SDMMC3_ID 86 --#define STM32MP1_ETZPC_DLYBSD3_ID 87 --#define STM32MP1_ETZPC_DMA1_ID 88 --#define STM32MP1_ETZPC_DMA2_ID 89 --#define STM32MP1_ETZPC_DMAMUX_ID 90 --#define STM32MP1_ETZPC_FMC_ID 91 --#define STM32MP1_ETZPC_QSPI_ID 92 --#define STM32MP1_ETZPC_DLYBQ_ID 93 --#define STM32MP1_ETZPC_ETH_ID 94 --/* 95 Reserved */ --#define STM32MP1_ETZPC_MAX_ID 96 -- --#endif /*__STM32MP1_ETZPC_H*/ -diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.c -index 3c3dd5e49..c07be0c53 100644 ---- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.c -+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_rcc.c -@@ -76,3 +76,20 @@ TEE_Result stm32_reset_deassert(unsigned int id, unsigned int to_us) - - return TEE_SUCCESS; - } -+ -+TEE_Result stm32_reset_assert_deassert_mcu(bool assert_not_deassert) -+{ -+ vaddr_t rcc_base = stm32_rcc_base(); -+ -+ /* -+ * The RCC_MP_GCR is a read/write register. -+ * Assert the MCU HOLD_BOOT means clear the BOOT_MCU bit -+ * Deassert the MCU HOLD_BOOT means set the BOOT_MCU the bit -+ */ -+ if (assert_not_deassert) -+ io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); -+ else -+ io_setbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); -+ -+ return TEE_SUCCESS; -+} -diff --git a/core/arch/arm/plat-stm32mp1/main.c b/core/arch/arm/plat-stm32mp1/main.c -index 40e426331..07af9fc1a 100644 ---- a/core/arch/arm/plat-stm32mp1/main.c -+++ b/core/arch/arm/plat-stm32mp1/main.c -@@ -11,11 +11,11 @@ - #include - #include - #include --#include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -102,6 +102,14 @@ register_dynamic_shm(TZDRAM_END, DRAM_END - TZDRAM_END); - /* Map non-secure DDR bottom for the low power sequence */ - register_phys_mem(MEM_AREA_RAM_NSEC, DDR_BASE, SMALL_PAGE_SIZE); - -+#ifdef CFG_RPROC_PTA -+/* Map MCU RETRAM as read write for Cortex-M4 firmware management */ -+register_phys_mem(MEM_AREA_IO_SEC, RETRAM_BASE, RETRAM_SIZE); -+ -+/* Map MCU SRAM as read write for Cortex-M4 firmware management */ -+register_phys_mem(MEM_AREA_IO_SEC, MCUSRAM_BASE, MCUSRAM_SIZE); -+#endif -+ - /* Map TEE physical RAM as read-only for content storage when suspending */ - register_phys_mem(MEM_AREA_ROM_SEC, TEE_RAM_START, TEE_RAM_PH_SIZE); - -@@ -549,6 +557,22 @@ bool stm32mp_supports_cpu_opp(uint32_t opp_id) - } - } - -+enum etzpc_decprot_attributes stm32mp_etzpc_binding2decprot(uint32_t mode) -+{ -+ switch (mode) { -+ case DECPROT_S_RW: -+ return ETZPC_DECPROT_S_RW; -+ case DECPROT_NS_R_S_W: -+ return ETZPC_DECPROT_NS_R_S_W; -+ case DECPROT_MCU_ISOLATION: -+ return ETZPC_DECPROT_MCU_ISOLATION; -+ case DECPROT_NS_RW: -+ return ETZPC_DECPROT_NS_RW; -+ default: -+ panic(); -+ } -+} -+ - unsigned int stm32mp_iwdg_irq2instance(size_t irq) - { - int id = irq - STM32MP1_IRQ_IWDG1; -diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c b/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c -index 362e6d651..d2824c609 100644 ---- a/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c -+++ b/core/arch/arm/plat-stm32mp1/nsec-service/rcc_svc.c -@@ -6,7 +6,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -16,29 +15,10 @@ - #include "rcc_svc.h" - #include "stm32mp1_smc.h" - --#undef FULL_RCC_ACCESS -- - static bool offset_is_clear_register(uint32_t __maybe_unused offset) - { --#ifdef FULL_RCC_ACCESS -- switch (offset) { -- case RCC_OCENCLRR: -- case RCC_MP_SREQCLRR: -- case RCC_APB5RSTCLRR: -- case RCC_AHB5RSTCLRR: -- case RCC_MP_APB5ENCLRR: -- case RCC_MP_AHB5ENCLRR: -- case RCC_MP_APB5LPENCLRR: -- case RCC_MP_AHB5LPENCLRR: -- case RCC_MP_IWDGFZCLRR: -- return true; -- default: -- return false; -- } --#else - /* All allowed registers are non set/clear registers */ - return false; --#endif - } - - static void access_allowed_mask(uint32_t request, uint32_t offset, -@@ -85,8 +65,8 @@ static void access_allowed_mask(uint32_t request, uint32_t offset, - } - } - --static void raw_allowed_access_request(uint32_t request, -- uint32_t offset, uint32_t value) -+static uint32_t raw_allowed_access_request(uint32_t request, -+ uint32_t offset, uint32_t value) - { - uint32_t allowed_mask = 0; - -@@ -95,50 +75,13 @@ static void raw_allowed_access_request(uint32_t request, - case RCC_MP_CIFR: - allowed_mask = RCC_MP_CIFR_WKUPF; - break; -- case RCC_MP_GCR: -- allowed_mask = RCC_MP_GCR_BOOT_MCU; -- break; -- --#ifdef FULL_RCC_ACCESS -- case RCC_OCENSETR: -- case RCC_OCENCLRR: -- case RCC_HSICFGR: -- case RCC_CSICFGR: -- case RCC_MP_BOOTCR: /* Allowed MPU/MCU reboot cfg */ -- case RCC_MP_GCR: /* Allowed MPU/MCU reboot cfg */ -- case RCC_MP_GRSTCSETR: /* Allowed MCU and system reset */ -- case RCC_BR_RSTSCLRR: /* Allowed system reset status */ -- case RCC_MC_RSTSCLRR: /* Allowed system reset status */ -- case RCC_MP_RSTSCLRR: /* Allowed system reset status */ -- case RCC_BDCR: -- case RCC_RDLSICR: -- case RCC_APB5RSTSETR: -- case RCC_APB5RSTCLRR: -- case RCC_MP_APB5ENSETR: -- case RCC_MP_APB5ENCLRR: -- case RCC_MP_APB5LPENSETR: -- case RCC_MP_APB5LPENCLRR: -- case RCC_AHB5RSTSETR: -- case RCC_AHB5RSTCLRR: -- case RCC_MP_AHB5ENSETR: -- case RCC_MP_AHB5ENCLRR: -- case RCC_MP_AHB5LPENSETR: -- case RCC_MP_AHB5LPENCLRR: -- case RCC_RTCDIVR: -- case RCC_I2C46CKSELR: -- case RCC_SPI6CKSELR: -- case RCC_UART1CKSELR: -- case RCC_RNG1CKSELR: -- case RCC_MP_IWDGFZSETR: -- case RCC_MP_IWDGFZCLRR: -- allowed_mask = UINT32_MAX; -- break; --#endif - default: -- panic(); -+ return STM32_SIP_SVC_INVALID_PARAMS; - } - - access_allowed_mask(request, offset, value, allowed_mask); -+ -+ return STM32_SIP_SVC_OK; - } - - uint32_t rcc_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3) -@@ -163,9 +106,7 @@ uint32_t rcc_scv_handler(uint32_t x1, uint32_t x2, uint32_t x3) - request == STM32_SIP_SVC_REG_SET ? "set" : "clear", - value, offset); - -- raw_allowed_access_request(request, offset, value); -- -- return STM32_SIP_SVC_OK; -+ return raw_allowed_access_request(request, offset, value); - } - - uint32_t rcc_opp_scv_handler(uint32_t x1, uint32_t x2, uint32_t *res) -diff --git a/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h b/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h -index 86deb592b..a1f0e5859 100644 ---- a/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h -+++ b/core/arch/arm/plat-stm32mp1/nsec-service/stm32mp1_smc.h -@@ -133,7 +133,9 @@ - #define STM32_SIP_SVC_BSEC_PROG_OTP 0x2 - #define STM32_SIP_SVC_BSEC_WRITE_SHADOW 0x3 - #define STM32_SIP_SVC_BSEC_READ_OTP 0x4 --#define STM32_SIP_SVC_BSEC_WRLOCK_OTP 0x5 -+/* reserved for STM32_SIP_SVC_SMC_READ_ALL 0x5 */ -+/* reserved for STM32_SIP_SVC_SMC_WRITE_ALL 0x6 */ -+#define STM32_SIP_SVC_BSEC_WRLOCK_OTP 0x7 - - /* - * SIP functions STM32_SIP_FUNC_SR_MODE -diff --git a/core/arch/arm/plat-stm32mp1/platform_config.h b/core/arch/arm/plat-stm32mp1/platform_config.h -index 2b4bd95b5..0ea5efc32 100644 ---- a/core/arch/arm/plat-stm32mp1/platform_config.h -+++ b/core/arch/arm/plat-stm32mp1/platform_config.h -@@ -39,6 +39,8 @@ - #endif /*CFG_WITH_PAGER*/ - - /* SoC interface registers base address */ -+#define MCUSRAM_BASE 0x30000000ul -+#define RETRAM_BASE 0x38000000ul - #define BKPSRAM_BASE 0x54000000 - #define BSEC_BASE 0x5c005000 - #define ETZPC_BASE 0x5c007000 -@@ -238,6 +240,12 @@ - #define SYSRAM_SEC_SIZE SYSRAM_SIZE - #endif - -+/* RETRAM layout */ -+#define RETRAM_SIZE 0x10000 -+ -+/* MCUSRAM layout */ -+#define MCUSRAM_SIZE 0x60000 -+ - /* SoC part numbers and revisions */ - #define STM32MP1_CHIP_ID 0x500 - -diff --git a/core/arch/arm/plat-stm32mp1/remoteproc_pta.c b/core/arch/arm/plat-stm32mp1/remoteproc_pta.c -new file mode 100644 -index 000000000..f8458336f ---- /dev/null -+++ b/core/arch/arm/plat-stm32mp1/remoteproc_pta.c -@@ -0,0 +1,528 @@ -+ // SPDX-License-Identifier: BSD-2-Clause -+ /* -+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define PTA_NAME "remoteproc.pta" -+ -+#define STM32_M4_FW_ID 0 -+ -+/* Firmware states */ -+enum rproc_load_state { -+ REMOTEPROC_OFF = 0, -+ REMOTEPROC_ON, -+}; -+ -+/* -+ * struct rproc_ta_etzpc_rams - memory protection strategy table -+ * @pa - Memory physical base address from current CPU space -+ * @size - Memory region byte size -+ * @etzpc_id - associated ETZPC identifier. -+ * @attr - memory access permission according to @etzpc_decprot_attributes -+ */ -+struct rproc_ta_etzpc_rams { -+ paddr_t pa; -+ size_t size; -+ uint32_t etzpc_id; -+ enum etzpc_decprot_attributes attr; -+}; -+ -+/* -+ * struct rproc_ta_memory_region - Represent a remote processor memory mapping -+ * @pa - Memory physical base address from current CPU space -+ * @da - Memory physical base address from remote processor space -+ * @size - Memory region byte size -+ */ -+struct rproc_ta_memory_region { -+ paddr_t pa; -+ paddr_t da; -+ size_t size; -+}; -+ -+static const struct rproc_ta_etzpc_rams rproc_ta_mp1_m4_rams[] = { -+ /* MCU SRAM 1*/ -+ { -+ .pa = MCUSRAM_BASE, -+ .size = 0x20000, -+ .etzpc_id = STM32MP1_ETZPC_SRAM1_ID, -+ .attr = ETZPC_DECPROT_MCU_ISOLATION, -+ }, -+ /* MCU SRAM 2*/ -+ { -+ .pa = MCUSRAM_BASE + 0x20000, -+ .size = 0x20000, -+ .etzpc_id = STM32MP1_ETZPC_SRAM2_ID, -+ .attr = ETZPC_DECPROT_MCU_ISOLATION, -+ }, -+ -+ /* MCU SRAM 3*/ -+ { -+ /* Used as shared memory between the NS and the coprocessor */ -+ .pa = MCUSRAM_BASE + 0x40000, -+ .size = 0x10000, -+ .etzpc_id = STM32MP1_ETZPC_SRAM3_ID, -+ .attr = ETZPC_DECPROT_NS_RW, -+ }, -+ /* MCU SRAM 4*/ -+ /* Not used reserved by NS for MDMA */ -+ { -+ .pa = MCUSRAM_BASE + 0x50000, -+ .size = 0x10000, -+ .etzpc_id = STM32MP1_ETZPC_SRAM4_ID, -+ .attr = ETZPC_DECPROT_NS_RW, -+ }, -+ -+ /* MCU RETRAM */ -+ { -+ .pa = RETRAM_BASE, -+ .size = RETRAM_SIZE, -+ .etzpc_id = STM32MP1_ETZPC_RETRAM_ID, -+ .attr = ETZPC_DECPROT_MCU_ISOLATION, -+ }, -+}; -+ -+static const struct rproc_ta_memory_region rproc_ta_mp1_m4_mems[] = { -+ /* MCU SRAM */ -+ { .pa = MCUSRAM_BASE, .da = 0x10000000, .size = MCUSRAM_SIZE }, -+ /* Alias of the MCU SRAM */ -+ { .pa = MCUSRAM_BASE, .da = 0x30000000, .size = MCUSRAM_SIZE }, -+ /* RETRAM */ -+ { .pa = RETRAM_BASE, .da = 0x00000000, .size = RETRAM_SIZE }, -+}; -+ -+static enum rproc_load_state rproc_ta_state; -+ -+static TEE_Result rproc_pta_capabilities(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_OUTPUT, -+ TEE_PARAM_TYPE_VALUE_OUTPUT, -+ TEE_PARAM_TYPE_NONE); -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ /* Support only ELF format */ -+ params[1].value.a = PTA_REMOTEPROC_ELF_FMT; -+ -+ /* -+ * Due to stm32mp1 pager, secure memory is too expensive. Support hash -+ * protected image only, so that firmware image can be loaded from -+ * non-secure memory. -+ */ -+ params[2].value.a = PTA_REMOTEPROC_FW_WITH_HASH_TABLE; -+ -+ return TEE_SUCCESS; -+} -+ -+static TEE_Result da_to_pa(paddr_t da, size_t size, paddr_t *pa) -+{ -+ const struct rproc_ta_memory_region *mems = rproc_ta_mp1_m4_mems; -+ size_t i = 0; -+ -+ DMSG("da addr: %#"PRIxPA" size: %zu", da, size); -+ -+ for (i = 0; i < ARRAY_SIZE(rproc_ta_mp1_m4_mems); i++) { -+ if (da >= mems[i].da && -+ (da + size) <= (mems[i].da + mems[i].size)) { -+ *pa = da - mems[i].da + mems[i].pa; -+ DMSG("da %#"PRIxPA" to pa %#"PRIxPA, da, *pa); -+ -+ return TEE_SUCCESS; -+ } -+ } -+ -+ return TEE_ERROR_ACCESS_DENIED; -+} -+ -+static TEE_Result rproc_pta_load_segment(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT); -+ TEE_Result res = TEE_ERROR_GENERIC; -+ paddr_t pa = 0; -+ uint8_t *dst = 0; -+ uint8_t *src = params[1].memref.buffer; -+ size_t size = params[1].memref.size; -+ uint8_t *hash = params[3].memref.buffer; -+ paddr_t da = (paddr_t)reg_pair_to_64(params[2].value.b, -+ params[2].value.a); -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ if (!hash || params[3].memref.size != TEE_SHA256_HASH_SIZE) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ /* Only STM32_M4_FW_ID supported */ -+ if (params[0].value.a != STM32_M4_FW_ID) { -+ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); -+ return TEE_ERROR_NOT_SUPPORTED; -+ } -+ -+ if (rproc_ta_state != REMOTEPROC_OFF) -+ return TEE_ERROR_BAD_STATE; -+ -+ /* Get the physical address in A7 mapping */ -+ res = da_to_pa(da, size, &pa); -+ if (res) -+ return res; -+ -+ /* Get the associated va */ -+ dst = (void *)core_mmu_get_va(pa, MEM_AREA_IO_SEC); -+ -+ /* Copy the segment to the remote processor memory*/ -+ memcpy(dst, src, size); -+ -+ /* Verify that loaded segment is valid */ -+ res = hash_sha256_check(hash, dst, size); -+ if (res) -+ memset(dst, 0, size); -+ -+ return res; -+} -+ -+static TEE_Result rproc_pta_set_memory(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT); -+ TEE_Result res = TEE_ERROR_GENERIC; -+ paddr_t pa = 0; -+ vaddr_t dst = 0; -+ paddr_t da = params[1].value.a; -+ size_t size = params[2].value.a; -+ char value = (char)params[3].value.a; -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ /* Only STM32_M4_FW_ID supported */ -+ if (params[0].value.a != STM32_M4_FW_ID) { -+ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); -+ return TEE_ERROR_NOT_SUPPORTED; -+ } -+ -+ if (rproc_ta_state != REMOTEPROC_OFF) -+ return TEE_ERROR_BAD_STATE; -+ -+ /* Get the physical address in CPU mapping */ -+ res = da_to_pa(da, size, &pa); -+ if (res) -+ return res; -+ -+ dst = core_mmu_get_va(pa, MEM_AREA_IO_SEC); -+ -+ memset((void *)dst, value, size); -+ -+ return TEE_SUCCESS; -+} -+ -+static TEE_Result rproc_pta_da_to_pa(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_OUTPUT); -+ TEE_Result res = TEE_ERROR_GENERIC; -+ paddr_t da = params[1].value.a; -+ size_t size = params[2].value.a; -+ paddr_t pa = 0; -+ -+ DMSG("Conversion for address %#"PRIxPA" size %zu", da, size); -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ /* Only STM32_M4_FW_ID supported */ -+ if (params[0].value.a != STM32_M4_FW_ID) { -+ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); -+ return TEE_ERROR_NOT_SUPPORTED; -+ } -+ -+ /* Target address is expected 32bit, ensure 32bit MSB are zero */ -+ if (params[1].value.b || params[2].value.b) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ res = da_to_pa(da, size, &pa); -+ if (res) -+ return res; -+ -+ reg_pair_from_64((uint64_t)pa, ¶ms[3].value.b, ¶ms[3].value.a); -+ -+ return TEE_SUCCESS; -+} -+ -+static void rproc_pta_mem_protect(bool secure_access) -+{ -+ unsigned int i = 0; -+ const struct rproc_ta_etzpc_rams *ram = NULL; -+ -+ /* -+ * MCU RAM banks access permissions for MCU memories depending on -+ * rproc_ta_mp1_m4_rams[]. -+ * If memory bank is declared as MCU isolated: -+ * if secure_access then set to secure world read/write permission -+ * else set to MCU isolated -+ * else apply memory permission as defined in rproc_ta_mp1_m4_rams[]. -+ */ -+ for (i = 0; i < ARRAY_SIZE(rproc_ta_mp1_m4_rams); i++) { -+ enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX; -+ -+ ram = &rproc_ta_mp1_m4_rams[i]; -+ attr = ram->attr; -+ -+ if (secure_access && attr == ETZPC_DECPROT_MCU_ISOLATION) -+ attr = ETZPC_DECPROT_S_RW; -+ -+ etzpc_configure_decprot(ram->etzpc_id, attr); -+ } -+} -+ -+static TEE_Result rproc_pta_start(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_NONE, -+ TEE_PARAM_TYPE_NONE, -+ TEE_PARAM_TYPE_NONE); -+ vaddr_t rcc_base = stm32_rcc_base(); -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ /* Only STM32_M4_FW_ID supported */ -+ if (params[0].value.a != STM32_M4_FW_ID) { -+ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); -+ return TEE_ERROR_NOT_SUPPORTED; -+ } -+ -+ if (rproc_ta_state != REMOTEPROC_OFF) -+ return TEE_ERROR_BAD_STATE; -+ -+ stm32_clock_enable(CK_MCU); -+ -+ /* Configure the Cortex-M4 RAMs as expected to run the firmware */ -+ rproc_pta_mem_protect(false); -+ -+ /* -+ * The firmware is started by deasserting the hold boot and -+ * asserting back to avoid auto restart on a crash. -+ * No need to release the MCU reset as it is automatically released by -+ * the hardware. -+ */ -+ io_setbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); -+ io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); -+ -+ rproc_ta_state = REMOTEPROC_ON; -+ -+ return TEE_SUCCESS; -+} -+ -+static TEE_Result rproc_pta_stop(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_NONE, -+ TEE_PARAM_TYPE_NONE, -+ TEE_PARAM_TYPE_NONE); -+ const struct rproc_ta_etzpc_rams *ram = NULL; -+ vaddr_t rcc_base = stm32_rcc_base(); -+ unsigned int i = 0; -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ /* Only STM32_M4_FW_ID supported */ -+ if (params[0].value.a != STM32_M4_FW_ID) { -+ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); -+ return TEE_ERROR_NOT_SUPPORTED; -+ } -+ -+ if (rproc_ta_state != REMOTEPROC_ON) -+ return TEE_ERROR_BAD_STATE; -+ -+ /* The firmware is stopped (reset with holdboot is active) */ -+ io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); -+ -+ stm32_reset_set(MCU_R); -+ -+ stm32_clock_disable(CK_MCU); -+ -+ /* -+ * Cortex-M4 memories are cleaned and access rights restored for the -+ * secure context. -+ */ -+ rproc_pta_mem_protect(true); -+ for (i = 0; i < ARRAY_SIZE(rproc_ta_mp1_m4_rams); i++) { -+ ram = &rproc_ta_mp1_m4_rams[i]; -+ if (ram->attr == ETZPC_DECPROT_MCU_ISOLATION) { -+ memset((void *)core_mmu_get_va(ram->pa, -+ MEM_AREA_IO_SEC), -+ 0, ram->size); -+ } -+ } -+ rproc_ta_state = REMOTEPROC_OFF; -+ -+ return TEE_SUCCESS; -+} -+ -+static TEE_Result rproc_pta_verify_rsa_signature(TEE_Param *hash, -+ TEE_Param *sig, uint32_t algo) -+{ -+ struct rsa_public_key key = { }; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ uint32_t e = TEE_U32_TO_BIG_ENDIAN(rproc_pub_key_exponent); -+ size_t hash_size = (size_t)hash->memref.size; -+ size_t sig_size = (size_t)sig->memref.size; -+ -+ res = crypto_acipher_alloc_rsa_public_key(&key, sig_size); -+ if (res) -+ return TEE_ERROR_SECURITY; -+ -+ res = crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key.e); -+ if (res) -+ goto out; -+ -+ res = crypto_bignum_bin2bn(rproc_pub_key_modulus, -+ rproc_pub_key_modulus_size, key.n); -+ if (res) -+ goto out; -+ -+ res = crypto_acipher_rsassa_verify(algo, &key, hash_size, -+ hash->memref.buffer, hash_size, -+ sig->memref.buffer, sig_size); -+ -+out: -+ crypto_acipher_free_rsa_public_key(&key); -+ -+ return res; -+} -+ -+static TEE_Result rproc_pta_verify_digest(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ struct rproc_pta_key_info *keyinfo = NULL; -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT); -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ /* Only STM32_M4_FW_ID supported */ -+ if (params[0].value.a != STM32_M4_FW_ID) { -+ EMSG("Unsupported firmware ID %#"PRIx32, params[0].value.a); -+ return TEE_ERROR_NOT_SUPPORTED; -+ } -+ -+ if (rproc_ta_state != REMOTEPROC_OFF) -+ return TEE_ERROR_BAD_STATE; -+ -+ keyinfo = params[1].memref.buffer; -+ -+ if (!keyinfo || -+ RPROC_PTA_GET_KEYINFO_SIZE(keyinfo) != params[1].memref.size) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ if (keyinfo->algo != TEE_ALG_RSASSA_PKCS1_V1_5_SHA256) -+ return TEE_ERROR_NOT_SUPPORTED; -+ -+ return rproc_pta_verify_rsa_signature(¶ms[2], ¶ms[3], -+ keyinfo->algo); -+} -+ -+static TEE_Result rproc_pta_invoke_command(void *pSessionContext __unused, -+ uint32_t cmd_id, -+ uint32_t param_types, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ switch (cmd_id) { -+ case PTA_REMOTEPROC_HW_CAPABILITIES: -+ return rproc_pta_capabilities(param_types, params); -+ case PTA_REMOTEPROC_LOAD_SEGMENT_SHA256: -+ return rproc_pta_load_segment(param_types, params); -+ case PTA_REMOTEPROC_SET_MEMORY: -+ return rproc_pta_set_memory(param_types, params); -+ case PTA_REMOTEPROC_FIRMWARE_START: -+ return rproc_pta_start(param_types, params); -+ case PTA_REMOTEPROC_FIRMWARE_STOP: -+ return rproc_pta_stop(param_types, params); -+ case PTA_REMOTEPROC_FIRMWARE_DA_TO_PA: -+ return rproc_pta_da_to_pa(param_types, params); -+ case PTA_REMOTEPROC_VERIFY_DIGEST: -+ return rproc_pta_verify_digest(param_types, params); -+ default: -+ break; -+ } -+ -+ return TEE_ERROR_NOT_IMPLEMENTED; -+} -+ -+/* -+ * Trusted Application entry points -+ */ -+static TEE_Result -+ rproc_pta_open_session(uint32_t param_types __unused, -+ TEE_Param params[TEE_NUM_PARAMS] __unused, -+ void **sess_ctx __unused) -+{ -+ struct tee_ta_session *s = tee_ta_get_calling_session(); -+ -+ /* Check that we're called from a user TA */ -+ if (!s) -+ return TEE_ERROR_ACCESS_DENIED; -+ -+ if (!is_user_ta_ctx(s->ctx)) -+ return TEE_ERROR_ACCESS_DENIED; -+ -+ return TEE_SUCCESS; -+} -+ -+static TEE_Result rproc_pta_init(void) -+{ -+ TEE_Result ret = TEE_ERROR_GENERIC; -+ vaddr_t rcc_base = stm32_rcc_base(); -+ -+ /* Configure the Cortex-M4 rams access right for secure context only */ -+ rproc_pta_mem_protect(true); -+ -+ /* Initialise the context */ -+ rproc_ta_state = REMOTEPROC_OFF; -+ -+ /* Ensure that the MCU is HOLD */ -+ io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU); -+ stm32_reset_set(MCU_R); -+ -+ return TEE_SUCCESS; -+} -+service_init_late(rproc_pta_init); -+ -+pseudo_ta_register(.uuid = PTA_REMOTEPROC_UUID, .name = PTA_NAME, -+ .flags = PTA_DEFAULT_FLAGS, -+ .invoke_command_entry_point = rproc_pta_invoke_command, -+ .open_session_entry_point = rproc_pta_open_session); -diff --git a/core/arch/arm/plat-stm32mp1/rproc_pub_key.h b/core/arch/arm/plat-stm32mp1/rproc_pub_key.h -new file mode 100644 -index 000000000..9b1db4271 ---- /dev/null -+++ b/core/arch/arm/plat-stm32mp1/rproc_pub_key.h -@@ -0,0 +1,16 @@ -+/* SPDX-License-Identifier: BSD-2-Clause */ -+/* -+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved -+ */ -+ -+#ifndef RPROC_PUB_KEY_H -+#define RPROC_PUB_KEY_H -+ -+#include -+ -+extern const uint32_t rproc_pub_key_exponent; -+extern const uint8_t rproc_pub_key_modulus[]; -+extern const size_t rproc_pub_key_modulus_size; -+ -+#endif /*RPROC_PUB_KEY_H*/ -+ -diff --git a/core/arch/arm/plat-stm32mp1/scmi_server.c b/core/arch/arm/plat-stm32mp1/scmi_server.c -index 5116b897a..2a0bdde4a 100644 ---- a/core/arch/arm/plat-stm32mp1/scmi_server.c -+++ b/core/arch/arm/plat-stm32mp1/scmi_server.c -@@ -135,6 +135,7 @@ struct stm32_scmi_rd stm32_scmi0_reset_domain[] = { - RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"), - RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"), - RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"), -+ RESET_CELL(RST_SCMI0_MCU_HOLD_BOOT, MCU_HOLD_BOOT_R, "mcu_hold_boot"), - }; - - struct scmi_agent_resources { -@@ -329,6 +330,7 @@ int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id, - - if (!clock) - return SCMI_NOT_FOUND; -+ - if (!stm32mp_nsec_can_access_clock(clock->clock_id)) - return SCMI_DENIED; - -@@ -445,6 +447,9 @@ int32_t plat_scmi_rd_autonomous(unsigned int agent_id, unsigned int scmi_id, - if (!stm32mp_nsec_can_access_reset(rd->reset_id)) - return SCMI_DENIED; - -+ if (rd->reset_id == MCU_HOLD_BOOT_R) -+ return SCMI_NOT_SUPPORTED; -+ - /* Supports only reset with context loss */ - if (state) - return SCMI_NOT_SUPPORTED; -@@ -471,6 +476,13 @@ int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id, - if (!stm32mp_nsec_can_access_reset(rd->reset_id)) - return SCMI_DENIED; - -+ if (rd->reset_id == MCU_HOLD_BOOT_R) { -+ DMSG("SCMI MCU hold boot %s", -+ assert_not_deassert ? "set" : "release"); -+ stm32_reset_assert_deassert_mcu(assert_not_deassert); -+ return SCMI_SUCCESS; -+ } -+ - if (assert_not_deassert) { - DMSG("SCMI reset %u set", scmi_id); - stm32_reset_set(rd->reset_id); -diff --git a/core/arch/arm/plat-stm32mp1/shared_resources.c b/core/arch/arm/plat-stm32mp1/shared_resources.c -index 08aa9a3f0..2726942ce 100644 ---- a/core/arch/arm/plat-stm32mp1/shared_resources.c -+++ b/core/arch/arm/plat-stm32mp1/shared_resources.c -@@ -5,10 +5,10 @@ - - #include - #include --#include - #include - #include - #include -+#include - #include - #include - #include -@@ -147,6 +147,9 @@ static const char __maybe_unused *shres2str_id_tbl[STM32MP1_SHRES_COUNT] = { - - static __maybe_unused const char *shres2str_id(enum stm32mp_shres id) - { -+ if (id >= ARRAY_SIZE(shres2str_id_tbl)) -+ panic("Invalid shared resource ID"); -+ - return shres2str_id_tbl[id]; - } - -@@ -407,6 +410,91 @@ void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin) - } - } - -+#ifdef CFG_STM32_ETZPC -+struct shres2decprot { -+ enum stm32mp_shres shres_id; -+ unsigned int decprot_id; -+}; -+ -+#define SHRES2DECPROT(shres, decprot) { \ -+ .shres_id = shres, \ -+ .decprot_id = decprot, \ -+ } -+ -+static const struct shres2decprot shres2decprot_tbl[] = { -+ SHRES2DECPROT(STM32MP1_SHRES_IWDG1, STM32MP1_ETZPC_IWDG1_ID), -+ SHRES2DECPROT(STM32MP1_SHRES_USART1, STM32MP1_ETZPC_USART1_ID), -+ SHRES2DECPROT(STM32MP1_SHRES_SPI6, STM32MP1_ETZPC_SPI6_ID), -+ SHRES2DECPROT(STM32MP1_SHRES_I2C4, STM32MP1_ETZPC_I2C4_ID), -+ SHRES2DECPROT(STM32MP1_SHRES_RNG1, STM32MP1_ETZPC_RNG1_ID), -+ SHRES2DECPROT(STM32MP1_SHRES_HASH1, STM32MP1_ETZPC_HASH1_ID), -+ SHRES2DECPROT(STM32MP1_SHRES_CRYP1, STM32MP1_ETZPC_CRYP1_ID), -+ SHRES2DECPROT(STM32MP1_SHRES_I2C6, STM32MP1_ETZPC_I2C6_ID), -+}; -+ -+static enum stm32mp_shres decprot2shres(unsigned int decprot_id) -+{ -+ size_t i = 0; -+ -+ for (i = 0; i < ARRAY_SIZE(shres2decprot_tbl); i++) -+ if (shres2decprot_tbl[i].decprot_id == decprot_id) -+ return shres2decprot_tbl[i].shres_id; -+ -+ DMSG("No shared resource for DECPROT ID %u", decprot_id); -+ return STM32MP1_SHRES_COUNT; -+} -+ -+void stm32mp_register_etzpc_decprot(unsigned int id, -+ enum etzpc_decprot_attributes attr) -+{ -+ enum shres_state state = SHRES_SECURE; -+ bool write_secure = false; -+ unsigned int id_shres = STM32MP1_SHRES_COUNT; -+ -+ switch (attr) { -+ case ETZPC_DECPROT_S_RW: -+ state = SHRES_SECURE; -+ break; -+ case ETZPC_DECPROT_NS_R_S_W: -+ case ETZPC_DECPROT_MCU_ISOLATION: -+ case ETZPC_DECPROT_NS_RW: -+ state = SHRES_NON_SECURE; -+ break; -+ default: -+ panic(); -+ } -+ -+ write_secure = attr == ETZPC_DECPROT_NS_R_S_W || -+ attr == ETZPC_DECPROT_S_RW; -+ -+ switch (id) { -+ case STM32MP1_ETZPC_STGENC_ID: -+ case STM32MP1_ETZPC_BKPSRAM_ID: -+ if (state != SHRES_SECURE) -+ panic("ETZPC: STGEN & BKSRAM should be secure"); -+ break; -+ case STM32MP1_ETZPC_DDRCTRL_ID: -+ case STM32MP1_ETZPC_DDRPHYC_ID: -+ /* We assume these must always be write-only to secure world */ -+ if (!write_secure) -+ panic("ETZPC: DDRCTRL & DDRPHY should be write secure"); -+ break; -+ default: -+ id_shres = decprot2shres(id); -+ if (id_shres >= STM32MP1_SHRES_COUNT) { -+ if (write_secure) { -+ DMSG("ETZPC: cannot secure DECPROT %s", -+ shres2str_id(id_shres)); -+ panic(); -+ } -+ } else { -+ register_periph(id_shres, state); -+ } -+ break; -+ } -+} -+#endif /*CFG_STM32_ETZPC*/ -+ - static void lock_registering(void) - { - registering_locked = true; -@@ -571,6 +659,7 @@ bool stm32mp_nsec_can_access_reset(unsigned int reset_id) - shres_id = STM32MP1_SHRES_MDMA; - break; - case MCU_R: -+ case MCU_HOLD_BOOT_R: - shres_id = STM32MP1_SHRES_MCU; - break; - default: -@@ -613,13 +702,39 @@ static void config_lock_decprot(uint32_t decprot_id, - etzpc_lock_decprot(decprot_id); - } - -+static bool decprot_is_write_secure(uint32_t decprot_id) -+{ -+ enum etzpc_decprot_attributes attr = etzpc_get_decprot(decprot_id); -+ -+ return attr == ETZPC_DECPROT_S_RW || -+ attr == ETZPC_DECPROT_NS_R_S_W; -+} -+ -+static bool decprot_is_secure(uint32_t decprot_id) -+{ -+ enum etzpc_decprot_attributes attr = etzpc_get_decprot(decprot_id); -+ -+ return attr == ETZPC_DECPROT_S_RW; -+} -+ - static void set_etzpc_secure_configuration(void) - { - /* Some peripherals shall be secure */ -- config_lock_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW); -- config_lock_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW); -- config_lock_decprot(STM32MP1_ETZPC_DDRCTRL_ID, ETZPC_DECPROT_S_RW); -- config_lock_decprot(STM32MP1_ETZPC_DDRPHYC_ID, ETZPC_DECPROT_S_RW); -+ if (!decprot_is_secure(STM32MP1_ETZPC_STGENC_ID)) -+ config_lock_decprot(STM32MP1_ETZPC_STGENC_ID, -+ ETZPC_DECPROT_S_RW); -+ -+ if (!decprot_is_secure(STM32MP1_ETZPC_BKPSRAM_ID)) -+ config_lock_decprot(STM32MP1_ETZPC_BKPSRAM_ID, -+ ETZPC_DECPROT_S_RW); -+ -+ if (!decprot_is_write_secure(STM32MP1_ETZPC_DDRCTRL_ID)) -+ config_lock_decprot(STM32MP1_ETZPC_DDRCTRL_ID, -+ ETZPC_DECPROT_NS_R_S_W); -+ -+ if (!decprot_is_write_secure(STM32MP1_ETZPC_DDRPHYC_ID)) -+ config_lock_decprot(STM32MP1_ETZPC_DDRPHYC_ID, -+ ETZPC_DECPROT_NS_R_S_W); - - /* Configure ETZPC with peripheral registering */ - config_lock_decprot(STM32MP1_ETZPC_IWDG1_ID, -diff --git a/core/arch/arm/plat-stm32mp1/stm32_util.h b/core/arch/arm/plat-stm32mp1/stm32_util.h -index 9c86cd26c..3fd5c602e 100644 ---- a/core/arch/arm/plat-stm32mp1/stm32_util.h -+++ b/core/arch/arm/plat-stm32mp1/stm32_util.h -@@ -120,6 +120,9 @@ int stm32mp1_round_opp_khz(uint32_t *freq_khz); - TEE_Result stm32_reset_assert(unsigned int id, unsigned int timeout_us); - TEE_Result stm32_reset_deassert(unsigned int id, unsigned int timeout_us); - -+/* Specific reset to manage the MCU hold boot */ -+TEE_Result stm32_reset_assert_deassert_mcu(bool assert_not_deassert); -+ - static inline void stm32_reset_set(unsigned int id) - { - (void)stm32_reset_assert(id, 0); -@@ -164,6 +167,11 @@ static inline int stm32mp_start_clock_calib(unsigned int clock_id __unused) - /* Platform util for the RTC driver */ - bool stm32_rtc_get_read_twice(void); - -+/* Platform util for the ETZPC driver */ -+ -+/* Convert a ETZPC mode from DT binding to ETZPC DECPROT configuration */ -+enum etzpc_decprot_attributes stm32mp_etzpc_binding2decprot(uint32_t mode); -+ - /* - * Return true if platform is in closed_device mode - */ -@@ -335,4 +343,8 @@ bool stm32mp_gpio_bank_is_non_secure(unsigned int bank); - /* Register parent clocks of @clock (ID used in clock DT bindings) as secure */ - void stm32mp_register_clock_parents_secure(unsigned long clock_id); - -+/* Register a resource identified by a ETZPC DECPROT identifier */ -+void stm32mp_register_etzpc_decprot(unsigned int id, -+ enum etzpc_decprot_attributes attr); -+ - #endif /*__STM32_UTIL_H__*/ -diff --git a/core/arch/arm/plat-stm32mp1/sub.mk b/core/arch/arm/plat-stm32mp1/sub.mk -index 69df1ced5..ae2041741 100644 ---- a/core/arch/arm/plat-stm32mp1/sub.mk -+++ b/core/arch/arm/plat-stm32mp1/sub.mk -@@ -6,6 +6,15 @@ srcs-$(CFG_STM32_RNG) += rng_seed.c - srcs-y += scmi_server.c - srcs-y += shared_resources.c - srcs-$(CFG_TZC400) += plat_tzc400.c -+srcs-$(CFG_RPROC_PTA) += remoteproc_pta.c -+ -+ifeq ($(CFG_RPROC_PTA),y) -+gensrcs-y += rproc_pub_key -+produce-rproc_pub_key = rproc_pub_key.c -+depends-rproc_pub_key = $(CFG_RPROC_SIGN_KEY) scripts/pem_to_pub_c.py -+recipe-rproc_pub_key = $(PYTHON3) scripts/pem_to_pub_c.py --prefix rproc_pub_key \ -+ --key $(CFG_RPROC_SIGN_KEY) --out $(sub-dir-out)/rproc_pub_key.c -+endif - - subdirs-y += drivers - subdirs-y += nsec-service -diff --git a/core/drivers/stm32_bsec.c b/core/drivers/stm32_bsec.c -index a563f79f9..8df9730a4 100644 ---- a/core/drivers/stm32_bsec.c -+++ b/core/drivers/stm32_bsec.c -@@ -287,7 +287,6 @@ TEE_Result stm32_bsec_shadow_read_otp(uint32_t *otp_value, uint32_t otp_id) - return result; - } - --#ifdef CFG_STM32_BSEC_WRITE - TEE_Result stm32_bsec_write_otp(uint32_t value, uint32_t otp_id) - { - TEE_Result result = 0; -@@ -312,6 +311,7 @@ TEE_Result stm32_bsec_write_otp(uint32_t value, uint32_t otp_id) - return TEE_SUCCESS; - } - -+#ifdef CFG_STM32_BSEC_WRITE - TEE_Result stm32_bsec_program_otp(uint32_t value, uint32_t otp_id) - { - TEE_Result result = 0; -diff --git a/core/drivers/stm32_etzpc.c b/core/drivers/stm32_etzpc.c -index 4a2cb251f..fc4daba87 100644 ---- a/core/drivers/stm32_etzpc.c -+++ b/core/drivers/stm32_etzpc.c -@@ -26,10 +26,16 @@ - #include - #include - #include -+#include - #include - --/* Devicetree compatibulity */ -+/* Devicetree compatibility */ - #define ETZPC_COMPAT "st,stm32-etzpc" -+#define ETZPC_LOCK_MASK BIT(0) -+#define ETZPC_MODE_SHIFT 8 -+#define ETZPC_MODE_MASK GENMASK_32(1, 0) -+#define ETZPC_ID_SHIFT 16 -+#define ETZPC_ID_MASK GENMASK_32(7, 0) - - /* ID Registers */ - #define ETZPC_TZMA0_SIZE 0x000U -@@ -288,7 +294,7 @@ static void get_hwcfg(struct etzpc_hwcfg *hwcfg) - ETZPC_HWCFGR_CHUNCKS1N4_SHIFT; - } - --static void init_devive_from_hw_config(struct etzpc_instance *dev, -+static void init_device_from_hw_config(struct etzpc_instance *dev, - paddr_t pbase) - { - struct etzpc_hwcfg hwcfg = { }; -@@ -312,10 +318,49 @@ static void init_devive_from_hw_config(struct etzpc_instance *dev, - - void stm32_etzpc_init(paddr_t base) - { -- init_devive_from_hw_config(&etzpc_dev, base); -+ init_device_from_hw_config(&etzpc_dev, base); - } - - #ifdef CFG_DT -+struct dt_id_attr { -+ /* The effective size of the array is meaningless here */ -+ fdt32_t id_attr[1]; -+}; -+ -+static void etzpc_dt_conf_decprot(void *fdt, int node) -+{ -+ const struct dt_id_attr *conf_list = NULL; -+ size_t i = 0; -+ int len = 0; -+ -+ conf_list = (const struct dt_id_attr *)fdt_getprop(fdt, node, -+ "st,decprot", &len); -+ if (conf_list == NULL) { -+ DMSG("No ETZPC DECPROT configuration in DT"); -+ return; -+ } -+ -+ for (i = 0; i < len / sizeof(uint32_t); i++) { -+ uint32_t value = fdt32_to_cpu(conf_list->id_attr[i]); -+ uint32_t id = (value >> ETZPC_ID_SHIFT) & ETZPC_ID_MASK; -+ uint32_t mode = (value >> ETZPC_MODE_SHIFT) & ETZPC_MODE_MASK; -+ bool lock = value & ETZPC_LOCK_MASK; -+ enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX; -+ -+ if (!valid_decprot_id(id)) { -+ DMSG("Invalid DECPROT %"PRIu32, id); -+ panic(); -+ } -+ -+ attr = stm32mp_etzpc_binding2decprot(mode); -+ stm32mp_register_etzpc_decprot(id, attr); -+ etzpc_configure_decprot(id, attr); -+ -+ if (lock) -+ etzpc_lock_decprot(id); -+ } -+} -+ - static TEE_Result init_etzpc_from_dt(void) - { - void *fdt = get_embedded_dt(); -@@ -337,7 +382,9 @@ static TEE_Result init_etzpc_from_dt(void) - if (pbase == (paddr_t)-1) - panic(); - -- init_devive_from_hw_config(&etzpc_dev, pbase); -+ init_device_from_hw_config(&etzpc_dev, pbase); -+ -+ etzpc_dt_conf_decprot(fdt, node); - - return TEE_SUCCESS; - } -diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c -index 093407252..96a59dcd5 100644 ---- a/core/drivers/stm32_gpio.c -+++ b/core/drivers/stm32_gpio.c -@@ -38,7 +38,7 @@ - #define GPIO_MODE_MASK GENMASK_32(1, 0) - #define GPIO_OSPEED_MASK GENMASK_32(1, 0) - #define GPIO_PUPD_PULL_MASK GENMASK_32(1, 0) --#define GPIO_ALTERNATE_MASK GENMASK_32(15, 0) -+#define GPIO_ALTERNATE_MASK GENMASK_32(3, 0) - - #define DT_GPIO_BANK_SHIFT 12 - #define DT_GPIO_BANK_MASK GENMASK_32(16, 12) -diff --git a/core/drivers/stm32_tim.c b/core/drivers/stm32_tim.c -index 612fbbc44..3283f1115 100644 ---- a/core/drivers/stm32_tim.c -+++ b/core/drivers/stm32_tim.c -@@ -63,6 +63,7 @@ - #define TIM_PRESCAL_HSI 10 - #define TIM_PRESCAL_CSI 7 - #define TIM_MIN_FREQ_CALIB 50000000U -+#define TIM_THRESHOLD 1U - - struct stm32_tim_instance { - struct io_pa_va base; -@@ -132,9 +133,9 @@ static int timer_config(struct stm32_tim_instance *timer) - static uint32_t timer_start_capture(struct stm32_tim_instance *timer) - { - uint64_t timeout_ref = 0; -+ uint64_t timeout_conv = 0; - uint32_t counter = 0; - uint32_t old_counter = 0; -- int twice = 0; - vaddr_t base = timer_base(timer); - - if (timer_config(timer)) -@@ -144,7 +145,7 @@ static uint32_t timer_start_capture(struct stm32_tim_instance *timer) - - io_write32(base + TIM_SR, 0); - -- timeout_ref = timeout_init_us(TIM_TIMEOUT_US); -+ timeout_ref = timeout_init_us(TIM_TIMEOUT_US / TIM_TIMEOUT_STEP_US); - - while (!timeout_elapsed(timeout_ref)) - if (io_read32(base + TIM_SR) & TIM_SR_UIF) -@@ -154,11 +155,20 @@ static uint32_t timer_start_capture(struct stm32_tim_instance *timer) - - io_write32(base + TIM_SR, 0); - -- for (twice = 0; (twice < 2) || (counter != old_counter); twice++) { -- timeout_ref = timeout_init_us(TIM_TIMEOUT_US); -+ timeout_conv = timeout_init_us(TIM_TIMEOUT_US); -+ -+ do { -+ if (timeout_elapsed(timeout_conv)) { -+ counter = 0; -+ goto bail; -+ } -+ -+ timeout_ref = timeout_init_us(TIM_TIMEOUT_US / -+ TIM_TIMEOUT_STEP_US); - while (!timeout_elapsed(timeout_ref)) - if (io_read32(base + TIM_SR) & TIM_SR_CC1IF) - break; -+ - if (!(io_read32(base + TIM_SR) & TIM_SR_CC1IF)) { - counter = 0; - goto bail; -@@ -166,7 +176,8 @@ static uint32_t timer_start_capture(struct stm32_tim_instance *timer) - - old_counter = counter; - counter = io_read32(base + TIM_CCR1); -- } -+ } while (MAX(counter, old_counter) - MIN(counter, old_counter) > -+ TIM_THRESHOLD); - - bail: - stm32_clock_disable(timer->clk); -diff --git a/core/include/drivers/stm32_bsec.h b/core/include/drivers/stm32_bsec.h -index d284eea10..9fe85bc98 100644 ---- a/core/include/drivers/stm32_bsec.h -+++ b/core/include/drivers/stm32_bsec.h -@@ -45,15 +45,7 @@ TEE_Result stm32_bsec_read_otp(uint32_t *value, uint32_t otp_id); - * @otp_id: OTP number - * Return a TEE_Result compliant return value - */ --#ifdef CFG_STM32_BSEC_WRITE - TEE_Result stm32_bsec_write_otp(uint32_t value, uint32_t otp_id); --#else --static inline TEE_Result stm32_bsec_write_otp(uint32_t value __unused, -- uint32_t otp_id __unused) --{ -- return TEE_ERROR_NOT_SUPPORTED; --} --#endif - - /* - * Program a bit in SAFMEM without BSEC data refresh -diff --git a/core/include/dt-bindings/reset/stm32mp1-resets.h b/core/include/dt-bindings/reset/stm32mp1-resets.h -index bc71924fa..f3a0ed317 100644 ---- a/core/include/dt-bindings/reset/stm32mp1-resets.h -+++ b/core/include/dt-bindings/reset/stm32mp1-resets.h -@@ -7,6 +7,7 @@ - #ifndef _DT_BINDINGS_STM32MP1_RESET_H_ - #define _DT_BINDINGS_STM32MP1_RESET_H_ - -+#define MCU_HOLD_BOOT_R 2144 - #define LTDC_R 3072 - #define DSI_R 3076 - #define DDRPERFM_R 3080 -@@ -117,5 +118,6 @@ - #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_STM32MP1_RESET_H_ */ -diff --git a/core/sub.mk b/core/sub.mk -index 03cc6bc71..c034276b6 100644 ---- a/core/sub.mk -+++ b/core/sub.mk -@@ -20,13 +20,16 @@ recipe-ldelf = scripts/gen_ldelf_hex.py --input $(out-dir)/ldelf/ldelf.elf \ - endif - - ifeq ($(CFG_WITH_USER_TA)-$(CFG_EARLY_TA),y-y) -+ifeq ($(CFG_EARLY_TA_COMPRESS),y) -+early-ta-compress = --compress -+endif - define process_early_ta - early-ta-$1-uuid := $(firstword $(subst ., ,$(notdir $1))) - gensrcs-y += early-ta-$1 - produce-early-ta-$1 = early_ta_$$(early-ta-$1-uuid).c - depends-early-ta-$1 = $1 scripts/ta_bin_to_c.py --recipe-early-ta-$1 = scripts/ta_bin_to_c.py --compress --ta $1 \ -- --out $(sub-dir-out)/early_ta_$$(early-ta-$1-uuid).c -+recipe-early-ta-$1 = scripts/ta_bin_to_c.py $(early-ta-compress) \ -+ --ta $1 --out $(sub-dir-out)/early_ta_$$(early-ta-$1-uuid).c - endef - $(foreach f, $(EARLY_TA_PATHS), $(eval $(call process_early_ta,$(f)))) - $(foreach f, $(CFG_IN_TREE_EARLY_TAS), $(eval $(call \ -diff --git a/keys/default_rproc.pem b/keys/default_rproc.pem -new file mode 100644 -index 000000000..d54476f35 ---- /dev/null -+++ b/keys/default_rproc.pem -@@ -0,0 +1,27 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpAIBAAKCAQEA1TD3AMwyJhzsliOhEStPrCrgnG9Gy8z+OCtialVngW/rkqQB -+cb/oOdiMPjfLoSio8zaUA86mTHo6DINZIopTZvs9pysnpvrOwbjCVRXTcIhgM/YZ -+GyN9c+Qo5fCbOlCsxD0PG40hP4O0dktWyzmWQfjy0+9BDAyMoW59lPeYZcJAKSWT -+M10V5h3JTabA4dqVroeztuTow3ftNImNuzMFYDqGDUcJy0EdluRsBfhOOKXE7ZaQ -+RXnwY9CTCGqgsuNKwE1g8evkseaLcJk4/JpVFOgZp4fUgsxU6EBRD2i+C+Jq9KXg -+qBcK0QwXNr2IwG3i76QmLzGGkpW7bKPn/QhGMQIDAQABAoIBAQCHBnAqzSmmAgPG -+Q+KroSbhAHcqHUBVrAwHP1Mhzd20mVI2mjFf/g/zMzf/4A7Uj5ASGqs8jhG9tlw1 -+uKsnuTyBqPavfiGrHIb/IynSAfTc/UMRJflYuu2mDQfqOq3WDWqfD50V8hjwxVXy -+5lyecma8ehQyLwKfwwL+66AWTYr0Rx+OdXkGdGj1SXbJU39nv7UH8ZggpICFhUXO -+r7NgJr2UOyhEje4stTGSb86SrvxHRm07JG1WSOJ2GV0EBhWNqbRtsnvH1NKNm03m -+yM+zMbqvtdg1Wkfcfxtx6h7MGHhUUIHwotDoKgZ1lz1EdVWk8clmlKCLFEBxcwIp -+sdbrodnBAoGBAPFQ1J7B+3eDBJjgrEFu9soygrjulhiA2+3qrra95RyuIE0wE8CO -+DPjAGHOnxAoUt8H+TEGF2Wo2HVQauz2ElPOlIxQctr3w2Xpi1DibKEdooQLRlaSS -+LHWAxTLZj9EI3NuYhdRvFHUW2ExEqCADOKY4+1xRSXuIbIkaLMaah8R9AoGBAOIq -+BEiqoaQM/EA4z+m7RuOjc1PtA0qo9DJIEb4Mj92gEGzSHCdNN+eDCKbqyd8BGo/w -+Pf6N8+dotjYvzlz3MqwfV1aczvQqbfkivzahO7GlK2KmwwLG3Vm8dZAZCZKEglOg -+ex6h/L8gOgqSP+C4OmdEU4jdA24BSHr+1ZArHPrFAoGBAL27l/DbBCSLVun8fHNW -+E6QW4sEUld7eMg12H7h+xc0u+ya1TlJvXbOXFaKZnYFvmKtmjf5WhwMDWTvvaJiN -+za9jf5kommXtIJEhc0quc5TxpubYcpfadipM/L9mX7UzCrN90Hueeq81LwuIT8gb -+wEaxNrD3GJeQRAXoFpxwk57hAoGAaeqLfwyKDq4WJG120VtnY4xUomVJOVnOow2l -+YX+4kG45wvzTOoSrPbzb/G/QgqOdsPMt1VzdcO5VByN0XY1XKcyztlhRg3+raRWg -+vxDbR+K2Ysj+YvqHB1N/KzDOjtOHxWpOvpXWLBwHkpPTXoZos5wIEvyOcqIfM5rM -+oWvPcpECgYBCtncnPQQJfYcFebw3+rzm9OodF/s6G9afOrzqgEk/0Z6mi20x1c23 -+dzcZUpLl9p7fCFg0iz9NwLUYR9tZ/4zy+J4ZET7PduxoLG3m1TVzxSJM+dU+GtQi -+fBcdQuC6od9K9MJD2egwmes/I+aWhrIAatrG2iMtrOTG5N0mUMUc+w== -+-----END RSA PRIVATE KEY----- -diff --git a/lib/libutee/include/remoteproc_pta.h b/lib/libutee/include/remoteproc_pta.h -new file mode 100644 -index 000000000..cede192eb ---- /dev/null -+++ b/lib/libutee/include/remoteproc_pta.h -@@ -0,0 +1,157 @@ -+/* SPDX-License-Identifier: BSD-2-Clause */ -+/* -+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved -+ */ -+ -+#ifndef __REMOTEPROC_PTA_H -+#define __REMOTEPROC_PTA_H -+ -+#include -+ -+/* -+ * Interface to the pseudo TA which provides platform implementation -+ * of the remote processor management -+ */ -+ -+#define PTA_REMOTEPROC_UUID { 0x54af4a68, 0x19be, 0x40d7, \ -+ { 0xbb, 0xe6, 0x89, 0x50, 0x35, 0x0a, 0x87, 0x44 } } -+ -+/* Firmware format */ -+#define PTA_REMOTEPROC_PROPRIETARY_FMT BIT32(0) -+#define PTA_REMOTEPROC_ELF_FMT BIT32(1) -+ -+/* Firmware image protection */ -+/* The platorm supports copy of the input firmware image in secure memory */ -+#define PTA_REMOTEPROC_FW_SECURE_COPY BIT32(0) -+/* The platorm supports load of segment with hash protection */ -+#define PTA_REMOTEPROC_FW_WITH_HASH_TABLE BIT32(1) -+/* The platorm is able to change access to secure the firmware input image */ -+#define PTA_REMOTEPROC_FW_MEMORY_PROTECTION BIT32(2) -+ -+/** -+ * struct rproc_pta_key_info - public key information -+ * @algo: Algorithm, defined by public key algorithms TEE_ALG_* -+ * from TEE Internal API specification -+ * @info_size: Byte size of the @info -+ * @info: Append key information data -+ */ -+struct rproc_pta_key_info { -+ uint32_t algo; -+ uint32_t info_size; -+ char info[]; -+}; -+ -+static inline size_t -+ rproc_pta_get_keyinfo_size(struct rproc_pta_key_info *keyinf) -+{ -+ size_t s = 0; -+ -+ if (!keyinf || ADD_OVERFLOW(sizeof(*keyinf), keyinf->info_size, &s)) -+ return 0; -+ -+ return s; -+} -+ -+#define RPROC_PTA_GET_KEYINFO_SIZE(x) rproc_pta_get_keyinfo_size((x)) -+ -+/* -+ * Platform capabilities. -+ * -+ * Get Platform firmware loader service capabilities. -+ * -+ * [in] params[0].value.a: Unique 32bit firmware identifier -+ * [out] params[1].value.a: Firmware format (PTA_REMOTEPROC_*_FMT) -+ * [out] params[2].value.a: Image protection method (PTA_REMOTEPROC_FW_*) -+ */ -+#define PTA_REMOTEPROC_HW_CAPABILITIES 1 -+ -+/* -+ * Firmware loading. -+ * -+ * Optional service to implement only in case of proprietary format. -+ * -+ * [in] params[0].value.a: Unique 32bit firmware identifier -+ * [in] params[1].memref: Loadable firmware image -+ */ -+#define PTA_REMOTEPROC_FIRMWARE_LOAD 2 -+ -+/* -+ * Load a segment with a SHA256 hash. -+ * -+ * This command is used when the platform secure memory is too expensive to -+ * save the whole firmware image in secure memory. Upon segment load, a -+ * successful completion ensures the loaded image complies with the provided -+ * hash. -+ * -+ * [in] params[0].value.a: Unique 32bit firmware identifier -+ * [in] params[1].memref: Section data to load -+ * [in] params[2].value.a: 32bit LSB load device segment address -+ * [in] params[2].value.b: 32bit MSB load device segment address -+ * [in] params[3].memref: Expected hash (SHA256) of the payload -+ */ -+#define PTA_REMOTEPROC_LOAD_SEGMENT_SHA256 3 -+ -+/* -+ * Memory set. -+ * -+ * Fill a remote device memory with requested value. this is use for instance -+ * to clear a memory on the remote firmware load. -+ * -+ * [in] params[0].value.a: Unique 32bit firmware identifier -+ * [in] params[1].value.a: 32bit LSB device memory address -+ * [in] params[1].value.b: 32bit MSB device memory address -+ * [in] params[2].value.a: 32bit LSB device memory size -+ * [in] params[2].value.b: 32bit MSB device memory size -+ * [in] params[3].value.a: Byte value to be set -+ */ -+#define PTA_REMOTEPROC_SET_MEMORY 4 -+ -+/* -+ * Firmware start. -+ * -+ * Start up a successfully remote processor firmware. -+ * -+ * [in] params[0].value.a: Unique 32bit firmware identifier -+ */ -+#define PTA_REMOTEPROC_FIRMWARE_START 5 -+ -+/* -+ * Firmware stop. -+ * -+ * Stop of the remote processor firmware and release/clean resources. -+ * After the command successful completion, remote processor firmware must be -+ * reloaded prior being started again. -+ * -+ * [in] params[0].value.a: Unique 32bit firmware identifier -+ */ -+#define PTA_REMOTEPROC_FIRMWARE_STOP 6 -+ -+/* -+ * Firmware device to physical address conversion. -+ * -+ * Return the physical address corresponding to an address got from the -+ * firmware address layout. -+ * -+ * [in] params[0].value.a: Unique 32bit firmware identifier -+ * [in] params[1].value.a: 32bit LSB Device memory address -+ * [in] params[1].value.b: 32bit MSB Device memory address -+ * [in] params[2].value.a: 32bit LSB Device memory size -+ * [in] params[2].value.b: 32bit MSB Device memory size -+ * [out] params[3].value.a: 32bit LSB converted physical address -+ * [out] params[3].value.b: 32bit MSB converted physical address -+ */ -+#define PTA_REMOTEPROC_FIRMWARE_DA_TO_PA 7 -+ -+/* -+ * Verify the firmware digest against a signature -+ * -+ * Return TEE_SUCCESS if the signature is verified, else an error -+ * -+ * [in] params[0].value.a: Unique 32bit firmware identifier -+ * [in] params[1].memref: Key information (refer to @rproc_pta_key_info) -+ * [in] params[2].memref: Digest of the firmware authenticated data -+ * [in] params[3].memref: Signature of the firmware authenticated data -+ */ -+#define PTA_REMOTEPROC_VERIFY_DIGEST 8 -+ -+#endif /* __REMOTEPROC_PTA_H */ -diff --git a/mk/config.mk b/mk/config.mk -index bc49f83d8..bc3e1dccf 100644 ---- a/mk/config.mk -+++ b/mk/config.mk -@@ -296,6 +296,9 @@ $(eval $(call cfg-depends-all,CFG_REE_FS_TA_BUFFERED,CFG_REE_FS_TA)) - # in-tree TAs. CFG_IN_TREE_EARLY_TAS is formatted as: - # / - # for instance avb/023f8f1a-292a-432b-8fc4-de8471358067 -+# -+# By default the early TAs are compressed in the TEE binary, it is possible to -+# not compress them with CFG_EARLY_TA_COMPRESS=n - ifneq ($(EARLY_TA_PATHS)$(CFG_IN_TREE_EARLY_TAS),) - $(call force,CFG_EARLY_TA,y) - else -@@ -304,6 +307,7 @@ endif - ifeq ($(CFG_EARLY_TA),y) - $(call force,CFG_ZLIB,y) - endif -+CFG_EARLY_TA_COMPRESS ?= y - - # Enable paging, requires SRAM, can't be enabled by default - CFG_WITH_PAGER ?= n -diff --git a/scripts/sign_rproc_fw.py b/scripts/sign_rproc_fw.py -new file mode 100755 -index 000000000..0fd0a8755 ---- /dev/null -+++ b/scripts/sign_rproc_fw.py -@@ -0,0 +1,400 @@ -+#!/usr/bin/env python3 -+# SPDX-License-Identifier: BSD-2-Clause -+# -+# Copyright (C) 2020, STMicroelectronics - All Rights Reserved -+# -+ -+from elftools.elf.elffile import ELFFile -+from elftools.elf.sections import SymbolTableSection -+from elftools.elf.enums import * -+from Cryptodome.Hash import SHA256 -+from Cryptodome.Signature import pkcs1_15 -+from Cryptodome.PublicKey import RSA -+from Cryptodome.Signature import DSS -+from Cryptodome.PublicKey import ECC -+import sys -+import struct -+import logging -+import binascii -+ -+ -+logging.basicConfig(stream=sys.stderr, level=logging.INFO) -+ -+ENUM_HASH_TYPE = dict( -+ SHA256=1, -+) -+ -+ENUM_SIGNATURE_TYPE = dict( -+ RSA=1, -+ ECC=2, -+) -+ -+ENUM_BINARY_TYPE = dict( -+ ELF=1, -+) -+ -+ -+def dump_buffer(buf, step=16, name="", logger=logging.info, indent=""): -+ logger("%s%s:" % (indent, name)) -+ for i in range(0, len(buf), step): -+ logger("%s " % (indent) + " ". -+ join(["%02X" % c for c in buf[i:i+step]])) -+ logger("\n") -+ -+ -+class RSA_Signature(object): -+ -+ def __init__(self, key): -+ self._hasher = SHA256.new() -+ self.signer = pkcs1_15.new(key) -+ -+ def hash_compute(self, segment): -+ self._hasher.update(segment) -+ -+ def sign(self): -+ return self.signer.sign(self._hasher) -+ -+ -+class ECC_Signature(object): -+ -+ def __init__(self, key): -+ self._hasher = SHA256.new() -+ self.signer = DSS.new(key, 'fips-186-3') -+ -+ def hash_compute(self, segment): -+ self._hasher.update(segment) -+ -+ def sign(self): -+ return self.signer.sign(self._hasher) -+ -+ -+Signature = { -+ 1: RSA_Signature, -+ 2: ECC_Signature, -+} -+ -+ -+class SegmentHashStruct: -+ pass -+ -+ -+class SegmentHash(object): -+ ''' -+ Hash table based on Elf program segments -+ ''' -+ def __init__(self, img): -+ self._num_segments = img.num_segments() -+ self._pack_fmt = '<%dL' % 8 -+ self.img = img -+ self.hashProgTable = bytes() -+ self._offset = 0 -+ -+ def get_table(self): -+ ''' -+ Create a segment hash table containing for each segment: -+ - the segments header -+ - a hash of the segment -+ ''' -+ h = SHA256.new() -+ seg = SegmentHashStruct() -+ self.size = (h.digest_size + 32) * self._num_segments -+ logging.debug("hash section size %d" % self.size) -+ del h -+ self.buf = bytearray(self.size) -+ self._bufview_ = memoryview(self.buf) -+ -+ for i in range(self._num_segments): -+ h = SHA256.new() -+ segment = self.img.get_segment(i) -+ seg.header = self.img.get_segment(i).header -+ logging.debug("compute hash for segment offset %s" % seg.header) -+ h.update(segment.data()) -+ seg.hash = h.digest() -+ logging.debug("hash computed: %s" % seg.hash) -+ del h -+ struct.pack_into('.sig') -+ -+ parsed = parser.parse_args() -+ -+ # Set defaults for optional arguments. -+ -+ if parsed.outf is None: -+ parsed.outf = str(parsed.inf)+'.sig' -+ -+ return parsed -+ -+ -+def rsa_key(keyf): -+ return RSA.importKey(open(keyf).read()) -+ -+ -+def ecc_key(keyf): -+ return ECC.import_key(open(keyf).read()) -+ -+ -+key_type = { -+ 1: rsa_key, -+ 2: ecc_key, -+} -+ -+ -+def rsa_sig_size(key): -+ return key.size_in_bytes() -+ -+ -+def ecc_sig_size(key): -+ # to be improve... -+ # DSA size is N/4 so 64 for DSA (L,N) = (2048, 256) -+ return 64 -+ -+ -+sig_size_type = { -+ 1: rsa_sig_size, -+ 2: ecc_sig_size, -+} -+ -+ -+def main(): -+ from Cryptodome.Signature import pss -+ from Cryptodome.Hash import SHA256 -+ from Cryptodome.PublicKey import RSA -+ import base64 -+ import logging -+ import os -+ import struct -+ -+ logging.basicConfig() -+ logger = logging.getLogger(os.path.basename(__file__)) -+ -+ args = get_args(logger) -+ -+ # Initialise the header */ -+ s_header = ImageHeader() -+ -+ get_key = key_type.get(ENUM_SIGNATURE_TYPE[args.key_type], -+ lambda: "Invalid sign type") -+ key = get_key(args.keyf) -+ -+ if not key.has_private(): -+ logger.error('Provided key cannot be used for signing, ' + -+ 'please use offline-signing mode.') -+ sys.exit(1) -+ -+ # Firmware image -+ input_file = open(args.inf, 'rb') -+ img = ELFFile(input_file) -+ -+ # need to reopen the file to get the raw data -+ with open(args.inf, 'rb') as f: -+ bin_img = f.read() -+ img_size = len(bin_img) -+ logging.debug("image size %d" % img_size) -+ s_header.img_length = img_size -+ s_header.img_type = ENUM_BINARY_TYPE['ELF'] -+ -+ # Hash table chunk -+ h = SHA256.new() -+ -+ # Compute the hash table -+ hash_table = SegmentHash(img) -+ hash = hash_table.get_table() -+ -+ s_header.hash_offset = s_header.size -+ s_header.hash_length = hash_table.size -+ s_header.hash_type = ENUM_HASH_TYPE['SHA256'] -+ # Get padding to align on 64 bytes -+ hash_align = s_header.hash_length % 8 -+ -+ # Key information chunk -+ if args.key_infof: -+ with open(args.key_infof, 'rb') as f: -+ key_info = f.read() -+ s_header.key_length = sys.getsizeof(key_info) -+ s_header.key_offset = s_header.hash_offset + s_header.hash_length + \ -+ hash_align -+ # Get padding to align on 64 bytes -+ key_info_align = s_header.key_length % 8 -+ else: -+ key_info_align = 0 -+ -+ # Signature chunk -+ s_header.sign_type = ENUM_SIGNATURE_TYPE[args.key_type] -+ -+ sign_size = sig_size_type.get(ENUM_SIGNATURE_TYPE[args.key_type], -+ lambda: "Invalid sign type")(key) -+ s_header.sign_length = sign_size -+ -+ if args.key_infof: -+ s_header.sign_offset = s_header.key_offset + s_header.key_length + \ -+ key_info_align -+ else: -+ s_header.sign_offset = s_header.hash_offset + s_header.hash_length + \ -+ hash_align -+ -+ s_header.img_offset = s_header.sign_offset + sign_size -+ -+ s_header.length = s_header.size + s_header.hash_length + hash_align + \ -+ s_header.key_length + key_info_align + s_header.sign_length -+ -+ header = s_header.get_packed() -+ -+ # Generate signature -+ signer = Signature.get(ENUM_SIGNATURE_TYPE[args.key_type])(key) -+ -+ signer.hash_compute(header) -+ signer.hash_compute(bytes(hash)) -+ if args.key_infof: -+ signer.hash_compute(key_info) -+ -+ signature = signer.sign() -+ if len(signature) != sign_size: -+ raise Exception(("Actual signature length is not equal to ", -+ "the computed one: {} != {}". -+ format(len(signature), sign_size))) -+ -+ s_header.dump() -+ -+ with open(args.outf, 'wb') as f: -+ f.write(header) -+ f.write(hash) -+ if hash_align: -+ f.write(bytearray(hash_align)) -+ if args.key_infof: -+ if key_info_align: -+ f.write(key_info) -+ f.write(bytearray(key_info_align)) -+ f.write(signature) -+ f.write(bytearray(sign_size - s_header.sign_length)) -+ f.write(bin_img) -+ -+ -+if __name__ == "__main__": -+ main() -diff --git a/ta/remoteproc/Makefile b/ta/remoteproc/Makefile -new file mode 100644 -index 000000000..0d1a5010c ---- /dev/null -+++ b/ta/remoteproc/Makefile -@@ -0,0 +1,18 @@ -+# The UUID for the Trusted Application -+BINARY=80a4c275-0a47-4905-8285-1486a9771a08 -+ -+ifdef TA_CROSS_COMPILE -+CROSS_COMPILE ?= $(TA_CROSS_COMPILE) -+endif -+export CROSS_COMPILE -+ -+CFG_TEE_TA_LOG_LEVEL ?= 2 -+CPPFLAGS += -DCFG_TEE_TA_LOG_LEVEL=$(CFG_TEE_TA_LOG_LEVEL) -+ -+-include $(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk -+ -+ifeq ($(wildcard $(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk), ) -+clean: -+ @echo 'Note: $$(TA_DEV_KIT_DIR)/mk/ta_dev_kit.mk not found, cannot clean TA' -+ @echo 'Note: TA_DEV_KIT_DIR=$(TA_DEV_KIT_DIR)' -+endif -diff --git a/ta/remoteproc/elf_parser.c b/ta/remoteproc/elf_parser.c -new file mode 100644 -index 000000000..59b7e0119 ---- /dev/null -+++ b/ta/remoteproc/elf_parser.c -@@ -0,0 +1,181 @@ -+ // SPDX-License-Identifier: BSD-2-Clause -+ /* -+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static bool va_in_fwm_image_range(void *va, uint8_t *fw, size_t fw_size) -+{ -+ uint8_t *vaddr = va; -+ -+ assert(fw + fw_size >= fw); -+ return vaddr >= fw && vaddr < fw + fw_size; -+} -+ -+/* -+ * e32_parse_ehdr() - Check and parse the ELF header -+ * -+ * fw: Firmware ELF file image -+ * size: Byte size of firmware ELF file image -+ */ -+TEE_Result e32_parse_ehdr(uint8_t *fw, size_t size) -+{ -+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(void *)fw; -+ -+ if (!fw || !ALIGNMENT_IS_OK(fw, uint32_t)) { -+ EMSG("Invalid fw address %p", fw); -+ return TEE_ERROR_BAD_PARAMETERS; -+ } -+ -+ if (size < sizeof(Elf32_Ehdr) || -+ size < (ehdr->e_shoff + sizeof(Elf32_Shdr))) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ if (!IS_ELF(*ehdr) || -+ ehdr->e_ident[EI_VERSION] != EV_CURRENT || -+ ehdr->e_ident[EI_CLASS] != ELFCLASS32 || -+ ehdr->e_phentsize != sizeof(Elf32_Phdr) || -+ ehdr->e_shentsize != sizeof(Elf32_Shdr)) { -+ EMSG("Invalid header"); -+ -+ return TEE_ERROR_BAD_FORMAT; -+ } -+ -+ if (ehdr->e_phnum == 0) { -+ EMSG("No loadable segment found"); -+ return TEE_ERROR_BAD_FORMAT; -+ } -+ -+ return TEE_SUCCESS; -+} -+ -+/* -+ * e32_parser_load_elf_image - simple ELF loader -+ * fw: Firmware ELF file image -+ * fw_size: Firmware ELF file image byte size -+ * load_seg: Callback for loading a firmware image segment into device memory -+ * priv_data: Private data passed to @load_seg callback. -+ */ -+TEE_Result e32_parser_load_elf_image(uint8_t *fw, size_t fw_size, -+ TEE_Result (*load_seg)(uint8_t *src, -+ uint32_t size, -+ uint32_t da, -+ uint32_t mem_size, -+ void *priv), -+ void *priv_data) -+{ -+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(void *)fw; -+ Elf32_Phdr *phdr = (void *)((int8_t *)ehdr + ehdr->e_phoff); -+ TEE_Result res = TEE_SUCCESS; -+ unsigned int i = 0; -+ -+ if (!load_seg) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ if (!ALIGNMENT_IS_OK(phdr, uint32_t) || -+ !va_in_fwm_image_range(phdr, fw, fw_size)) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ for (i = 0; i < ehdr->e_phnum; i++, phdr++) { -+ uint32_t dst = phdr->p_paddr; -+ uint8_t *src = NULL; -+ -+ if (!va_in_fwm_image_range((void *)((vaddr_t)(phdr + 1) - 1), -+ fw, fw_size)) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ if (phdr->p_type != PT_LOAD) -+ continue; -+ -+ src = (uint8_t *)fw + phdr->p_offset; -+ -+ if (!va_in_fwm_image_range(src, fw, fw_size) || -+ !va_in_fwm_image_range(src + phdr->p_filesz, fw, fw_size)) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ res = load_seg(src, phdr->p_filesz, dst, phdr->p_memsz, -+ priv_data); -+ if (res) -+ return res; -+ } -+ -+ return TEE_SUCCESS; -+} -+ -+/* Helper to find resource table in an ELF image */ -+int e32_parser_find_rsc_table(uint8_t *fw, size_t fw_size, -+ Elf32_Addr *rsc_addr, Elf32_Word *rsc_size) -+{ -+ Elf32_Shdr *shdr = NULL; -+ int i = 0; -+ char *name_table = NULL; -+ struct resource_table *table = NULL; -+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(void *)fw; -+ uint8_t *elf_data = fw; -+ -+ shdr = (void *)(fw + ehdr->e_shoff); -+ if (!ALIGNMENT_IS_OK(shdr, uint32_t) || -+ !va_in_fwm_image_range(shdr, fw, fw_size)) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ name_table = (char *)elf_data + shdr[ehdr->e_shstrndx].sh_offset; -+ if (!va_in_fwm_image_range(name_table, fw, fw_size)) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ for (i = 0; i < ehdr->e_shnum; i++, shdr++) { -+ size_t size = shdr->sh_size; -+ size_t offset = shdr->sh_offset; -+ -+ if (!va_in_fwm_image_range(shdr, fw, fw_size)) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ if (strcmp(name_table + shdr->sh_name, ".resource_table")) -+ continue; -+ -+ if (offset + size > fw_size || offset + size < size) { -+ EMSG("Resource table truncated"); -+ return TEE_ERROR_BAD_FORMAT; -+ } -+ -+ if (sizeof(struct resource_table) > size) { -+ EMSG("No header found in resource table"); -+ return TEE_ERROR_BAD_FORMAT; -+ } -+ -+ table = (struct resource_table *)(void *)(elf_data + offset); -+ if (!ALIGNMENT_IS_OK(table, uint32_t)) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ if (table->ver != 1) { -+ EMSG("Unsupported fw version %"PRId32, table->ver); -+ return TEE_ERROR_BAD_FORMAT; -+ } -+ -+ if (table->reserved[0] || table->reserved[1]) { -+ EMSG("Non zero reserved bytes"); -+ return TEE_ERROR_BAD_FORMAT; -+ } -+ -+ if (table->num * sizeof(*table->offset) + -+ sizeof(struct resource_table) > size) { -+ EMSG("Resource table incomplete"); -+ return TEE_ERROR_BAD_FORMAT; -+ } -+ -+ DMSG("Resource table address %#"PRIx32", size %"PRIu32, -+ shdr->sh_addr, shdr->sh_size); -+ -+ *rsc_addr = shdr->sh_addr; -+ *rsc_size = shdr->sh_size; -+ -+ return TEE_SUCCESS; -+ } -+ -+ return TEE_ERROR_NO_DATA; -+} -diff --git a/ta/remoteproc/include/elf32.h b/ta/remoteproc/include/elf32.h -new file mode 100644 -index 000000000..2806c615d ---- /dev/null -+++ b/ta/remoteproc/include/elf32.h -@@ -0,0 +1,243 @@ -+/* SPDX-License-Identifier: BSD-2-Clause */ -+/*- -+ * Copyright (c) 1996-1998 John D. Polstra. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * $FreeBSD$ -+ */ -+ -+#ifndef _SYS_ELF32_H_ -+#define _SYS_ELF32_H_ 1 -+ -+#include -+#include -+ -+/* -+ * ELF definitions common to all 32-bit architectures. -+ */ -+ -+typedef uint32_t Elf32_Addr; -+typedef uint16_t Elf32_Half; -+typedef uint32_t Elf32_Off; -+typedef int32_t Elf32_Sword; -+typedef uint32_t Elf32_Word; -+typedef uint64_t Elf32_Lword; -+ -+typedef Elf32_Word Elf32_Hashelt; -+ -+/* Non-standard class-dependent datatype used for abstraction. */ -+typedef Elf32_Word Elf32_Size; -+typedef Elf32_Sword Elf32_Ssize; -+ -+/* -+ * ELF header. -+ */ -+ -+typedef struct { -+ unsigned char e_ident[EI_NIDENT]; /* File identification. */ -+ Elf32_Half e_type; /* File type. */ -+ Elf32_Half e_machine; /* Machine architecture. */ -+ Elf32_Word e_version; /* ELF format version. */ -+ Elf32_Addr e_entry; /* Entry point. */ -+ Elf32_Off e_phoff; /* Program header file offset. */ -+ Elf32_Off e_shoff; /* Section header file offset. */ -+ Elf32_Word e_flags; /* Architecture-specific flags. */ -+ Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ -+ Elf32_Half e_phentsize; /* Size of program header entry. */ -+ Elf32_Half e_phnum; /* Number of program header entries. */ -+ Elf32_Half e_shentsize; /* Size of section header entry. */ -+ Elf32_Half e_shnum; /* Number of section header entries. */ -+ Elf32_Half e_shstrndx; /* Section name strings section. */ -+} Elf32_Ehdr; -+ -+/* -+ * Section header. -+ */ -+ -+typedef struct { -+ Elf32_Word sh_name; /* Section name (index into the -+ section header string table). */ -+ Elf32_Word sh_type; /* Section type. */ -+ Elf32_Word sh_flags; /* Section flags. */ -+ Elf32_Addr sh_addr; /* Address in memory image. */ -+ Elf32_Off sh_offset; /* Offset in file. */ -+ Elf32_Word sh_size; /* Size in bytes. */ -+ Elf32_Word sh_link; /* Index of a related section. */ -+ Elf32_Word sh_info; /* Depends on section type. */ -+ Elf32_Word sh_addralign; /* Alignment in bytes. */ -+ Elf32_Word sh_entsize; /* Size of each entry in section. */ -+} Elf32_Shdr; -+ -+/* -+ * Program header. -+ */ -+ -+typedef struct { -+ Elf32_Word p_type; /* Entry type. */ -+ Elf32_Off p_offset; /* File offset of contents. */ -+ Elf32_Addr p_vaddr; /* Virtual address in memory image. */ -+ Elf32_Addr p_paddr; /* Physical address (not used). */ -+ Elf32_Word p_filesz; /* Size of contents in file. */ -+ Elf32_Word p_memsz; /* Size of contents in memory. */ -+ Elf32_Word p_flags; /* Access permission flags. */ -+ Elf32_Word p_align; /* Alignment in memory and file. */ -+} Elf32_Phdr; -+ -+/* -+ * Dynamic structure. The ".dynamic" section contains an array of them. -+ */ -+ -+typedef struct { -+ Elf32_Sword d_tag; /* Entry type. */ -+ union { -+ Elf32_Word d_val; /* Integer value. */ -+ Elf32_Addr d_ptr; /* Address value. */ -+ } d_un; -+} Elf32_Dyn; -+ -+/* -+ * Relocation entries. -+ */ -+ -+/* Relocations that don't need an addend field. */ -+typedef struct { -+ Elf32_Addr r_offset; /* Location to be relocated. */ -+ Elf32_Word r_info; /* Relocation type and symbol index. */ -+} Elf32_Rel; -+ -+/* Relocations that need an addend field. */ -+typedef struct { -+ Elf32_Addr r_offset; /* Location to be relocated. */ -+ Elf32_Word r_info; /* Relocation type and symbol index. */ -+ Elf32_Sword r_addend; /* Addend. */ -+} Elf32_Rela; -+ -+/* Macros for accessing the fields of r_info. */ -+#define ELF32_R_SYM(info) ((info) >> 8) -+#define ELF32_R_TYPE(info) ((unsigned char)(info)) -+ -+/* Macro for constructing r_info from field values. */ -+#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) -+ -+/* -+ * Note entry header -+ */ -+typedef Elf_Note Elf32_Nhdr; -+ -+/* -+ * Move entry -+ */ -+typedef struct { -+ Elf32_Lword m_value; /* symbol value */ -+ Elf32_Word m_info; /* size + index */ -+ Elf32_Word m_poffset; /* symbol offset */ -+ Elf32_Half m_repeat; /* repeat count */ -+ Elf32_Half m_stride; /* stride info */ -+} Elf32_Move; -+ -+/* -+ * The macros compose and decompose values for Move.r_info -+ * -+ * sym = ELF32_M_SYM(M.m_info) -+ * size = ELF32_M_SIZE(M.m_info) -+ * M.m_info = ELF32_M_INFO(sym, size) -+ */ -+#define ELF32_M_SYM(info) ((info)>>8) -+#define ELF32_M_SIZE(info) ((unsigned char)(info)) -+#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) -+ -+/* -+ * Hardware/Software capabilities entry -+ */ -+typedef struct { -+ Elf32_Word c_tag; /* how to interpret value */ -+ union { -+ Elf32_Word c_val; -+ Elf32_Addr c_ptr; -+ } c_un; -+} Elf32_Cap; -+ -+/* -+ * Symbol table entries. -+ */ -+ -+typedef struct { -+ Elf32_Word st_name; /* String table index of name. */ -+ Elf32_Addr st_value; /* Symbol value. */ -+ Elf32_Word st_size; /* Size of associated object. */ -+ unsigned char st_info; /* Type and binding information. */ -+ unsigned char st_other; /* Reserved (not used). */ -+ Elf32_Half st_shndx; /* Section index of symbol. */ -+} Elf32_Sym; -+ -+/* Macros for accessing the fields of st_info. */ -+#define ELF32_ST_BIND(info) ((info) >> 4) -+#define ELF32_ST_TYPE(info) ((info) & 0xf) -+ -+/* Macro for constructing st_info from field values. */ -+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) -+ -+/* Macro for accessing the fields of st_other. */ -+#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3) -+ -+/* Structures used by Sun & GNU symbol versioning. */ -+typedef struct { -+ Elf32_Half vd_version; -+ Elf32_Half vd_flags; -+ Elf32_Half vd_ndx; -+ Elf32_Half vd_cnt; -+ Elf32_Word vd_hash; -+ Elf32_Word vd_aux; -+ Elf32_Word vd_next; -+} Elf32_Verdef; -+ -+typedef struct { -+ Elf32_Word vda_name; -+ Elf32_Word vda_next; -+} Elf32_Verdaux; -+ -+typedef struct { -+ Elf32_Half vn_version; -+ Elf32_Half vn_cnt; -+ Elf32_Word vn_file; -+ Elf32_Word vn_aux; -+ Elf32_Word vn_next; -+} Elf32_Verneed; -+ -+typedef struct { -+ Elf32_Word vna_hash; -+ Elf32_Half vna_flags; -+ Elf32_Half vna_other; -+ Elf32_Word vna_name; -+ Elf32_Word vna_next; -+} Elf32_Vernaux; -+ -+typedef Elf32_Half Elf32_Versym; -+ -+typedef struct { -+ Elf32_Half si_boundto; /* direct bindings - symbol bound to */ -+ Elf32_Half si_flags; /* per symbol flags */ -+} Elf32_Syminfo; -+ -+#endif /* !_SYS_ELF32_H_ */ -diff --git a/ta/remoteproc/include/elf_common.h b/ta/remoteproc/include/elf_common.h -new file mode 100644 -index 000000000..a1da0ef80 ---- /dev/null -+++ b/ta/remoteproc/include/elf_common.h -@@ -0,0 +1,1014 @@ -+/* SPDX-License-Identifier: BSD-2-Clause */ -+/*- -+ * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien -+ * Copyright (c) 1998 John D. Polstra. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * $FreeBSD$ -+ */ -+ -+#ifndef _SYS_ELF_COMMON_H_ -+#define _SYS_ELF_COMMON_H_ 1 -+ -+#include -+ -+/* -+ * ELF definitions that are independent of architecture or word size. -+ */ -+ -+#ifndef __ASSEMBLER__ -+/* -+ * Note header. The ".note" section contains an array of notes. Each -+ * begins with this header, aligned to a word boundary. Immediately -+ * following the note header is n_namesz bytes of name, padded to the -+ * next word boundary. Then comes n_descsz bytes of descriptor, again -+ * padded to a word boundary. The values of n_namesz and n_descsz do -+ * not include the padding. -+ */ -+ -+typedef struct { -+ uint32_t n_namesz; /* Length of name. */ -+ uint32_t n_descsz; /* Length of descriptor. */ -+ uint32_t n_type; /* Type of this note. */ -+} Elf_Note; -+ -+/* -+ * The header for GNU-style hash sections. -+ */ -+ -+typedef struct { -+ uint32_t gh_nbuckets; /* Number of hash buckets. */ -+ uint32_t gh_symndx; /* First visible symbol in .dynsym. */ -+ uint32_t gh_maskwords; /* #maskwords used in bloom filter. */ -+ uint32_t gh_shift2; /* Bloom filter shift count. */ -+} Elf_GNU_Hash_Header; -+#endif /*__ASSEMBLER__*/ -+ -+/* Indexes into the e_ident array. Keep synced with -+ http://www.sco.com/developers/gabi/latest/ch4.eheader.html */ -+#define EI_MAG0 0 /* Magic number, byte 0. */ -+#define EI_MAG1 1 /* Magic number, byte 1. */ -+#define EI_MAG2 2 /* Magic number, byte 2. */ -+#define EI_MAG3 3 /* Magic number, byte 3. */ -+#define EI_CLASS 4 /* Class of machine. */ -+#define EI_DATA 5 /* Data format. */ -+#define EI_VERSION 6 /* ELF format version. */ -+#define EI_OSABI 7 /* Operating system / ABI identification */ -+#define EI_ABIVERSION 8 /* ABI version */ -+#define OLD_EI_BRAND 8 /* Start of architecture identification. */ -+#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ -+#define EI_NIDENT 16 /* Size of e_ident array. */ -+ -+/* Values for the magic number bytes. */ -+#define ELFMAG0 0x7f -+#define ELFMAG1 'E' -+#define ELFMAG2 'L' -+#define ELFMAG3 'F' -+#define ELFMAG "\177ELF" /* magic string */ -+#define SELFMAG 4 /* magic string size */ -+ -+/* Values for e_ident[EI_VERSION] and e_version. */ -+#define EV_NONE 0 -+#define EV_CURRENT 1 -+ -+/* Values for e_ident[EI_CLASS]. */ -+#define ELFCLASSNONE 0 /* Unknown class. */ -+#define ELFCLASS32 1 /* 32-bit architecture. */ -+#define ELFCLASS64 2 /* 64-bit architecture. */ -+ -+/* Values for e_ident[EI_DATA]. */ -+#define ELFDATANONE 0 /* Unknown data format. */ -+#define ELFDATA2LSB 1 /* 2's complement little-endian. */ -+#define ELFDATA2MSB 2 /* 2's complement big-endian. */ -+ -+/* Values for e_ident[EI_OSABI]. */ -+#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -+#define ELFOSABI_HPUX 1 /* HP-UX operating system */ -+#define ELFOSABI_NETBSD 2 /* NetBSD */ -+#define ELFOSABI_LINUX 3 /* GNU/Linux */ -+#define ELFOSABI_HURD 4 /* GNU/Hurd */ -+#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ -+#define ELFOSABI_SOLARIS 6 /* Solaris */ -+#define ELFOSABI_AIX 7 /* AIX */ -+#define ELFOSABI_IRIX 8 /* IRIX */ -+#define ELFOSABI_FREEBSD 9 /* FreeBSD */ -+#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ -+#define ELFOSABI_MODESTO 11 /* Novell Modesto */ -+#define ELFOSABI_OPENBSD 12 /* OpenBSD */ -+#define ELFOSABI_OPENVMS 13 /* Open VMS */ -+#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ -+#define ELFOSABI_AROS 15 /* Amiga Research OS */ -+#define ELFOSABI_ARM 97 /* ARM */ -+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ -+ -+#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */ -+#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */ -+ -+/* e_ident */ -+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ -+ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ -+ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ -+ (ehdr).e_ident[EI_MAG3] == ELFMAG3) -+ -+/* Values for e_type. */ -+#define ET_NONE 0 /* Unknown type. */ -+#define ET_REL 1 /* Relocatable. */ -+#define ET_EXEC 2 /* Executable. */ -+#define ET_DYN 3 /* Shared object. */ -+#define ET_CORE 4 /* Core file. */ -+#define ET_LOOS 0xfe00 /* First operating system specific. */ -+#define ET_HIOS 0xfeff /* Last operating system-specific. */ -+#define ET_LOPROC 0xff00 /* First processor-specific. */ -+#define ET_HIPROC 0xffff /* Last processor-specific. */ -+ -+/* Values for e_machine. */ -+#define EM_NONE 0 /* Unknown machine. */ -+#define EM_M32 1 /* AT&T WE32100. */ -+#define EM_SPARC 2 /* Sun SPARC. */ -+#define EM_386 3 /* Intel i386. */ -+#define EM_68K 4 /* Motorola 68000. */ -+#define EM_88K 5 /* Motorola 88000. */ -+#define EM_860 7 /* Intel i860. */ -+#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */ -+#define EM_S370 9 /* IBM System/370. */ -+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */ -+#define EM_PARISC 15 /* HP PA-RISC. */ -+#define EM_VPP500 17 /* Fujitsu VPP500. */ -+#define EM_SPARC32PLUS 18 /* SPARC v8plus. */ -+#define EM_960 19 /* Intel 80960. */ -+#define EM_PPC 20 /* PowerPC 32-bit. */ -+#define EM_PPC64 21 /* PowerPC 64-bit. */ -+#define EM_S390 22 /* IBM System/390. */ -+#define EM_V800 36 /* NEC V800. */ -+#define EM_FR20 37 /* Fujitsu FR20. */ -+#define EM_RH32 38 /* TRW RH-32. */ -+#define EM_RCE 39 /* Motorola RCE. */ -+#define EM_ARM 40 /* ARM. */ -+#define EM_SH 42 /* Hitachi SH. */ -+#define EM_SPARCV9 43 /* SPARC v9 64-bit. */ -+#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */ -+#define EM_ARC 45 /* Argonaut RISC Core. */ -+#define EM_H8_300 46 /* Hitachi H8/300. */ -+#define EM_H8_300H 47 /* Hitachi H8/300H. */ -+#define EM_H8S 48 /* Hitachi H8S. */ -+#define EM_H8_500 49 /* Hitachi H8/500. */ -+#define EM_IA_64 50 /* Intel IA-64 Processor. */ -+#define EM_MIPS_X 51 /* Stanford MIPS-X. */ -+#define EM_COLDFIRE 52 /* Motorola ColdFire. */ -+#define EM_68HC12 53 /* Motorola M68HC12. */ -+#define EM_MMA 54 /* Fujitsu MMA. */ -+#define EM_PCP 55 /* Siemens PCP. */ -+#define EM_NCPU 56 /* Sony nCPU. */ -+#define EM_NDR1 57 /* Denso NDR1 microprocessor. */ -+#define EM_STARCORE 58 /* Motorola Star*Core processor. */ -+#define EM_ME16 59 /* Toyota ME16 processor. */ -+#define EM_ST100 60 /* STMicroelectronics ST100 processor. */ -+#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */ -+#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ -+#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */ -+#define EM_PDSP 63 /* Sony DSP Processor. */ -+#define EM_FX66 66 /* Siemens FX66 microcontroller. */ -+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 -+ microcontroller. */ -+#define EM_ST7 68 /* STmicroelectronics ST7 8-bit -+ microcontroller. */ -+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller. */ -+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller. */ -+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller. */ -+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller. */ -+#define EM_SVX 73 /* Silicon Graphics SVx. */ -+#define EM_ST19 74 /* STMicroelectronics ST19 8-bit mc. */ -+#define EM_VAX 75 /* Digital VAX. */ -+#define EM_CRIS 76 /* Axis Communications 32-bit embedded -+ processor. */ -+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded -+ processor. */ -+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor. */ -+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor. */ -+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc. */ -+#define EM_HUANY 81 /* Harvard University machine-independent -+ object files. */ -+#define EM_PRISM 82 /* SiTera Prism. */ -+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller. */ -+#define EM_FR30 84 /* Fujitsu FR30. */ -+#define EM_D10V 85 /* Mitsubishi D10V. */ -+#define EM_D30V 86 /* Mitsubishi D30V. */ -+#define EM_V850 87 /* NEC v850. */ -+#define EM_M32R 88 /* Mitsubishi M32R. */ -+#define EM_MN10300 89 /* Matsushita MN10300. */ -+#define EM_MN10200 90 /* Matsushita MN10200. */ -+#define EM_PJ 91 /* picoJava. */ -+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor. */ -+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5. */ -+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture. */ -+#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor. */ -+#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose -+ Processor. */ -+#define EM_NS32K 97 /* National Semiconductor 32000 series. */ -+#define EM_TPC 98 /* Tenor Network TPC processor. */ -+#define EM_SNP1K 99 /* Trebia SNP 1000 processor. */ -+#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller. */ -+#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family. */ -+#define EM_MAX 102 /* MAX Processor. */ -+#define EM_CR 103 /* National Semiconductor CompactRISC -+ microprocessor. */ -+#define EM_F2MC16 104 /* Fujitsu F2MC16. */ -+#define EM_MSP430 105 /* Texas Instruments embedded microcontroller -+ msp430. */ -+#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor. */ -+#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors. */ -+#define EM_SEP 108 /* Sharp embedded microprocessor. */ -+#define EM_ARCA 109 /* Arca RISC Microprocessor. */ -+#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd. -+ and MPRC of Peking University */ -+#define EM_AARCH64 183 /* AArch64 (64-bit ARM) */ -+ -+/* Non-standard or deprecated. */ -+#define EM_486 6 /* Intel i486. */ -+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ -+#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */ -+#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */ -+ -+/* e_flags for EM_ARM */ -+#define EF_ARM_ABI_VERSION 0x05000000 /* ABI version 5 */ -+#define EF_ARM_ABIMASK 0xFF000000 -+#define EF_ARM_BE8 0x00800000 -+#define EF_ARM_ABI_FLOAT_HARD 0x00000400 /* ABI version 5 and later */ -+#define EF_ARM_ABI_FLOAT_SOFT 0x00000200 /* ABI version 5 and later */ -+ -+/* Special section indexes. */ -+#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ -+#define SHN_LORESERVE 0xff00 /* First of reserved range. */ -+#define SHN_LOPROC 0xff00 /* First processor-specific. */ -+#define SHN_HIPROC 0xff1f /* Last processor-specific. */ -+#define SHN_LOOS 0xff20 /* First operating system-specific. */ -+#define SHN_HIOS 0xff3f /* Last operating system-specific. */ -+#define SHN_ABS 0xfff1 /* Absolute values. */ -+#define SHN_COMMON 0xfff2 /* Common data. */ -+#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */ -+#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ -+ -+/* sh_type */ -+#define SHT_NULL 0 /* inactive */ -+#define SHT_PROGBITS 1 /* program defined information */ -+#define SHT_SYMTAB 2 /* symbol table section */ -+#define SHT_STRTAB 3 /* string table section */ -+#define SHT_RELA 4 /* relocation section with addends */ -+#define SHT_HASH 5 /* symbol hash table section */ -+#define SHT_DYNAMIC 6 /* dynamic section */ -+#define SHT_NOTE 7 /* note section */ -+#define SHT_NOBITS 8 /* no space section */ -+#define SHT_REL 9 /* relocation section - no addends */ -+#define SHT_SHLIB 10 /* reserved - purpose unknown */ -+#define SHT_DYNSYM 11 /* dynamic symbol table section */ -+#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */ -+#define SHT_FINI_ARRAY 15 /* Termination function pointers. */ -+#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */ -+#define SHT_GROUP 17 /* Section group. */ -+#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */ -+#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ -+#define SHT_LOSUNW 0x6ffffff4 -+#define SHT_SUNW_dof 0x6ffffff4 -+#define SHT_SUNW_cap 0x6ffffff5 -+#define SHT_SUNW_SIGNATURE 0x6ffffff6 -+#define SHT_GNU_HASH 0x6ffffff6 -+#define SHT_GNU_LIBLIST 0x6ffffff7 -+#define SHT_SUNW_ANNOTATE 0x6ffffff7 -+#define SHT_SUNW_DEBUGSTR 0x6ffffff8 -+#define SHT_SUNW_DEBUG 0x6ffffff9 -+#define SHT_SUNW_move 0x6ffffffa -+#define SHT_SUNW_COMDAT 0x6ffffffb -+#define SHT_SUNW_syminfo 0x6ffffffc -+#define SHT_SUNW_verdef 0x6ffffffd -+#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */ -+#define SHT_SUNW_verneed 0x6ffffffe -+#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */ -+#define SHT_SUNW_versym 0x6fffffff -+#define SHT_GNU_versym 0x6fffffff /* Symbol version table */ -+#define SHT_HISUNW 0x6fffffff -+#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ -+#define SHT_LOPROC 0x70000000 /* reserved range for processor */ -+#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */ -+#define SHT_ARM_EXIDX 0x70000001 /* Exception index table. */ -+#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking -+ pre-emption map. */ -+#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility -+ attributes. */ -+#define SHT_ARM_DEBUGOVERLAY 0x70000004 /* See DBGOVL for details. */ -+#define SHT_ARM_OVERLAYSECTION 0x70000005 /* See DBGOVL for details. */ -+#define SHT_MIPS_REGINFO 0x70000006 -+#define SHT_MIPS_OPTIONS 0x7000000d -+#define SHT_MIPS_DWARF 0x7000001e /* MIPS gcc uses MIPS_DWARF */ -+#define SHT_HIPROC 0x7fffffff /* specific section header types */ -+#define SHT_LOUSER 0x80000000 /* reserved range for application */ -+#define SHT_HIUSER 0xffffffff /* specific indexes */ -+ -+/* Flags for sh_flags. */ -+#define SHF_WRITE 0x1 /* Section contains writable data. */ -+#define SHF_ALLOC 0x2 /* Section occupies memory. */ -+#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ -+#define SHF_MERGE 0x10 /* Section may be merged. */ -+#define SHF_STRINGS 0x20 /* Section contains strings. */ -+#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */ -+#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */ -+#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */ -+#define SHF_GROUP 0x200 /* Member of section group. */ -+#define SHF_TLS 0x400 /* Section contains TLS data. */ -+#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */ -+#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */ -+ -+/* Values for p_type. */ -+#define PT_NULL 0 /* Unused entry. */ -+#define PT_LOAD 1 /* Loadable segment. */ -+#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ -+#define PT_INTERP 3 /* Pathname of interpreter. */ -+#define PT_NOTE 4 /* Auxiliary information. */ -+#define PT_SHLIB 5 /* Reserved (not used). */ -+#define PT_PHDR 6 /* Location of program header itself. */ -+#define PT_TLS 7 /* Thread local storage segment */ -+#define PT_LOOS 0x60000000 /* First OS-specific. */ -+#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */ -+#define PT_GNU_EH_FRAME 0x6474e550 -+#define PT_GNU_STACK 0x6474e551 -+#define PT_GNU_RELRO 0x6474e552 -+#define PT_LOSUNW 0x6ffffffa -+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -+#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */ -+#define PT_SUNWDTRACE 0x6ffffffc /* private */ -+#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */ -+#define PT_HISUNW 0x6fffffff -+#define PT_HIOS 0x6fffffff /* Last OS-specific. */ -+#define PT_LOPROC 0x70000000 /* First processor-specific type. */ -+#define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */ -+#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ -+ -+/* Values for p_flags. */ -+#define PF_X 0x1 /* Executable. */ -+#define PF_W 0x2 /* Writable. */ -+#define PF_R 0x4 /* Readable. */ -+#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */ -+#define PF_MASKPROC 0xf0000000 /* Processor-specific. */ -+ -+/* Extended program header index. */ -+#define PN_XNUM 0xffff -+ -+/* Values for d_tag. */ -+#define DT_NULL 0 /* Terminating entry. */ -+#define DT_NEEDED 1 /* String table offset of a needed shared -+ library. */ -+#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ -+#define DT_PLTGOT 3 /* Processor-dependent address. */ -+#define DT_HASH 4 /* Address of symbol hash table. */ -+#define DT_STRTAB 5 /* Address of string table. */ -+#define DT_SYMTAB 6 /* Address of symbol table. */ -+#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ -+#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ -+#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ -+#define DT_STRSZ 10 /* Size of string table. */ -+#define DT_SYMENT 11 /* Size of each symbol table entry. */ -+#define DT_INIT 12 /* Address of initialization function. */ -+#define DT_FINI 13 /* Address of finalization function. */ -+#define DT_SONAME 14 /* String table offset of shared object -+ name. */ -+#define DT_RPATH 15 /* String table offset of library path. [sup] */ -+#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ -+#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ -+#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ -+#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ -+#define DT_PLTREL 20 /* Type of relocation used for PLT. */ -+#define DT_DEBUG 21 /* Reserved (not used). */ -+#define DT_TEXTREL 22 /* Indicates there may be relocations in -+ non-writable segments. [sup] */ -+#define DT_JMPREL 23 /* Address of PLT relocations. */ -+#define DT_BIND_NOW 24 /* [sup] */ -+#define DT_INIT_ARRAY 25 /* Address of the array of pointers to -+ initialization functions */ -+#define DT_FINI_ARRAY 26 /* Address of the array of pointers to -+ termination functions */ -+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of -+ initialization functions. */ -+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of -+ termination functions. */ -+#define DT_RUNPATH 29 /* String table offset of a null-terminated -+ library search path string. */ -+#define DT_FLAGS 30 /* Object specific flag values. */ -+#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING -+ and less than DT_LOOS follow the rules for -+ the interpretation of the d_un union -+ as follows: even == 'd_ptr', odd == 'd_val' -+ or none */ -+#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to -+ pre-initialization functions. */ -+#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of -+ pre-initialization functions. */ -+#define DT_MAXPOSTAGS 34 /* number of positive tags */ -+#define DT_LOOS 0x6000000d /* First OS-specific */ -+#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */ -+#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */ -+#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */ -+#define DT_SUNW_CAP 0x60000010 /* hardware/software */ -+#define DT_HIOS 0x6ffff000 /* Last OS-specific */ -+ -+/* -+ * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the -+ * Dyn.d_un.d_val field of the Elf*_Dyn structure. -+ */ -+#define DT_VALRNGLO 0x6ffffd00 -+#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */ -+#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */ -+#define DT_MOVEENT 0x6ffffdfa /* move table entry size */ -+#define DT_MOVESZ 0x6ffffdfb /* move table size */ -+#define DT_FEATURE_1 0x6ffffdfc /* feature holder */ -+#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */ -+ /* the following DT_* entry. */ -+ /* See DF_P1_* definitions */ -+#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */ -+#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */ -+#define DT_VALRNGHI 0x6ffffdff -+ -+/* -+ * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the -+ * Dyn.d_un.d_ptr field of the Elf*_Dyn structure. -+ * -+ * If any adjustment is made to the ELF object after it has been -+ * built, these entries will need to be adjusted. -+ */ -+#define DT_ADDRRNGLO 0x6ffffe00 -+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table */ -+#define DT_CONFIG 0x6ffffefa /* configuration information */ -+#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */ -+#define DT_AUDIT 0x6ffffefc /* object auditing */ -+#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */ -+#define DT_MOVETAB 0x6ffffefe /* move table */ -+#define DT_SYMINFO 0x6ffffeff /* syminfo table */ -+#define DT_ADDRRNGHI 0x6ffffeff -+ -+#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */ -+#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */ -+#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */ -+#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */ -+#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */ -+#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */ -+#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */ -+#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */ -+ -+#define DT_LOPROC 0x70000000 /* First processor-specific type. */ -+#define DT_DEPRECATED_SPARC_REGISTER 0x7000001 -+#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */ -+#define DT_USED 0x7ffffffe /* ignored - same as needed */ -+#define DT_FILTER 0x7fffffff /* shared library filter name */ -+#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ -+ -+/* Values for DT_FLAGS */ -+#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may -+ make reference to the $ORIGIN substitution -+ string */ -+#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ -+#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in -+ non-writable segments. */ -+#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should -+ process all relocations for the object -+ containing this entry before transferring -+ control to the program. */ -+#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or -+ executable contains code using a static -+ thread-local storage scheme. */ -+ -+/* Values for DT_FLAGS_1 */ -+#define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */ -+#define DF_1_GLOBAL 0x00000002 /* Set the RTLD_GLOBAL for object */ -+#define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */ -+#define DF_1_LOADFLTR 0x00000010 /* Immediate loading of filtees */ -+#define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */ -+#define DF_1_ORIGIN 0x00000080 /* Process $ORIGIN */ -+#define DF_1_INTERPOSE 0x00000400 /* Interpose all objects but main */ -+#define DF_1_NODEFLIB 0x00000800 /* Do not search default paths */ -+ -+/* Values for n_type. Used in core files. */ -+#define NT_PRSTATUS 1 /* Process status. */ -+#define NT_FPREGSET 2 /* Floating point registers. */ -+#define NT_PRPSINFO 3 /* Process state info. */ -+#define NT_THRMISC 7 /* Thread miscellaneous info. */ -+#define NT_PROCSTAT_PROC 8 /* Procstat proc data. */ -+#define NT_PROCSTAT_FILES 9 /* Procstat files data. */ -+#define NT_PROCSTAT_VMMAP 10 /* Procstat vmmap data. */ -+#define NT_PROCSTAT_GROUPS 11 /* Procstat groups data. */ -+#define NT_PROCSTAT_UMASK 12 /* Procstat umask data. */ -+#define NT_PROCSTAT_RLIMIT 13 /* Procstat rlimit data. */ -+#define NT_PROCSTAT_OSREL 14 /* Procstat osreldate data. */ -+#define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */ -+#define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */ -+ -+/* Symbol Binding - ELFNN_ST_BIND - st_info */ -+#define STB_LOCAL 0 /* Local symbol */ -+#define STB_GLOBAL 1 /* Global symbol */ -+#define STB_WEAK 2 /* like global - lower precedence */ -+#define STB_LOOS 10 /* Reserved range for operating system */ -+#define STB_HIOS 12 /* specific semantics. */ -+#define STB_LOPROC 13 /* reserved range for processor */ -+#define STB_HIPROC 15 /* specific semantics. */ -+ -+/* Symbol type - ELFNN_ST_TYPE - st_info */ -+#define STT_NOTYPE 0 /* Unspecified type. */ -+#define STT_OBJECT 1 /* Data object. */ -+#define STT_FUNC 2 /* Function. */ -+#define STT_SECTION 3 /* Section. */ -+#define STT_FILE 4 /* Source file. */ -+#define STT_COMMON 5 /* Uninitialized common block. */ -+#define STT_TLS 6 /* TLS object. */ -+#define STT_NUM 7 -+#define STT_LOOS 10 /* Reserved range for operating system */ -+#define STT_GNU_IFUNC 10 -+#define STT_HIOS 12 /* specific semantics. */ -+#define STT_LOPROC 13 /* reserved range for processor */ -+#define STT_HIPROC 15 /* specific semantics. */ -+ -+/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ -+#define STV_DEFAULT 0x0 /* Default visibility (see binding). */ -+#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */ -+#define STV_HIDDEN 0x2 /* Not visible. */ -+#define STV_PROTECTED 0x3 /* Visible but not preemptible. */ -+#define STV_EXPORTED 0x4 -+#define STV_SINGLETON 0x5 -+#define STV_ELIMINATE 0x6 -+ -+/* Special symbol table indexes. */ -+#define STN_UNDEF 0 /* Undefined symbol index. */ -+ -+/* Symbol versioning flags. */ -+#define VER_DEF_CURRENT 1 -+#define VER_DEF_IDX(x) VER_NDX(x) -+ -+#define VER_FLG_BASE 0x01 -+#define VER_FLG_WEAK 0x02 -+ -+#define VER_NEED_CURRENT 1 -+#define VER_NEED_WEAK (1u << 15) -+#define VER_NEED_HIDDEN VER_NDX_HIDDEN -+#define VER_NEED_IDX(x) VER_NDX(x) -+ -+#define VER_NDX_LOCAL 0 -+#define VER_NDX_GLOBAL 1 -+#define VER_NDX_GIVEN 2 -+ -+#define VER_NDX_HIDDEN (1u << 15) -+#define VER_NDX(x) ((x) & ~(1u << 15)) -+ -+#define CA_SUNW_NULL 0 -+#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */ -+#define CA_SUNW_SF_1 2 /* first software capabilities entry */ -+ -+/* -+ * Syminfo flag values -+ */ -+#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */ -+ /* to object containing defn. */ -+#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */ -+#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */ -+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */ -+ /* lazily-loaded */ -+#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */ -+ /* object containing defn. */ -+#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */ -+ /* directly bind to this symbol */ -+#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */ -+#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */ -+ -+/* -+ * Syminfo.si_boundto values. -+ */ -+#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */ -+#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */ -+#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */ -+#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */ -+#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */ -+ -+/* -+ * Syminfo version values. -+ */ -+#define SYMINFO_NONE 0 /* Syminfo version */ -+#define SYMINFO_CURRENT 1 -+#define SYMINFO_NUM 2 -+ -+/* -+ * Relocation types. -+ * -+ * All machine architectures are defined here to allow tools on one to -+ * handle others. -+ */ -+ -+#define R_386_NONE 0 /* No relocation. */ -+#define R_386_32 1 /* Add symbol value. */ -+#define R_386_PC32 2 /* Add PC-relative symbol value. */ -+#define R_386_GOT32 3 /* Add PC-relative GOT offset. */ -+#define R_386_PLT32 4 /* Add PC-relative PLT offset. */ -+#define R_386_COPY 5 /* Copy data from shared object. */ -+#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ -+#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ -+#define R_386_RELATIVE 8 /* Add load address of shared object. */ -+#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ -+#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ -+#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ -+#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ -+#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ -+#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ -+#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ -+#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ -+#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ -+#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ -+#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ -+#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ -+#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ -+#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ -+#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ -+#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ -+#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ -+#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ -+#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ -+#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ -+#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ -+#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ -+#define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */ -+ -+#define R_AARCH64_ABS64 257 -+#define R_AARCH64_GLOB_DAT 1025 /* Set GOT entry to data address. */ -+#define R_AARCH64_JUMP_SLOT 1026 /* Set GOT entry to code address. */ -+#define R_AARCH64_RELATIVE 1027 -+ -+#define R_ARM_NONE 0 /* No relocation. */ -+#define R_ARM_PC24 1 -+#define R_ARM_ABS32 2 -+#define R_ARM_REL32 3 -+#define R_ARM_PC13 4 -+#define R_ARM_ABS16 5 -+#define R_ARM_ABS12 6 -+#define R_ARM_THM_ABS5 7 -+#define R_ARM_ABS8 8 -+#define R_ARM_SBREL32 9 -+#define R_ARM_THM_PC22 10 -+#define R_ARM_THM_PC8 11 -+#define R_ARM_AMP_VCALL9 12 -+#define R_ARM_SWI24 13 -+#define R_ARM_THM_SWI8 14 -+#define R_ARM_XPC25 15 -+#define R_ARM_THM_XPC22 16 -+/* TLS relocations */ -+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ -+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ -+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ -+#define R_ARM_COPY 20 /* Copy data from shared object. */ -+#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */ -+#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */ -+#define R_ARM_RELATIVE 23 /* Add load address of shared object. */ -+#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */ -+#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */ -+#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */ -+#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ -+#define R_ARM_GNU_VTENTRY 100 -+#define R_ARM_GNU_VTINHERIT 101 -+#define R_ARM_RSBREL32 250 -+#define R_ARM_THM_RPC22 251 -+#define R_ARM_RREL32 252 -+#define R_ARM_RABS32 253 -+#define R_ARM_RPC24 254 -+#define R_ARM_RBASE 255 -+ -+/* Name Value Field Calculation */ -+#define R_IA_64_NONE 0 /* None */ -+#define R_IA_64_IMM14 0x21 /* immediate14 S + A */ -+#define R_IA_64_IMM22 0x22 /* immediate22 S + A */ -+#define R_IA_64_IMM64 0x23 /* immediate64 S + A */ -+#define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */ -+#define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */ -+#define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */ -+#define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */ -+#define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */ -+#define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */ -+#define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */ -+#define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */ -+#define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */ -+#define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */ -+#define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */ -+#define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */ -+#define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */ -+#define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */ -+#define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */ -+#define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */ -+#define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */ -+#define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */ -+#define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */ -+#define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */ -+#define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */ -+#define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */ -+#define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */ -+#define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */ -+#define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */ -+#define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */ -+#define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */ -+#define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */ -+#define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */ -+#define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */ -+#define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */ -+#define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */ -+#define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */ -+#define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */ -+#define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */ -+#define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */ -+#define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */ -+#define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */ -+#define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */ -+#define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */ -+#define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */ -+#define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */ -+#define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */ -+#define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */ -+#define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */ -+#define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */ -+#define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */ -+#define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */ -+#define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */ -+#define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */ -+#define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */ -+#define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */ -+#define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */ -+#define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */ -+#define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */ -+#define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */ -+#define R_IA_64_SUB 0x85 /* immediate64 A - S */ -+#define R_IA_64_LTOFF22X 0x86 /* immediate22 special */ -+#define R_IA_64_LDXMOV 0x87 /* immediate22 special */ -+#define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */ -+#define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */ -+#define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */ -+#define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */ -+#define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */ -+#define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */ -+#define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */ -+#define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */ -+#define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */ -+#define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */ -+#define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */ -+#define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */ -+#define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */ -+#define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */ -+#define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */ -+#define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */ -+#define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */ -+ -+#define R_MIPS_NONE 0 /* No reloc */ -+#define R_MIPS_16 1 /* Direct 16 bit */ -+#define R_MIPS_32 2 /* Direct 32 bit */ -+#define R_MIPS_REL32 3 /* PC relative 32 bit */ -+#define R_MIPS_26 4 /* Direct 26 bit shifted */ -+#define R_MIPS_HI16 5 /* High 16 bit */ -+#define R_MIPS_LO16 6 /* Low 16 bit */ -+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ -+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ -+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ -+#define R_MIPS_PC16 10 /* PC relative 16 bit */ -+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ -+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ -+#define R_MIPS_64 18 /* Direct 64 bit */ -+#define R_MIPS_GOTHI16 21 /* GOT HI 16 bit */ -+#define R_MIPS_GOTLO16 22 /* GOT LO 16 bit */ -+#define R_MIPS_CALLHI16 30 /* upper 16 bit GOT entry for function */ -+#define R_MIPS_CALLLO16 31 /* lower 16 bit GOT entry for function */ -+ -+#define R_PPC_NONE 0 /* No relocation. */ -+#define R_PPC_ADDR32 1 -+#define R_PPC_ADDR24 2 -+#define R_PPC_ADDR16 3 -+#define R_PPC_ADDR16_LO 4 -+#define R_PPC_ADDR16_HI 5 -+#define R_PPC_ADDR16_HA 6 -+#define R_PPC_ADDR14 7 -+#define R_PPC_ADDR14_BRTAKEN 8 -+#define R_PPC_ADDR14_BRNTAKEN 9 -+#define R_PPC_REL24 10 -+#define R_PPC_REL14 11 -+#define R_PPC_REL14_BRTAKEN 12 -+#define R_PPC_REL14_BRNTAKEN 13 -+#define R_PPC_GOT16 14 -+#define R_PPC_GOT16_LO 15 -+#define R_PPC_GOT16_HI 16 -+#define R_PPC_GOT16_HA 17 -+#define R_PPC_PLTREL24 18 -+#define R_PPC_COPY 19 -+#define R_PPC_GLOB_DAT 20 -+#define R_PPC_JMP_SLOT 21 -+#define R_PPC_RELATIVE 22 -+#define R_PPC_LOCAL24PC 23 -+#define R_PPC_UADDR32 24 -+#define R_PPC_UADDR16 25 -+#define R_PPC_REL32 26 -+#define R_PPC_PLT32 27 -+#define R_PPC_PLTREL32 28 -+#define R_PPC_PLT16_LO 29 -+#define R_PPC_PLT16_HI 30 -+#define R_PPC_PLT16_HA 31 -+#define R_PPC_SDAREL16 32 -+#define R_PPC_SECTOFF 33 -+#define R_PPC_SECTOFF_LO 34 -+#define R_PPC_SECTOFF_HI 35 -+#define R_PPC_SECTOFF_HA 36 -+ -+/* -+ * 64-bit relocations -+ */ -+#define R_PPC64_ADDR64 38 -+#define R_PPC64_ADDR16_HIGHER 39 -+#define R_PPC64_ADDR16_HIGHERA 40 -+#define R_PPC64_ADDR16_HIGHEST 41 -+#define R_PPC64_ADDR16_HIGHESTA 42 -+#define R_PPC64_UADDR64 43 -+#define R_PPC64_REL64 44 -+#define R_PPC64_PLT64 45 -+#define R_PPC64_PLTREL64 46 -+#define R_PPC64_TOC16 47 -+#define R_PPC64_TOC16_LO 48 -+#define R_PPC64_TOC16_HI 49 -+#define R_PPC64_TOC16_HA 50 -+#define R_PPC64_TOC 51 -+#define R_PPC64_DTPMOD64 68 -+#define R_PPC64_TPREL64 73 -+#define R_PPC64_DTPREL64 78 -+ -+/* -+ * TLS relocations -+ */ -+#define R_PPC_TLS 67 -+#define R_PPC_DTPMOD32 68 -+#define R_PPC_TPREL16 69 -+#define R_PPC_TPREL16_LO 70 -+#define R_PPC_TPREL16_HI 71 -+#define R_PPC_TPREL16_HA 72 -+#define R_PPC_TPREL32 73 -+#define R_PPC_DTPREL16 74 -+#define R_PPC_DTPREL16_LO 75 -+#define R_PPC_DTPREL16_HI 76 -+#define R_PPC_DTPREL16_HA 77 -+#define R_PPC_DTPREL32 78 -+#define R_PPC_GOT_TLSGD16 79 -+#define R_PPC_GOT_TLSGD16_LO 80 -+#define R_PPC_GOT_TLSGD16_HI 81 -+#define R_PPC_GOT_TLSGD16_HA 82 -+#define R_PPC_GOT_TLSLD16 83 -+#define R_PPC_GOT_TLSLD16_LO 84 -+#define R_PPC_GOT_TLSLD16_HI 85 -+#define R_PPC_GOT_TLSLD16_HA 86 -+#define R_PPC_GOT_TPREL16 87 -+#define R_PPC_GOT_TPREL16_LO 88 -+#define R_PPC_GOT_TPREL16_HI 89 -+#define R_PPC_GOT_TPREL16_HA 90 -+ -+/* -+ * The remaining relocs are from the Embedded ELF ABI, and are not in the -+ * SVR4 ELF ABI. -+ */ -+ -+#define R_PPC_EMB_NADDR32 101 -+#define R_PPC_EMB_NADDR16 102 -+#define R_PPC_EMB_NADDR16_LO 103 -+#define R_PPC_EMB_NADDR16_HI 104 -+#define R_PPC_EMB_NADDR16_HA 105 -+#define R_PPC_EMB_SDAI16 106 -+#define R_PPC_EMB_SDA2I16 107 -+#define R_PPC_EMB_SDA2REL 108 -+#define R_PPC_EMB_SDA21 109 -+#define R_PPC_EMB_MRKREF 110 -+#define R_PPC_EMB_RELSEC16 111 -+#define R_PPC_EMB_RELST_LO 112 -+#define R_PPC_EMB_RELST_HI 113 -+#define R_PPC_EMB_RELST_HA 114 -+#define R_PPC_EMB_BIT_FLD 115 -+#define R_PPC_EMB_RELSDA 116 -+ -+#define R_SPARC_NONE 0 -+#define R_SPARC_8 1 -+#define R_SPARC_16 2 -+#define R_SPARC_32 3 -+#define R_SPARC_DISP8 4 -+#define R_SPARC_DISP16 5 -+#define R_SPARC_DISP32 6 -+#define R_SPARC_WDISP30 7 -+#define R_SPARC_WDISP22 8 -+#define R_SPARC_HI22 9 -+#define R_SPARC_22 10 -+#define R_SPARC_13 11 -+#define R_SPARC_LO10 12 -+#define R_SPARC_GOT10 13 -+#define R_SPARC_GOT13 14 -+#define R_SPARC_GOT22 15 -+#define R_SPARC_PC10 16 -+#define R_SPARC_PC22 17 -+#define R_SPARC_WPLT30 18 -+#define R_SPARC_COPY 19 -+#define R_SPARC_GLOB_DAT 20 -+#define R_SPARC_JMP_SLOT 21 -+#define R_SPARC_RELATIVE 22 -+#define R_SPARC_UA32 23 -+#define R_SPARC_PLT32 24 -+#define R_SPARC_HIPLT22 25 -+#define R_SPARC_LOPLT10 26 -+#define R_SPARC_PCPLT32 27 -+#define R_SPARC_PCPLT22 28 -+#define R_SPARC_PCPLT10 29 -+#define R_SPARC_10 30 -+#define R_SPARC_11 31 -+#define R_SPARC_64 32 -+#define R_SPARC_OLO10 33 -+#define R_SPARC_HH22 34 -+#define R_SPARC_HM10 35 -+#define R_SPARC_LM22 36 -+#define R_SPARC_PC_HH22 37 -+#define R_SPARC_PC_HM10 38 -+#define R_SPARC_PC_LM22 39 -+#define R_SPARC_WDISP16 40 -+#define R_SPARC_WDISP19 41 -+#define R_SPARC_GLOB_JMP 42 -+#define R_SPARC_7 43 -+#define R_SPARC_5 44 -+#define R_SPARC_6 45 -+#define R_SPARC_DISP64 46 -+#define R_SPARC_PLT64 47 -+#define R_SPARC_HIX22 48 -+#define R_SPARC_LOX10 49 -+#define R_SPARC_H44 50 -+#define R_SPARC_M44 51 -+#define R_SPARC_L44 52 -+#define R_SPARC_REGISTER 53 -+#define R_SPARC_UA64 54 -+#define R_SPARC_UA16 55 -+#define R_SPARC_TLS_GD_HI22 56 -+#define R_SPARC_TLS_GD_LO10 57 -+#define R_SPARC_TLS_GD_ADD 58 -+#define R_SPARC_TLS_GD_CALL 59 -+#define R_SPARC_TLS_LDM_HI22 60 -+#define R_SPARC_TLS_LDM_LO10 61 -+#define R_SPARC_TLS_LDM_ADD 62 -+#define R_SPARC_TLS_LDM_CALL 63 -+#define R_SPARC_TLS_LDO_HIX22 64 -+#define R_SPARC_TLS_LDO_LOX10 65 -+#define R_SPARC_TLS_LDO_ADD 66 -+#define R_SPARC_TLS_IE_HI22 67 -+#define R_SPARC_TLS_IE_LO10 68 -+#define R_SPARC_TLS_IE_LD 69 -+#define R_SPARC_TLS_IE_LDX 70 -+#define R_SPARC_TLS_IE_ADD 71 -+#define R_SPARC_TLS_LE_HIX22 72 -+#define R_SPARC_TLS_LE_LOX10 73 -+#define R_SPARC_TLS_DTPMOD32 74 -+#define R_SPARC_TLS_DTPMOD64 75 -+#define R_SPARC_TLS_DTPOFF32 76 -+#define R_SPARC_TLS_DTPOFF64 77 -+#define R_SPARC_TLS_TPOFF32 78 -+#define R_SPARC_TLS_TPOFF64 79 -+ -+#define R_X86_64_NONE 0 /* No relocation. */ -+#define R_X86_64_64 1 /* Add 64 bit symbol value. */ -+#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */ -+#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */ -+#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */ -+#define R_X86_64_COPY 5 /* Copy data from shared object. */ -+#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */ -+#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */ -+#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */ -+#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */ -+#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */ -+#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */ -+#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */ -+#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */ -+#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */ -+#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */ -+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -+#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */ -+#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */ -+#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */ -+#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */ -+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -+#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ -+#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ -+#define R_X86_64_IRELATIVE 37 -+ -+#endif /* !_SYS_ELF_COMMON_H_ */ -diff --git a/ta/remoteproc/include/elf_parser.h b/ta/remoteproc/include/elf_parser.h -new file mode 100644 -index 000000000..5950db971 ---- /dev/null -+++ b/ta/remoteproc/include/elf_parser.h -@@ -0,0 +1,59 @@ -+/* SPDX-License-Identifier: BSD-2-Clause */ -+/* -+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved -+ */ -+ -+#ifndef ELF_PARSER -+#define ELF_PARSER -+ -+#include -+#include -+#include -+ -+/** -+ * struct resource_table - firmware resource table header -+ * @ver: version number -+ * @num: number of resource entries -+ * @reserved: reserved (must be zero) -+ * @offset: array of offsets pointing at the various resource entries -+ * -+ * A resource table is essentially a list of system resources required -+ * by the remote processor. It may also include configuration entries. -+ * If needed, the remote processor firmware should contain this table -+ * as a dedicated ".resource_table" ELF section. -+ * -+ * This structure shall be consistent with the Linux kernel structure -+ * definition from include/linux/remoteproc.h. -+ */ -+struct resource_table { -+ uint32_t ver; -+ uint32_t num; -+ uint32_t reserved[2]; -+ uint32_t offset[]; -+} __packed; -+ -+struct fw_elf32 { -+ uintptr_t e_entry; -+ uintptr_t e_phoff; -+ uintptr_t e_shoff; -+ uint32_t e_phnum; -+ uint32_t e_shnum; -+ uint32_t e_phentsize; -+ uint32_t e_shentsize; -+ -+ Elf32_Phdr *phdr; -+ Elf32_Shdr *shdr; -+}; -+ -+TEE_Result e32_parse_ehdr(uint8_t *fw, size_t size); -+TEE_Result e32_parser_load_elf_image(uint8_t *fw, size_t fw_size, -+ TEE_Result (*load_seg)(uint8_t *src, -+ uint32_t size, -+ uint32_t da, -+ uint32_t mem_size, -+ void *priv), -+ void *priv_data); -+int e32_parser_find_rsc_table(uint8_t *fw, size_t fw_size, Elf32_Addr *rsc_addr, -+ Elf32_Word *rsc_size); -+ -+#endif /*ELF_PARSER*/ -diff --git a/ta/remoteproc/include/ta_remoteproc.h b/ta/remoteproc/include/ta_remoteproc.h -new file mode 100644 -index 000000000..a51ba5f70 ---- /dev/null -+++ b/ta/remoteproc/include/ta_remoteproc.h -@@ -0,0 +1,65 @@ -+/* SPDX-License-Identifier: BSD-2-Clause */ -+/* -+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved -+ */ -+ -+#ifndef TA_RPROC_FW_H -+#define TA_RPROC_FW_H -+ -+/* -+ * This UUID is generated with uuidgen -+ * the ITU-T UUID generator at http://www.itu.int/ITU-T/asn1/uuid.html -+ */ -+#define TA_REMOTEPROC_UUID \ -+ { 0x80a4c275, 0x0a47, 0x4905, \ -+ { 0x82, 0x85, 0x14, 0x86, 0xa9, 0x77, 0x1a, 0x08} } -+ -+/* The function IDs implemented in this TA */ -+ -+/* -+ * Authentication of the firmware and load in the remote processor memory. -+ * -+ * [in] params[0].value.a: unique 32bit identifier of the firmware -+ * [in] params[1].memref: buffer containing the image of the firmware -+ */ -+#define TA_RPROC_FW_CMD_LOAD_FW 1 -+ -+/* -+ * Start the remote processor. -+ * -+ * [in] params[0].value.a: unique 32bit identifier of the firmware -+ */ -+#define TA_RPROC_FW_CMD_START_FW 2 -+ -+/* -+ * Stop the remote processor. -+ * -+ * [in] params[0].value.a: unique 32bit identifier of the firmware -+ */ -+#define TA_RPROC_FW_CMD_STOP_FW 3 -+ -+/* -+ * Return the physical address of the resource table, or 0 if not found -+ * No check is done to verify that the address returned is accessible by the -+ * non secure world. If the resource table is loaded in a protected memory, -+ * then accesses from non-secure world will likely fail. -+ * -+ * [in] params[0].value.a: unique 32bit identifier of the firmware -+ * [out] params[1].value.a: 32bit LSB resource table memory address -+ * [out] params[1].value.b: 32bit MSB resource table memory address -+ * [out] params[2].value.a: 32bit LSB resource table memory size -+ * [out] params[2].value.b: 32bit MSB resource table memory size -+ */ -+#define TA_RPROC_FW_CMD_GET_RSC_TABLE 4 -+ -+/* -+ * Get remote processor firmware core dump. If found, return either -+ * TEE_SUCCESS on successful completion or TEE_ERROR_SHORT_BUFFER if output -+ * buffer is too short to store the core dump. -+ * -+ * [in] params[0].value.a: unique 32bit identifier of the firmware -+ * [out] params[1].memref: Core dump, if found -+ */ -+#define TA_RPROC_FW_CMD_GET_COREDUMP 5 -+ -+#endif /*TA_RPROC_FW_H*/ -diff --git a/ta/remoteproc/include/user_ta_header_defines.h b/ta/remoteproc/include/user_ta_header_defines.h -new file mode 100644 -index 000000000..c2ef1b21b ---- /dev/null -+++ b/ta/remoteproc/include/user_ta_header_defines.h -@@ -0,0 +1,29 @@ -+/* SPDX-License-Identifier: BSD-2-Clause */ -+/* -+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved -+ */ -+ -+#ifndef USER_TA_HEADER_DEFINES_H -+#define USER_TA_HEADER_DEFINES_H -+ -+#include -+ -+#define TA_UUID TA_REMOTEPROC_UUID -+ -+#define TA_FLAGS (TA_FLAG_DEVICE_ENUM | \ -+ TA_FLAG_SINGLE_INSTANCE | \ -+ TA_FLAG_INSTANCE_KEEP_ALIVE) -+ -+/* Provisioned stack size */ -+#define TA_STACK_SIZE (4 * 1024) -+ -+/* Provisioned heap size for TEE_Malloc() and friends */ -+#define TA_DATA_SIZE (4 * 1024) -+ -+/* The gpd.ta.version property */ -+#define TA_VERSION "1.0" -+ -+/* The gpd.ta.description property */ -+#define TA_DESCRIPTION "remote processor firmware management" -+ -+#endif /* USER_TA_HEADER_DEFINES_H */ -diff --git a/ta/remoteproc/remoteproc_core.c b/ta/remoteproc/remoteproc_core.c -new file mode 100644 -index 000000000..341827b13 ---- /dev/null -+++ b/ta/remoteproc/remoteproc_core.c -@@ -0,0 +1,781 @@ -+ // SPDX-License-Identifier: BSD-2-Clause -+ /* -+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Firmware state */ -+enum remoteproc_state { -+ REMOTEPROC_OFF, -+ REMOTEPROC_LOADED, -+ REMOTEPROC_STARTED, -+}; -+ -+#define RPROC_HDR_MAGIC 0x3543A468 /*random value */ -+#define HEADER_VERSION 1 -+ -+/* Supported signature algorithm */ -+enum remoteproc_sign_type { -+ RPROC_RSASSA_PKCS1_v1_5_SHA256 = 1, -+ RPROC_ECDSA_SHA256 = 2, -+}; -+ -+/* -+ * struct remoteproc_segment - program header with hash structure -+ * @phdr: program header -+ * @hash: hash associated to the program segment. -+ */ -+struct remoteproc_segment { -+ Elf32_Phdr phdr; -+ unsigned char hash[TEE_SHA256_HASH_SIZE]; -+}; -+ -+/* -+ * struct remoteproc_fw_hdr - firmware header -+ * @magic: Magic number, must be equal to RPROC_HDR_MAGIC -+ * @version: Version of the header (must be 1) -+ * @hdr_length: Total header byte length including chunks -+ * @sign_length: Signature chunk byte length -+ * @sign_offset: Signature chunk byte offset from header start -+ * @sign_type: Signature type -+ * @phhdr_length: Program header with hashes byte size, possibly 0 -+ * @phhdr_offset: Program header with hashes byte offset, 0 if not used -+ * @phhdr_type: Program header with hash type or 0 if not used -+ * @key_length: Authentication key info byte length, possibly 0 -+ * @key_offset: Authentication key info byte offset, 0 if not used -+ * @img_length: Firmware image chunk byte length -+ * @img_offset: Firmware image chunk byte offset -+ * @img_type: Firmware image type -+ */ -+struct remoteproc_fw_hdr { -+ uint32_t magic; -+ uint32_t version; -+ uint32_t hdr_length; -+ uint32_t sign_length; -+ uint32_t sign_offset; -+ uint32_t sign_type; -+ uint32_t phhdr_length; -+ uint32_t phhdr_offset; -+ uint32_t phhdr_type; -+ uint32_t key_length; -+ uint32_t key_offset; -+ uint32_t img_length; -+ uint32_t img_offset; -+ uint32_t img_type; -+}; -+ -+/* -+ * struct remoteproc_sig_algo - signature algorithm information -+ * @sign_type: Header signature type -+ * @id: Signature algorigthm identifier TEE_ALG_* -+ * @hash_len: Signature hash length -+ */ -+struct remoteproc_sig_algo { -+ enum remoteproc_sign_type sign_type; -+ uint32_t id; -+ size_t hash_len; -+}; -+ -+/* -+ * struct remoteproc_context - firmware context -+ * @fw_id: Unique Id of the firmware -+ * @hdr: Location of a secure copy of the firmware header -+ * @fw_img: Firmware image -+ * @fw_img_size: Byte size of the firmware image -+ * @rsc_pa: Physical address of the firmware resource table -+ * @rsc_size: Byte size of the firmware resource table -+ * @state: Remote-processor state -+ * @hw_fmt: Image format capabilities of the remoteproc PTA -+ * @hw_img_prot: Image protection capabilities of the remoteproc PTA -+ * @link: Linked list element -+ */ -+struct remoteproc_context { -+ uint32_t fw_id; -+ struct remoteproc_fw_hdr *hdr; -+ uint8_t *fw_img; -+ size_t fw_img_size; -+ paddr_t rsc_pa; -+ size_t rsc_size; -+ enum remoteproc_state state; -+ uint32_t hw_fmt; -+ uint32_t hw_img_prot; -+ TAILQ_ENTRY(remoteproc_context) link; -+}; -+ -+TAILQ_HEAD(remoteproc_firmware_head, remoteproc_context); -+ -+static struct remoteproc_firmware_head firmware_head = -+ TAILQ_HEAD_INITIALIZER(firmware_head); -+ -+static const struct remoteproc_sig_algo rproc_ta_sign_algo[] = { -+ { -+ .sign_type = RPROC_RSASSA_PKCS1_v1_5_SHA256, -+ .id = TEE_ALG_RSASSA_PKCS1_V1_5_SHA256, -+ .hash_len = TEE_SHA256_HASH_SIZE, -+ }, -+ { -+ .sign_type = RPROC_ECDSA_SHA256, -+ .id = TEE_ALG_ECDSA_P256, -+ .hash_len = TEE_SHA256_HASH_SIZE, -+ }, -+}; -+ -+static size_t session_refcount; -+static TEE_TASessionHandle pta_session; -+ -+static void remoteproc_header_dump(struct remoteproc_fw_hdr __maybe_unused *hdr) -+{ -+ DMSG("magic :\t%#"PRIx32, hdr->magic); -+ DMSG("version :\t%#"PRIx32, hdr->version); -+ DMSG("hdr_length :\t%#"PRIx32, hdr->hdr_length); -+ DMSG("sign_length :\t%#"PRIx32, hdr->sign_length); -+ DMSG("sign_offset :\t%#"PRIx32, hdr->sign_offset); -+ DMSG("sign_type :\t%#"PRIx32, hdr->sign_type); -+ DMSG("phhdr_length :\t%#"PRIx32, hdr->phhdr_length); -+ DMSG("phhdr_offset :\t%#"PRIx32, hdr->phhdr_offset); -+ DMSG("phhdr_type :\t%#"PRIx32, hdr->phhdr_type); -+ DMSG("key_length :\t%#"PRIx32, hdr->key_length); -+ DMSG("key_offset :\t%#"PRIx32, hdr->key_offset); -+ DMSG("img_length :\t%#"PRIx32, hdr->img_length); -+ DMSG("img_offset :\t%#"PRIx32, hdr->img_offset); -+ DMSG("img_type :\t%#"PRIx32, hdr->img_type); -+} -+ -+static struct remoteproc_context *remoteproc_find_firmware(uint32_t fw_id) -+{ -+ struct remoteproc_context *ctx = NULL; -+ -+ TAILQ_FOREACH(ctx, &firmware_head, link) { -+ if (ctx->fw_id == fw_id) -+ return ctx; -+ } -+ -+ return NULL; -+} -+ -+static struct remoteproc_context *remoteproc_add_firmware(uint32_t fw_id) -+{ -+ struct remoteproc_context *ctx = NULL; -+ -+ ctx = TEE_Malloc(sizeof(*ctx), TEE_MALLOC_FILL_ZERO); -+ if (!ctx) -+ return NULL; -+ -+ ctx->fw_id = fw_id; -+ -+ TAILQ_INSERT_TAIL(&firmware_head, ctx, link); -+ -+ return ctx; -+} -+ -+static const struct remoteproc_sig_algo *remoteproc_get_algo(uint32_t sign_type) -+{ -+ unsigned int i = 0; -+ -+ for (i = 0; i < ARRAY_SIZE(rproc_ta_sign_algo); i++) -+ if (sign_type == rproc_ta_sign_algo[i].sign_type) -+ return &rproc_ta_sign_algo[i]; -+ -+ return NULL; -+} -+ -+static TEE_Result remoteproc_pta_verify(struct remoteproc_context *ctx, -+ const struct remoteproc_sig_algo *algo, -+ char *hash, size_t hash_len) -+{ -+ TEE_Result res = TEE_ERROR_GENERIC; -+ struct remoteproc_fw_hdr *hdr = ctx->hdr; -+ struct rproc_pta_key_info *keyinfo = NULL; -+ uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT); -+ TEE_Param params[TEE_NUM_PARAMS] = { }; -+ -+ keyinfo = TEE_Malloc(sizeof(*keyinfo) + hdr->key_length, 0); -+ if (!keyinfo) -+ return TEE_ERROR_OUT_OF_MEMORY; -+ -+ keyinfo->algo = algo->id; -+ keyinfo->info_size = hdr->key_length; -+ memcpy(keyinfo->info, (uint8_t *)hdr + hdr->key_offset, -+ hdr->key_length); -+ -+ params[0].value.a = ctx->fw_id; -+ params[1].memref.buffer = keyinfo; -+ params[1].memref.size = RPROC_PTA_GET_KEYINFO_SIZE(keyinfo); -+ params[2].memref.buffer = hash; -+ params[2].memref.size = hash_len; -+ params[3].memref.buffer = (uint8_t *)hdr + hdr->sign_offset; -+ params[3].memref.size = hdr->sign_length; -+ -+ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, -+ PTA_REMOTEPROC_VERIFY_DIGEST, -+ param_types, params, NULL); -+ if (res != TEE_SUCCESS) -+ EMSG("Failed to verify signature, res = %#"PRIx32, res); -+ -+ TEE_Free(keyinfo); -+ -+ return res; -+} -+ -+static TEE_Result remoteproc_save_fw_header(struct remoteproc_context *ctx, -+ void *fw_orig, -+ uint32_t fw_orig_size) -+{ -+ struct remoteproc_fw_hdr *hdr = fw_orig; -+ -+ remoteproc_header_dump(hdr); -+ -+ if (fw_orig_size <= sizeof(*hdr) || fw_orig_size <= hdr->hdr_length) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ ctx->hdr = TEE_Malloc(hdr->hdr_length, TEE_MALLOC_FILL_ZERO); -+ if (!ctx->hdr) -+ return TEE_ERROR_OUT_OF_MEMORY; -+ -+ memcpy(ctx->hdr, fw_orig, hdr->hdr_length); -+ -+ return TEE_SUCCESS; -+} -+ -+static TEE_Result remoteproc_verify_signature(struct remoteproc_context *ctx) -+{ -+ TEE_OperationHandle op = TEE_HANDLE_NULL; -+ struct remoteproc_fw_hdr *hdr = ctx->hdr; -+ const struct remoteproc_sig_algo *algo = NULL; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ char *hash = NULL; -+ size_t hash_len = 0; -+ -+ algo = remoteproc_get_algo(hdr->sign_type); -+ if (!algo) { -+ EMSG("Unsupported signature type %d", hdr->sign_type); -+ return TEE_ERROR_NOT_SUPPORTED; -+ } -+ -+ /* Compute the header hash */ -+ hash_len = algo->hash_len; -+ hash = TEE_Malloc(hash_len, 0); -+ if (!hash) -+ return TEE_ERROR_OUT_OF_MEMORY; -+ -+ res = TEE_AllocateOperation(&op, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0); -+ if (res != TEE_SUCCESS) -+ goto free_hash; -+ -+ res = TEE_DigestDoFinal(op, hdr, hdr->sign_offset, hash, &hash_len); -+ if (res != TEE_SUCCESS) -+ goto out; -+ -+ /* -+ * TODO: -+ * Provide alternative to verify the signature in the TA. This could -+ * be done for instance by getting the key object from secure storage. -+ */ -+ -+ /* By default ask the pta to verify the signature. */ -+ res = remoteproc_pta_verify(ctx, algo, hash, hash_len); -+ -+out: -+ TEE_FreeOperation(op); -+free_hash: -+ TEE_Free(hash); -+ -+ return res; -+} -+ -+static TEE_Result remoteproc_verify_header(struct remoteproc_context *ctx) -+{ -+ struct remoteproc_fw_hdr *hdr = ctx->hdr; -+ uint32_t hdr_size = 0; -+ uint32_t chunk_size = 0; -+ uint32_t alignment = 0; -+ -+ if (hdr->magic != RPROC_HDR_MAGIC) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ if (hdr->version != HEADER_VERSION) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ /* -+ * The offsets are aligned to 64 bits format. The hdr_length takes into -+ * account these alignments while the length of each chunks are the -+ * effective length,excluding the alignment padding bytes. -+ */ -+ alignment = hdr->sign_length % sizeof(uint64_t) + -+ hdr->phhdr_length % sizeof(uint64_t) + -+ hdr->key_length % sizeof(uint64_t); -+ -+ if (ADD_OVERFLOW(sizeof(*hdr), hdr->sign_length, &hdr_size) || -+ ADD_OVERFLOW(hdr_size, hdr->phhdr_length, &hdr_size) || -+ ADD_OVERFLOW(hdr_size, hdr->key_length, &hdr_size) || -+ ADD_OVERFLOW(hdr_size, alignment, &hdr_size) || -+ hdr->hdr_length != hdr_size) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ if (ADD_OVERFLOW(hdr->sign_offset, hdr->sign_length, &chunk_size) || -+ chunk_size > hdr_size || -+ ADD_OVERFLOW(hdr->key_offset, hdr->key_length, &chunk_size) || -+ chunk_size > hdr_size || -+ ADD_OVERFLOW(hdr->phhdr_offset, hdr->phhdr_length, &chunk_size) || -+ chunk_size > hdr_size) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ if (hdr->phhdr_length % sizeof(struct remoteproc_segment)) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ return remoteproc_verify_signature(ctx); -+} -+ -+static TEE_Result get_rproc_pta_capabilities(struct remoteproc_context *ctx) -+{ -+ uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_OUTPUT, -+ TEE_PARAM_TYPE_VALUE_OUTPUT, -+ TEE_PARAM_TYPE_NONE); -+ TEE_Param params[TEE_NUM_PARAMS] = { }; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ -+ params[0].value.a = ctx->fw_id; -+ -+ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, -+ PTA_REMOTEPROC_HW_CAPABILITIES, -+ param_types, params, NULL); -+ if (res) -+ return res; -+ -+ ctx->hw_fmt = params[1].value.a; -+ ctx->hw_img_prot = params[2].value.a; -+ -+ return TEE_SUCCESS; -+} -+ -+static TEE_Result remoteproc_verify_firmware(struct remoteproc_context *ctx, -+ uint8_t *fw_orig, -+ uint32_t fw_orig_size) -+{ -+ struct remoteproc_fw_hdr *hdr = NULL; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ -+ res = get_rproc_pta_capabilities(ctx); -+ if (res) -+ return res; -+ -+ /* Secure the firmware image depending on strategy */ -+ if (!(ctx->hw_img_prot & PTA_REMOTEPROC_FW_WITH_HASH_TABLE) || -+ ctx->hw_fmt != PTA_REMOTEPROC_ELF_FMT) { -+ /* -+ * Only hash table for ELF format support implemented -+ * in a first step. -+ */ -+ return TEE_ERROR_NOT_IMPLEMENTED; -+ } -+ -+ res = remoteproc_save_fw_header(ctx, fw_orig, fw_orig_size); -+ if (res) -+ return res; -+ -+ res = remoteproc_verify_header(ctx); -+ if (res) -+ goto free_hdr; -+ -+ /* Store location of the loadable binary in non-secure memory */ -+ hdr = ctx->hdr; -+ ctx->fw_img_size = hdr->img_length; -+ ctx->fw_img = fw_orig + hdr->img_offset; -+ -+ DMSG("Firmware image addr: %p size: %zu", ctx->fw_img, -+ ctx->fw_img_size); -+ -+free_hdr: -+ TEE_Free(ctx->hdr); -+ -+ return res; -+} -+ -+static paddr_t remoteproc_da_to_pa(uint32_t da, int32_t size, void *priv) -+{ -+ struct remoteproc_context *ctx = priv; -+ uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_OUTPUT); -+ TEE_Param params[TEE_NUM_PARAMS] = { }; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ -+ params[0].value.a = ctx->fw_id; -+ params[1].value.a = da; -+ params[2].value.a = size; -+ -+ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, -+ PTA_REMOTEPROC_FIRMWARE_DA_TO_PA, -+ param_types, params, NULL); -+ if (res != TEE_SUCCESS) { -+ EMSG("Failed to translate device address %#"PRIx32, da); -+ return 0; -+ } -+ -+ return (paddr_t)reg_pair_to_64(params[3].value.b, params[3].value.a); -+} -+ -+static TEE_Result remoteproc_parse_rsc_table(struct remoteproc_context *ctx) -+{ -+ uint32_t da = 0; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ -+ res = e32_parser_find_rsc_table(ctx->fw_img, ctx->fw_img_size, -+ &da, &ctx->rsc_size); -+ if (res == TEE_ERROR_NO_DATA) { -+ /* Firmware without resource table */ -+ ctx->rsc_size = 0; -+ ctx->rsc_pa = 0; -+ return TEE_SUCCESS; -+ } -+ if (res) -+ return res; -+ -+ if (da) { -+ DMSG("Resource table device address %#"PRIx32" size %zu", -+ da, ctx->rsc_size); -+ -+ ctx->rsc_pa = remoteproc_da_to_pa(da, ctx->rsc_size, ctx); -+ if (!ctx->rsc_pa) -+ return TEE_ERROR_ACCESS_DENIED; -+ } -+ -+ return TEE_SUCCESS; -+} -+ -+static TEE_Result get_segment_hash(struct remoteproc_context *ctx, uint8_t *src, -+ uint32_t size, uint32_t da, -+ uint32_t mem_size, unsigned char **hash) -+{ -+ struct remoteproc_fw_hdr *hdr = ctx->hdr; -+ struct remoteproc_segment *peh = NULL; -+ unsigned int i = 0; -+ unsigned int nb_entry = hdr->phhdr_length / sizeof(*peh); -+ -+ peh = (void *)((uint8_t *)hdr + hdr->phhdr_offset); -+ -+ for (i = 0; i < nb_entry; peh++, i++) { -+ if (peh->phdr.p_paddr != da) -+ continue; -+ -+ /* -+ * Segment is read from a non secure memory. Crosscheck it using -+ * the hash table to verify that the segment has not been -+ * corrupted. -+ */ -+ if (peh->phdr.p_type != PT_LOAD) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ if (peh->phdr.p_filesz != size || peh->phdr.p_memsz != mem_size) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ if ((Elf32_Off)(src - ctx->fw_img) != peh->phdr.p_offset) -+ return TEE_ERROR_CORRUPT_OBJECT; -+ -+ *hash = peh->hash; -+ -+ return TEE_SUCCESS; -+ } -+ -+ return TEE_ERROR_NO_DATA; -+} -+ -+static TEE_Result remoteproc_load_segment(uint8_t *src, uint32_t size, -+ uint32_t da, uint32_t mem_size, -+ void *priv) -+{ -+ struct remoteproc_context *ctx = priv; -+ uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT); -+ TEE_Param params[TEE_NUM_PARAMS] = { }; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ unsigned char *hash = NULL; -+ -+ /* -+ * Invoke platform remoteproc PTA to load the segment in remote -+ * processor memory which is not mapped in the TA space. -+ */ -+ -+ DMSG("Load segment %#"PRIx32" size %"PRIu32" (%"PRIu32")", da, size, -+ mem_size); -+ -+ res = get_segment_hash(ctx, src, size, da, mem_size, &hash); -+ if (res) -+ return res; -+ -+ params[0].value.a = ctx->fw_id; -+ params[1].memref.buffer = src; -+ params[1].memref.size = size; -+ params[2].value.a = da; -+ params[3].memref.buffer = hash; -+ params[3].memref.size = TEE_SHA256_HASH_SIZE; -+ -+ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, -+ PTA_REMOTEPROC_LOAD_SEGMENT_SHA256, -+ param_types, params, NULL); -+ if (res != TEE_SUCCESS) { -+ EMSG("Fails to load segment, res = 0x%x", res); -+ return res; -+ } -+ -+ /* Fill the rest of the memory with 0 */ -+ if (size < mem_size) { -+ param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_INPUT); -+ params[1].value.a = da + size; -+ params[2].value.a = mem_size - size; -+ params[3].value.a = 0; -+ -+ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, -+ PTA_REMOTEPROC_SET_MEMORY, -+ param_types, params, NULL); -+ if (res != TEE_SUCCESS) -+ EMSG("Fails to clear segment, res = 0x%x", res); -+ } -+ -+ return res; -+} -+ -+static TEE_Result remoteproc_load_elf(struct remoteproc_context *ctx) -+{ -+ TEE_Result res = TEE_ERROR_GENERIC; -+ -+ res = e32_parse_ehdr(ctx->fw_img, ctx->fw_img_size); -+ if (res) { -+ EMSG("Failed to parse firmware, res = %#"PRIx32, res); -+ return res; -+ } -+ -+ return e32_parser_load_elf_image(ctx->fw_img, ctx->fw_img_size, -+ remoteproc_load_segment, ctx); -+} -+ -+static TEE_Result remoteproc_load_fw(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_MEMREF_INPUT, -+ TEE_PARAM_TYPE_NONE, -+ TEE_PARAM_TYPE_NONE); -+ struct remoteproc_context *ctx = NULL; -+ uint32_t fw_id = params[0].value.a; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ ctx = remoteproc_find_firmware(fw_id); -+ if (!ctx) -+ ctx = remoteproc_add_firmware(fw_id); -+ if (!ctx) -+ return TEE_ERROR_OUT_OF_MEMORY; -+ -+ if (ctx->state != REMOTEPROC_OFF) -+ return TEE_ERROR_BAD_STATE; -+ -+ if (!params[1].memref.buffer || !params[1].memref.size) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ DMSG("Got base addr: %p size %zu", params[1].memref.buffer, -+ params[1].memref.size); -+ -+ res = remoteproc_verify_firmware(ctx, params[1].memref.buffer, -+ params[1].memref.size); -+ if (res) { -+ EMSG("Can't Authenticate the firmware, res = %#"PRIx32, res); -+ goto out; -+ } -+ -+ res = remoteproc_load_elf(ctx); -+ if (res) -+ goto out; -+ -+ /* Take opportunity to get the resource table address */ -+ res = remoteproc_parse_rsc_table(ctx); -+ if (res == TEE_SUCCESS) -+ ctx->state = REMOTEPROC_LOADED; -+ -+out: -+ /* Clear reference to firmware image from shared memory */ -+ ctx->fw_img = NULL; -+ ctx->fw_img_size = 0; -+ -+ return res; -+} -+ -+static TEE_Result remoteproc_start_fw(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_NONE, -+ TEE_PARAM_TYPE_NONE, -+ TEE_PARAM_TYPE_NONE); -+ struct remoteproc_context *ctx = NULL; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ ctx = remoteproc_find_firmware(params[0].value.a); -+ if (!ctx) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ switch (ctx->state) { -+ case REMOTEPROC_OFF: -+ res = TEE_ERROR_BAD_STATE; -+ break; -+ case REMOTEPROC_STARTED: -+ res = TEE_SUCCESS; -+ break; -+ case REMOTEPROC_LOADED: -+ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, -+ PTA_REMOTEPROC_FIRMWARE_START, -+ pt, params, NULL); -+ if (res == TEE_SUCCESS) -+ ctx->state = REMOTEPROC_STARTED; -+ break; -+ default: -+ res = TEE_ERROR_BAD_STATE; -+ } -+ -+ return res; -+} -+ -+static TEE_Result remoteproc_stop_fw(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_NONE, -+ TEE_PARAM_TYPE_NONE, -+ TEE_PARAM_TYPE_NONE); -+ struct remoteproc_context *ctx = NULL; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ ctx = remoteproc_find_firmware(params[0].value.a); -+ if (!ctx) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ switch (ctx->state) { -+ case REMOTEPROC_LOADED: -+ res = TEE_ERROR_BAD_STATE; -+ break; -+ case REMOTEPROC_OFF: -+ res = TEE_SUCCESS; -+ break; -+ case REMOTEPROC_STARTED: -+ res = TEE_InvokeTACommand(pta_session, TEE_TIMEOUT_INFINITE, -+ PTA_REMOTEPROC_FIRMWARE_STOP, -+ pt, params, NULL); -+ if (res == TEE_SUCCESS) -+ ctx->state = REMOTEPROC_OFF; -+ break; -+ default: -+ res = TEE_ERROR_BAD_STATE; -+ } -+ -+ return res; -+} -+ -+static TEE_Result remoteproc_get_rsc_table(uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, -+ TEE_PARAM_TYPE_VALUE_OUTPUT, -+ TEE_PARAM_TYPE_VALUE_OUTPUT, -+ TEE_PARAM_TYPE_NONE); -+ struct remoteproc_context *ctx = NULL; -+ -+ if (pt != exp_pt) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ ctx = remoteproc_find_firmware(params[0].value.a); -+ if (!ctx) -+ return TEE_ERROR_BAD_PARAMETERS; -+ -+ if (ctx->state == REMOTEPROC_OFF) -+ return TEE_ERROR_BAD_STATE; -+ -+ reg_pair_from_64((uint64_t)ctx->rsc_pa, -+ ¶ms[1].value.b, ¶ms[1].value.a); -+ reg_pair_from_64((uint64_t)ctx->rsc_size, -+ ¶ms[2].value.b, ¶ms[2].value.a); -+ -+ return TEE_SUCCESS; -+} -+ -+TEE_Result TA_CreateEntryPoint(void) -+{ -+ return TEE_SUCCESS; -+} -+ -+void TA_DestroyEntryPoint(void) -+{ -+} -+ -+TEE_Result TA_OpenSessionEntryPoint(uint32_t pt __unused, -+ TEE_Param params[TEE_NUM_PARAMS] __unused, -+ void **sess __unused) -+{ -+ static const TEE_UUID uuid = PTA_REMOTEPROC_UUID; -+ TEE_Result res = TEE_ERROR_GENERIC; -+ -+ if (!session_refcount) { -+ res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE, 0, NULL, -+ &pta_session, NULL); -+ if (res) -+ return res; -+ } -+ -+ session_refcount++; -+ -+ return TEE_SUCCESS; -+} -+ -+void TA_CloseSessionEntryPoint(void *sess __unused) -+{ -+ session_refcount--; -+ -+ if (!session_refcount) -+ TEE_CloseTASession(pta_session); -+} -+ -+TEE_Result TA_InvokeCommandEntryPoint(void *sess __unused, uint32_t cmd_id, -+ uint32_t pt, -+ TEE_Param params[TEE_NUM_PARAMS]) -+{ -+ switch (cmd_id) { -+ case TA_RPROC_FW_CMD_LOAD_FW: -+ return remoteproc_load_fw(pt, params); -+ case TA_RPROC_FW_CMD_START_FW: -+ return remoteproc_start_fw(pt, params); -+ case TA_RPROC_FW_CMD_STOP_FW: -+ return remoteproc_stop_fw(pt, params); -+ case TA_RPROC_FW_CMD_GET_RSC_TABLE: -+ return remoteproc_get_rsc_table(pt, params); -+ case TA_RPROC_FW_CMD_GET_COREDUMP: -+ return TEE_ERROR_NOT_IMPLEMENTED; -+ default: -+ return TEE_ERROR_BAD_PARAMETERS; -+ } -+} -diff --git a/ta/remoteproc/sub.mk b/ta/remoteproc/sub.mk -new file mode 100644 -index 000000000..caca5901a ---- /dev/null -+++ b/ta/remoteproc/sub.mk -@@ -0,0 +1,3 @@ -+global-incdirs-y += include -+srcs-y += remoteproc_core.c -+srcs-y += elf_parser.c -diff --git a/ta/remoteproc/user_ta.mk b/ta/remoteproc/user_ta.mk -new file mode 100644 -index 000000000..6db23f705 ---- /dev/null -+++ b/ta/remoteproc/user_ta.mk -@@ -0,0 +1 @@ -+user-ta-uuid := 80a4c275-0a47-4905-8285-1486a9771a08 -\ No newline at end of file --- -2.17.1 - diff --git a/recipes-security/optee/optee-os/README.HOW_TO.txt b/recipes-security/optee/optee-os/README.HOW_TO.txt index 7058d68..ea606de 100644 --- a/recipes-security/optee/optee-os/README.HOW_TO.txt +++ b/recipes-security/optee/optee-os/README.HOW_TO.txt @@ -68,71 +68,19 @@ MANDATORY: You must update sources 5. Build optee-os source code: -------------------------------- -To compile optee-os source code - $> make -f $PWD/../Makefile.sdk -or for a specific config : - $ make -f $PWD/../Makefile.sdk CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1 +Since OpenSTLinux has activated FIP by default, so the FIP_artifacts should be specified before launching compilation + - In case of using SOURCES-xxxx.tar.gz of Developer package the FIP_DEPLOYDIR_ROOT should be set as below: + $> export FIP_DEPLOYDIR_ROOT=$PWD/../../FIP_artifacts -Binaries generated are as follow: -##> PWD/../build/tee-*-optee.stm32 +To compile optee-os source code + $> make -f $PWD/../Makefile.sdk all +or for a specific config : + $ make -f $PWD/../Makefile.sdk CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1 all + +The generated FIP images are available in $FIP_DEPLOYDIR_ROOT/fip 6. Update software on board: ---------------------------- -6.1. partitioning of binaries: ------------------------------ -Using the above command, the OP-TEE provides 3 binary files which MUST -be loaded in their respective partition as listed below: -- "tee-header-*-optee.stm32" in "teeh" partition -- "tee-pageable-*-optee.stm32" in "teed" partition -- "tee-pager-*-optee.stm32" in "teex" partition +Please use STM32CubeProgrammer and only tick the ssbl-boot and fip partitions (more informations on the wiki website http://wiki.st.com/stm32mpu) -6.2. Update via SDCARD: ------------------------ -Copy each binary to its dedicated partition, on SDCARD/USB disk -the OP-TEE partitions are the partitions 4/5/6: - - SDCARD: /dev/mmcblkXp4 /dev/mmcblkXp5 /dev/mmcblkXp6 - (where X is the instance number) - - SDCARD via USB reader: /dev/sdX4 /dev/sdX5 /dev/sdX6 - (where X is the instance identifier) -So, for each binary: -$ dd if= of=/dev/ bs=1M conv=fdatasync - -6.3. Update via USB mass storage on U-boot: -------------------------------------------- -* Plug the SDCARD on Board. -* Start the board and stop on U-boot shell: - Hit any key to stop autoboot: 0 - STM32MP> -* plug an USB cable between the PC and the board via USB OTG port. -* On U-Boot shell, call the USB mass storage functionnality: - STM32MP> ums 0 mmc 0 - - ums - ex.: -For SDCARD: ums 0 mmc 0 -For USB disk: ums 0 usb 0 - -* Follow section 6.2 to load the "tee-*-optee.stm32" image files in the target - partitions /dev/sd. - - - -FAQ: Partitions identification - -To find the partition associated to a specific label, connect the -SDCARD to your PC or run on target U-boot 'ums' command -and list /dev/disk/by-partlabel/ content, i.e: - - $ ls -l /dev/disk/by-partlabel/ - total 0 - lrwxrwxrwx 1 root root 15 Jan 23 19:11 bootfs -> ../../mmcblk0p7 - lrwxrwxrwx 1 root root 15 Jan 23 19:11 fsbl1 -> ../../mmcblk0p1 # FSBL (TF-A) - lrwxrwxrwx 1 root root 15 Jan 23 19:11 fsbl2 -> ../../mmcblk0p2 # FSBL backup (TF-A backup – same content as FSBL) - lrwxrwxrwx 1 root root 15 Jan 23 19:11 rootfs -> ../../mmcblk0p9 - lrwxrwxrwx 1 root root 15 Jan 23 19:11 ssbl -> ../../mmcblk0p3 # SSBL (U-Boot) - lrwxrwxrwx 1 root root 15 Jan 23 19:11 teed -> ../../mmcblk0p5 # TEED (OP-TEE tee-pageable) - lrwxrwxrwx 1 root root 15 Jan 23 19:11 teeh -> ../../mmcblk0p4 # TEEH (OP-TEE tee-header) - lrwxrwxrwx 1 root root 15 Jan 23 19:11 teex -> ../../mmcblk0p6 # TEEX (OP-TEE tee-pager) - lrwxrwxrwx 1 root root 16 Jan 23 19:11 userfs -> ../../mmcblk0p10 - lrwxrwxrwx 1 root root 15 Jan 23 19:11 vendorfs -> ../../mmcblk0p8