"Das U-Boot" Source Tree
at master 1908 lines 47 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2011 The Chromium OS Authors. 4 * 5 * NOTE: Please do not add new devicetree-reading functionality into this file. 6 * Add it to the ofnode API instead, since that is compatible with livetree. 7 */ 8 9#ifndef USE_HOSTCC 10 11#define LOG_CATEGORY LOGC_DT 12 13#include <bloblist.h> 14#include <boot_fit.h> 15#include <display_options.h> 16#include <dm.h> 17#include <hang.h> 18#include <init.h> 19#include <log.h> 20#include <malloc.h> 21#include <net.h> 22#include <spl.h> 23#include <env.h> 24#include <errno.h> 25#include <fdtdec.h> 26#include <fdt_support.h> 27#include <gzip.h> 28#include <mapmem.h> 29#include <linux/libfdt.h> 30#include <serial.h> 31#include <asm/global_data.h> 32#include <asm/sections.h> 33#include <dm/ofnode.h> 34#include <dm/of_extra.h> 35#include <linux/ctype.h> 36#include <linux/lzo.h> 37#include <linux/ioport.h> 38 39DECLARE_GLOBAL_DATA_PTR; 40 41/* 42 * Here are the type we know about. One day we might allow drivers to 43 * register. For now we just put them here. The COMPAT macro allows us to 44 * turn this into a sparse list later, and keeps the ID with the name. 45 * 46 * NOTE: This list is basically a TODO list for things that need to be 47 * converted to driver model. So don't add new things here unless there is a 48 * good reason why driver-model conversion is infeasible. Examples include 49 * things which are used before driver model is available. 50 */ 51#define COMPAT(id, name) name 52static const char * const compat_names[COMPAT_COUNT] = { 53 COMPAT(UNKNOWN, "<none>"), 54 COMPAT(NVIDIA_TEGRA20_EMC, "nvidia,tegra20-emc"), 55 COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"), 56 COMPAT(NVIDIA_TEGRA20_NAND, "nvidia,tegra20-nand"), 57 COMPAT(NVIDIA_TEGRA124_XUSB_PADCTL, "nvidia,tegra124-xusb-padctl"), 58 COMPAT(NVIDIA_TEGRA210_XUSB_PADCTL, "nvidia,tegra210-xusb-padctl"), 59 COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"), 60 COMPAT(SAMSUNG_EXYNOS5_USB3_PHY, "samsung,exynos5250-usb3-phy"), 61 COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"), 62 COMPAT(SAMSUNG_EXYNOS_MIPI_DSI, "samsung,exynos-mipi-dsi"), 63 COMPAT(SAMSUNG_EXYNOS_DWMMC, "samsung,exynos-dwmmc"), 64 COMPAT(GENERIC_SPI_FLASH, "jedec,spi-nor"), 65 COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"), 66 COMPAT(INTEL_MICROCODE, "intel,microcode"), 67 COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"), 68 COMPAT(ALTERA_SOCFPGA_DWMAC, "altr,socfpga-stmmac"), 69 COMPAT(ALTERA_SOCFPGA_DWMMC, "altr,socfpga-dw-mshc"), 70 COMPAT(ALTERA_SOCFPGA_DWC2USB, "snps,dwc2"), 71 COMPAT(INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"), 72 COMPAT(INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"), 73 COMPAT(INTEL_IVYBRIDGE_FSP, "intel,ivybridge-fsp"), 74 COMPAT(ALTERA_SOCFPGA_CLK, "altr,clk-mgr"), 75 COMPAT(ALTERA_SOCFPGA_PINCTRL_SINGLE, "pinctrl-single"), 76 COMPAT(ALTERA_SOCFPGA_H2F_BRG, "altr,socfpga-hps2fpga-bridge"), 77 COMPAT(ALTERA_SOCFPGA_LWH2F_BRG, "altr,socfpga-lwhps2fpga-bridge"), 78 COMPAT(ALTERA_SOCFPGA_F2H_BRG, "altr,socfpga-fpga2hps-bridge"), 79 COMPAT(ALTERA_SOCFPGA_F2SDR0, "altr,socfpga-fpga2sdram0-bridge"), 80 COMPAT(ALTERA_SOCFPGA_F2SDR1, "altr,socfpga-fpga2sdram1-bridge"), 81 COMPAT(ALTERA_SOCFPGA_F2SDR2, "altr,socfpga-fpga2sdram2-bridge"), 82 COMPAT(ALTERA_SOCFPGA_FPGA0, "altr,socfpga-a10-fpga-mgr"), 83 COMPAT(ALTERA_SOCFPGA_NOC, "altr,socfpga-a10-noc"), 84 COMPAT(ALTERA_SOCFPGA_CLK_INIT, "altr,socfpga-a10-clk-init") 85}; 86 87static const char *const fdt_src_name[] = { 88 [FDTSRC_SEPARATE] = "separate", 89 [FDTSRC_FIT] = "fit", 90 [FDTSRC_BOARD] = "board", 91 [FDTSRC_EMBED] = "embed", 92 [FDTSRC_ENV] = "env", 93 [FDTSRC_BLOBLIST] = "bloblist", 94}; 95 96extern u8 __dtb_dt_begin[]; /* embedded device tree blob */ 97extern u8 __dtb_dt_spl_begin[]; /* embedded device tree blob for SPL/TPL */ 98 99/* Get a pointer to the embedded devicetree, if there is one, else NULL */ 100static u8 *dtb_dt_embedded(void) 101{ 102 u8 *addr = NULL; 103 104 if (IS_ENABLED(CONFIG_OF_EMBED)) { 105 addr = __dtb_dt_begin; 106 107 if (IS_ENABLED(CONFIG_XPL_BUILD)) 108 addr = __dtb_dt_spl_begin; 109 } 110 return addr; 111} 112 113const char *fdtdec_get_srcname(void) 114{ 115 return fdt_src_name[gd->fdt_src]; 116} 117 118const char *fdtdec_get_compatible(enum fdt_compat_id id) 119{ 120 /* We allow reading of the 'unknown' ID for testing purposes */ 121 assert(id >= 0 && id < COMPAT_COUNT); 122 return compat_names[id]; 123} 124 125fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node, 126 const char *prop_name, int index, int na, 127 int ns, fdt_size_t *sizep, 128 bool translate) 129{ 130 const fdt32_t *prop, *prop_end; 131 const fdt32_t *prop_addr, *prop_size, *prop_after_size; 132 int len; 133 fdt_addr_t addr; 134 135 debug("%s: %s: ", __func__, prop_name); 136 137 prop = fdt_getprop(blob, node, prop_name, &len); 138 if (!prop) { 139 debug("(not found)\n"); 140 return FDT_ADDR_T_NONE; 141 } 142 prop_end = prop + (len / sizeof(*prop)); 143 144 prop_addr = prop + (index * (na + ns)); 145 prop_size = prop_addr + na; 146 prop_after_size = prop_size + ns; 147 if (prop_after_size > prop_end) { 148 debug("(not enough data: expected >= %d cells, got %d cells)\n", 149 (u32)(prop_after_size - prop), ((u32)(prop_end - prop))); 150 return FDT_ADDR_T_NONE; 151 } 152 153#if CONFIG_IS_ENABLED(OF_TRANSLATE) 154 if (translate) 155 addr = fdt_translate_address(blob, node, prop_addr); 156 else 157#endif 158 addr = fdtdec_get_number(prop_addr, na); 159 160 if (sizep) { 161 *sizep = fdtdec_get_number(prop_size, ns); 162 debug("addr=%08llx, size=%llx\n", (unsigned long long)addr, 163 (unsigned long long)*sizep); 164 } else { 165 debug("addr=%08llx\n", (unsigned long long)addr); 166 } 167 168 return addr; 169} 170 171fdt_addr_t fdtdec_get_addr_size_auto_parent(const void *blob, int parent, 172 int node, const char *prop_name, 173 int index, fdt_size_t *sizep, 174 bool translate) 175{ 176 int na, ns; 177 178 debug("%s: ", __func__); 179 180 na = fdt_address_cells(blob, parent); 181 if (na < 1) { 182 debug("(bad #address-cells)\n"); 183 return FDT_ADDR_T_NONE; 184 } 185 186 ns = fdt_size_cells(blob, parent); 187 if (ns < 0) { 188 debug("(bad #size-cells)\n"); 189 return FDT_ADDR_T_NONE; 190 } 191 192 debug("na=%d, ns=%d, ", na, ns); 193 194 return fdtdec_get_addr_size_fixed(blob, node, prop_name, index, na, 195 ns, sizep, translate); 196} 197 198fdt_addr_t fdtdec_get_addr_size_auto_noparent(const void *blob, int node, 199 const char *prop_name, int index, 200 fdt_size_t *sizep, 201 bool translate) 202{ 203 int parent; 204 205 debug("%s: ", __func__); 206 207 parent = fdt_parent_offset(blob, node); 208 if (parent < 0) { 209 debug("(no parent found)\n"); 210 return FDT_ADDR_T_NONE; 211 } 212 213 return fdtdec_get_addr_size_auto_parent(blob, parent, node, prop_name, 214 index, sizep, translate); 215} 216 217fdt_addr_t fdtdec_get_addr_size(const void *blob, int node, 218 const char *prop_name, fdt_size_t *sizep) 219{ 220 int ns = sizep ? (sizeof(fdt_size_t) / sizeof(fdt32_t)) : 0; 221 222 return fdtdec_get_addr_size_fixed(blob, node, prop_name, 0, 223 sizeof(fdt_addr_t) / sizeof(fdt32_t), 224 ns, sizep, false); 225} 226 227fdt_addr_t fdtdec_get_addr(const void *blob, int node, const char *prop_name) 228{ 229 return fdtdec_get_addr_size(blob, node, prop_name, NULL); 230} 231 232int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device) 233{ 234 const char *list, *end; 235 int len; 236 237 list = fdt_getprop(blob, node, "compatible", &len); 238 if (!list) 239 return -ENOENT; 240 241 end = list + len; 242 while (list < end) { 243 len = strlen(list); 244 if (len >= strlen("pciVVVV,DDDD")) { 245 char *s = strstr(list, "pci"); 246 247 /* 248 * check if the string is something like pciVVVV,DDDD.RR 249 * or just pciVVVV,DDDD 250 */ 251 if (s && s[7] == ',' && 252 (s[12] == '.' || s[12] == 0)) { 253 s += 3; 254 *vendor = simple_strtol(s, NULL, 16); 255 256 s += 5; 257 *device = simple_strtol(s, NULL, 16); 258 259 return 0; 260 } 261 } 262 list += (len + 1); 263 } 264 265 return -ENOENT; 266} 267 268int fdtdec_get_pci_bar32(const struct udevice *dev, struct fdt_pci_addr *addr, 269 u32 *bar) 270{ 271 int barnum; 272 273 /* extract the bar number from fdt_pci_addr */ 274 barnum = addr->phys_hi & 0xff; 275 if (barnum < PCI_BASE_ADDRESS_0 || barnum > PCI_CARDBUS_CIS) 276 return -EINVAL; 277 278 barnum = (barnum - PCI_BASE_ADDRESS_0) / 4; 279 280 *bar = dm_pci_read_bar32(dev, barnum); 281 282 return 0; 283} 284 285int fdtdec_get_pci_bus_range(const void *blob, int node, 286 struct fdt_resource *res) 287{ 288 const u32 *values; 289 int len; 290 291 values = fdt_getprop(blob, node, "bus-range", &len); 292 if (!values || len < sizeof(*values) * 2) 293 return -EINVAL; 294 295 res->start = fdt32_to_cpu(*values++); 296 res->end = fdt32_to_cpu(*values); 297 298 return 0; 299} 300 301uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name, 302 uint64_t default_val) 303{ 304 const unaligned_fdt64_t *cell64; 305 int length; 306 307 cell64 = fdt_getprop(blob, node, prop_name, &length); 308 if (!cell64 || length < sizeof(*cell64)) 309 return default_val; 310 311 return fdt64_to_cpu(*cell64); 312} 313 314int fdtdec_get_is_enabled(const void *blob, int node) 315{ 316 const char *cell; 317 318 /* 319 * It should say "okay", so only allow that. Some fdts use "ok" but 320 * this is a bug. Please fix your device tree source file. See here 321 * for discussion: 322 * 323 * http://www.mail-archive.com/u-boot@lists.denx.de/msg71598.html 324 */ 325 cell = fdt_getprop(blob, node, "status", NULL); 326 if (cell) 327 return strcmp(cell, "okay") == 0; 328 return 1; 329} 330 331enum fdt_compat_id fdtdec_lookup(const void *blob, int node) 332{ 333 enum fdt_compat_id id; 334 335 /* Search our drivers */ 336 for (id = COMPAT_UNKNOWN; id < COMPAT_COUNT; id++) 337 if (fdt_node_check_compatible(blob, node, 338 compat_names[id]) == 0) 339 return id; 340 return COMPAT_UNKNOWN; 341} 342 343int fdtdec_next_compatible(const void *blob, int node, enum fdt_compat_id id) 344{ 345 return fdt_node_offset_by_compatible(blob, node, compat_names[id]); 346} 347 348int fdtdec_next_compatible_subnode(const void *blob, int node, 349 enum fdt_compat_id id, int *depthp) 350{ 351 do { 352 node = fdt_next_node(blob, node, depthp); 353 } while (*depthp > 1); 354 355 /* If this is a direct subnode, and compatible, return it */ 356 if (*depthp == 1 && 0 == fdt_node_check_compatible( 357 blob, node, compat_names[id])) 358 return node; 359 360 return -FDT_ERR_NOTFOUND; 361} 362 363int fdtdec_next_alias(const void *blob, const char *name, enum fdt_compat_id id, 364 int *upto) 365{ 366#define MAX_STR_LEN 20 367 char str[MAX_STR_LEN + 20]; 368 int node, err; 369 370 /* snprintf() is not available */ 371 assert(strlen(name) < MAX_STR_LEN); 372 sprintf(str, "%.*s%d", MAX_STR_LEN, name, *upto); 373 node = fdt_path_offset(blob, str); 374 if (node < 0) 375 return node; 376 err = fdt_node_check_compatible(blob, node, compat_names[id]); 377 if (err < 0) 378 return err; 379 if (err) 380 return -FDT_ERR_NOTFOUND; 381 (*upto)++; 382 return node; 383} 384 385int fdtdec_find_aliases_for_id(const void *blob, const char *name, 386 enum fdt_compat_id id, int *node_list, 387 int maxcount) 388{ 389 memset(node_list, '\0', sizeof(*node_list) * maxcount); 390 391 return fdtdec_add_aliases_for_id(blob, name, id, node_list, maxcount); 392} 393 394/* TODO: Can we tighten this code up a little? */ 395int fdtdec_add_aliases_for_id(const void *blob, const char *name, 396 enum fdt_compat_id id, int *node_list, 397 int maxcount) 398{ 399 int name_len = strlen(name); 400 int nodes[maxcount]; 401 int num_found = 0; 402 int offset, node; 403 int alias_node; 404 int count; 405 int i, j; 406 407 /* find the alias node if present */ 408 alias_node = fdt_path_offset(blob, "/aliases"); 409 410 /* 411 * start with nothing, and we can assume that the root node can't 412 * match 413 */ 414 memset(nodes, '\0', sizeof(nodes)); 415 416 /* First find all the compatible nodes */ 417 for (node = count = 0; node >= 0 && count < maxcount;) { 418 node = fdtdec_next_compatible(blob, node, id); 419 if (node >= 0) 420 nodes[count++] = node; 421 } 422 if (node >= 0) 423 debug("%s: warning: maxcount exceeded with alias '%s'\n", 424 __func__, name); 425 426 /* Now find all the aliases */ 427 for (offset = fdt_first_property_offset(blob, alias_node); 428 offset > 0; 429 offset = fdt_next_property_offset(blob, offset)) { 430 const struct fdt_property *prop; 431 const char *path; 432 int number; 433 int found; 434 435 node = 0; 436 prop = fdt_get_property_by_offset(blob, offset, NULL); 437 path = fdt_string(blob, fdt32_to_cpu(prop->nameoff)); 438 if (prop->len && 0 == strncmp(path, name, name_len)) 439 node = fdt_path_offset(blob, prop->data); 440 if (node <= 0) 441 continue; 442 443 /* Get the alias number */ 444 number = dectoul(path + name_len, NULL); 445 if (number < 0 || number >= maxcount) { 446 debug("%s: warning: alias '%s' is out of range\n", 447 __func__, path); 448 continue; 449 } 450 451 /* Make sure the node we found is actually in our list! */ 452 found = -1; 453 for (j = 0; j < count; j++) 454 if (nodes[j] == node) { 455 found = j; 456 break; 457 } 458 459 if (found == -1) { 460 debug("%s: warning: alias '%s' points to a node " 461 "'%s' that is missing or is not compatible " 462 " with '%s'\n", __func__, path, 463 fdt_get_name(blob, node, NULL), 464 compat_names[id]); 465 continue; 466 } 467 468 /* 469 * Add this node to our list in the right place, and mark 470 * it as done. 471 */ 472 if (fdtdec_get_is_enabled(blob, node)) { 473 if (node_list[number]) { 474 debug("%s: warning: alias '%s' requires that " 475 "a node be placed in the list in a " 476 "position which is already filled by " 477 "node '%s'\n", __func__, path, 478 fdt_get_name(blob, node, NULL)); 479 continue; 480 } 481 node_list[number] = node; 482 if (number >= num_found) 483 num_found = number + 1; 484 } 485 nodes[found] = 0; 486 } 487 488 /* Add any nodes not mentioned by an alias */ 489 for (i = j = 0; i < maxcount; i++) { 490 if (!node_list[i]) { 491 for (; j < maxcount; j++) 492 if (nodes[j] && 493 fdtdec_get_is_enabled(blob, nodes[j])) 494 break; 495 496 /* Have we run out of nodes to add? */ 497 if (j == maxcount) 498 break; 499 500 assert(!node_list[i]); 501 node_list[i] = nodes[j++]; 502 if (i >= num_found) 503 num_found = i + 1; 504 } 505 } 506 507 return num_found; 508} 509 510int fdtdec_get_alias_seq(const void *blob, const char *base, int offset, 511 int *seqp) 512{ 513 int base_len = strlen(base); 514 const char *find_name; 515 int find_namelen; 516 int prop_offset; 517 int aliases; 518 519 find_name = fdt_get_name(blob, offset, &find_namelen); 520 debug("Looking for '%s' at %d, name %s\n", base, offset, find_name); 521 522 aliases = fdt_path_offset(blob, "/aliases"); 523 for (prop_offset = fdt_first_property_offset(blob, aliases); 524 prop_offset > 0; 525 prop_offset = fdt_next_property_offset(blob, prop_offset)) { 526 const char *prop; 527 const char *name; 528 const char *slash; 529 int len, val; 530 531 prop = fdt_getprop_by_offset(blob, prop_offset, &name, &len); 532 debug(" - %s, %s\n", name, prop); 533 if (len < find_namelen || *prop != '/' || prop[len - 1] || 534 strncmp(name, base, base_len)) 535 continue; 536 537 slash = strrchr(prop, '/'); 538 if (strcmp(slash + 1, find_name)) 539 continue; 540 541 /* 542 * Adding an extra check to distinguish DT nodes with 543 * same name 544 */ 545 if (IS_ENABLED(CONFIG_PHANDLE_CHECK_SEQ)) { 546 if (fdt_get_phandle(blob, offset) != 547 fdt_get_phandle(blob, fdt_path_offset(blob, prop))) 548 continue; 549 } 550 551 val = trailing_strtol(name); 552 if (val != -1) { 553 *seqp = val; 554 debug("Found seq %d\n", *seqp); 555 return 0; 556 } 557 } 558 559 debug("Not found\n"); 560 return -ENOENT; 561} 562 563int fdtdec_get_alias_highest_id(const void *blob, const char *base) 564{ 565 int base_len = strlen(base); 566 int prop_offset; 567 int aliases; 568 int max = -1; 569 570 debug("Looking for highest alias id for '%s'\n", base); 571 572 aliases = fdt_path_offset(blob, "/aliases"); 573 for (prop_offset = fdt_first_property_offset(blob, aliases); 574 prop_offset > 0; 575 prop_offset = fdt_next_property_offset(blob, prop_offset)) { 576 const char *prop; 577 const char *name; 578 int len, val; 579 580 prop = fdt_getprop_by_offset(blob, prop_offset, &name, &len); 581 debug(" - %s, %s\n", name, prop); 582 if (*prop != '/' || prop[len - 1] || 583 strncmp(name, base, base_len)) 584 continue; 585 586 val = trailing_strtol(name); 587 if (val > max) { 588 debug("Found seq %d\n", val); 589 max = val; 590 } 591 } 592 593 return max; 594} 595 596const char *fdtdec_get_chosen_prop(const void *blob, const char *name) 597{ 598 int chosen_node; 599 600 if (!blob) 601 return NULL; 602 chosen_node = fdt_path_offset(blob, "/chosen"); 603 return fdt_getprop(blob, chosen_node, name, NULL); 604} 605 606int fdtdec_get_chosen_node(const void *blob, const char *name) 607{ 608 const char *prop; 609 610 prop = fdtdec_get_chosen_prop(blob, name); 611 if (!prop) 612 return -FDT_ERR_NOTFOUND; 613 return fdt_path_offset(blob, prop); 614} 615 616/** 617 * fdtdec_prepare_fdt() - Check we have a valid fdt available to control U-Boot 618 * 619 * @blob: Blob to check 620 * 621 * If not, a message is printed to the console if the console is ready. 622 * 623 * Return: 0 if all ok, -ENOENT if not 624 */ 625static int fdtdec_prepare_fdt(const void *blob) 626{ 627 if (!blob || ((uintptr_t)blob & 3) || fdt_check_header(blob)) { 628 if (xpl_phase() <= PHASE_SPL) { 629 puts("Missing DTB\n"); 630 } else { 631 printf("No valid device tree binary found at %p\n", 632 blob); 633 if (_DEBUG && blob) { 634 printf("fdt_blob=%p\n", blob); 635 print_buffer((ulong)blob, blob, 4, 32, 0); 636 } 637 } 638 return -ENOENT; 639 } 640 641 return 0; 642} 643 644int fdtdec_check_fdt(void) 645{ 646 /* 647 * We must have an FDT, but we cannot panic() yet since the console 648 * is not ready. So for now, just assert(). Boards which need an early 649 * FDT (prior to console ready) will need to make their own 650 * arrangements and do their own checks. 651 */ 652 assert(!fdtdec_prepare_fdt(gd->fdt_blob)); 653 return 0; 654} 655 656int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name) 657{ 658 const u32 *phandle; 659 int lookup; 660 661 debug("%s: %s\n", __func__, prop_name); 662 phandle = fdt_getprop(blob, node, prop_name, NULL); 663 if (!phandle) 664 return -FDT_ERR_NOTFOUND; 665 666 lookup = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*phandle)); 667 return lookup; 668} 669 670/** 671 * Look up a property in a node and check that it has a minimum length. 672 * 673 * @param blob FDT blob 674 * @param node node to examine 675 * @param prop_name name of property to find 676 * @param min_len minimum property length in bytes 677 * @param err 0 if ok, or -FDT_ERR_NOTFOUND if the property is not 678 found, or -FDT_ERR_BADLAYOUT if not enough data 679 * Return: pointer to cell, which is only valid if err == 0 680 */ 681static const void *get_prop_check_min_len(const void *blob, int node, 682 const char *prop_name, int min_len, 683 int *err) 684{ 685 const void *cell; 686 int len; 687 688 debug("%s: %s\n", __func__, prop_name); 689 cell = fdt_getprop(blob, node, prop_name, &len); 690 if (!cell) 691 *err = -FDT_ERR_NOTFOUND; 692 else if (len < min_len) 693 *err = -FDT_ERR_BADLAYOUT; 694 else 695 *err = 0; 696 return cell; 697} 698 699int fdtdec_get_int_array(const void *blob, int node, const char *prop_name, 700 u32 *array, int count) 701{ 702 const u32 *cell; 703 int err = 0; 704 705 debug("%s: %s\n", __func__, prop_name); 706 cell = get_prop_check_min_len(blob, node, prop_name, 707 sizeof(u32) * count, &err); 708 if (!err) { 709 int i; 710 711 for (i = 0; i < count; i++) 712 array[i] = fdt32_to_cpu(cell[i]); 713 } 714 return err; 715} 716 717int fdtdec_get_int_array_count(const void *blob, int node, 718 const char *prop_name, u32 *array, int count) 719{ 720 const u32 *cell; 721 int len, elems; 722 int i; 723 724 debug("%s: %s\n", __func__, prop_name); 725 cell = fdt_getprop(blob, node, prop_name, &len); 726 if (!cell) 727 return -FDT_ERR_NOTFOUND; 728 elems = len / sizeof(u32); 729 if (count > elems) 730 count = elems; 731 for (i = 0; i < count; i++) 732 array[i] = fdt32_to_cpu(cell[i]); 733 734 return count; 735} 736 737const u32 *fdtdec_locate_array(const void *blob, int node, 738 const char *prop_name, int count) 739{ 740 const u32 *cell; 741 int err; 742 743 cell = get_prop_check_min_len(blob, node, prop_name, 744 sizeof(u32) * count, &err); 745 return err ? NULL : cell; 746} 747 748int fdtdec_get_bool(const void *blob, int node, const char *prop_name) 749{ 750 const s32 *cell; 751 int len; 752 753 debug("%s: %s\n", __func__, prop_name); 754 cell = fdt_getprop(blob, node, prop_name, &len); 755 return cell != NULL; 756} 757 758int fdtdec_parse_phandle_with_args(const void *blob, int src_node, 759 const char *list_name, 760 const char *cells_name, 761 int cell_count, int index, 762 struct fdtdec_phandle_args *out_args) 763{ 764 const __be32 *list, *list_end; 765 int rc = 0, size, cur_index = 0; 766 uint32_t count = 0; 767 int node = -1; 768 int phandle; 769 770 /* Retrieve the phandle list property */ 771 list = fdt_getprop(blob, src_node, list_name, &size); 772 if (!list) 773 return -ENOENT; 774 list_end = list + size / sizeof(*list); 775 776 /* Loop over the phandles until all the requested entry is found */ 777 while (list < list_end) { 778 rc = -EINVAL; 779 count = 0; 780 781 /* 782 * If phandle is 0, then it is an empty entry with no 783 * arguments. Skip forward to the next entry. 784 */ 785 phandle = be32_to_cpup(list++); 786 if (phandle) { 787 /* 788 * Find the provider node and parse the #*-cells 789 * property to determine the argument length. 790 * 791 * This is not needed if the cell count is hard-coded 792 * (i.e. cells_name not set, but cell_count is set), 793 * except when we're going to return the found node 794 * below. 795 */ 796 if (cells_name || cur_index == index) { 797 node = fdt_node_offset_by_phandle(blob, 798 phandle); 799 if (node < 0) { 800 debug("%s: could not find phandle\n", 801 fdt_get_name(blob, src_node, 802 NULL)); 803 goto err; 804 } 805 } 806 807 if (cells_name) { 808 count = fdtdec_get_int(blob, node, cells_name, 809 -1); 810 if (count == -1) { 811 debug("%s: could not get %s for %s\n", 812 fdt_get_name(blob, src_node, 813 NULL), 814 cells_name, 815 fdt_get_name(blob, node, 816 NULL)); 817 goto err; 818 } 819 } else { 820 count = cell_count; 821 } 822 823 /* 824 * Make sure that the arguments actually fit in the 825 * remaining property data length 826 */ 827 if (list + count > list_end) { 828 debug("%s: arguments longer than property\n", 829 fdt_get_name(blob, src_node, NULL)); 830 goto err; 831 } 832 } 833 834 /* 835 * All of the error cases above bail out of the loop, so at 836 * this point, the parsing is successful. If the requested 837 * index matches, then fill the out_args structure and return, 838 * or return -ENOENT for an empty entry. 839 */ 840 rc = -ENOENT; 841 if (cur_index == index) { 842 if (!phandle) 843 goto err; 844 845 if (out_args) { 846 int i; 847 848 if (count > MAX_PHANDLE_ARGS) { 849 debug("%s: too many arguments %d\n", 850 fdt_get_name(blob, src_node, 851 NULL), count); 852 count = MAX_PHANDLE_ARGS; 853 } 854 out_args->node = node; 855 out_args->args_count = count; 856 for (i = 0; i < count; i++) { 857 out_args->args[i] = 858 be32_to_cpup(list++); 859 } 860 } 861 862 /* Found it! return success */ 863 return 0; 864 } 865 866 node = -1; 867 list += count; 868 cur_index++; 869 } 870 871 /* 872 * Result will be one of: 873 * -ENOENT : index is for empty phandle 874 * -EINVAL : parsing error on data 875 * [1..n] : Number of phandle (count mode; when index = -1) 876 */ 877 rc = index < 0 ? cur_index : -ENOENT; 878 err: 879 return rc; 880} 881 882int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name, 883 u8 *array, int count) 884{ 885 const u8 *cell; 886 int err; 887 888 cell = get_prop_check_min_len(blob, node, prop_name, count, &err); 889 if (!err) 890 memcpy(array, cell, count); 891 return err; 892} 893 894const u8 *fdtdec_locate_byte_array(const void *blob, int node, 895 const char *prop_name, int count) 896{ 897 const u8 *cell; 898 int err; 899 900 cell = get_prop_check_min_len(blob, node, prop_name, count, &err); 901 if (err) 902 return NULL; 903 return cell; 904} 905 906u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells) 907{ 908 u64 number = 0; 909 910 while (cells--) 911 number = (number << 32) | fdt32_to_cpu(*ptr++); 912 913 return number; 914} 915 916int fdt_get_resource(const void *fdt, int node, const char *property, 917 unsigned int index, struct fdt_resource *res) 918{ 919 const fdt32_t *ptr, *end; 920 int na, ns, len, parent; 921 unsigned int i = 0; 922 923 parent = fdt_parent_offset(fdt, node); 924 if (parent < 0) 925 return parent; 926 927 na = fdt_address_cells(fdt, parent); 928 ns = fdt_size_cells(fdt, parent); 929 930 ptr = fdt_getprop(fdt, node, property, &len); 931 if (!ptr) 932 return len; 933 934 end = ptr + len / sizeof(*ptr); 935 936 while (ptr + na + ns <= end) { 937 if (i == index) { 938 if (CONFIG_IS_ENABLED(OF_TRANSLATE)) 939 res->start = fdt_translate_address(fdt, node, ptr); 940 else 941 res->start = fdtdec_get_number(ptr, na); 942 943 res->end = res->start; 944 res->end += fdtdec_get_number(&ptr[na], ns) - 1; 945 return 0; 946 } 947 948 ptr += na + ns; 949 i++; 950 } 951 952 return -FDT_ERR_NOTFOUND; 953} 954 955int fdt_get_named_resource(const void *fdt, int node, const char *property, 956 const char *prop_names, const char *name, 957 struct fdt_resource *res) 958{ 959 int index; 960 961 index = fdt_stringlist_search(fdt, node, prop_names, name); 962 if (index < 0) 963 return index; 964 965 return fdt_get_resource(fdt, node, property, index, res); 966} 967 968static int decode_timing_property(const void *blob, int node, const char *name, 969 struct timing_entry *result) 970{ 971 int length, ret = 0; 972 const u32 *prop; 973 974 prop = fdt_getprop(blob, node, name, &length); 975 if (!prop) { 976 debug("%s: could not find property %s\n", 977 fdt_get_name(blob, node, NULL), name); 978 return length; 979 } 980 981 if (length == sizeof(u32)) { 982 result->typ = fdtdec_get_int(blob, node, name, 0); 983 result->min = result->typ; 984 result->max = result->typ; 985 } else { 986 ret = fdtdec_get_int_array(blob, node, name, &result->min, 3); 987 } 988 989 return ret; 990} 991 992int fdtdec_decode_display_timing(const void *blob, int parent, int index, 993 struct display_timing *dt) 994{ 995 int i, node, timings_node; 996 u32 val = 0; 997 int ret = 0; 998 999 timings_node = fdt_subnode_offset(blob, parent, "display-timings"); 1000 if (timings_node < 0) 1001 return timings_node; 1002 1003 for (i = 0, node = fdt_first_subnode(blob, timings_node); 1004 node > 0 && i != index; 1005 node = fdt_next_subnode(blob, node)) 1006 i++; 1007 1008 if (node < 0) 1009 return node; 1010 1011 memset(dt, 0, sizeof(*dt)); 1012 1013 ret |= decode_timing_property(blob, node, "hback-porch", 1014 &dt->hback_porch); 1015 ret |= decode_timing_property(blob, node, "hfront-porch", 1016 &dt->hfront_porch); 1017 ret |= decode_timing_property(blob, node, "hactive", &dt->hactive); 1018 ret |= decode_timing_property(blob, node, "hsync-len", &dt->hsync_len); 1019 ret |= decode_timing_property(blob, node, "vback-porch", 1020 &dt->vback_porch); 1021 ret |= decode_timing_property(blob, node, "vfront-porch", 1022 &dt->vfront_porch); 1023 ret |= decode_timing_property(blob, node, "vactive", &dt->vactive); 1024 ret |= decode_timing_property(blob, node, "vsync-len", &dt->vsync_len); 1025 ret |= decode_timing_property(blob, node, "clock-frequency", 1026 &dt->pixelclock); 1027 1028 dt->flags = 0; 1029 val = fdtdec_get_int(blob, node, "vsync-active", -1); 1030 if (val != -1) { 1031 dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH : 1032 DISPLAY_FLAGS_VSYNC_LOW; 1033 } 1034 val = fdtdec_get_int(blob, node, "hsync-active", -1); 1035 if (val != -1) { 1036 dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH : 1037 DISPLAY_FLAGS_HSYNC_LOW; 1038 } 1039 val = fdtdec_get_int(blob, node, "de-active", -1); 1040 if (val != -1) { 1041 dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH : 1042 DISPLAY_FLAGS_DE_LOW; 1043 } 1044 val = fdtdec_get_int(blob, node, "pixelclk-active", -1); 1045 if (val != -1) { 1046 dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE : 1047 DISPLAY_FLAGS_PIXDATA_NEGEDGE; 1048 } 1049 1050 if (fdtdec_get_bool(blob, node, "interlaced")) 1051 dt->flags |= DISPLAY_FLAGS_INTERLACED; 1052 if (fdtdec_get_bool(blob, node, "doublescan")) 1053 dt->flags |= DISPLAY_FLAGS_DOUBLESCAN; 1054 if (fdtdec_get_bool(blob, node, "doubleclk")) 1055 dt->flags |= DISPLAY_FLAGS_DOUBLECLK; 1056 1057 return ret; 1058} 1059 1060int fdtdec_setup_mem_size_base(void) 1061{ 1062 int ret; 1063 ofnode mem; 1064 struct resource res; 1065 1066 mem = ofnode_path("/memory"); 1067 if (!ofnode_valid(mem)) { 1068 debug("%s: Missing /memory node\n", __func__); 1069 return -EINVAL; 1070 } 1071 1072 ret = ofnode_read_resource(mem, 0, &res); 1073 if (ret != 0) { 1074 debug("%s: Unable to decode first memory bank\n", __func__); 1075 return -EINVAL; 1076 } 1077 1078 gd->ram_size = (phys_size_t)(res.end - res.start + 1); 1079 gd->ram_base = (unsigned long)res.start; 1080 debug("%s: Initial DRAM size %llx\n", __func__, 1081 (unsigned long long)gd->ram_size); 1082 1083 return 0; 1084} 1085 1086ofnode get_next_memory_node(ofnode mem) 1087{ 1088 do { 1089 mem = ofnode_by_prop_value(mem, "device_type", "memory", 7); 1090 } while (!ofnode_is_enabled(mem)); 1091 1092 return mem; 1093} 1094 1095int fdtdec_setup_memory_banksize(void) 1096{ 1097 int bank, ret, reg = 0; 1098 struct resource res; 1099 ofnode mem = ofnode_null(); 1100 1101 mem = get_next_memory_node(mem); 1102 if (!ofnode_valid(mem)) { 1103 debug("%s: Missing /memory node\n", __func__); 1104 return -EINVAL; 1105 } 1106 1107 for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { 1108 ret = ofnode_read_resource(mem, reg++, &res); 1109 if (ret < 0) { 1110 reg = 0; 1111 mem = get_next_memory_node(mem); 1112 if (!ofnode_valid(mem)) 1113 break; 1114 1115 ret = ofnode_read_resource(mem, reg++, &res); 1116 if (ret < 0) 1117 break; 1118 } 1119 1120 if (ret != 0) 1121 return -EINVAL; 1122 1123 gd->bd->bi_dram[bank].start = (phys_addr_t)res.start; 1124 gd->bd->bi_dram[bank].size = 1125 (phys_size_t)(res.end - res.start + 1); 1126 1127 debug("%s: DRAM Bank #%d: start = 0x%llx, size = 0x%llx\n", 1128 __func__, bank, 1129 (unsigned long long)gd->bd->bi_dram[bank].start, 1130 (unsigned long long)gd->bd->bi_dram[bank].size); 1131 } 1132 1133 return 0; 1134} 1135 1136int fdtdec_setup_mem_size_base_lowest(void) 1137{ 1138 int bank, ret, reg = 0; 1139 struct resource res; 1140 unsigned long base; 1141 phys_size_t size; 1142 ofnode mem = ofnode_null(); 1143 1144 gd->ram_base = (unsigned long)~0; 1145 1146 mem = get_next_memory_node(mem); 1147 if (!ofnode_valid(mem)) { 1148 debug("%s: Missing /memory node\n", __func__); 1149 return -EINVAL; 1150 } 1151 1152 for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { 1153 ret = ofnode_read_resource(mem, reg++, &res); 1154 if (ret < 0) { 1155 reg = 0; 1156 mem = get_next_memory_node(mem); 1157 if (!ofnode_valid(mem)) 1158 break; 1159 1160 ret = ofnode_read_resource(mem, reg++, &res); 1161 if (ret < 0) 1162 break; 1163 } 1164 1165 if (ret != 0) 1166 return -EINVAL; 1167 1168 base = (unsigned long)res.start; 1169 size = (phys_size_t)(res.end - res.start + 1); 1170 1171 if (gd->ram_base > base && size) { 1172 gd->ram_base = base; 1173 gd->ram_size = size; 1174 debug("%s: Initial DRAM base %lx size %lx\n", 1175 __func__, base, (unsigned long)size); 1176 } 1177 } 1178 1179 return 0; 1180} 1181 1182static int uncompress_blob(const void *src, ulong sz_src, void **dstp) 1183{ 1184#if CONFIG_IS_ENABLED(MULTI_DTB_FIT_GZIP) ||\ 1185 CONFIG_IS_ENABLED(MULTI_DTB_FIT_LZO) 1186 size_t sz_out = CONFIG_VAL(MULTI_DTB_FIT_UNCOMPRESS_SZ); 1187 bool gzip = 0, lzo = 0; 1188 ulong sz_in = sz_src; 1189 void *dst; 1190 int rc; 1191 1192 if (CONFIG_IS_ENABLED(GZIP) && CONFIG_IS_ENABLED(MULTI_DTB_FIT_GZIP)) 1193 if (gzip_parse_header(src, sz_in) >= 0) 1194 gzip = 1; 1195 if (CONFIG_IS_ENABLED(LZO) && CONFIG_IS_ENABLED(MULTI_DTB_FIT_LZO)) 1196 if (!gzip && lzop_is_valid_header(src)) 1197 lzo = 1; 1198 1199 if (!gzip && !lzo) 1200 return -EBADMSG; 1201 1202 if (CONFIG_IS_ENABLED(MULTI_DTB_FIT_DYN_ALLOC)) { 1203 dst = malloc(sz_out); 1204 if (!dst) { 1205 puts("uncompress_blob: Unable to allocate memory\n"); 1206 return -ENOMEM; 1207 } 1208 } else { 1209# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_USER_DEFINED_AREA) 1210 dst = (void *)CONFIG_VAL(MULTI_DTB_FIT_USER_DEF_ADDR); 1211# else 1212 return -ENOTSUPP; 1213# endif 1214 } 1215 1216 if (CONFIG_IS_ENABLED(GZIP) && gzip) 1217 rc = gunzip(dst, sz_out, (u8 *)src, &sz_in); 1218 else if (CONFIG_IS_ENABLED(LZO) && lzo) 1219 rc = lzop_decompress(src, sz_in, dst, &sz_out); 1220 else 1221 hang(); 1222 1223 if (rc < 0) { 1224 /* not a valid compressed blob */ 1225 puts("uncompress_blob: Unable to uncompress\n"); 1226 if (CONFIG_IS_ENABLED(MULTI_DTB_FIT_DYN_ALLOC)) 1227 free(dst); 1228 return -EBADMSG; 1229 } 1230 *dstp = dst; 1231#else 1232 *dstp = (void *)src; 1233 *dstp = (void *)src; 1234#endif 1235 return 0; 1236} 1237 1238/** 1239 * fdt_find_separate() - Find a devicetree at the end of the image 1240 * 1241 * Return: pointer to FDT blob 1242 */ 1243static void *fdt_find_separate(void) 1244{ 1245 void *fdt_blob = NULL; 1246 1247 if (IS_ENABLED(CONFIG_SANDBOX)) 1248 return NULL; 1249 1250#ifdef CONFIG_XPL_BUILD 1251 /* FDT is at end of BSS unless it is in a different memory region */ 1252 if (CONFIG_IS_ENABLED(SEPARATE_BSS)) 1253 fdt_blob = (ulong *)_image_binary_end; 1254 else 1255 fdt_blob = (ulong *)__bss_end; 1256#else 1257 /* FDT is at end of image */ 1258 fdt_blob = (ulong *)_end; 1259 1260 if (_DEBUG && !fdtdec_prepare_fdt(fdt_blob)) { 1261 int stack_ptr; 1262 const void *top = fdt_blob + fdt_totalsize(fdt_blob); 1263 1264 /* 1265 * Perform a sanity check on the memory layout. If this fails, 1266 * it indicates that the device tree is positioned above the 1267 * global data pointer or the stack pointer. This should not 1268 * happen. 1269 * 1270 * If this fails, check that SYS_INIT_SP_ADDR has enough space 1271 * below it for SYS_MALLOC_F_LEN and global_data, as well as the 1272 * stack, without overwriting the device tree or U-Boot itself. 1273 * Since the device tree is sitting at _end (the start of the 1274 * BSS region), we need the top of the device tree to be below 1275 * any memory allocated by board_init_f_alloc_reserve(). 1276 */ 1277 if (top > (void *)gd || top > (void *)&stack_ptr) { 1278 printf("FDT %p gd %p\n", fdt_blob, gd); 1279 panic("FDT overlap"); 1280 } 1281 } 1282#endif 1283 1284 return fdt_blob; 1285} 1286 1287int fdtdec_set_ethernet_mac_address(void *fdt, const u8 *mac, size_t size) 1288{ 1289 const char *path; 1290 int offset, err; 1291 1292 if (!is_valid_ethaddr(mac)) 1293 return -EINVAL; 1294 1295 path = fdt_get_alias(fdt, "ethernet"); 1296 if (!path) 1297 return 0; 1298 1299 debug("ethernet alias found: %s\n", path); 1300 1301 offset = fdt_path_offset(fdt, path); 1302 if (offset < 0) { 1303 debug("ethernet alias points to absent node %s\n", path); 1304 return -ENOENT; 1305 } 1306 1307 err = fdt_setprop_inplace(fdt, offset, "local-mac-address", mac, size); 1308 if (err < 0) 1309 return err; 1310 1311 debug("MAC address: %pM\n", mac); 1312 1313 return 0; 1314} 1315 1316static int fdtdec_init_reserved_memory(void *blob) 1317{ 1318 int na, ns, node, err; 1319 fdt32_t value; 1320 1321 /* inherit #address-cells and #size-cells from the root node */ 1322 na = fdt_address_cells(blob, 0); 1323 ns = fdt_size_cells(blob, 0); 1324 1325 node = fdt_add_subnode(blob, 0, "reserved-memory"); 1326 if (node < 0) 1327 return node; 1328 1329 err = fdt_setprop(blob, node, "ranges", NULL, 0); 1330 if (err < 0) 1331 return err; 1332 1333 value = cpu_to_fdt32(ns); 1334 1335 err = fdt_setprop(blob, node, "#size-cells", &value, sizeof(value)); 1336 if (err < 0) 1337 return err; 1338 1339 value = cpu_to_fdt32(na); 1340 1341 err = fdt_setprop(blob, node, "#address-cells", &value, sizeof(value)); 1342 if (err < 0) 1343 return err; 1344 1345 return node; 1346} 1347 1348int fdtdec_add_reserved_memory(void *blob, const char *basename, 1349 const struct fdt_memory *carveout, 1350 const char **compatibles, unsigned int count, 1351 uint32_t *phandlep, unsigned long flags) 1352{ 1353 fdt32_t cells[4] = {}, *ptr = cells; 1354 uint32_t upper, lower, phandle; 1355 int parent, node, na, ns, err; 1356 fdt_size_t size; 1357 char name[64]; 1358 1359 /* create an empty /reserved-memory node if one doesn't exist */ 1360 parent = fdt_path_offset(blob, "/reserved-memory"); 1361 if (parent < 0) { 1362 parent = fdtdec_init_reserved_memory(blob); 1363 if (parent < 0) 1364 return parent; 1365 } 1366 1367 /* only 1 or 2 #address-cells and #size-cells are supported */ 1368 na = fdt_address_cells(blob, parent); 1369 if (na < 1 || na > 2) 1370 return -FDT_ERR_BADNCELLS; 1371 1372 ns = fdt_size_cells(blob, parent); 1373 if (ns < 1 || ns > 2) 1374 return -FDT_ERR_BADNCELLS; 1375 1376 /* find a matching node and return the phandle to that */ 1377 fdt_for_each_subnode(node, blob, parent) { 1378 const char *name = fdt_get_name(blob, node, NULL); 1379 fdt_addr_t addr; 1380 fdt_size_t size; 1381 1382 addr = fdtdec_get_addr_size_fixed(blob, node, "reg", 0, na, ns, 1383 &size, false); 1384 if (addr == FDT_ADDR_T_NONE) { 1385 debug("failed to read address/size for %s\n", name); 1386 continue; 1387 } 1388 1389 if (addr == carveout->start && (addr + size - 1) == 1390 carveout->end) { 1391 if (phandlep) 1392 *phandlep = fdt_get_phandle(blob, node); 1393 return 0; 1394 } 1395 } 1396 1397 /* 1398 * Unpack the start address and generate the name of the new node 1399 * base on the basename and the unit-address. 1400 */ 1401 upper = upper_32_bits(carveout->start); 1402 lower = lower_32_bits(carveout->start); 1403 1404 if (na > 1 && upper > 0) 1405 snprintf(name, sizeof(name), "%s@%x,%x", basename, upper, 1406 lower); 1407 else { 1408 if (upper > 0) { 1409 debug("address %08x:%08x exceeds addressable space\n", 1410 upper, lower); 1411 return -FDT_ERR_BADVALUE; 1412 } 1413 1414 snprintf(name, sizeof(name), "%s@%x", basename, lower); 1415 } 1416 1417 node = fdt_add_subnode(blob, parent, name); 1418 if (node < 0) 1419 return node; 1420 1421 if (flags & FDTDEC_RESERVED_MEMORY_NO_MAP) { 1422 err = fdt_setprop(blob, node, "no-map", NULL, 0); 1423 if (err < 0) 1424 return err; 1425 } 1426 1427 if (phandlep) { 1428 err = fdt_generate_phandle(blob, &phandle); 1429 if (err < 0) 1430 return err; 1431 1432 err = fdtdec_set_phandle(blob, node, phandle); 1433 if (err < 0) 1434 return err; 1435 } 1436 1437 /* store one or two address cells */ 1438 if (na > 1) 1439 *ptr++ = cpu_to_fdt32(upper); 1440 1441 *ptr++ = cpu_to_fdt32(lower); 1442 1443 /* store one or two size cells */ 1444 size = carveout->end - carveout->start + 1; 1445 upper = upper_32_bits(size); 1446 lower = lower_32_bits(size); 1447 1448 if (ns > 1) 1449 *ptr++ = cpu_to_fdt32(upper); 1450 1451 *ptr++ = cpu_to_fdt32(lower); 1452 1453 err = fdt_setprop(blob, node, "reg", cells, (na + ns) * sizeof(*cells)); 1454 if (err < 0) 1455 return err; 1456 1457 if (compatibles && count > 0) { 1458 size_t length = 0, len = 0; 1459 unsigned int i; 1460 char *buffer; 1461 1462 for (i = 0; i < count; i++) 1463 length += strlen(compatibles[i]) + 1; 1464 1465 buffer = malloc(length); 1466 if (!buffer) 1467 return -FDT_ERR_INTERNAL; 1468 1469 for (i = 0; i < count; i++) 1470 len += strlcpy(buffer + len, compatibles[i], 1471 length - len) + 1; 1472 1473 err = fdt_setprop(blob, node, "compatible", buffer, length); 1474 free(buffer); 1475 if (err < 0) 1476 return err; 1477 } 1478 1479 /* return the phandle for the new node for the caller to use */ 1480 if (phandlep) 1481 *phandlep = phandle; 1482 1483 return 0; 1484} 1485 1486int fdtdec_get_carveout(const void *blob, const char *node, 1487 const char *prop_name, unsigned int index, 1488 struct fdt_memory *carveout, const char **name, 1489 const char ***compatiblesp, unsigned int *countp, 1490 unsigned long *flags) 1491{ 1492 const fdt32_t *prop; 1493 uint32_t phandle; 1494 int offset, len; 1495 fdt_size_t size; 1496 1497 offset = fdt_path_offset(blob, node); 1498 if (offset < 0) 1499 return offset; 1500 1501 prop = fdt_getprop(blob, offset, prop_name, &len); 1502 if (!prop) { 1503 debug("failed to get %s for %s\n", prop_name, node); 1504 return -FDT_ERR_NOTFOUND; 1505 } 1506 1507 if ((len % sizeof(phandle)) != 0) { 1508 debug("invalid phandle property\n"); 1509 return -FDT_ERR_BADPHANDLE; 1510 } 1511 1512 if (len < (sizeof(phandle) * (index + 1))) { 1513 debug("invalid phandle index\n"); 1514 return -FDT_ERR_NOTFOUND; 1515 } 1516 1517 phandle = fdt32_to_cpu(prop[index]); 1518 1519 offset = fdt_node_offset_by_phandle(blob, phandle); 1520 if (offset < 0) { 1521 debug("failed to find node for phandle %u\n", phandle); 1522 return offset; 1523 } 1524 1525 if (name) 1526 *name = fdt_get_name(blob, offset, NULL); 1527 1528 if (compatiblesp) { 1529 const char **compatibles = NULL; 1530 const char *start, *end, *ptr; 1531 unsigned int count = 0; 1532 1533 prop = fdt_getprop(blob, offset, "compatible", &len); 1534 if (!prop) 1535 goto skip_compat; 1536 1537 start = ptr = (const char *)prop; 1538 end = start + len; 1539 1540 while (ptr < end) { 1541 ptr = strchrnul(ptr, '\0'); 1542 count++; 1543 ptr++; 1544 } 1545 1546 compatibles = malloc(sizeof(ptr) * count); 1547 if (!compatibles) 1548 return -FDT_ERR_INTERNAL; 1549 1550 ptr = start; 1551 count = 0; 1552 1553 while (ptr < end) { 1554 compatibles[count] = ptr; 1555 ptr = strchrnul(ptr, '\0'); 1556 count++; 1557 ptr++; 1558 } 1559 1560skip_compat: 1561 *compatiblesp = compatibles; 1562 1563 if (countp) 1564 *countp = count; 1565 } 1566 1567 carveout->start = fdtdec_get_addr_size_auto_noparent(blob, offset, 1568 "reg", 0, &size, 1569 true); 1570 if (carveout->start == FDT_ADDR_T_NONE) { 1571 debug("failed to read address/size from \"reg\" property\n"); 1572 return -FDT_ERR_NOTFOUND; 1573 } 1574 1575 carveout->end = carveout->start + size - 1; 1576 1577 if (flags) { 1578 *flags = 0; 1579 1580 if (fdtdec_get_bool(blob, offset, "no-map")) 1581 *flags |= FDTDEC_RESERVED_MEMORY_NO_MAP; 1582 } 1583 1584 return 0; 1585} 1586 1587int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, 1588 unsigned int index, const struct fdt_memory *carveout, 1589 const char *name, const char **compatibles, 1590 unsigned int count, unsigned long flags) 1591{ 1592 uint32_t phandle; 1593 int err, offset, len; 1594 fdt32_t value; 1595 void *prop; 1596 1597 err = fdtdec_add_reserved_memory(blob, name, carveout, compatibles, 1598 count, &phandle, flags); 1599 if (err < 0) { 1600 debug("failed to add reserved memory: %d\n", err); 1601 return err; 1602 } 1603 1604 offset = fdt_path_offset(blob, node); 1605 if (offset < 0) { 1606 debug("failed to find offset for node %s: %d\n", node, offset); 1607 return offset; 1608 } 1609 1610 value = cpu_to_fdt32(phandle); 1611 1612 if (!fdt_getprop(blob, offset, prop_name, &len)) { 1613 if (len == -FDT_ERR_NOTFOUND) 1614 len = 0; 1615 else 1616 return len; 1617 } 1618 1619 if ((index + 1) * sizeof(value) > len) { 1620 err = fdt_setprop_placeholder(blob, offset, prop_name, 1621 (index + 1) * sizeof(value), 1622 &prop); 1623 if (err < 0) { 1624 debug("failed to resize reserved memory property: %s\n", 1625 fdt_strerror(err)); 1626 return err; 1627 } 1628 } 1629 1630 err = fdt_setprop_inplace_namelen_partial(blob, offset, prop_name, 1631 strlen(prop_name), 1632 index * sizeof(value), 1633 &value, sizeof(value)); 1634 if (err < 0) { 1635 debug("failed to update %s property for node %s: %s\n", 1636 prop_name, node, fdt_strerror(err)); 1637 return err; 1638 } 1639 1640 return 0; 1641} 1642 1643/* TODO(sjg@chromium.org): This function should not be weak */ 1644__weak int fdtdec_board_setup(const void *fdt_blob) 1645{ 1646 return 0; 1647} 1648 1649/** 1650 * setup_multi_dtb_fit() - locate the correct dtb from a FIT 1651 * 1652 * This supports the CONFIG_MULTI_DTB_FIT feature, looking for the dtb in a 1653 * supplied FIT 1654 * 1655 * It accepts the current value of gd->fdt_blob, which points to the FIT, then 1656 * updates that gd->fdt_blob, to point to the chosen dtb so that U-Boot uses the 1657 * correct one 1658 */ 1659static void setup_multi_dtb_fit(void) 1660{ 1661 void *blob; 1662 1663 /* 1664 * Try and uncompress the blob. 1665 * Unfortunately there is no way to know how big the input blob really 1666 * is. So let us set the maximum input size arbitrarily high. 16MB 1667 * ought to be more than enough for packed DTBs. 1668 */ 1669 if (uncompress_blob(gd->fdt_blob, 0x1000000, &blob) == 0) 1670 gd->fdt_blob = blob; 1671 1672 /* 1673 * Check if blob is a FIT images containings DTBs. 1674 * If so, pick the most relevant 1675 */ 1676 blob = locate_dtb_in_fit(gd->fdt_blob); 1677 if (blob) { 1678 gd_set_multi_dtb_fit(gd->fdt_blob); 1679 gd->fdt_blob = blob; 1680 gd->fdt_src = FDTSRC_FIT; 1681 } 1682} 1683 1684void fdtdec_setup_embed(void) 1685{ 1686 gd->fdt_blob = dtb_dt_embedded(); 1687 gd->fdt_src = FDTSRC_EMBED; 1688} 1689 1690int fdtdec_setup(void) 1691{ 1692 int ret = -ENOENT; 1693 1694 /* 1695 * If allowing a bloblist, check that first. There was discussion about 1696 * adding an OF_BLOBLIST Kconfig, but this was rejected. 1697 * 1698 * The necessary test is whether the previous phase passed a bloblist, 1699 * not whether this phase creates one. 1700 */ 1701 if (CONFIG_IS_ENABLED(BLOBLIST) && 1702 (xpl_prev_phase() != PHASE_TPL || 1703 IS_ENABLED(CONFIG_TPL_BLOBLIST))) { 1704 ret = bloblist_maybe_init(); 1705 if (!ret) { 1706 gd->fdt_blob = bloblist_find(BLOBLISTT_CONTROL_FDT, 0); 1707 if (gd->fdt_blob) { 1708 gd->fdt_src = FDTSRC_BLOBLIST; 1709 log_debug("Devicetree is in bloblist at %p\n", 1710 gd->fdt_blob); 1711 ret = 0; 1712 } else { 1713 log_debug("No FDT found in bloblist\n"); 1714 ret = -ENOENT; 1715 } 1716 } 1717 } 1718 1719 /* Otherwise, the devicetree is typically appended to U-Boot */ 1720 if (ret) { 1721 if (IS_ENABLED(CONFIG_OF_SEPARATE)) { 1722 gd->fdt_blob = fdt_find_separate(); 1723 gd->fdt_src = FDTSRC_SEPARATE; 1724 } else { /* embed dtb in ELF file for testing / development */ 1725 fdtdec_setup_embed(); 1726 } 1727 } 1728 1729 /* Allow the board to override the fdt address. */ 1730 if (IS_ENABLED(CONFIG_OF_BOARD)) { 1731 void *blob; 1732 1733 blob = (void *)gd->fdt_blob; 1734 ret = board_fdt_blob_setup(&blob); 1735 if (ret) { 1736 if (ret != -EEXIST) 1737 return ret; 1738 } else { 1739 gd->fdt_src = FDTSRC_BOARD; 1740 gd->fdt_blob = blob; 1741 } 1742 } 1743 1744 /* Allow the early environment to override the fdt address */ 1745 if (!IS_ENABLED(CONFIG_XPL_BUILD)) { 1746 ulong addr; 1747 1748 addr = env_get_hex("fdtcontroladdr", 0); 1749 if (addr) { 1750 gd->fdt_blob = map_sysmem(addr, 0); 1751 gd->fdt_src = FDTSRC_ENV; 1752 } 1753 } 1754 1755 if (CONFIG_IS_ENABLED(MULTI_DTB_FIT)) 1756 setup_multi_dtb_fit(); 1757 1758 ret = fdtdec_prepare_fdt(gd->fdt_blob); 1759 if (!ret) 1760 ret = fdtdec_board_setup(gd->fdt_blob); 1761 oftree_reset(); 1762 1763 return ret; 1764} 1765 1766int fdtdec_resetup(int *rescan) 1767{ 1768 void *fdt_blob; 1769 1770 /* 1771 * If the current DTB is part of a compressed FIT image, 1772 * try to locate the best match from the uncompressed 1773 * FIT image stillpresent there. Save the time and space 1774 * required to uncompress it again. 1775 */ 1776 if (gd_multi_dtb_fit()) { 1777 fdt_blob = locate_dtb_in_fit(gd_multi_dtb_fit()); 1778 1779 if (fdt_blob == gd->fdt_blob) { 1780 /* 1781 * The best match did not change. no need to tear down 1782 * the DM and rescan the fdt. 1783 */ 1784 *rescan = 0; 1785 return 0; 1786 } 1787 1788 *rescan = 1; 1789 gd->fdt_blob = fdt_blob; 1790 return fdtdec_prepare_fdt(fdt_blob); 1791 } 1792 1793 /* 1794 * If multi_dtb_fit is NULL, it means that blob appended to u-boot is 1795 * not a FIT image containings DTB, but a single DTB. There is no need 1796 * to teard down DM and rescan the DT in this case. 1797 */ 1798 *rescan = 0; 1799 return 0; 1800} 1801 1802int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id, 1803 phys_addr_t *basep, phys_size_t *sizep, 1804 struct bd_info *bd) 1805{ 1806 int addr_cells, size_cells; 1807 const u32 *cell, *end; 1808 u64 total_size, size, addr; 1809 int node, child; 1810 bool auto_size; 1811 int bank; 1812 int len; 1813 1814 debug("%s: board_id=%d\n", __func__, board_id); 1815 if (!area) 1816 area = "/memory"; 1817 node = fdt_path_offset(blob, area); 1818 if (node < 0) { 1819 debug("No %s node found\n", area); 1820 return -ENOENT; 1821 } 1822 1823 cell = fdt_getprop(blob, node, "reg", &len); 1824 if (!cell) { 1825 debug("No reg property found\n"); 1826 return -ENOENT; 1827 } 1828 1829 addr_cells = fdt_address_cells(blob, node); 1830 size_cells = fdt_size_cells(blob, node); 1831 1832 /* Check the board id and mask */ 1833 for (child = fdt_first_subnode(blob, node); 1834 child >= 0; 1835 child = fdt_next_subnode(blob, child)) { 1836 int match_mask, match_value; 1837 1838 match_mask = fdtdec_get_int(blob, child, "match-mask", -1); 1839 match_value = fdtdec_get_int(blob, child, "match-value", -1); 1840 1841 if (match_value >= 0 && 1842 ((board_id & match_mask) == match_value)) { 1843 /* Found matching mask */ 1844 debug("Found matching mask %d\n", match_mask); 1845 node = child; 1846 cell = fdt_getprop(blob, node, "reg", &len); 1847 if (!cell) { 1848 debug("No memory-banks property found\n"); 1849 return -EINVAL; 1850 } 1851 break; 1852 } 1853 } 1854 /* Note: if no matching subnode was found we use the parent node */ 1855 1856 if (bd) { 1857 memset(bd->bi_dram, '\0', sizeof(bd->bi_dram[0]) * 1858 CONFIG_NR_DRAM_BANKS); 1859 } 1860 1861 auto_size = fdtdec_get_bool(blob, node, "auto-size"); 1862 1863 total_size = 0; 1864 end = cell + len / 4 - addr_cells - size_cells; 1865 debug("cell at %p, end %p\n", cell, end); 1866 for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { 1867 if (cell > end) 1868 break; 1869 addr = 0; 1870 if (addr_cells == 2) 1871 addr += (u64)fdt32_to_cpu(*cell++) << 32UL; 1872 addr += fdt32_to_cpu(*cell++); 1873 if (bd) 1874 bd->bi_dram[bank].start = addr; 1875 if (basep && !bank) 1876 *basep = (phys_addr_t)addr; 1877 1878 size = 0; 1879 if (size_cells == 2) 1880 size += (u64)fdt32_to_cpu(*cell++) << 32UL; 1881 size += fdt32_to_cpu(*cell++); 1882 1883 if (auto_size) { 1884 u64 new_size; 1885 1886 debug("Auto-sizing %llx, size %llx: ", addr, size); 1887 new_size = get_ram_size((long *)(uintptr_t)addr, size); 1888 if (new_size == size) { 1889 debug("OK\n"); 1890 } else { 1891 debug("sized to %llx\n", new_size); 1892 size = new_size; 1893 } 1894 } 1895 1896 if (bd) 1897 bd->bi_dram[bank].size = size; 1898 total_size += size; 1899 } 1900 1901 debug("Memory size %llu\n", total_size); 1902 if (sizep) 1903 *sizep = (phys_size_t)total_size; 1904 1905 return 0; 1906} 1907 1908#endif /* !USE_HOSTCC */