]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
lmb: Optionally limit available memory to 4 GiB on limited systems
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Wed, 3 Jun 2026 14:17:55 +0000 (16:17 +0200)
committerTom Rini <trini@konsulko.com>
Thu, 4 Jun 2026 14:26:41 +0000 (08:26 -0600)
Some architectures can not DMA above 4 GiB boundary,
limit available memory to memory below 4 GiB boundary.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Tested-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> #rpi4 8GiB
lib/Kconfig
lib/lmb.c

index 77ebc79e1db54da4a775c32b28e9ef8cf8a047fe..29911068a69c9da6b5bca4fe63b6cfdbb7762e7f 100644 (file)
@@ -1295,6 +1295,14 @@ config SPL_LMB_ARCH_MEM_MAP
          memory map. Enable this config in such scenarios which allow
          architectures and boards to define their own memory map.
 
+config LMB_LIMIT_DMA_BELOW_4G
+       bool
+       depends on LMB
+       default y if ARCH_BCM283X
+       help
+         Some architectures can not DMA above 4 GiB boundary,
+         limit available memory to memory below 4 GiB boundary.
+
 config PHANDLE_CHECK_SEQ
        bool "Enable phandle check while getting sequence number"
        help
index 8f12c6ad8e595c39ab061fb27a4c4f2f55f23198..a2aeb526e299156a146fb9c36f95b4a439d11873 100644 (file)
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -611,6 +611,7 @@ static __maybe_unused void lmb_reserve_common_spl(void)
 static void lmb_add_memory(void)
 {
        int i;
+       phys_addr_t bank_end;
        phys_size_t size;
        u64 ram_top = gd->ram_top;
        struct bd_info *bd = gd->bd;
@@ -625,8 +626,25 @@ static void lmb_add_memory(void)
        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
                size = bd->bi_dram[i].size;
 
-               if (size)
+               if (size) {
                        lmb_add(bd->bi_dram[i].start, size);
+                       if (!IS_ENABLED(CONFIG_LMB_LIMIT_DMA_BELOW_4G))
+                               continue;
+
+                       bank_end = bd->bi_dram[i].start + size;
+
+                       /*
+                        * Reserve memory above ram_top as
+                        * no-overwrite so that it cannot be
+                        * allocated
+                        */
+                       if (bd->bi_dram[i].start >= ram_top)
+                               lmb_reserve(bd->bi_dram[i].start, size,
+                                           LMB_NOOVERWRITE);
+                       else if (bank_end > ram_top)
+                               lmb_reserve(ram_top, bank_end - ram_top,
+                                           LMB_NOOVERWRITE);
+               }
        }
 }