X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=lib%2Ffdtdec.c;h=df9d9ae4333a3f82212ab5e84f92f1c7f53a924c;hb=5fbed8f2c63bde8a482ccba6bce6477346301cb4;hp=c4582eaccae7ae8c96dade8a46b21c2183b9e07a;hpb=b06c46de632c55f4c39d404c6f0f65e414b31050;p=people%2Fms%2Fu-boot.git diff --git a/lib/fdtdec.c b/lib/fdtdec.c index c4582eacca..df9d9ae433 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -83,8 +83,9 @@ const char *fdtdec_get_compatible(enum fdt_compat_id id) } fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node, - const char *prop_name, int index, int na, int ns, - fdt_size_t *sizep, bool translate) + const char *prop_name, int index, int na, + int ns, fdt_size_t *sizep, + bool translate) { const fdt32_t *prop, *prop_end; const fdt32_t *prop_addr, *prop_size, *prop_after_size; @@ -138,8 +139,9 @@ fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node, } fdt_addr_t fdtdec_get_addr_size_auto_parent(const void *blob, int parent, - int node, const char *prop_name, int index, fdt_size_t *sizep, - bool translate) + int node, const char *prop_name, + int index, fdt_size_t *sizep, + bool translate) { int na, ns; @@ -164,8 +166,9 @@ fdt_addr_t fdtdec_get_addr_size_auto_parent(const void *blob, int parent, } fdt_addr_t fdtdec_get_addr_size_auto_noparent(const void *blob, int node, - const char *prop_name, int index, fdt_size_t *sizep, - bool translate) + const char *prop_name, int index, + fdt_size_t *sizep, + bool translate) { int parent; @@ -182,7 +185,7 @@ fdt_addr_t fdtdec_get_addr_size_auto_noparent(const void *blob, int node, } fdt_addr_t fdtdec_get_addr_size(const void *blob, int node, - const char *prop_name, fdt_size_t *sizep) + const char *prop_name, fdt_size_t *sizep) { int ns = sizep ? (sizeof(fdt_size_t) / sizeof(fdt32_t)) : 0; @@ -191,15 +194,14 @@ fdt_addr_t fdtdec_get_addr_size(const void *blob, int node, ns, sizep, false); } -fdt_addr_t fdtdec_get_addr(const void *blob, int node, - const char *prop_name) +fdt_addr_t fdtdec_get_addr(const void *blob, int node, const char *prop_name) { return fdtdec_get_addr_size(blob, node, prop_name, NULL); } #if defined(CONFIG_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 char *prop_name, struct fdt_pci_addr *addr) { const u32 *cell; int len; @@ -231,10 +233,10 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type, addr->phys_mid = fdt32_to_cpu(cell[1]); addr->phys_lo = fdt32_to_cpu(cell[1]); break; - } else { - cell += (FDT_PCI_ADDR_CELLS + - FDT_PCI_SIZE_CELLS); } + + cell += (FDT_PCI_ADDR_CELLS + + FDT_PCI_SIZE_CELLS); } if (i == num) { @@ -243,10 +245,10 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type, } return 0; - } else { - ret = -EINVAL; } + ret = -EINVAL; + fail: debug("(not found)\n"); return ret; @@ -263,11 +265,9 @@ int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device) end = list + len; while (list < end) { - char *s; - len = strlen(list); if (len >= strlen("pciVVVV,DDDD")) { - s = strstr(list, "pci"); + char *s = strstr(list, "pci"); /* * check if the string is something like pciVVVV,DDDD.RR @@ -297,7 +297,7 @@ int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr, /* extract the bar number from fdt_pci_addr */ barnum = addr->phys_hi & 0xff; - if ((barnum < PCI_BASE_ADDRESS_0) || (barnum > PCI_CARDBUS_CIS)) + if (barnum < PCI_BASE_ADDRESS_0 || barnum > PCI_CARDBUS_CIS) return -EINVAL; barnum = (barnum - PCI_BASE_ADDRESS_0) / 4; @@ -308,7 +308,7 @@ int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr, #endif uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name, - uint64_t default_val) + uint64_t default_val) { const uint64_t *cell64; int length; @@ -333,7 +333,7 @@ int fdtdec_get_is_enabled(const void *blob, int node) */ cell = fdt_getprop(blob, node, "status", NULL); if (cell) - return 0 == strcmp(cell, "okay"); + return strcmp(cell, "okay") == 0; return 1; } @@ -343,20 +343,19 @@ enum fdt_compat_id fdtdec_lookup(const void *blob, int node) /* Search our drivers */ for (id = COMPAT_UNKNOWN; id < COMPAT_COUNT; id++) - if (0 == fdt_node_check_compatible(blob, node, - compat_names[id])) + if (fdt_node_check_compatible(blob, node, + compat_names[id]) == 0) return id; return COMPAT_UNKNOWN; } -int fdtdec_next_compatible(const void *blob, int node, - enum fdt_compat_id id) +int fdtdec_next_compatible(const void *blob, int node, enum fdt_compat_id id) { return fdt_node_offset_by_compatible(blob, node, compat_names[id]); } int fdtdec_next_compatible_subnode(const void *blob, int node, - enum fdt_compat_id id, int *depthp) + enum fdt_compat_id id, int *depthp) { do { node = fdt_next_node(blob, node, depthp); @@ -370,8 +369,8 @@ int fdtdec_next_compatible_subnode(const void *blob, int node, return -FDT_ERR_NOTFOUND; } -int fdtdec_next_alias(const void *blob, const char *name, - enum fdt_compat_id id, int *upto) +int fdtdec_next_alias(const void *blob, const char *name, enum fdt_compat_id id, + int *upto) { #define MAX_STR_LEN 20 char str[MAX_STR_LEN + 20]; @@ -393,7 +392,8 @@ int fdtdec_next_alias(const void *blob, const char *name, } int fdtdec_find_aliases_for_id(const void *blob, const char *name, - enum fdt_compat_id id, int *node_list, int maxcount) + enum fdt_compat_id id, int *node_list, + int maxcount) { memset(node_list, '\0', sizeof(*node_list) * maxcount); @@ -402,7 +402,8 @@ int fdtdec_find_aliases_for_id(const void *blob, const char *name, /* TODO: Can we tighten this code up a little? */ int fdtdec_add_aliases_for_id(const void *blob, const char *name, - enum fdt_compat_id id, int *node_list, int maxcount) + enum fdt_compat_id id, int *node_list, + int maxcount) { int name_len = strlen(name); int nodes[maxcount]; @@ -429,7 +430,7 @@ int fdtdec_add_aliases_for_id(const void *blob, const char *name, } if (node >= 0) debug("%s: warning: maxcount exceeded with alias '%s'\n", - __func__, name); + __func__, name); /* Now find all the aliases */ for (offset = fdt_first_property_offset(blob, alias_node); @@ -452,7 +453,7 @@ int fdtdec_add_aliases_for_id(const void *blob, const char *name, number = simple_strtoul(path + name_len, NULL, 10); if (number < 0 || number >= maxcount) { debug("%s: warning: alias '%s' is out of range\n", - __func__, path); + __func__, path); continue; } @@ -498,7 +499,7 @@ int fdtdec_add_aliases_for_id(const void *blob, const char *name, if (!node_list[i]) { for (; j < maxcount; j++) if (nodes[j] && - fdtdec_get_is_enabled(blob, nodes[j])) + fdtdec_get_is_enabled(blob, nodes[j])) break; /* Have we run out of nodes to add? */ @@ -641,7 +642,8 @@ int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name) * @return pointer to cell, which is only valid if err == 0 */ static const void *get_prop_check_min_len(const void *blob, int node, - const char *prop_name, int min_len, int *err) + const char *prop_name, int min_len, + int *err) { const void *cell; int len; @@ -658,15 +660,17 @@ static const void *get_prop_check_min_len(const void *blob, int node, } int fdtdec_get_int_array(const void *blob, int node, const char *prop_name, - u32 *array, int count) + u32 *array, int count) { const u32 *cell; - int i, err = 0; + int err = 0; debug("%s: %s\n", __func__, prop_name); cell = get_prop_check_min_len(blob, node, prop_name, sizeof(u32) * count, &err); if (!err) { + int i; + for (i = 0; i < count; i++) array[i] = fdt32_to_cpu(cell[i]); } @@ -850,7 +854,7 @@ int fdtdec_get_child_count(const void *blob, int node) } int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name, - u8 *array, int count) + u8 *array, int count) { const u8 *cell; int err; @@ -862,7 +866,7 @@ int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name, } const u8 *fdtdec_locate_byte_array(const void *blob, int node, - const char *prop_name, int count) + const char *prop_name, int count) { const u8 *cell; int err; @@ -874,7 +878,7 @@ const u8 *fdtdec_locate_byte_array(const void *blob, int node, } int fdtdec_get_config_int(const void *blob, const char *prop_name, - int default_val) + int default_val) { int config_node; @@ -971,7 +975,8 @@ int fdt_get_resource(const void *fdt, int node, const char *property, while (ptr + na + ns <= end) { if (i == index) { - res->start = res->end = fdtdec_get_number(ptr, na); + res->start = fdtdec_get_number(ptr, na); + res->end = res->start; res->end += fdtdec_get_number(&ptr[na], ns) - 1; return 0; } @@ -1176,21 +1181,33 @@ int fdtdec_setup_memory_size(void) #if defined(CONFIG_NR_DRAM_BANKS) int fdtdec_setup_memory_banksize(void) { - int bank, ret, mem; + int bank, ret, mem, reg = 0; struct fdt_resource res; - mem = fdt_path_offset(gd->fdt_blob, "/memory"); + mem = fdt_node_offset_by_prop_value(gd->fdt_blob, -1, "device_type", + "memory", 7); if (mem < 0) { debug("%s: Missing /memory node\n", __func__); return -EINVAL; } for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { - ret = fdt_get_resource(gd->fdt_blob, mem, "reg", bank, &res); - if (ret == -FDT_ERR_NOTFOUND) - break; - if (ret != 0) + ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res); + if (ret == -FDT_ERR_NOTFOUND) { + reg = 0; + mem = fdt_node_offset_by_prop_value(gd->fdt_blob, mem, + "device_type", + "memory", 7); + if (mem == -FDT_ERR_NOTFOUND) + break; + + ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res); + if (ret == -FDT_ERR_NOTFOUND) + break; + } + if (ret != 0) { return -EINVAL; + } gd->bd->bi_dram[bank].start = (phys_addr_t)res.start; gd->bd->bi_dram[bank].size = @@ -1260,6 +1277,28 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) # endif #endif +#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) +/* + * For CONFIG_OF_SEPARATE, the board may optionally implement this to + * provide and/or fixup the fdt. + */ +__weak void *board_fdt_blob_setup(void) +{ + void *fdt_blob = NULL; +#ifdef CONFIG_SPL_BUILD + /* FDT is at end of BSS unless it is in a different memory region */ + if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) + fdt_blob = (ulong *)&_image_binary_end; + else + fdt_blob = (ulong *)&__bss_end; +#else + /* FDT is at end of image */ + fdt_blob = (ulong *)&_end; +#endif + return fdt_blob; +} +#endif + int fdtdec_setup(void) { #if CONFIG_IS_ENABLED(OF_CONTROL) @@ -1268,19 +1307,12 @@ int fdtdec_setup(void) # endif # ifdef CONFIG_OF_EMBED /* Get a pointer to the FDT */ - gd->fdt_blob = __dtb_dt_begin; -# elif defined CONFIG_OF_SEPARATE # ifdef CONFIG_SPL_BUILD - /* FDT is at end of BSS unless it is in a different memory region */ - if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) - gd->fdt_blob = (ulong *)&_image_binary_end; - else - gd->fdt_blob = (ulong *)&__bss_end; + gd->fdt_blob = __dtb_dt_spl_begin; # else - /* FDT is at end of image */ - gd->fdt_blob = (ulong *)&_end; + gd->fdt_blob = __dtb_dt_begin; # endif -# elif defined(CONFIG_OF_BOARD) +# elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) /* Allow the board to override the fdt address. */ gd->fdt_blob = board_fdt_blob_setup(); # elif defined(CONFIG_OF_HOSTFILE)