bootmeth.h 12 KB

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