[PATCH 0/5] sunxi: enable automatic eMMC boot partition support

39 views
Skip to first unread message

Andre Przywara

unread,
Nov 8, 2020, 8:14:25 AM11/8/20
to Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, Tom Rini, linux...@googlegroups.com, u-b...@lists.denx.de
The eMMC standard describes the concept of boot partitions, consisting
of two storage areas separate from the main user data partition.
The Allwinner BootROM supports loading SPL/Boot0 from such a boot
partition, if that is configured in the eMMC device [1].

To load U-Boot proper along with the SPL from there, currently this
requires to enable CONFIG_SUPPORT_EMMC_BOOT, and this means that this
build won't boot from the normal eMMC user partition anymore.
Also the raw MMC sector offset needs to be adjusted manually, preventing
a boot from an SD card.

This series introduces automatic detection of eMMC boot partition boot.
Patch 3/5 automates the raw MMC sector offset decision, allowing such
a build to also boot from an SD card.
Unfortunately the BootROM does not mark an eMMC boot partition boot
differently from the normal eMMC user data partition boot, so patch 4/5
introduces a function that repeats the BootROM algorithm, so that the SPL
comes to the same conclusion as the BootROM. This allows to build one
single image that boots from everywhere: eMMC user data, eMMC boot,
SD card, SPI flash.
Patch 1/5 contains a bugfix that's needed in a later patch, patch 2/5
extends the generic spl_mmc_boot_mode() interface to make 4/5 feasible.

Without enabling CONFIG_SUPPORT_EMMC_BOOT, the AArch64 SPL grows by
92 bytes, ARMv7 grows by 36 bytes. With enabling the feature, the size
goes up by 444 bytes (AArch64) and 260 bytes (ARMv7).
Even for AArch64 this is still 4.5 KB below the SPL limit, so patch 5/5
enables this new mechanism for some boards I could test this on.

Please have a look and test this if you have a board with eMMC.
I put installation instructions into the linux-sunxi Wiki:
http://linux-sunxi.org/Bootable_eMMC

Cheers,
Andre

[1] http://linux-sunxi.org/Bootable_eMMC#The_BROM_implementation_details

Andre Przywara (5):
sunxi: Fix is_boot0_magic macro
spl: mmc: extend spl_mmc_boot_mode() to take mmc argument
sunxi: Simplify eMMC boot partition booting
sunxi: eMMC: Add automatic boot detection
sunxi: defconfig: enable eMMC boot partition support

arch/arm/include/asm/arch-sunxi/spl.h | 2 +-
arch/arm/mach-imx/spl.c | 2 +-
arch/arm/mach-k3/am6_init.c | 2 +-
arch/arm/mach-k3/j721e_init.c | 2 +-
arch/arm/mach-omap2/boot-common.c | 2 +-
arch/arm/mach-rockchip/spl.c | 2 +-
arch/arm/mach-socfpga/spl_a10.c | 2 +-
arch/arm/mach-socfpga/spl_agilex.c | 2 +-
arch/arm/mach-socfpga/spl_gen5.c | 2 +-
arch/arm/mach-socfpga/spl_s10.c | 2 +-
arch/arm/mach-stm32mp/spl.c | 2 +-
arch/arm/mach-sunxi/board.c | 94 +++++++++++++++++++++-
arch/arm/mach-uniphier/mmc-boot-mode.c | 5 +-
common/spl/spl_mmc.c | 4 +-
configs/bananapi_m64_defconfig | 1 +
configs/emlid_neutis_n5_devboard_defconfig | 1 +
configs/pine64-lts_defconfig | 1 +
configs/pine_h64_defconfig | 1 +
include/spl.h | 3 +-
19 files changed, 113 insertions(+), 19 deletions(-)

--
2.17.5

Andre Przywara

unread,
Nov 8, 2020, 8:14:26 AM11/8/20
to Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, Tom Rini, linux...@googlegroups.com, u-b...@lists.denx.de, Andre Przywara
The is_boot0_magic macro is missing parentheses around the macro
argument, breaking any usage with a more complex argument.

Signed-off-by: Andre Przywara <andre.p...@arm.com>
---
arch/arm/include/asm/arch-sunxi/spl.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index 8c916e8c752..6b3566f55e5 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -83,7 +83,7 @@ struct boot_file_head {
/* Compile time check to assure proper alignment of structure */
typedef char boot_file_head_not_multiple_of_32[1 - 2*(sizeof(struct boot_file_head) % 32)];

-#define is_boot0_magic(addr) (memcmp((void *)addr, BOOT0_MAGIC, 8) == 0)
+#define is_boot0_magic(addr) (memcmp((void *)(addr), BOOT0_MAGIC, 8) == 0)

uint32_t sunxi_get_boot_device(void);

--
2.17.5

Andre Przywara

unread,
Nov 8, 2020, 8:14:29 AM11/8/20
to Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, Tom Rini, linux...@googlegroups.com, u-b...@lists.denx.de, Stefano Babic, Fabio Estevam, NXP i . MX U-Boot Team, Lokesh Vutla, Philipp Tomsich, Kever Yang, Marek Vasut, Simon Goldschmidt, Ley Foon Tan, Patrick Delaunay, Patrice Chotard, Andre Przywara
Platforms can overwrite the weak definition of spl_mmc_boot_mode() to
determine where to load U-Boot proper from.
For most of them this is a trivial decision based on Kconfig variables,
but it might be desirable the probe the actual device to answer this
question.

Pass the pointer to the mmc struct to that function, so implementations
can make use of them.

Compile-tested for all users changed.

Cc: Stefano Babic <sba...@denx.de>
Cc: Fabio Estevam <fest...@gmail.com>
Cc: NXP i.MX U-Boot Team <uboo...@nxp.com>
Cc: Lokesh Vutla <lokes...@ti.com>
Cc: Philipp Tomsich <philipp...@theobroma-systems.com>
Cc: Kever Yang <kever...@rock-chips.com>
Cc: Marek Vasut <ma...@denx.de>
Cc: Simon Goldschmidt <simon.k.r....@gmail.com>
Cc: Ley Foon Tan <ley.fo...@intel.com>
Cc: Patrick Delaunay <patrick....@st.com>
Cc: Patrice Chotard <patrice...@st.com>
Signed-off-by: Andre Przywara <andre.p...@arm.com>
---
arch/arm/mach-imx/spl.c | 2 +-
arch/arm/mach-k3/am6_init.c | 2 +-
arch/arm/mach-k3/j721e_init.c | 2 +-
arch/arm/mach-omap2/boot-common.c | 2 +-
arch/arm/mach-rockchip/spl.c | 2 +-
arch/arm/mach-socfpga/spl_a10.c | 2 +-
arch/arm/mach-socfpga/spl_agilex.c | 2 +-
arch/arm/mach-socfpga/spl_gen5.c | 2 +-
arch/arm/mach-socfpga/spl_s10.c | 2 +-
arch/arm/mach-stm32mp/spl.c | 2 +-
arch/arm/mach-uniphier/mmc-boot-mode.c | 5 +----
common/spl/spl_mmc.c | 4 ++--
include/spl.h | 3 ++-
13 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c
index aa2686bb921..2cfedccfaf2 100644
--- a/arch/arm/mach-imx/spl.c
+++ b/arch/arm/mach-imx/spl.c
@@ -197,7 +197,7 @@ int g_dnl_get_board_bcd_device_number(int gcnum)

#if defined(CONFIG_SPL_MMC_SUPPORT)
/* called from spl_mmc to see type of boot mode for storage (RAW or FAT) */
-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
#if defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || defined(CONFIG_IMX8)
switch (get_boot_device()) {
diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c
index 603834e5078..55328757a64 100644
--- a/arch/arm/mach-k3/am6_init.c
+++ b/arch/arm/mach-k3/am6_init.c
@@ -252,7 +252,7 @@ void board_init_f(ulong dummy)
spl_enable_dcache();
}

-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
#if defined(CONFIG_SUPPORT_EMMC_BOOT)
u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT);
diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c
index a36e4ed603b..97818a0be6d 100644
--- a/arch/arm/mach-k3/j721e_init.c
+++ b/arch/arm/mach-k3/j721e_init.c
@@ -220,7 +220,7 @@ void board_init_f(ulong dummy)
spl_enable_dcache();
}

-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
switch (boot_device) {
case BOOT_DEVICE_MMC1:
diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c
index cb9d7fdb156..b65827668de 100644
--- a/arch/arm/mach-omap2/boot-common.c
+++ b/arch/arm/mach-omap2/boot-common.c
@@ -188,7 +188,7 @@ u32 spl_boot_device(void)
return gd->arch.omap_boot_device;
}

-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
return gd->arch.omap_boot_mode;
}
diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c
index f148d48b6a3..24c5f385e19 100644
--- a/arch/arm/mach-rockchip/spl.c
+++ b/arch/arm/mach-rockchip/spl.c
@@ -64,7 +64,7 @@ u32 spl_boot_device(void)
return boot_device;
}

-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
return MMCSD_MODE_RAW;
}
diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c
index 45aea4ab6cc..618ca898dd7 100644
--- a/arch/arm/mach-socfpga/spl_a10.c
+++ b/arch/arm/mach-socfpga/spl_a10.c
@@ -93,7 +93,7 @@ u32 spl_boot_device(void)
}

#ifdef CONFIG_SPL_MMC_SUPPORT
-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
return MMCSD_MODE_FS;
diff --git a/arch/arm/mach-socfpga/spl_agilex.c b/arch/arm/mach-socfpga/spl_agilex.c
index 78b5d7c8d98..fe4253b8e65 100644
--- a/arch/arm/mach-socfpga/spl_agilex.c
+++ b/arch/arm/mach-socfpga/spl_agilex.c
@@ -30,7 +30,7 @@ u32 spl_boot_device(void)
}

#ifdef CONFIG_SPL_MMC_SUPPORT
-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
return MMCSD_MODE_FS;
diff --git a/arch/arm/mach-socfpga/spl_gen5.c b/arch/arm/mach-socfpga/spl_gen5.c
index 5a7c5ef76d5..e526470aa15 100644
--- a/arch/arm/mach-socfpga/spl_gen5.c
+++ b/arch/arm/mach-socfpga/spl_gen5.c
@@ -52,7 +52,7 @@ u32 spl_boot_device(void)
}

#ifdef CONFIG_SPL_MMC_SUPPORT
-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
return MMCSD_MODE_FS;
diff --git a/arch/arm/mach-socfpga/spl_s10.c b/arch/arm/mach-socfpga/spl_s10.c
index daed05653ad..732c6f6d648 100644
--- a/arch/arm/mach-socfpga/spl_s10.c
+++ b/arch/arm/mach-socfpga/spl_s10.c
@@ -32,7 +32,7 @@ u32 spl_boot_device(void)
}

#ifdef CONFIG_SPL_MMC_SUPPORT
-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
return MMCSD_MODE_FS;
diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c
index b679b0a6454..85d394b55da 100644
--- a/arch/arm/mach-stm32mp/spl.c
+++ b/arch/arm/mach-stm32mp/spl.c
@@ -50,7 +50,7 @@ u32 spl_boot_device(void)
return BOOT_DEVICE_MMC1;
}

-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
return MMCSD_MODE_RAW;
}
diff --git a/arch/arm/mach-uniphier/mmc-boot-mode.c b/arch/arm/mach-uniphier/mmc-boot-mode.c
index e47e5df6480..09cad743c55 100644
--- a/arch/arm/mach-uniphier/mmc-boot-mode.c
+++ b/arch/arm/mach-uniphier/mmc-boot-mode.c
@@ -7,10 +7,8 @@
#include <mmc.h>
#include <spl.h>

-u32 spl_mmc_boot_mode(const u32 boot_device)
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
- struct mmc *mmc;
-
/*
* work around a bug in the Boot ROM of LD4, Pro4, and sLD8:
*
@@ -24,7 +22,6 @@ u32 spl_mmc_boot_mode(const u32 boot_device)
* Fixup mmc->part_config here because it is used to determine the
* partition which the U-Boot image is read from.
*/
- mmc = find_mmc_device(0);
mmc->part_config &= ~EXT_CSD_BOOT_PART_NUM(PART_ACCESS_MASK);
mmc->part_config |= EXT_CSD_BOOT_PARTITION_ENABLE;

diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index add2785b4e3..309abaf961a 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -300,7 +300,7 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
}
#endif

-u32 __weak spl_mmc_boot_mode(const u32 boot_device)
+u32 __weak spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
return MMCSD_MODE_FS;
@@ -351,7 +351,7 @@ int spl_mmc_load(struct spl_image_info *spl_image,
}
}

- boot_mode = spl_mmc_boot_mode(bootdev->boot_device);
+ boot_mode = spl_mmc_boot_mode(mmc, bootdev->boot_device);
err = -EINVAL;
switch (boot_mode) {
case MMCSD_MODE_EMMCBOOT:
diff --git a/include/spl.h b/include/spl.h
index b72dfc7e3d4..d3b960ccffe 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -14,6 +14,7 @@
#include <asm/global_data.h>
#include <asm/spl.h>
#include <handoff.h>
+#include <mmc.h>

struct blk_desc;
struct image_header;
@@ -271,7 +272,7 @@ u32 spl_boot_device(void);
* Note: It is important to use the boot_device parameter instead of e.g.
* spl_boot_device() as U-Boot is not always loaded from the same device as SPL.
*/
-u32 spl_mmc_boot_mode(const u32 boot_device);
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device);

/**
* spl_mmc_boot_partition() - MMC partition to load U-Boot from.
--
2.17.5

Andre Przywara

unread,
Nov 8, 2020, 8:14:32 AM11/8/20
to Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, Tom Rini, linux...@googlegroups.com, u-b...@lists.denx.de, Andre Przywara
When the Allwinner BROM loads the SPL from an eMMC boot partition, it
sets the boot source byte to the same value as when booting from the
user data partition. This prevents us from easily determining the boot
source to load U-Boot proper from the proper partition.

To learn about the boot source anyway, we repeat the algorithm the BROM
used to select the boot partition in the first place:
- Test EXT_CSD[179] to check if an eMMC boot partition is enabled.
- Test EXT_CSD[177] to check for valid MMC interface settings.
- Check if BOOT_ACK is enabled.
- Check the beginning of the first sector for a valid eGON signature.
- Load the whole SPL (limited to be at most 32KB).
- Recalculate the checksum to verify the SPL is valid.

If one of those steps fails, we bail out and continue loading from the
user data partition. Otherwise we load from the selected boot partition,
automatically adjusting the sector offset accordingly.

Since the boot source is needed twice in the boot process, we cache the
result of this test to avoid doing this costly test multiple times.

This allows the very same image file to be put onto an SD card, into the
eMMC user data partition or into the eMMC boot partition.
CONFIG_SUPPORT_EMMC_BOOT needs still to be enabled to activate this
feature, but it does not force booting from the eMMC boot partition
anymore.

Signed-off-by: Andre Przywara <andre.p...@arm.com>
---
arch/arm/mach-sunxi/board.c | 86 ++++++++++++++++++++++++++++++++++++-
1 file changed, 85 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 586af24535d..a141f24acdd 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -291,7 +291,7 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc)

switch (sunxi_get_boot_source()) {
case SUNXI_BOOTED_FROM_MMC2:
- if (IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT))
+ if (spl_mmc_boot_mode(mmc, 1) == MMCSD_MODE_EMMCBOOT)
sector -= 8 * 2;
break;
case SUNXI_BOOTED_FROM_MMC0_HIGH:
@@ -310,6 +310,90 @@ u32 spl_boot_device(void)
return sunxi_get_boot_device();
}

+/*
+ * When booting from an eMMC boot partition, the SPL puts the same boot
+ * source code into SRAM A1 as when loading the SPL from the normal
+ * eMMC user data partition: 0x2. So to know where we have been loaded
+ * from, we repeat the BROM algorithm here: checking for a valid eGON boot
+ * image at offset 0 of a (potentially) selected boot partition.
+ * If any of the conditions is not met, it must have been the eMMC user
+ * data partition.
+ */
+static bool sunxi_valid_emmc_boot(struct mmc *mmc)
+{
+ struct blk_desc *bd = mmc_get_blk_desc(mmc);
+ uint32_t *buffer = (void *)(uintptr_t)CONFIG_SYS_TEXT_BASE;
+ int bootpart = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
+ uint32_t spl_size, emmc_checksum, chksum = 0;
+ ulong count;
+
+ /* The BROM requires BOOT_ACK to be enabled. */
+ if (!EXT_CSD_EXTRACT_BOOT_ACK(mmc->part_config))
+ return false;
+
+ /*
+ * The BOOT_BUS_CONDITION register must be 4-bit SDR, with (0x09)
+ * or without (0x01) high speed timings.
+ */
+ if ((mmc->ext_csd[EXT_CSD_BOOT_BUS_WIDTH] & 0x1b) != 0x01 &&
+ (mmc->ext_csd[EXT_CSD_BOOT_BUS_WIDTH] & 0x1b) != 0x09)
+ return false;
+
+ /* Partition 0 is the user data partition, bootpart must be 1 or 2. */
+ if (bootpart != 1 && bootpart != 2)
+ return false;
+
+ mmc_switch_part(mmc, bootpart);
+
+ /* Read the first block to do some sanity checks on the eGON header. */
+ count = blk_dread(bd, 0, 1, buffer);
+ if (count != 1 || !is_boot0_magic(buffer + 1))
+ return false;
+
+ /* The BROM will only read up to 32KB into SRAM A1. */
+ spl_size = buffer[4];
+ if ((spl_size & 3) || spl_size > 32768)
+ return false;
+
+ /* Read the rest of the SPL now we know it's halfway sane. */
+ count = blk_dread(bd, 1, DIV_ROUND_UP(spl_size, bd->blksz) - 1,
+ buffer + bd->blksz / 4);
+
+ /* Save the checksum and replace it with the "stamp value". */
+ emmc_checksum = buffer[3];
+ buffer[3] = 0x5f0a6c39;
+
+ /* The checksum is a simple ignore-carry addition of all words. */
+ for (count = 0; count < spl_size / 4; count++)
+ chksum += buffer[count];
+
+ debug("eMMC boot part SPL checksum: stored: 0x%08x, computed: 0x%08x\n",
+ emmc_checksum, chksum);
+
+ return emmc_checksum == chksum;
+}
+
+u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
+{
+ static u32 result = ~0;
+
+ if (result != ~0)
+ return result;
+
+ result = MMCSD_MODE_RAW;
+ if (!IS_SD(mmc) && IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT)) {
+ if (sunxi_valid_emmc_boot(mmc))
+ result = MMCSD_MODE_EMMCBOOT;
+ else
+ mmc_switch_part(mmc, 0);
+ }
+
+ debug("%s(): %s part\n", __func__,
+ result == MMCSD_MODE_RAW ? "user" : "boot");
+
+ return result;
+}
+
void board_init_f(ulong dummy)
{
spl_init();
--
2.17.5

Andre Przywara

unread,
Nov 8, 2020, 8:14:32 AM11/8/20
to Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, Tom Rini, linux...@googlegroups.com, u-b...@lists.denx.de, Andre Przywara
The Allwinner BROM also supports loading the SPL from the eMMC boot
partition, for this we have to set the CONFIG_SUPPORT_EMMC_BOOT Kconfig
symbol. But on top of that a user has to manually adjust the raw sector
to load U-Boot proper from: CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR.

To simplify this, we adjust the sector offset dynamically, whenever we
find CONFIG_SUPPORT_EMMC_BOOT enabled and are booting from the eMMC.

Unfortunately the BROM sets the same boot source code as for the boot
from the normal eMMC user data partition, so we can't tell those two
cases apart easily (yet).

Signed-off-by: Andre Przywara <andre.p...@arm.com>
---
arch/arm/mach-sunxi/board.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index f40fccd8f8b..586af24535d 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -279,21 +279,29 @@ uint32_t sunxi_get_boot_device(void)
#ifdef CONFIG_SPL_BUILD
/*
* The eGON SPL image can be located at 8KB or at 128KB into an SD card or
- * an eMMC device. The boot source has bit 4 set in the latter case.
+ * an eMMC user partition. The boot source has bit 4 set in the latter case.
* By adding 120KB to the normal offset when booting from a "high" location
* we can support both cases.
+ * In an eMMC boot partition the SPL is located at offset 0, so we subtract
+ * the usual 8K offset.
*/
unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc)
{
unsigned long sector = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR;

switch (sunxi_get_boot_source()) {
+ case SUNXI_BOOTED_FROM_MMC2:
+ if (IS_ENABLED(CONFIG_SUPPORT_EMMC_BOOT))
+ sector -= 8 * 2;
+ break;
case SUNXI_BOOTED_FROM_MMC0_HIGH:
case SUNXI_BOOTED_FROM_MMC2_HIGH:
sector += (128 - 8) * 2;
break;
}

+ debug("loading U-Boot proper from sector 0x%lx\n", sector);
+
return sector;
}

--
2.17.5

Andre Przywara

unread,
Nov 8, 2020, 8:14:34 AM11/8/20
to Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, Tom Rini, linux...@googlegroups.com, u-b...@lists.denx.de, Andre Przywara
Now that the SPL can detect whether it was loaded from an eMMC boot
partition or the normal user data partition, let's enable this feature
on some boards that feature eMMC storage.

That covers the boards where I could test this on.

Signed-off-by: Andre Przywara <andre.p...@arm.com>
---
configs/bananapi_m64_defconfig | 1 +
configs/emlid_neutis_n5_devboard_defconfig | 1 +
configs/pine64-lts_defconfig | 1 +
configs/pine_h64_defconfig | 1 +
4 files changed, 4 insertions(+)

diff --git a/configs/bananapi_m64_defconfig b/configs/bananapi_m64_defconfig
index 802f9820d07..f28dd7771b7 100644
--- a/configs/bananapi_m64_defconfig
+++ b/configs/bananapi_m64_defconfig
@@ -5,6 +5,7 @@ CONFIG_MACH_SUN50I=y
CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
CONFIG_MMC0_CD_PIN="PH13"
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-bananapi-m64"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SUN8I_EMAC=y
diff --git a/configs/emlid_neutis_n5_devboard_defconfig b/configs/emlid_neutis_n5_devboard_defconfig
index 0e908c327b1..59062bf8bcc 100644
--- a/configs/emlid_neutis_n5_devboard_defconfig
+++ b/configs/emlid_neutis_n5_devboard_defconfig
@@ -6,5 +6,6 @@ CONFIG_DRAM_CLK=408
CONFIG_DRAM_ZQ=3881977
# CONFIG_DRAM_ODT_EN is not set
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-emlid-neutis-n5-devboard"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/pine64-lts_defconfig b/configs/pine64-lts_defconfig
index 048b31d73ce..24d479ce5d3 100644
--- a/configs/pine64-lts_defconfig
+++ b/configs/pine64-lts_defconfig
@@ -7,6 +7,7 @@ CONFIG_DRAM_CLK=552
CONFIG_DRAM_ZQ=3881949
CONFIG_MMC0_CD_PIN=""
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_SPL_SPI_SUNXI=y
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-pine64-lts"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/pine_h64_defconfig b/configs/pine_h64_defconfig
index 2fa66f38343..2cfa3df2ff4 100644
--- a/configs/pine_h64_defconfig
+++ b/configs/pine_h64_defconfig
@@ -6,6 +6,7 @@ CONFIG_SUNXI_DRAM_H6_LPDDR3=y
CONFIG_MACPWR="PC16"
CONFIG_MMC0_CD_PIN="PF6"
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_USB3_VBUS_PIN="PL5"
CONFIG_SPL_SPI_SUNXI=y
# CONFIG_PSCI_RESET is not set
--
2.17.5

Peter Robinson

unread,
Nov 8, 2020, 9:59:46 AM11/8/20
to Andre Przywara, Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, Tom Rini, linux...@googlegroups.com, u-b...@lists.denx.de
It would probably be good to put that link in the local Allwinner docs
so it's easier for people to find.

Peter

André Przywara

unread,
Nov 8, 2020, 10:48:34 AM11/8/20
to Peter Robinson, Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, Tom Rini, linux...@googlegroups.com, u-b...@lists.denx.de
On 08/11/2020 14:59, Peter Robinson wrote:

Hi,
Yeah, actually as you mention it:
There does not seem to be some generic README.sunxi file where this
would belong to.

Jagan: would it make sense to create one, and describe how to get U-Boot
into the devices (SD card, eMMC, SPI flash, FEL)? That could move some
parts of README.sunxi64 out of there, since they apply to all Allwinner
devices.

If people agree that this is the right thing to do, I would be happy to
send a patch.

Tom Rini

unread,
Nov 10, 2020, 7:38:47 AM11/10/20
to André Przywara, Peter Robinson, Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, linux...@googlegroups.com, u-b...@lists.denx.de
Well, rST file in doc/boards/ and all of that, but, yes please.

--
Tom
signature.asc

André Przywara

unread,
Nov 10, 2020, 7:57:17 AM11/10/20
to Tom Rini, Peter Robinson, Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, linux...@googlegroups.com, u-b...@lists.denx.de
On 10/11/2020 12:38, Tom Rini wrote:

Hi Tom,
Ah, thanks for the pointer, looks good.
Do we accept symlinks in the tree? There are quite some references to
board/sunxi/README.sunxi64 out there. Or shall I keep a stub instead?

Cheers,
Andre

Tom Rini

unread,
Nov 10, 2020, 8:08:23 AM11/10/20
to André Przywara, Peter Robinson, Jagan Teki, Petr Štetiar, Sunil Mohan Adapa, Samuel Holland, Aleksandr Aleksandrov, Icenowy Zheng, Simon Glass, linux...@googlegroups.com, u-b...@lists.denx.de
As there's external references to the README file, yes, please stub it
out pointing people to the new rST file. Thanks!

--
Tom
signature.asc
Reply all
Reply to author
Forward
0 new messages