From: Guodong Xu <[email protected]>

When DRAM size exceeds 4GB, it may be split into two separate banks,
leaving an address hole between them.

To properly handle this configuration, LMB regions must be calculated
individually for each memory bank. Additionally, all address
calculations should support 64-bit to accommodate large memory ranges.

Signed-off-by: Guodong Xu <[email protected]>
Signed-off-by: Raymond Mao <[email protected]>
---
 cmd/meminfo.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/cmd/meminfo.c b/cmd/meminfo.c
index 537ef2a0e13..c5cf01f62ef 100644
--- a/cmd/meminfo.c
+++ b/cmd/meminfo.c
@@ -31,31 +31,53 @@ static void print_region(const char *name, phys_addr_t 
base, phys_addr_t size,
               (unsigned long long)base,
               (unsigned long long)size,
               (unsigned long long)end);
-       if (*uptop)
+       if (*uptop > end)
                printf(" %13llx", (unsigned long long)(*uptop - end));
+       else
+               printf(" %13llx", (unsigned long long)(end - end));
        putc('\n');
        *uptop = base;
 }
 
 static void show_lmb(const struct lmb *lmb, phys_addr_t *uptop)
 {
-       int i;
+       int i, j;
+       phys_addr_t bank_top[CONFIG_NR_DRAM_BANKS];
+       struct bd_info *bd = gd->bd;
+       bool get_bank;
+
+       for (j = 0; j < CONFIG_NR_DRAM_BANKS; j++)
+               bank_top[j] = bd->bi_dram[j].start + bd->bi_dram[j].size;
 
        for (i = lmb->used_mem.count - 1; i >= 0; i--) {
                const struct lmb_region *rgn = alist_get(&lmb->used_mem, i,
                                                         struct lmb_region);
 
+               for (j = 0, get_bank = false; j < CONFIG_NR_DRAM_BANKS; j++) {
+                       if (rgn->base >= bd->bi_dram[j].start &&
+                           rgn->base < bank_top[j]) {
+                               get_bank = true;
+                               break;
+                       }
+               }
+               if (!get_bank) {
+                       log_err("The region (base:0x%llx, size:0x%llx) does not 
exists in any DRAM bank.\n",
+                               (unsigned long long)rgn->base, (unsigned long 
long)rgn->size);
+                       return;
+               }
                /*
                 * Assume that the top lmb region is the U-Boot region, so just
                 * take account of the memory not already reported
                 */
                if (lmb->used_mem.count - 1)
-                       print_region("lmb", rgn->base, *uptop - rgn->base,
-                                    uptop);
+                       print_region("lmb", rgn->base, bank_top[j] - rgn->base,
+                                    &bank_top[j]);
                else
-                       print_region("lmb", rgn->base, rgn->size, uptop);
-               *uptop = rgn->base;
+                       print_region("lmb", rgn->base, rgn->size, &bank_top[j]);
+               bank_top[j] = rgn->base;
        }
+
+       *uptop = bank_top[0];
 }
 
 static int do_meminfo(struct cmd_tbl *cmdtp, int flag, int argc,
-- 
2.25.1

Reply via email to