1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Standard U-Boot boot framework
4  *
5  * Copyright 2021 Google LLC
6  * Written by Simon Glass <sjg@chromium.org>
7  */
8 
9 #ifndef __bootstd_h
10 #define __bootstd_h
11 
12 #include <alist.h>
13 #include <dm/ofnode_decl.h>
14 #include <linux/types.h>
15 
16 struct udevice;
17 
18 /**
19  * struct bootstd_priv - priv data for the bootstd driver
20  *
21  * This is attached to the (only) bootstd device, so there is only one instance
22  * of this struct. It provides overall information about bootdevs and bootflows.
23  *
24  * TODO(sjg@chromium.org): Convert prefixes, bootdev_order and env_order to use
25  *	alist
26  *
27  * @prefixes: NULL-terminated list of prefixes to use for bootflow filenames,
28  *	e.g. "/", "/boot/"; NULL if none
29  * @bootdev_order: Order to use for bootdevs (or NULL if none), with each item
30  *	being a bootdev label, e.g. "mmc2", "mmc1" (NULL terminated)
31  * @env_order: Order as specified by the boot_targets env var (or NULL if none),
32  *	with each item being a bootdev label, e.g. "mmc2", "mmc1" (NULL
33  *	terminated)
34  * @cur_bootdev: Currently selected bootdev (for commands)
35  * @cur_bootflow: Currently selected bootflow (for commands)
36  * @bootflows: (struct bootflow) Global list of all bootflows across all
37  *	bootdevs
38  * @bootmeth_count: Number of bootmeth devices in @bootmeth_order
39  * @bootmeth_order: List of bootmeth devices to use, in order, NULL-terminated
40  * @vbe_bootmeth: Currently selected VBE bootmeth, NULL if none
41  * @theme: Node containing the theme information
42  * @hunters_used: Bitmask of used hunters, indexed by their position in the
43  * linker list. The bit is set if the hunter has been used already
44  */
45 struct bootstd_priv {
46 	const char **prefixes;
47 	const char **bootdev_order;
48 	const char **env_order;
49 	struct udevice *cur_bootdev;
50 	struct bootflow *cur_bootflow;
51 	struct alist bootflows;
52 	int bootmeth_count;
53 	struct udevice **bootmeth_order;
54 	struct udevice *vbe_bootmeth;
55 	ofnode theme;
56 	uint hunters_used;
57 };
58 
59 /**
60  * bootstd_get_bootdev_order() - Get the boot-order list
61  *
62  * This reads the boot order, e.g. {"mmc0", "mmc2", NULL}
63  *
64  * The list is alloced by the bootstd driver so should not be freed. That is the
65  * reason for all the const stuff in the function signature
66  *
67  * @dev: bootstd device
68  * @okp: returns true if OK, false if out of memory
69  * Return: list of string pointers, terminated by NULL; or NULL if no boot
70  * order. Note that this returns NULL in the case of an empty list
71  */
72 const char *const *const bootstd_get_bootdev_order(struct udevice *dev,
73 						   bool *okp);
74 
75 /**
76  * bootstd_get_prefixes() - Get the filename-prefixes list
77  *
78  * This reads the prefixes, e.g. {"/", "/boot", NULL}
79  *
80  * The list is alloced by the bootstd driver so should not be freed. That is the
81  * reason for all the const stuff in the function signature
82  *
83  * Return: list of string points, terminated by NULL; or NULL if no boot order
84  */
85 const char *const *const bootstd_get_prefixes(struct udevice *dev);
86 
87 /**
88  * bootstd_get_priv() - Get the (single) state for the bootstd system
89  *
90  * The state holds a global list of all bootflows that have been found.
91  *
92  * Return: 0 if OK, -ve if the uclass does not exist
93  */
94 int bootstd_get_priv(struct bootstd_priv **stdp);
95 
96 /**
97  * bootstd_try_priv() - Try to get the (single) state for the bootstd system
98  *
99  * The state holds a global list of all bootflows that have been found. This
100  * function returns the state if available, but takes care not to create the
101  * device (or uclass) if it doesn't exist.
102  *
103  * This function is safe to use in the 'unbind' path. It will always return NULL
104  * unless the bootstd device is probed and ready, e.g. bootstd_get_priv() has
105  * previously been called.
106  *
107  * TODO(sjg@chromium.org): Consider adding a bootstd pointer to global_data
108  *
109  * Return: pointer if the device exists, else NULL
110  */
111 struct bootstd_priv *bootstd_try_priv(void);
112 
113 /**
114  * bootstd_clear_glob() - Clear the global list of bootflows
115  *
116  * This removes all bootflows globally and across all bootdevs.
117  */
118 void bootstd_clear_glob(void);
119 
120 /**
121  * bootstd_prog_boot() - Run standard boot in a fully programmatic mode
122  *
123  * Attempts to boot without making any use of U-Boot commands
124  *
125  * Returns: -ve error value (does not return except on failure to boot)
126  */
127 int bootstd_prog_boot(void);
128 
129 /**
130  * bootstd_add_bootflow() - Add a bootflow to the global list
131  *
132  * All fields in @bflow must be set up. Note that @bflow->dev is used to add the
133  * bootflow to that device.
134  *
135  * The bootflow is also added to the global list of all bootflows
136  *
137  * @dev: Bootdev device to add to
138  * @bflow: Bootflow to add. Note that fields within bflow must be allocated
139  *	since this function takes over ownership of these. This functions makes
140  *	a copy of @bflow itself (without allocating its fields again), so the
141  *	caller must dispose of the memory used by the @bflow pointer itself
142  * Return: element number in the list, if OK, -ENOMEM if out of memory
143  */
144 int bootstd_add_bootflow(struct bootflow *bflow);
145 
146 /**
147  * bootstd_clear_bootflows_for_bootdev() - Clear bootflows from a bootdev
148  *
149  * Each bootdev maintains a list of discovered bootflows. This provides a
150  * way to clear it. These bootflows are removed from the global list too.
151  *
152  * @dev: bootdev device to update
153  */
154 int bootstd_clear_bootflows_for_bootdev(struct udevice *dev);
155 
156 #endif
157