From a622712abe3248f960839fed5c0585553a94285c Mon Sep 17 00:00:00 2001 From: Christophe Priouzeau Date: Tue, 27 Oct 2020 12:17:23 +0100 Subject: [PATCH] OPTEE-OS: OPTEE-OS-STM32MP: Update to 3.9.0-stm32mp-r2 Change-Id: I3a9d6960a76f14d043aee7cca844cb56473987c5 --- .../optee/optee-os-stm32mp-archiver.inc | 4 + .../optee/optee-os-stm32mp_3.9.0.bb | 5 +- .../optee-os/0002-3.9.0-stm32mp-r2.patch | 4765 +++++++++++++++++ .../optee/optee-os/README.HOW_TO.txt | 10 +- 4 files changed, 4773 insertions(+), 11 deletions(-) create mode 100644 recipes-security/optee/optee-os/0002-3.9.0-stm32mp-r2.patch diff --git a/recipes-security/optee/optee-os-stm32mp-archiver.inc b/recipes-security/optee/optee-os-stm32mp-archiver.inc index b2edb8b..44c262c 100644 --- a/recipes-security/optee/optee-os-stm32mp-archiver.inc +++ b/recipes-security/optee/optee-os-stm32mp-archiver.inc @@ -47,5 +47,9 @@ archiver_create_makefile_for_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 + + echo "" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo "clean:" >> ${ARCHIVER_OUTDIR}/Makefile.sdk + echo " rm -rf \$(LOCAL_PATH)/../build" >> ${ARCHIVER_OUTDIR}/Makefile.sdk } do_ar_original[prefuncs] += "archiver_create_makefile_for_sdk" diff --git a/recipes-security/optee/optee-os-stm32mp_3.9.0.bb b/recipes-security/optee/optee-os-stm32mp_3.9.0.bb index 52e80d3..0e945a8 100644 --- a/recipes-security/optee/optee-os-stm32mp_3.9.0.bb +++ b/recipes-security/optee/optee-os-stm32mp_3.9.0.bb @@ -7,10 +7,11 @@ SRCREV = "af141c61fe7a2430f3b4bb89661d8414117013b3" SRC_URI += " \ file://0001-3.9.0-stm32mp-r1.patch \ + file://0002-3.9.0-stm32mp-r2.patch \ " OPTEE_VERSION = "3.9.0" -PV = "${OPTEE_VERSION}.r1" +PV = "${OPTEE_VERSION}.r2" S = "${WORKDIR}/git" @@ -39,7 +40,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 = "dbfbd96e5850747842b008b54e7d2be171c6d83f" +SRCREV_class-devupstream = "6a3dd87a133bee8a18409969380dbb1fc289f803" # --------------------------------- # Configure default preference to manage dynamic selection between tarball and github 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 new file mode 100644 index 0000000..bca1d8e --- /dev/null +++ b/recipes-security/optee/optee-os/0002-3.9.0-stm32mp-r2.patch @@ -0,0 +1,4765 @@ +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 69e31d3..7058d68 100644 --- a/recipes-security/optee/optee-os/README.HOW_TO.txt +++ b/recipes-security/optee/optee-os/README.HOW_TO.txt @@ -10,14 +10,6 @@ Compilation of Optee-os (Trusted Execution Environment): ----------------- OpenSTLinux SDK must be installed. -For optee-os build you need to install: -- Wand python and/or python crypto package - Ubuntu: sudo apt-get install python-wand python-crypto python-pycryptopp - Fedora: sudo yum install python-wand python-crypto -- git: - Ubuntu: sudo apt-get install git-core gitk - Fedora: sudo yum install git - If you have never configured you git configuration: $ git config --global user.name "your_name" $ git config --global user.email "your_email@example.com" @@ -143,4 +135,4 @@ and list /dev/disk/by-partlabel/ content, i.e: 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 \ No newline at end of file + lrwxrwxrwx 1 root root 15 Jan 23 19:11 vendorfs -> ../../mmcblk0p8