From: Thierry Reding Date: Fri, 3 Sep 2021 13:16:19 +0000 (+0200) Subject: fdtdec: Support compatible string list for reserved memory X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=46cb067803bef50cb8a1334a56897d05b5f85e02;p=u-boot.git fdtdec: Support compatible string list for reserved memory Reserved memory nodes can have a compatible string list to identify the type of reserved memory that they represent. Support specifying an optional compatible string list when creating these nodes. Signed-off-by: Thierry Reding Reviewed-by: Simon Glass Signed-off-by: Tom Warren --- diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 41f3e95019..4f17c327af 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, false); if (ret) { debug("%s: failed to add reserved memory\n", __func__); return ret; diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c index 61cf893526..7ac30a4f7c 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, false); 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 1f7aa0050c..58077255d0 100644 --- a/board/nvidia/p2371-2180/p2371-2180.c +++ b/board/nvidia/p2371-2180/p2371-2180.c @@ -128,7 +128,8 @@ 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, NULL); + err = fdtdec_get_carveout(src, node, "memory-region", 0, &fb, NULL, + NULL, NULL); if (err < 0) { if (err != -FDT_ERR_NOTFOUND) printf("failed to get carveout for %s: %d\n", node, @@ -138,7 +139,7 @@ static int ft_copy_carveout(void *dst, const void *src, const char *node) } err = fdtdec_set_carveout(dst, node, "memory-region", 0, "framebuffer", - &fb); + NULL, 0, &fb); if (err < 0) { printf("failed to set carveout for %s: %d\n", node, err); return err; diff --git a/board/nvidia/p2771-0000/p2771-0000.c b/board/nvidia/p2771-0000/p2771-0000.c index aca86c3426..e35e6b6f48 100644 --- a/board/nvidia/p2771-0000/p2771-0000.c +++ b/board/nvidia/p2771-0000/p2771-0000.c @@ -104,7 +104,8 @@ 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, NULL); + err = fdtdec_get_carveout(src, node, "memory-region", 0, &fb, NULL, + NULL, NULL); if (err < 0) { if (err != -FDT_ERR_NOTFOUND) printf("failed to get carveout for %s: %d\n", node, @@ -114,7 +115,7 @@ static int ft_copy_carveout(void *dst, const void *src, const char *node) } err = fdtdec_set_carveout(dst, node, "memory-region", 0, "framebuffer", - &fb); + NULL, 0, &fb); if (err < 0) { printf("failed to set carveout for %s: %d\n", node, err); return err; diff --git a/board/nvidia/p3450-0000/p3450-0000.c b/board/nvidia/p3450-0000/p3450-0000.c index 7c1e75307f..f16916460e 100644 --- a/board/nvidia/p3450-0000/p3450-0000.c +++ b/board/nvidia/p3450-0000/p3450-0000.c @@ -127,7 +127,8 @@ 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, NULL); + err = fdtdec_get_carveout(src, node, "memory-region", 0, &fb, NULL, + NULL, NULL); if (err < 0) { if (err != -FDT_ERR_NOTFOUND) printf("failed to get carveout for %s: %d\n", node, @@ -137,7 +138,7 @@ static int ft_copy_carveout(void *dst, const void *src, const char *node) } err = fdtdec_set_carveout(dst, node, "memory-region", 0, "framebuffer", - &fb); + NULL, 0, &fb); if (err < 0) { printf("failed to set carveout for %s: %d\n", node, err); return err; diff --git a/include/fdtdec.h b/include/fdtdec.h index f961f03012..5a6a7cbd99 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -995,7 +995,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, + * false); * * This results in the following subnode being added to the top-level * /reserved-memory node: @@ -1020,6 +1021,8 @@ 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 @@ -1027,6 +1030,7 @@ static inline int fdtdec_set_phandle(void *blob, int node, uint32_t phandle) */ int fdtdec_add_reserved_memory(void *blob, const char *basename, const struct fdt_memory *carveout, + const char **compatibles, unsigned int count, uint32_t *phandlep, bool no_map); /** @@ -1043,11 +1047,14 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, * @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 * @return 0 on success or a negative error code on failure */ int fdtdec_get_carveout(const void *blob, const char *node, const char *prop_name, unsigned int index, - struct fdt_memory *carveout, const char **name); + struct fdt_memory *carveout, const char **name, + const char ***compatiblesp, unsigned int *countp); /** * fdtdec_set_carveout() - sets a carveout region for a given node @@ -1065,7 +1072,8 @@ int fdtdec_get_carveout(const void *blob, const char *node, * .end = 0x934b2fff, * }; * - * fdtdec_set_carveout(fdt, node, "memory-region", 0, "framebuffer", &fb); + * fdtdec_set_carveout(fdt, node, "memory-region", 0, "framebuffer", NULL, + * 0, &fb); * * 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 @@ -1104,10 +1112,13 @@ int fdtdec_get_carveout(const void *blob, const char *node, * @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 compatibles compatible strings to set for the carveout + * @param count number of compatible strings * @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 char **compatibles, unsigned int count, const struct fdt_memory *carveout); /** diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 3ada77d80c..f124f0555b 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1293,6 +1293,7 @@ static int fdtdec_init_reserved_memory(void *blob) int fdtdec_add_reserved_memory(void *blob, const char *basename, const struct fdt_memory *carveout, + const char **compatibles, unsigned int count, uint32_t *phandlep, bool no_map) { fdt32_t cells[4] = {}, *ptr = cells; @@ -1399,6 +1400,28 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, return err; } + 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; + } + /* return the phandle for the new node for the caller to use */ if (phandlep) *phandlep = phandle; @@ -1408,7 +1431,8 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, int fdtdec_get_carveout(const void *blob, const char *node, const char *prop_name, unsigned int index, - struct fdt_memory *carveout, const char **name) + struct fdt_memory *carveout, const char **name, + const char ***compatiblesp, unsigned int *countp) { const fdt32_t *prop; uint32_t phandle; @@ -1446,6 +1470,45 @@ int fdtdec_get_carveout(const void *blob, const char *node, 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); @@ -1461,6 +1524,7 @@ int fdtdec_get_carveout(const void *blob, const char *node, int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, unsigned int index, const char *name, + const char **compatibles, unsigned int count, const struct fdt_memory *carveout) { uint32_t phandle; @@ -1468,7 +1532,8 @@ int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, 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, false); 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 760aca2669..72c3001a21 100644 --- a/lib/fdtdec_test.c +++ b/lib/fdtdec_test.c @@ -190,7 +190,7 @@ static int make_fdt_carveout_device(void *fdt, uint32_t na, uint32_t ns) CHECK(fdt_setprop(fdt, offset, "reg", cells, (na + ns) * sizeof(*cells))); return fdtdec_set_carveout(fdt, name, "memory-region", 0, - "framebuffer", &carveout); + "framebuffer", NULL, 0, &carveout); } static int check_fdt_carveout(void *fdt, uint32_t address_cells, @@ -215,7 +215,7 @@ static int check_fdt_carveout(void *fdt, uint32_t address_cells, &expected.end, address_cells, size_cells); 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 766d0d9e3f..3fbde934fb 100644 --- a/lib/optee/optee.c +++ b/lib/optee/optee.c @@ -177,6 +177,7 @@ int optee_copy_fdt_nodes(void *new_blob) ret = fdtdec_add_reserved_memory(new_blob, nodename, &carveout, + NULL, 0, NULL, true); free(oldname); diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c index 1f630ea3ee..7b543e7b99 100644 --- a/test/dm/fdtdec.c +++ b/test/dm/fdtdec.c @@ -30,19 +30,19 @@ static int dm_test_fdtdec_set_carveout(struct unit_test_state *uts) resv.end = 0x2000; ut_assertok(fdtdec_set_carveout(blob, "/a-test", "memory-region", 2, "test_resv1", - &resv)); + NULL, 0, &resv)); resv.start = 0x10000; resv.end = 0x20000; ut_assertok(fdtdec_set_carveout(blob, "/a-test", "memory-region", 1, "test_resv2", - &resv)); + NULL, 0, &resv)); resv.start = 0x100000; resv.end = 0x200000; ut_assertok(fdtdec_set_carveout(blob, "/a-test", "memory-region", 0, "test_resv3", - &resv)); + NULL, 0, &resv)); offset = fdt_path_offset(blob, "/a-test"); ut_assert(offset > 0); @@ -80,8 +80,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, false)); /* Test /reserve-memory and its subnode should exist */ parent = fdt_path_offset(blob, "/reserved-memory"); @@ -101,8 +101,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, true)); subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region1"); ut_assert(subnode > 0); @@ -118,8 +118,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, false)); subnode = fdt_path_offset(blob, "/reserved-memory/rsvd_region2"); ut_assert(subnode < 0);