[U-Boot] HAB synchronous error loop i.MX8M

Fabio Estevam festevam at gmail.com
Thu Oct 3 13:13:19 UTC 2019


Hi Patrick,

On Thu, Oct 3, 2019 at 10:01 AM Patrick Wildt <patrick at blueri.se> wrote:

> Boundary Devices U-Boot is about a year old, and I haven't checked how
> they implemented it.  I have a diff for i.MX8M HAB support which works
> for me.

Please submit the i.MX8M HAB support as a formal patch.

Thanks

>
> Best regards,
> Patrick
>
> diff --git a/arch/arm/include/asm/arch-imx8m/clock.h b/arch/arm/include/asm/arch-imx8m/clock.h
> index e7c1670f6b..5cebe10c6f 100644
> --- a/arch/arm/include/asm/arch-imx8m/clock.h
> +++ b/arch/arm/include/asm/arch-imx8m/clock.h
> @@ -675,4 +675,5 @@ int set_clk_qspi(void);
>  void enable_ocotp_clk(unsigned char enable);
>  int enable_i2c_clk(unsigned char enable, unsigned int i2c_num);
>  int set_clk_enet(enum enet_freq type);
> +void hab_caam_clock_enable(unsigned char enable);
>  #endif
> diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h
> index 95df88423c..f3bbad36de 100644
> --- a/arch/arm/include/asm/mach-imx/hab.h
> +++ b/arch/arm/include/asm/mach-imx/hab.h
> @@ -10,6 +10,8 @@
>  #include <linux/types.h>
>  #include <linux/compiler.h>
>
> +DECLARE_GLOBAL_DATA_PTR;
> +
>  /*
>   * IVT header definitions
>   * Security Reference Manual for i.MX 7Dual and 7Solo Applications Processors,
> @@ -165,6 +167,15 @@ typedef void hapi_clock_init_t(void);
>  #define HAB_ENG_RTL            0x77   /* RTL simulation engine */
>  #define HAB_ENG_SW             0xff   /* Software engine */
>
> +#ifdef CONFIG_ARM64
> +#define HAB_RVT_BASE                   0x00000880
> +
> +#define HAB_RVT_ENTRY                  ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x08))
> +#define HAB_RVT_EXIT                   ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x10))
> +#define HAB_RVT_AUTHENTICATE_IMAGE     ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x20))
> +#define HAB_RVT_REPORT_EVENT           ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x40))
> +#define HAB_RVT_REPORT_STATUS          ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x48))
> +#else
>  #ifdef CONFIG_ROM_UNIFIED_SECTIONS
>  #define HAB_RVT_BASE                   0x00000100
>  #else
> @@ -178,13 +189,14 @@ typedef void hapi_clock_init_t(void);
>                         HAB_RVT_BASE_NEW : HAB_RVT_BASE_OLD)
>  #endif
>
> -#define HAB_RVT_ENTRY                  (*(uint32_t *)(HAB_RVT_BASE + 0x04))
> -#define HAB_RVT_EXIT                   (*(uint32_t *)(HAB_RVT_BASE + 0x08))
> -#define HAB_RVT_CHECK_TARGET           (*(uint32_t *)(HAB_RVT_BASE + 0x0C))
> -#define HAB_RVT_AUTHENTICATE_IMAGE     (*(uint32_t *)(HAB_RVT_BASE + 0x10))
> -#define HAB_RVT_REPORT_EVENT           (*(uint32_t *)(HAB_RVT_BASE + 0x20))
> -#define HAB_RVT_REPORT_STATUS          (*(uint32_t *)(HAB_RVT_BASE + 0x24))
> -#define HAB_RVT_FAILSAFE               (*(uint32_t *)(HAB_RVT_BASE + 0x28))
> +#define HAB_RVT_ENTRY                  ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x04))
> +#define HAB_RVT_EXIT                   ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x08))
> +#define HAB_RVT_CHECK_TARGET           ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x0C))
> +#define HAB_RVT_AUTHENTICATE_IMAGE     ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x10))
> +#define HAB_RVT_REPORT_EVENT           ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x20))
> +#define HAB_RVT_REPORT_STATUS          ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x24))
> +#define HAB_RVT_FAILSAFE               ((ulong)*(uint32_t *)(HAB_RVT_BASE + 0x28))
> +#endif
>
>  #define HAB_CID_ROM 0 /**< ROM Caller ID */
>  #define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/
> diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h
> index 4925dd7894..65791cb1b2 100644
> --- a/arch/arm/include/asm/mach-imx/sys_proto.h
> +++ b/arch/arm/include/asm/mach-imx/sys_proto.h
> @@ -133,7 +133,8 @@ int mxs_wait_mask_set(struct mxs_register_32 *reg, u32 mask, u32 timeout);
>  int mxs_wait_mask_clr(struct mxs_register_32 *reg, u32 mask, u32 timeout);
>
>  unsigned long call_imx_sip(unsigned long id, unsigned long reg0,
> -                          unsigned long reg1, unsigned long reg2);
> +                          unsigned long reg1, unsigned long reg2,
> +                          unsigned long reg3);
>  unsigned long call_imx_sip_ret2(unsigned long id, unsigned long reg0,
>                                 unsigned long *reg1, unsigned long reg2,
>                                 unsigned long reg3);
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index aeb5493488..1efc1ed8fa 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -36,9 +36,9 @@ config USE_IMXIMG_PLUGIN
>
>  config SECURE_BOOT
>         bool "Support i.MX HAB features"
> -       depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX5
> +       depends on ARCH_IMX8M || ARCH_MX7 || ARCH_MX6 || ARCH_MX5
>         select FSL_CAAM if HAS_CAAM
> -       imply CMD_DEKBLOB
> +       imply CMD_DEKBLOB if !ARCH_IMX8M
>         help
>           This option enables the support for secure boot (HAB).
>           See doc/README.mxc_hab for more details.
> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> index 08ee52edbf..61d6bf176e 100644
> --- a/arch/arm/mach-imx/Makefile
> +++ b/arch/arm/mach-imx/Makefile
> @@ -16,6 +16,7 @@ endif
>  obj-$(CONFIG_ENV_IS_IN_MMC) += mmc_env.o
>  obj-$(CONFIG_FEC_MXC) += mac.o
>  obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
> +obj-$(CONFIG_SECURE_BOOT) += hab.o
>  obj-y += cpu.o
>  endif
>
> diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
> index ce50dbe907..6b3f7928dd 100644
> --- a/arch/arm/mach-imx/hab.c
> +++ b/arch/arm/mach-imx/hab.c
> @@ -20,7 +20,18 @@
>  #define MX6SL_PU_IROM_MMU_EN_VAR       0x00901c60
>  #define IS_HAB_ENABLED_BIT \
>         (is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 :     \
> -        (is_soc_type(MXC_SOC_MX7) ? 0x2000000 : 0x2))
> +        ((is_soc_type(MXC_SOC_MX7) || is_soc_type(MXC_SOC_IMX8M)) ? 0x2000000 : 0x2))
> +
> +#ifdef CONFIG_ARM64
> +#define FSL_SIP_HAB                    0xC2000007
> +#define FSL_SIP_HAB_AUTHENTICATE       0x00
> +#define FSL_SIP_HAB_ENTRY              0x01
> +#define FSL_SIP_HAB_EXIT               0x02
> +#define FSL_SIP_HAB_REPORT_EVENT       0x03
> +#define FSL_SIP_HAB_REPORT_STATUS      0x04
> +
> +static volatile gd_t *gd_save;
> +#endif
>
>  static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr)
>  {
> @@ -47,6 +58,97 @@ static int verify_ivt_header(struct ivt_header *ivt_hdr)
>         return result;
>  }
>
> +static inline void save_gd(void)
> +{
> +#ifdef CONFIG_ARM64
> +       gd_save = gd;
> +#endif
> +}
> +
> +static inline void restore_gd(void)
> +{
> +#ifdef CONFIG_ARM64
> +       /*
> +        * Make will already error that reserving x18 is not supported at the
> +        * time of writing, clang: error: unknown argument: '-ffixed-x18'
> +        */
> +       __asm__ volatile("mov x18, %0\n" : : "r" (gd_save));
> +#endif
> +}
> +
> +static enum hab_status hab_rvt_entry(void)
> +{
> +       enum hab_status ret;
> +       hab_rvt_entry_t *hab_rvt_entry_func;
> +
> +       hab_rvt_entry_func = (hab_rvt_entry_t *)HAB_RVT_ENTRY;
> +
> +#if defined(CONFIG_ARM64)
> +       if (current_el() != 3) {
> +               /* call sip */
> +               ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB,
> +                   FSL_SIP_HAB_ENTRY, 0, 0, 0);
> +               return ret;
> +       }
> +#endif
> +
> +       save_gd();
> +       ret = hab_rvt_entry_func();
> +       restore_gd();
> +
> +       return ret;
> +}
> +
> +static enum hab_status hab_rvt_exit(void)
> +{
> +       enum hab_status ret;
> +       hab_rvt_exit_t *hab_rvt_exit_func;
> +
> +       hab_rvt_exit_func = (hab_rvt_exit_t *)HAB_RVT_EXIT;
> +
> +#if defined(CONFIG_ARM64)
> +       if (current_el() != 3) {
> +               /* call sip */
> +               ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB,
> +                   FSL_SIP_HAB_EXIT, 0, 0, 0);
> +               return ret;
> +       }
> +#endif
> +
> +       save_gd();
> +       ret = hab_rvt_exit_func();
> +       restore_gd();
> +
> +       return ret;
> +}
> +
> +static void *hab_rvt_authenticate_image(uint8_t cid, ptrdiff_t ivt_offset,
> +    void **start, size_t *bytes, hab_loader_callback_f_t loader)
> +{
> +       void *ret;
> +       hab_rvt_authenticate_image_t *hab_rvt_authenticate_image_func;
> +
> +       hab_rvt_authenticate_image_func =
> +           (hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE;
> +
> +#if defined(CONFIG_ARM64)
> +       if (current_el() != 3) {
> +               /* call sip */
> +               ret = (void *)call_imx_sip(FSL_SIP_HAB,
> +                   FSL_SIP_HAB_AUTHENTICATE, (unsigned long)ivt_offset,
> +                   (unsigned long)start, (unsigned long)bytes);
> +               return ret;
> +       }
> +#endif
> +
> +       save_gd();
> +       ret = hab_rvt_authenticate_image_func(cid, ivt_offset, start,
> +           bytes, loader);
> +       restore_gd();
> +
> +       return ret;
> +}
> +
>  #if !defined(CONFIG_SPL_BUILD)
>
>  #define MAX_RECORD_BYTES     (8*1024) /* 4 kbytes */
> @@ -245,6 +347,57 @@ static void display_event(uint8_t *event_data, size_t bytes)
>         process_event_record(event_data, bytes);
>  }
>
> +static enum hab_status hab_rvt_report_event(enum hab_status status,
> +    uint32_t index, uint8_t *event, size_t *bytes)
> +{
> +       enum hab_status ret;
> +       hab_rvt_report_event_t *hab_rvt_report_event;
> +
> +       hab_rvt_report_event = (hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT;
> +
> +#if defined(CONFIG_ARM64)
> +       if (current_el() != 3) {
> +               /* call sip */
> +               ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB,
> +                   FSL_SIP_HAB_REPORT_EVENT, (unsigned long)index,
> +                   (unsigned long)event, (unsigned long)bytes);
> +               return ret;
> +       }
> +#endif
> +
> +       save_gd();
> +       ret = hab_rvt_report_event(status, index, event, bytes);
> +       restore_gd();
> +
> +       return ret;
> +}
> +
> +static enum hab_status hab_rvt_report_status(enum hab_config *config,
> +    enum hab_state *state)
> +{
> +       enum hab_status ret;
> +       hab_rvt_report_status_t *hab_rvt_report_status_func;
> +
> +       hab_rvt_report_status_func =
> +                       (hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS;
> +
> +#if defined(CONFIG_ARM64)
> +       if (current_el() != 3) {
> +               /* call sip */
> +               ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB,
> +                   FSL_SIP_HAB_REPORT_STATUS, (unsigned long)config,
> +                   (unsigned long)state, 0);
> +               return ret;
> +       }
> +#endif
> +
> +       save_gd();
> +       ret = hab_rvt_report_status_func(config, state);
> +       restore_gd();
> +
> +       return ret;
> +}
> +
>  static int get_hab_status(void)
>  {
>         uint32_t index = 0; /* Loop index */
> @@ -252,12 +405,6 @@ static int get_hab_status(void)
>         size_t bytes = sizeof(event_data); /* Event size in bytes */
>         enum hab_config config = 0;
>         enum hab_state state = 0;
> -       hab_rvt_report_event_t *hab_rvt_report_event;
> -       hab_rvt_report_status_t *hab_rvt_report_status;
> -
> -       hab_rvt_report_event = (hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT;
> -       hab_rvt_report_status =
> -                       (hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS;
>
>         if (imx_hab_is_enabled())
>                 puts("\nSecure boot enabled\n");
> @@ -349,6 +496,7 @@ static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc,
>         return rcode;
>  }
>
> +#ifdef HAB_RVT_FAILSAFE
>  static int do_hab_failsafe(cmd_tbl_t *cmdtp, int flag, int argc,
>                            char * const argv[])
>  {
> @@ -389,6 +537,7 @@ static int do_authenticate_image_or_failover(cmd_tbl_t *cmdtp, int flag,
>  error:
>         return ret;
>  }
> +#endif
>
>  U_BOOT_CMD(
>                 hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
> @@ -405,6 +554,7 @@ U_BOOT_CMD(
>                 "ivt_offset - hex offset of IVT in the image"
>           );
>
> +#ifdef HAB_RVT_FAILSAFE
>  U_BOOT_CMD(
>                 hab_failsafe, CONFIG_SYS_MAXARGS, 1, do_hab_failsafe,
>                 "run BootROM failsafe routine",
> @@ -420,6 +570,7 @@ U_BOOT_CMD(
>                 "length - image hex length\n"
>                 "ivt_offset - hex offset of IVT in the image"
>           );
> +#endif
>
>  #endif /* !defined(CONFIG_SPL_BUILD) */
>
> @@ -471,7 +622,7 @@ static bool csf_is_valid(struct ivt *ivt, ulong start_addr, size_t bytes)
>                 return false;
>         }
>
> -       csf_hdr = (u8 *)ivt->csf;
> +       csf_hdr = (u8 *)(ulong)ivt->csf;
>
>         /* Verify if CSF Header exist */
>         if (*csf_hdr != HAB_CMD_HDR) {
> @@ -539,24 +690,19 @@ bool imx_hab_is_enabled(void)
>  int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
>                                uint32_t ivt_offset)
>  {
> -       uint32_t load_addr = 0;
> +       ulong load_addr = 0;
>         size_t bytes;
> -       uint32_t ivt_addr = 0;
> +       ulong ivt_addr = 0;
>         int result = 1;
>         ulong start;
> -       hab_rvt_authenticate_image_t *hab_rvt_authenticate_image;
> -       hab_rvt_entry_t *hab_rvt_entry;
> -       hab_rvt_exit_t *hab_rvt_exit;
> -       hab_rvt_check_target_t *hab_rvt_check_target;
>         struct ivt *ivt;
>         struct ivt_header *ivt_hdr;
> +#ifdef HAB_RVT_CHECK_TARGET
> +       hab_rvt_check_target_t *hab_rvt_check_target;
>         enum hab_status status;
>
> -       hab_rvt_authenticate_image =
> -               (hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE;
> -       hab_rvt_entry = (hab_rvt_entry_t *)HAB_RVT_ENTRY;
> -       hab_rvt_exit = (hab_rvt_exit_t *)HAB_RVT_EXIT;
>         hab_rvt_check_target = (hab_rvt_check_target_t *)HAB_RVT_CHECK_TARGET;
> +#endif
>
>         if (!imx_hab_is_enabled()) {
>                 puts("hab fuse not enabled\n");
> @@ -579,8 +725,8 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
>
>         /* Verify IVT body */
>         if (ivt->self != ivt_addr) {
> -               printf("ivt->self 0x%08x pointer is 0x%08x\n",
> -                      ivt->self, ivt_addr);
> +               printf("ivt->self 0x%08x pointer is 0x%08lx\n",
> +                      ivt->self, (ulong)ivt_addr);
>                 goto hab_authentication_exit;
>         }
>
> @@ -602,12 +748,14 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
>                 goto hab_exit_failure_print_status;
>         }
>
> +#ifdef HAB_RVT_CHECK_TARGET
>         status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)ddr_start, bytes);
>         if (status != HAB_SUCCESS) {
>                 printf("HAB check target 0x%08x-0x%08x fail\n",
>                        ddr_start, ddr_start + bytes);
>                 goto hab_exit_failure_print_status;
>         }
> +#endif
>  #ifdef DEBUG
>         printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr);
>         printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry,
> @@ -627,6 +775,8 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
>         printf("\tstart = 0x%08lx\n", start);
>         printf("\tbytes = 0x%x\n", bytes);
>  #endif
> +
> +#ifndef CONFIG_ARM64
>         /*
>          * If the MMU is enabled, we have to notify the ROM
>          * code, or it won't flush the caches when needed.
> @@ -654,8 +804,9 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
>                         writel(1, MX6SL_PU_IROM_MMU_EN_VAR);
>                 }
>         }
> +#endif
>
> -       load_addr = (uint32_t)hab_rvt_authenticate_image(
> +       load_addr = (ulong)hab_rvt_authenticate_image(
>                         HAB_CID_UBOOT,
>                         ivt_offset, (void **)&start,
>                         (size_t *)&bytes, NULL);
> diff --git a/arch/arm/mach-imx/imx8m/clock.c b/arch/arm/mach-imx/imx8m/clock.c
> index 289b9417aa..232219f2f6 100644
> --- a/arch/arm/mach-imx/imx8m/clock.c
> +++ b/arch/arm/mach-imx/imx8m/clock.c
> @@ -304,6 +304,13 @@ static u32 get_root_clk(enum clk_root_index clock_id)
>         return root_src_clk / (post_podf + 1) / (pre_podf + 1);
>  }
>
> +#ifdef CONFIG_SECURE_BOOT
> +void hab_caam_clock_enable(unsigned char enable)
> +{
> +       /* The CAAM clock is always on for iMX8M */
> +}
> +#endif
> +
>  #ifdef CONFIG_MXC_OCOTP
>  void enable_ocotp_clk(unsigned char enable)
>  {
> diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c
> index 18d7e6819c..3d9422d5a2 100644
> --- a/arch/arm/mach-imx/imx_bootaux.c
> +++ b/arch/arm/mach-imx/imx_bootaux.c
> @@ -26,7 +26,7 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data)
>
>         /* Enable M4 */
>  #ifdef CONFIG_IMX8M
> -       call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0);
> +       call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, 0);
>  #else
>         clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET,
>                         SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK);
> @@ -38,7 +38,7 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data)
>  int arch_auxiliary_core_check_up(u32 core_id)
>  {
>  #ifdef CONFIG_IMX8M
> -       return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0);
> +       return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, 0);
>  #else
>         unsigned int val;
>
> diff --git a/arch/arm/mach-imx/sip.c b/arch/arm/mach-imx/sip.c
> index 968e7cf309..fca520c671 100644
> --- a/arch/arm/mach-imx/sip.c
> +++ b/arch/arm/mach-imx/sip.c
> @@ -7,7 +7,8 @@
>  #include <asm/arch/sys_proto.h>
>
>  unsigned long call_imx_sip(unsigned long id, unsigned long reg0,
> -                          unsigned long reg1, unsigned long reg2)
> +                          unsigned long reg1, unsigned long reg2,
> +                          unsigned long reg3)
>  {
>         struct pt_regs regs;
>
> @@ -15,6 +16,7 @@ unsigned long call_imx_sip(unsigned long id, unsigned long reg0,
>         regs.regs[1] = reg0;
>         regs.regs[2] = reg1;
>         regs.regs[3] = reg2;
> +       regs.regs[4] = reg3;
>
>         smc_call(&regs);
>
> diff --git a/configs/imx8mq_evk_defconfig b/configs/imx8mq_evk_defconfig
> index e45731edda..d5f6cdf1ca 100644
> --- a/configs/imx8mq_evk_defconfig
> +++ b/configs/imx8mq_evk_defconfig
> @@ -1,4 +1,5 @@
>  CONFIG_ARM=y
> +CONFIG_SECURE_BOOT=y
>  CONFIG_SPL_SYS_ICACHE_OFF=y
>  CONFIG_SPL_SYS_DCACHE_OFF=y
>  CONFIG_ARCH_IMX8M=y
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list