[U-Boot] [PATCH v2] rpi4: fix dram bank initialization
Jian-Hong Pan
jian-hong at endlessm.com
Thu Nov 7 08:32:35 UTC 2019
Raspberry Pi's memory address & size cells are defined in FDT's root
node.
/ {
memreserve = <0x3b400000 0x04c00000>;
serial-number = "10000000d659c597";
compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
model = "Raspberry Pi 4 Model B Rev 1.1";
interrupt-parent = <0x00000001>;
#address-cells = <0x00000002>;
#size-cells = <0x00000001>;
...
memory at 0 {
device_type = "memory";
reg = <0x00000000 0x00000000 0x3b400000 0x00000000 0x40000000 0xbc000000>;
};
...
};
So, original fdtdec_decode_ram_size() having the cells in memory node
will get wrong size cells which misleads memory's reg parsing and have
wrong memory banks.
This patch provides new decode_ram_size() to parse the memory's reg in
FDT for Raspberry Pi 4.
Fixes: commit 9de5b89e4c89 ("rpi4: enable dram bank initialization")
Signed-off-by: Jian-Hong Pan <jian-hong at endlessm.com>
---
v2:
- Add FDT memory related information into commit message
- Add memory reg array's length constraint to prevent memory overflow
copying into bi_dram
board/raspberrypi/rpi/rpi.c | 64 +++++++++++++++++++++++++++++++++++--
1 file changed, 62 insertions(+), 2 deletions(-)
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 9e0abdda31..3307690108 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -314,10 +314,70 @@ int dram_init(void)
#ifdef CONFIG_OF_BOARD
#ifdef CONFIG_BCM2711
+static int decode_ram_size(const void *blob, phys_size_t *sizep, bd_t *bd)
+{
+ int addr_cells, size_cells;
+ u64 total_size, size, addr;
+ const u32 *cell, *end;
+ int node;
+ int bank;
+ int len;
+
+ /* Raspberry Pi's address and size cells are defined in root node */
+ addr_cells = fdt_address_cells(blob, 0);
+ size_cells = fdt_size_cells(blob, 0);
+
+ node = fdt_path_offset(blob, "/memory");
+ if (node < 0) {
+ debug("No /memory node found\n");
+ return -ENOENT;
+ }
+
+ cell = fdt_getprop(blob, node, "reg", &len);
+ if (!cell) {
+ debug("No reg property found\n");
+ return -ENOENT;
+ }
+
+ if (bd) {
+ memset(bd->bi_dram, '\0', sizeof(bd->bi_dram[0]) *
+ CONFIG_NR_DRAM_BANKS);
+ }
+
+ total_size = 0;
+ end = cell + len / sizeof(*cell) - addr_cells - size_cells;
+ for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
+ if (cell > end)
+ break;
+
+ addr = 0;
+ if (addr_cells == 2)
+ addr += (u64)fdt32_to_cpu(*cell++) << 32UL;
+ addr += fdt32_to_cpu(*cell++);
+ if (bd)
+ bd->bi_dram[bank].start = addr;
+
+ size = 0;
+ if (size_cells == 2)
+ size += (u64)fdt32_to_cpu(*cell++) << 32UL;
+ size += fdt32_to_cpu(*cell++);
+ if (bd)
+ bd->bi_dram[bank].size = size;
+
+ total_size += size;
+ }
+
+ debug("Memory size %llu\n", total_size);
+ if (sizep)
+ *sizep = (phys_size_t)total_size;
+
+ return 0;
+}
+
int dram_init_banksize(void)
{
- return fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL,
- (phys_size_t *)&gd->ram_size, gd->bd);
+ return decode_ram_size(gd->fdt_blob, (phys_size_t *)&gd->ram_size,
+ gd->bd);
}
#endif
#endif
--
2.23.0
More information about the U-Boot
mailing list