From: Anatolij Gustschin <ag...@denx.de>

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 <ag...@denx.de>
Signed-off-by: Lukasz Majewski <lu...@denx.de>

---

Changes in v2:
- Move XEA's env adjustments to xea.env file (from include/configs/xea.h)

 board/liebherr/xea/boot_img_scr.h | 27 ++++++++++
 board/liebherr/xea/xea.c          | 85 +++++++++++++++++++++++++++++++
 2 files changed, 112 insertions(+)
 create mode 100644 board/liebherr/xea/boot_img_scr.h

diff --git a/board/liebherr/xea/boot_img_scr.h 
b/board/liebherr/xea/boot_img_scr.h
new file mode 100644
index 0000000000..baa3072b49
--- /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 e4d2eb65cc..c8ac526cb4 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 @@ void board_init_f(ulong arg)
        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 @@ void spl_board_init(void)
        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;
-- 
2.39.2

Reply via email to