Message ID | 20191210154558.9307-2-frieder.schrempf@kontron.de |
---|---|
State | Changes Requested |
Delegated to: | Tom Rini |
Headers | show |
Series | [1/2] menu: Make some parts of the menu available to other components | expand |
On 10.12.19 16:45, Schrempf Frieder wrote: > From: Frieder Schrempf <frieder.schrempf@kontron.de> > > In order to auto-select an option from the pxe boot menu, that > matches the detected board, we check the board model string in the > devicetree and set the default menu selection, if it matches the > label of the menu entry and there is no default selection already > set. > > This is useful in combination with SPL that loads a FIT image with > U-Boot and multiple DTBs. SPL can detect the board and choose the > matching configuration in the FIT by using > board_fit_config_name_match(). > > Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de> I forgot to fix some compiler warnings in this code, so this is probably more like a RFC until I send a fixed v2. > --- > cmd/pxe_utils.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 62 insertions(+) > > diff --git a/cmd/pxe_utils.c b/cmd/pxe_utils.c > index a636346bb5..510957e68f 100644 > --- a/cmd/pxe_utils.c > +++ b/cmd/pxe_utils.c > @@ -1219,6 +1219,61 @@ struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg) > return cfg; > } > > +#ifdef CONFIG_OF_CONTROL > +/* > + * Check if an item's name matches a provided string, pointed to by extra. > + * > + * This is called via menu_items_iter, so it returns a pointer to the item if > + * the name matches, and returns NULL otherwise. > + */ > +static inline void *pxe_item_name_match(struct menu *m, struct menu_item *item, > + void *extra) > +{ > + char *name = extra; > + struct pxe_label *label; > + > + if (!name || !item->key) > + return NULL; > + > + label = (struct pxe_label *)item->data; > + > + if (strcmp(label->name, name) == 0) > + return item; > + > + return NULL; > +} > + > +/* > + * Find the first item with a name matching the given name, if any exists. > + */ > +inline struct menu_item *menu_item_by_pxe_name(struct menu *m, char *name) > +{ > + return menu_items_iter(m, pxe_item_name_match, name); > +} > + > +int pxe_runtime_select_menu_default(struct menu *m) > +{ > + DECLARE_GLOBAL_DATA_PTR; > + struct menu_item *item = NULL; > + const char *model; > + > + model = fdt_getprop(gd->fdt_blob, 0, "model", NULL); > + > + if (!model) > + return 0; > + > + item = menu_item_by_pxe_name(m, model); > + > + if (item) { > + printf("Menu entry %s fits detected board. " \ > + "Use as default selection...\n", item->key); > + m->default_item = item; > + } > + > + return 0; > +} > +#endif > + > /* > * Converts a pxe_menu struct into a menu struct for use with U-Boot's generic > * menu code. > @@ -1257,6 +1312,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) > /* > * After we've created items for each label in the menu, set the > * menu's default label if one was specified. > + * If OF_CONTROL is enabled and we don't have a default specified, > + * we try to use an entry that matches the board/model name as default. > */ > if (default_num) { > err = menu_default_set(m, default_num); > @@ -1268,6 +1325,11 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) > > printf("Missing default: %s\n", cfg->default_label); > } > +#ifdef CONFIG_OF_CONTROL > + } else if (pxe_runtime_select_menu_default(m)) { > + menu_destroy(m); > + return NULL; > +#endif > } > > return m; >
diff --git a/cmd/pxe_utils.c b/cmd/pxe_utils.c index a636346bb5..510957e68f 100644 --- a/cmd/pxe_utils.c +++ b/cmd/pxe_utils.c @@ -1219,6 +1219,61 @@ struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg) return cfg; } +#ifdef CONFIG_OF_CONTROL +/* + * Check if an item's name matches a provided string, pointed to by extra. + * + * This is called via menu_items_iter, so it returns a pointer to the item if + * the name matches, and returns NULL otherwise. + */ +static inline void *pxe_item_name_match(struct menu *m, struct menu_item *item, + void *extra) +{ + char *name = extra; + struct pxe_label *label; + + if (!name || !item->key) + return NULL; + + label = (struct pxe_label *)item->data; + + if (strcmp(label->name, name) == 0) + return item; + + return NULL; +} + +/* + * Find the first item with a name matching the given name, if any exists. + */ +inline struct menu_item *menu_item_by_pxe_name(struct menu *m, char *name) +{ + return menu_items_iter(m, pxe_item_name_match, name); +} + +int pxe_runtime_select_menu_default(struct menu *m) +{ + DECLARE_GLOBAL_DATA_PTR; + struct menu_item *item = NULL; + const char *model; + + model = fdt_getprop(gd->fdt_blob, 0, "model", NULL); + + if (!model) + return 0; + + item = menu_item_by_pxe_name(m, model); + + if (item) { + printf("Menu entry %s fits detected board. " \ + "Use as default selection...\n", item->key); + m->default_item = item; + } + + return 0; +} +#endif + /* * Converts a pxe_menu struct into a menu struct for use with U-Boot's generic * menu code. @@ -1257,6 +1312,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) /* * After we've created items for each label in the menu, set the * menu's default label if one was specified. + * If OF_CONTROL is enabled and we don't have a default specified, + * we try to use an entry that matches the board/model name as default. */ if (default_num) { err = menu_default_set(m, default_num); @@ -1268,6 +1325,11 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) printf("Missing default: %s\n", cfg->default_label); } +#ifdef CONFIG_OF_CONTROL + } else if (pxe_runtime_select_menu_default(m)) { + menu_destroy(m); + return NULL; +#endif } return m;