1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * Copyright 2021 Google LLC 4 * Written by Simon Glass <sjg@chromium.org> 5 */ 6 7 #ifndef __bootflow_h 8 #define __bootflow_h 9 10 #include <bootdev.h> 11 #include <dm/ofnode_decl.h> 12 #include <linux/list.h> 13 14 struct bootstd_priv; 15 struct expo; 16 17 enum { 18 BOOTFLOW_MAX_USED_DEVS = 16, 19 }; 20 21 /** 22 * enum bootflow_state_t - states that a particular bootflow can be in 23 * 24 * Only bootflows in state BOOTFLOWST_READY can be used to boot. 25 * 26 * See bootflow_state[] for the names for each of these 27 */ 28 enum bootflow_state_t { 29 BOOTFLOWST_BASE, /**< Nothing known yet */ 30 BOOTFLOWST_MEDIA, /**< Media exists */ 31 BOOTFLOWST_PART, /**< Partition exists */ 32 BOOTFLOWST_FS, /**< Filesystem exists */ 33 BOOTFLOWST_FILE, /**< Bootflow file exists */ 34 BOOTFLOWST_READY, /**< Bootflow file loaded */ 35 36 BOOTFLOWST_COUNT 37 }; 38 39 /** 40 * enum bootflow_flags_t - flags for bootflows 41 * 42 * @BOOTFLOWF_USE_PRIOR_FDT: Indicates that an FDT was not found by the bootmeth 43 * and it is using the prior-stage FDT, which is the U-Boot control FDT. 44 * This is only possible with the EFI bootmeth (distro-efi) and only when 45 * CONFIG_OF_HAS_PRIOR_STAGE is enabled 46 */ 47 enum bootflow_flags_t { 48 BOOTFLOWF_USE_PRIOR_FDT = 1 << 0, 49 }; 50 51 /** 52 * struct bootflow - information about a bootflow 53 * 54 * This is connected into two separate linked lists: 55 * 56 * bm_sibling - links all bootflows in the same bootdev 57 * glob_sibling - links all bootflows in all bootdevs 58 * 59 * @bm_node: Points to siblings in the same bootdev 60 * @glob_node: Points to siblings in the global list (all bootdev) 61 * @dev: Bootdevice device which produced this bootflow 62 * @blk: Block device which contains this bootflow, NULL if this is a network 63 * device or sandbox 'host' device 64 * @part: Partition number (0 for whole device) 65 * @fs_type: Filesystem type (FS_TYPE...) if this is fixed by the media, else 0. 66 * For example, the sandbox host-filesystem bootdev sets this to 67 * FS_TYPE_SANDBOX 68 * @method: Bootmethod device used to perform the boot and read files 69 * @name: Name of bootflow (allocated) 70 * @state: Current state (enum bootflow_state_t) 71 * @subdir: Subdirectory to fetch files from (with trailing /), or NULL if none 72 * @fname: Filename of bootflow file (allocated) 73 * @logo: Logo to display for this bootflow (BMP format) 74 * @logo_size: Size of the logo in bytes 75 * @buf: Bootflow file contents (allocated) 76 * @size: Size of bootflow file in bytes 77 * @err: Error number received (0 if OK) 78 * @os_name: Name of the OS / distro being booted, or NULL if not known 79 * (allocated) 80 * @fdt_fname: Filename of FDT file 81 * @fdt_size: Size of FDT file 82 * @fdt_addr: Address of loaded fdt 83 * @flags: Flags for the bootflow (see enum bootflow_flags_t) 84 */ 85 struct bootflow { 86 struct list_head bm_node; 87 struct list_head glob_node; 88 struct udevice *dev; 89 struct udevice *blk; 90 int part; 91 int fs_type; 92 struct udevice *method; 93 char *name; 94 enum bootflow_state_t state; 95 char *subdir; 96 char *fname; 97 void *logo; 98 uint logo_size; 99 char *buf; 100 int size; 101 int err; 102 char *os_name; 103 char *fdt_fname; 104 int fdt_size; 105 ulong fdt_addr; 106 int flags; 107 }; 108 109 /** 110 * enum bootflow_iter_flags_t - flags for the bootflow iterator 111 * 112 * @BOOTFLOWIF_FIXED: Only used fixed/internal media 113 * @BOOTFLOWIF_SHOW: Show each bootdev before scanning it; show each hunter 114 * before using it 115 * @BOOTFLOWIF_ALL: Return bootflows with errors as well 116 * @BOOTFLOWIF_HUNT: Hunt for new bootdevs using the bootdrv hunters 117 * 118 * Internal flags: 119 * @BOOTFLOWIF_SINGLE_DEV: (internal) Just scan one bootdev 120 * @BOOTFLOWIF_SKIP_GLOBAL: (internal) Don't scan global bootmeths 121 * @BOOTFLOWIF_SINGLE_UCLASS: (internal) Keep scanning through all devices in 122 * this uclass (used with things like "mmc") 123 * @BOOTFLOWIF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used 124 * with things like "mmc1") 125 */ 126 enum bootflow_iter_flags_t { 127 BOOTFLOWIF_FIXED = 1 << 0, 128 BOOTFLOWIF_SHOW = 1 << 1, 129 BOOTFLOWIF_ALL = 1 << 2, 130 BOOTFLOWIF_HUNT = 1 << 3, 131 132 /* 133 * flags used internally by standard boot - do not set these when 134 * calling bootflow_scan_bootdev() etc. 135 */ 136 BOOTFLOWIF_SINGLE_DEV = 1 << 16, 137 BOOTFLOWIF_SKIP_GLOBAL = 1 << 17, 138 BOOTFLOWIF_SINGLE_UCLASS = 1 << 18, 139 BOOTFLOWIF_SINGLE_MEDIA = 1 << 19, 140 }; 141 142 /** 143 * enum bootflow_meth_flags_t - flags controlling which bootmeths are used 144 * 145 * Used during iteration, e.g. by bootdev_find_by_label(), to determine which 146 * bootmeths are used for the current bootdev. The flags reset when the bootdev 147 * changes 148 * 149 * @BOOTFLOW_METHF_DHCP_ONLY: Only use dhcp (scripts and EFI) 150 * @BOOTFLOW_METHF_PXE_ONLY: Only use pxe (PXE boot) 151 * @BOOTFLOW_METHF_SINGLE_DEV: Scan only a single bootdev (used for labels like 152 * "3"). This is used if a sequence number is provided instead of a label 153 * @BOOTFLOW_METHF_SINGLE_UCLASS: Scan all bootdevs in this one uclass (used 154 * with things like "mmc"). If this is not set, then the bootdev has an integer 155 * value in the label (like "mmc2") 156 */ 157 enum bootflow_meth_flags_t { 158 BOOTFLOW_METHF_DHCP_ONLY = 1 << 0, 159 BOOTFLOW_METHF_PXE_ONLY = 1 << 1, 160 BOOTFLOW_METHF_SINGLE_DEV = 1 << 2, 161 BOOTFLOW_METHF_SINGLE_UCLASS = 1 << 3, 162 }; 163 164 /** 165 * struct bootflow_iter - state for iterating through bootflows 166 * 167 * This starts at with the first bootdev/partition/bootmeth and can be used to 168 * iterate through all of them. 169 * 170 * Iteration starts with the bootdev. The first partition (0, i.e. whole device) 171 * is scanned first. For partition 0, it iterates through all the available 172 * bootmeths to see which one(s) can provide a bootflow. Then it moves to 173 * parition 1 (if there is one) and the process continues. Once all partitions 174 * are examined, it moves to the next bootdev. 175 * 176 * Initially @max_part is 0, meaning that only the whole device (@part=0) can be 177 * used. During scanning, if a partition table is found, then @max_part is 178 * updated to a larger value, no less than the number of available partitions. 179 * This ensures that iteration works through all partitions on the bootdev. 180 * 181 * @flags: Flags to use (see enum bootflow_iter_flags_t). If 182 * BOOTFLOWIF_GLOBAL_FIRST is enabled then the global bootmeths are being 183 * scanned, otherwise we have moved onto the bootdevs 184 * @dev: Current bootdev, NULL if none. This is only ever updated in 185 * bootflow_iter_set_dev() 186 * @part: Current partition number (0 for whole device) 187 * @method: Current bootmeth 188 * @max_part: Maximum hardware partition number in @dev, 0 if there is no 189 * partition table 190 * @first_bootable: First bootable partition, or 0 if none 191 * @err: Error obtained from checking the last iteration. This is used to skip 192 * forward (e.g. to skip the current partition because it is not valid) 193 * -ESHUTDOWN: try next bootdev 194 * @num_devs: Number of bootdevs in @dev_used 195 * @max_devs: Maximum number of entries in @dev_used 196 * @dev_used: List of bootdevs used during iteration 197 * @labels: List of labels to scan for bootdevs 198 * @cur_label: Current label being processed 199 * @num_methods: Number of bootmeth devices in @method_order 200 * @cur_method: Current method number, an index into @method_order 201 * @first_glob_method: First global method, if any, else -1 202 * @cur_prio: Current priority being scanned 203 * @method_order: List of bootmeth devices to use, in order. The normal methods 204 * appear first, then the global ones, if any 205 * @doing_global: true if we are iterating through the global bootmeths (which 206 * happens before the normal ones) 207 * @method_flags: flags controlling which methods should be used for this @dev 208 * (enum bootflow_meth_flags_t) 209 */ 210 struct bootflow_iter { 211 int flags; 212 struct udevice *dev; 213 int part; 214 struct udevice *method; 215 int max_part; 216 int first_bootable; 217 int err; 218 int num_devs; 219 int max_devs; 220 struct udevice *dev_used[BOOTFLOW_MAX_USED_DEVS]; 221 const char *const *labels; 222 int cur_label; 223 int num_methods; 224 int cur_method; 225 int first_glob_method; 226 enum bootdev_prio_t cur_prio; 227 struct udevice **method_order; 228 bool doing_global; 229 int method_flags; 230 }; 231 232 /** 233 * bootflow_init() - Set up a bootflow struct 234 * 235 * The bootflow is zeroed and set to state BOOTFLOWST_BASE 236 * 237 * @bflow: Struct to set up 238 * @bootdev: Bootdev to use 239 * @meth: Bootmeth to use 240 */ 241 void bootflow_init(struct bootflow *bflow, struct udevice *bootdev, 242 struct udevice *meth); 243 244 /** 245 * bootflow_iter_init() - Reset a bootflow iterator 246 * 247 * This sets everything to the starting point, ready for use. 248 * 249 * @iter: Place to store private info (inited by this call) 250 * @flags: Flags to use (see enum bootflow_iter_flags_t) 251 */ 252 void bootflow_iter_init(struct bootflow_iter *iter, int flags); 253 254 /** 255 * bootflow_iter_uninit() - Free memory used by an interator 256 * 257 * @iter: Iterator to free 258 */ 259 void bootflow_iter_uninit(struct bootflow_iter *iter); 260 261 /** 262 * bootflow_iter_drop_bootmeth() - Remove a bootmeth from an iterator 263 * 264 * Update the iterator so that the bootmeth will not be used again while this 265 * iterator is in use 266 * 267 * @iter: Iterator to update 268 * @bmeth: Boot method to remove 269 */ 270 int bootflow_iter_drop_bootmeth(struct bootflow_iter *iter, 271 const struct udevice *bmeth); 272 273 /** 274 * bootflow_scan_first() - find the first bootflow for a device or label 275 * 276 * If @flags includes BOOTFLOWIF_ALL then bootflows with errors are returned too 277 * 278 * @dev: Boot device to scan, NULL to work through all of them until it 279 * finds one that can supply a bootflow 280 * @label: Label to control the scan, NULL to work through all devices 281 * until it finds one that can supply a bootflow 282 * @iter: Place to store private info (inited by this call) 283 * @flags: Flags for iterator (enum bootflow_iter_flags_t). Note that if 284 * @dev is NULL, then BOOTFLOWIF_SKIP_GLOBAL is set automatically by this 285 * function 286 * @bflow: Place to put the bootflow if found 287 * Return: 0 if found, -ENODEV if no device, other -ve on other error 288 * (iteration can continue) 289 */ 290 int bootflow_scan_first(struct udevice *dev, const char *label, 291 struct bootflow_iter *iter, int flags, 292 struct bootflow *bflow); 293 294 /** 295 * bootflow_scan_next() - find the next bootflow 296 * 297 * This works through the available bootdev devices until it finds one that 298 * can supply a bootflow. It then returns that bootflow 299 * 300 * @iter: Private info (as set up by bootflow_scan_first()) 301 * @bflow: Place to put the bootflow if found 302 * Return: 0 if found, -ENODEV if no device, -ESHUTDOWN if no more bootflows, 303 * other -ve on other error (iteration can continue) 304 */ 305 int bootflow_scan_next(struct bootflow_iter *iter, struct bootflow *bflow); 306 307 /** 308 * bootflow_first_glob() - Get the first bootflow from the global list 309 * 310 * Returns the first bootflow in the global list, no matter what bootflow it is 311 * attached to 312 * 313 * @bflowp: Returns a pointer to the bootflow 314 * Return: 0 if found, -ENOENT if there are no bootflows 315 */ 316 int bootflow_first_glob(struct bootflow **bflowp); 317 318 /** 319 * bootflow_next_glob() - Get the next bootflow from the global list 320 * 321 * Returns the next bootflow in the global list, no matter what bootflow it is 322 * attached to 323 * 324 * @bflowp: On entry, the last bootflow returned , e.g. from 325 * bootflow_first_glob() 326 * Return: 0 if found, -ENOENT if there are no more bootflows 327 */ 328 int bootflow_next_glob(struct bootflow **bflowp); 329 330 /** 331 * bootflow_free() - Free memory used by a bootflow 332 * 333 * This frees fields within @bflow, but not the @bflow pointer itself 334 */ 335 void bootflow_free(struct bootflow *bflow); 336 337 /** 338 * bootflow_boot() - boot a bootflow 339 * 340 * @bflow: Bootflow to boot 341 * Return: -EPROTO if bootflow has not been loaded, -ENOSYS if the bootflow 342 * type is not supported, -EFAULT if the boot returned without an error 343 * when we are expecting it to boot, -ENOTSUPP if trying method resulted in 344 * finding out that is not actually supported for this boot and should not 345 * be tried again unless something changes 346 */ 347 int bootflow_boot(struct bootflow *bflow); 348 349 /** 350 * bootflow_run_boot() - Try to boot a bootflow 351 * 352 * @iter: Current iteration (or NULL if none). Used to disable a bootmeth if the 353 * boot returns -ENOTSUPP 354 * @bflow: Bootflow to boot 355 * Return: result of trying to boot 356 */ 357 int bootflow_run_boot(struct bootflow_iter *iter, struct bootflow *bflow); 358 359 /** 360 * bootflow_state_get_name() - Get the name of a bootflow state 361 * 362 * @state: State to check 363 * Return: name, or "?" if invalid 364 */ 365 const char *bootflow_state_get_name(enum bootflow_state_t state); 366 367 /** 368 * bootflow_remove() - Remove a bootflow and free its memory 369 * 370 * This updates the linked lists containing the bootflow then frees it. 371 * 372 * @bflow: Bootflow to remove 373 */ 374 void bootflow_remove(struct bootflow *bflow); 375 376 /** 377 * bootflow_iter_check_blk() - Check that a bootflow uses a block device 378 * 379 * This checks the bootdev in the bootflow to make sure it uses a block device 380 * 381 * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. ethernet) 382 */ 383 int bootflow_iter_check_blk(const struct bootflow_iter *iter); 384 385 /** 386 * bootflow_iter_check_sf() - Check that a bootflow uses SPI FLASH 387 * 388 * This checks the bootdev in the bootflow to make sure it uses SPI flash 389 * 390 * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. ethernet) 391 */ 392 int bootflow_iter_check_sf(const struct bootflow_iter *iter); 393 394 /** 395 * bootflow_iter_check_net() - Check that a bootflow uses a network device 396 * 397 * This checks the bootdev in the bootflow to make sure it uses a network 398 * device 399 * 400 * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. MMC) 401 */ 402 int bootflow_iter_check_net(const struct bootflow_iter *iter); 403 404 /** 405 * bootflow_iter_check_system() - Check that a bootflow uses the bootstd device 406 * 407 * This checks the bootdev in the bootflow to make sure it uses the bootstd 408 * device 409 * 410 * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. MMC) 411 */ 412 int bootflow_iter_check_system(const struct bootflow_iter *iter); 413 414 /** 415 * bootflow_menu_new() - Create a new bootflow menu 416 * 417 * @expp: Returns the expo created 418 * Returns 0 on success, -ve on error 419 */ 420 int bootflow_menu_new(struct expo **expp); 421 422 /** 423 * bootflow_menu_apply_theme() - Apply a theme to a bootmenu 424 * 425 * @exp: Expo to update 426 * @node: Node containing the theme information 427 * Returns 0 on success, -ve on error 428 */ 429 int bootflow_menu_apply_theme(struct expo *exp, ofnode node); 430 431 /** 432 * bootflow_menu_run() - Create and run a menu of available bootflows 433 * 434 * @std: Bootstd information 435 * @text_mode: Uses a text-based menu suitable for a serial port 436 * @bflowp: Returns chosen bootflow (set to NULL if nothing is chosen) 437 * @return 0 if an option was chosen, -EAGAIN if nothing was chosen, -ve on 438 * error 439 */ 440 int bootflow_menu_run(struct bootstd_priv *std, bool text_mode, 441 struct bootflow **bflowp); 442 443 #endif 444