summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2022-08-12 12:51:14 -0400
committerTom Rini <[email protected]>2022-08-12 12:51:14 -0400
commit6fc212779c990ff27a430e370bfb8fac01ddde7f (patch)
tree32ecaafa1d653e275683cfacac41dd2bb57efca1 /include
parentf5003e0791dbe796bf7b41515d67ae5527679ec9 (diff)
parent5fe76d460d857b00d582d7cd6cea9ac740ea912b (diff)
Merge branch '2022-08-11-verified-boot-for-embedded-initial-support'
To quote Simon: This adds the concept of a VBE method to U-Boot, along with an implementation of the 'VBE simple' method, basically a simple way of updating firmware in MMC from userspace and monitoring it from U-Boot. VBE simple is implemented in fwupd. U-Boot's role is to set up the device tree with the required firmware-update properties and provide the developer with information about the current VBE state. To that end this series includes a new 'vbe' command that allows VBE methods to be listed and examined. As part of this work, support for doing FDT fixups via the event interface is provided, along with the ability to write to the device tree via the ofnode interface. Another (significant) change is that bootmeths now have a 'global' flag, to allow the implementation of EFI bootmgr (and VBE) to be cleaned up. The 'system' bootdev is no-longer needed and these bootmeths are scanned first. Further work is needed to pull everything together, but this is a step along the way.
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