diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/bootdev.h | 206 | ||||
-rw-r--r-- | include/bootflow.h | 134 | ||||
-rw-r--r-- | include/bootmeth.h | 35 | ||||
-rw-r--r-- | include/bootstd.h | 17 | ||||
-rw-r--r-- | include/configs/rk3399_common.h | 5 | ||||
-rw-r--r-- | include/configs/rockchip-common.h | 2 | ||||
-rw-r--r-- | include/dm/uclass-id.h | 4 | ||||
-rw-r--r-- | include/dm/util.h | 8 | ||||
-rw-r--r-- | include/net.h | 31 | ||||
-rw-r--r-- | include/part.h | 8 | ||||
-rw-r--r-- | include/test/test.h | 72 | ||||
-rw-r--r-- | include/vsprintf.h | 24 |
12 files changed, 476 insertions, 70 deletions
diff --git a/include/bootdev.h b/include/bootdev.h index 9fc219839fe..b92ff4d4f15 100644 --- a/include/bootdev.h +++ b/include/bootdev.h @@ -11,6 +11,7 @@ struct bootflow; struct bootflow_iter; +struct bootstd_priv; struct udevice; /** @@ -20,19 +21,87 @@ struct udevice; * * Smallest value is the highest priority. By default, bootdevs are scanned from * highest to lowest priority + * + * BOOTDEVP_0_NONE: Invalid value, do not use + * @BOOTDEVP_6_PRE_SCAN: Scan bootdevs with this priority always, before + * starting any bootflow scan + * @BOOTDEVP_2_INTERNAL_FAST: Internal devices which don't need scanning and + * generally very quick to access, e.g. less than 100ms + * @BOOTDEVP_3_INTERNAL_SLOW: Internal devices which don't need scanning but + * take a significant fraction of a second to access + * @BOOTDEVP_4_SCAN_FAST: Extenal devices which need scanning or bus + * enumeration to find, but this enumeration happens quickly, typically under + * 100ms + * @BOOTDEVP_5_SCAN_SLOW: Extenal devices which need scanning or bus + * enumeration to find. The enumeration takes significant fraction of a second + * to complete + * @BOOTDEVP_6_NET_BASE: Basic network devices which are quickly and easily + * available. Typically used for an internal Ethernet device + * @BOOTDEVP_7_NET_FALLBACK: Secondary network devices which require extra time + * to start up, or are less desirable. Typically used for secondary Ethernet + * devices. Note that USB ethernet devices are found during USB enumeration, + * so do not use this priority */ enum bootdev_prio_t { - BOOTDEVP_0_INTERNAL_FAST = 10, - BOOTDEVP_1_INTERNAL_SLOW = 20, - BOOTDEVP_2_SCAN_FAST = 30, - BOOTDEVP_3_SCAN_SLOW = 40, - BOOTDEVP_4_NET_BASE = 50, - BOOTDEVP_5_NET_FALLBACK = 60, - BOOTDEVP_6_SYSTEM = 70, + BOOTDEVP_0_NONE, + BOOTDEVP_1_PRE_SCAN, + BOOTDEVP_2_INTERNAL_FAST, + BOOTDEVP_3_INTERNAL_SLOW, + BOOTDEVP_4_SCAN_FAST, + BOOTDEVP_5_SCAN_SLOW, + BOOTDEVP_6_NET_BASE, + BOOTDEVP_7_NET_FALLBACK, BOOTDEVP_COUNT, }; +struct bootdev_hunter; + +/** + * bootdev_hunter_func - function to probe for bootdevs of a given type + * + * This should hunt around for bootdevs of the given type, binding them as it + * finds them. This may involve bus enumeration, etc. + * + * @info: Info structure describing this hunter + * @show: true to show information from the hunter + * Returns: 0 if OK, -ve on error + */ +typedef int (*bootdev_hunter_func)(struct bootdev_hunter *info, bool show); + +/** + * struct bootdev_hunter - information about how to hunt for bootdevs + * + * @prio: Scanning priority of this hunter + * @uclass: Uclass ID for the media associated with this bootdev + * @drv: bootdev driver for the things found by this hunter + * @hunt: Function to call to hunt for bootdevs of this type (NULL if none) + * + * Some bootdevs are not visible until other devices are enumerated. For + * example, USB bootdevs only appear when the USB bus is enumerated. + * + * On the other hand, we don't always want to enumerate all the buses just to + * find the first valid bootdev. Ideally we want to work through them in + * priority order, so that the fastest bootdevs are discovered first. + * + * This struct holds information about the bootdev so we can determine the probe + * order and how to hunt for bootdevs of this type + */ +struct bootdev_hunter { + enum bootdev_prio_t prio; + enum uclass_id uclass; + struct driver *drv; + bootdev_hunter_func hunt; +}; + +/* declare a new bootdev hunter */ +#define BOOTDEV_HUNTER(__name) \ + ll_entry_declare(struct bootdev_hunter, __name, bootdev_hunter) + +/* access a bootdev hunter by name */ +#define BOOTDEV_HUNTER_GET(__name) \ + ll_entry_get(struct bootdev_hunter, __name, bootdev_hunter) + /** * struct bootdev_uc_plat - uclass information about a bootdev * @@ -50,7 +119,10 @@ struct bootdev_uc_plat { /** struct bootdev_ops - Operations for the bootdev uclass */ struct bootdev_ops { /** - * get_bootflow() - get a bootflow + * get_bootflow() - get a bootflow (optional) + * + * If this is NULL then the default implementaton is used, which is + * default_get_bootflow() * * @dev: Bootflow device to check * @iter: Provides current dev, part, method to get. Should update @@ -171,40 +243,136 @@ int bootdev_next_bootflow(struct bootflow **bflowp); * @label: Label to look up (e.g. "mmc1" or "mmc0") * @devp: Returns the bootdev device found, or NULL if none (note it does not * return the media device, but its bootdev child) + * @method_flagsp: If non-NULL, returns any flags implied by the label + * (enum bootflow_meth_flags_t), 0 if none. Unset if function fails * Return: 0 if OK, -EINVAL if the uclass is not supported by this board, - * -ENOENT if there is no device with that number + * -ENOENT if there is no device with that number */ -int bootdev_find_by_label(const char *label, struct udevice **devp); +int bootdev_find_by_label(const char *label, struct udevice **devp, + int *method_flagsp); /** * bootdev_find_by_any() - Find a bootdev by name, label or sequence * * @name: name (e.g. "mmc2.bootdev"), label ("mmc2"), or sequence ("2") to find * @devp: returns the device found, on success - * Return: 0 if OK, -ve on error + * @method_flagsp: If non-NULL, returns any flags implied by the label + * (enum bootflow_meth_flags_t), 0 if none. Unset if function fails + * Return: 0 if OK, -EINVAL if the uclass is not supported by this board, + * -ENOENT if there is no device with that number */ -int bootdev_find_by_any(const char *name, struct udevice **devp); +int bootdev_find_by_any(const char *name, struct udevice **devp, + int *method_flagsp); /** - * bootdev_setup_iter_order() - Set up the ordering of bootdevs to scan - * - * This sets up the ordering information in @iter, based on the priority of each - * bootdev and the bootdev-order property in the bootstd node + * bootdev_setup_iter() - Set up iteration through bootdevs * - * If a single device is requested, no ordering is needed + * This sets up the an interation, based on the provided device or label. If + * neither is provided, the iteration is based on the priority of each bootdev, + * the * bootdev-order property in the bootstd node (or the boot_targets env + * var). * * @iter: Iterator to update with the order + * @label: label to scan, or NULL to scan all * @devp: On entry, *devp is NULL to scan all, otherwise this is the (single) * device to scan. Returns the first device to use, which is the passed-in * @devp if it was non-NULL + * @method_flagsp: If non-NULL, returns any flags implied by the label + * (enum bootflow_meth_flags_t), 0 if none * Return: 0 if OK, -ENOENT if no bootdevs, -ENOMEM if out of memory, other -ve * on other error */ -int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp); +int bootdev_setup_iter(struct bootflow_iter *iter, const char *label, + struct udevice **devp, int *method_flagsp); + +/** + * bootdev_list_hunters() - List the available bootdev hunters + * + * These provide a way to find new bootdevs by enumerating buses, etc. This + * function lists the available hunters + * + * @std: Pointer to bootstd private info + */ +void bootdev_list_hunters(struct bootstd_priv *std); + +/** + * bootdev_hunt() - Hunt for bootdevs matching a particular spec + * + * This runs the selected hunter (or all if @spec is NULL) to try to find new + * bootdevs. + * + * @spec: Spec to match, e.g. "mmc0", or NULL for any. If provided, this must + * match a uclass name so that the hunter can be determined. Any trailing number + * is ignored + * @show: true to show each hunter before using it + * Returns: 0 if OK, -ve on error + */ +int bootdev_hunt(const char *spec, bool show); + +/** + * bootdev_hunt_prio() - Hunt for bootdevs of a particular priority + * + * This runs all hunters which can find bootdevs of the given priority. + * + * @prio: Priority to use + * @show: true to show each hunter as it is used + * Returns: 0 if OK, -ve on error + */ +int bootdev_hunt_prio(enum bootdev_prio_t prio, bool show); + +/** + * bootdev_hunt_and_find_by_label() - Hunt for bootdevs by label + * + * Runs the hunter for the label, then tries to find the bootdev, possible + * created by the hunter + * + * @label: Label to look up (e.g. "mmc1" or "mmc0") + * @devp: Returns the bootdev device found, or NULL if none (note it does not + * return the media device, but its bootdev child) + * @method_flagsp: If non-NULL, returns any flags implied by the label + * (enum bootflow_meth_flags_t), 0 if none. Unset if function fails + * Return: 0 if OK, -EINVAL if the uclass is not supported by this board, + * -ENOENT if there is no device with that number + */ +int bootdev_hunt_and_find_by_label(const char *label, struct udevice **devp, + int *method_flagsp); + +/** + * bootdev_next_label() - Move to the next bootdev in the label sequence + * + * Looks through the remaining labels until it finds one that matches a bootdev. + * Bootdev scanners are used as needed. For example a label "mmc1" results in + * running the "mmc" bootdrv. + * + * @iter: Interation info, containing iter->cur_label + * @devp: New bootdev found, if any was found + * @method_flagsp: If non-NULL, returns any flags implied by the label + * (enum bootflow_meth_flags_t), 0 if none + * Returns 0 if OK, -ENODEV if no bootdev was found + */ +int bootdev_next_label(struct bootflow_iter *iter, struct udevice **devp, + int *method_flagsp); + +/** + * bootdev_next_prio() - Find the next bootdev in priority order + * + * This moves @devp to the next bootdev with the current priority. If there is + * none, then it moves to the next priority and scans for new bootdevs there. + * + * @iter: Interation info, containing iter->cur_prio + * @devp: On entry this is the previous bootdev that was considered. On exit + * this is the new bootdev, if any was found + * Returns 0 on success (*devp is updated), -ENODEV if there are no more + * bootdevs at any priority + */ +int bootdev_next_prio(struct bootflow_iter *iter, struct udevice **devp); #if CONFIG_IS_ENABLED(BOOTSTD) /** - * bootdev_setup_for_dev() - Bind a new bootdev device + * bootdev_setup_for_dev() - Bind a new bootdev device (deprecated) + * + * Please use bootdev_setup_sibling_blk() instead since it supports multiple + * (child) block devices for each media device. * * Creates a bootdev device as a child of @parent. This should be called from * the driver's bind() method or its uclass' post_bind() method. diff --git a/include/bootflow.h b/include/bootflow.h index c201246c6de..f516bf8dea4 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -7,12 +7,17 @@ #ifndef __bootflow_h #define __bootflow_h +#include <bootdev.h> #include <dm/ofnode_decl.h> #include <linux/list.h> struct bootstd_priv; struct expo; +enum { + BOOTFLOW_MAX_USED_DEVS = 16, +}; + /** * enum bootflow_state_t - states that a particular bootflow can be in * @@ -43,7 +48,7 @@ enum bootflow_state_t { * @glob_node: Points to siblings in the global list (all bootdev) * @dev: Bootdevice device which produced this bootflow * @blk: Block device which contains this bootflow, NULL if this is a network - * device + * device or sandbox 'host' device * @part: Partition number (0 for whole device) * @fs_type: Filesystem type (FS_TYPE...) if this is fixed by the media, else 0. * For example, the sandbox host-filesystem bootdev sets this to @@ -60,6 +65,9 @@ enum bootflow_state_t { * @err: Error number received (0 if OK) * @os_name: Name of the OS / distro being booted, or NULL if not known * (allocated) + * @fdt_fname: Filename of FDT file + * @fdt_size: Size of FDT file + * @fdt_addr: Address of loaded fdt */ struct bootflow { struct list_head bm_node; @@ -79,23 +87,64 @@ struct bootflow { int size; int err; char *os_name; + char *fdt_fname; + int fdt_size; + ulong fdt_addr; }; /** * enum bootflow_flags_t - flags for the bootflow iterator * * @BOOTFLOWF_FIXED: Only used fixed/internal media - * @BOOTFLOWF_SHOW: Show each bootdev before scanning it + * @BOOTFLOWF_SHOW: Show each bootdev before scanning it; show each hunter + * before using it * @BOOTFLOWF_ALL: Return bootflows with errors as well - * @BOOTFLOWF_SINGLE_DEV: Just scan one bootmeth - * @BOOTFLOWF_SKIP_GLOBAL: Don't scan global bootmeths + * @BOOTFLOWF_HUNT: Hunt for new bootdevs using the bootdrv hunters + * + * Internal flags: + * @BOOTFLOWF_SINGLE_DEV: (internal) Just scan one bootdev + * @BOOTFLOWF_SKIP_GLOBAL: (internal) Don't scan global bootmeths + * @BOOTFLOWF_SINGLE_UCLASS: (internal) Keep scanning through all devices in + * this uclass (used with things like "mmc") + * @BOOTFLOWF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used + * with things like "mmc1") */ 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, + BOOTFLOWF_HUNT = 1 << 3, + + /* + * flags used internally by standard boot - do not set these when + * calling bootflow_scan_bootdev() etc. + */ + BOOTFLOWF_SINGLE_DEV = 1 << 16, + BOOTFLOWF_SKIP_GLOBAL = 1 << 17, + BOOTFLOWF_SINGLE_UCLASS = 1 << 18, + BOOTFLOWF_SINGLE_MEDIA = 1 << 19, +}; + +/** + * enum bootflow_meth_flags_t - flags controlling which bootmeths are used + * + * Used during iteration, e.g. by bootdev_find_by_label(), to determine which + * bootmeths are used for the current bootdev. The flags reset when the bootdev + * changes + * + * @BOOTFLOW_METHF_DHCP_ONLY: Only use dhcp (scripts and EFI) + * @BOOTFLOW_METHF_PXE_ONLY: Only use pxe (PXE boot) + * @BOOTFLOW_METHF_SINGLE_DEV: Scan only a single bootdev (used for labels like + * "3"). This is used if a sequence number is provided instead of a label + * @BOOTFLOW_METHF_SINGLE_UCLASS: Scan all bootdevs in this one uclass (used + * with things like "mmc"). If this is not set, then the bootdev has an integer + * value in the label (like "mmc2") + */ +enum bootflow_meth_flags_t { + BOOTFLOW_METHF_DHCP_ONLY = 1 << 0, + BOOTFLOW_METHF_PXE_ONLY = 1 << 1, + BOOTFLOW_METHF_SINGLE_DEV = 1 << 2, + BOOTFLOW_METHF_SINGLE_UCLASS = 1 << 3, }; /** @@ -118,25 +167,31 @@ enum bootflow_flags_t { * @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 + * @dev: Current bootdev, NULL if none. This is only ever updated in + * bootflow_iter_set_dev() * @part: Current partition number (0 for whole device) * @method: Current bootmeth * @max_part: Maximum hardware partition number in @dev, 0 if there is no * partition table + * @first_bootable: First bootable partition, or 0 if none * @err: Error obtained from checking the last iteration. This is used to skip * forward (e.g. to skip the current partition because it is not valid) * -ESHUTDOWN: try next bootdev - * @num_devs: Number of bootdevs in @dev_order - * @cur_dev: Current bootdev number, an index into @dev_order[] - * @dev_order: List of bootdevs to scan, in order of priority. The scan starts - * with the first one on the list + * @num_devs: Number of bootdevs in @dev_used + * @max_devs: Maximum number of entries in @dev_used + * @dev_used: List of bootdevs used during iteration + * @labels: List of labels to scan for bootdevs + * @cur_label: Current label being processed * @num_methods: Number of bootmeth devices in @method_order * @cur_method: Current method number, an index into @method_order * @first_glob_method: First global method, if any, else -1 + * @cur_prio: Current priority being scanned * @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) + * @method_flags: flags controlling which methods should be used for this @dev + * (enum bootflow_meth_flags_t) */ struct bootflow_iter { int flags; @@ -144,15 +199,20 @@ struct bootflow_iter { int part; struct udevice *method; int max_part; + int first_bootable; int err; int num_devs; - int cur_dev; - struct udevice **dev_order; + int max_devs; + struct udevice *dev_used[BOOTFLOW_MAX_USED_DEVS]; + const char *const *labels; + int cur_label; int num_methods; int cur_method; int first_glob_method; + enum bootdev_prio_t cur_prio; struct udevice **method_order; bool doing_global; + int method_flags; }; /** @@ -197,36 +257,23 @@ int bootflow_iter_drop_bootmeth(struct bootflow_iter *iter, const struct udevice *bmeth); /** - * bootflow_scan_bootdev() - find the first bootflow in a bootdev + * bootflow_scan_first() - find the first bootflow for a device or label * * 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 + * @label: Label to control the scan, NULL to work through all devices + * until it finds one that can supply a bootflow * @iter: Place to store private info (inited by this call) - * @flags: Flags for iterator (enum bootflow_flags_t) + * @flags: Flags for iterator (enum bootflow_flags_t). Note that if @dev + * is NULL, then BOOTFLOWF_SKIP_GLOBAL is set automatically by this function * @bflow: Place to put the bootflow if found * Return: 0 if found, -ENODEV if no device, other -ve on other error * (iteration can continue) */ -int bootflow_scan_bootdev(struct udevice *dev, struct bootflow_iter *iter, - int flags, struct bootflow *bflow); - -/** - * bootflow_scan_first() - find the first bootflow - * - * This works through the available bootdev devices until it finds one that - * can supply a bootflow. It then returns that - * - * If @flags includes BOOTFLOWF_ALL then bootflows with errors are returned too - * - * @iter: Place to store private info (inited by this call), with - * @flags: Flags for bootdev (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) - */ -int bootflow_scan_first(struct bootflow_iter *iter, int flags, +int bootflow_scan_first(struct udevice *dev, const char *label, + struct bootflow_iter *iter, int flags, struct bootflow *bflow); /** @@ -312,33 +359,42 @@ const char *bootflow_state_get_name(enum bootflow_state_t state); void bootflow_remove(struct bootflow *bflow); /** - * bootflow_iter_uses_blk_dev() - Check that a bootflow uses a block device + * bootflow_iter_check_blk() - Check that a bootflow uses a block device * * This checks the bootdev in the bootflow to make sure it uses a block device * * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. ethernet) */ -int bootflow_iter_uses_blk_dev(const struct bootflow_iter *iter); +int bootflow_iter_check_blk(const struct bootflow_iter *iter); + +/** + * bootflow_iter_check_sf() - Check that a bootflow uses SPI FLASH + * + * This checks the bootdev in the bootflow to make sure it uses SPI flash + * + * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. ethernet) + */ +int bootflow_iter_check_sf(const struct bootflow_iter *iter); /** - * bootflow_iter_uses_network() - Check that a bootflow uses a network device + * bootflow_iter_check_net() - Check that a bootflow uses a network device * * This checks the bootdev in the bootflow to make sure it uses a network * device * * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. MMC) */ -int bootflow_iter_uses_network(const struct bootflow_iter *iter); +int bootflow_iter_check_net(const struct bootflow_iter *iter); /** - * bootflow_iter_uses_system() - Check that a bootflow uses the bootstd device + * bootflow_iter_check_system() - Check that a bootflow uses the bootstd device * * This checks the bootdev in the bootflow to make sure it uses the bootstd * device * * Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. MMC) */ -int bootflow_iter_uses_system(const struct bootflow_iter *iter); +int bootflow_iter_check_system(const struct bootflow_iter *iter); /** * bootflow_menu_new() - Create a new bootflow menu diff --git a/include/bootmeth.h b/include/bootmeth.h index 669b14ce81e..b12dfd42c90 100644 --- a/include/bootmeth.h +++ b/include/bootmeth.h @@ -88,6 +88,22 @@ struct bootmeth_ops { int (*read_bootflow)(struct udevice *dev, struct bootflow *bflow); /** + * set_bootflow() - set the bootflow for a device + * + * This provides a bootflow file to the bootmeth, to see if it is valid. + * If it is, the bootflow is set up accordingly. + * + * @dev: Bootmethod device to use + * @bflow: On entry, provides bootdev. + * Returns updated bootflow if found + * @buf: Buffer containing the possible bootflow file + * @size: Size of file + * Return: 0 if OK, -ve on error + */ + int (*set_bootflow)(struct udevice *dev, struct bootflow *bflow, + char *buf, int size); + + /** * read_file() - read a file needed for a bootflow * * Read a file from the same place as the bootflow came from @@ -174,6 +190,23 @@ int bootmeth_check(struct udevice *dev, struct bootflow_iter *iter); int bootmeth_read_bootflow(struct udevice *dev, struct bootflow *bflow); /** + * bootmeth_set_bootflow() - set the bootflow for a device + * + * This provides a bootflow file to the bootmeth, to see if it is valid. + * If it is, the bootflow is set up accordingly. + * + * @dev: Bootmethod device to use + * @bflow: On entry, provides bootdev. + * Returns updated bootflow if found + * @buf: Buffer containing the possible bootflow file (must be allocated + * by caller to @size + 1 bytes) + * @size: Size of file + * Return: 0 if OK, -ve on error + */ +int bootmeth_set_bootflow(struct udevice *dev, struct bootflow *bflow, + char *buf, int size); + +/** * bootmeth_read_file() - read a file needed for a bootflow * * Read a file from the same place as the bootflow came from @@ -240,7 +273,7 @@ int bootmeth_set_order(const char *order_str); * caller before reading the file. * * @bflow: Information about file to try - * @desc: Block descriptor to read from + * @desc: Block descriptor to read from (NULL for sandbox host) * @prefix: Filename prefix to prepend to @fname (NULL for none) * @fname: Filename to read * Return: 0 if OK, -ENOMEM if not enough memory to allocate bflow->fname, diff --git a/include/bootstd.h b/include/bootstd.h index 4fa0d531001..dddb3e15384 100644 --- a/include/bootstd.h +++ b/include/bootstd.h @@ -22,7 +22,10 @@ struct udevice; * @prefixes: NULL-terminated list of prefixes to use for bootflow filenames, * e.g. "/", "/boot/"; NULL if none * @bootdev_order: Order to use for bootdevs (or NULL if none), with each item - * being a bootdev label, e.g. "mmc2", "mmc1"; + * being a bootdev label, e.g. "mmc2", "mmc1" (NULL terminated) + * @env_order: Order as specified by the boot_targets env var (or NULL if none), + * with each item being a bootdev label, e.g. "mmc2", "mmc1" (NULL + * 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 @@ -30,10 +33,13 @@ struct udevice; * @bootmeth_order: List of bootmeth devices to use, in order, NULL-terminated * @vbe_bootmeth: Currently selected VBE bootmeth, NULL if none * @theme: Node containing the theme information + * @hunters_used: Bitmask of used hunters, indexed by their position in the + * linker list. The bit is set if the hunter has been used already */ struct bootstd_priv { const char **prefixes; const char **bootdev_order; + const char **env_order; struct udevice *cur_bootdev; struct bootflow *cur_bootflow; struct list_head glob_head; @@ -41,6 +47,7 @@ struct bootstd_priv { struct udevice **bootmeth_order; struct udevice *vbe_bootmeth; ofnode theme; + uint hunters_used; }; /** @@ -51,9 +58,13 @@ struct bootstd_priv { * The list is alloced by the bootstd driver so should not be freed. That is the * reason for all the const stuff in the function signature * - * Return: list of string points, terminated by NULL; or NULL if no boot order + * @dev: bootstd device + * @okp: returns true if OK, false if out of memory + * Return: list of string pointers, terminated by NULL; or NULL if no boot + * order. Note that this returns NULL in the case of an empty list */ -const char *const *const bootstd_get_bootdev_order(struct udevice *dev); +const char *const *const bootstd_get_bootdev_order(struct udevice *dev, + bool *okp); /** * bootstd_get_prefixes() - Get the filename-prefixes list diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h index 95cb27c8951..3ef9ffa2e9c 100644 --- a/include/configs/rk3399_common.h +++ b/include/configs/rk3399_common.h @@ -48,15 +48,12 @@ #define ROCKCHIP_DEVICE_SETTINGS #endif -#include <config_distro_bootcmd.h> -#include <environment/distro/sf.h> #define CFG_EXTRA_ENV_SETTINGS \ ENV_MEM_LAYOUT_SETTINGS \ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ "partitions=" PARTS_DEFAULT \ ROCKCHIP_DEVICE_SETTINGS \ - BOOTENV \ - BOOTENV_SF \ + "boot_targets=" BOOT_TARGETS "\0" \ "altbootcmd=" \ "setenv boot_syslinux_conf extlinux/extlinux-rollback.conf;" \ "run distro_bootcmd\0" diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h index 1f6b82f2d02..0b23e4c0433 100644 --- a/include/configs/rockchip-common.h +++ b/include/configs/rockchip-common.h @@ -65,12 +65,14 @@ BOOT_TARGET_PXE(func) \ BOOT_TARGET_DHCP(func) \ BOOT_TARGET_SF(func) +#define BOOT_TARGETS "mmc1 mmc0 nvme scsi usb pxe dhcp spi" #else #define BOOT_TARGET_DEVICES(func) \ BOOT_TARGET_MMC(func) \ BOOT_TARGET_USB(func) \ BOOT_TARGET_PXE(func) \ BOOT_TARGET_DHCP(func) +#define BOOT_TARGETS "mmc1 mmc0 usb pxe dhcp" #endif #ifdef CONFIG_ARM64 diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 376f741cc2b..33e43c20db6 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -47,9 +47,9 @@ enum uclass_id { UCLASS_CPU, /* CPU, typically part of an SoC */ UCLASS_CROS_EC, /* Chrome OS EC */ UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */ - UCLASS_DSI_HOST, /* Display Serial Interface host */ UCLASS_DMA, /* Direct Memory Access */ UCLASS_DSA, /* Distributed (Ethernet) Switch Architecture */ + UCLASS_DSI_HOST, /* Display Serial Interface host */ UCLASS_ECDSA, /* Elliptic curve cryptographic device */ UCLASS_EFI_LOADER, /* Devices created by UEFI applications */ UCLASS_EFI_MEDIA, /* Devices provided by UEFI firmware */ @@ -101,6 +101,7 @@ enum uclass_id { UCLASS_PINCTRL, /* Pinctrl (pin muxing/configuration) device */ UCLASS_PMIC, /* PMIC I/O device */ UCLASS_POWER_DOMAIN, /* (SoC) Power domains */ + UCLASS_PVBLOCK, /* Xen virtual block device */ UCLASS_PWM, /* Pulse-width modulator */ UCLASS_PWRSEQ, /* Power sequence device */ UCLASS_QFW, /* QEMU firmware config device */ @@ -142,7 +143,6 @@ enum uclass_id { UCLASS_W1, /* Dallas 1-Wire bus */ UCLASS_W1_EEPROM, /* one-wire EEPROMs */ UCLASS_WDT, /* Watchdog Timer driver */ - UCLASS_PVBLOCK, /* Xen virtual block device */ UCLASS_COUNT, UCLASS_INVALID = -1, diff --git a/include/dm/util.h b/include/dm/util.h index e10c6060ce0..4bb49e9e8c0 100644 --- a/include/dm/util.h +++ b/include/dm/util.h @@ -26,8 +26,12 @@ struct list_head; */ int list_count_items(struct list_head *head); -/* Dump out a tree of all devices */ -void dm_dump_tree(void); +/** + * Dump out a tree of all devices + * + * @sort: Sort by uclass name + */ +void dm_dump_tree(bool sort); /* Dump out a list of uclasses and their devices */ void dm_dump_uclass(void); diff --git a/include/net.h b/include/net.h index ee08f3307ec..399af5e0645 100644 --- a/include/net.h +++ b/include/net.h @@ -66,6 +66,21 @@ struct in_addr { int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); /** + * dhcp_run() - Run DHCP on the current ethernet device + * + * This sets the autoload variable, then puts it back to similar to its original + * state (y, n or unset). + * + * @addr: Address to load the file into (0 if @autoload is false) + * @fname: Filename of file to load (NULL if @autoload is false or to use the + * default filename) + * @autoload: true to load the file, false to just get the network IP + * @return 0 if OK, -EINVAL if the environment failed, -ENOENT if ant file was + * not found + */ +int dhcp_run(ulong addr, const char *fname, bool autoload); + +/** * An incoming packet handler. * @param pkt pointer to the application packet * @param dport destination UDP port @@ -886,4 +901,20 @@ static inline struct in_addr env_get_ip(char *var) */ void reset_phy(void); +#if CONFIG_IS_ENABLED(NET) +/** + * eth_set_enable_bootdevs() - Enable or disable binding of Ethernet bootdevs + * + * These get in the way of bootstd testing, so are normally disabled by tests. + * This provide control of this setting. It only affects binding of Ethernet + * devices, so if that has already happened, this flag does nothing. + * + * @enable: true to enable binding of bootdevs when binding new Ethernet + * devices, false to disable it + */ +void eth_set_enable_bootdevs(bool enable); +#else +static inline void eth_set_enable_bootdevs(bool enable) {} +#endif + #endif /* __NET_H__ */ diff --git a/include/part.h b/include/part.h index 807370d9429..be75c735495 100644 --- a/include/part.h +++ b/include/part.h @@ -303,6 +303,14 @@ part_get_info_by_dev_and_name_or_num(const char *dev_iface, } #endif +/** + * part_get_bootable() - Find the first bootable partition + * + * @desc: Block-device descriptor + * @return first bootable partition, or 0 if there is none + */ +int part_get_bootable(struct blk_desc *desc); + struct udevice; /** * part_create_block_devices - Create block devices for disk partitions diff --git a/include/test/test.h b/include/test/test.h index 4ad74614afc..838e3ce8a8f 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -71,6 +71,8 @@ enum { * since it cannot access the flags. */ UT_TESTF_MANUAL = BIT(8), + UT_TESTF_ETH_BOOTDEV = BIT(9), /* enable Ethernet bootdevs */ + UT_TESTF_SF_BOOTDEV = BIT(10), /* enable SPI flash bootdevs */ }; /** @@ -169,4 +171,74 @@ static inline int test_load_other_fdt(struct unit_test_state *uts) return ret; } +/** + * Control skipping of time delays + * + * Some tests have unnecessay time delays (e.g. USB). Allow these to be + * skipped to speed up testing + * + * @param skip_delays true to skip delays from now on, false to honour delay + * requests + */ +static inline void test_set_skip_delays(bool skip_delays) +{ +#ifdef CONFIG_SANDBOX + state_set_skip_delays(skip_delays); +#endif +} + +/** + * test_set_eth_enable() - Enable / disable Ethernet + * + * Allows control of whether Ethernet packets are actually send/received + * + * @enable: true to enable Ethernet, false to disable + */ +static inline void test_set_eth_enable(bool enable) +{ +#ifdef CONFIG_SANDBOX + sandbox_set_eth_enable(enable); +#endif +} + +/* Allow ethernet to be disabled for testing purposes */ +static inline bool test_eth_enabled(void) +{ + bool enabled = true; + +#ifdef CONFIG_SANDBOX + enabled = sandbox_eth_enabled(); +#endif + return enabled; +} + +/* Allow ethernet bootdev to be ignored for testing purposes */ +static inline bool test_eth_bootdev_enabled(void) +{ + bool enabled = true; + +#ifdef CONFIG_SANDBOX + enabled = sandbox_eth_enabled(); +#endif + return enabled; +} + +/* Allow SPI flash bootdev to be ignored for testing purposes */ +static inline bool test_sf_bootdev_enabled(void) +{ + bool enabled = true; + +#ifdef CONFIG_SANDBOX + enabled = sandbox_sf_bootdev_enabled(); +#endif + return enabled; +} + +static inline void test_sf_set_enable_bootdevs(bool enable) +{ +#ifdef CONFIG_SANDBOX + sandbox_sf_set_enable_bootdevs(enable); +#endif +} + #endif /* __TEST_TEST_H */ diff --git a/include/vsprintf.h b/include/vsprintf.h index e006af200fd..ed8a060ee17 100644 --- a/include/vsprintf.h +++ b/include/vsprintf.h @@ -329,6 +329,30 @@ char *strmhz(char *buf, unsigned long hz); void str_to_upper(const char *in, char *out, size_t len); /** + * str_to_list() - Convert a string to a list of string pointers + * + * Splits a string containing space-delimited substrings into a number of + * separate strings, e.g. "this is" becomes {"this", "is", NULL}. If @instr is + * empty then this returns just {NULL}. The string should have only a single + * space between items, with no leading or trailing spaces. + * + * @instr: String to process (this is alloced by this function) + * Returns: List of string pointers, terminated by NULL. Each entry points to + * a string. If @instr is empty, the list consists just of a single NULL entry. + * Note that the first entry points to the alloced string. + * Returns NULL if out of memory + */ +const char **str_to_list(const char *instr); + +/** + * str_free_list() - Free a string list + * + * @ptr: String list to free, as created by str_to_list(). This can also be + * NULL, in which case the function does nothing + */ +void str_free_list(const char **ptr); + +/** * vsscanf - Unformat a buffer into a list of arguments * @inp: input buffer * @fmt0: format of buffer |