
Hi Patrick,
On Thu, Oct 3, 2019 at 10:01 AM Patrick Wildt patrick@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(®s);
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@lists.denx.de https://lists.denx.de/listinfo/u-boot