4766 lines
159 KiB
Diff
4766 lines
159 KiB
Diff
From 755a68e59924e2437b9fb46c8ae1bfe690db1343 Mon Sep 17 00:00:00 2001
|
|
From: Christophe Priouzeau <christophe.priouzeau@st.com>
|
|
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 <drivers/stm32_etzpc.h>
|
|
#include <drivers/stm32_iwdg.h>
|
|
#include <drivers/stm32_uart.h>
|
|
-#include <drivers/stm32mp1_etzpc.h>
|
|
#include <drivers/stm32mp1_pmic.h>
|
|
#include <drivers/stm32mp1_rcc.h>
|
|
#include <drivers/stpmic1.h>
|
|
#include <dt-bindings/clock/stm32mp1-clks.h>
|
|
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
|
#include <io.h>
|
|
#include <kernel/dt.h>
|
|
#include <kernel/generic_boot.h>
|
|
@@ -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 <drivers/stm32mp1_rcc.h>
|
|
#include <dt-bindings/clock/stm32mp1-clks.h>
|
|
#include <inttypes.h>
|
|
-#include <kernel/panic.h>
|
|
#include <io.h>
|
|
#include <mm/core_memprot.h>
|
|
#include <platform_config.h>
|
|
@@ -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 <crypto/crypto.h>
|
|
+#include <drivers/stm32_etzpc.h>
|
|
+#include <drivers/stm32mp1_rcc.h>
|
|
+#include <dt-bindings/clock/stm32mp1-clks.h>
|
|
+#include <dt-bindings/reset/stm32mp1-resets.h>
|
|
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
|
+#include <initcall.h>
|
|
+#include <kernel/pseudo_ta.h>
|
|
+#include <kernel/user_ta.h>
|
|
+#include <mm/core_memprot.h>
|
|
+#include <mm/core_mmu.h>
|
|
+#include <remoteproc_pta.h>
|
|
+#include <rproc_pub_key.h>
|
|
+#include <stm32_util.h>
|
|
+#include <string.h>
|
|
+
|
|
+#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 <types_ext.h>
|
|
+
|
|
+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 <drivers/stm32_etzpc.h>
|
|
#include <drivers/stm32_gpio.h>
|
|
-#include <drivers/stm32mp1_etzpc.h>
|
|
#include <drivers/stm32mp1_rcc.h>
|
|
#include <dt-bindings/clock/stm32mp1-clks.h>
|
|
#include <dt-bindings/reset/stm32mp1-resets.h>
|
|
+#include <dt-bindings/soc/st,stm32-etzpc.h>
|
|
#include <initcall.h>
|
|
#include <io.h>
|
|
#include <keep.h>
|
|
@@ -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 <kernel/pm.h>
|
|
#include <libfdt.h>
|
|
#include <mm/core_memprot.h>
|
|
+#include <stm32_util.h>
|
|
#include <util.h>
|
|
|
|
-/* 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 <util.h>
|
|
+
|
|
+/*
|
|
+ * 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:
|
|
# <name-of-ta>/<uuid>
|
|
# 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('<I', self._bufview_, self._offset,
|
|
+ ENUM_P_TYPE[seg.header.p_type])
|
|
+ self._offset += 4
|
|
+ struct.pack_into('<7I', self._bufview_, self._offset,
|
|
+ seg.header.p_offset, seg.header.p_vaddr,
|
|
+ seg.header.p_paddr, seg.header.p_filesz,
|
|
+ seg.header.p_memsz, seg.header.p_flags,
|
|
+ seg.header.p_align)
|
|
+ self._offset += 28
|
|
+ struct.pack_into('<32B', self._bufview_, self._offset, *seg.hash)
|
|
+ self._offset += 32
|
|
+ dump_buffer(self.buf, name='hash table', indent="\t")
|
|
+ return self.buf
|
|
+
|
|
+
|
|
+class ImageHeader(object):
|
|
+ '''
|
|
+ Image header
|
|
+ '''
|
|
+
|
|
+ magic = 'HELF' # SHDR_MAGIC
|
|
+ version = 1
|
|
+ sign_type = 1 # SHA256
|
|
+ img_type = 1 # ELF
|
|
+
|
|
+ MAGIC_OFFSET = 0
|
|
+ VERSION_OFFSET = 4
|
|
+ LENGTH_OFFSET = 8
|
|
+ SIGNATURE_LEN_OFFSET = 12
|
|
+ SIGNATURE_OFFSET_OFFSET = 16
|
|
+ SIGNATURE_TYPE_OFFSET = 20
|
|
+ HASH_LEN_OFFSET = 24
|
|
+ HASH_OFFSET_OFFSET = 28
|
|
+ HASH_TYPE_OFFSET = 32
|
|
+ PUBLIC_INFO_LEN_OFFSET = 36
|
|
+ PUBLIC_INFO_OFFSET_OFFSET = 40
|
|
+ IMG_LEN_OFFSET = 44
|
|
+ IMG_OFFSET_OFFSET = 48
|
|
+ IMG_TYPE_OFFSET = 52
|
|
+
|
|
+ def __init__(self):
|
|
+ self.size = 56
|
|
+
|
|
+ self.magic = 0x3543A468
|
|
+ self.version = 1
|
|
+ self.length = 0
|
|
+ self.sign_length = 0
|
|
+ self.sign_offset = 0
|
|
+ self.sign_type = 0
|
|
+ self.hash_length = 0
|
|
+ self.hash_offset = 0
|
|
+ self.hash_type = 0
|
|
+ self.key_length = 0
|
|
+ self.key_offset = 0
|
|
+ self.img_length = 0
|
|
+ self.img_offset = 0
|
|
+ self.img_type = 0
|
|
+
|
|
+ self.shdr = struct.pack('<IIIIIIIIIIIIII',
|
|
+ self.magic, self.version, self.length,
|
|
+ self.sign_length, self.sign_offset,
|
|
+ self.sign_type, self.hash_length,
|
|
+ self.hash_offset, self.hash_type,
|
|
+ self.key_length, self.key_offset,
|
|
+ self.img_length, self.img_offset,
|
|
+ self.img_type)
|
|
+
|
|
+ def dump(self):
|
|
+ logging.info("\tMAGIC\t\t= %08X" % (self.magic))
|
|
+ logging.info("\tHEADER_VERSION\t= %08X" % (self.version))
|
|
+ logging.info("\tHEADER_LENGTH\t= %08X" % (self.length))
|
|
+ logging.info("\tSIGN_LENGTH\t= %08X" % (self.sign_length))
|
|
+ logging.info("\tSIGN_OFFSET\t= %08X" % (self.sign_offset))
|
|
+ logging.info("\tSIGN_TYPE\t= %08X" % (self.sign_type))
|
|
+ logging.info("\tHASH_LENGTH\t= %08X" % (self.hash_length))
|
|
+ logging.info("\tHASH_OFFSET\t= %08X" % (self.hash_offset))
|
|
+ logging.info("\tHASH_TYPE\t= %08X" % (self.hash_type))
|
|
+ logging.info("\tPKEY_LENGTH\t= %08X" % (self.key_length))
|
|
+ logging.info("\tPKEY_OFFSET\t= %08X" % (self.key_offset))
|
|
+ logging.info("\tIMAGE_LENGTH\t= %08X" % (self.img_length))
|
|
+ logging.info("\tIMAGE_OFFSET\t= %08X" % (self.img_offset))
|
|
+ logging.info("\tIMAGE_TYPE\t= %08X" % (self.img_type))
|
|
+
|
|
+ def get_packed(self):
|
|
+ return struct.pack('<IIIIIIIIIIIIII',
|
|
+ self.magic, self.version, self.length,
|
|
+ self.sign_length, self.sign_offset, self.sign_type,
|
|
+ self.hash_length, self.hash_offset, self.hash_type,
|
|
+ self.key_length, self.key_offset, self.img_length,
|
|
+ self.img_offset, self.img_type)
|
|
+
|
|
+
|
|
+def get_args(logger):
|
|
+ from argparse import ArgumentParser, RawDescriptionHelpFormatter
|
|
+ import textwrap
|
|
+ command_base = ['sign']
|
|
+ command_choices = command_base
|
|
+
|
|
+ parser = ArgumentParser(
|
|
+ description='Sign a remote processor firmware loadable by OP-TEE.',
|
|
+ usage='\n %(prog)s command [ arguments ]\n\n'
|
|
+
|
|
+ ' command:\n' +
|
|
+ ' sign Generate signed loadable binary \n' +
|
|
+ ' Takes arguments --in, --out --key\n' +
|
|
+ ' %(prog)s --help show available commands and arguments\n\n',
|
|
+ formatter_class=RawDescriptionHelpFormatter,
|
|
+ )
|
|
+ parser.add_argument(
|
|
+ 'command', choices=command_choices, nargs='?',
|
|
+ default='sign',
|
|
+ help='Command, one of [' + ', '.join(command_base) + ']')
|
|
+ parser.add_argument('--key', required=True,
|
|
+ help='Name of signing key file',
|
|
+ dest='keyf')
|
|
+ parser.add_argument('--key_info', required=False,
|
|
+ help='Name file containing extra key information',
|
|
+ dest='key_infof')
|
|
+ parser.add_argument('--key_type', required=False,
|
|
+ help='Type of signing key: should be RSA or ECC',
|
|
+ default='RSA',
|
|
+ dest='key_type')
|
|
+ parser.add_argument(
|
|
+ '--in', required=True, dest='inf',
|
|
+ help='Name of firmware input file')
|
|
+ parser.add_argument(
|
|
+ '--out', required=False, dest='outf',
|
|
+ help='Name of the signed firmware output file,' +
|
|
+ ' default <in base name>.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 <assert.h>
|
|
+#include <elf_parser.h>
|
|
+#include <string.h>
|
|
+#include <trace.h>
|
|
+#include <types_ext.h>
|
|
+#include <util.h>
|
|
+
|
|
+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 <elf_common.h>
|
|
+#include <stdint.h>
|
|
+
|
|
+/*
|
|
+ * 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 <stdint.h>
|
|
+
|
|
+/*
|
|
+ * 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 <elf32.h>
|
|
+#include <stdint.h>
|
|
+#include <tee_api_types.h>
|
|
+
|
|
+/**
|
|
+ * 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 <ta_remoteproc.h>
|
|
+
|
|
+#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 <elf_parser.h>
|
|
+#include <remoteproc_pta.h>
|
|
+#include <string.h>
|
|
+#include <sys/queue.h>
|
|
+#include <ta_remoteproc.h>
|
|
+#include <tee_internal_api.h>
|
|
+#include <tee_internal_api_extensions.h>
|
|
+#include <types_ext.h>
|
|
+#include <utee_defines.h>
|
|
+
|
|
+/* 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
|
|
|