diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/bios_emul.h | 6 | ||||
| -rw-r--r-- | include/bootflow.h | 20 | ||||
| -rw-r--r-- | include/bootmeth.h | 65 | ||||
| -rw-r--r-- | include/bootstd.h | 2 | ||||
| -rw-r--r-- | include/dm/of_access.h | 22 | ||||
| -rw-r--r-- | include/dm/ofnode.h | 122 | ||||
| -rw-r--r-- | include/dm/ofnode_decl.h | 85 | ||||
| -rw-r--r-- | include/event.h | 21 | ||||
| -rw-r--r-- | include/of_live.h | 16 | ||||
| -rw-r--r-- | include/test/test.h | 2 | ||||
| -rw-r--r-- | include/vbe.h | 147 | ||||
| -rw-r--r-- | include/vesa.h | 116 |
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 |
