diff mbox series

[2/2] pxe: Get default selection from board type if label matches

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

Commit Message

Frieder Schrempf Dec. 10, 2019, 3:47 p.m. UTC
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>
---
 cmd/pxe_utils.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

Comments

Frieder Schrempf Dec. 11, 2019, 9:40 a.m. UTC | #1
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 mbox series

Patch

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;