[Bug 269181] sysutils/u-boot-rpi-arm64: RPi4/8G fails to boot: "** Reading file would overwrite reserved memory **"

From: <bugzilla-noreply_at_freebsd.org>
Date: Sun, 05 Feb 2023 06:14:05 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=269181

--- Comment #2 from Mark Millard <marklmi26-fbsd@yahoo.com> ---
(In reply to Mark Millard from comment #1)

Well, that was not the problem. And the problem is not
specific to RPi*'s at all, through they are examples
of hitting the issue.

I give details of the actual problem later below, but
the issue can be worked around by providing a couple
of CONFIG_LMB_*'s in the fragments. Using the RPi*'s
as examples:

# git -C /usr/ports diff sysutils/u-boot-rpi*/files/*fragment | more
diff --git a/sysutils/u-boot-rpi-0-w/files/rpi_0_w_fragment
b/sysutils/u-boot-rpi-0-w/files/rpi_0_w_fragment
index 56ca46fe5f31..7274e7a5f219 100644
--- a/sysutils/u-boot-rpi-0-w/files/rpi_0_w_fragment
+++ b/sysutils/u-boot-rpi-0-w/files/rpi_0_w_fragment
@@ -1,3 +1,5 @@
 CONFIG_OF_EMBED=n
 CONFIG_OF_BOARD=y
 CONFIG_API=y
+CONFIG_LMB_USE_MAX_REGIONS=y
+CONFIG_LMB_MAX_REGIONS=64
diff --git a/sysutils/u-boot-rpi-arm64/files/rpi_arm64_fragment
b/sysutils/u-boot-rpi-arm64/files/rpi_arm64_fragment
index 7a61bd18844a..8cc45d6fd3bc 100644
--- a/sysutils/u-boot-rpi-arm64/files/rpi_arm64_fragment
+++ b/sysutils/u-boot-rpi-arm64/files/rpi_arm64_fragment
@@ -1,2 +1,4 @@
 CONFIG_ENV_FAT_DEVICE_AND_PART="1:1"
 CONFIG_RPI_EFI_NR_SPIN_PAGES=2
+CONFIG_LMB_USE_MAX_REGIONS=y
+CONFIG_LMB_MAX_REGIONS=64
diff --git a/sysutils/u-boot-rpi/files/rpi_fragment
b/sysutils/u-boot-rpi/files/rpi_fragment
index 56ca46fe5f31..7274e7a5f219 100644
--- a/sysutils/u-boot-rpi/files/rpi_fragment
+++ b/sysutils/u-boot-rpi/files/rpi_fragment
@@ -1,3 +1,5 @@
 CONFIG_OF_EMBED=n
 CONFIG_OF_BOARD=y
 CONFIG_API=y
+CONFIG_LMB_USE_MAX_REGIONS=y
+CONFIG_LMB_MAX_REGIONS=64
diff --git a/sysutils/u-boot-rpi2/files/rpi2_fragment
b/sysutils/u-boot-rpi2/files/rpi2_fragment
index e5849534639e..05ca226cd650 100644
--- a/sysutils/u-boot-rpi2/files/rpi2_fragment
+++ b/sysutils/u-boot-rpi2/files/rpi2_fragment
@@ -2,3 +2,5 @@ CONFIG_OF_EMBED=n
 CONFIG_OF_BOARD=y
 CONFIG_ARMV7_NONSEC=n
 CONFIG_EFI_GRUB_ARM32_WORKAROUND=y
+CONFIG_LMB_USE_MAX_REGIONS=y
+CONFIG_LMB_MAX_REGIONS=64
diff --git a/sysutils/u-boot-rpi3/files/rpi3_fragment
b/sysutils/u-boot-rpi3/files/rpi3_fragment
index 1dbf430f1931..dd8033f49d4e 100644
--- a/sysutils/u-boot-rpi3/files/rpi3_fragment
+++ b/sysutils/u-boot-rpi3/files/rpi3_fragment
@@ -2,3 +2,5 @@ CONFIG_OF_EMBED=n
 CONFIG_OF_BOARD=y
 CONFIG_ENV_FAT_DEVICE_AND_PART="1:1"
 CONFIG_RPI_EFI_NR_SPIN_PAGES=2
+CONFIG_LMB_USE_MAX_REGIONS=y
+CONFIG_LMB_MAX_REGIONS=64
diff --git a/sysutils/u-boot-rpi4/files/rpi4_fragment
b/sysutils/u-boot-rpi4/files/rpi4_fragment
index 7a61bd18844a..8cc45d6fd3bc 100644
--- a/sysutils/u-boot-rpi4/files/rpi4_fragment
+++ b/sysutils/u-boot-rpi4/files/rpi4_fragment
@@ -1,2 +1,4 @@
 CONFIG_ENV_FAT_DEVICE_AND_PART="1:1"
 CONFIG_RPI_EFI_NR_SPIN_PAGES=2
+CONFIG_LMB_USE_MAX_REGIONS=y
+CONFIG_LMB_MAX_REGIONS=64


What this does is avoid a case of lack of initialization
tied to lack of either of 2 types of CONFIG_LMB_* use.
The details are as follows.

lib/lmb.c has:

/* This routine called with relocation disabled. */
static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base,
phys_size_t size, enum lmb_flags flags)
{
. . .
        if (rgn->cnt >= rgn->max)
                return -1;

        /* Couldn't coalesce the LMB, so add it to the sorted table. */
. . .

This code expects rgn->max to always be well defined.
But note the lack of initialization of the 2 .max fields
for the implicit "#else" case in:

void lmb_init(struct lmb *lmb)
{
#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS)
        lmb->memory.max = CONFIG_LMB_MAX_REGIONS;
        lmb->reserved.max = CONFIG_LMB_MAX_REGIONS;
#elif defined(CONFIG_LMB_MEMORY_REGIONS)
        lmb->memory.max = CONFIG_LMB_MEMORY_REGIONS;
        lmb->reserved.max = CONFIG_LMB_RESERVED_REGIONS;
        lmb->memory.region = lmb->memory_regions;
        lmb->reserved.region = lmb->reserved_regions;
#endif
        lmb->memory.cnt = 0;
        lmb->reserved.cnt = 0;
}

I've not found other initialization of the 2 .max
fields. Presuming I got that right, then for the
combination:

  !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS)
&& !defined(CONFIG_LMB_MEMORY_REGIONS)

neither .max is initialized. Another possibility is that
there should be a #else leading to rejection of the
compile (combination invalid):

#else
#error . . .

(In that case CONFIG_LMB_* additions would need to
have landed in all the official U-Boot configs/*_defconfig
files at some point. Only a small subset of such in
2023.01 of U-Boot.)

There was a time when there was:

void lmb_init(struct lmb *lmb)
{
#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS)
        lmb->memory.max = CONFIG_LMB_MAX_REGIONS;
        lmb->reserved.max = CONFIG_LMB_MAX_REGIONS;
#else
        lmb->memory.max = CONFIG_LMB_MEMORY_REGIONS;
        lmb->reserved.max = CONFIG_LMB_RESERVED_REGIONS;
        lmb->memory.region = lmb->memory_regions;
        lmb->reserved.region = lmb->reserved_regions;
#endif
        lmb->memory.cnt = 0;
        lmb->reserved.cnt = 0;
}

That always provided an initialization of the 2 .max
fields if the code compiled. (In this form the
#error mentioned earlier would not be needed in
order to catch errors. But, as stands, most
configs/*_defconfig files would lead to build failure
for CONFIG_LMB_MEMORY_REGIONS and
CONFIG_LMB_RESERVED_REGIONS being undefined.)

-- 
You are receiving this mail because:
You are the assignee for the bug.