|
37 | 37 |
|
38 | 38 | #define MAX_DISP_MAPPINGS 8 |
39 | 39 |
|
| 40 | +#define MAX_MEM_REGIONS 32 |
| 41 | + |
40 | 42 | static void *dt = NULL; |
41 | 43 | static int dt_bufsize = 0; |
42 | 44 | static void *initrd_start = NULL; |
@@ -330,13 +332,72 @@ static int dt_set_memory(void) |
330 | 332 | printf("FDT: DRAM at 0x%lx size 0x%lx\n", dram_base, dram_size); |
331 | 333 | printf("FDT: Usable memory is 0x%lx..0x%lx (0x%lx)\n", dram_min, dram_max, dram_max - dram_min); |
332 | 334 |
|
333 | | - u64 memreg[2] = {cpu_to_fdt64(dram_min), cpu_to_fdt64(dram_max - dram_min)}; |
| 335 | + struct { |
| 336 | + fdt64_t start; |
| 337 | + fdt64_t size; |
| 338 | + } memreg[MAX_MEM_REGIONS] = {{cpu_to_fdt64(dram_min), cpu_to_fdt64(dram_max - dram_min)}}; |
| 339 | + int num_regions = 1; |
| 340 | + |
| 341 | + int resv_node = fdt_path_offset(dt, "/reserved-memory"); |
| 342 | + if (resv_node < 0) |
| 343 | + bail("FDT: '/reserved-memory' not found\n"); |
| 344 | + |
| 345 | + int node; |
| 346 | + /* Find all reserved memory nodes */ |
| 347 | + fdt_for_each_subnode(node, dt, resv_node) |
| 348 | + { |
| 349 | + const char *name = fdt_get_name(dt, node, NULL); |
| 350 | + const char *status = fdt_getprop(dt, node, "status", NULL); |
| 351 | + if (status && !strcmp(status, "disabled")) |
| 352 | + continue; |
| 353 | + |
| 354 | + if (fdt_getprop(dt, node, "no-map", NULL)) |
| 355 | + continue; |
| 356 | + |
| 357 | + const fdt64_t *reg = fdt_getprop(dt, node, "reg", NULL); |
| 358 | + if (!reg) |
| 359 | + continue; |
| 360 | + |
| 361 | + u64 resv_start = fdt64_to_cpu(reg[0]); |
| 362 | + u64 resv_len = fdt64_to_cpu(reg[1]); |
| 363 | + u64 resv_end = resv_start + resv_len; |
| 364 | + |
| 365 | + if (resv_start < dram_min) { |
| 366 | + if (resv_end > dram_min) { |
| 367 | + bail("FDT: reserved-memory node %s intersects start of RAM (%lx..%lx %lx..%lx)\n", |
| 368 | + name, resv_start, resv_end, dram_min, dram_max); |
| 369 | + } |
| 370 | + } else if (resv_end > dram_max) { |
| 371 | + if (resv_start < dram_max) { |
| 372 | + bail("FDT: reserved-memory node %s intersects end of RAM (%lx..%lx %lx..%lx)\n", |
| 373 | + name, resv_start, resv_end, dram_min, dram_max); |
| 374 | + } |
| 375 | + } else { |
| 376 | + continue; |
| 377 | + } |
| 378 | + |
| 379 | + if ((resv_start | resv_len) & (SZ_16K - 1)) { |
| 380 | + bail("FDT: reserved-memory node %s not page-aligned, ignoring (%lx..%lx)\n", name, |
| 381 | + resv_start, resv_end); |
| 382 | + continue; |
| 383 | + } |
| 384 | + |
| 385 | + printf("FDT: Adding reserved-memory node %s (%lx..%lx) to RAM map\n", name, resv_start, |
| 386 | + resv_end); |
| 387 | + |
| 388 | + if (num_regions >= MAX_MEM_REGIONS) { |
| 389 | + bail("FDT: Out of memory regions for reserved-memory\n"); |
| 390 | + } |
| 391 | + |
| 392 | + memreg[num_regions].start = cpu_to_fdt64(resv_start); |
| 393 | + memreg[num_regions++].size = cpu_to_fdt64(resv_len); |
| 394 | + } |
334 | 395 |
|
335 | | - int node = fdt_path_offset(dt, "/memory"); |
| 396 | + node = fdt_path_offset(dt, "/memory"); |
336 | 397 | if (node < 0) |
337 | 398 | bail("FDT: /memory node not found in devtree\n"); |
338 | 399 |
|
339 | | - if (fdt_setprop(dt, node, "reg", memreg, sizeof(memreg))) |
| 400 | + if (fdt_setprop(dt, node, "reg", memreg, sizeof(memreg[0]) * num_regions)) |
340 | 401 | bail("FDT: couldn't set memory.reg property\n"); |
341 | 402 |
|
342 | 403 | return 0; |
|
0 commit comments