fit: prefer the default configuration on best-match ties
With CONFIG_FIT_BEST_MATCH, fit_conf_find_compat() selects the configuration matching the most specific U-Boot compatible string; on equal matches the first listed configuration wins and the configurations node 'default' property is never consulted. A FIT whose configurations all share the same base devicetree compatible (e.g. one manifest carrying a base tree plus overlay combinations for a single board) therefore always boots the first configuration, silently ignoring the default chosen by the manifest author. Break score ties in favour of the default configuration. A strictly better compatible match still wins over it, and FITs without a default keep the current first-listed behaviour. Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Tom Rini <trini@konsulko.com> Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
@@ -8,8 +8,76 @@
|
||||
|
||||
#include <image.h>
|
||||
#include <test/ut.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include "bootstd_common.h"
|
||||
|
||||
/* Test that the default configuration breaks best-match ties */
|
||||
static int test_fit_conf_find_compat(struct unit_test_state *uts)
|
||||
{
|
||||
char fdt[256], fit[1024];
|
||||
int confs, images, node;
|
||||
int ret;
|
||||
|
||||
/* control devicetree with a two-entry compatible list */
|
||||
ut_assertok(fdt_create_empty_tree(fdt, sizeof(fdt)));
|
||||
ut_assertok(fdt_appendprop_string(fdt, 0, "compatible",
|
||||
"test,board-a"));
|
||||
ut_assertok(fdt_appendprop_string(fdt, 0, "compatible",
|
||||
"test,fallback"));
|
||||
|
||||
/* FIT with two configurations matching the same compatible */
|
||||
ut_assertok(fdt_create_empty_tree(fit, sizeof(fit)));
|
||||
images = fdt_add_subnode(fit, 0, "images");
|
||||
ut_assert(images >= 0);
|
||||
confs = fdt_add_subnode(fit, 0, "configurations");
|
||||
ut_assert(confs >= 0);
|
||||
ut_assertok(fdt_setprop_string(fit, confs, FIT_DEFAULT_PROP, "conf-2"));
|
||||
/*
|
||||
* fdt_add_subnode() inserts before existing subnodes: create conf-2
|
||||
* first so that conf-1 ends up listed first, like an .its compiled
|
||||
* with the configurations in that order
|
||||
*/
|
||||
node = fdt_add_subnode(fit, confs, "conf-2");
|
||||
ut_assert(node >= 0);
|
||||
ut_assertok(fdt_setprop_string(fit, node, "compatible",
|
||||
"test,board-a"));
|
||||
node = fdt_add_subnode(fit, confs, "conf-1");
|
||||
ut_assert(node >= 0);
|
||||
ut_assertok(fdt_setprop_string(fit, node, "compatible",
|
||||
"test,board-a"));
|
||||
confs = fdt_path_offset(fit, "/configurations");
|
||||
node = fdt_first_subnode(fit, confs);
|
||||
ut_asserteq_str("conf-1", fdt_get_name(fit, node, NULL));
|
||||
|
||||
/* on a tie, the default configuration wins */
|
||||
ret = fit_conf_find_compat(fit, fdt);
|
||||
ut_assert(ret > 0);
|
||||
ut_asserteq_str("conf-2", fdt_get_name(fit, ret, NULL));
|
||||
|
||||
/* without a default, the first listed configuration wins */
|
||||
confs = fdt_path_offset(fit, "/configurations");
|
||||
ut_assertok(fdt_delprop(fit, confs, FIT_DEFAULT_PROP));
|
||||
confs = fdt_path_offset(fit, "/configurations");
|
||||
ut_assertnull((void *)fdt_getprop(fit, confs, FIT_DEFAULT_PROP, NULL));
|
||||
ret = fit_conf_find_compat(fit, fdt);
|
||||
ut_assert(ret > 0);
|
||||
ut_asserteq_str("conf-1", fdt_get_name(fit, ret, NULL));
|
||||
|
||||
/* a strictly better match still beats the default */
|
||||
confs = fdt_path_offset(fit, "/configurations");
|
||||
ut_assertok(fdt_setprop_string(fit, confs, FIT_DEFAULT_PROP, "conf-2"));
|
||||
confs = fdt_path_offset(fit, "/configurations");
|
||||
node = fdt_subnode_offset(fit, confs, "conf-2");
|
||||
ut_assertok(fdt_setprop_string(fit, node, "compatible",
|
||||
"test,fallback"));
|
||||
ret = fit_conf_find_compat(fit, fdt);
|
||||
ut_assert(ret > 0);
|
||||
ut_asserteq_str("conf-1", fdt_get_name(fit, ret, NULL));
|
||||
|
||||
return 0;
|
||||
}
|
||||
BOOTSTD_TEST(test_fit_conf_find_compat, 0);
|
||||
|
||||
/* Test of image phase */
|
||||
static int test_image_phase(struct unit_test_state *uts)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user