[PATCH 1/3] ARM: imx: Factor out parsing of ROM log

From: Fedor Ross fedor.ross@ifm.com
Factor out parsing of ROM log in function spl_mmc_emmc_boot_partition(). This can be helpful to detect a secondary image boot without fiddling around with MMC partitions. This way for example, U-Boot is able to detect a secondary image boot and can enter some fallback scenario like starting a recovery mode.
Signed-off-by: Fedor Ross fedor.ross@ifm.com Signed-off-by: Marek Vasut marex@denx.de --- Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de --- arch/arm/mach-imx/imx8m/soc.c | 55 +++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 18 deletions(-)
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index d5254886bed..b8d7a050dc9 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -647,19 +647,17 @@ struct rom_api *g_rom_api = (struct rom_api *)0x980;
#if defined(CONFIG_IMX8M) #include <spl.h> -int spl_mmc_emmc_boot_partition(struct mmc *mmc) +int imx8m_detect_secondary_image_boot(void) { u32 *rom_log_addr = (u32 *)0x9e0; u32 *rom_log; u8 event_id; - int i, part; - - part = default_spl_mmc_emmc_boot_partition(mmc); + int i, boot_secondary = 0;
/* If the ROM event log pointer is not valid. */ if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xb00000 || *rom_log_addr & 0x3) - return part; + return -EINVAL;
/* Parse the ROM event ID version 2 log */ rom_log = (u32 *)(uintptr_t)(*rom_log_addr); @@ -667,7 +665,7 @@ int spl_mmc_emmc_boot_partition(struct mmc *mmc) event_id = rom_log[i] >> 24; switch (event_id) { case 0x00: /* End of list */ - return part; + return boot_secondary; /* Log entries with 1 parameter, skip 1 */ case 0x80: /* Start to perform the device initialization */ case 0x81: /* The boot device initialization completes */ @@ -685,24 +683,45 @@ int spl_mmc_emmc_boot_partition(struct mmc *mmc) continue; /* Boot from the secondary boot image */ case 0x51: - /* - * Swap the eMMC boot partitions in case there was a - * fallback event (i.e. primary image was corrupted - * and that corruption was recognized by the BootROM), - * so the SPL loads the rest of the U-Boot from the - * correct eMMC boot partition, since the BootROM - * leaves the boot partition set to the corrupted one. - */ - if (part == 1) - part = 2; - else if (part == 2) - part = 1; + boot_secondary = 1; continue; default: continue; } }
+ return boot_secondary; +} + +int spl_mmc_emmc_boot_partition(struct mmc *mmc) +{ + int part, ret; + + part = default_spl_mmc_emmc_boot_partition(mmc); + if (part == 0) + return part; + + ret = imx8m_detect_secondary_image_boot(); + if (ret < 0) { + printf("Could not get boot partition! Using %d\n", part); + return part; + } + + if (ret == 1) { + /* + * Swap the eMMC boot partitions in case there was a + * fallback event (i.e. primary image was corrupted + * and that corruption was recognized by the BootROM), + * so the SPL loads the rest of the U-Boot from the + * correct eMMC boot partition, since the BootROM + * leaves the boot partition set to the corrupted one. + */ + if (part == 1) + part = 2; + else if (part == 2) + part = 1; + } + return part; } #endif

From: Fedor Ross fedor.ross@ifm.com
In case of a secondary image boot from the user area of an eMMC device, the correct offset must be calculated. The offset is fused in the fuse IMG_CNTN_SET1_OFFSET of the i.MX8M Nano and Plus. The calculation of the offset is described in the reference manual (IMX8MNRM Rev. 2, 07/2022 and IMX8MPRM Rev. 1, 06/2021):
The fuse IMG_CNTN_SET1_OFFSET (0x490[22:19]) is defined as follows: * Secondary boot is disabled if fuse value is bigger than 10, n = fuse value bigger than 10. * n == 0: Offset = 4MB * n == 2: Offset = 1MB * Others & n <= 10 : Offset = 1MB*2^n
Signed-off-by: Fedor Ross fedor.ross@ifm.com Signed-off-by: Marek Vasut marex@denx.de --- Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de --- arch/arm/mach-imx/imx8m/soc.c | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index b8d7a050dc9..2234ef947a1 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -28,8 +28,10 @@ #include <errno.h> #include <fdt_support.h> #include <fsl_wdog.h> +#include <fuse.h> #include <imx_sip.h> #include <linux/bitops.h> +#include <linux/bitfield.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -726,6 +728,43 @@ int spl_mmc_emmc_boot_partition(struct mmc *mmc) } #endif
+#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP) +#define IMG_CNTN_SET1_OFFSET GENMASK(22, 19) +unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc, + unsigned long raw_sect) +{ + u32 val, offset; + + if (fuse_read(2, 1, &val)) { + debug("Error reading fuse!\n"); + return raw_sect; + } + + val = FIELD_GET(IMG_CNTN_SET1_OFFSET, val); + if (val > 10) { + debug("Secondary image boot disabled!\n"); + return raw_sect; + } + + if (val == 0) + offset = SZ_4M; + else if (val == 1) + offset = SZ_2M; + else if (val == 2) + offset = SZ_1M; + else /* flash.bin offset = 1 MiB * 2^n */ + offset = SZ_1M << val; + + offset /= 512; + offset -= CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET; + + if (imx8m_detect_secondary_image_boot()) + raw_sect += offset; + + return raw_sect; +} +#endif + bool is_usb_boot(void) { return get_boot_device() == USB_BOOT;

From: Fedor Ross fedor.ross@ifm.com
Implement the 'getprisec' subcommand of 'bmode' command for i.MX8M by reading out the ROM log events. This event is set by the BootROM if it switched to the secondary copy due to primary copy being corrupted.
Signed-off-by: Fedor Ross fedor.ross@ifm.com Signed-off-by: Marek Vasut marex@denx.de --- Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de --- arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/imx8m/soc.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index d94b5828d0d..982d542b1c8 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -70,7 +70,7 @@ config CSF_SIZE config CMD_BMODE bool "Support the 'bmode' command" default y - depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX5 + depends on ARCH_IMX8M || ARCH_MX7 || ARCH_MX6 || ARCH_MX5 help This enables the 'bmode' (bootmode) command for forcing a boot from specific media. diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 2234ef947a1..10e5aeb48a2 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -726,6 +726,11 @@ int spl_mmc_emmc_boot_partition(struct mmc *mmc)
return part; } + +int boot_mode_getprisec(void) +{ + return !!imx8m_detect_secondary_image_boot(); +} #endif
#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)

Hi Fedor, Marek,
On 29.07.23 17:09, Marek Vasut wrote:
From: Fedor Ross fedor.ross@ifm.com
Implement the 'getprisec' subcommand of 'bmode' command for i.MX8M by reading out the ROM log events. This event is set by the BootROM if it switched to the secondary copy due to primary copy being corrupted.
Signed-off-by: Fedor Ross fedor.ross@ifm.com Signed-off-by: Marek Vasut marex@denx.de
Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de
arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/imx8m/soc.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index d94b5828d0d..982d542b1c8 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -70,7 +70,7 @@ config CSF_SIZE config CMD_BMODE bool "Support the 'bmode' command" default y
- depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX5
- depends on ARCH_IMX8M || ARCH_MX7 || ARCH_MX6 || ARCH_MX5 help This enables the 'bmode' (bootmode) command for forcing a boot from specific media.
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 2234ef947a1..10e5aeb48a2 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -726,6 +726,11 @@ int spl_mmc_emmc_boot_partition(struct mmc *mmc)
return part; }
+int boot_mode_getprisec(void) +{
- return !!imx8m_detect_secondary_image_boot();
+} #endif
#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
This breaks several board, I bisected imx8mm-cl-iot-gate because those boards don't define boot_mode_apply:
+arch/arm/mach-imx/cmd_bmode.c:86: undefined reference to `boot_mode_apply' +make[1]: *** [Makefile:1765: u-boot] Error 139
I cannot apply this, please check and repost, thanks.
Best regards, Stefano

On 10/16/23 08:44, Stefano Babic wrote:
Hi Fedor, Marek,
On 29.07.23 17:09, Marek Vasut wrote:
From: Fedor Ross fedor.ross@ifm.com
Implement the 'getprisec' subcommand of 'bmode' command for i.MX8M by reading out the ROM log events. This event is set by the BootROM if it switched to the secondary copy due to primary copy being corrupted.
Signed-off-by: Fedor Ross fedor.ross@ifm.com Signed-off-by: Marek Vasut marex@denx.de
Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de
arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/imx8m/soc.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index d94b5828d0d..982d542b1c8 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -70,7 +70,7 @@ config CSF_SIZE config CMD_BMODE bool "Support the 'bmode' command" default y - depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX5 + depends on ARCH_IMX8M || ARCH_MX7 || ARCH_MX6 || ARCH_MX5 help This enables the 'bmode' (bootmode) command for forcing a boot from specific media. diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 2234ef947a1..10e5aeb48a2 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -726,6 +726,11 @@ int spl_mmc_emmc_boot_partition(struct mmc *mmc) return part; }
+int boot_mode_getprisec(void) +{ + return !!imx8m_detect_secondary_image_boot(); +} #endif #if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
This breaks several board, I bisected imx8mm-cl-iot-gate because those boards don't define boot_mode_apply:
+arch/arm/mach-imx/cmd_bmode.c:86: undefined reference to `boot_mode_apply' +make[1]: *** [Makefile:1765: u-boot] Error 139
I cannot apply this, please check and repost, thanks.
I sent a slightly more extensive V2 which passes CI.
participants (2)
-
Marek Vasut
-
Stefano Babic