cancel
Showing results for 
Search instead for 
Did you mean: 

Boot Failure on STM32MP157C: Secure Mode Issues (smc execution failure)

VivekB
Senior

Hi, 

I am working with an STM32MP157CAA Rev.Z on a custom STM32CubeMX board running OpenSTLinux 6.6 (Yocto Scarthgap MPU v24.11.06). I have successfully integrated and bootstrapped various boot components.

I first got the TF-A and OPTEE to boot the system and now it is also able to bring up the uboot. However, while trying to boot up the uboot gets into an "secure mode execution errors". I am not sure where it is coming from? We have hash-and-boot-options_hash-and-boot-options.bin flashed into the OTP area. Is that something could potentially lead to this type of issue? 

BL2 (TF-A) Loading

  • BL2 (TF-A) executes as expected and starts platform initialization.

  • The board is in trusted mode, and secure boot appears to be enabled.

  • Below are the logs confirming BL2 is executing:

 

NOTICE:  CPU: STM32MP157CAA Rev.Z
NOTICE:  Model: STMicroelectronics custom STM32CubeMX board - openstlinux-6.6-yocto-scarthgap-mpu-v24.11.06
NOTICE:  BL2: v2.10-stm32mp1-r1.0(release)
NOTICE:  BL2: Built : 14:58:08, Mar  4 2025
NOTICE:  TRUSTED_BOARD_BOOT support enabled

 

Image Loading Sequence

  • BL2 successfully attempts to load various images, including:

    • TF-A (tf-a-stm32mp157c-ccb-mx_Signed.stm32)
    • OP-TEE (tos-fw.bin, tos-fw-extra1.bin)
    • SCP firmware (scp-fw.bin)
    • NT firmware (nt-fw.bin)

 

ERROR:   BL2: Preparing to load image id 1 (tf-a-stm32mp157c-ccb-mx_Signed.stm32)
ERROR:   BL2: Loading image id 1 (tf-a-stm32mp157c-ccb-mx_Signed.stm32)
ERROR:   BL2: Calling load_auth_image() for image id 1 with base 0x2ffff000
ERROR:   ROTPK is not deployed on platform. Skipping ROTPK verification.

 

"ROTPK is not deployed", looks like Root of Trust Public Key (ROTPK) verification is being skipped. I am not sure whether this is expected behaviour in my setup or what is causing this.

OP-TEE Boot & Peripheral Initialization

  • OP-TEE initialises successfully and maps secure memory regions.

  • Secure components like TZC400, STPMIC, and STM32MP1 clocks are initialized.

  • However, multiple SMC call failures appear:

 

stm32_smc: Failed to exec svc=82001003 op=1 in secure mode (err = -1)

 

U-Boot Execution

  • U-Boot executes successfully but reports errors related to secure mode calls:

 

stm32_smc: Failed to exec svc=82001003 op=1 in secure mode (err = -1)

 

EFI system partition detection fails, which is unexpected:

 

No EFI system partition
Failed to persist EFI variables

 

At this point, the system does not proceed further due to the OP-TEE watchdog panic.

 

E/TC:0   Panic 'Watchdog' at core/drivers/stm32_iwdg.c:228 <stm32_iwdg_it_handler>

 

I have also attached the full boot_log.txt in the attachment for reference. 

The below is the details of my platform: 

Hardware & Software Details

  • CPU: STM32MP157CAA Rev.Z
  • Board: STMicroelectronics custom STM32CubeMX board
  • Software Version: OpenSTLinux 6.6 Yocto Scarthgap MPU (v24.11.06)
  • TF-A Version: v2.10-stm32mp1-r1.0 (Release)
  • U-Boot Version: 2023.10-stm32mp-r1
  • OP-TEE Version: REL_0.8.7-8-g79647115eb
  • Boot Mode: Trusted Mode with Secure Boot Enabled

I need some help to understand what are the areas I need to investigate to resolve this issue. 

Many Thanks

Best Regards, 

Vivek

27 REPLIES 27

I was able to eliminate the "Card did not respond to voltage select! : -110" by removing some device tree changes to sdmmc2 make by the customer.  Then usbotg was configured incorrectly, but now it finally downloads. This is u-boot for DFU at this point.  Next I will need to get their u-boot and kernel working with op-tee.

I am using the same version that you are using, eco system v6.0

 

Excellent news, I have just added this part in my project dts: 

819 &sdmmc2 {
 820     status = "okay";
 821 
 822     /* USER CODE BEGIN sdmmc2 */
 823     cap-sd-highspeed;
 824     cap-mmc-highspeed;
 825     max-frequency = <0x7270e00>;
 826     bus-width = <4>;
 827     vmmc-supply = <&v3v3>;
 828     vqmmc-supply = <&vdd>;
 829     mmc-ddr-3_3v;
 830     /* USER CODE END sdmmc2 */
 831 };

In my case sdmmc2 node was missing in the project dts and is status = disabled in the uboot dts. I am compiling and will test how it goes. Thanks for confirming the releases.

In my case even after adding the sdmmc2 node in the uboot dts file (project specific dts file - attached), I am still getting the same error:

VBDBG:mmc_start_init: 2916 - Entering mmc_start_init()
VBDBG:mmc_start_init: 2920 - Host capabilities set: 0x1000000f
VBDBG:mmc_start_init: 2942 - Calling mmc_deferred_probe()
VBDBG:mmc_start_init: 2948 - mmc_getcd() returned 1, no_card=0
VBDBG:mmc_start_init: 2967 - Calling mmc_get_op_cond()
VBDBG:mmc_start_init: 2969 - mmc_get_op_cond() returned -110
VBDBG:mmc_start_init: 2976 - Exiting mmc_start_init(), err=-110
VBDBG: mmc_init: 3050 - mmc_start_init() after rescan returned -110
VBDBG: mmc_init: 3075 - MMC STM32 SD/MMC initialization failed after retries: -110

Not sure where it is going wrong. 

GatienC
ST Employee

Hello @VivekB ,

Looking at your device tree, I'm not sure what you're trying to do.

SDMMC1 is your boot storage and seems to be an Emmc, right?  (deduced from mmc-ddr-3_3v; and bus-width = <8>; )

If you don't use SDMMC2, then please disable the node, there's no property to make it functional in your device tree. And it seems that you use Wifi on sdmmc3.

Which instance of sdmmc is causing this trace? Are all SDMMC instances secure configuration  that you use compatible with U-Boot (Non-secure, non isolated for cortex M4)?

Cheers,

Gatien

 
 

Hi @GatienC apologies couldn't reply earlier. I was doing a bit of experiemnts with the sdmmc nodes I have. It would be deemed as my lack of understanding about the terminologies used in the uboot for the sdmmc. So trying to enable sdmmc2 was a failed attempt at that. Basically at the moment I facing the issue, while trying to download the code it fails with the following error: 

VivekB_0-1742917839551.png

When I look into the log it shows the below: 

mmc_init: -110, time 24
Error: mmc device 1 not found

If I drop at the uboot prompt, and do a mmc rescan it finds the mmc1. So I tried implementing a rescan mechanims in the uboot code. If I do that it detects the mmc1 and the above error goes away but then it cannot fetch the erase block size for some reason and it fails again. Thta's why I was trying to check if SDMMC2 node has to be enabled in my project speciifc dts file and if that helps. But that didn't help. Sorry bit vague in my description but I am not entirely sure why it fails to detect mmc1. I have also tried changing the HW and it doesn't look like a HW issue. I think there maybe something wrong in my dts file and hence the error. Many thanks, Vivek

Hi @GatienC 

Looks like there are other issues in my case.

One thing I’ve identified is that the stpmic driver and the surrounding codebase have changed significantly. This can possibly why the code is crashing at the below point: 

DFU alt info setting: done
D/TC:0   sm_platform_handler:95 VBDBG:sm_platform_handler:95: OPTEE_SMC_OWNER_SIP
D/TC:0   sip_service:36 VBDBG:sip_service:36: calling pwr_scv_handler
D/TC:0   pwr_scv_handler:56 PWR service: write 0x40000100 at offset 0xc
F/TC:0   pwr_scv_handler:72 wrt off c=40000100 => 40000100
D/TC:0   sip_service:39 VBDBG:sip_service:39: Backtrace:
E/TC:0   TEE load address @ 0xde000000
E/TC:0   Call stack:
E/TC:0    0xde003511
E/TC:0    0xde0315ef
E/TC:0    0xde031731
E/TC:0    0xde007205
E/TC:0    0xde007098
D/TC:0   sm_platform_handler:95 VBDBG:sm_platform_handler:95: OPTEE_SMC_OWNER_SIP
D/TC:0   sip_service:36 VBDBG:sip_service:36: calling pwr_scv_handler
D/TC:0   pwr_scv_handler:56 PWR service: write 0xd0000100 at offset 0xc
F/TC:0   pwr_scv_handler:72 wrt off c=50000100 => d0000100
D/TC:0   sip_service:39 VBDBG:sip_service:39: Backtrace:
E/TC:0   TEE load address @ 0xde000000
E/TC:0   Call stack:
E/TC:0    0xde003511
E/TC:0    0xde0315ef
E/TC:0    0xde031731
E/TC:0    0xde007205
E/TC:0    0xde007098

Looks like it is trying to power up the system but crashing. Apologies for the speculation but the traces from pwr_scv_handler give me a hint towards that. 

We previously used a custom optee patch for our board (below), but now when I try to cherry-pick the changes, it appears the structure has changed quite a bit.

Adds option to device tree for changing current limit on pwr_sw2 output for a stpmic1 from 600mA to 1100mA.  option in device tree is:
st,regulator-ocp-1a;
And needs setting in the relevant node.
---
 .../arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c |  3 +++
 core/drivers/regulator/core.c                      |  4 ++++
 core/drivers/stpmic1.c                             | 14 ++++++++++++++
 core/include/drivers/regulator.h                   |  2 ++
 core/include/drivers/stpmic1.h                     |  8 ++++++++
 5 files changed, 31 insertions(+)

diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c
index 4eda619..34b3839 100644
--- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c
+++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c
@@ -311,6 +311,9 @@ static TEE_Result pmic_set_flag(const struct regul_desc *desc, uint16_t flag)
 	case REGUL_ENABLE_BYPASS:
 		ret = stpmic1_regulator_bypass_mode_set(desc->node_name);
 		break;
+	case REGUL_ENABLE_OCP1A:
+		ret = stpmic1_regulator_ocp_1a_set(desc->node_name);
+		break;
 	default:
 		DMSG("Invalid flag %#"PRIx16, flag);
 		panic();
diff --git a/core/drivers/regulator/core.c b/core/drivers/regulator/core.c
index d4dc375..7b462fc 100644
--- a/core/drivers/regulator/core.c
+++ b/core/drivers/regulator/core.c
@@ -542,6 +542,10 @@ static struct regul_property flag_prop[] = {
 		.name = "st,regulator-bypass",
 		.flag = REGUL_ENABLE_BYPASS,
 	},
+	{
+		.name = "st,regulator-ocp-1a",
+		.flag = REGUL_ENABLE_OCP1A,
+	},
 };
 
 static TEE_Result parse_properties(const void *fdt, struct rdev *rdev, int node)
diff --git a/core/drivers/stpmic1.c b/core/drivers/stpmic1.c
index b558d6b..3449d92 100644
--- a/core/drivers/stpmic1.c
+++ b/core/drivers/stpmic1.c
@@ -27,6 +27,7 @@ struct regul_struct {
 	uint8_t mask_reset_pos;
 	uint8_t icc_reg;
 	uint8_t icc_mask;
+	uint8_t ocp1a_pos;
 };
 
 static struct i2c_handle_s *pmic_i2c_handle;
@@ -608,6 +609,7 @@ static const struct regul_struct regulators_table[] = {
 		.enable_pos	= SWIN_SWOUT_ENABLED_POS,
 		.icc_reg	= BUCK_ICC_TURNOFF_REG,
 		.icc_mask	= PWR_SW2_ICC_SHIFT,
+		.ocp1a_pos	= OCP_LIMIT_HIGH_POS,
 	},
 };
 
@@ -787,6 +789,18 @@ int stpmic1_regulator_bypass_mode_set(const char *name)
 				       LDO3_BYPASS | LDO_VOLTAGE_MASK);
 }
 
+int stpmic1_regulator_ocp_1a_set(const char *name)
+{
+	const struct regul_struct *regul = get_regulator_data(name);
+
+	if (!regul->ocp1a_pos )
+		return -1;
+
+	return stpmic1_register_update(regul->control_reg,
+				       BIT(regul->ocp1a_pos),
+				       BIT(regul->ocp1a_pos));
+}
+
 int stpmic1_active_discharge_mode_set(const char *name)
 {
 	if (!strncmp(name, "pwr_sw1", 7))
diff --git a/core/include/drivers/regulator.h b/core/include/drivers/regulator.h
index 827b681..a999d87 100644
--- a/core/include/drivers/regulator.h
+++ b/core/include/drivers/regulator.h
@@ -46,6 +46,8 @@ int plat_get_lp_mode_count(void);
 #define REGUL_SINK_SOURCE	BIT(6)
 /* st,regulator-bypass: set the regulator in bypass mode */
 #define REGUL_ENABLE_BYPASS	BIT(7)
+/* st,regulator-bypass: set the regulator in 1A over current protection mode */
+#define REGUL_ENABLE_OCP1A	BIT(8)
 
 struct rdev *regulator_get_by_node_name(const char *node_name);
 struct rdev *regulator_get_by_regulator_name(const char *reg_name);
diff --git a/core/include/drivers/stpmic1.h b/core/include/drivers/stpmic1.h
index 5fe4823..502dadc 100644
--- a/core/include/drivers/stpmic1.h
+++ b/core/include/drivers/stpmic1.h
@@ -259,6 +259,14 @@ int stpmic1_lp_reg_on_off(const char *name, uint8_t enable);
 int stpmic1_lp_set_mode(const char *name, uint8_t hplp);
 int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts);
 
+/**
+ * @brief                   INDRA specific creation to set 1A limit on pwr_sw2 as there was no mapping of register option to device tree settings
+ * 
+ * @param   name            name of regulator to set option for (only works for pwr_sw2)
+ * @return  int             some kind of error value TODO: improve this when function is written
+*/
+int stpmic1_regulator_ocp_1a_set(const char *name);
+
 #ifdef CFG_STM32MP15
 /*
  * Specific API for controlling regulators driven from STPMIC1 device
-- 
2.25.1

Would you mind taking a look at the attached patch and advising on how best to adapt these changes to the new stpmic driver in the optee-os repository? 

I really appreciate your help.

Best regards,
Vivek

GatienC
ST Employee

Hi Vivek, I'm clearly not an expert on this but I expect most of the patch to be applied to core/drivers/regulator/regulator_dt.c for the device tree part and maybe handle the flag in pmic_supplied_init()?

 

Cheers,

Gatien

Thanks @GatienC for the lead, I will investigate this area and come back.

BR, Vivek