From 91c973496683de7d725e4c3743ea273b4910eea4 Mon Sep 17 00:00:00 2001 From: Lionel VITTE Date: Mon, 3 Jul 2023 10:50:53 +0200 Subject: [PATCH] OPTEE-OS-STM32MP: 3.16.0-stm32mp-r2.1 Change-Id: Ibb1ea4150d8102d80865f1fef87ecc0309b440d1 Signed-off-by: Lionel VITTE --- .../optee/optee-os-stm32mp_3.16.0.bb | 5 +- .../optee-os/0003-3.16.0-stm32mp-r2.1.patch | 848 ++++++++++++++++++ 2 files changed, 851 insertions(+), 2 deletions(-) create mode 100644 recipes-security/optee/optee-os/0003-3.16.0-stm32mp-r2.1.patch diff --git a/recipes-security/optee/optee-os-stm32mp_3.16.0.bb b/recipes-security/optee/optee-os-stm32mp_3.16.0.bb index f923e5d..b1f6862 100644 --- a/recipes-security/optee/optee-os-stm32mp_3.16.0.bb +++ b/recipes-security/optee/optee-os-stm32mp_3.16.0.bb @@ -9,13 +9,14 @@ SRC_URI += " \ file://fonts.tar.gz;subdir=git;name=fonts \ file://0001-3.16.0-stm32mp-r1.patch \ file://0002-3.16.0-stm32mp-r2.patch \ + file://0003-3.16.0-stm32mp-r2.1.patch \ " SRC_URI[fonts.sha256sum] = "4941e8bb6d8ac377838e27b214bf43008c496a24a8f897e0b06433988cbd53b2" OPTEE_VERSION = "3.16.0" OPTEE_SUBVERSION = "stm32mp" -OPTEE_RELEASE = "r2" +OPTEE_RELEASE = "r2.1" PV = "${OPTEE_VERSION}-${OPTEE_SUBVERSION}-${OPTEE_RELEASE}" @@ -50,7 +51,7 @@ include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'optee-os-stm3 BBCLASSEXTEND = "devupstream:target" SRC_URI:class-devupstream = "git://github.com/STMicroelectronics/optee_os.git;protocol=https;branch=${ARCHIVER_ST_BRANCH}" -SRCREV:class-devupstream = "0f631da995da50fe7e19e0b7291032d77f7048bc" +SRCREV:class-devupstream = "b8750c4600166f0019a8c1cf35362b1889840ec3" # --------------------------------- # Configure default preference to manage dynamic selection between tarball and github diff --git a/recipes-security/optee/optee-os/0003-3.16.0-stm32mp-r2.1.patch b/recipes-security/optee/optee-os/0003-3.16.0-stm32mp-r2.1.patch new file mode 100644 index 0000000..5dd33e5 --- /dev/null +++ b/recipes-security/optee/optee-os/0003-3.16.0-stm32mp-r2.1.patch @@ -0,0 +1,848 @@ +From 40bea7e6dd305b8fec278fa56bc38eed127ce946 Mon Sep 17 00:00:00 2001 +From: Lionel VITTE +Date: Mon, 3 Jul 2023 10:30:06 +0200 +Subject: [PATCH] 3.16.0-stm32mp-r2.1-rc1 + +--- + core/arch/arm/dts/stm32mp135f-dk.dts | 4 +- + core/arch/arm/plat-stm32mp1/conf.mk | 4 +- + .../arm/plat-stm32mp1/drivers/stm32mp1_pmic.c | 151 +++++++++++++----- + .../plat-stm32mp1/drivers/stm32mp1_pwr_irq.c | 78 ++++++--- + core/arch/arm/plat-stm32mp1/main.c | 4 +- + core/arch/arm/plat-stm32mp1/pm/context.c | 12 +- + core/arch/arm/plat-stm32mp1/pm/low_power.c | 15 +- + core/drivers/crypto/stm32/stm32_saes.c | 7 + + core/drivers/regulator/core.c | 5 + + core/drivers/stm32_iwdg.c | 18 ++- + core/drivers/stm32_rng.c | 12 +- + core/drivers/stm32_uart.c | 4 +- + core/include/drivers/stpmic1.h | 35 ---- + core/include/kernel/huk_subkey.h | 5 + + core/kernel/huk_subkey.c | 16 +- + .../devicetree/bindings/mfd/st,stpmic1.yaml | 51 ++++++ + 16 files changed, 293 insertions(+), 128 deletions(-) + +diff --git a/core/arch/arm/dts/stm32mp135f-dk.dts b/core/arch/arm/dts/stm32mp135f-dk.dts +index 4400b2b13..710446101 100644 +--- a/core/arch/arm/dts/stm32mp135f-dk.dts ++++ b/core/arch/arm/dts/stm32mp135f-dk.dts +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -192,7 +193,8 @@ + reg = <0x33>; + status = "okay"; + st,wakeup-pin-number = <1>; +- st,notif-it-id = <0>; ++ st,pmic-it-id = ; ++ st,notif-it-id = <0 2>; + + regulators { + compatible = "st,stpmic1-regulators"; +diff --git a/core/arch/arm/plat-stm32mp1/conf.mk b/core/arch/arm/plat-stm32mp1/conf.mk +index 6c959d4bc..05229e61e 100644 +--- a/core/arch/arm/plat-stm32mp1/conf.mk ++++ b/core/arch/arm/plat-stm32mp1/conf.mk +@@ -310,10 +310,8 @@ CFG_ENABLE_EMBEDDED_TESTS ?= y + CFG_WITH_STATS ?= y + CFG_WERROR ?= y + +-# Enable to allow debug +-ifeq ($(CFG_TEE_CORE_DEBUG),y) ++# Enable OTP update with BSEC driver + CFG_STM32_BSEC_WRITE ?= y +-endif + + # Default disable some support for pager memory size constraint + ifeq ($(CFG_WITH_PAGER),y) +diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c +index 4eda619cf..653ac4f7d 100644 +--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c ++++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -26,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -42,6 +44,17 @@ + static struct i2c_handle_s *i2c_pmic_handle; + static uint32_t pmic_i2c_addr; + ++struct pmic_it_handle_s { ++ uint8_t pmic_reg; ++ uint8_t pmic_bit; ++ uint8_t notif_id; ++ ++ SLIST_ENTRY(pmic_it_handle_s) link; ++}; ++ ++static SLIST_HEAD(pmic_it_handle_head, pmic_it_handle_s) pmic_it_handle_list = ++ SLIST_HEAD_INITIALIZER(pmic_it_handle_list); ++ + /* CPU voltage supplier if found */ + static char cpu_supply_name[PMIC_REGU_SUPPLY_NAME_LEN]; + +@@ -508,11 +521,10 @@ static void register_non_secure_pmic(void) + } + } + +-static enum itr_return stpmic1_irq_handler(struct itr_handler *handler) ++static enum itr_return stpmic1_irq_handler(struct itr_handler *handler __unused) + { + uint8_t read_val = 0U; + unsigned int i = 0U; +- uint32_t *it_id = handler->data; + + FMSG("Stpmic1 irq handler"); + +@@ -523,16 +535,22 @@ static enum itr_return stpmic1_irq_handler(struct itr_handler *handler) + panic(); + + if (read_val) { ++ struct pmic_it_handle_s *prv = NULL; ++ + FMSG("Stpmic1 irq pending %u: %#"PRIx8, i, read_val); + + if (stpmic1_register_write(ITCLEARLATCH1_REG + i, + read_val)) + panic(); + +- /* forward falling interrupt to non-secure */ +- if (i == 0 && (read_val & BIT(IT_PONKEY_F))) +- if (it_id) +- notif_send_it(*it_id); ++ SLIST_FOREACH(prv, &pmic_it_handle_list, link) ++ if ((prv->pmic_reg == ITCLEARMASK1_REG + i) && ++ (read_val & BIT(prv->pmic_bit))) { ++ FMSG("STPMIC1 send notif %u", ++ prv->notif_id); ++ ++ notif_send_it(prv->notif_id); ++ } + } + } + +@@ -587,57 +605,104 @@ static void initialize_pmic(const void *fdt, int pmic_node) + stm32mp_put_pmic(); + } + +-static TEE_Result stm32_pmic_probe(const void *fdt, int node, +- const void *compat_data __unused) ++static TEE_Result stm32_pmic_init_it(const void *fdt, int node) + { +- TEE_Result res = TEE_SUCCESS; +- const fdt32_t *cuint = NULL; ++ TEE_Result res = TEE_ERROR_GENERIC; ++ const uint32_t *notif_ids = NULL; ++ int nb_notif = 0; ++ size_t pwr_it = 0; + struct itr_handler *hdl = NULL; +- size_t it = 0; +- uint32_t *it_id = NULL; ++ const fdt32_t *cuint = NULL; + +- res = i2c_dt_get_by_subnode(fdt, node, &i2c_pmic_handle); +- if (res) +- return res; ++ cuint = fdt_getprop(fdt, node, "st,wakeup-pin-number", NULL); ++ if (!cuint) { ++ IMSG("Missing wake-up pin description"); ++ return TEE_SUCCESS; ++ } + +- initialize_pmic(fdt, node); ++ pwr_it = fdt32_to_cpu(*cuint) - 1U; + +- if (IS_ENABLED(CFG_STM32MP13)) { +- cuint = fdt_getprop(fdt, node, "st,wakeup-pin-number", NULL); +- if (!cuint) { +- IMSG("Missing wake-up pin description"); +- return TEE_SUCCESS; +- } ++ notif_ids = fdt_getprop(fdt, node, "st,notif-it-id", &nb_notif); ++ if (!notif_ids) ++ return TEE_ERROR_ITEM_NOT_FOUND; + +- it = fdt32_to_cpu(*cuint) - 1U; ++ if (nb_notif > 0) { ++ struct pmic_it_handle_s *prv = NULL; ++ unsigned int i = 0; ++ const uint32_t *pmic_its = NULL; ++ int nb_it = 0; + +- cuint = fdt_getprop(fdt, node, "st,notif-it-id", NULL); +- if (cuint) { +- it_id = calloc(1, sizeof(it_id)); +- if (!it_id) +- return TEE_ERROR_OUT_OF_MEMORY; ++ pmic_its = fdt_getprop(fdt, node, "st,pmic-it-id", &nb_it); ++ if (!pmic_its) ++ return TEE_ERROR_ITEM_NOT_FOUND; + +- *it_id = fdt32_to_cpu(*cuint); +- } ++ if (nb_it != nb_notif) ++ panic("st,notif-it-id incorrect description"); + +- res = stm32mp1_pwr_itr_alloc_add(it, stpmic1_irq_handler, +- PWR_WKUP_FLAG_FALLING | +- PWR_WKUP_FLAG_THREADED, +- it_id, &hdl); +- if (res) +- panic("pmic: Couldn't allocate itr"); ++ for (i = 0; i < (nb_notif / sizeof(uint32_t)); i++) { ++ uint8_t val = 0; ++ uint8_t pmic_it = 0; + +- stm32mp1_pwr_itr_enable(hdl->it); ++ prv = calloc(1, sizeof(*prv)); ++ if (!prv) ++ panic("pmic: Couldn't allocate pmic it"); + +- /* Enable ponkey irq */ +- stm32mp_get_pmic(); +- if (stpmic1_register_write(ITCLEARMASK1_REG, +- BIT(IT_PONKEY_F) | BIT(IT_PONKEY_R))) +- panic(); ++ pmic_it = fdt32_to_cpu(pmic_its[i]); ++ ++ assert(pmic_it <= IT_SWIN_R); ++ ++ prv->pmic_reg = ITCLEARMASK1_REG + pmic_it / U(8); ++ prv->pmic_bit = pmic_it % U(8); ++ prv->notif_id = fdt32_to_cpu(notif_ids[i]); ++ ++ SLIST_INSERT_HEAD(&pmic_it_handle_list, prv, link); ++ ++ stm32mp_get_pmic(); + +- stm32mp_put_pmic(); ++ /* Enable requested interrupt */ ++ if (stpmic1_register_read(prv->pmic_reg, &val)) ++ panic(); ++ ++ val |= BIT(prv->pmic_bit); ++ ++ if (stpmic1_register_write(prv->pmic_reg, val)) ++ panic(); ++ ++ stm32mp_put_pmic(); ++ } ++ ++ SLIST_FOREACH(prv, &pmic_it_handle_list, link) { ++ FMSG("STPMIC1 forwards irq reg:%u bit:%u as notif:%u", ++ prv->pmic_reg, prv->pmic_bit, prv->notif_id); ++ } + } + ++ res = stm32mp1_pwr_itr_alloc_add(pwr_it, stpmic1_irq_handler, ++ PWR_WKUP_FLAG_FALLING | ++ PWR_WKUP_FLAG_THREADED, ++ NULL, &hdl); ++ if (res) ++ panic("pmic: Couldn't allocate itr"); ++ ++ stm32mp1_pwr_itr_enable(hdl->it); ++ ++ return res; ++} ++ ++static TEE_Result stm32_pmic_probe(const void *fdt, int node, ++ const void *compat_data __unused) ++{ ++ TEE_Result res = TEE_SUCCESS; ++ ++ res = i2c_dt_get_by_subnode(fdt, node, &i2c_pmic_handle); ++ if (res) ++ return res; ++ ++ initialize_pmic(fdt, node); ++ ++ if (IS_ENABLED(CFG_STM32MP13)) ++ res = stm32_pmic_init_it(fdt, node); ++ + return res; + } + +diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr_irq.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr_irq.c +index 0913e9151..ca2761a81 100644 +--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr_irq.c ++++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr_irq.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -47,6 +48,7 @@ struct stm32_pwr_data { + struct itr_handler *gic_hdl; + bool threaded[PWR_NB_WAKEUPPINS]; + bool pending[PWR_NB_WAKEUPPINS]; ++ unsigned int spinlock; + }; + + static struct stm32_pwr_data *pwr_data; +@@ -148,6 +150,7 @@ static TEE_Result + stm32_pwr_irq_set_pull_config(size_t it, enum wkup_pull_setting config) + { + struct stm32_pwr_data *priv = pwr_data; ++ uint32_t exceptions = 0; + + VERBOSE_PWR("irq:%zu pull config:0%#"PRIx32, it, config); + +@@ -156,29 +159,59 @@ stm32_pwr_irq_set_pull_config(size_t it, enum wkup_pull_setting config) + return TEE_ERROR_GENERIC; + } + ++ exceptions = cpu_spin_lock_xsave(&priv->spinlock); ++ + io_mask32(priv->base + WKUPCR, + (config & WKUP_PULL_MASK) << (WKUP_PULL_SHIFT + it * 2), + (WKUP_PULL_MASK) << (WKUP_PULL_SHIFT + it * 2)); + ++ cpu_spin_unlock_xrestore(&priv->spinlock, exceptions); ++ + return TEE_SUCCESS; + } + +-static TEE_Result +-stm32_pwr_irq_set_trig(size_t it, enum pwr_wkup_flags trig) ++static void stm32mp1_pwr_itr_enable_nolock(size_t it) ++{ ++ struct stm32_pwr_data *priv = pwr_data; ++ ++ VERBOSE_PWR("Pwr irq enable"); ++ ++ if (IS_ENABLED(CFG_STM32_EXTI)) ++ stm32_exti_enable_wake(PWR_EXTI_WKUP1 + it); ++ ++ io_setbits32(priv->base + MPUWKUPENR, BIT(it)); ++} ++ ++static void stm32mp1_pwr_itr_disable_nolock(size_t it) ++{ ++ struct stm32_pwr_data *priv = pwr_data; ++ ++ VERBOSE_PWR("Pwr irq disable"); ++ ++ io_clrbits32(priv->base + MPUWKUPENR, BIT(it)); ++ ++ if (IS_ENABLED(CFG_STM32_EXTI)) ++ stm32_exti_disable_wake(PWR_EXTI_WKUP1 + it); ++} ++ ++static TEE_Result stm32_pwr_irq_set_trig(size_t it, enum pwr_wkup_flags trig) + { + struct stm32_pwr_data *priv = pwr_data; ++ uint32_t exceptions = 0; + uint32_t wkupcr = 0; + int en = 0; + + VERBOSE_PWR("irq:%zu trig:%#"PRIx32, it, trig); + ++ exceptions = cpu_spin_lock_xsave(&priv->spinlock); ++ + en = io_read32(priv->base + MPUWKUPENR) & BIT(it); + /* + * Reference manual request to disable the wakeup pin while +- * changing the edge detection setting ++ * changing the edge detection setting. + */ + if (en) +- stm32mp1_pwr_itr_disable(it); ++ stm32mp1_pwr_itr_disable_nolock(it); + + wkupcr = io_read32(priv->base + WKUPCR); + switch (trig) { +@@ -195,7 +228,9 @@ stm32_pwr_irq_set_trig(size_t it, enum pwr_wkup_flags trig) + io_write32(priv->base + WKUPCR, wkupcr); + + if (en) +- stm32mp1_pwr_itr_enable(it); ++ stm32mp1_pwr_itr_enable_nolock(it); ++ ++ cpu_spin_unlock_xrestore(&priv->spinlock, exceptions); + + return TEE_SUCCESS; + } +@@ -203,25 +238,21 @@ stm32_pwr_irq_set_trig(size_t it, enum pwr_wkup_flags trig) + void stm32mp1_pwr_itr_enable(size_t it) + { + struct stm32_pwr_data *priv = pwr_data; ++ uint32_t exceptions = 0; + +- VERBOSE_PWR("Pwr irq enable"); +- +- if (IS_ENABLED(CFG_STM32_EXTI)) +- stm32_exti_enable_wake(PWR_EXTI_WKUP1 + it); +- +- io_setbits32(priv->base + MPUWKUPENR, BIT(it)); ++ exceptions = cpu_spin_lock_xsave(&priv->spinlock); ++ stm32mp1_pwr_itr_enable_nolock(it); ++ cpu_spin_unlock_xrestore(&priv->spinlock, exceptions); + } + + void stm32mp1_pwr_itr_disable(size_t it) + { + struct stm32_pwr_data *priv = pwr_data; ++ uint32_t exceptions = 0; + +- VERBOSE_PWR("Pwr irq disable"); +- +- io_clrbits32(priv->base + MPUWKUPENR, BIT(it)); +- +- if (IS_ENABLED(CFG_STM32_EXTI)) +- stm32_exti_disable_wake(PWR_EXTI_WKUP1 + it); ++ exceptions = cpu_spin_lock_xsave(&priv->spinlock); ++ stm32mp1_pwr_itr_disable_nolock(it); ++ cpu_spin_unlock_xrestore(&priv->spinlock, exceptions); + } + + static TEE_Result stm32mp1_pwr_irt_add(struct itr_handler *hdl) +@@ -231,7 +262,9 @@ static TEE_Result stm32mp1_pwr_irt_add(struct itr_handler *hdl) + struct stm32_pinctrl_list pinctrl_list = { }; + struct stm32_pinctrl pin = { }; + struct stm32_pinctrl *pinctrl = NULL; ++ uint32_t exceptions = 0; + unsigned int i = 0; ++ bool itr_free = false; + + VERBOSE_PWR("Pwr IRQ add"); + +@@ -241,10 +274,15 @@ static TEE_Result stm32mp1_pwr_irt_add(struct itr_handler *hdl) + } + + assert(it >= PWR_WKUP_PIN1 && it < PWR_NB_WAKEUPPINS); +- /* check IRQ not already in use */ +- assert(!priv->hdl[it]); + +- priv->hdl[it] = hdl; ++ /* Use PWR lock to ensure consistent interrupt registering */ ++ exceptions = cpu_spin_lock_xsave(&priv->spinlock); ++ itr_free = !priv->hdl[it]; ++ if (itr_free) ++ priv->hdl[it] = hdl; ++ cpu_spin_unlock_xrestore(&priv->spinlock, exceptions); ++ if (!itr_free) ++ return TEE_ERROR_GENERIC; + + if (hdl->flags & PWR_WKUP_FLAG_THREADED) + priv->threaded[it] = true; +diff --git a/core/arch/arm/plat-stm32mp1/main.c b/core/arch/arm/plat-stm32mp1/main.c +index 2e9f7a699..3ae327ee5 100644 +--- a/core/arch/arm/plat-stm32mp1/main.c ++++ b/core/arch/arm/plat-stm32mp1/main.c +@@ -165,9 +165,9 @@ static TEE_Result init_console_from_dt(void) + /* Replace early console with the new one */ + console_flush(); + console_data = *pd; +- free(pd); + register_serial_console(&console_data.chip); + IMSG("DTB enables console (%ssecure)", pd->secure ? "" : "non-"); ++ free(pd); + + return TEE_SUCCESS; + } +@@ -727,7 +727,7 @@ static TEE_Result stm32_configure_tamp(void) + return TEE_SUCCESS; + } + +-driver_init_late(stm32_configure_tamp); ++service_init(stm32_configure_tamp); + #endif + + #ifdef CFG_STM32_HSE_MONITORING +diff --git a/core/arch/arm/plat-stm32mp1/pm/context.c b/core/arch/arm/plat-stm32mp1/pm/context.c +index c9d26ee37..7e08bc0a2 100644 +--- a/core/arch/arm/plat-stm32mp1/pm/context.c ++++ b/core/arch/arm/plat-stm32mp1/pm/context.c +@@ -213,7 +213,7 @@ static void __maybe_unused print_ccm_decryption_duration(void) + ((unsigned long long)ctx->stgen_cnt * 1000) / + io_read32(stgen + CNTFID_OFFSET)); + +- clk_enable(pm_clocks.bkpsram); ++ clk_disable(pm_clocks.bkpsram); + } + #else + static void __maybe_unused print_ccm_decryption_duration(void) +@@ -582,15 +582,17 @@ TEE_Result stm32mp_pm_call_bl2_lp_entry(unsigned int soc_mode) + + dcache_op_all(DCACHE_OP_CLEAN_INV); + ++ /* Disable Cache & MMU before calling low_power section */ ++ write_sctlr(read_sctlr() & ~(SCTLR_C | SCTLR_M)); ++ + dsb(); ++ isb(); + +- /* Disable MMU before calling low_power section */ +- write_sctlr(read_sctlr() & ~SCTLR_M); + + (*stm32_pwr_down_wfi)(true, soc_mode); + +- /* Enable MMU */ +- write_sctlr(read_sctlr() | SCTLR_M); ++ /* Enable Cache & MMU */ ++ write_sctlr(read_sctlr() | SCTLR_C | SCTLR_M); + + clk_disable(pm_clocks.bkpsram); + +diff --git a/core/arch/arm/plat-stm32mp1/pm/low_power.c b/core/arch/arm/plat-stm32mp1/pm/low_power.c +index cbc5fa151..653c3dfb7 100644 +--- a/core/arch/arm/plat-stm32mp1/pm/low_power.c ++++ b/core/arch/arm/plat-stm32mp1/pm/low_power.c +@@ -292,13 +292,6 @@ void stm32_enter_cstop(uint32_t mode) + io_clrsetbits32(pwr_base + PWR_CR3_OFF, PWR_CR3_POPL_MASK, + 20U << PWR_CR3_POPL_SHIFT); + +- /* Keep backup RAM content in standby */ +- io_setbits32(pwr_base + PWR_CR2_OFF, PWR_CR2_BREN); +- +- // TODO add a timeout? +- while (!(io_read32(pwr_base + PWR_CR2_OFF) & PWR_CR2_BRRDY)) +- ; +- + #ifndef CFG_STM32MP13 + if (stm32mp1_is_retram_during_standby()) { + /* Keep retention in standby */ +@@ -344,9 +337,6 @@ void stm32_exit_cstop(void) + dsb(); + isb(); + +- /* Disable retention and backup RAM content after stop */ +- io_clrbits32(stm32_pwr_base() + PWR_CR2_OFF, PWR_CR2_BREN); +- + #ifndef CFG_STM32MP13 + /* Disable retention and backup RAM content after stop */ + io_clrbits32(stm32_pwr_base() + PWR_CR2_OFF, PWR_CR2_RREN); +@@ -525,6 +515,11 @@ static TEE_Result init_low_power(void) + RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1); + #endif + ++ /* Keep backup RAM content in standby */ ++ io_setbits32(pwr_base + PWR_CR2_OFF, PWR_CR2_BREN); ++ while (!(io_read32(pwr_base + PWR_CR2_OFF) & PWR_CR2_BRRDY)) ++ ; ++ + return TEE_SUCCESS; + } + driver_init_late(init_low_power); +diff --git a/core/drivers/crypto/stm32/stm32_saes.c b/core/drivers/crypto/stm32/stm32_saes.c +index 9453d0d52..d8495a16e 100644 +--- a/core/drivers/crypto/stm32/stm32_saes.c ++++ b/core/drivers/crypto/stm32/stm32_saes.c +@@ -1337,6 +1337,13 @@ TEE_Result huk_subkey_derive(enum huk_subkey_usage usage, + struct stm32_saes_context ctx = { }; + uint8_t separator = 0; + ++ // Check if driver is probed ++ if (saes_pdata.base.pa == 0) { ++ DMSG("Use __huk_subkey_derive instead of SAES IP features"); ++ return __huk_subkey_derive(usage, const_data, const_data_len, ++ subkey, subkey_len); ++ } ++ + input = malloc(const_data_len + sizeof(separator) + sizeof(usage) + + sizeof(subkey_bitlen) + AES_BLOCK_SIZE); + if (!input) +diff --git a/core/drivers/regulator/core.c b/core/drivers/regulator/core.c +index d4dc3751d..7ef58b268 100644 +--- a/core/drivers/regulator/core.c ++++ b/core/drivers/regulator/core.c +@@ -575,6 +575,11 @@ static TEE_Result parse_properties(const void *fdt, struct rdev *rdev, int node) + } + + rdev->reg_name = fdt_getprop(fdt, node, "regulator-name", NULL); ++ if (rdev->reg_name) { ++ rdev->reg_name = strdup(rdev->reg_name); ++ if (!rdev->reg_name) ++ panic(); ++ } + + return TEE_SUCCESS; + } +diff --git a/core/drivers/stm32_iwdg.c b/core/drivers/stm32_iwdg.c +index 49e4fad50..fba4abe7e 100644 +--- a/core/drivers/stm32_iwdg.c ++++ b/core/drivers/stm32_iwdg.c +@@ -35,6 +35,7 @@ + #define IWDG_EWCR_OFFSET U(0x14) + + /* Registers values */ ++#define IWDG_KR_WPROT_KEY U(0x0000) + #define IWDG_KR_ACCESS_KEY U(0x5555) + #define IWDG_KR_RELOAD_KEY U(0xAAAA) + #define IWDG_KR_START_KEY U(0xCCCC) +@@ -45,6 +46,7 @@ + #define IWDG_RLR_RL_MASK GENMASK_32(11, 0) + + #define IWDG_SR_EWU BIT(3) ++#define IWDG_SR_EWIF BIT(14) + + #define IWDG_EWCR_EWIE BIT(15) + #define IWDG_EWCR_EWIC BIT(14) +@@ -88,10 +90,22 @@ static enum itr_return stm32_iwdg_it_handler(struct itr_handler *handler) + + stm32mp_dump_core_registers(true); + +- iwdg_refresh(iwdg); +- + clk_enable(iwdg->pdata.clock); + ++ /* Check for spurious interrupt */ ++ if (!(io_read32(iwdg_base + IWDG_SR_OFFSET) & IWDG_SR_EWIF)) { ++ clk_disable(iwdg->pdata.clock); ++ return ITRR_NONE; ++ } ++ ++ /* ++ * Writing IWDG_EWCR_EWIT triggers a watchdog refresh. ++ * To prevent the watchdog refresh, write-protect all the registers; ++ * this makes read-only all IWDG_EWCR fields except IWDG_EWCR_EWIC. ++ */ ++ io_write32(iwdg_base + IWDG_KR_OFFSET, IWDG_KR_WPROT_KEY); ++ ++ /* Disable early interrupt */ + io_setbits32(iwdg_base + IWDG_EWCR_OFFSET, IWDG_EWCR_EWIC); + + clk_disable(iwdg->pdata.clock); +diff --git a/core/drivers/stm32_rng.c b/core/drivers/stm32_rng.c +index ef5862308..363aeee00 100644 +--- a/core/drivers/stm32_rng.c ++++ b/core/drivers/stm32_rng.c +@@ -140,9 +140,19 @@ static TEE_Result stm32_rng_read_available(struct stm32_rng_device *dev, + + /* RNG is ready: read up to 4 32bit words */ + while (size) { +- uint32_t data32 = io_read32(base + RNG_DR); ++ uint32_t data32 = 0; + size_t sz = MIN(size, sizeof(uint32_t)); + ++ if (!(io_read32(base + RNG_SR) & RNG_SR_DRDY)) ++ return TEE_ERROR_NO_DATA; ++ ++ data32 = io_read32(base + RNG_DR); ++ /* Late seed error case: DR being 0 is an error status */ ++ if (!data32) { ++ conceal_seed_error(dev); ++ return TEE_ERROR_NO_DATA; ++ } ++ + memcpy(buf, &data32, sz); + buf += sz; + size -= sz; +diff --git a/core/drivers/stm32_uart.c b/core/drivers/stm32_uart.c +index 5105b14bc..1ffc99117 100644 +--- a/core/drivers/stm32_uart.c ++++ b/core/drivers/stm32_uart.c +@@ -38,12 +38,12 @@ + * Bit 5 RXNE: Read data register not empty/RXFIFO not empty + * Bit 6 TC: Transmission complete + * Bit 7 TXE/TXFNF: Transmit data register empty/TXFIFO not full +- * Bit 27 TXFE: TXFIFO threshold reached ++ * Bit 23 TXFE: TXFIFO empty + */ + #define USART_ISR_RXNE_RXFNE BIT(5) + #define USART_ISR_TC BIT(6) + #define USART_ISR_TXE_TXFNF BIT(7) +-#define USART_ISR_TXFE BIT(27) ++#define USART_ISR_TXFE BIT(23) + + static vaddr_t loc_chip_to_base(struct serial_chip *chip) + { +diff --git a/core/include/drivers/stpmic1.h b/core/include/drivers/stpmic1.h +index 5fe48232f..b293c846f 100644 +--- a/core/include/drivers/stpmic1.h ++++ b/core/include/drivers/stpmic1.h +@@ -171,41 +171,6 @@ + #define USBSW_OTG_SWITCH_ENABLED_POS 1 + #define BOOST_ENABLED_POS 0 + +-/* IRQ definitions */ +-#define IT_PONKEY_F 0 +-#define IT_PONKEY_R 1 +-#define IT_WAKEUP_F 2 +-#define IT_WAKEUP_R 3 +-#define IT_VBUS_OTG_F 4 +-#define IT_VBUS_OTG_R 5 +-#define IT_SWOUT_F 6 +-#define IT_SWOUT_R 7 +- +-#define IT_CURLIM_BUCK1 0 +-#define IT_CURLIM_BUCK2 1 +-#define IT_CURLIM_BUCK3 2 +-#define IT_CURLIM_BUCK4 3 +-#define IT_OCP_OTG 4 +-#define IT_OCP_SWOUT 5 +-#define IT_OCP_BOOST 6 +-#define IT_OVP_BOOST 7 +- +-#define IT_CURLIM_LDO1 0 +-#define IT_CURLIM_LDO2 1 +-#define IT_CURLIM_LDO3 2 +-#define IT_CURLIM_LDO4 3 +-#define IT_CURLIM_LDO5 4 +-#define IT_CURLIM_LDO6 5 +-#define IT_SHORT_SWOTG 6 +-#define IT_SHORT_SWOUT 7 +- +-#define IT_TWARN_F 0 +-#define IT_TWARN_R 1 +-#define IT_VINLOW_F 2 +-#define IT_VINLOW_R 3 +-#define IT_SWIN_F 4 +-#define IT_SWIN_R 5 +- + /* + * Bind SPMIC1 device driver with a specific I2C bus instance + * @i2c_handle: target I2C instance to use +diff --git a/core/include/kernel/huk_subkey.h b/core/include/kernel/huk_subkey.h +index 59bcf2773..a6a18e953 100644 +--- a/core/include/kernel/huk_subkey.h ++++ b/core/include/kernel/huk_subkey.h +@@ -49,12 +49,17 @@ enum huk_subkey_usage { + * + * Returns a subkey derived from the hardware unique key. Given the same + * input the same subkey is returned each time. ++ * Function huk_subkey_derive is __weak to allow platform custom implementation. ++ * __huk_subkey_derive implements the default behavior of huk_subkey_derive. + * + * Return TEE_SUCCES on success or an error code on failure. + */ + TEE_Result huk_subkey_derive(enum huk_subkey_usage usage, + const void *const_data, size_t const_data_len, + uint8_t *subkey, size_t subkey_len); ++TEE_Result __huk_subkey_derive(enum huk_subkey_usage usage, ++ const void *const_data, size_t const_data_len, ++ uint8_t *subkey, size_t subkey_len); + + + #endif /*__KERNEL_HUK_SUBKEY_H*/ +diff --git a/core/kernel/huk_subkey.c b/core/kernel/huk_subkey.c +index 5481120b6..3db2cfe5f 100644 +--- a/core/kernel/huk_subkey.c ++++ b/core/kernel/huk_subkey.c +@@ -58,10 +58,9 @@ static TEE_Result huk_compat(void *ctx, enum huk_subkey_usage usage) + } + #endif /*CFG_CORE_HUK_SUBKEY_COMPAT*/ + +-__weak +-TEE_Result huk_subkey_derive(enum huk_subkey_usage usage, +- const void *const_data, size_t const_data_len, +- uint8_t *subkey, size_t subkey_len) ++TEE_Result __huk_subkey_derive(enum huk_subkey_usage usage, ++ const void *const_data, size_t const_data_len, ++ uint8_t *subkey, size_t subkey_len) + { + void *ctx = NULL; + struct tee_hw_unique_key huk = { }; +@@ -106,3 +105,12 @@ out: + crypto_mac_free_ctx(ctx); + return res; + } ++ ++__weak ++TEE_Result huk_subkey_derive(enum huk_subkey_usage usage, ++ const void *const_data, size_t const_data_len, ++ uint8_t *subkey, size_t subkey_len) ++{ ++ return __huk_subkey_derive(usage, const_data, const_data_len, subkey, ++ subkey_len); ++} +diff --git a/documentation/devicetree/bindings/mfd/st,stpmic1.yaml b/documentation/devicetree/bindings/mfd/st,stpmic1.yaml +index 344623f1f..7d97a7082 100644 +--- a/documentation/devicetree/bindings/mfd/st,stpmic1.yaml ++++ b/documentation/devicetree/bindings/mfd/st,stpmic1.yaml +@@ -262,6 +262,51 @@ properties: + minItems: 1 + maxItems: 1 + ++ st,pmic-it-id: ++ description: PMIC interruptions id to forward to the non-secure world ++ in the form of OPTEE notifications described by st,notif-it-id. ++ IT_PONKEY_F = 0 ++ IT_PONKEY_R = 1 ++ IT_WAKEUP_F = 2 ++ IT_WAKEUP_R = 3 ++ IT_VBUS_OTG_F = 4 ++ IT_VBUS_OTG_R = 5 ++ IT_SWOUT_F = 6 ++ IT_SWOUT_R = 7 ++ IT_CURLIM_BUCK1 = 8 ++ IT_CURLIM_BUCK2 = 9 ++ IT_CURLIM_BUCK3 = 10 ++ IT_CURLIM_BUCK4 = 11 ++ IT_OCP_OTG = 12 ++ IT_OCP_SWOUT = 13 ++ IT_OCP_BOOST = 14 ++ IT_OVP_BOOST = 15 ++ IT_CURLIM_LDO1 = 16 ++ IT_CURLIM_LDO2 = 17 ++ IT_CURLIM_LDO3 = 18 ++ IT_CURLIM_LDO4 = 19 ++ IT_CURLIM_LDO5 = 20 ++ IT_CURLIM_LDO6 = 21 ++ IT_SHORT_SWOTG = 22 ++ IT_SHORT_SWOUT = 23 ++ IT_TWARN_F = 24 ++ IT_TWARN_R = 25 ++ IT_VINLOW_F = 26 ++ IT_VINLOW_R = 27 ++ IT_SWIN_F = 30 ++ IT_SWIN_R = 31 ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ minItems: 1 ++ maxItems: 32 ++ ++ st,notif-it-id: ++ description: OPTEE notification numbers to send to the non-secure world. ++ One notification is needed for each interruption listed by st,pmic-it-id, ++ so the number of notifications must be eaqual to the number of interrupts. ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ minItems: 1 ++ maxItems: 32 ++ + additionalProperties: false + + required: +@@ -271,6 +316,10 @@ required: + - "#interrupt-cells" + - interrupt-controller + ++dependencies: ++ st,notif-it-id: [ 'st,pmic-it-id' ] ++ st,pmic-it-id: [ 'st,notif-it-id' ] ++ + examples: + - | + #include +@@ -289,6 +338,8 @@ examples: + #interrupt-cells = <2>; + + st,wakeup-pin-number = <1>; ++ st,pmic-it-id = ; ++ st,notif-it-id = <0 2>; + + onkey { + compatible = "st,stpmic1-onkey"; +-- +2.25.1 +