mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-18 02:24:18 +00:00
feat(imx8m): obtain boot image set for imx8mn/mp
In i.MX8MM/MQ it is possible to have two copies of bootloader in SD/eMMC and switch between them. The switch is triggered either by the BootROM in case the bootloader image is faulty OR can be enforced by the user, and there is API introduced in9ce232fe
("feat(plat/imx8m): add SiP call for secondary boot"), which leverages this SoC feature. However neither i.MX8MP nor i.MX8MN have a dedicated bit which indicates what boot image set is currently booted. According to AN12853 [1] "i.MX ROMs Log Events", it is possible to determine whether fallback event occurred by parsing the BootROM event log. In case ROM event ID 0x51 is present,fallback event did occur and secondary boot image was booted. Knowing which boot image was booted might be useful for reliable bootloader A/B updates, detecting fallback event might be used for making decision if boot firmware rollback is required. This patche introduces implementation, that replicates the same imx_src_handler() behaviour as on i.MX8MM/MQ SoCs. The code is based on original U-Boot implementation [2]. [1]: https://www.nxp.com/webapp/Download?colCode=AN12853 [2]:a5ee05cf71
Change-Id: I9a4c5229aa0e53fa23b5261459da99cb3ce6bdbe Signed-off-by: Igor Opaniuk <igor.opaniuk@foundries.io>
This commit is contained in:
parent
6c74b55637
commit
6d2c502afb
3 changed files with 84 additions and 2 deletions
|
@ -17,6 +17,15 @@
|
|||
#include <lib/mmio.h>
|
||||
#include <sci/sci.h>
|
||||
|
||||
#if defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
|
||||
/*
|
||||
* Defined in
|
||||
* table 11. ROM event log buffer address location
|
||||
* AN12853 "i.MX ROMs Log Events"
|
||||
*/
|
||||
#define ROM_LOG_BUFFER_ADDR 0x9E0
|
||||
#endif
|
||||
|
||||
#if defined(PLAT_imx8qm) || defined(PLAT_imx8qx)
|
||||
|
||||
#ifdef PLAT_imx8qm
|
||||
|
@ -177,6 +186,76 @@ int imx_src_handler(uint32_t smc_fid,
|
|||
}
|
||||
#endif /* defined(PLAT_imx8mm) || defined(PLAT_imx8mq) */
|
||||
|
||||
#if defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
|
||||
static bool is_secondary_boot(void)
|
||||
{
|
||||
uint32_t *rom_log_addr = (uint32_t *)ROM_LOG_BUFFER_ADDR;
|
||||
bool is_secondary = false;
|
||||
uint32_t *rom_log;
|
||||
uint8_t event_id;
|
||||
|
||||
/* If the ROM event log pointer is not valid. */
|
||||
if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xB00000 ||
|
||||
*rom_log_addr & 0x3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Parse the ROM event ID version 2 log */
|
||||
rom_log = (uint32_t *)(uintptr_t)(*rom_log_addr);
|
||||
for (size_t i = 0; i < 128; i++) {
|
||||
event_id = rom_log[i] >> 24;
|
||||
switch (event_id) {
|
||||
case 0x00: /* End of list */
|
||||
return is_secondary;
|
||||
/* Log entries with 1 parameter, skip 1 */
|
||||
case 0x80: /* Perform the device initialization */
|
||||
case 0x81: /* The boot device initialization completes */
|
||||
case 0x82: /* Execute boot device driver pre-config */
|
||||
case 0x8F: /* The boot device initialization fails */
|
||||
case 0x90: /* Start to read data from boot device */
|
||||
case 0x91: /* Reading data from boot device completes */
|
||||
case 0x9F: /* Reading data from boot device fails */
|
||||
i += 1;
|
||||
continue;
|
||||
/* Log entries with 2 parameters, skip 2 */
|
||||
case 0xA0: /* Image authentication result */
|
||||
case 0xC0: /* Jump to the boot image soon */
|
||||
i += 2;
|
||||
continue;
|
||||
/* Booted the primary boot image */
|
||||
case 0x50:
|
||||
is_secondary = false;
|
||||
continue;
|
||||
/* Booted the secondary boot image */
|
||||
case 0x51:
|
||||
is_secondary = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return is_secondary;
|
||||
}
|
||||
|
||||
int imx_src_handler(uint32_t smc_fid,
|
||||
u_register_t x1,
|
||||
u_register_t x2,
|
||||
u_register_t x3,
|
||||
void *handle)
|
||||
{
|
||||
switch (x1) {
|
||||
case IMX_SIP_SRC_SET_SECONDARY_BOOT:
|
||||
/* we do support that on these SoCs */
|
||||
break;
|
||||
case IMX_SIP_SRC_IS_SECONDARY_BOOT:
|
||||
return is_secondary_boot();
|
||||
default:
|
||||
return SMC_UNK;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(PLAT_imx8mn) || defined(PLAT_imx8mp) */
|
||||
|
||||
static uint64_t imx_get_commit_hash(u_register_t x2,
|
||||
u_register_t x3,
|
||||
u_register_t x4)
|
||||
|
|
|
@ -60,7 +60,8 @@ static uintptr_t imx_sip_handler(unsigned int smc_fid,
|
|||
case IMX_SIP_MISC_SET_TEMP:
|
||||
SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
|
||||
#endif
|
||||
#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
|
||||
#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq) || defined(PLAT_imx8mn) || \
|
||||
defined(PLAT_imx8mp)
|
||||
case IMX_SIP_SRC:
|
||||
SMC_RET1(handle, imx_src_handler(smc_fid, x1, x2, x3, handle));
|
||||
break;
|
||||
|
|
|
@ -68,7 +68,9 @@ int imx_gpc_handler(uint32_t smc_fid, u_register_t x1,
|
|||
u_register_t x2, u_register_t x3);
|
||||
#endif
|
||||
|
||||
#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
|
||||
#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq) || defined(PLAT_imx8mn) || \
|
||||
defined(PLAT_imx8mp)
|
||||
|
||||
int imx_src_handler(uint32_t smc_fid, u_register_t x1,
|
||||
u_register_t x2, u_register_t x3, void *handle);
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue