From 4aed22762303755f8f26d14f0ad2608d63550e72 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Sep 2020 18:49:26 -0600 Subject: bloblist: Add a command It is helpful to be able to see basic statistics about the bloblist and also to list its contents. Add a 'bloblist' command to handle this. Put the display functions in the bloblist modules rather than in the command code itself. That allows showing a list from SPL, where commands are not available. Also make bloblist_first/next_blob() static as they are not used outside this file. Signed-off-by: Simon Glass --- include/bloblist.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'include') diff --git a/include/bloblist.h b/include/bloblist.h index 5784c2226e7..6c37cd2a639 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -19,6 +19,7 @@ enum { BLOBLIST_ALIGN = 16, }; +/* Supported tags - add new ones to tag_name in bloblist.c */ enum bloblist_tag_t { BLOBLISTT_NONE = 0, @@ -35,6 +36,8 @@ enum bloblist_tag_t { BLOBLISTT_INTEL_VBT, /* Intel Video-BIOS table */ BLOBLISTT_TPM2_TCG_LOG, /* TPM v2 log space */ BLOBLISTT_TCPA_LOG, /* TPM log space */ + + BLOBLISTT_COUNT }; /** @@ -206,6 +209,35 @@ int bloblist_check(ulong addr, uint size); */ int bloblist_finish(void); +/** + * bloblist_get_stats() - Get information about the bloblist + * + * This returns useful information about the bloblist + */ +void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp); + +/** + * bloblist_show_stats() - Show information about the bloblist + * + * This shows useful information about the bloblist on the console + */ +void bloblist_show_stats(void); + +/** + * bloblist_show_list() - Show a list of blobs in the bloblist + * + * This shows a list of blobs, showing their address, size and tag. + */ +void bloblist_show_list(void); + +/** + * bloblist_tag_name() - Get the name for a tag + * + * @tag: Tag to check + * @return name of tag, or "invalid" if an invalid tag is provided + */ +const char *bloblist_tag_name(enum bloblist_tag_t tag); + /** * bloblist_init() - Init the bloblist system with a single bloblist * -- cgit v1.3.1 From cdd4e30dfcaba706120df340c0c8757d56e48b7a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Sep 2020 18:49:27 -0600 Subject: bloblist: Compare addresses rather than pointers in tests When running these tests on sandbox any failures result in very large or long pointer values which are a pain to work with. Map them to an address so it is easier to diagnose failures. Signed-off-by: Simon Glass --- include/test/ut.h | 13 +++++++++++++ test/bloblist.c | 27 ++++++++++++++------------- 2 files changed, 27 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/test/ut.h b/include/test/ut.h index 3295cd4e548..3f2ee7514b8 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -224,6 +224,19 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); } \ } +/* Assert that two addresses (converted from pointers) are equal */ +#define ut_asserteq_addr(expr1, expr2) { \ + ulong _val1 = map_to_sysmem(expr1); \ + ulong _val2 = map_to_sysmem(expr2); \ + \ + if (_val1 != _val2) { \ + ut_failf(uts, __FILE__, __LINE__, __func__, \ + #expr1 " = " #expr2, \ + "Expected %lx, got %lx", _val1, _val2); \ + return CMD_RET_FAILURE; \ + } \ +} + /* Assert that a pointer is NULL */ #define ut_assertnull(expr) { \ const void *_val = (expr); \ diff --git a/test/bloblist.c b/test/bloblist.c index cbdc9db4ecf..028b0a9383c 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -95,26 +95,27 @@ static int bloblist_test_blob(struct unit_test_state *uts) hdr = clear_bloblist(); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_asserteq(map_to_sysmem(hdr), TEST_ADDR); /* Add a record and check that we can find it */ data = bloblist_add(TEST_TAG, TEST_SIZE); rec = (void *)(hdr + 1); - ut_asserteq_ptr(rec + 1, data); + ut_asserteq_addr(rec + 1, data); data = bloblist_find(TEST_TAG, TEST_SIZE); - ut_asserteq_ptr(rec + 1, data); + ut_asserteq_addr(rec + 1, data); /* Check the data is zeroed */ ut_assertok(check_zero(data, TEST_SIZE)); /* Check the 'ensure' method */ - ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); + ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2)); rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN)); ut_assertok(check_zero(data, TEST_SIZE)); /* Check for a non-existent record */ - ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); - ut_asserteq_ptr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2)); + ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); + ut_asserteq_addr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2)); ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0)); return 0; @@ -140,7 +141,7 @@ static int bloblist_test_blob_ensure(struct unit_test_state *uts) /* Check that we get the same thing again */ ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2)); ut_asserteq(TEST_SIZE, size); - ut_asserteq_ptr(data, data2); + ut_asserteq_addr(data, data2); /* Check that the size remains the same */ size = TEST_SIZE2; @@ -164,8 +165,8 @@ static int bloblist_test_bad_blob(struct unit_test_state *uts) ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); data = hdr + 1; data += sizeof(struct bloblist_rec); - ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); - ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); + ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); + ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); return 0; } @@ -251,7 +252,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) gd->flags |= GD_FLG_SILENT; console_record_reset(); run_command("bloblist info", 0); - ut_assert_nextline("base: %x", map_to_sysmem(hdr)); + ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); ut_assert_nextline("size: 100 256 Bytes"); ut_assert_nextline("alloced: 70 112 Bytes"); ut_assert_nextline("free: 90 144 Bytes"); @@ -280,10 +281,10 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts) console_record_reset(); run_command("bloblist list", 0); ut_assert_nextline("Address Size Tag Name"); - ut_assert_nextline("%08x %8x 1 EC host event", map_to_sysmem(data), - TEST_SIZE); - ut_assert_nextline("%08x %8x 2 SPL hand-off", map_to_sysmem(data2), - TEST_SIZE2); + ut_assert_nextline("%08lx %8x 1 EC host event", + (ulong)map_to_sysmem(data), TEST_SIZE); + ut_assert_nextline("%08lx %8x 2 SPL hand-off", + (ulong)map_to_sysmem(data2), TEST_SIZE2); ut_assert_console_end(); gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD); -- cgit v1.3.1 From 4c1497e77661eea47d3dbb9bee029532cc0da198 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Sep 2020 18:49:29 -0600 Subject: bloblist: Allow custom alignment for blobs Some blobs need a larger alignment than the default. For example, ACPI tables often start at a 4KB boundary. Add support for this. Update the size of the test blob to allow these larger records. Signed-off-by: Simon Glass --- arch/x86/cpu/intel_common/acpi.c | 2 +- arch/x86/cpu/intel_common/intel_opregion.c | 2 +- common/bloblist.c | 32 ++++++++++++++--------- include/bloblist.h | 6 +++-- test/bloblist.c | 42 +++++++++++++++++++++++------- 5 files changed, 59 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/arch/x86/cpu/intel_common/acpi.c b/arch/x86/cpu/intel_common/acpi.c index a4d5fbd38a7..4496bbfd999 100644 --- a/arch/x86/cpu/intel_common/acpi.c +++ b/arch/x86/cpu/intel_common/acpi.c @@ -198,7 +198,7 @@ int southbridge_inject_dsdt(const struct udevice *dev, struct acpi_ctx *ctx) struct acpi_global_nvs *gnvs; int ret; - ret = bloblist_ensure_size(BLOBLISTT_ACPI_GNVS, sizeof(*gnvs), + ret = bloblist_ensure_size(BLOBLISTT_ACPI_GNVS, sizeof(*gnvs), 0, (void **)&gnvs); if (ret) return log_msg_ret("bloblist", ret); diff --git a/arch/x86/cpu/intel_common/intel_opregion.c b/arch/x86/cpu/intel_common/intel_opregion.c index 4e6c64d9aaa..c95ae04992d 100644 --- a/arch/x86/cpu/intel_common/intel_opregion.c +++ b/arch/x86/cpu/intel_common/intel_opregion.c @@ -108,7 +108,7 @@ int intel_gma_init_igd_opregion(struct udevice *dev, struct optionrom_vbt *ext_vbt; ret = bloblist_ensure_size(BLOBLISTT_INTEL_VBT, - vbt->hdr_vbt_size, + vbt->hdr_vbt_size, 0, (void **)&ext_vbt); if (ret) { log_err("GMA: Unable to add Ext VBT to bloblist\n"); diff --git a/common/bloblist.c b/common/bloblist.c index 173f28d8ec9..33b58623807 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -83,18 +83,25 @@ static struct bloblist_rec *bloblist_findrec(uint tag) return NULL; } -static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp) +static int bloblist_addrec(uint tag, int size, int align, + struct bloblist_rec **recp) { struct bloblist_hdr *hdr = gd->bloblist; struct bloblist_rec *rec; int data_start, new_alloced; + if (!align) + align = BLOBLIST_ALIGN; + /* Figure out where the new data will start */ - data_start = hdr->alloced + sizeof(*rec); - data_start = ALIGN(data_start, BLOBLIST_ALIGN); + data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec); + + /* Align the address and then calculate the offset from ->alloced */ + data_start = ALIGN(data_start, align) - map_to_sysmem(hdr); /* Calculate the new allocated total */ - new_alloced = data_start + ALIGN(size, BLOBLIST_ALIGN); + new_alloced = data_start + ALIGN(size, align); + if (new_alloced >= hdr->size) { log(LOGC_BLOBLIST, LOGL_ERR, "Failed to allocate %x bytes size=%x, need size=%x\n", @@ -117,7 +124,8 @@ static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp) return 0; } -static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size) +static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size, + int align) { struct bloblist_rec *rec; @@ -130,7 +138,7 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size) } else { int ret; - ret = bloblist_addrec(tag, size, &rec); + ret = bloblist_addrec(tag, size, align, &rec); if (ret) return ret; } @@ -152,22 +160,22 @@ void *bloblist_find(uint tag, int size) return (void *)rec + rec->hdr_size; } -void *bloblist_add(uint tag, int size) +void *bloblist_add(uint tag, int size, int align) { struct bloblist_rec *rec; - if (bloblist_addrec(tag, size, &rec)) + if (bloblist_addrec(tag, size, align, &rec)) return NULL; return (void *)rec + rec->hdr_size; } -int bloblist_ensure_size(uint tag, int size, void **blobp) +int bloblist_ensure_size(uint tag, int size, int align, void **blobp) { struct bloblist_rec *rec; int ret; - ret = bloblist_ensurerec(tag, &rec, size); + ret = bloblist_ensurerec(tag, &rec, size, align); if (ret) return ret; *blobp = (void *)rec + rec->hdr_size; @@ -179,7 +187,7 @@ void *bloblist_ensure(uint tag, int size) { struct bloblist_rec *rec; - if (bloblist_ensurerec(tag, &rec, size)) + if (bloblist_ensurerec(tag, &rec, size, 0)) return NULL; return (void *)rec + rec->hdr_size; @@ -190,7 +198,7 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp) struct bloblist_rec *rec; int ret; - ret = bloblist_ensurerec(tag, &rec, *sizep); + ret = bloblist_ensurerec(tag, &rec, *sizep, 0); if (ret == -ESPIPE) *sizep = rec->size; else if (ret) diff --git a/include/bloblist.h b/include/bloblist.h index 6c37cd2a639..965d8e9a29b 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -132,10 +132,11 @@ void *bloblist_find(uint tag, int size); * * @tag: Tag to add (enum bloblist_tag_t) * @size: Size of the blob + * @align: Alignment of the blob (in bytes), 0 for default * @return pointer to the newly added block, or NULL if there is not enough * space for the blob */ -void *bloblist_add(uint tag, int size); +void *bloblist_add(uint tag, int size, int align); /** * bloblist_ensure_size() - Find or add a blob @@ -145,10 +146,11 @@ void *bloblist_add(uint tag, int size); * @tag: Tag to add (enum bloblist_tag_t) * @size: Size of the blob * @blobp: Returns a pointer to blob on success + * @align: Alignment of the blob (in bytes), 0 for default * @return 0 if OK, -ENOSPC if it is missing and could not be added due to lack * of space, or -ESPIPE it exists but has the wrong size */ -int bloblist_ensure_size(uint tag, int size, void **blobp); +int bloblist_ensure_size(uint tag, int size, int align, void **blobp); /** * bloblist_ensure() - Find or add a blob diff --git a/test/bloblist.c b/test/bloblist.c index 68535237641..0bb9e2d81e7 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -25,10 +25,10 @@ enum { TEST_SIZE = 10, TEST_SIZE2 = 20, - TEST_SIZE_LARGE = 0xe0, + TEST_SIZE_LARGE = 0x3e0, TEST_ADDR = CONFIG_BLOBLIST_ADDR, - TEST_BLOBLIST_SIZE = 0x100, + TEST_BLOBLIST_SIZE = 0x400, ERASE_BYTE = '\xff', }; @@ -100,7 +100,7 @@ static int bloblist_test_blob(struct unit_test_state *uts) ut_asserteq(map_to_sysmem(hdr), TEST_ADDR); /* Add a record and check that we can find it */ - data = bloblist_add(TEST_TAG, TEST_SIZE); + data = bloblist_add(TEST_TAG, TEST_SIZE, 0); rec = (void *)(hdr + 1); ut_asserteq_addr(rec + 1, data); data = bloblist_find(TEST_TAG, TEST_SIZE); @@ -206,10 +206,10 @@ static int bloblist_test_checksum(struct unit_test_state *uts) hdr->chksum--; /* Make sure the checksum changes when we add blobs */ - data = bloblist_add(TEST_TAG, TEST_SIZE); + data = bloblist_add(TEST_TAG, TEST_SIZE, 0); ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); - data2 = bloblist_add(TEST_TAG2, TEST_SIZE2); + data2 = bloblist_add(TEST_TAG2, TEST_SIZE2, 0); ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_finish()); @@ -255,9 +255,9 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) console_record_reset(); run_command("bloblist info", 0); ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr)); - ut_assert_nextline("size: 100 256 Bytes"); + ut_assert_nextline("size: 400 1 KiB"); ut_assert_nextline("alloced: 70 112 Bytes"); - ut_assert_nextline("free: 90 144 Bytes"); + ut_assert_nextline("free: 390 912 Bytes"); ut_assert_console_end(); gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD); @@ -298,6 +298,8 @@ BLOBLIST_TEST(bloblist_test_cmd_list, 0); static int bloblist_test_align(struct unit_test_state *uts) { struct bloblist_hdr *hdr; + ulong addr; + char *data; int i; /* At the start there should be no records */ @@ -305,14 +307,14 @@ static int bloblist_test_align(struct unit_test_state *uts) ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); - /* Check the alignment */ + /* Check the default alignment */ for (i = 0; i < 3; i++) { int size = i * 3; ulong addr; char *data; int j; - data = bloblist_add(i, size); + data = bloblist_add(i, size, 0); ut_assertnonnull(data); addr = map_to_sysmem(data); ut_asserteq(0, addr & (BLOBLIST_ALIGN - 1)); @@ -324,6 +326,28 @@ static int bloblist_test_align(struct unit_test_state *uts) ut_asserteq(ERASE_BYTE, data[j]); } + /* Check larger alignment */ + for (i = 0; i < 3; i++) { + int align = 32 << i; + + data = bloblist_add(3 + i, i * 4, align); + ut_assertnonnull(data); + addr = map_to_sysmem(data); + ut_asserteq(0, addr & (align - 1)); + } + + /* Check alignment with an bloblist starting on a smaller alignment */ + hdr = map_sysmem(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE); + memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); + memset(hdr, '\0', sizeof(*hdr)); + ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE, + 0)); + + data = bloblist_add(1, 5, BLOBLIST_ALIGN * 2); + ut_assertnonnull(data); + addr = map_to_sysmem(data); + ut_asserteq(0, addr & (BLOBLIST_ALIGN * 2 - 1)); + return 0; } BLOBLIST_TEST(bloblist_test_align, 0); -- cgit v1.3.1 From e9b6b2c77dd57b591d025f6895a779930a39a5ff Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Sep 2020 18:49:30 -0600 Subject: bloblist: Fix up a few comments Adjust a few comments to make the meaning clearer. Signed-off-by: Simon Glass --- include/bloblist.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/bloblist.h b/include/bloblist.h index 965d8e9a29b..2b4b6696897 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -68,7 +68,7 @@ enum bloblist_tag_t { * the bloblist can grow up to this size. This starts out as * sizeof(bloblist_hdr) since we need at least that much space to store a * valid bloblist - * @spare: Space space + * @spare: Spare space (for future use) * @chksum: CRC32 for the entire bloblist allocated area. Since any of the * blobs can be altered after being created, this checksum is only valid * when the bloblist is finalised before jumping to the next stage of boot. @@ -115,7 +115,7 @@ struct bloblist_rec { * Searches the bloblist and returns the blob with the matching tag * * @tag: Tag to search for (enum bloblist_tag_t) - * @size: Expected size of the blob + * @size: Expected size of the blob, or 0 for any size * @return pointer to blob if found, or NULL if not found, or a blob was found * but it is the wrong size */ -- cgit v1.3.1 From 45dbe75da6fbc3de280021bf4b5c9dfc94c70f8f Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 23 Sep 2020 08:23:27 +0200 Subject: dm: ofnode: Fix compile breakage with OF_CHECKS enabled Include missing log.h and change _ofnode_to_np() to ofnode_to_np() so that compiling with OF_CHECKS enabled does not break. Signed-off-by: Stefan Roese Cc: Simon Glass Reviewed-by: Simon Glass --- include/dm/ofnode.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 8df2facf998..d7852daf7f4 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -10,6 +10,7 @@ /* TODO(sjg@chromium.org): Drop fdtdec.h include */ #include #include +#include /* Enable checks to protect against invalid calls */ #undef OF_CHECKS @@ -84,7 +85,7 @@ struct ofprop { }; /** - * _ofnode_to_np() - convert an ofnode to a live DT node pointer + * ofnode_to_np() - convert an ofnode to a live DT node pointer * * This cannot be called if the reference contains an offset. * @@ -182,8 +183,8 @@ static inline bool ofnode_is_np(ofnode node) * live tree is in use. */ assert(!ofnode_valid(node) || - (of_live_active() ? _ofnode_to_np(node) - : _ofnode_to_np(node))); + (of_live_active() ? ofnode_to_np(node) + : ofnode_to_np(node))); #endif return of_live_active() && ofnode_valid(node); } -- cgit v1.3.1 From 6d9949fe866751c527c5dafab5350af89b7b8332 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 24 Sep 2020 17:26:20 +0200 Subject: dm: update test on of_offset in ofnode_valid Update the test for node.of_offset because an invalid offset is not always set to -1 because the return value of the libfdt functions are: + an error with a value < 0 + a valid offset with value >=0 For example, in ofnode_get_by_phandle() function, we have: node.of_offset = fdt_node_offset_by_phandle(gd->fdt_blob, phandle); and this function can return -FDT_ERR_BADPHANDLE (-6). Without this patch, the added test dm_test_ofnode_get_by_phandle failed. Signed-off-by: Patrick Delaunay Reviewed-by: Simon Glass --- include/dm/ofnode.h | 2 +- test/dm/ofnode.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index d7852daf7f4..98c64fece30 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -128,7 +128,7 @@ static inline bool ofnode_valid(ofnode node) if (of_live_active()) return node.np != NULL; else - return node.of_offset != -1; + return node.of_offset >= 0; } /** diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 8bfb7066026..4ae8d281a70 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -19,6 +19,22 @@ static int dm_test_ofnode_compatible(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_compatible, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts) +{ + /* test invalid phandle */ + ut_assert(!ofnode_valid(ofnode_get_by_phandle(0))); + ut_assert(!ofnode_valid(ofnode_get_by_phandle(-1))); + + /* test first valid phandle */ + ut_assert(ofnode_valid(ofnode_get_by_phandle(1))); + + /* test unknown phandle */ + ut_assert(!ofnode_valid(ofnode_get_by_phandle(0x1000000))); + + return 0; +} +DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts) { const char propname[] = "compatible"; -- cgit v1.3.1 From 89f68302cacaa41330959420d7329b7c89afdd88 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 25 Sep 2020 09:41:14 +0200 Subject: dm: add cells_count parameter in *_count_phandle_with_args The cell_count argument is required when cells_name is NULL. This patch adds this parameter in live tree API - of_count_phandle_with_args - ofnode_count_phandle_with_args - dev_count_phandle_with_args This parameter solves issue when these API is used to count the number of element of a cell without cell name. This parameter allow to force the size cell. For example: count = dev_count_phandle_with_args(dev, "array", NULL, 3); Signed-off-by: Patrick Delaunay Reviewed-by: Simon Glass --- board/st/stm32mp1/stm32mp1.c | 2 +- drivers/clk/clk-uclass.c | 4 ++-- drivers/core/of_access.c | 7 ++++--- drivers/core/ofnode.c | 6 +++--- drivers/core/read.c | 5 +++-- drivers/net/designware.c | 3 ++- drivers/phy/phy-uclass.c | 2 +- drivers/power/domain/power-domain-uclass.c | 2 +- drivers/reset/reset-uclass.c | 3 ++- drivers/usb/host/ehci-generic.c | 4 ++-- drivers/usb/host/ohci-da8xx.c | 3 ++- drivers/usb/host/ohci-generic.c | 6 ++++-- include/dm/of_access.h | 4 +++- include/dm/ofnode.h | 3 ++- include/dm/read.h | 8 +++++--- 15 files changed, 37 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 3b677d339b7..03a19af9302 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -314,7 +314,7 @@ static int board_check_usb_power(void) * for each of them */ adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd", - "#io-channel-cells"); + "#io-channel-cells", 0); if (adc_count < 0) { if (adc_count == -ENOENT) return 0; diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 4076535271b..31c5997aead 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -161,7 +161,7 @@ int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk) bulk->count = 0; - count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); + count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells", 0); if (count < 1) return count; @@ -213,7 +213,7 @@ static int clk_set_default_parents(struct udevice *dev, int stage) int ret; num_parents = dev_count_phandle_with_args(dev, "assigned-clock-parents", - "#clock-cells"); + "#clock-cells", 0); if (num_parents < 0) { debug("%s: could not read assigned-clock-parents for %p\n", __func__, dev); diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index bcf1644d050..0a12e9b26f8 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -756,10 +756,11 @@ int of_parse_phandle_with_args(const struct device_node *np, } int of_count_phandle_with_args(const struct device_node *np, - const char *list_name, const char *cells_name) + const char *list_name, const char *cells_name, + int cell_count) { - return __of_parse_phandle_with_args(np, list_name, cells_name, 0, - -1, NULL); + return __of_parse_phandle_with_args(np, list_name, cells_name, + cell_count, -1, NULL); } static void of_alias_add(struct alias_prop *ap, struct device_node *np, diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 79fcdf5ce21..7d1b89514c7 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -432,15 +432,15 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, } int ofnode_count_phandle_with_args(ofnode node, const char *list_name, - const char *cells_name) + const char *cells_name, int cell_count) { if (ofnode_is_np(node)) return of_count_phandle_with_args(ofnode_to_np(node), - list_name, cells_name); + list_name, cells_name, cell_count); else return fdtdec_parse_phandle_with_args(gd->fdt_blob, ofnode_to_offset(node), list_name, cells_name, - 0, -1, NULL); + cell_count, -1, NULL); } ofnode ofnode_path(const char *path) diff --git a/drivers/core/read.c b/drivers/core/read.c index 86f3f881706..076125824ca 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -214,10 +214,11 @@ int dev_read_phandle_with_args(const struct udevice *dev, const char *list_name, } int dev_count_phandle_with_args(const struct udevice *dev, - const char *list_name, const char *cells_name) + const char *list_name, const char *cells_name, + int cell_count) { return ofnode_count_phandle_with_args(dev_ofnode(dev), list_name, - cells_name); + cells_name, cell_count); } int dev_read_addr_cells(const struct udevice *dev) diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 1c0e8294078..4c19abbaf0c 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -688,7 +688,8 @@ int designware_eth_probe(struct udevice *dev) int i, clock_nb; priv->clock_count = 0; - clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); + clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells", + 0); if (clock_nb > 0) { priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk), GFP_KERNEL); diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c index 8f456f33d27..f344e94b438 100644 --- a/drivers/phy/phy-uclass.c +++ b/drivers/phy/phy-uclass.c @@ -214,7 +214,7 @@ int generic_phy_get_bulk(struct udevice *dev, struct phy_bulk *bulk) if (!dev_read_prop(dev, "phys", NULL)) return 0; - count = dev_count_phandle_with_args(dev, "phys", "#phy-cells"); + count = dev_count_phandle_with_args(dev, "phys", "#phy-cells", 0); if (count < 1) return count; diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c index c2c7c3bd507..af829db9da1 100644 --- a/drivers/power/domain/power-domain-uclass.c +++ b/drivers/power/domain/power-domain-uclass.c @@ -117,7 +117,7 @@ static int dev_power_domain_ctrl(struct udevice *dev, bool on) int i, count, ret = 0; count = dev_count_phandle_with_args(dev, "power-domains", - "#power-domain-cells"); + "#power-domain-cells", 0); for (i = 0; i < count; i++) { ret = power_domain_get_by_index(dev, &pd, i); if (ret) diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c index e7e407ca350..071c389ca07 100644 --- a/drivers/reset/reset-uclass.c +++ b/drivers/reset/reset-uclass.c @@ -108,7 +108,8 @@ static int __reset_get_bulk(struct udevice *dev, ofnode node, bulk->count = 0; - count = ofnode_count_phandle_with_args(node, "resets", "#reset-cells"); + count = ofnode_count_phandle_with_args(node, "resets", "#reset-cells", + 0); if (count < 1) return count; diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c index 304a3437d56..c93a7051a79 100644 --- a/drivers/usb/host/ehci-generic.c +++ b/drivers/usb/host/ehci-generic.c @@ -86,7 +86,7 @@ static int ehci_usb_probe(struct udevice *dev) err = 0; priv->clock_count = 0; clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks", - "#clock-cells"); + "#clock-cells", 0); if (clock_nb > 0) { priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk), GFP_KERNEL); @@ -116,7 +116,7 @@ static int ehci_usb_probe(struct udevice *dev) priv->reset_count = 0; reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets", - "#reset-cells"); + "#reset-cells", 0); if (reset_nb > 0) { priv->resets = devm_kcalloc(dev, reset_nb, sizeof(struct reset_ctl), diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index 22e7b565b5b..aa1eba262a9 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -95,7 +95,8 @@ static int ohci_da8xx_probe(struct udevice *dev) err = 0; priv->clock_count = 0; - clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); + clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells", + 0); if (clock_nb < 0) return clock_nb; diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c index ed5e500b2c9..ac9b7e1e3c0 100644 --- a/drivers/usb/host/ohci-generic.c +++ b/drivers/usb/host/ohci-generic.c @@ -85,7 +85,8 @@ static int ohci_usb_probe(struct udevice *dev) err = 0; priv->clock_count = 0; - clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); + clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells", + 0); if (clock_nb > 0) { priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk), GFP_KERNEL); @@ -111,7 +112,8 @@ static int ohci_usb_probe(struct udevice *dev) } priv->reset_count = 0; - reset_nb = dev_count_phandle_with_args(dev, "resets", "#reset-cells"); + reset_nb = dev_count_phandle_with_args(dev, "resets", "#reset-cells", + 0); if (reset_nb > 0) { priv->resets = devm_kcalloc(dev, reset_nb, sizeof(struct reset_ctl), diff --git a/include/dm/of_access.h b/include/dm/of_access.h index 2fa65c9332e..cc382b1671c 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -450,6 +450,7 @@ int of_parse_phandle_with_args(const struct device_node *np, * @np: pointer to a device tree node containing a list * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count + * @cells_count: Cell count to use if @cells_name is NULL * @return number of phandle found, -ENOENT if * @list_name does not exist, -EINVAL if a phandle was not found, * @cells_name could not be found, the arguments were truncated or there @@ -460,7 +461,8 @@ int of_parse_phandle_with_args(const struct device_node *np, * */ int of_count_phandle_with_args(const struct device_node *np, - const char *list_name, const char *cells_name); + const char *list_name, const char *cells_name, + int cells_count); /** * of_alias_scan() - Scan all properties of the 'aliases' node diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 98c64fece30..4b7af370560 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -556,12 +556,13 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, * @node: device tree node containing a list * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count + * @cells_count: Cell count to use if @cells_name is NULL * @return number of phandle on success, -ENOENT if @list_name does not * exist, -EINVAL if a phandle was not found, @cells_name could not * be found. */ int ofnode_count_phandle_with_args(ofnode node, const char *list_name, - const char *cells_name); + const char *cells_name, int cell_count); /** * ofnode_path() - find a node by full path diff --git a/include/dm/read.h b/include/dm/read.h index 67db94adfc1..0585eb12281 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -429,12 +429,14 @@ int dev_read_phandle_with_args(const struct udevice *dev, const char *list_name, * @dev: device whose node containing a list * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count + * @cells_count: Cell count to use if @cells_name is NULL * @Returns number of phandle found on success, on error returns appropriate * errno value. */ int dev_count_phandle_with_args(const struct udevice *dev, - const char *list_name, const char *cells_name); + const char *list_name, const char *cells_name, + int cell_count); /** * dev_read_addr_cells() - Get the number of address cells for a device's node @@ -880,10 +882,10 @@ static inline int dev_read_phandle_with_args(const struct udevice *dev, } static inline int dev_count_phandle_with_args(const struct udevice *dev, - const char *list_name, const char *cells_name) + const char *list_name, const char *cells_name, int cell_count) { return ofnode_count_phandle_with_args(dev_ofnode(dev), list_name, - cells_name); + cells_name, cell_count); } static inline int dev_read_addr_cells(const struct udevice *dev) -- cgit v1.3.1