X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Ffdt_support.c;h=f31e9b0cc5a899ade8f400d1af83fe08e5c593cd;hb=634931fea542fc59cf7537b6c2c163942a6ccd15;hp=916a448c11d43a82e25155f001c919cd8b5e9541;hpb=336aee50cf55d4d98ddf3a4412c18286e7f0a4c0;p=oweals%2Fu-boot.git diff --git a/common/fdt_support.c b/common/fdt_support.c index 916a448c11..f31e9b0cc5 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -1,19 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2007 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com * * Copyright 2010-2011 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ */ #include -#include +#include #include #include #include #include -#include +#include #include #include #include @@ -410,7 +409,7 @@ static int fdt_pack_reg(const void *fdt, void *buf, u64 *address, u64 *size, return p - (char *)buf; } -#ifdef CONFIG_NR_DRAM_BANKS +#if CONFIG_NR_DRAM_BANKS > 4 #define MEMORY_BANKS_MAX CONFIG_NR_DRAM_BANKS #else #define MEMORY_BANKS_MAX 4 @@ -418,7 +417,7 @@ static int fdt_pack_reg(const void *fdt, void *buf, u64 *address, u64 *size, int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) { int err, nodeoffset; - int len; + int len, i; u8 tmp[MEMORY_BANKS_MAX * 16]; /* Up to 64-bit address + 64-bit size */ if (banks > MEMORY_BANKS_MAX) { @@ -447,6 +446,13 @@ int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) return err; } + for (i = 0; i < banks; i++) { + if (start[i] == 0 && size[i] == 0) + break; + } + + banks = i; + if (!banks) return 0; @@ -469,12 +475,16 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) void fdt_fixup_ethernet(void *fdt) { - int i, j, prop; + int i = 0, j, prop; char *tmp, *end; char mac[16]; const char *path; unsigned char mac_addr[ARP_HLEN]; int offset; +#ifdef FDT_SEQ_MACADDR_FROM_ENV + int nodeoff; + const struct fdt_property *fdt_prop; +#endif if (fdt_path_offset(fdt, "/aliases") < 0) return; @@ -487,7 +497,7 @@ void fdt_fixup_ethernet(void *fdt) offset = fdt_first_property_offset(fdt, fdt_path_offset(fdt, "/aliases")); /* Select property number 'prop' */ - for (i = 0; i < prop; i++) + for (j = 0; j < prop; j++) offset = fdt_next_property_offset(fdt, offset); if (offset < 0) @@ -496,11 +506,16 @@ void fdt_fixup_ethernet(void *fdt) path = fdt_getprop_by_offset(fdt, offset, &name, NULL); if (!strncmp(name, "ethernet", 8)) { /* Treat plain "ethernet" same as "ethernet0". */ - if (!strcmp(name, "ethernet")) + if (!strcmp(name, "ethernet") +#ifdef FDT_SEQ_MACADDR_FROM_ENV + || !strcmp(name, "ethernet0") +#endif + ) i = 0; +#ifndef FDT_SEQ_MACADDR_FROM_ENV else i = trailing_strtol(name); - +#endif if (i != -1) { if (i == 0) strcpy(mac, "ethaddr"); @@ -509,6 +524,14 @@ void fdt_fixup_ethernet(void *fdt) } else { continue; } +#ifdef FDT_SEQ_MACADDR_FROM_ENV + nodeoff = fdt_path_offset(fdt, path); + fdt_prop = fdt_get_property(fdt, nodeoff, "status", + NULL); + if (fdt_prop && !strcmp(fdt_prop->data, "disabled")) + continue; + i++; +#endif tmp = env_get(mac); if (!tmp) continue; @@ -528,6 +551,45 @@ void fdt_fixup_ethernet(void *fdt) } } +int fdt_record_loadable(void *blob, u32 index, const char *name, + uintptr_t load_addr, u32 size, uintptr_t entry_point, + const char *type, const char *os) +{ + int err, node; + + err = fdt_check_header(blob); + if (err < 0) { + printf("%s: %s\n", __func__, fdt_strerror(err)); + return err; + } + + /* find or create "/fit-images" node */ + node = fdt_find_or_add_subnode(blob, 0, "fit-images"); + if (node < 0) + return node; + + /* find or create "/fit-images/" node */ + node = fdt_find_or_add_subnode(blob, node, name); + if (node < 0) + return node; + + /* + * We record these as 32bit entities, possibly truncating addresses. + * However, spl_fit.c is not 64bit safe either: i.e. we should not + * have an issue here. + */ + fdt_setprop_u32(blob, node, "load-addr", load_addr); + if (entry_point != -1) + fdt_setprop_u32(blob, node, "entry-point", entry_point); + fdt_setprop_u32(blob, node, "size", size); + if (type) + fdt_setprop_string(blob, node, "type", type); + if (os) + fdt_setprop_string(blob, node, "os", os); + + return node; +} + /* Resize the fdt to its actual size + a bit of padding */ int fdt_shrink_to_minimum(void *blob, uint extrasize) { @@ -535,6 +597,7 @@ int fdt_shrink_to_minimum(void *blob, uint extrasize) uint64_t addr, size; int total, ret; uint actualsize; + int fdt_memrsv = 0; if (!blob) return 0; @@ -544,6 +607,7 @@ int fdt_shrink_to_minimum(void *blob, uint extrasize) fdt_get_mem_rsv(blob, i, &addr, &size); if (addr == (uintptr_t)blob) { fdt_del_mem_rsv(blob, i); + fdt_memrsv = 1; break; } } @@ -565,10 +629,12 @@ int fdt_shrink_to_minimum(void *blob, uint extrasize) /* Change the fdt header to reflect the correct size */ fdt_set_totalsize(blob, actualsize); - /* Add the new reservation */ - ret = fdt_add_mem_rsv(blob, (uintptr_t)blob, actualsize); - if (ret < 0) - return ret; + if (fdt_memrsv) { + /* Add the new reservation */ + ret = fdt_add_mem_rsv(blob, map_to_sysmem(blob), actualsize); + if (ret < 0) + return ret; + } return actualsize; } @@ -656,12 +722,7 @@ int fdt_increase_size(void *fdt, int add_len) #include #include -struct reg_cell { - unsigned int r0; - unsigned int r1; -}; - -int fdt_del_subnodes(const void *blob, int parent_offset) +static int fdt_del_subnodes(const void *blob, int parent_offset) { int off, ndepth; int ret; @@ -686,7 +747,7 @@ int fdt_del_subnodes(const void *blob, int parent_offset) return 0; } -int fdt_del_partitions(void *blob, int parent_offset) +static int fdt_del_partitions(void *blob, int parent_offset) { const void *prop; int ndepth = 0; @@ -719,15 +780,22 @@ int fdt_node_set_part_info(void *blob, int parent_offset, { struct list_head *pentry; struct part_info *part; - struct reg_cell cell; int off, ndepth = 0; int part_num, ret; + int sizecell; char buf[64]; ret = fdt_del_partitions(blob, parent_offset); if (ret < 0) return ret; + /* + * Check if size/address is 1 or 2 cells. + * We assume #address-cells and #size-cells have same value. + */ + sizecell = fdt_getprop_u32_default_node(blob, parent_offset, + 0, "#size-cells", 1); + /* * Check if it is nand {}; subnode, adjust * the offset in this case @@ -776,10 +844,21 @@ add_ro: goto err_prop; } - cell.r0 = cpu_to_fdt32(part->offset); - cell.r1 = cpu_to_fdt32(part->size); add_reg: - ret = fdt_setprop(blob, newoff, "reg", &cell, sizeof(cell)); + if (sizecell == 2) { + ret = fdt_setprop_u64(blob, newoff, + "reg", part->offset); + if (!ret) + ret = fdt_appendprop_u64(blob, newoff, + "reg", part->size); + } else { + ret = fdt_setprop_u32(blob, newoff, + "reg", part->offset); + if (!ret) + ret = fdt_appendprop_u32(blob, newoff, + "reg", part->size); + } + if (ret == -FDT_ERR_NOSPACE) { ret = fdt_increase_size(blob, 512); if (!ret) @@ -825,9 +904,9 @@ err_prop: * * fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); */ -void fdt_fixup_mtdparts(void *blob, void *node_info, int node_info_size) +void fdt_fixup_mtdparts(void *blob, const struct node_info *node_info, + int node_info_size) { - struct node_info *ni = node_info; struct mtd_device *dev; int i, idx; int noff; @@ -837,12 +916,13 @@ void fdt_fixup_mtdparts(void *blob, void *node_info, int node_info_size) for (i = 0; i < node_info_size; i++) { idx = 0; - noff = fdt_node_offset_by_compatible(blob, -1, ni[i].compat); + noff = fdt_node_offset_by_compatible(blob, -1, + node_info[i].compat); while (noff != -FDT_ERR_NOTFOUND) { debug("%s: %s, mtd dev type %d\n", fdt_get_name(blob, noff, 0), - ni[i].compat, ni[i].type); - dev = device_find(ni[i].type, idx++); + node_info[i].compat, node_info[i].type); + dev = device_find(node_info[i].type, idx++); if (dev) { if (fdt_node_set_part_info(blob, noff, dev)) return; /* return on error */ @@ -850,7 +930,7 @@ void fdt_fixup_mtdparts(void *blob, void *node_info, int node_info_size) /* Jump to next flash node */ noff = fdt_node_offset_by_compatible(blob, noff, - ni[i].compat); + node_info[i].compat); } } } @@ -956,8 +1036,7 @@ static u64 of_bus_default_map(fdt32_t *addr, const fdt32_t *range, s = fdt_read_number(range + na + pna, ns); da = fdt_read_number(addr, na); - debug("OF: default map, cp=%" PRIu64 ", s=%" PRIu64 - ", da=%" PRIu64 "\n", cp, s, da); + debug("OF: default map, cp=%llx, s=%llx, da=%llx\n", cp, s, da); if (da < cp || da >= (cp + s)) return OF_BAD_ADDR; @@ -1012,8 +1091,7 @@ static u64 of_bus_isa_map(fdt32_t *addr, const fdt32_t *range, s = fdt_read_number(range + na + pna, ns); da = fdt_read_number(addr + 1, na - 1); - debug("OF: ISA map, cp=%" PRIu64 ", s=%" PRIu64 - ", da=%" PRIu64 "\n", cp, s, da); + debug("OF: ISA map, cp=%llx, s=%llx, da=%llx\n", cp, s, da); if (da < cp || da >= (cp + s)) return OF_BAD_ADDR; @@ -1119,7 +1197,7 @@ static int of_translate_one(const void *blob, int parent, struct of_bus *bus, finish: of_dump_addr("OF: parent translation for:", addr, pna); - debug("OF: with offset: %" PRIu64 "\n", offset); + debug("OF: with offset: %llu\n", offset); /* Translate it into parent bus space */ return pbus->translate(addr, offset, pna); @@ -1449,9 +1527,9 @@ int fdt_verify_alias_address(void *fdt, int anode, const char *alias, u64 addr) dt_addr = fdt_translate_address(fdt, node, reg); if (addr != dt_addr) { - printf("Warning: U-Boot configured device %s at address %" - PRIx64 ",\n but the device tree has it address %" - PRIx64 ".\n", alias, addr, dt_addr); + printf("Warning: U-Boot configured device %s at address %llu,\n" + "but the device tree has it address %llx.\n", + alias, addr, dt_addr); return 0; } @@ -1599,7 +1677,7 @@ int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width, if (ret < 0) return ret; - snprintf(name, sizeof(name), "framebuffer@%" PRIx64, base_address); + snprintf(name, sizeof(name), "framebuffer@%llx", base_address); ret = fdt_set_name(fdt, node, name); if (ret < 0) return ret; @@ -1655,3 +1733,34 @@ int fdt_fixup_display(void *blob, const char *path, const char *display) } return toff; } + +#ifdef CONFIG_OF_LIBFDT_OVERLAY +/** + * fdt_overlay_apply_verbose - Apply an overlay with verbose error reporting + * + * @fdt: ptr to device tree + * @fdto: ptr to device tree overlay + * + * Convenience function to apply an overlay and display helpful messages + * in the case of an error + */ +int fdt_overlay_apply_verbose(void *fdt, void *fdto) +{ + int err; + bool has_symbols; + + err = fdt_path_offset(fdt, "/__symbols__"); + has_symbols = err >= 0; + + err = fdt_overlay_apply(fdt, fdto); + if (err < 0) { + printf("failed on fdt_overlay_apply(): %s\n", + fdt_strerror(err)); + if (!has_symbols) { + printf("base fdt does did not have a /__symbols__ node\n"); + printf("make sure you've compiled with -@\n"); + } + } + return err; +} +#endif