From 805e89e3f7fe5118374b5005e5c2dc214185dcac Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:41 -0600 Subject: alist: Mention the error condition in alist_add_placeholder() Update the function comment to note that this function can return NULL if it runs out of memory. Signed-off-by: Simon Glass --- include/alist.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/alist.h b/include/alist.h index 68d268f01af..0343946bc4a 100644 --- a/include/alist.h +++ b/include/alist.h @@ -151,8 +151,9 @@ void *alist_ensure_ptr(struct alist *lst, uint index); * alist_add_placeholder() - Add a new item to the end of the list * * @lst: alist to add to - * Return: Pointer to the newly added position. Note that this is not inited so - * the caller must copy the requested struct to the returned pointer + * Return: Pointer to the newly added position, or NULL if out of memory. Note + * that this is not inited so the caller must copy the requested struct to the + * returned pointer */ void *alist_add_placeholder(struct alist *lst); -- cgit v1.2.3 From 55c8aad164da140485f8cb146765523b3c7811ce Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:42 -0600 Subject: alist: Add a comment for alist_init_struct() Comment this macro so that it is clear how to use it. Signed-off-by: Simon Glass --- include/alist.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/alist.h b/include/alist.h index 0343946bc4a..a727f1c7dfa 100644 --- a/include/alist.h +++ b/include/alist.h @@ -198,6 +198,12 @@ bool alist_expand_by(struct alist *lst, uint inc_by); */ bool alist_init(struct alist *lst, uint obj_size, uint alloc_size); +/** + * alist_init_struct() - Typed version of alist_init() + * + * Use as: + * alist_init(&lst, struct my_struct); + */ #define alist_init_struct(_lst, _struct) \ alist_init(_lst, sizeof(_struct), 0) -- cgit v1.2.3 From eb6e87a7ab9f93596983b57eef08509beeedf3fb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:43 -0600 Subject: alist: Expand the comment for alist_get() Add a better description for this macro. Signed-off-by: Simon Glass --- include/alist.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/alist.h b/include/alist.h index a727f1c7dfa..2c78ede201e 100644 --- a/include/alist.h +++ b/include/alist.h @@ -116,7 +116,12 @@ static inline const void *alist_getd(struct alist *lst, uint index) return lst->data + index * lst->obj_size; } -/** get an entry as a constant */ +/** + * alist_get() - get an entry as a constant + * + * Use as (to obtain element 2 of the list): + * const struct my_struct *ptr = alist_get(lst, 2, struct my_struct) + */ #define alist_get(_lst, _index, _struct) \ ((const _struct *)alist_get_ptr(_lst, _index)) -- cgit v1.2.3 From 1d49f78c362981435a88d887c777ccc445f5a4e7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:44 -0600 Subject: alist: Add a way to get the next element Add a new function which returns the next element after the one provided, if it exists in the list. Signed-off-by: Simon Glass --- include/alist.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'include') diff --git a/include/alist.h b/include/alist.h index 2c78ede201e..97523af37a6 100644 --- a/include/alist.h +++ b/include/alist.h @@ -71,6 +71,21 @@ static inline bool alist_has(struct alist *lst, uint index) return index < lst->count; } +/** + * alist_calc_index() - Calculate the index of an item in the list + * + * The returned element number will be -1 if the list is empty or the pointer + * pointers to before the list starts. + * + * If the pointer points to after the last item, the calculated element-number + * will be returned, even though it is greater than lst->count + * + * @lst: alist to check + * @ptr: pointer to check + * Return: element number of the pointer + */ +int alist_calc_index(const struct alist *lst, const void *ptr); + /** * alist_err() - Check if the alist is still valid * @@ -190,6 +205,25 @@ bool alist_expand_by(struct alist *lst, uint inc_by); #define alist_add(_lst, _obj) \ ((typeof(_obj) *)alist_add_ptr(_lst, &(_obj))) +/** get next entry as a constant */ +#define alist_next(_lst, _objp) \ + ((const typeof(_objp))alist_next_ptrd(_lst, _objp)) + +/** get next entry, which can be written to */ +#define alist_nextw(_lst, _objp) \ + ((typeof(_objp))alist_next_ptrd(_lst, _objp)) + +/** + * alist_next_ptrd() - Get a pointer to the next list element + * + * This returns NULL if the requested element is beyond lst->count + * + * @lst: List to check + * @ptr: Pointer to current element (must be valid) + * Return: Pointer to next element, or NULL if @ptr is the last + */ +const void *alist_next_ptrd(const struct alist *lst, const void *ptr); + /** * alist_init() - Set up a new object list * -- cgit v1.2.3 From d785a77d18acdf6714f4570c14e622caadf4d5e3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:45 -0600 Subject: alist: Add for-loop helpers Add some macros which permit easy iteration through an alist, similar to those provided by the 'list' implementation. Signed-off-by: Simon Glass --- include/alist.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'include') diff --git a/include/alist.h b/include/alist.h index 97523af37a6..0090b9c0eb1 100644 --- a/include/alist.h +++ b/include/alist.h @@ -224,6 +224,56 @@ bool alist_expand_by(struct alist *lst, uint inc_by); */ const void *alist_next_ptrd(const struct alist *lst, const void *ptr); +/** + * alist_chk_ptr() - Check whether a pointer is within a list + * + * Checks if the pointer points to an existing element of the list. The pointer + * must point to the start of an element, either in the list, or just outside of + * it. This function is only useful for handling for() loops + * + * Return: true if @ptr is within the list (0..count-1), else false + */ +bool alist_chk_ptr(const struct alist *lst, const void *ptr); + +/** + * alist_start() - Get the start of the list (first element) + * + * Note that this will always return ->data even if it is not NULL + * + * Usage: + * const struct my_struct *obj; # 'const' is optional + * + * alist_start(&lst, struct my_struct) + */ +#define alist_start(_lst, _struct) \ + ((_struct *)(_lst)->data) + +/** + * alist_end() - Get the end of the list (just after last element) + * + * Usage: + * const struct my_struct *obj; # 'const' is optional + * + * alist_end(&lst, struct my_struct) + */ +#define alist_end(_lst, _struct) \ + ((_struct *)(_lst)->data + (_lst)->count) + +/** + * alist_for_each() - Iterate over an alist (with constant pointer) + * + * Use as: + * const struct my_struct *obj; # 'const' is optional + * + * alist_for_each(obj, &lst) { + * obj->... + * } + */ +#define alist_for_each(_pos, _lst) \ + for (_pos = alist_start(_lst, typeof(*(_pos))); \ + _pos < alist_end(_lst, typeof(*(_pos))); \ + _pos++) + /** * alist_init() - Set up a new object list * -- cgit v1.2.3 From 5bd4ead8bd76c85aa599c44e8bfb12f512d8ed09 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:46 -0600 Subject: alist: Add a function to empty the list Sometimes it is useful to empty the list without de-allocating any of the memory used, e.g. when the list will be re-populated immediately afterwards. Add a new function for this. Signed-off-by: Simon Glass --- include/alist.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/alist.h b/include/alist.h index 0090b9c0eb1..c639e42ab7d 100644 --- a/include/alist.h +++ b/include/alist.h @@ -274,6 +274,13 @@ bool alist_chk_ptr(const struct alist *lst, const void *ptr); _pos < alist_end(_lst, typeof(*(_pos))); \ _pos++) +/** + * alist_empty() - Empty an alist + * + * This removes all entries from the list, without changing the allocated size + */ +void alist_empty(struct alist *lst); + /** * alist_init() - Set up a new object list * -- cgit v1.2.3 From 5dfc1c8078572436fc68817d22d9e046eaa01398 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:47 -0600 Subject: alist: Add a way to efficiently filter an alist Unlike linked lists, it is inefficient to remove items from an alist, particularly if it is large. If most items need to be removed, then the time-complexity approaches O(n2). Provide a way to do this efficiently, by working through the alist once and copying elements down. Signed-off-by: Simon Glass --- include/alist.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'include') diff --git a/include/alist.h b/include/alist.h index c639e42ab7d..b00d9ea97d6 100644 --- a/include/alist.h +++ b/include/alist.h @@ -274,6 +274,36 @@ bool alist_chk_ptr(const struct alist *lst, const void *ptr); _pos < alist_end(_lst, typeof(*(_pos))); \ _pos++) +/** + * alist_for_each_filter() - version which sets up a 'from' pointer too + * + * This is used for filtering out information in the list. It works by iterating + * through the list, copying elements down over the top of elements to be + * deleted. + * + * In this example, 'from' iterates through the list from start to end,, 'to' + * also begins at the start, but only increments if the element at 'from' should + * be kept. This provides an O(n) filtering operation. Note that + * alist_update_end() must be called after the loop, to update the count. + * + * alist_for_each_filter(from, to, &lst) { + * if (from->val != 2) + * *to++ = *from; + * } + * alist_update_end(&lst, to); + */ +#define alist_for_each_filter(_pos, _from, _lst) \ + for (_pos = _from = alist_start(_lst, typeof(*(_pos))); \ + _pos < alist_end(_lst, typeof(*(_pos))); \ + _pos++) + +/** + * alist_update_end() - Set the element count based on a given pointer + * + * Set the given element as the final one + */ +void alist_update_end(struct alist *lst, const void *end); + /** * alist_empty() - Empty an alist * -- cgit v1.2.3 From 79b3e9d25b3f96fdf66f9d7dc6a14fdce9a15f93 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Oct 2024 09:21:49 -0600 Subject: dm: core: Add a function to see if a device exists All the uclass functions for finding a device end up creating a uclass if it doesn't exist. Add a function which instead returns NULL in this case. This is useful when in the 'unbind' path, since we don't want to undo any unbinding which has already happened. Signed-off-by: Simon Glass --- include/dm/uclass.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 456eef7f2f3..c2793040923 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -435,6 +435,17 @@ int uclass_next_device_check(struct udevice **devp); int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data, struct udevice **devp); +/** + * uclass_try_first_device()- See if there is a device for a uclass + * + * If the uclass exists, this returns the first device on that uclass, without + * probing it. If the uclass does not exist, it gives up + * + * @id: Uclass ID to check + * Return: Pointer to device, if found, else NULL + */ +struct udevice *uclass_try_first_device(enum uclass_id id); + /** * uclass_probe_all() - Probe all devices based on an uclass ID * -- cgit v1.2.3 From ae3b5928d61190d0faef7dfb2bbfc415a25b6ca5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 14 Oct 2024 16:32:11 -0600 Subject: x86: coreboot: Allow building an expo for editing CMOS config Coreboot provides the CMOS layout in the tables it passes to U-Boot. Use that to build an editor for the CMOS settings. Signed-off-by: Simon Glass --- include/expo.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/expo.h b/include/expo.h index 8cb37260db5..3c383d2e2ee 100644 --- a/include/expo.h +++ b/include/expo.h @@ -762,4 +762,12 @@ int expo_apply_theme(struct expo *exp, ofnode node); */ int expo_build(ofnode root, struct expo **expp); +/** + * cb_expo_build() - Build an expo for coreboot CMOS RAM + * + * @expp: Returns the expo created + * Return: 0 if OK, -ve on error + */ +int cb_expo_build(struct expo **expp); + #endif /*__EXPO_H */ -- cgit v1.2.3 From 12d583b38fa570da1fc5aba6d1f5aaf2ba3d8505 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 28 Oct 2024 13:47:52 +0100 Subject: log: Add a new category for tests In some core test code, no existing categories make sense. Add a new one for testing. Signed-off-by: Simon Glass --- include/log.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/log.h b/include/log.h index bf81a27011f..4f6d6a2c2cf 100644 --- a/include/log.h +++ b/include/log.h @@ -106,6 +106,8 @@ enum log_category_t { LOGC_EXPO, /** @LOGC_CONSOLE: Related to the console and stdio */ LOGC_CONSOLE, + /** @LOGC_TEST: Related to testing */ + LOGC_TEST, /** @LOGC_COUNT: Number of log categories */ LOGC_COUNT, /** @LOGC_END: Sentinel value for lists of log categories */ -- cgit v1.2.3 From 3f1d79932a1b3804fe108961ad95c44adbc6cb72 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 28 Oct 2024 13:47:53 +0100 Subject: test: Allow saving and restoring the bloblist Tests which create a new bloblist overwrite the existing one in sandbox. Provide a flag for tests to declare this behaviour. Save and restore the bloblist pointer so that other tests remain unaffected. Note that when sandbox is running normally, the bloblist has been relocated to high in memory. The existing bloblist tests create a new bloblist low in memory, so they do not conflict. Correct a build error on coreboot by using accessors for gd->bloblist: Signed-off-by: Simon Glass --- include/asm-generic/global_data.h | 2 ++ include/test/test.h | 3 +++ 2 files changed, 5 insertions(+) (limited to 'include') diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index bf593d96a84..26277b93976 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -545,8 +545,10 @@ static_assert(sizeof(struct global_data) == GD_SIZE); #if CONFIG_IS_ENABLED(BLOBLIST) #define gd_bloblist() gd->bloblist +#define gd_set_bloblist(_val) gd->bloblist = (_val) #else #define gd_bloblist() NULL +#define gd_set_bloblist(_val) #endif #if CONFIG_IS_ENABLED(BOOTSTAGE) diff --git a/include/test/test.h b/include/test/test.h index 92eec2eb6f9..21c0478befe 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -29,6 +29,7 @@ * @of_other: Live tree for the other FDT * @runs_per_test: Number of times to run each test (typically 1) * @force_run: true to run tests marked with the UTF_MANUAL flag + * @old_bloblist: stores the old gd->bloblist pointer * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value */ @@ -50,6 +51,7 @@ struct unit_test_state { struct device_node *of_other; int runs_per_test; bool force_run; + void *old_bloblist; char expect_str[512]; char actual_str[512]; }; @@ -73,6 +75,7 @@ enum ut_flags { UTF_MANUAL = BIT(8), UTF_ETH_BOOTDEV = BIT(9), /* enable Ethernet bootdevs */ UTF_SF_BOOTDEV = BIT(10), /* enable SPI flash bootdevs */ + UFT_BLOBLIST = BIT(11), /* test changes gd->bloblist */ }; /** -- cgit v1.2.3