diff options
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/soc.c | 3 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra/board.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/dt-setup.c | 147 | ||||
-rw-r--r-- | arch/riscv/lib/fdt_fixup.c | 2 | ||||
-rw-r--r-- | board/nvidia/p2371-2180/p2371-2180.c | 94 | ||||
-rw-r--r-- | board/nvidia/p2771-0000/p2771-0000.c | 98 | ||||
-rw-r--r-- | board/nvidia/p3450-0000/p3450-0000.c | 96 | ||||
-rw-r--r-- | include/configs/tegra210-common.h | 2 | ||||
-rw-r--r-- | include/fdtdec.h | 39 | ||||
-rw-r--r-- | lib/fdtdec.c | 99 | ||||
-rw-r--r-- | lib/fdtdec_test.c | 7 | ||||
-rw-r--r-- | lib/optee/optee.c | 4 | ||||
-rw-r--r-- | test/dm/fdtdec.c | 28 |
13 files changed, 321 insertions, 308 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 41f3e95..adf3b4e 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -54,7 +54,8 @@ int ls_gic_rd_tables_init(void *blob) lpi_base.start = addr; lpi_base.end = addr + size - 1; - ret = fdtdec_add_reserved_memory(blob, "lpi_rd_table", &lpi_base, NULL, false); + ret = fdtdec_add_reserved_memory(blob, "lpi_rd_table", &lpi_base, NULL, + NULL, 0, 0); if (ret) { debug("%s: failed to add reserved memory\n", __func__); return ret; diff --git a/arch/arm/include/asm/arch-tegra/board.h b/arch/arm/include/asm/arch-tegra/board.h index 24d0db8..cd4d0ee 100644 --- a/arch/arm/include/asm/arch-tegra/board.h +++ b/arch/arm/include/asm/arch-tegra/board.h @@ -30,4 +30,14 @@ void pin_mux_nand(void); /* overridable NAND pinmux setup */ void pin_mux_mmc(void); /* overridable mmc pinmux setup */ void pin_mux_display(void); /* overridable DISPLAY pinmux setup */ +/* + * Helpers for various standard DT update mechanisms. + */ + +#if defined(CONFIG_ARM64) +void ft_mac_address_setup(void *fdt); +void ft_carveout_setup(void *fdt, const char *const *nodes, + unsigned int count); +#endif + #endif diff --git a/arch/arm/mach-tegra/dt-setup.c b/arch/arm/mach-tegra/dt-setup.c index 602b20e..c114947 100644 --- a/arch/arm/mach-tegra/dt-setup.c +++ b/arch/arm/mach-tegra/dt-setup.c @@ -4,6 +4,9 @@ */ #include <common.h> +#include <fdtdec.h> +#include <stdlib.h> +#include <asm/arch-tegra/cboot.h> #include <asm/arch-tegra/gpu.h> /* @@ -31,3 +34,147 @@ int ft_system_setup(void *blob, struct bd_info *bd) return 0; } + +#if defined(CONFIG_ARM64) +void ft_mac_address_setup(void *fdt) +{ + const void *cboot_fdt = (const void *)cboot_boot_x0; + uint8_t mac[ETH_ALEN], local_mac[ETH_ALEN]; + const char *path; + int offset, err; + + err = cboot_get_ethaddr(cboot_fdt, local_mac); + if (err < 0) + memset(local_mac, 0, ETH_ALEN); + + path = fdt_get_alias(fdt, "ethernet"); + if (!path) + return; + + debug("ethernet alias found: %s\n", path); + + offset = fdt_path_offset(fdt, path); + if (offset < 0) { + printf("ethernet alias points to absent node %s\n", path); + return; + } + + if (is_valid_ethaddr(local_mac)) { + err = fdt_setprop(fdt, offset, "local-mac-address", local_mac, + ETH_ALEN); + if (!err) + debug("Local MAC address set: %pM\n", local_mac); + } + + if (eth_env_get_enetaddr("ethaddr", mac)) { + if (memcmp(local_mac, mac, ETH_ALEN) != 0) { + err = fdt_setprop(fdt, offset, "mac-address", mac, + ETH_ALEN); + if (!err) + debug("MAC address set: %pM\n", mac); + } + } +} + +static int ft_copy_carveout(void *dst, const void *src, const char *node) +{ + const char *names = "memory-region-names"; + struct fdt_memory carveout; + unsigned int index = 0; + int err, offset, len; + const void *prop; + + while (true) { + const char **compatibles = NULL; + unsigned int num_compatibles; + unsigned long flags; + char *copy = NULL; + const char *name; + + err = fdtdec_get_carveout(src, node, "memory-region", index, + &carveout, &name, &compatibles, + &num_compatibles, &flags); + if (err < 0) { + if (err != -FDT_ERR_NOTFOUND) + printf("failed to get carveout for %s: %d\n", + node, err); + else + break; + + return err; + } + + if (name) { + const char *ptr = strchr(name, '@'); + + if (ptr) { + copy = strndup(name, ptr - name); + name = copy; + } + } else { + name = "carveout"; + } + + err = fdtdec_set_carveout(dst, node, "memory-region", index, + &carveout, name, compatibles, + num_compatibles, flags); + if (err < 0) { + printf("failed to set carveout for %s: %d\n", node, + err); + return err; + } + + if (copy) + free(copy); + + index++; + } + + offset = fdt_path_offset(src, node); + if (offset < 0) { + debug("failed to find source offset for %s: %s\n", node, + fdt_strerror(err)); + return err; + } + + prop = fdt_getprop(src, offset, names, &len); + if (prop) { + offset = fdt_path_offset(dst, node); + if (offset < 0) { + debug("failed to find destination offset for %s: %s\n", + node, fdt_strerror(err)); + return err; + } + + err = fdt_setprop(dst, offset, "memory-region-names", prop, + len); + if (err < 0) { + debug("failed to copy \"%s\" property: %s\n", names, + fdt_strerror(err)); + return err; + } + } + + return 0; +} + +void ft_carveout_setup(void *fdt, const char * const *nodes, unsigned int count) +{ + const void *cboot_fdt = (const void *)cboot_boot_x0; + unsigned int i; + int err; + + for (i = 0; i < count; i++) { + printf("copying carveout for %s...\n", nodes[i]); + + err = ft_copy_carveout(fdt, cboot_fdt, nodes[i]); + if (err < 0) { + if (err != -FDT_ERR_NOTFOUND) + printf("failed to copy carveout for %s: %d\n", + nodes[i], err); + + continue; + } + } +} +#endif diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c index 61cf893..36c16e9 100644 --- a/arch/riscv/lib/fdt_fixup.c +++ b/arch/riscv/lib/fdt_fixup.c @@ -75,7 +75,7 @@ int riscv_fdt_copy_resv_mem_node(const void *src, void *dst) pmp_mem.start = addr; pmp_mem.end = addr + size - 1; err = fdtdec_add_reserved_memory(dst, basename, &pmp_mem, - &phandle, false); + NULL, 0, &phandle, 0); if (err < 0 && err != -FDT_ERR_EXISTS) { log_err("failed to add reserved memory: %d\n", err); return err; diff --git a/board/nvidia/p2371-2180/p2371-2180.c b/board/nvidia/p2371-2180/p2371-2180.c index 7423a97..816c7be 100644 --- a/board/nvidia/p2371-2180/p2371-2180.c +++ b/board/nvidia/p2371-2180/p2371-2180.c @@ -10,11 +10,12 @@ #include <i2c.h> #include <log.h> #include <net.h> +#include <stdlib.h> #include <linux/bitops.h> #include <linux/libfdt.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> -#include <asm/arch-tegra/cboot.h> +#include <asm/arch-tegra/board.h> #include "../p2571/max77620_init.h" void pin_mux_mmc(void) @@ -83,95 +84,16 @@ int tegra_pcie_board_init(void) } #endif /* PCI */ -static void ft_mac_address_setup(void *fdt) -{ - const void *cboot_fdt = (const void *)cboot_boot_x0; - uint8_t mac[ETH_ALEN], local_mac[ETH_ALEN]; - const char *path; - int offset, err; - - err = cboot_get_ethaddr(cboot_fdt, local_mac); - if (err < 0) - memset(local_mac, 0, ETH_ALEN); - - path = fdt_get_alias(fdt, "ethernet"); - if (!path) - return; - - debug("ethernet alias found: %s\n", path); - - offset = fdt_path_offset(fdt, path); - if (offset < 0) { - printf("ethernet alias points to absent node %s\n", path); - return; - } - - if (is_valid_ethaddr(local_mac)) { - err = fdt_setprop(fdt, offset, "local-mac-address", local_mac, - ETH_ALEN); - if (!err) - debug("Local MAC address set: %pM\n", local_mac); - } - - if (eth_env_get_enetaddr("ethaddr", mac)) { - if (memcmp(local_mac, mac, ETH_ALEN) != 0) { - err = fdt_setprop(fdt, offset, "mac-address", mac, - ETH_ALEN); - if (!err) - debug("MAC address set: %pM\n", mac); - } - } -} - -static int ft_copy_carveout(void *dst, const void *src, const char *node) -{ - struct fdt_memory fb; - int err; - - err = fdtdec_get_carveout(src, node, "memory-region", 0, &fb); - if (err < 0) { - if (err != -FDT_ERR_NOTFOUND) - printf("failed to get carveout for %s: %d\n", node, - err); - - return err; - } - - err = fdtdec_set_carveout(dst, node, "memory-region", 0, "framebuffer", - &fb); - if (err < 0) { - printf("failed to set carveout for %s: %d\n", node, err); - return err; - } - - return 0; -} - -static void ft_carveout_setup(void *fdt) -{ - const void *cboot_fdt = (const void *)cboot_boot_x0; - static const char * const nodes[] = { - "/host1x@50000000/dc@54200000", - "/host1x@50000000/dc@54240000", - }; - unsigned int i; - int err; - - for (i = 0; i < ARRAY_SIZE(nodes); i++) { - err = ft_copy_carveout(fdt, cboot_fdt, nodes[i]); - if (err < 0) { - if (err != -FDT_ERR_NOTFOUND) - printf("failed to copy carveout for %s: %d\n", - nodes[i], err); - continue; - } - } -} +static const char * const nodes[] = { + "/host1x@50000000/dc@54200000", + "/host1x@50000000/dc@54240000", + "/external-memory-controller@7001b000", +}; int ft_board_setup(void *fdt, struct bd_info *bd) { ft_mac_address_setup(fdt); - ft_carveout_setup(fdt); + ft_carveout_setup(fdt, nodes, ARRAY_SIZE(nodes)); return 0; } diff --git a/board/nvidia/p2771-0000/p2771-0000.c b/board/nvidia/p2771-0000/p2771-0000.c index 508c4d2..5ff89c4 100644 --- a/board/nvidia/p2771-0000/p2771-0000.c +++ b/board/nvidia/p2771-0000/p2771-0000.c @@ -9,8 +9,9 @@ #include <i2c.h> #include <log.h> #include <net.h> +#include <stdlib.h> #include <linux/libfdt.h> -#include <asm/arch-tegra/cboot.h> +#include <asm/arch-tegra/board.h> #include "../p2571/max77620_init.h" void pin_mux_mmc(void) @@ -59,99 +60,16 @@ int tegra_pcie_board_init(void) } #endif -static void ft_mac_address_setup(void *fdt) -{ - const void *cboot_fdt = (const void *)cboot_boot_x0; - uint8_t mac[ETH_ALEN], local_mac[ETH_ALEN]; - const char *path; - int offset, err; - - err = cboot_get_ethaddr(cboot_fdt, local_mac); - if (err < 0) - memset(local_mac, 0, ETH_ALEN); - - path = fdt_get_alias(fdt, "ethernet"); - if (!path) - return; - - debug("ethernet alias found: %s\n", path); - - offset = fdt_path_offset(fdt, path); - if (offset < 0) { - printf("ethernet alias points to absent node %s\n", path); - return; - } - - if (is_valid_ethaddr(local_mac)) { - err = fdt_setprop(fdt, offset, "local-mac-address", local_mac, - ETH_ALEN); - if (!err) - debug("Local MAC address set: %pM\n", local_mac); - } - - if (eth_env_get_enetaddr("ethaddr", mac)) { - if (memcmp(local_mac, mac, ETH_ALEN) != 0) { - err = fdt_setprop(fdt, offset, "mac-address", mac, - ETH_ALEN); - if (!err) - debug("MAC address set: %pM\n", mac); - } - } -} - -static int ft_copy_carveout(void *dst, const void *src, const char *node) -{ - struct fdt_memory fb; - int err; - - err = fdtdec_get_carveout(src, node, "memory-region", 0, &fb); - if (err < 0) { - if (err != -FDT_ERR_NOTFOUND) - printf("failed to get carveout for %s: %d\n", node, - err); - - return err; - } - - err = fdtdec_set_carveout(dst, node, "memory-region", 0, "framebuffer", - &fb); - if (err < 0) { - printf("failed to set carveout for %s: %d\n", node, err); - return err; - } - - return 0; -} - -static void ft_carveout_setup(void *fdt) -{ - const void *cboot_fdt = (const void *)cboot_boot_x0; - static const char * const nodes[] = { - "/host1x@13e00000/display-hub@15200000/display@15200000", - "/host1x@13e00000/display-hub@15200000/display@15210000", - "/host1x@13e00000/display-hub@15200000/display@15220000", - }; - unsigned int i; - int err; - - for (i = 0; i < ARRAY_SIZE(nodes); i++) { - printf("copying carveout for %s...\n", nodes[i]); - - err = ft_copy_carveout(fdt, cboot_fdt, nodes[i]); - if (err < 0) { - if (err != -FDT_ERR_NOTFOUND) - printf("failed to copy carveout for %s: %d\n", - nodes[i], err); - - continue; - } - } -} +static const char * const nodes[] = { + "/host1x@13e00000/display-hub@15200000/display@15200000", + "/host1x@13e00000/display-hub@15200000/display@15210000", + "/host1x@13e00000/display-hub@15200000/display@15220000", +}; int ft_board_setup(void *fdt, struct bd_info *bd) { ft_mac_address_setup(fdt); - ft_carveout_setup(fdt); + ft_carveout_setup(fdt, nodes, ARRAY_SIZE(nodes)); return 0; } diff --git a/board/nvidia/p3450-0000/p3450-0000.c b/board/nvidia/p3450-0000/p3450-0000.c index e6b6696..fb1a224 100644 --- a/board/nvidia/p3450-0000/p3450-0000.c +++ b/board/nvidia/p3450-0000/p3450-0000.c @@ -11,9 +11,9 @@ #include <linux/bitops.h> #include <linux/libfdt.h> #include <pca953x.h> -#include <asm/arch-tegra/cboot.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> +#include <asm/arch-tegra/board.h> #include "../p2571/max77620_init.h" void pin_mux_mmc(void) @@ -82,98 +82,16 @@ int tegra_pcie_board_init(void) } #endif /* PCI */ -static void ft_mac_address_setup(void *fdt) -{ - const void *cboot_fdt = (const void *)cboot_boot_x0; - uint8_t mac[ETH_ALEN], local_mac[ETH_ALEN]; - const char *path; - int offset, err; - - err = cboot_get_ethaddr(cboot_fdt, local_mac); - if (err < 0) - memset(local_mac, 0, ETH_ALEN); - - path = fdt_get_alias(fdt, "ethernet"); - if (!path) - return; - - debug("ethernet alias found: %s\n", path); - - offset = fdt_path_offset(fdt, path); - if (offset < 0) { - printf("ethernet alias points to absent node %s\n", path); - return; - } - - if (is_valid_ethaddr(local_mac)) { - err = fdt_setprop(fdt, offset, "local-mac-address", local_mac, - ETH_ALEN); - if (!err) - debug("Local MAC address set: %pM\n", local_mac); - } - - if (eth_env_get_enetaddr("ethaddr", mac)) { - if (memcmp(local_mac, mac, ETH_ALEN) != 0) { - err = fdt_setprop(fdt, offset, "mac-address", mac, - ETH_ALEN); - if (!err) - debug("MAC address set: %pM\n", mac); - } - } -} - -static int ft_copy_carveout(void *dst, const void *src, const char *node) -{ - struct fdt_memory fb; - int err; - - err = fdtdec_get_carveout(src, node, "memory-region", 0, &fb); - if (err < 0) { - if (err != -FDT_ERR_NOTFOUND) - printf("failed to get carveout for %s: %d\n", node, - err); - - return err; - } - - err = fdtdec_set_carveout(dst, node, "memory-region", 0, "framebuffer", - &fb); - if (err < 0) { - printf("failed to set carveout for %s: %d\n", node, err); - return err; - } - - return 0; -} - -static void ft_carveout_setup(void *fdt) -{ - const void *cboot_fdt = (const void *)cboot_boot_x0; - static const char * const nodes[] = { - "/host1x@50000000/dc@54200000", - "/host1x@50000000/dc@54240000", - }; - unsigned int i; - int err; - - for (i = 0; i < ARRAY_SIZE(nodes); i++) { - printf("copying carveout for %s...\n", nodes[i]); - - err = ft_copy_carveout(fdt, cboot_fdt, nodes[i]); - if (err < 0) { - if (err != -FDT_ERR_NOTFOUND) - printf("failed to copy carveout for %s: %d\n", - nodes[i], err); - - continue; - } - } -} +static const char * const nodes[] = { + "/host1x@50000000/dc@54200000", + "/host1x@50000000/dc@54240000", + "/external-memory-controller@7001b000", +}; int ft_board_setup(void *fdt, struct bd_info *bd) { ft_mac_address_setup(fdt); - ft_carveout_setup(fdt); + ft_carveout_setup(fdt, nodes, ARRAY_SIZE(nodes)); return 0; } diff --git a/include/configs/tegra210-common.h b/include/configs/tegra210-common.h index c36bdb0..3ba12be 100644 --- a/include/configs/tegra210-common.h +++ b/include/configs/tegra210-common.h @@ -44,7 +44,7 @@ "kernel_addr_r=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \ "fdtfile=" FDTFILE "\0" \ "fdt_addr_r=0x83000000\0" \ - "ramdisk_addr_r=0x83200000\0" + "ramdisk_addr_r=0x83420000\0" /* For USB EHCI controller */ #define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10 diff --git a/include/fdtdec.h b/include/fdtdec.h index 23efbe7..f94d1f4 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -977,6 +977,9 @@ static inline int fdtdec_set_phandle(void *blob, int node, uint32_t phandle) return fdt_setprop_u32(blob, node, "phandle", phandle); } +/* add "no-map" property */ +#define FDTDEC_RESERVED_MEMORY_NO_MAP (1 << 0) + /** * fdtdec_add_reserved_memory() - add or find a reserved-memory node * @@ -995,7 +998,8 @@ static inline int fdtdec_set_phandle(void *blob, int node, uint32_t phandle) * }; * uint32_t phandle; * - * fdtdec_add_reserved_memory(fdt, "framebuffer", &fb, &phandle, false); + * fdtdec_add_reserved_memory(fdt, "framebuffer", &fb, NULL, 0, &phandle, + * 0); * * This results in the following subnode being added to the top-level * /reserved-memory node: @@ -1020,14 +1024,17 @@ static inline int fdtdec_set_phandle(void *blob, int node, uint32_t phandle) * @param blob FDT blob * @param basename base name of the node to create * @param carveout information about the carveout region + * @param compatibles list of compatible strings for the carveout region + * @param count number of compatible strings for the carveout region * @param phandlep return location for the phandle of the carveout region * can be NULL if no phandle should be added - * @param no_map add "no-map" property if true + * @param flags bitmask of flags to set for the carveout region * @return 0 on success or a negative error code on failure */ int fdtdec_add_reserved_memory(void *blob, const char *basename, const struct fdt_memory *carveout, - uint32_t *phandlep, bool no_map); + const char **compatibles, unsigned int count, + uint32_t *phandlep, unsigned long flags); /** * fdtdec_get_carveout() - reads a carveout from an FDT @@ -1038,14 +1045,21 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, * * @param blob FDT blob * @param node name of a node - * @param name name of the property in the given node that contains + * @param prop_name name of the property in the given node that contains * the phandle for the carveout * @param index index of the phandle for which to read the carveout * @param carveout return location for the carveout information + * @param name return location for the carveout name + * @param compatiblesp return location for compatible strings + * @param countp return location for the number of compatible strings + * @param flags return location for the flags of the carveout * @return 0 on success or a negative error code on failure */ -int fdtdec_get_carveout(const void *blob, const char *node, const char *name, - unsigned int index, struct fdt_memory *carveout); +int fdtdec_get_carveout(const void *blob, const char *node, + const char *prop_name, unsigned int index, + struct fdt_memory *carveout, const char **name, + const char ***compatiblesp, unsigned int *countp, + unsigned long *flags); /** * fdtdec_set_carveout() - sets a carveout region for a given node @@ -1063,7 +1077,8 @@ int fdtdec_get_carveout(const void *blob, const char *node, const char *name, * .end = 0x934b2fff, * }; * - * fdtdec_set_carveout(fdt, node, "memory-region", 0, "framebuffer", &fb); + * fdtdec_set_carveout(fdt, node, "memory-region", 0, "framebuffer", NULL, + * 0, &fb, 0); * * dc@54200000 is a display controller and was set up by the bootloader to * scan out the framebuffer specified by "fb". This would cause the following @@ -1100,13 +1115,17 @@ int fdtdec_get_carveout(const void *blob, const char *node, const char *name, * @param prop_name name of the property in which to store the phandle of * the carveout * @param index index of the phandle to store - * @param name base name of the reserved-memory node to create * @param carveout information about the carveout to add + * @param name base name of the reserved-memory node to create + * @param compatibles compatible strings to set for the carveout + * @param count number of compatible strings + * @param flags bitmask of flags to set for the carveout * @return 0 on success or a negative error code on failure */ int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, - unsigned int index, const char *name, - const struct fdt_memory *carveout); + unsigned int index, const struct fdt_memory *carveout, + const char *name, const char **compatibles, + unsigned int count, unsigned long flags); /** * Set up the device tree ready for use diff --git a/lib/fdtdec.c b/lib/fdtdec.c index af92e65..ad090ea 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1293,7 +1293,8 @@ static int fdtdec_init_reserved_memory(void *blob) int fdtdec_add_reserved_memory(void *blob, const char *basename, const struct fdt_memory *carveout, - uint32_t *phandlep, bool no_map) + const char **compatibles, unsigned int count, + uint32_t *phandlep, unsigned long flags) { fdt32_t cells[4] = {}, *ptr = cells; uint32_t upper, lower, phandle; @@ -1363,6 +1364,12 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, if (node < 0) return node; + if (flags & FDTDEC_RESERVED_MEMORY_NO_MAP) { + err = fdt_setprop(blob, node, "no-map", NULL, 0); + if (err < 0) + return err; + } + if (phandlep) { err = fdt_generate_phandle(blob, &phandle); if (err < 0) @@ -1393,8 +1400,24 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, if (err < 0) return err; - if (no_map) { - err = fdt_setprop(blob, node, "no-map", NULL, 0); + if (compatibles && count > 0) { + size_t length = 0, len = 0; + unsigned int i; + char *buffer; + + for (i = 0; i < count; i++) + length += strlen(compatibles[i]) + 1; + + buffer = malloc(length); + if (!buffer) + return -FDT_ERR_INTERNAL; + + for (i = 0; i < count; i++) + len += strlcpy(buffer + len, compatibles[i], + length - len) + 1; + + err = fdt_setprop(blob, node, "compatible", buffer, length); + free(buffer); if (err < 0) return err; } @@ -1406,8 +1429,11 @@ 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) +int fdtdec_get_carveout(const void *blob, const char *node, + const char *prop_name, unsigned int index, + struct fdt_memory *carveout, const char **name, + const char ***compatiblesp, unsigned int *countp, + unsigned long *flags) { const fdt32_t *prop; uint32_t phandle; @@ -1418,9 +1444,9 @@ int fdtdec_get_carveout(const void *blob, const char *node, const char *name, if (offset < 0) return offset; - prop = fdt_getprop(blob, offset, name, &len); + prop = fdt_getprop(blob, offset, prop_name, &len); if (!prop) { - debug("failed to get %s for %s\n", name, node); + debug("failed to get %s for %s\n", prop_name, node); return -FDT_ERR_NOTFOUND; } @@ -1431,7 +1457,7 @@ int fdtdec_get_carveout(const void *blob, const char *node, const char *name, if (len < (sizeof(phandle) * (index + 1))) { debug("invalid phandle index\n"); - return -FDT_ERR_BADPHANDLE; + return -FDT_ERR_NOTFOUND; } phandle = fdt32_to_cpu(prop[index]); @@ -1442,6 +1468,48 @@ int fdtdec_get_carveout(const void *blob, const char *node, const char *name, return offset; } + if (name) + *name = fdt_get_name(blob, offset, NULL); + + if (compatiblesp) { + const char **compatibles = NULL; + const char *start, *end, *ptr; + unsigned int count = 0; + + prop = fdt_getprop(blob, offset, "compatible", &len); + if (!prop) + goto skip_compat; + + start = ptr = (const char *)prop; + end = start + len; + + while (ptr < end) { + ptr = strchrnul(ptr, '\0'); + count++; + ptr++; + } + + compatibles = malloc(sizeof(ptr) * count); + if (!compatibles) + return -FDT_ERR_INTERNAL; + + ptr = start; + count = 0; + + while (ptr < end) { + compatibles[count] = ptr; + ptr = strchrnul(ptr, '\0'); + count++; + ptr++; + } + +skip_compat: + *compatiblesp = compatibles; + + if (countp) + *countp = count; + } + carveout->start = fdtdec_get_addr_size_auto_noparent(blob, offset, "reg", 0, &size, true); @@ -1452,19 +1520,28 @@ int fdtdec_get_carveout(const void *blob, const char *node, const char *name, carveout->end = carveout->start + size - 1; + if (flags) { + *flags = 0; + + if (fdtdec_get_bool(blob, offset, "no-map")) + *flags |= FDTDEC_RESERVED_MEMORY_NO_MAP; + } + 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) + unsigned int index, const struct fdt_memory *carveout, + const char *name, const char **compatibles, + unsigned int count, unsigned long flags) { uint32_t phandle; int err, offset, len; fdt32_t value; void *prop; - err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle, false); + err = fdtdec_add_reserved_memory(blob, name, carveout, compatibles, + count, &phandle, flags); if (err < 0) { debug("failed to add reserved memory: %d\n", err); return err; diff --git a/lib/fdtdec_test.c b/lib/fdtdec_test.c index e0c6e09..85351c7 100644 --- a/lib/fdtdec_test.c +++ b/lib/fdtdec_test.c @@ -189,8 +189,8 @@ static int make_fdt_carveout_device(void *fdt, uint32_t na, uint32_t ns) offset = CHECK(fdt_add_subnode(fdt, 0, name + 1)); CHECK(fdt_setprop(fdt, offset, "reg", cells, (na + ns) * sizeof(*cells))); - return fdtdec_set_carveout(fdt, name, "memory-region", 0, - "framebuffer", &carveout); + return fdtdec_set_carveout(fdt, name, "memory-region", 0, &carveout, + "framebuffer", NULL, 0, 0); } static int check_fdt_carveout(void *fdt, uint32_t address_cells, @@ -214,7 +214,8 @@ static int check_fdt_carveout(void *fdt, uint32_t address_cells, printf("carveout: %pap-%pap na=%u ns=%u: ", &expected.start, &expected.end, address_cells, size_cells); - CHECK(fdtdec_get_carveout(fdt, name, "memory-region", 0, &carveout)); + CHECK(fdtdec_get_carveout(fdt, name, "memory-region", 0, &carveout, + NULL, NULL, NULL, NULL)); if ((carveout.start != expected.start) || (carveout.end != expected.end)) { diff --git a/lib/optee/optee.c b/lib/optee/optee.c index 766d0d9..b036224 100644 --- a/lib/optee/optee.c +++ b/lib/optee/optee.c @@ -161,6 +161,7 @@ int optee_copy_fdt_nodes(void *new_blob) .start = res.start, .end = res.end, }; + unsigned long flags = FDTDEC_RESERVED_MEMORY_NO_MAP; char *oldname, *nodename, *tmp; oldname = strdup(name); @@ -177,7 +178,8 @@ int optee_copy_fdt_nodes(void *new_blob) ret = fdtdec_add_reserved_memory(new_blob, nodename, &carveout, - NULL, true); + NULL, 0, + NULL, flags); free(oldname); if (ret < 0) diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c index 1f630ea..087d484 100644 --- a/test/dm/fdtdec.c +++ b/test/dm/fdtdec.c @@ -28,21 +28,18 @@ static int dm_test_fdtdec_set_carveout(struct unit_test_state *uts) resv.start = 0x1000; resv.end = 0x2000; - ut_assertok(fdtdec_set_carveout(blob, "/a-test", - "memory-region", 2, "test_resv1", - &resv)); + ut_assertok(fdtdec_set_carveout(blob, "/a-test", "memory-region", 2, + &resv, "test_resv1", NULL, 0, 0)); resv.start = 0x10000; resv.end = 0x20000; - ut_assertok(fdtdec_set_carveout(blob, "/a-test", - "memory-region", 1, "test_resv2", - &resv)); + ut_assertok(fdtdec_set_carveout(blob, "/a-test", "memory-region", 1, + &resv, "test_resv2", NULL, 0, 0)); resv.start = 0x100000; resv.end = 0x200000; - ut_assertok(fdtdec_set_carveout(blob, "/a-test", - "memory-region", 0, "test_resv3", - &resv)); + ut_assertok(fdtdec_set_carveout(blob, "/a-test", "memory-region", 0, + &resv, "test_resv3", NULL, 0, 0)); offset = fdt_path_offset(blob, "/a-test"); ut_assert(offset > 0); @@ -67,6 +64,7 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts) fdt_addr_t addr; fdt_size_t size; void *blob; + unsigned long flags = FDTDEC_RESERVED_MEMORY_NO_MAP; int blob_sz, parent, subnode; uint32_t phandle, phandle1; @@ -80,8 +78,8 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts) /* Insert a memory region in /reserved-memory node */ resv.start = 0x1000; resv.end = 0x1fff; - ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region", - &resv, &phandle, false)); + ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region", &resv, + NULL, 0, &phandle, 0)); /* Test /reserve-memory and its subnode should exist */ parent = fdt_path_offset(blob, "/reserved-memory"); @@ -101,8 +99,8 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts) resv.start = 0x2000; resv.end = 0x2fff; - ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region1", - &resv, &phandle1, true)); + ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region1", &resv, + NULL, 0, &phandle1, flags)); subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region1"); ut_assert(subnode > 0); @@ -118,8 +116,8 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts) */ resv.start = 0x1000; resv.end = 0x1fff; - ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region2", - &resv, &phandle1, false)); + ut_assertok(fdtdec_add_reserved_memory(blob, "rsvd_region2", &resv, + NULL, 0, &phandle1, 0)); subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region2"); ut_assert(subnode < 0); |