summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/spl.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/spl.c')
-rw-r--r--arch/arm/mach-imx/spl.c72
1 files changed, 69 insertions, 3 deletions
diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c
index ea709d15a5..fe33a7b611 100644
--- a/arch/arm/mach-imx/spl.c
+++ b/arch/arm/mach-imx/spl.c
@@ -21,6 +21,8 @@
#include <g_dnl.h>
#include <linux/libfdt.h>
#include <mmc.h>
+#include <image.h>
+#include <asm/sections.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -148,7 +150,7 @@ u32 spl_boot_device(void)
return BOOT_DEVICE_NONE;
}
-#elif defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || defined(CONFIG_IMX8)
+#elif defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || defined(CONFIG_IMX8) || defined(CONFIG_IMX9)
/* Translate iMX7/i.MX8M boot device to the SPL boot device enumeration */
u32 spl_boot_device(void)
{
@@ -184,7 +186,7 @@ u32 spl_boot_device(void)
#ifdef CONFIG_SPL_USB_GADGET
int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
{
- put_unaligned(0x0151, &dev->idProduct);
+ put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM + 0xfff, &dev->idProduct);
return 0;
}
@@ -314,7 +316,10 @@ ulong board_spl_fit_size_align(ulong size)
*/
size = ALIGN(size, 0x1000);
- size += CONFIG_CSF_SIZE;
+ size += 2 * CONFIG_CSF_SIZE;
+
+ if (size > CONFIG_SYS_BOOTM_LEN)
+ panic("spl: ERROR: image too big\n");
return size;
}
@@ -347,6 +352,42 @@ int dram_init_banksize(void)
}
#endif
+#if IS_ENABLED(CONFIG_SPL_LOAD_FIT) && IS_ENABLED(CONFIG_IMX_HAB) && \
+ !IS_ENABLED(CONFIG_SPL_FIT_SIGNATURE)
+static int spl_verify_fit_hash(const void *fit)
+{
+ unsigned long size;
+ u8 value[SHA256_SUM_LEN];
+ int value_len;
+ ulong fit_hash;
+
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+ if (gd->fdt_blob && !fdt_check_header(gd->fdt_blob)) {
+ fit_hash = roundup((unsigned long)&_end +
+ fdt_totalsize(gd->fdt_blob), 4) + 0x18000;
+ }
+#else
+ fit_hash = (unsigned long)&_end + 0x18000;
+#endif
+
+ size = fdt_totalsize(fit);
+
+ if (calculate_hash(fit, size, "sha256", value, &value_len)) {
+ printf("Unsupported hash algorithm\n");
+ return -1;
+ }
+
+ if (value_len != SHA256_SUM_LEN) {
+ printf("Bad hash value len\n");
+ return -1;
+ } else if (memcmp(value, (const void *)fit_hash, value_len) != 0) {
+ printf("Bad hash value\n");
+ return -1;
+ }
+
+ return 0;
+}
+
/*
* read the address where the IVT header must sit
* from IVT image header, loaded from SPL into
@@ -361,6 +402,30 @@ void *spl_load_simple_fit_fix_load(const void *fit)
unsigned long size;
u8 *tmp = (u8 *)fit;
+ if (IS_ENABLED(CONFIG_IMX_HAB)) {
+ if (IS_ENABLED(CONFIG_IMX_SPL_FIT_FDT_SIGNATURE)) {
+ u32 offset = ALIGN(fdt_totalsize(fit), 0x1000);
+
+ if (imx_hab_authenticate_image((uintptr_t)fit,
+ offset + 2 * CSF_PAD_SIZE,
+ offset + CSF_PAD_SIZE)) {
+#ifdef CONFIG_ANDROID_SUPPORT
+ printf("spl: ERROR: FIT FDT authentication unsuccessful\n");
+ return NULL;
+#else
+ panic("spl: ERROR: FIT FDT authentication unsuccessful\n");
+#endif
+ }
+ } else {
+ int ret = spl_verify_fit_hash(fit);
+
+ if (ret && imx_hab_is_enabled())
+ panic("spl: ERROR: FIT hash verify unsuccessful\n");
+
+ debug("spl_verify_fit_hash %d\n", ret);
+ }
+ }
+
offset = ALIGN(fdt_totalsize(fit), 0x1000);
size = ALIGN(fdt_totalsize(fit), 4);
size = board_spl_fit_size_align(size);
@@ -379,6 +444,7 @@ void *spl_load_simple_fit_fix_load(const void *fit)
return (void *)new;
}
+#endif
#if defined(CONFIG_IMX8MP) || defined(CONFIG_IMX8MN)
int board_handle_rdc_config(void *fdt_addr, const char *config_name, void *dst_addr)