Reading FLASH_EXT_USER_BASE gives always 0 from User Application after OEMiRoT jumped with EXITHDPLIB_PFUNC->JumpHDPLvl2
On the STM32C542RC, this is my current FLASH layout:
-- OEMiRoT flash layout:
-- Bootloader : 0x08000000 .. +0x10000
-- Keys : +0x10000 (0x2000)
-- NV counters : +0x12000 (0x2000)
-- Primary app slot : 0x8014000 size=0x16000
-- App code (post-hdr) : 0x8014400 size=0x15c00
-- Secondary app slot : 0x802a000 size=0x16000
-- OEMiRoT option bytes to program:
-- HDP1_END = 0x9 WRPSGn1 = 0xfe00Everything is working well (update of user application, boot, etc...) (MCUBOOT_USE_HASH_REF is not defined).
But I have an issue:
I want to use the external User Data Flash at the address FLASH_EXT_USER_BASE 0x08400000UL, requiring the option byte EDATA_EN = 0. When I read from that address in the User Application, I only read zeroes (RAZ) -- simple as `*(const int *)FLASH_EXT_USER_BASE == 0`, so this feels like the cause is some sort of HDP. By the way, the writes do work (at least when the MCU is reset, as STM32CubeProgrammer did read the data I wrote to that address).
Note: I get RAZ only from User Application after OEMiRoT jumped, while I get a correct read non-zero value if I flash the User Application alone on the MCU. The problem is the combination OEMiRoT+User App.
I tried different things: enabling/invalidating/disabling cache (with ICACHE and/or MPU), setting HDPEXT to 0
HAL_FLASH_ITF_Unlock(mx_flash_gethandle()->instance);
HAL_FLASH_ITF_SetHDPExtArea(mx_flash_gethandle()->instance, HAL_FLASH_BANK_1, 0);
HAL_FLASH_ITF_SetHDPExtArea(mx_flash_gethandle()->instance, HAL_FLASH_BANK_2, 0);
HAL_FLASH_ITF_Lock(mx_flash_gethandle()->instance);(but from what I understand the HDPEXT can only be incremented, and is reset only at reboot). I also made sure that the code reading at that address is executed in privileged mode.
The code base I'm using is this ST example https://github.com/STMicroelectronics/STM32CubeC5/tree/main/examples/advanced/rot/oemirot_dualslot/NUCLEO-C542RC which uses this HAL2 branch of mcuboot: https://github.com/STMicroelectronics/stm32-mw-mcuboot/tree/hal2 , but I do not find any evidence of HDPEXT changes.
So I was wondering if the cause could be EXITHDPLIB_PFUNC->JumpHDPLvl2, which is used to jump to user application. RM0522 says:
User calls JumpHDPLvl2 to:
• Close user Flash HDPL1 area by incrementing HDPL to 2
• Jump to the reset handler embedded within the Vector Table which address is passed as input parameter
After closing HDPL1, JumpHDPLvl2 enables the MPU region provided as input parameter. Once the MPU is enabled, the function sets the SP to the address provided by the passed Vector Table and jumps to the Reset Handler function supported by the Vector Table too. JumpHDPLvl2 does not set the new vector table. On successful execution, the function does not return and does not push LR onto the stack.
And the MPU region used for the jump is the following one:
HAL_CORTEX_MPU_REGION_1,
{
0x8014400,
0x802a000 - 1U,
HAL_CORTEX_MPU_REGION_ONLY_PRIV_RO,
HAL_CORTEX_MPU_EXECUTION_ATTR_ENABLE,
MPU_MEM_ATTR_CODE_IDX // which is using attribute HAL_CORTEX_MPU_NORMAL_MEM_WT_RA
}In the User Application I can read nonzero values from the App Slot 2.
To be honnest I’m kinda lost here. I do not know what kind of security thing I’m not following in order to read from FLASH_EXT_USER_BASE without RAZ, and I don’t know where to look. I tried to read from that address directly in the OEMiRoT too:
- in `boot_platform_init(), before `SECURITY_ApplyRunTimeProtections()`, the value is read correctly (non-zero)
- after `SECURITY_ApplyRunTimeProtections()`, the read causes a HardFault. And if I insert the read just at the very beginning of that function (before everything else !) I get also a HardFault. So I guess the compiler is doing some reordering and therefore I cannot point out a single point of failure. All I can say is that in OEMiRoT, reading FLASH_EXT_USER_BASE never returns 0.
I’m aware that MCUBoot features Data slots, but I don’t want to use these as I’m already short in main FLASH size (256KB), so using the additional 64KB user data Flash would be really great. I’m just storing non-sensible information.
Any help is very welcomed.
