diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/bootdev.h | 36 | ||||
| -rw-r--r-- | include/bootflow.h | 85 | ||||
| -rw-r--r-- | include/bootmeth.h | 22 | ||||
| -rw-r--r-- | include/bootstd.h | 50 | ||||
| -rw-r--r-- | include/pxe_utils.h | 14 |
5 files changed, 161 insertions, 46 deletions
diff --git a/include/bootdev.h b/include/bootdev.h index ad4af0d1310..12c90c4ec1b 100644 --- a/include/bootdev.h +++ b/include/bootdev.h @@ -109,11 +109,9 @@ struct bootdev_hunter { * This is attached to each device in the bootdev uclass and accessible via * dev_get_uclass_plat(dev) * - * @bootflows: List of available bootflows for this bootdev * @piro: Priority of this bootdev */ struct bootdev_uc_plat { - struct list_head bootflow_head; enum bootdev_prio_t prio; }; @@ -186,31 +184,6 @@ int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk, void bootdev_list(bool probe); /** - * bootdev_clear_bootflows() - Clear bootflows from a bootdev - * - * Each bootdev maintains a list of discovered bootflows. This provides a - * way to clear it. These bootflows are removed from the global list too. - * - * @dev: bootdev device to update - */ -void bootdev_clear_bootflows(struct udevice *dev); - -/** - * bootdev_add_bootflow() - Add a bootflow to the bootdev's list - * - * All fields in @bflow must be set up. Note that @bflow->dev is used to add the - * bootflow to that device. - * - * @dev: Bootdev device to add to - * @bflow: Bootflow to add. Note that fields within bflow must be allocated - * since this function takes over ownership of these. This functions makes - * a copy of @bflow itself (without allocating its fields again), so the - * caller must dispose of the memory used by the @bflow pointer itself - * Return: 0 if OK, -ENOMEM if out of memory - */ -int bootdev_add_bootflow(struct bootflow *bflow); - -/** * bootdev_first_bootflow() - Get the first bootflow from a bootdev * * Returns the first bootflow attached to a bootdev @@ -429,6 +402,15 @@ static int bootdev_setup_for_sibling_blk(struct udevice *blk, int bootdev_get_sibling_blk(struct udevice *dev, struct udevice **blkp); /** + * bootdev_get_from_blk() - Get the bootdev given a block device + * + * @blk: Block device to check + * @bootdebp: Returns the bootdev found, if any + * Return 0 if OK, -ve on error + */ +int bootdev_get_from_blk(struct udevice *blk, struct udevice **bootdevp); + +/** * bootdev_unbind_dev() - Unbind a bootdev device * * Remove and unbind a bootdev device which is a child of @parent. This should diff --git a/include/bootflow.h b/include/bootflow.h index 4d2fc7b69b5..480cf8a5af1 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -7,7 +7,9 @@ #ifndef __bootflow_h #define __bootflow_h +#include <alist.h> #include <bootdev.h> +#include <image.h> #include <dm/ofnode_decl.h> #include <linux/list.h> @@ -56,13 +58,8 @@ enum bootflow_flags_t { /** * struct bootflow - information about a bootflow * - * This is connected into two separate linked lists: + * All bootflows are listed in bootstd's bootflow alist in struct bootstd_priv * - * bm_sibling - links all bootflows in the same bootdev - * glob_sibling - links all bootflows in all bootdevs - * - * @bm_node: Points to siblings in the same bootdev - * @glob_node: Points to siblings in the global list (all bootdev) * @dev: Bootdev device which produced this bootflow, NULL for flows created by * BOOTMETHF_GLOBAL bootmeths * @blk: Block device which contains this bootflow, NULL if this is a network @@ -90,10 +87,9 @@ enum bootflow_flags_t { * @cmdline: OS command line, or NULL if not known (allocated) * @x86_setup: Pointer to x86 setup block inside @buf, NULL if not present * @bootmeth_priv: Private data for the bootmeth + * @images: List of loaded images (struct bootstd_img) */ struct bootflow { - struct list_head bm_node; - struct list_head glob_node; struct udevice *dev; struct udevice *blk; int part; @@ -116,6 +112,44 @@ struct bootflow { char *cmdline; void *x86_setup; void *bootmeth_priv; + struct alist images; +}; + +/** + * bootflow_img_t: Supported image types + * + * This uses image_type_t for most types, but extends it + * + * @BFI_EXTLINUX_CFG: extlinux configuration-file + * @BFI_LOGO: logo image + * @BFI_EFI: EFI PE image + * @BFI_CMDLINE: OS command-line string + */ +enum bootflow_img_t { + BFI_FIRST = IH_TYPE_COUNT, + BFI_EXTLINUX_CFG = BFI_FIRST, + BFI_LOGO, + BFI_EFI, + BFI_CMDLINE, + + BFI_COUNT, +}; + +/** + * struct bootflow_img - Information about an image which has been loaded + * + * This keeps track of a single, loaded image. + * + * @fname: Filename used to load the image (allocated) + * @type: Image type (IH_TYPE_...) + * @addr: Address to which the image was loaded, 0 if not yet loaded + * @size: Size of the image + */ +struct bootflow_img { + char *fname; + enum bootflow_img_t type; + ulong addr; + ulong size; }; /** @@ -393,7 +427,10 @@ const char *bootflow_state_get_name(enum bootflow_state_t state); /** * bootflow_remove() - Remove a bootflow and free its memory * - * This updates the linked lists containing the bootflow then frees it. + * This updates the 'global' linked list containing the bootflow, then frees it. + * It does not remove it from bootflows alist in struct bootstd_priv + * + * This does not free bflow itself, since this is assumed to be in an alist * * @bflow: Bootflow to remove */ @@ -569,4 +606,34 @@ int bootflow_cmdline_get_arg(struct bootflow *bflow, const char *arg, */ int bootflow_cmdline_auto(struct bootflow *bflow, const char *arg); +/** + * bootflow_img_type_name() - Get the name for an image type + * + * @type: Type to check (either enum bootflow_img_t or enum image_type_t + * Return: Image name, or "unknown" if not known + */ +const char *bootflow_img_type_name(enum bootflow_img_t type); + +/** + * bootflow_img_add() - Add a new image to a bootflow + * + * @bflow: Bootflow to add to + * @fname: Image filename (will be allocated) + * @type: Image type + * @addr: Address the image was loaded to, or 0 if not loaded + * @size: Image size + * Return: pointer to the added image, or NULL if out of memory + */ +struct bootflow_img *bootflow_img_add(struct bootflow *bflow, const char *fname, + enum bootflow_img_t type, ulong addr, + ulong size); +/** + * bootflow_get_seq() - Get the sequence number of a bootflow + * + * Bootflows are numbered by their position in the bootstd list. + * + * Return: Sequence number of bootflow (0 = first) + */ +int bootflow_get_seq(const struct bootflow *bflow); + #endif diff --git a/include/bootmeth.h b/include/bootmeth.h index a08ebf005ad..26de593a9a4 100644 --- a/include/bootmeth.h +++ b/include/bootmeth.h @@ -7,11 +7,10 @@ #ifndef __bootmeth_h #define __bootmeth_h +#include <bootflow.h> #include <linux/bitops.h> struct blk_desc; -struct bootflow; -struct bootflow_iter; struct udevice; /** @@ -117,13 +116,15 @@ struct bootmeth_ops { * @bflow: Bootflow providing info on where to read from * @file_path: Path to file (may be absolute or relative) * @addr: Address to load file + * @type: File type (IH_TYPE_...) * @sizep: On entry provides the maximum permitted size; on exit * returns the size of the file * Return: 0 if OK, -ENOSPC if the file is too large for @sizep, other * -ve value if something else goes wrong */ int (*read_file)(struct udevice *dev, struct bootflow *bflow, - const char *file_path, ulong addr, ulong *sizep); + const char *file_path, ulong addr, + enum bootflow_img_t type, ulong *sizep); #if CONFIG_IS_ENABLED(BOOTSTD_FULL) /** * readall() - read all files for a bootflow @@ -245,13 +246,15 @@ int bootmeth_set_bootflow(struct udevice *dev, struct bootflow *bflow, * @bflow: Bootflow providing info on where to read from * @file_path: Path to file (may be absolute or relative) * @addr: Address to load file + * @type: File type (IH_TYPE_...) * @sizep: On entry provides the maximum permitted size; on exit * returns the size of the file * Return: 0 if OK, -ENOSPC if the file is too large for @sizep, other * -ve value if something else goes wrong */ int bootmeth_read_file(struct udevice *dev, struct bootflow *bflow, - const char *file_path, ulong addr, ulong *sizep); + const char *file_path, ulong addr, + enum bootflow_img_t type, ulong *sizep); /** * bootmeth_read_all() - read all bootflow files @@ -365,10 +368,12 @@ int bootmeth_try_file(struct bootflow *bflow, struct blk_desc *desc, * @bflow: Information about file to read * @size_limit: Maximum file size to permit * @align: Allocation alignment (1 for unaligned) + * @type: File type (IH_TYPE_...) * Return: 0 if OK, -E2BIG if file is too large, -ENOMEM if out of memory, * other -ve on other error */ -int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align); +int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align, + enum bootflow_img_t type); /** * bootmeth_alloc_other() - Allocate and read a file for a bootflow @@ -379,12 +384,13 @@ int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align); * * @bflow: Information about file to read * @fname: Filename to read from (within bootflow->subdir) + * @type: File type (IH_TYPE_...) * @bufp: Returns a pointer to the allocated buffer * @sizep: Returns the size of the buffer * Return: 0 if OK, -ENOMEM if out of memory, other -ve on other error */ int bootmeth_alloc_other(struct bootflow *bflow, const char *fname, - void **bufp, uint *sizep); + enum bootflow_img_t type, void **bufp, uint *sizep); /** * bootmeth_common_read_file() - Common handler for reading a file @@ -395,11 +401,13 @@ int bootmeth_alloc_other(struct bootflow *bflow, const char *fname, * @bflow: Bootflow information * @file_path: Path to file * @addr: Address to load file to + * @type: File type (IH_TYPE_...) * @sizep: On entry, the maximum file size to accept, on exit the actual file * size read */ int bootmeth_common_read_file(struct udevice *dev, struct bootflow *bflow, - const char *file_path, ulong addr, ulong *sizep); + const char *file_path, ulong addr, + enum bootflow_img_t type, ulong *sizep); /** * bootmeth_get_bootflow() - Get a bootflow from a global bootmeth diff --git a/include/bootstd.h b/include/bootstd.h index ac756e98d84..3398e48e88b 100644 --- a/include/bootstd.h +++ b/include/bootstd.h @@ -9,6 +9,7 @@ #ifndef __bootstd_h #define __bootstd_h +#include <alist.h> #include <dm/ofnode_decl.h> #include <linux/list.h> #include <linux/types.h> @@ -30,7 +31,8 @@ struct udevice; * terminated) * @cur_bootdev: Currently selected bootdev (for commands) * @cur_bootflow: Currently selected bootflow (for commands) - * @glob_head: Head for the global list of all bootflows across all bootdevs + * @bootflows: (struct bootflow) Global list of all bootflows across all + * bootdevs * @bootmeth_count: Number of bootmeth devices in @bootmeth_order * @bootmeth_order: List of bootmeth devices to use, in order, NULL-terminated * @vbe_bootmeth: Currently selected VBE bootmeth, NULL if none @@ -44,7 +46,7 @@ struct bootstd_priv { const char **env_order; struct udevice *cur_bootdev; struct bootflow *cur_bootflow; - struct list_head glob_head; + struct alist bootflows; int bootmeth_count; struct udevice **bootmeth_order; struct udevice *vbe_bootmeth; @@ -90,6 +92,23 @@ const char *const *const bootstd_get_prefixes(struct udevice *dev); int bootstd_get_priv(struct bootstd_priv **stdp); /** + * bootstd_try_priv() - Try to get the (single) state for the bootstd system + * + * The state holds a global list of all bootflows that have been found. This + * function returns the state if available, but takes care not to create the + * device (or uclass) if it doesn't exist. + * + * This function is safe to use in the 'unbind' path. It will always return NULL + * unless the bootstd device is probed and ready, e.g. bootstd_get_priv() has + * previously been called. + * + * TODO([email protected]): Consider adding a bootstd pointer to global_data + * + * Return: pointer if the device exists, else NULL + */ +struct bootstd_priv *bootstd_try_priv(void); + +/** * bootstd_clear_glob() - Clear the global list of bootflows * * This removes all bootflows globally and across all bootdevs. @@ -105,4 +124,31 @@ void bootstd_clear_glob(void); */ int bootstd_prog_boot(void); +/** + * bootstd_add_bootflow() - Add a bootflow to the global list + * + * All fields in @bflow must be set up. Note that @bflow->dev is used to add the + * bootflow to that device. + * + * The bootflow is also added to the global list of all bootflows + * + * @dev: Bootdev device to add to + * @bflow: Bootflow to add. Note that fields within bflow must be allocated + * since this function takes over ownership of these. This functions makes + * a copy of @bflow itself (without allocating its fields again), so the + * caller must dispose of the memory used by the @bflow pointer itself + * Return: element number in the list, if OK, -ENOMEM if out of memory + */ +int bootstd_add_bootflow(struct bootflow *bflow); + +/** + * bootstd_clear_bootflows_for_bootdev() - Clear bootflows from a bootdev + * + * Each bootdev maintains a list of discovered bootflows. This provides a + * way to clear it. These bootflows are removed from the global list too. + * + * @dev: bootdev device to update + */ +int bootstd_clear_bootflows_for_bootdev(struct udevice *dev); + #endif diff --git a/include/pxe_utils.h b/include/pxe_utils.h index 68ac40b64ad..0378f2889f7 100644 --- a/include/pxe_utils.h +++ b/include/pxe_utils.h @@ -3,6 +3,7 @@ #ifndef __PXE_UTILS_H #define __PXE_UTILS_H +#include <bootflow.h> #include <linux/list.h> /* @@ -82,8 +83,19 @@ struct pxe_menu { }; struct pxe_context; + +/** + * Read a file + * + * @ctx: PXE context + * @file_path: Full path to filename to read + * @file_addr: String containing the to which to read the file + * @type: File type + * @fileszeip: Returns file size + */ typedef int (*pxe_getfile_func)(struct pxe_context *ctx, const char *file_path, - char *file_addr, ulong *filesizep); + char *file_addr, enum bootflow_img_t type, + ulong *filesizep); /** * struct pxe_context - context information for PXE parsing |
