arm: xea: Add support for boot image source descriptor in SPL
We load two boot image source descriptor structures from last
two sectors in the SPI NOR flash and determine the boot source
for loading the kernel/DTB images, then adjust the boot order for
loading image from eMMC boot0 or boot1 partition.
Signed-off-by: Anatolij Gustschin <agust@denx.de>
Signed-off-by: Lukasz Majewski <lukma@denx.de>
diff --git a/board/liebherr/xea/boot_img_scr.h b/board/liebherr/xea/boot_img_scr.h
new file mode 100644
index 0000000..baa3072
--- /dev/null
+++ b/board/liebherr/xea/boot_img_scr.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Struct for boot image source description for placing in last
+ * two SPI NOR flash sectors on legcom.
+ */
+
+struct boot_img_src {
+ u8 magic; /* Must be 'B' = 0x42 */
+ u8 flags; /* flags to specify mmcblk[0|1] boot[0|1] */
+ u8 crc8; /* CRC-8 over above two bytes */
+} __packed;
+
+/*
+ * Bit definition in boot_img_src.flags:
+ * Bit 0: mmcblk device 0 or 1 (1 - if this bit set)
+ * Bit 1: mmcblk boot partition 0 or 1.
+ * for eMMC: boot0 if this bit is cleared, boot1 - if set
+ * for SD-card the boot partition value will always be 0
+ * (independent of the value of this bit)
+ *
+ */
+#define BOOT_SRC_MMC1 BIT(0)
+#define BOOT_SRC_PART1 BIT(1)
+
+/* Offset of the first boot image source descriptor in SPI NOR */
+#define SPI_FLASH_BOOT_SRC_OFFS 0xFE0000
+#define SPI_FLASH_SECTOR_SIZE 0x10000
diff --git a/board/liebherr/xea/xea.c b/board/liebherr/xea/xea.c
index e4d2eb6..c8ac526 100644
--- a/board/liebherr/xea/xea.c
+++ b/board/liebherr/xea/xea.c
@@ -32,6 +32,11 @@
#include <errno.h>
#include <usb.h>
#include <serial.h>
+#include <u-boot/crc.h>
+#include "boot_img_scr.h"
+
+#include <spi.h>
+#include <spi_flash.h>
#ifdef CONFIG_SPL_BUILD
#include <spl.h>
@@ -66,6 +71,52 @@
preloader_console_init();
}
+static struct boot_img_src img_src[2];
+static int spi_load_boot_info(void)
+{
+ struct spi_flash *flash;
+ int err;
+
+ flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+ CONFIG_SF_DEFAULT_CS,
+ CONFIG_SF_DEFAULT_SPEED,
+ CONFIG_SF_DEFAULT_MODE);
+ if (!flash) {
+ printf("%s: SPI probe err\n", __func__);
+ return -ENODEV;
+ }
+
+ /*
+ * Load both boot info structs from SPI flash
+ */
+ err = spi_flash_read(flash, SPI_FLASH_BOOT_SRC_OFFS,
+ sizeof(img_src[0]),
+ (void *)&img_src[0]);
+ if (err) {
+ debug("%s: First boot info NOR sector read error %d\n",
+ __func__, err);
+ return err;
+ }
+
+ err = spi_flash_read(flash,
+ SPI_FLASH_BOOT_SRC_OFFS + SPI_FLASH_SECTOR_SIZE,
+ sizeof(img_src[0]),
+ (void *)&img_src[1]);
+ if (err) {
+ debug("%s: First boot info NOR sector read error %d\n",
+ __func__, err);
+ return err;
+ }
+
+ debug("%s: BI0 0x%x 0x%x 0x%x\n", __func__,
+ img_src[0].magic, img_src[0].flags, img_src[0].crc8);
+
+ debug("%s: BI1 0x%x 0x%x 0x%x\n", __func__,
+ img_src[1].magic, img_src[1].flags, img_src[1].crc8);
+
+ return 0;
+}
+
static int boot_tiva0, boot_tiva1;
/* Check if TIVAs request booting via U-Boot proper */
@@ -114,6 +165,40 @@
boot_tiva1 = dm_gpio_get_value(&btiva1);
}
+int spl_mmc_emmc_boot_partition(struct mmc *mmc)
+{
+ int i, src_idx = -1, ret;
+
+ ret = spi_load_boot_info();
+ if (ret) {
+ printf("%s: Cannot read XEA boot info! [%d]\n", __func__, ret);
+ /* To avoid bricking board - by default boot from boot0 eMMC */
+ return 1;
+ }
+
+ for (i = 0; i < 2; i++) {
+ if (img_src[i].magic == 'B' &&
+ img_src[i].crc8 == crc8(0, &img_src[i].magic, 2)) {
+ src_idx = i;
+ break;
+ }
+ }
+
+ debug("%s: src idx: %d\n", __func__, src_idx);
+
+ if (src_idx < 0)
+ /*
+ * Always use eMMC (mmcblkX) boot0 if no
+ * valid image source description found
+ */
+ return 1;
+
+ if (img_src[src_idx].flags & BOOT_SRC_PART1)
+ return 2;
+
+ return 1;
+}
+
void board_boot_order(u32 *spl_boot_list)
{
spl_boot_list[0] = BOOT_DEVICE_MMC1;