summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/bios_emul.h6
-rw-r--r--include/bootflow.h20
-rw-r--r--include/bootmeth.h65
-rw-r--r--include/bootstd.h2
-rw-r--r--include/dm/of_access.h22
-rw-r--r--include/dm/ofnode.h122
-rw-r--r--include/dm/ofnode_decl.h85
-rw-r--r--include/event.h21
-rw-r--r--include/of_live.h16
-rw-r--r--include/test/test.h2
-rw-r--r--include/vbe.h147
-rw-r--r--include/vesa.h116
12 files changed, 442 insertions, 182 deletions
diff --git a/include/bios_emul.h b/include/bios_emul.h
index 72410dc7948..a7e6d73972c 100644
--- a/include/bios_emul.h
+++ b/include/bios_emul.h
@@ -36,14 +36,14 @@ typedef struct {
u8 LowMem[1536];
} BE_VGAInfo;
-struct vbe_mode_info;
+struct vesa_state;
int BootVideoCardBIOS(struct udevice *pcidev, BE_VGAInfo **pVGAInfo,
int clean_up);
/* Run a BIOS ROM natively (only supported on x86 machines) */
void bios_run_on_x86(struct udevice *dev, unsigned long addr, int vesa_mode,
- struct vbe_mode_info *mode_info);
+ struct vesa_state *mode_info);
/**
* bios_set_interrupt_handler() - Install an interrupt handler for the BIOS
@@ -61,6 +61,6 @@ int biosemu_setup(struct udevice *pcidev, BE_VGAInfo **pVGAInfo);
int biosemu_run(struct udevice *dev, uchar *bios_rom, int bios_len,
BE_VGAInfo *vga_info, int clean_up, int vesa_mode,
- struct vbe_mode_info *mode_info);
+ struct vesa_state *mode_info);
#endif
diff --git a/include/bootflow.h b/include/bootflow.h
index c30ba042a48..6aa3d1fff8d 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -77,12 +77,14 @@ struct bootflow {
* @BOOTFLOWF_SHOW: Show each bootdev before scanning it
* @BOOTFLOWF_ALL: Return bootflows with errors as well
* @BOOTFLOWF_SINGLE_DEV: Just scan one bootmeth
+ * @BOOTFLOWF_SKIP_GLOBAL: Don't scan global bootmeths
*/
enum bootflow_flags_t {
BOOTFLOWF_FIXED = 1 << 0,
BOOTFLOWF_SHOW = 1 << 1,
BOOTFLOWF_ALL = 1 << 2,
BOOTFLOWF_SINGLE_DEV = 1 << 3,
+ BOOTFLOWF_SKIP_GLOBAL = 1 << 4,
};
/**
@@ -102,8 +104,10 @@ enum bootflow_flags_t {
* updated to a larger value, no less than the number of available partitions.
* This ensures that iteration works through all partitions on the bootdev.
*
- * @flags: Flags to use (see enum bootflow_flags_t)
- * @dev: Current bootdev
+ * @flags: Flags to use (see enum bootflow_flags_t). If BOOTFLOWF_GLOBAL_FIRST is
+ * enabled then the global bootmeths are being scanned, otherwise we have
+ * moved onto the bootdevs
+ * @dev: Current bootdev, NULL if none
* @part: Current partition number (0 for whole device)
* @method: Current bootmeth
* @max_part: Maximum hardware partition number in @dev, 0 if there is no
@@ -117,7 +121,11 @@ enum bootflow_flags_t {
* with the first one on the list
* @num_methods: Number of bootmeth devices in @method_order
* @cur_method: Current method number, an index into @method_order
- * @method_order: List of bootmeth devices to use, in order
+ * @first_glob_method: First global method, if any, else -1
+ * @method_order: List of bootmeth devices to use, in order. The normal methods
+ * appear first, then the global ones, if any
+ * @doing_global: true if we are iterating through the global bootmeths (which
+ * happens before the normal ones)
*/
struct bootflow_iter {
int flags;
@@ -131,7 +139,9 @@ struct bootflow_iter {
struct udevice **dev_order;
int num_methods;
int cur_method;
+ int first_glob_method;
struct udevice **method_order;
+ bool doing_global;
};
/**
@@ -169,9 +179,9 @@ int bootflow_iter_drop_bootmeth(struct bootflow_iter *iter,
* If @flags includes BOOTFLOWF_ALL then bootflows with errors are returned too
*
* @dev: Boot device to scan, NULL to work through all of them until it
- * finds one that * can supply a bootflow
+ * finds one that can supply a bootflow
* @iter: Place to store private info (inited by this call)
- * @flags: Flags for bootdev (enum bootflow_flags_t)
+ * @flags: Flags for iterator (enum bootflow_flags_t)
* @bflow: Place to put the bootflow if found
* Return: 0 if found, -ENODEV if no device, other -ve on other error
* (iteration can continue)
diff --git a/include/bootmeth.h b/include/bootmeth.h
index 484e503e338..50ded055f3f 100644
--- a/include/bootmeth.h
+++ b/include/bootmeth.h
@@ -13,18 +13,47 @@ struct bootflow_iter;
struct udevice;
/**
+ * enum bootmeth_flags - Flags for bootmeths
+ *
+ * @BOOTMETHF_GLOBAL: bootmeth handles bootdev selection automatically
+ */
+enum bootmeth_flags {
+ BOOTMETHF_GLOBAL = BIT(0),
+};
+
+/**
* struct bootmeth_uc_plat - information the uclass keeps about each bootmeth
*
* @desc: A long description of the bootmeth
+ * @flags: Flags for this bootmeth (enum bootmeth_flags)
*/
struct bootmeth_uc_plat {
const char *desc;
+ int flags;
};
/** struct bootmeth_ops - Operations for boot methods */
struct bootmeth_ops {
/**
- * check_supported() - check if a bootmeth supports this bootflow
+ * get_state_desc() - get detailed state information
+ *
+ * Prodecues a textual description of the state of the bootmeth. This
+ * can include newline characters if it extends to multiple lines. It
+ * must be a nul-terminated string.
+ *
+ * This may involve reading state from the system, e.g. some data in
+ * the firmware area.
+ *
+ * @dev: Bootmethod device to check
+ * @buf: Buffer to place the info in (terminator must fit)
+ * @maxsize: Size of buffer
+ * Returns: 0 if OK, -ENOSPC is buffer is too small, other -ve error if
+ * something else went wrong
+ */
+ int (*get_state_desc)(struct udevice *dev, char *buf, int maxsize);
+
+ /**
+ * check_supported() - check if a bootmeth supports this bootdev
*
* This is optional. If not provided, the bootdev is assumed to be
* supported
@@ -92,6 +121,24 @@ struct bootmeth_ops {
#define bootmeth_get_ops(dev) ((struct bootmeth_ops *)(dev)->driver->ops)
/**
+ * bootmeth_get_state_desc() - get detailed state information
+ *
+ * Prodecues a textual description of the state of the bootmeth. This
+ * can include newline characters if it extends to multiple lines. It
+ * must be a nul-terminated string.
+ *
+ * This may involve reading state from the system, e.g. some data in
+ * the firmware area.
+ *
+ * @dev: Bootmethod device to check
+ * @buf: Buffer to place the info in (terminator must fit)
+ * @maxsize: Size of buffer
+ * Returns: 0 if OK, -ENOSPC is buffer is too small, other -ve error if
+ * something else went wrong
+ */
+int bootmeth_get_state_desc(struct udevice *dev, char *buf, int maxsize);
+
+/**
* bootmeth_check() - check if a bootmeth supports this bootflow
*
* This is optional. If not provided, the bootdev is assumed to be
@@ -162,10 +209,12 @@ int bootmeth_boot(struct udevice *dev, struct bootflow *bflow);
* ordering there, then all bootmethods are added
*
* @iter: Iterator to update with the order
+ * @include_global: true to add the global bootmeths, in which case they appear
+ * first
* Return: 0 if OK, -ENOENT if no bootdevs, -ENOMEM if out of memory, other -ve
* on other error
*/
-int bootmeth_setup_iter_order(struct bootflow_iter *iter);
+int bootmeth_setup_iter_order(struct bootflow_iter *iter, bool include_global);
/**
* bootmeth_set_order() - Set the bootmeth order
@@ -231,4 +280,16 @@ int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align);
int bootmeth_common_read_file(struct udevice *dev, struct bootflow *bflow,
const char *file_path, ulong addr, ulong *sizep);
+/**
+ * bootmeth_get_bootflow() - Get a bootflow from a global bootmeth
+ *
+ * Check the bootmeth for a bootflow which can be used. In this case the
+ * bootmeth handles all bootdev selection, etc.
+ *
+ * @dev: bootmeth device to read from
+ * @bflow: Bootflow information
+ * @return 0 on success, -ve if a bootflow could not be found or had an error
+ */
+int bootmeth_get_bootflow(struct udevice *dev, struct bootflow *bflow);
+
#endif
diff --git a/include/bootstd.h b/include/bootstd.h
index b002365f4f0..01be249d16e 100644
--- a/include/bootstd.h
+++ b/include/bootstd.h
@@ -26,6 +26,7 @@ struct udevice;
* @glob_head: Head for the 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
*/
struct bootstd_priv {
const char **prefixes;
@@ -35,6 +36,7 @@ struct bootstd_priv {
struct list_head glob_head;
int bootmeth_count;
struct udevice **bootmeth_order;
+ struct udevice *vbe_bootmeth;
};
/**
diff --git a/include/dm/of_access.h b/include/dm/of_access.h
index ec6e6e2c7c0..5b7821d0a1b 100644
--- a/include/dm/of_access.h
+++ b/include/dm/of_access.h
@@ -197,6 +197,11 @@ struct device_node *of_get_parent(const struct device_node *np);
/**
* of_find_node_opts_by_path() - Find a node matching a full OF path
*
+ * Note that alias processing is only available on the control FDT (gd->of_root).
+ * For other trees it is skipped, so any attempt to obtain an alias will result
+ * in returning NULL.
+ *
+ * @root: Root node of the tree to use. If this is NULL, then gd->of_root is used
* @path: Either the full path to match, or if the path does not start with
* '/', the name of a property of the /aliases node (an alias). In the
* case of an alias, the node matching the alias' value will be returned.
@@ -210,12 +215,13 @@ struct device_node *of_get_parent(const struct device_node *np);
*
* Return: a node pointer or NULL if not found
*/
-struct device_node *of_find_node_opts_by_path(const char *path,
+struct device_node *of_find_node_opts_by_path(struct device_node *root,
+ const char *path,
const char **opts);
static inline struct device_node *of_find_node_by_path(const char *path)
{
- return of_find_node_opts_by_path(path, NULL);
+ return of_find_node_opts_by_path(NULL, path, NULL);
}
/**
@@ -513,4 +519,16 @@ int of_alias_get_highest_id(const char *stem);
*/
struct device_node *of_get_stdout(void);
+/**
+ * of_write_prop() - Write a property to the device tree
+ *
+ * @np: device node to which the property value is to be written
+ * @propname: name of the property to write
+ * @value: value of the property
+ * @len: length of the property in bytes
+ * Returns: 0 if OK, -ve on error
+ */
+int of_write_prop(struct device_node *np, const char *propname, int len,
+ const void *value);
+
#endif
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index bb60433124b..7ce1e4c6d91 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -19,41 +19,7 @@
struct resource;
-/**
- * typedef union ofnode_union ofnode - reference to a device tree node
- *
- * This union can hold either a straightforward pointer to a struct device_node
- * in the live device tree, or an offset within the flat device tree. In the
- * latter case, the pointer value is just the integer offset within the flat DT.
- *
- * Thus we can reference nodes in both the live tree (once available) and the
- * flat tree (until then). Functions are available to translate between an
- * ofnode and either an offset or a `struct device_node *`.
- *
- * The reference can also hold a null offset, in which case the pointer value
- * here is NULL. This corresponds to a struct device_node * value of
- * NULL, or an offset of -1.
- *
- * There is no ambiguity as to whether ofnode holds an offset or a node
- * pointer: when the live tree is active it holds a node pointer, otherwise it
- * holds an offset. The value itself does not need to be unique and in theory
- * the same value could point to a valid device node or a valid offset. We
- * could arrange for a unique value to be used (e.g. by making the pointer
- * point to an offset within the flat device tree in the case of an offset) but
- * this increases code size slightly due to the subtraction. Since it offers no
- * real benefit, the approach described here seems best.
- *
- * For now these points use constant types, since we don't allow writing
- * the DT.
- *
- * @np: Pointer to device node, used for live tree
- * @of_offset: Pointer into flat device tree, used for flat tree. Note that this
- * is not a really a pointer to a node: it is an offset value. See above.
- */
-typedef union ofnode_union {
- const struct device_node *np;
- long of_offset;
-} ofnode;
+#include <dm/ofnode_decl.h>
struct ofnode_phandle_args {
ofnode node;
@@ -62,45 +28,38 @@ struct ofnode_phandle_args {
};
/**
- * struct ofprop - reference to a property of a device tree node
- *
- * This struct hold the reference on one property of one node,
- * using struct ofnode and an offset within the flat device tree or either
- * a pointer to a struct property in the live device tree.
- *
- * Thus we can reference arguments in both the live tree and the flat tree.
+ * ofnode_to_np() - convert an ofnode to a live DT node pointer
*
- * The property reference can also hold a null reference. This corresponds to
- * a struct property NULL pointer or an offset of -1.
+ * This cannot be called if the reference contains an offset.
*
- * @node: Pointer to device node
- * @offset: Pointer into flat device tree, used for flat tree.
- * @prop: Pointer to property, used for live treee.
+ * @node: Reference containing struct device_node * (possibly invalid)
+ * Return: pointer to device node (can be NULL)
*/
-
-struct ofprop {
- ofnode node;
- union {
- int offset;
- const struct property *prop;
- };
-};
+static inline const struct device_node *ofnode_to_np(ofnode node)
+{
+#ifdef OF_CHECKS
+ if (!of_live_active())
+ return NULL;
+#endif
+ return node.np;
+}
/**
- * ofnode_to_np() - convert an ofnode to a live DT node pointer
+ * ofnode_to_npw() - convert an ofnode to a writeable live DT node pointer
*
* This cannot be called if the reference contains an offset.
*
* @node: Reference containing struct device_node * (possibly invalid)
* Return: pointer to device node (can be NULL)
*/
-static inline const struct device_node *ofnode_to_np(ofnode node)
+static inline struct device_node *ofnode_to_npw(ofnode node)
{
#ifdef OF_CHECKS
if (!of_live_active())
return NULL;
#endif
- return node.np;
+ /* Drop constant */
+ return (struct device_node *)node.np;
}
/**
@@ -236,6 +195,23 @@ static inline ofnode ofnode_root(void)
}
/**
+ * oftree_default() - Returns the default device tree (U-Boot's control FDT)
+ *
+ * Returns: reference to the control FDT
+ */
+static inline oftree oftree_default(void)
+{
+ oftree tree;
+
+ if (of_live_active())
+ tree.np = gd_of_root();
+ else
+ tree.fdt = (void *)gd->fdt_blob;
+
+ return tree;
+}
+
+/**
* ofnode_name_eq() - Check if the node name is equivalent to a given name
* ignoring the unit address
*
@@ -699,12 +675,23 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
/**
* ofnode_path() - find a node by full path
*
+ * This uses the control FDT.
+ *
* @path: Full path to node, e.g. "/bus/spi@1"
* Return: reference to the node found. Use ofnode_valid() to check if it exists
*/
ofnode ofnode_path(const char *path);
/**
+ * ofnode_path_root() - find a node by full path from a root node
+ *
+ * @tree: Device tree to use
+ * @path: Full path to node, e.g. "/bus/spi@1"
+ * Return: reference to the node found. Use ofnode_valid() to check if it exists
+ */
+ofnode ofnode_path_root(oftree tree, const char *path);
+
+/**
* ofnode_read_chosen_prop() - get the value of a chosen property
*
* This looks for a property within the /chosen node and returns its value
@@ -1140,17 +1127,18 @@ int ofnode_device_is_compatible(ofnode node, const char *compat);
* ofnode_write_prop() - Set a property of a ofnode
*
* Note that the value passed to the function is *not* allocated by the
- * function itself, but must be allocated by the caller if necessary.
+ * function itself, but must be allocated by the caller if necessary. However
+ * it does allocate memory for the property struct and name.
*
* @node: The node for whose property should be set
* @propname: The name of the property to set
- * @len: The length of the new value of the property
* @value: The new value of the property (must be valid prior to calling
* the function)
+ * @len: The length of the new value of the property
* Return: 0 if successful, -ve on error
*/
-int ofnode_write_prop(ofnode node, const char *propname, int len,
- const void *value);
+int ofnode_write_prop(ofnode node, const char *propname, const void *value,
+ int len);
/**
* ofnode_write_string() - Set a string property of a ofnode
@@ -1167,6 +1155,16 @@ int ofnode_write_prop(ofnode node, const char *propname, int len,
int ofnode_write_string(ofnode node, const char *propname, const char *value);
/**
+ * ofnode_write_u32() - Set an integer property of an ofnode
+ *
+ * @node: The node for whose string property should be set
+ * @propname: The name of the string property to set
+ * @value: The new value of the 32-bit integer property
+ * Return: 0 if successful, -ve on error
+ */
+int ofnode_write_u32(ofnode node, const char *propname, u32 value);
+
+/**
* ofnode_set_enabled() - Enable or disable a device tree node given by its
* ofnode
*
diff --git a/include/dm/ofnode_decl.h b/include/dm/ofnode_decl.h
new file mode 100644
index 00000000000..266253d5e33
--- /dev/null
+++ b/include/dm/ofnode_decl.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <[email protected]>
+ */
+
+#ifndef _DM_OFNODE_DECL_H
+#define _DM_OFNODE_DECL_H
+
+/**
+ * typedef union ofnode_union ofnode - reference to a device tree node
+ *
+ * This union can hold either a straightforward pointer to a struct device_node
+ * in the live device tree, or an offset within the flat device tree. In the
+ * latter case, the pointer value is just the integer offset within the flat DT.
+ *
+ * Thus we can reference nodes in both the live tree (once available) and the
+ * flat tree (until then). Functions are available to translate between an
+ * ofnode and either an offset or a `struct device_node *`.
+ *
+ * The reference can also hold a null offset, in which case the pointer value
+ * here is NULL. This corresponds to a struct device_node * value of
+ * NULL, or an offset of -1.
+ *
+ * There is no ambiguity as to whether ofnode holds an offset or a node
+ * pointer: when the live tree is active it holds a node pointer, otherwise it
+ * holds an offset. The value itself does not need to be unique and in theory
+ * the same value could point to a valid device node or a valid offset. We
+ * could arrange for a unique value to be used (e.g. by making the pointer
+ * point to an offset within the flat device tree in the case of an offset) but
+ * this increases code size slightly due to the subtraction. Since it offers no
+ * real benefit, the approach described here seems best.
+ *
+ * For now these points use constant types, since we don't allow writing
+ * the DT.
+ *
+ * @np: Pointer to device node, used for live tree
+ * @of_offset: Pointer into flat device tree, used for flat tree. Note that this
+ * is not a really a pointer to a node: it is an offset value. See above.
+ */
+typedef union ofnode_union {
+ const struct device_node *np;
+ long of_offset;
+} ofnode;
+
+/**
+ * struct ofprop - reference to a property of a device tree node
+ *
+ * This struct hold the reference on one property of one node,
+ * using struct ofnode and an offset within the flat device tree or either
+ * a pointer to a struct property in the live device tree.
+ *
+ * Thus we can reference arguments in both the live tree and the flat tree.
+ *
+ * The property reference can also hold a null reference. This corresponds to
+ * a struct property NULL pointer or an offset of -1.
+ *
+ * @node: Pointer to device node
+ * @offset: Pointer into flat device tree, used for flat tree.
+ * @prop: Pointer to property, used for live treee.
+ */
+
+struct ofprop {
+ ofnode node;
+ union {
+ int offset;
+ const struct property *prop;
+ };
+};
+
+/**
+ * union oftree_union - reference to a tree of device tree nodes
+ *
+ * One or other of the members is used, depending on of_live_active()
+ *
+ * @np: Pointer to roott device node, used for live tree
+ * @fdt: Pointer to the flat device tree, used for flat tree
+ */
+typedef union oftree_union {
+ struct device_node *np;
+ void *fdt;
+} oftree;
+
+#endif
+
diff --git a/include/event.h b/include/event.h
index c00c4fb68dc..e8f2f55c63d 100644
--- a/include/event.h
+++ b/include/event.h
@@ -10,6 +10,8 @@
#ifndef __event_h
#define __event_h
+#include <dm/ofnode_decl.h>
+
/**
* enum event_t - Types of events supported by U-Boot
*
@@ -29,6 +31,9 @@ enum event_t {
/* Init hooks */
EVT_MISC_INIT_F,
+ /* Device tree fixups before booting */
+ EVT_FT_FIXUP,
+
EVT_COUNT
};
@@ -50,6 +55,15 @@ union event_data {
struct event_dm {
struct udevice *dev;
} dm;
+
+ /**
+ * struct event_ft_fixup - FDT fixup before booting
+ *
+ * @tree: tree to update
+ */
+ struct event_ft_fixup {
+ oftree tree;
+ } ft_fixup;
};
/**
@@ -123,10 +137,13 @@ static inline const char *event_spy_id(struct evspy_info *spy)
* The only solution I can think of is to mark linker-list entries as 'used'
* using an attribute. This should be safe, since we don't actually want to drop
* any of these. However this does slightly limit LTO's optimisation choices.
+ *
+ * Another issue has come up, only with clang: using 'static' makes it throw
+ * away the linker-list entry sometimes, e.g. with the EVT_FT_FIXUP entry in
+ * vbe_simple.c - so for now, make it global.
*/
#define EVENT_SPY(_type, _func) \
- static __attribute__((used)) ll_entry_declare(struct evspy_info, \
- _type, evspy_info) = \
+ __used ll_entry_declare(struct evspy_info, _type, evspy_info) = \
_ESPY_REC(_type, _func)
/**
diff --git a/include/of_live.h b/include/of_live.h
index b2b9679ae84..f59d6af3350 100644
--- a/include/of_live.h
+++ b/include/of_live.h
@@ -20,4 +20,20 @@ struct device_node;
*/
int of_live_build(const void *fdt_blob, struct device_node **rootp);
+/**
+ * unflatten_device_tree() - create tree of device_nodes from flat blob
+ *
+ * Note that this allocates a single block of memory, pointed to by *mynodes.
+ * To free the tree, use free(*mynodes)
+ *
+ * unflattens a device-tree, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ * @blob: The blob to expand
+ * @mynodes: The device_node tree created by the call
+ * Return: 0 if OK, -ve on error
+ */
+int unflatten_device_tree(const void *blob, struct device_node **mynodes);
+
#endif
diff --git a/include/test/test.h b/include/test/test.h
index 0104e189f63..c888d68b1ed 100644
--- a/include/test/test.h
+++ b/include/test/test.h
@@ -46,6 +46,8 @@ enum {
UT_TESTF_CONSOLE_REC = BIT(5), /* needs console recording */
/* do extra driver model init and uninit */
UT_TESTF_DM = BIT(6),
+ /* live or flat device tree, but not both in the same executable */
+ UT_TESTF_LIVE_OR_FLAT = BIT(4),
};
/**
diff --git a/include/vbe.h b/include/vbe.h
index 1631260eb73..b83f6f0c519 100644
--- a/include/vbe.h
+++ b/include/vbe.h
@@ -1,113 +1,48 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-/******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation
- * Copyright (c) 2009 Pattrick Hueper <[email protected]>
- * All rights reserved.
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Verified Boot for Embedded (VBE) support
+ * See doc/develop/vbe.rst
*
- * Contributors:
- * IBM Corporation - initial implementation
- *****************************************************************************/
-#ifndef _VBE_H
-#define _VBE_H
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <[email protected]>
+ */
-/* these structs are for input from and output to OF */
-struct __packed vbe_screen_info {
- u8 display_type; /* 0=NONE, 1= analog, 2=digital */
- u16 screen_width;
- u16 screen_height;
- /* bytes per line in framebuffer, may be more than screen_width */
- u16 screen_linebytes;
- u8 color_depth; /* color depth in bits per pixel */
- u32 framebuffer_address;
- u8 edid_block_zero[128];
-};
+#ifndef __VBE_H
+#define __VBE_H
-struct __packed vbe_screen_info_input {
- u8 signature[4];
- u16 size_reserved;
- u8 monitor_number;
- u16 max_screen_width;
- u8 color_depth;
-};
-
-/* these structs only store the required a subset of the VBE-defined fields */
-struct __packed vbe_info {
- char signature[4];
- u16 version;
- u32 oem_string_ptr;
- u32 capabilities;
- u32 modes_ptr;
- u16 total_memory;
- u16 oem_version;
- u32 vendor_name_ptr;
- u32 product_name_ptr;
- u32 product_rev_ptr;
-};
-
-struct __packed vesa_mode_info {
- u16 mode_attributes; /* 00 */
- u8 win_a_attributes; /* 02 */
- u8 win_b_attributes; /* 03 */
- u16 win_granularity; /* 04 */
- u16 win_size; /* 06 */
- u16 win_a_segment; /* 08 */
- u16 win_b_segment; /* 0a */
- u32 win_func_ptr; /* 0c */
- u16 bytes_per_scanline; /* 10 */
- u16 x_resolution; /* 12 */
- u16 y_resolution; /* 14 */
- u8 x_charsize; /* 16 */
- u8 y_charsize; /* 17 */
- u8 number_of_planes; /* 18 */
- u8 bits_per_pixel; /* 19 */
- u8 number_of_banks; /* 20 */
- u8 memory_model; /* 21 */
- u8 bank_size; /* 22 */
- u8 number_of_image_pages; /* 23 */
- u8 reserved_page;
- u8 red_mask_size;
- u8 red_mask_pos;
- u8 green_mask_size;
- u8 green_mask_pos;
- u8 blue_mask_size;
- u8 blue_mask_pos;
- u8 reserved_mask_size;
- u8 reserved_mask_pos;
- u8 direct_color_mode_info;
- u32 phys_base_ptr;
- u32 offscreen_mem_offset;
- u16 offscreen_mem_size;
- u8 reserved[206];
-};
-
-struct vbe_mode_info {
- u16 video_mode;
- bool valid;
- union {
- struct vesa_mode_info vesa;
- u8 mode_info_block[256];
- };
-};
-
-struct vbe_ddc_info {
- u8 port_number; /* i.e. monitor number */
- u8 edid_transfer_time;
- u8 ddc_level;
- u8 edid_block_zero[128];
-};
-
-#define VESA_GET_INFO 0x4f00
-#define VESA_GET_MODE_INFO 0x4f01
-#define VESA_SET_MODE 0x4f02
-#define VESA_GET_CUR_MODE 0x4f03
+/**
+ * vbe_list() - List the VBE bootmeths
+ *
+ * This shows a list of the VBE bootmeth devices
+ *
+ * @return 0 (always)
+ */
+int vbe_list(void);
-extern struct vbe_mode_info mode_info;
+/**
+ * vbe_find_by_any() - Find a VBE bootmeth by name or sequence
+ *
+ * @name: name (e.g. "vbe-simple"), or sequence ("2") to find
+ * @devp: returns the device found, on success
+ * Return: 0 if OK, -ve on error
+ */
+int vbe_find_by_any(const char *name, struct udevice **devp);
+
+/**
+ * vbe_find_first_device() - Find the first VBE bootmeth
+ *
+ * @devp: Returns first available VBE bootmeth, or NULL if none
+ * Returns: 0 (always)
+ */
+int vbe_find_first_device(struct udevice **devp);
-struct video_priv;
-struct video_uc_plat;
-int vbe_setup_video_priv(struct vesa_mode_info *vesa,
- struct video_priv *uc_priv,
- struct video_uc_plat *plat);
-int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void));
+/**
+ * vbe_find_next_device() - Find the next available VBE bootmeth
+ *
+ * @devp: Previous device to start from. Returns next available VBE bootmeth,
+ * or NULL if none
+ * Returns: 0 (always)
+ */
+int vbe_find_next_device(struct udevice **devp);
#endif
diff --git a/include/vesa.h b/include/vesa.h
new file mode 100644
index 00000000000..a42c1796863
--- /dev/null
+++ b/include/vesa.h
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * Copyright (c) 2009 Pattrick Hueper <[email protected]>
+ * All rights reserved.
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+#ifndef _VESA_H
+#define _VESA_H
+
+/* these structs are for input from and output to OF */
+struct __packed vesa_screen_info {
+ u8 display_type; /* 0=NONE, 1= analog, 2=digital */
+ u16 screen_width;
+ u16 screen_height;
+ /* bytes per line in framebuffer, may be more than screen_width */
+ u16 screen_linebytes;
+ u8 color_depth; /* color depth in bits per pixel */
+ u32 framebuffer_address;
+ u8 edid_block_zero[128];
+};
+
+struct __packed vesa_screen_info_input {
+ u8 signature[4];
+ u16 size_reserved;
+ u8 monitor_number;
+ u16 max_screen_width;
+ u8 color_depth;
+};
+
+/*
+ * These structs only store the required subset of fields in Vesa BIOS
+ * Extensions
+ */
+struct __packed vesa_bios_ext_info {
+ char signature[4];
+ u16 version;
+ u32 oem_string_ptr;
+ u32 capabilities;
+ u32 modes_ptr;
+ u16 total_memory;
+ u16 oem_version;
+ u32 vendor_name_ptr;
+ u32 product_name_ptr;
+ u32 product_rev_ptr;
+};
+
+struct __packed vesa_mode_info {
+ u16 mode_attributes; /* 00 */
+ u8 win_a_attributes; /* 02 */
+ u8 win_b_attributes; /* 03 */
+ u16 win_granularity; /* 04 */
+ u16 win_size; /* 06 */
+ u16 win_a_segment; /* 08 */
+ u16 win_b_segment; /* 0a */
+ u32 win_func_ptr; /* 0c */
+ u16 bytes_per_scanline; /* 10 */
+ u16 x_resolution; /* 12 */
+ u16 y_resolution; /* 14 */
+ u8 x_charsize; /* 16 */
+ u8 y_charsize; /* 17 */
+ u8 number_of_planes; /* 18 */
+ u8 bits_per_pixel; /* 19 */
+ u8 number_of_banks; /* 20 */
+ u8 memory_model; /* 21 */
+ u8 bank_size; /* 22 */
+ u8 number_of_image_pages; /* 23 */
+ u8 reserved_page;
+ u8 red_mask_size;
+ u8 red_mask_pos;
+ u8 green_mask_size;
+ u8 green_mask_pos;
+ u8 blue_mask_size;
+ u8 blue_mask_pos;
+ u8 reserved_mask_size;
+ u8 reserved_mask_pos;
+ u8 direct_color_mode_info;
+ u32 phys_base_ptr;
+ u32 offscreen_mem_offset;
+ u16 offscreen_mem_size;
+ u8 reserved[206];
+};
+
+struct vesa_state {
+ u16 video_mode;
+ bool valid;
+ union {
+ struct vesa_mode_info vesa;
+ u8 mode_info_block[256];
+ };
+};
+
+struct vesa_ddc_info {
+ u8 port_number; /* i.e. monitor number */
+ u8 edid_transfer_time;
+ u8 ddc_level;
+ u8 edid_block_zero[128];
+};
+
+#define VESA_GET_INFO 0x4f00
+#define VESA_GET_MODE_INFO 0x4f01
+#define VESA_SET_MODE 0x4f02
+#define VESA_GET_CUR_MODE 0x4f03
+
+extern struct vesa_state mode_info;
+
+struct video_priv;
+struct video_uc_plat;
+int vesa_setup_video_priv(struct vesa_mode_info *vesa,
+ struct video_priv *uc_priv,
+ struct video_uc_plat *plat);
+int vesa_setup_video(struct udevice *dev, int (*int15_handler)(void));
+
+#endif