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 __bootmeth_h 8 #define __bootmeth_h 9 10 #include <bootflow.h> 11 #include <linux/bitops.h> 12 13 struct blk_desc; 14 struct udevice; 15 16 /** 17 * enum bootmeth_flags - Flags for bootmeths 18 * 19 * @BOOTMETHF_GLOBAL: bootmeth handles bootdev selection automatically 20 * @BOOTMETHF_ANY_PART: bootmeth is willing to check any partition, even if it 21 * has no filesystem 22 */ 23 enum bootmeth_flags { 24 BOOTMETHF_GLOBAL = BIT(0), 25 BOOTMETHF_ANY_PART = BIT(1), 26 }; 27 28 /** 29 * struct bootmeth_uc_plat - information the uclass keeps about each bootmeth 30 * 31 * @desc: A long description of the bootmeth 32 * @flags: Flags for this bootmeth (enum bootmeth_flags) 33 */ 34 struct bootmeth_uc_plat { 35 const char *desc; 36 int flags; 37 }; 38 39 /** struct bootmeth_ops - Operations for boot methods */ 40 struct bootmeth_ops { 41 /** 42 * get_state_desc() - get detailed state information 43 * 44 * Produces a textual description of the state of the boot method. This 45 * can include newline characters if it extends to multiple lines. It 46 * must be a nul-terminated string. 47 * 48 * This may involve reading state from the system, e.g. some data in 49 * the firmware area. 50 * 51 * @dev: Bootmethod device to check 52 * @buf: Buffer to place the info in (terminator must fit) 53 * @maxsize: Size of buffer 54 * Returns: 0 if OK, -ENOSPC is buffer is too small, other -ve error if 55 * something else went wrong 56 */ 57 int (*get_state_desc)(struct udevice *dev, char *buf, int maxsize); 58 59 /** 60 * check_supported() - check if a bootmeth supports this bootdev 61 * 62 * This is optional. If not provided, the bootdev is assumed to be 63 * supported 64 * 65 * The bootmeth can check the bootdev (e.g. to make sure it is a 66 * network device) or the partition information. The following fields 67 * in @iter are available: 68 * 69 * name, dev, state, part 70 * max_part may be set if part != 0 (i.e. there is a valid partition 71 * table). Otherwise max_part is 0 72 * method is available but is the same as @dev 73 * the partition has not yet been read, nor has the filesystem been 74 * checked 75 * 76 * It may update only the flags in @iter 77 * 78 * @dev: Bootmethod device to check against 79 * @iter: On entry, provides bootdev, hwpart, part 80 * Return: 0 if OK, -ENOTSUPP if this bootdev is not supported 81 */ 82 int (*check)(struct udevice *dev, struct bootflow_iter *iter); 83 84 /** 85 * read_bootflow() - read a bootflow for a device 86 * 87 * @dev: Bootmethod device to use 88 * @bflow: On entry, provides dev, hwpart, part and method. 89 * Returns updated bootflow if found 90 * Return: 0 if OK, -ve on error 91 */ 92 int (*read_bootflow)(struct udevice *dev, struct bootflow *bflow); 93 94 /** 95 * set_bootflow() - set the bootflow for a device 96 * 97 * This provides a bootflow file to the bootmeth, to see if it is valid. 98 * If it is, the bootflow is set up accordingly. 99 * 100 * @dev: Bootmethod device to use 101 * @bflow: On entry, provides bootdev. 102 * Returns updated bootflow if found 103 * @buf: Buffer containing the possible bootflow file 104 * @size: Size of file 105 * Return: 0 if OK, -ve on error 106 */ 107 int (*set_bootflow)(struct udevice *dev, struct bootflow *bflow, 108 char *buf, int size); 109 110 /** 111 * read_file() - read a file needed for a bootflow 112 * 113 * Read a file from the same place as the bootflow came from 114 * 115 * @dev: Bootmethod device to use 116 * @bflow: Bootflow providing info on where to read from 117 * @file_path: Path to file (may be absolute or relative) 118 * @addr: Address to load file 119 * @type: File type (IH_TYPE_...) 120 * @sizep: On entry provides the maximum permitted size; on exit 121 * returns the size of the file 122 * Return: 0 if OK, -ENOSPC if the file is too large for @sizep, other 123 * -ve value if something else goes wrong 124 */ 125 int (*read_file)(struct udevice *dev, struct bootflow *bflow, 126 const char *file_path, ulong addr, 127 enum bootflow_img_t type, ulong *sizep); 128 #if CONFIG_IS_ENABLED(BOOTSTD_FULL) 129 /** 130 * readall() - read all files for a bootflow 131 * 132 * @dev: Bootmethod device to boot 133 * @bflow: Bootflow to read 134 * Return: 0 if OK, -EIO on I/O error, other -ve on other error 135 */ 136 int (*read_all)(struct udevice *dev, struct bootflow *bflow); 137 #endif /* BOOTSTD_FULL */ 138 /** 139 * boot() - boot a bootflow 140 * 141 * @dev: Bootmethod device to boot 142 * @bflow: Bootflow to boot 143 * Return: does not return on success, since it should boot the 144 * operating system. Returns -EFAULT if that fails, -ENOTSUPP if 145 * trying method resulted in finding out that is not actually 146 * supported for this boot and should not be tried again unless 147 * something changes, other -ve on other error 148 */ 149 int (*boot)(struct udevice *dev, struct bootflow *bflow); 150 151 /** 152 * set_property() - set the bootmeth property 153 * 154 * This allows the setting of boot method specific properties to enable 155 * automated finer grain control of the boot process 156 * 157 * @name: String containing the name of the relevant boot method 158 * @property: String containing the name of the property to set 159 * @value: String containing the value to be set for the specified 160 * property 161 * Return: 0 if OK, -ENODEV if an unknown bootmeth or property is 162 * provided, -ENOENT if there are no bootmeth devices 163 */ 164 int (*set_property)(struct udevice *dev, const char *property, 165 const char *value); 166 }; 167 168 #define bootmeth_get_ops(dev) ((struct bootmeth_ops *)(dev)->driver->ops) 169 170 /** 171 * bootmeth_get_state_desc() - get detailed state information 172 * 173 * Produces a textual description of the state of the boot method. This 174 * can include newline characters if it extends to multiple lines. It 175 * must be a nul-terminated string. 176 * 177 * This may involve reading state from the system, e.g. some data in 178 * the firmware area. 179 * 180 * @dev: Bootmethod device to check 181 * @buf: Buffer to place the info in (terminator must fit) 182 * @maxsize: Size of buffer 183 * Returns: 0 if OK, -ENOSPC is buffer is too small, other -ve error if 184 * something else went wrong 185 */ 186 int bootmeth_get_state_desc(struct udevice *dev, char *buf, int maxsize); 187 188 /** 189 * bootmeth_check() - check if a bootmeth supports this bootflow 190 * 191 * This is optional. If not provided, the bootdev is assumed to be 192 * supported 193 * 194 * The bootmeth can check the bootdev (e.g. to make sure it is a 195 * network device) or the partition information. The following fields 196 * in @iter are available: 197 * 198 * name, dev, state, part 199 * max_part may be set if part != 0 (i.e. there is a valid partition 200 * table). Otherwise max_part is 0 201 * method is available but is the same as @dev 202 * the partition has not yet been read, nor has the filesystem been 203 * checked 204 * 205 * It may update only the flags in @iter 206 * 207 * @dev: Bootmethod device to check against 208 * @iter: On entry, provides bootdev, hwpart, part 209 * Return: 0 if OK, -ENOTSUPP if this bootdev is not supported 210 */ 211 int bootmeth_check(struct udevice *dev, struct bootflow_iter *iter); 212 213 /** 214 * bootmeth_read_bootflow() - set up a bootflow for a device 215 * 216 * @dev: Bootmethod device to check 217 * @bflow: On entry, provides dev, hwpart, part and method. 218 * Returns updated bootflow if found 219 * Return: 0 if OK, -ve on error 220 */ 221 int bootmeth_read_bootflow(struct udevice *dev, struct bootflow *bflow); 222 223 /** 224 * bootmeth_set_bootflow() - set the bootflow for a device 225 * 226 * This provides a bootflow file to the bootmeth, to see if it is valid. 227 * If it is, the bootflow is set up accordingly. 228 * 229 * @dev: Bootmethod device to use 230 * @bflow: On entry, provides bootdev. 231 * Returns updated bootflow if found 232 * @buf: Buffer containing the possible bootflow file (must be allocated 233 * by caller to @size + 1 bytes) 234 * @size: Size of file 235 * Return: 0 if OK, -ve on error 236 */ 237 int bootmeth_set_bootflow(struct udevice *dev, struct bootflow *bflow, 238 char *buf, int size); 239 240 /** 241 * bootmeth_read_file() - read a file needed for a bootflow 242 * 243 * Read a file from the same place as the bootflow came from 244 * 245 * @dev: Bootmethod device to use 246 * @bflow: Bootflow providing info on where to read from 247 * @file_path: Path to file (may be absolute or relative) 248 * @addr: Address to load file 249 * @type: File type (IH_TYPE_...) 250 * @sizep: On entry provides the maximum permitted size; on exit 251 * returns the size of the file 252 * Return: 0 if OK, -ENOSPC if the file is too large for @sizep, other 253 * -ve value if something else goes wrong 254 */ 255 int bootmeth_read_file(struct udevice *dev, struct bootflow *bflow, 256 const char *file_path, ulong addr, 257 enum bootflow_img_t type, ulong *sizep); 258 259 /** 260 * bootmeth_read_all() - read all bootflow files 261 * 262 * Some bootmeths delay reading of large files until booting is requested. This 263 * causes those files to be read. 264 * 265 * @dev: Bootmethod device to use 266 * @bflow: Bootflow to read 267 * Return: does not return on success, since it should boot the 268 * operating system. Returns -EFAULT if that fails, other -ve on 269 * other error 270 */ 271 int bootmeth_read_all(struct udevice *dev, struct bootflow *bflow); 272 273 /** 274 * bootmeth_boot() - boot a bootflow 275 * 276 * @dev: Bootmethod device to boot 277 * @bflow: Bootflow to boot 278 * Return: does not return on success, since it should boot the 279 * operating system. Returns -EFAULT if that fails, other -ve on 280 * other error 281 */ 282 int bootmeth_boot(struct udevice *dev, struct bootflow *bflow); 283 284 /** 285 * bootmeth_setup_iter_order() - Set up the ordering of bootmeths to scan 286 * 287 * This sets up the ordering information in @iter, based on the selected 288 * ordering of the boot methods in bootstd_priv->bootmeth_order. If there is no 289 * ordering there, then all bootmethods are added 290 * 291 * @iter: Iterator to update with the order 292 * @include_global: true to add the global bootmeths, in which case they appear 293 * first 294 * Return: 0 if OK, -ENOENT if no bootdevs, -ENOMEM if out of memory, other -ve 295 * on other error 296 */ 297 int bootmeth_setup_iter_order(struct bootflow_iter *iter, bool include_global); 298 299 /** 300 * bootmeth_set_order() - Set the bootmeth order 301 * 302 * This selects the ordering to use for bootmeths 303 * 304 * @order_str: String containing the ordering. This is a comma-separate list of 305 * bootmeth-device names, e.g. "extlinux,efi". If empty then a default ordering 306 * is used, based on the sequence number of devices (i.e. using aliases) 307 * Return: 0 if OK, -ENODEV if an unknown bootmeth is mentioned, -ENOMEM if 308 * out of memory, -ENOENT if there are no bootmeth devices 309 */ 310 int bootmeth_set_order(const char *order_str); 311 312 /** 313 * bootmeth_set_property() - Set the bootmeth property 314 * 315 * This allows the setting of boot method specific properties to enable 316 * automated finer grain control of the boot process 317 * 318 * @name: String containing the name of the relevant boot method 319 * @property: String containing the name of the property to set 320 * @value: String containing the value to be set for the specified property 321 * Return: 0 if OK, -ENODEV if an unknown bootmeth or property is provided, 322 * -ENOENT if there are no bootmeth devices 323 */ 324 int bootmeth_set_property(const char *name, const char *property, 325 const char *value); 326 327 /** 328 * bootmeth_setup_fs() - Set up read to read a file 329 * 330 * We must redo the setup before each filesystem operation. This function 331 * handles that, including setting the filesystem type if a block device is not 332 * being used 333 * 334 * @bflow: Information about file to try 335 * @desc: Block descriptor to read from (NULL if not a block device) 336 * Return: 0 if OK, -ve on error 337 */ 338 int bootmeth_setup_fs(struct bootflow *bflow, struct blk_desc *desc); 339 340 /** 341 * bootmeth_try_file() - See we can access a given file 342 * 343 * Check for a file with a given name. If found, the filename is allocated in 344 * @bflow 345 * 346 * Sets the state to BOOTFLOWST_FILE on success. It also calls 347 * fs_set_blk_dev_with_part() so that this does not need to be done by the 348 * caller before reading the file. 349 * 350 * @bflow: Information about file to try 351 * @desc: Block descriptor to read from (NULL for sandbox host) 352 * @prefix: Filename prefix to prepend to @fname (NULL for none) 353 * @fname: Filename to read 354 * Return: 0 if OK, -ENOMEM if not enough memory to allocate bflow->fname, 355 * other -ve value on other error 356 */ 357 int bootmeth_try_file(struct bootflow *bflow, struct blk_desc *desc, 358 const char *prefix, const char *fname); 359 360 /** 361 * bootmeth_alloc_file() - Allocate and read a bootflow file 362 * 363 * Allocates memory for a bootflow file and reads it in. Sets the state to 364 * BOOTFLOWST_READY on success 365 * 366 * Note that fs_set_blk_dev_with_part() must have been called previously. 367 * 368 * @bflow: Information about file to read 369 * @size_limit: Maximum file size to permit 370 * @align: Allocation alignment (1 for unaligned) 371 * @type: File type (IH_TYPE_...) 372 * Return: 0 if OK, -E2BIG if file is too large, -ENOMEM if out of memory, 373 * other -ve on other error 374 */ 375 int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align, 376 enum bootflow_img_t type); 377 378 /** 379 * bootmeth_alloc_other() - Allocate and read a file for a bootflow 380 * 381 * This reads an arbitrary file in the same directory as the bootflow, 382 * allocating memory for it. The buffer is one byte larger than the file length, 383 * so that it can be nul-terminated. 384 * 385 * @bflow: Information about file to read 386 * @fname: Filename to read from (within bootflow->subdir) 387 * @type: File type (IH_TYPE_...) 388 * @bufp: Returns a pointer to the allocated buffer 389 * @sizep: Returns the size of the buffer 390 * Return: 0 if OK, -ENOMEM if out of memory, other -ve on other error 391 */ 392 int bootmeth_alloc_other(struct bootflow *bflow, const char *fname, 393 enum bootflow_img_t type, void **bufp, uint *sizep); 394 395 /** 396 * bootmeth_common_read_file() - Common handler for reading a file 397 * 398 * Reads a named file from the same location as the bootflow file. 399 * 400 * @dev: bootmeth device to read from 401 * @bflow: Bootflow information 402 * @file_path: Path to file 403 * @addr: Address to load file to 404 * @type: File type (IH_TYPE_...) 405 * @sizep: On entry, the maximum file size to accept, on exit the actual file 406 * size read 407 */ 408 int bootmeth_common_read_file(struct udevice *dev, struct bootflow *bflow, 409 const char *file_path, ulong addr, 410 enum bootflow_img_t type, ulong *sizep); 411 412 /** 413 * bootmeth_get_bootflow() - Get a bootflow from a global bootmeth 414 * 415 * Check the bootmeth for a bootflow which can be used. In this case the 416 * bootmeth handles all bootdev selection, etc. 417 * 418 * @dev: bootmeth device to read from 419 * @bflow: Bootflow information 420 * @return 0 on success, -ve if a bootflow could not be found or had an error 421 */ 422 int bootmeth_get_bootflow(struct udevice *dev, struct bootflow *bflow); 423 424 #endif 425