[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