Skip to content

Commit a96d565

Browse files
Marek Vasuttrini
Marek Vasut
authored andcommitted
image: fdt: Fix DT relocation handling with multiple DRAM banks with gap
The current implementation of boot_relocate_fdt() places DT at the highest usable DRAM address, which is calculated as: env_get_bootm_low() + env_get_bootm_mapsize() which by default becomes gd->ram_base + gd->ram_size. Systems like i.MX53 can have multiple DRAM banks with gap between them, e.g. have DRAM at 0x70000000-0x8fffffff and 0xb0000000-0xcfffffff , so for them the calculated highest DRAM address is 0xafffffff, which is exactly in the gap and thus not usable. Fix this by iterating over all DRAM banks and tracking the remaining amount of the total mapping size obtained from env_get_bootm_mapsize(). Limit the maximum LMB area size to each bank, to avoid using nonexistent DRAM. Reviewed-by: Simon Glass <[email protected]> Signed-off-by: Marek Vasut <[email protected]> Cc: Heinrich Schuchardt <[email protected]> Cc: Simon Glass <[email protected]> Cc: Tom Rini <[email protected]>
1 parent 4448d0c commit a96d565

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

boot/image-fdt.c

+36-4
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,11 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
165165
{
166166
void *fdt_blob = *of_flat_tree;
167167
void *of_start = NULL;
168+
u64 start, size, usable;
168169
char *fdt_high;
170+
ulong mapsize, low;
169171
ulong of_len = 0;
172+
int bank;
170173
int err;
171174
int disable_relocation = 0;
172175

@@ -206,10 +209,39 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
206209
(void *)(ulong) lmb_alloc(lmb, of_len, 0x1000);
207210
}
208211
} else {
209-
of_start =
210-
(void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
211-
env_get_bootm_mapsize()
212-
+ env_get_bootm_low());
212+
mapsize = env_get_bootm_mapsize();
213+
low = env_get_bootm_low();
214+
of_start = NULL;
215+
216+
for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
217+
start = gd->bd->bi_dram[bank].start;
218+
size = gd->bd->bi_dram[bank].size;
219+
220+
/* DRAM bank addresses are too low, skip it. */
221+
if (start + size < low)
222+
continue;
223+
224+
usable = min(size, (u64)mapsize);
225+
226+
/*
227+
* At least part of this DRAM bank is usable, try
228+
* using it for LMB allocation.
229+
*/
230+
of_start =
231+
(void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
232+
start + usable);
233+
/* Allocation succeeded, use this block. */
234+
if (of_start != NULL)
235+
break;
236+
237+
/*
238+
* Reduce the mapping size in the next bank
239+
* by the size of attempt in current bank.
240+
*/
241+
mapsize -= usable - max(start, (u64)low);
242+
if (!mapsize)
243+
break;
244+
}
213245
}
214246

215247
if (of_start == NULL) {

0 commit comments

Comments
 (0)