From: Pranav Sanwal <[email protected]>

Move DRAM bank detection from fdtdec to custom implementation to
ensure memory banks are populated before get_page_table_size() is
called during MMU initialization.

The current fdtdec-based approach populates gd->bd->bi_dram[] too
late in the boot sequence, causing get_page_table_size() to be
called with unpopulated DRAM information. This prevents dynamic
page table sizing based on actual memory configuration.

Parse /memory nodes in dram_init() to fill versal2_mem_map[]
early enough for MMU setup. Supports up to
CONFIG_NR_DRAM_BANKS (36) non-contiguous banks with high memory
regions (>4GB) and use __weak get_page_table_size implementation
to estimate page table size based on the populated DRAM banks.

Signed-off-by: Pranav Sanwal <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
---

 arch/arm/mach-versal2/cpu.c                   | 57 ++++++++++++---
 .../arm/mach-versal2/include/mach/sys_proto.h |  4 +-
 board/amd/versal2/board.c                     | 70 +++++++++++++++----
 include/dm/ofnode.h                           |  2 +
 4 files changed, 109 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-versal2/cpu.c b/arch/arm/mach-versal2/cpu.c
index 2dfcadb369eb..896ff958bc02 100644
--- a/arch/arm/mach-versal2/cpu.c
+++ b/arch/arm/mach-versal2/cpu.c
@@ -63,30 +63,71 @@ static struct mm_region 
versal2_mem_map[VERSAL2_MEM_MAP_MAX] = {
        }
 };
 
-void mem_map_fill(void)
+/**
+ * mem_map_fill() - Populate global memory map with DRAM banks
+ * @bank_info: Array of memory regions parsed from device tree
+ * @num_banks: Number of valid DRAM banks in bank_info array
+ *
+ * Copies DRAM bank information into the global versal2_mem_map[] array
+ * starting at index VERSAL2_MEM_MAP_USED (5), which is after the fixed
+ * device mappings. This must be called early in boot before MMU
+ * initialization so that get_page_table_size() can calculate the
+ * required page table size based on actual memory configuration.
+ */
+void mem_map_fill(struct mm_region *bank_info, u32 num_banks)
 {
        int banks = VERSAL2_MEM_MAP_USED;
 
-       for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
-               /* Zero size means no more DDR that's this is end */
-               if (!gd->bd->bi_dram[i].size)
-                       break;
+       for (int i = 0; i < num_banks; i++) {
+               if (banks > VERSAL2_MEM_MAP_MAX)
+                       return;
 
-               versal2_mem_map[banks].virt = gd->bd->bi_dram[i].start;
-               versal2_mem_map[banks].phys = gd->bd->bi_dram[i].start;
-               versal2_mem_map[banks].size = gd->bd->bi_dram[i].size;
+               versal2_mem_map[banks].virt = bank_info[i].phys;
+               versal2_mem_map[banks].phys = bank_info[i].phys;
+               versal2_mem_map[banks].size = bank_info[i].size;
                versal2_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
                                              PTE_BLOCK_INNER_SHARE;
                banks = banks + 1;
        }
 }
 
+/**
+ * fill_gd_mem_info() - Copy DRAM banks from mem_map to bd_info
+ *
+ * Transfers DRAM bank information from the global versal2_mem_map[]
+ * array to bd->bi_dram[] for passing memory configuration to the
+ * Linux kernel via boot parameters (ATAGS/FDT). Each bank's physical
+ * address and size are copied.
+ *
+ * This is called during dram_init_banksize() after the memory map
+ * has been populated by mem_map_fill() in dram_init().
+ *
+ * Context: Called after dram_init() but before kernel handoff
+ * Side effects: Modifies bd->bi_dram[] array
+ */
+void fill_bd_mem_info(void)
+{
+       struct bd_info *bd = gd->bd;
+       int banks = VERSAL2_MEM_MAP_USED;
+
+       for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+               if (!versal2_mem_map[banks].size)
+                       break;
+
+               bd->bi_dram[i].start = versal2_mem_map[banks].phys;
+               bd->bi_dram[i].size = versal2_mem_map[banks].size;
+               banks++;
+       }
+}
+
 struct mm_region *mem_map = versal2_mem_map;
 
+#if CONFIG_IS_ENABLED(SYS_MEM_RSVD_FOR_MMU)
 u64 get_page_table_size(void)
 {
        return 0x14000;
 }
+#endif
 
 U_BOOT_DRVINFO(soc_amd_versal2) = {
        .name = "soc_amd_versal2",
diff --git a/arch/arm/mach-versal2/include/mach/sys_proto.h 
b/arch/arm/mach-versal2/include/mach/sys_proto.h
index 7b1726a7ef40..cee134886208 100644
--- a/arch/arm/mach-versal2/include/mach/sys_proto.h
+++ b/arch/arm/mach-versal2/include/mach/sys_proto.h
@@ -5,5 +5,7 @@
  */
 
 #include <linux/build_bug.h>
+#include <asm/armv8/mmu.h>
 
-void mem_map_fill(void);
+void mem_map_fill(struct mm_region *bank_info, u32 num_banks);
+void fill_bd_mem_info(void);
diff --git a/board/amd/versal2/board.c b/board/amd/versal2/board.c
index 1fd05a1157ab..ba5900cc3d2e 100644
--- a/board/amd/versal2/board.c
+++ b/board/amd/versal2/board.c
@@ -18,6 +18,7 @@
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/sections.h>
 #include <dm/device.h>
 #include <dm/uclass.h>
 #include <versalpl.h>
@@ -27,6 +28,7 @@
 #include <linux/bitfield.h>
 #include <debug_uart.h>
 #include <generated/dt.h>
+#include <linux/ioport.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -361,28 +363,66 @@ int board_late_init(void)
 
 int dram_init_banksize(void)
 {
-       int ret;
-
-       ret = fdtdec_setup_memory_banksize();
-       if (ret)
-               return ret;
-
-       mem_map_fill();
-
+       fill_bd_mem_info();
        return 0;
 }
 
 int dram_init(void)
 {
-       int ret;
+       struct mm_region bank_info[CONFIG_NR_DRAM_BANKS];
+       ofnode mem = ofnode_null();
+       struct resource res;
+       int ret, i, reg = 0;
+       u32 num_banks = 0;
+       u64 text = (u64)_start;
+
+       gd->ram_base = (unsigned long)~0;
+
+       mem = get_next_memory_node(mem);
+       if (!ofnode_valid(mem)) {
+               printf("%s: Missing /memory node\n", __func__);
+               return -EINVAL;
+       }
 
-       if (IS_ENABLED(CONFIG_SYS_MEM_RSVD_FOR_MMU))
-               ret = fdtdec_setup_mem_size_base();
-       else
-               ret = fdtdec_setup_mem_size_base_lowest();
+       for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+               ret = ofnode_read_resource(mem, reg++, &res);
+               if (ret < 0) {
+                       reg = 0;
+                       mem = get_next_memory_node(mem);
+                       if (!ofnode_valid(mem))
+                               break;
+
+                       ret = ofnode_read_resource(mem, reg++, &res);
+                       if (ret < 0)
+                               break;
+               }
 
-       if (ret)
-               return -EINVAL;
+               if (ret != 0)
+                       return -EINVAL;
+
+               bank_info[i].phys = (phys_addr_t)res.start;
+               bank_info[i].size  = (phys_size_t)(res.end - res.start + 1);
+
+               if (bank_info[i].size == 0)
+                       break;
+
+               debug("%s: DRAM Bank #%d: start = 0x%llx, size = 0x%llx\n",
+                     __func__, i, (unsigned long long)bank_info[i].phys,
+                     (unsigned long long)bank_info[i].size);
+
+               if (text > bank_info[i].phys &&
+                   text < (bank_info[i].phys + bank_info[i].size)) {
+                       gd->ram_base = bank_info[i].phys;
+                       gd->ram_size = bank_info[i].size;
+                       debug("%s: Text base = 0x%llx\n", __func__, text);
+               }
+               num_banks++;
+       }
+
+       mem_map_fill(bank_info, num_banks);
+
+       debug("%s: Initial DRAM: start = 0x%lx, size = 0x%lx\n", __func__,
+             gd->ram_base, (unsigned long)gd->ram_size);
 
        return 0;
 }
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 120393426dbf..5be9513f5238 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -1886,4 +1886,6 @@ int ofnode_copy_node(ofnode dst_parent, const char *name, 
ofnode src,
  */
 int ofnode_delete(ofnode *nodep);
 
+ofnode get_next_memory_node(ofnode mem);
+
 #endif
-- 
2.43.0

base-commit: ed4a3618875869287b87b6b57fd55f4c6a36f046
branch: debian-sent3

Reply via email to