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