X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=lib%2Ffdtdec.c;h=1f2b763acc312a27490a11ecc3a2dd42e3dfced3;hb=1099b2abef35c3c887f6afac1a8ef18c7924d5d2;hp=fea44a9a8c65d22cff39fd953328532e5b9b55aa;hpb=b4ee6daad7a2604ca9466b2ba48de86cc27d381f;p=oweals%2Fu-boot.git diff --git a/lib/fdtdec.c b/lib/fdtdec.c index fea44a9a8c..1f2b763acc 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -7,10 +7,17 @@ #include #include #include +#include +#include +#include +#include +#include #include +#include #include #include #include +#include #include #include #include @@ -184,60 +191,6 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node, const char *prop_name) } #if CONFIG_IS_ENABLED(PCI) && defined(CONFIG_DM_PCI) -int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type, - const char *prop_name, struct fdt_pci_addr *addr) -{ - const u32 *cell; - int len; - int ret = -ENOENT; - - debug("%s: %s: ", __func__, prop_name); - - /* - * If we follow the pci bus bindings strictly, we should check - * the value of the node's parent node's #address-cells and - * #size-cells. They need to be 3 and 2 accordingly. However, - * for simplicity we skip the check here. - */ - cell = fdt_getprop(blob, node, prop_name, &len); - if (!cell) - goto fail; - - if ((len % FDT_PCI_REG_SIZE) == 0) { - int num = len / FDT_PCI_REG_SIZE; - int i; - - for (i = 0; i < num; i++) { - debug("pci address #%d: %08lx %08lx %08lx\n", i, - (ulong)fdt32_to_cpu(cell[0]), - (ulong)fdt32_to_cpu(cell[1]), - (ulong)fdt32_to_cpu(cell[2])); - if ((fdt32_to_cpu(*cell) & type) == type) { - addr->phys_hi = fdt32_to_cpu(cell[0]); - addr->phys_mid = fdt32_to_cpu(cell[1]); - addr->phys_lo = fdt32_to_cpu(cell[1]); - break; - } - - cell += (FDT_PCI_ADDR_CELLS + - FDT_PCI_SIZE_CELLS); - } - - if (i == num) { - ret = -ENXIO; - goto fail; - } - - return 0; - } - - ret = -EINVAL; - -fail: - debug("(not found)\n"); - return ret; -} - int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device) { const char *list, *end; @@ -274,7 +227,7 @@ int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device) return -ENOENT; } -int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr, +int fdtdec_get_pci_bar32(const struct udevice *dev, struct fdt_pci_addr *addr, u32 *bar) { int barnum; @@ -294,7 +247,7 @@ int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr, uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name, uint64_t default_val) { - const uint64_t *cell64; + const unaligned_fdt64_t *cell64; int length; cell64 = fdt_getprop(blob, node, prop_name, &length); @@ -859,17 +812,6 @@ int fdtdec_parse_phandle_with_args(const void *blob, int src_node, return rc; } -int fdtdec_get_child_count(const void *blob, int node) -{ - int subnode; - int num = 0; - - fdt_for_each_subnode(subnode, blob, node) - num++; - - return num; -} - int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name, u8 *array, int count) { @@ -1261,6 +1203,35 @@ __weak void *board_fdt_blob_setup(void) } #endif +int fdtdec_set_ethernet_mac_address(void *fdt, const u8 *mac, size_t size) +{ + const char *path; + int offset, err; + + if (!is_valid_ethaddr(mac)) + return -EINVAL; + + path = fdt_get_alias(fdt, "ethernet"); + if (!path) + return 0; + + debug("ethernet alias found: %s\n", path); + + offset = fdt_path_offset(fdt, path); + if (offset < 0) { + debug("ethernet alias points to absent node %s\n", path); + return -ENOENT; + } + + err = fdt_setprop_inplace(fdt, offset, "local-mac-address", mac, size); + if (err < 0) + return err; + + debug("MAC address: %pM\n", mac); + + return 0; +} + static int fdtdec_init_reserved_memory(void *blob) { int na, ns, node, err; @@ -1300,6 +1271,7 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, fdt32_t cells[4] = {}, *ptr = cells; uint32_t upper, lower, phandle; int parent, node, na, ns, err; + fdt_size_t size; char name[64]; /* create an empty /reserved-memory node if one doesn't exist */ @@ -1330,8 +1302,10 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, continue; } - if (addr == carveout->start && (addr + size) == carveout->end) { - *phandlep = fdt_get_phandle(blob, node); + if (addr == carveout->start && (addr + size - 1) == + carveout->end) { + if (phandlep) + *phandlep = fdt_get_phandle(blob, node); return 0; } } @@ -1340,7 +1314,8 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, * Unpack the start address and generate the name of the new node * base on the basename and the unit-address. */ - lower = fdt_addr_unpack(carveout->start, &upper); + upper = upper_32_bits(carveout->start); + lower = lower_32_bits(carveout->start); if (na > 1 && upper > 0) snprintf(name, sizeof(name), "%s@%x,%x", basename, upper, @@ -1359,13 +1334,15 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, if (node < 0) return node; - err = fdt_generate_phandle(blob, &phandle); - if (err < 0) - return err; + if (phandlep) { + err = fdt_generate_phandle(blob, &phandle); + if (err < 0) + return err; - err = fdtdec_set_phandle(blob, node, phandle); - if (err < 0) - return err; + err = fdtdec_set_phandle(blob, node, phandle); + if (err < 0) + return err; + } /* store one or two address cells */ if (na > 1) @@ -1374,7 +1351,9 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, *ptr++ = cpu_to_fdt32(lower); /* store one or two size cells */ - lower = fdt_size_unpack(carveout->end - carveout->start + 1, &upper); + size = carveout->end - carveout->start + 1; + upper = upper_32_bits(size); + lower = lower_32_bits(size); if (ns > 1) *ptr++ = cpu_to_fdt32(upper); @@ -1446,14 +1425,9 @@ int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, const struct fdt_memory *carveout) { uint32_t phandle; - int err, offset; + int err, offset, len; fdt32_t value; - - /* XXX implement support for multiple phandles */ - if (index > 0) { - debug("invalid index %u\n", index); - return -FDT_ERR_BADOFFSET; - } + void *prop; err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle); if (err < 0) { @@ -1469,18 +1443,45 @@ int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, value = cpu_to_fdt32(phandle); - err = fdt_setprop(blob, offset, prop_name, &value, sizeof(value)); + if (!fdt_getprop(blob, offset, prop_name, &len)) { + if (len == -FDT_ERR_NOTFOUND) + len = 0; + else + return len; + } + + if ((index + 1) * sizeof(value) > len) { + err = fdt_setprop_placeholder(blob, offset, prop_name, + (index + 1) * sizeof(value), + &prop); + if (err < 0) { + debug("failed to resize reserved memory property: %s\n", + fdt_strerror(err)); + return err; + } + } + + err = fdt_setprop_inplace_namelen_partial(blob, offset, prop_name, + strlen(prop_name), + index * sizeof(value), + &value, sizeof(value)); if (err < 0) { - debug("failed to set %s property for node %s: %d\n", prop_name, - node, err); + debug("failed to update %s property for node %s: %s\n", + prop_name, node, fdt_strerror(err)); return err; } return 0; } +__weak int fdtdec_board_setup(const void *fdt_blob) +{ + return 0; +} + int fdtdec_setup(void) { + int ret; #if CONFIG_IS_ENABLED(OF_CONTROL) # if CONFIG_IS_ENABLED(MULTI_DTB_FIT) void *fdt_blob; @@ -1500,16 +1501,14 @@ int fdtdec_setup(void) puts("Failed to read control FDT\n"); return -1; } +# elif defined(CONFIG_OF_PRIOR_STAGE) + gd->fdt_blob = (void *)prior_stage_fdt_address; # endif # ifndef CONFIG_SPL_BUILD /* Allow the early environment to override the fdt address */ -# if CONFIG_IS_ENABLED(OF_PRIOR_STAGE) - gd->fdt_blob = (void *)prior_stage_fdt_address; -# else gd->fdt_blob = map_sysmem (env_get_ulong("fdtcontroladdr", 16, (unsigned long)map_to_sysmem(gd->fdt_blob)), 0); -# endif # endif # if CONFIG_IS_ENABLED(MULTI_DTB_FIT) @@ -1535,7 +1534,10 @@ int fdtdec_setup(void) # endif #endif - return fdtdec_prepare_fdt(); + ret = fdtdec_prepare_fdt(); + if (!ret) + ret = fdtdec_board_setup(gd->fdt_blob); + return ret; } #if CONFIG_IS_ENABLED(MULTI_DTB_FIT)