efi_loader: efi_dp_from_file() expect UTF-8 path
[oweals/u-boot.git] / lib / fdtdec.c
index d247141f0b39ff9274b27fcc6cc3484ed2f6927f..3ee786b57940df4b12f89cce3003f2c2a252c9e0 100644 (file)
@@ -45,7 +45,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"),
        COMPAT(SAMSUNG_EXYNOS_MIPI_DSI, "samsung,exynos-mipi-dsi"),
        COMPAT(SAMSUNG_EXYNOS_DWMMC, "samsung,exynos-dwmmc"),
-       COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
+       COMPAT(GENERIC_SPI_FLASH, "jedec,spi-nor"),
        COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
        COMPAT(INTEL_MICROCODE, "intel,microcode"),
        COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"),
@@ -1261,11 +1261,33 @@ __weak void *board_fdt_blob_setup(void)
 }
 #endif
 
-int fdtdec_set_phandle(void *blob, int node, uint32_t phandle)
+int fdtdec_set_ethernet_mac_address(void *fdt, const u8 *mac, size_t size)
 {
-       fdt32_t value = cpu_to_fdt32(phandle);
+       const char *path;
+       int offset, err;
 
-       return fdt_setprop(blob, node, "phandle", &value, sizeof(value));
+       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)
@@ -1307,6 +1329,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 */
@@ -1347,7 +1370,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,
@@ -1381,7 +1405,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);
@@ -1399,6 +1425,93 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename,
        return 0;
 }
 
+int fdtdec_get_carveout(const void *blob, const char *node, const char *name,
+                       unsigned int index, struct fdt_memory *carveout)
+{
+       const fdt32_t *prop;
+       uint32_t phandle;
+       int offset, len;
+       fdt_size_t size;
+
+       offset = fdt_path_offset(blob, node);
+       if (offset < 0)
+               return offset;
+
+       prop = fdt_getprop(blob, offset, name, &len);
+       if (!prop) {
+               debug("failed to get %s for %s\n", name, node);
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       if ((len % sizeof(phandle)) != 0) {
+               debug("invalid phandle property\n");
+               return -FDT_ERR_BADPHANDLE;
+       }
+
+       if (len < (sizeof(phandle) * (index + 1))) {
+               debug("invalid phandle index\n");
+               return -FDT_ERR_BADPHANDLE;
+       }
+
+       phandle = fdt32_to_cpu(prop[index]);
+
+       offset = fdt_node_offset_by_phandle(blob, phandle);
+       if (offset < 0) {
+               debug("failed to find node for phandle %u\n", phandle);
+               return offset;
+       }
+
+       carveout->start = fdtdec_get_addr_size_auto_noparent(blob, offset,
+                                                            "reg", 0, &size,
+                                                            true);
+       if (carveout->start == FDT_ADDR_T_NONE) {
+               debug("failed to read address/size from \"reg\" property\n");
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       carveout->end = carveout->start + size - 1;
+
+       return 0;
+}
+
+int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name,
+                       unsigned int index, const char *name,
+                       const struct fdt_memory *carveout)
+{
+       uint32_t phandle;
+       int err, offset;
+       fdt32_t value;
+
+       /* XXX implement support for multiple phandles */
+       if (index > 0) {
+               debug("invalid index %u\n", index);
+               return -FDT_ERR_BADOFFSET;
+       }
+
+       err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle);
+       if (err < 0) {
+               debug("failed to add reserved memory: %d\n", err);
+               return err;
+       }
+
+       offset = fdt_path_offset(blob, node);
+       if (offset < 0) {
+               debug("failed to find offset for node %s: %d\n", node, offset);
+               return offset;
+       }
+
+       value = cpu_to_fdt32(phandle);
+
+       err = fdt_setprop(blob, offset, prop_name, &value, sizeof(value));
+       if (err < 0) {
+               debug("failed to set %s property for node %s: %d\n", prop_name,
+                     node, err);
+               return err;
+       }
+
+       return 0;
+}
+
 int fdtdec_setup(void)
 {
 #if CONFIG_IS_ENABLED(OF_CONTROL)