diff options
author | Tom Rini <trini@konsulko.com> | 2023-01-24 14:04:14 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-01-24 14:04:14 -0500 |
commit | 4e1ab2065e21e48a3087144ab826f12cfb797a65 (patch) | |
tree | 1dc9e793258c5a4a1be4d5e6d554f7f1a82450f3 /drivers/core/dump.c | |
parent | dd31cd58b02729807934cb699b164b1f8736620f (diff) | |
parent | 3891c68ef50eda38d78c95ecd03aed030aa6bb53 (diff) |
Merge branch '2023-01-24-bootstd-allow-migration-from-distro_bootcmd-script'
To quote the author:
So far, standard boot does not replicate all the of the functionality
of the distro_bootcmd scripts. In particular it lacks some bootdevs and
some of the bootmeths are incomplete.
Also there is currently no internal mechanism to enumerate buses in order
to discover bootdevs, e.g. with USB.
This series addresses these shortcomings:
- Adds the concept of a 'bootdev hunter' to enumerate buses, etc. in an
effort to find bootdevs of a certain priority
- Adds bootdevs for SCSI, IDE, NVMe, virtio, SPI flash
- Handles PXE and DHCP properly
- Supports reading the device tree with EFI and reading scripts from the
network
It also tidies up label processing, so it is possible to use:
bootflow scan mmc2
to scan just one MMC device (with BOOTSTD_FULL).
As before this implementation still relies on CONFIG_CMDLINE being
enabled, mostly for the network stack. Further work would be required to
disentangle that.
Quite a few tests are added but there are some gaps:
- SPI flash bootdev
- EFI FDT loading
Note that SATA works via SCSI (CONFIG_SCSI_AHCI) and does not use
driver model. Only pogo_v4 seems to be affected. Probably all thats is
needed is to call bootdev_setup_sibling_blk() in the Marvell SATA driver.
Also, while it would be possible to init MMC in a bootdev hunter, there is
no point since U-Boot always inits MMC on startup, if present.
With this series it should be possible to migrate boards to standard boot
by removing the inclusion of config_distro_bootcmd.h and instead adding
a suitable value for boot_targets to the environment, e.g.:
boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi
Thus it is possible to boot automatically without scripts and boards can
use a text-based environment instead of the config.h files.
To demonstrate this, rockpro64-rk3399 is migrated to standard boot in this
series. Full migration could probably be automated using a script, similar
in concept to moveconfig:
- obtain the board environment via 'make u-boot-initial-env'
- get the value of "boot_targets"
- drop config_distro_bootcmd.h from the config.h file
- rebuild again to get the environment without distro scripts
- write the environment (adding boot_targets) to board.env
- remove CONFIG_EXTRA_ENV_SETTINGS from the config.h file
Diffstat (limited to 'drivers/core/dump.c')
-rw-r--r-- | drivers/core/dump.c | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/drivers/core/dump.c b/drivers/core/dump.c index 1c1f7e4d308..0c7d2ec4d0c 100644 --- a/drivers/core/dump.c +++ b/drivers/core/dump.c @@ -5,12 +5,34 @@ #include <common.h> #include <dm.h> +#include <malloc.h> #include <mapmem.h> +#include <sort.h> #include <dm/root.h> #include <dm/util.h> #include <dm/uclass-internal.h> -static void show_devices(struct udevice *dev, int depth, int last_flag) +/** + * struct sort_info - information used for sorting + * + * @dev: List of devices + * @alloced: Maximum number of devices in @dev + */ +struct sort_info { + struct udevice **dev; + int size; +}; + +static int h_cmp_uclass_id(const void *d1, const void *d2) +{ + const struct udevice *const *dev1 = d1; + const struct udevice *const *dev2 = d2; + + return device_get_uclass_id(*dev1) - device_get_uclass_id(*dev2); +} + +static void show_devices(struct udevice *dev, int depth, int last_flag, + struct udevice **devs) { int i, is_last; struct udevice *child; @@ -39,21 +61,52 @@ static void show_devices(struct udevice *dev, int depth, int last_flag) printf("%s\n", dev->name); - device_foreach_child(child, dev) { - is_last = list_is_last(&child->sibling_node, &dev->child_head); - show_devices(child, depth + 1, (last_flag << 1) | is_last); + if (devs) { + int count; + int i; + + count = 0; + device_foreach_child(child, dev) + devs[count++] = child; + qsort(devs, count, sizeof(struct udevice *), h_cmp_uclass_id); + + for (i = 0; i < count; i++) { + show_devices(devs[i], depth + 1, + (last_flag << 1) | (i == count - 1), + devs + count); + } + } else { + device_foreach_child(child, dev) { + is_last = list_is_last(&child->sibling_node, + &dev->child_head); + show_devices(child, depth + 1, + (last_flag << 1) | is_last, NULL); + } } } -void dm_dump_tree(void) +void dm_dump_tree(bool sort) { struct udevice *root; root = dm_root(); if (root) { + int dev_count, uclasses; + struct udevice **devs = NULL; + + dm_get_stats(&dev_count, &uclasses); + printf(" Class Index Probed Driver Name\n"); printf("-----------------------------------------------------------\n"); - show_devices(root, -1, 0); + if (sort) { + devs = calloc(dev_count, sizeof(struct udevice *)); + if (!devs) { + printf("(out of memory)\n"); + return; + } + } + show_devices(root, -1, 0, devs); + free(devs); } } |