]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
imx: hab: Make imx_hab_is_enabled dependent on FIELD_RETURN
authorPaul Geurts <paul.geurts@prodrive-technologies.com>
Fri, 1 Nov 2024 08:49:21 +0000 (09:49 +0100)
committerFabio Estevam <festevam@gmail.com>
Sat, 9 Nov 2024 11:53:36 +0000 (08:53 -0300)
The decision on whether HAB is enabled is solely based on the SEC_CONFIG
fuse. The HAB FIELD_RETURN feature is able to permanently disable HAB on
a CPU, after which it is able to boot unsigned firmware. U-Boot however
does not take into account the FIELD_RETURN mode, and refuses to boot
unsigned software when the feature is enabled.

Also take the FIELD_RETURN fuse into account when deciding whether HAB
is enabled. When The FIELD_RETURN fuse is blown, HAB is not enabled.

Tested on i.MX8M Mini, i.MX8M Plus, i.MX8M Nano and i.MX6ULL

Signed-off-by: Paul Geurts <paul.geurts@prodrive-technologies.com>
arch/arm/include/asm/mach-imx/hab.h
arch/arm/mach-imx/hab.c
arch/arm/mach-imx/imx8m/soc.c
arch/arm/mach-imx/mx6/soc.c
arch/arm/mach-imx/mx7/soc.c
arch/arm/mach-imx/mx7ulp/soc.c

index 9410f30eef2e0b7f64e4c7a4bcee45444ee5ed97..c0caf57fe61d8968ee2fefb616993a6e175a8d60 100644 (file)
@@ -139,6 +139,7 @@ struct imx_fuse {
 
 #if defined(CONFIG_IMX_HAB)
 extern struct imx_fuse const imx_sec_config_fuse;
+extern struct imx_fuse const imx_field_return_fuse;
 #endif
 
 /*Function prototype description*/
index 7e4eaa4b14fba5c584ea9edd9ae32863ab853768..600092389a327ab9c78929addadeb85240e7a1cf 100644 (file)
@@ -26,6 +26,14 @@ DECLARE_GLOBAL_DATA_PTR;
 #define IS_HAB_ENABLED_BIT \
        (is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 :     \
         ((is_soc_type(MXC_SOC_MX7) || is_soc_type(MXC_SOC_IMX8M)) ? 0x2000000 : 0x2))
+#define FIELD_RETURN_FUSE_MASK \
+       (is_imx8mp() ? 0xFFFFFFFF : 0x00000001)
+/*
+ * The fuse pattern for i.MX8M Plus is 0x28001401, but bit 2 is already set from factory.
+ * This means when field return is set, the fuse word value reads 0x28001405
+ */
+#define FIELD_RETURN_PATTERN \
+       (is_imx8mp() ? 0x28001405 : 0x00000001)
 
 #ifdef CONFIG_MX7ULP
 #define HAB_M4_PERSISTENT_START        ((soc_rev() >= CHIP_REV_2_0) ? 0x20008040 : \
@@ -870,18 +878,30 @@ static int validate_ivt(struct ivt *ivt_initial)
 
 bool imx_hab_is_enabled(void)
 {
-       struct imx_fuse *fuse =
+       struct imx_fuse *sec_config =
                (struct imx_fuse *)&imx_sec_config_fuse;
+       struct imx_fuse *field_return =
+               (struct imx_fuse *)&imx_field_return_fuse;
        uint32_t reg;
+       bool is_enabled;
        int ret;
 
-       ret = fuse_read(fuse->bank, fuse->word, &reg);
+       ret = fuse_read(sec_config->bank, sec_config->word, &reg);
        if (ret) {
-               puts("\nSecure boot fuse read error\n");
+               puts("Secure boot fuse read error\n");
                return ret;
        }
+       is_enabled = reg & IS_HAB_ENABLED_BIT;
+       if (is_enabled) {
+               ret = fuse_read(field_return->bank, field_return->word, &reg);
+               if (ret) {
+                       puts("Field return fuse read error\n");
+                       return ret;
+               }
+               is_enabled = (reg & FIELD_RETURN_FUSE_MASK) != FIELD_RETURN_PATTERN;
+       }
 
-       return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT;
+       return is_enabled;
 }
 
 int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
index e6c00e85412be72114134242f172e65c9dcddbcf..09a528a64f8e221274d6069321bd7b9dfd93562f 100644 (file)
@@ -41,6 +41,11 @@ struct imx_fuse const imx_sec_config_fuse = {
        .bank = 1,
        .word = 3,
 };
+
+struct imx_fuse const imx_field_return_fuse = {
+       .bank = 8,
+       .word = 3,
+};
 #endif
 
 int timer_init(void)
index e9dd33845635481a74c49f928c6aa59dc967fff8..d4a61731a67d87beffb7f65e77b0954b83e09d19 100644 (file)
@@ -55,6 +55,11 @@ struct imx_fuse const imx_sec_config_fuse = {
        .bank = 0,
        .word = 6,
 };
+
+struct imx_fuse const imx_field_return_fuse = {
+       .bank = 5,
+       .word = 6,
+};
 #endif
 
 u32 get_nr_cpus(void)
index 11e8ac066086eeda8f861947eefd483ffd6ae0e4..e504c1fd52a06e3cb5d0798373ed79b2695ea202 100644 (file)
@@ -131,6 +131,11 @@ struct imx_fuse const imx_sec_config_fuse = {
        .bank = 1,
        .word = 3,
 };
+
+struct imx_fuse const imx_field_return_fuse = {
+       .bank = 8,
+       .word = 3,
+};
 #endif
 
 static bool is_mx7d(void)
index b50ad1cfa195dc0f9e1ebbd2b77f1d2a1ec2920a..61d331e018195c1e69d1b68e449013b54972b19e 100644 (file)
@@ -42,6 +42,11 @@ struct imx_fuse const imx_sec_config_fuse = {
        .bank = 29,
        .word = 6,
 };
+
+struct imx_fuse const imx_field_return_fuse = {
+       .bank = 9,
+       .word = 6,
+};
 #endif
 
 #define ROM_VERSION_ADDR 0x80