summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/bootdev.h36
-rw-r--r--include/bootflow.h85
-rw-r--r--include/bootmeth.h22
-rw-r--r--include/bootstd.h50
-rw-r--r--include/pxe_utils.h14
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