[U-Boot] [PATCH 1/4] Implement "pci enum" command for CONFIG_DM_PCI

From: Stephen Warren swarren@nvidia.com
With CONFIG_DM_PCI enabled, PCI buses are not enumerated at boot, as they are without that config option enabled. No command exists to enumerate the PCI buses. Hence, unless some board-specific code causes PCI enumeration, PCI-based Ethernet devices are not detected, and network access is not available.
This patch implements "pci enum" in the CONFIG_DM_PCI case, thus giving a mechanism whereby PCI can be enumerated.
do_pci()'s handling of case 'e' is moved into a single location before the dev variable is assigned, in order to skip calculation of dev. The enum sub-command doesn't need the dev value, and skipping its calculation avoids an irrelevant error being printed.
Using a command to initialize PCI like this has a disadvantage relative to enumerating PCI at boot. In particular, Ethernet devices are not probed during PCI enumeration, but only when used. This defers setting variables such as ethact, ethaddr, etc. until the first network-related command is executed. Hopefully this will not cause further issues. Perhaps in the long term, we need a "net start/enum" command too?
Signed-off-by: Stephen Warren swarren@nvidia.com --- This series naturally needs to be applied in order in a single branch. This series depends on all previous applied test/py patches.
common/cmd_pci.c | 18 +++++------------- drivers/pci/pci-uclass.c | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/common/cmd_pci.c b/common/cmd_pci.c index 8094d3380fbd..2f4978af9fe3 100644 --- a/common/cmd_pci.c +++ b/common/cmd_pci.c @@ -578,9 +578,10 @@ static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if ((bdf = get_pci_dev(argv[2])) == -1) return 1; break; -#ifdef CONFIG_CMD_PCI_ENUM +#if defined(CONFIG_CMD_PCI_ENUM) || defined(CONFIG_DM_PCI) case 'e': - break; + pci_init(); + return 0; #endif default: /* scan bus */ value = 1; /* short listing */ @@ -621,15 +622,6 @@ static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) break; case 'd': /* display */ return pci_cfg_display(dev, addr, size, value); -#ifdef CONFIG_CMD_PCI_ENUM - case 'e': -# ifdef CONFIG_DM_PCI - printf("This command is not yet supported with driver model\n"); -# else - pci_init(); -# endif - break; -#endif case 'n': /* next */ if (argc < 4) goto usage; @@ -665,9 +657,9 @@ static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) static char pci_help_text[] = "[bus] [long]\n" " - short or long list of PCI devices on bus 'bus'\n" -#ifdef CONFIG_CMD_PCI_ENUM +#if defined(CONFIG_CMD_PCI_ENUM) || defined(CONFIG_DM_PCI) "pci enum\n" - " - re-enumerate PCI buses\n" + " - Enumerate PCI buses\n" #endif "pci header b.d.f\n" " - show header of PCI device 'bus.device.function'\n" diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 685df9d274e4..f51f08289d66 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1247,3 +1247,18 @@ U_BOOT_DRIVER(pci_generic_drv) = { .id = UCLASS_PCI_GENERIC, .of_match = pci_generic_ids, }; + +void pci_init(void) +{ + struct udevice *bus; + + /* + * Enumerate all known controller devices. Enumeration has the side- + * effect of probing them, so PCIe devices will be enumerated too. + */ + for (uclass_first_device(UCLASS_PCI, &bus); + bus; + uclass_next_device(&bus)) { + ; + } +}

From: Stephen Warren swarren@nvidia.com
Currently, the distro boot commands always enumerate USB devices before performing network operations. However, depending on the board and end- user configuration, network devices may not be attached to USB, and so enumerating USB may not be necessary. Enhance the scripts to make this step optional, so that the user can decrease boot time if they don't need USB.
This change is performed by moving the "usb start" invocation into a standalone variable. If the user desires, they can replace that variable's value with some no-op command such as "true" instead.
Booting from a USB storage device always needs to enumerate USB devices, so this action is still hard-coded.
Signed-off-by: Stephen Warren swarren@nvidia.com --- doc/README.distro | 7 +++++++ include/config_distro_bootcmd.h | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/doc/README.distro b/doc/README.distro index 9e4722a86ee5..019903ea7d91 100644 --- a/doc/README.distro +++ b/doc/README.distro @@ -341,6 +341,13 @@ scan_dev_for_scripts: If you want to disable boot.scr on all disks, set the value to something innocuous, e.g. setenv scan_dev_for_scripts true.
+boot_net_usb_start: + + If you want to prevent USB enumeration by distro boot commands which execute + network operations, set the value to something innocuous, e.g. setenv + boot_net_usb_start true. This would be useful if you know your Ethernet + device is not attached to USB, and you wish to increase boot speed by + avoiding unnecessary actions.
Interactively booting from a specific device at the u-boot prompt ================================================================= diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 66264ce3b471..c027d8643967 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -140,15 +140,16 @@ #endif
#ifdef CONFIG_CMD_USB -#define BOOTENV_RUN_USB_INIT "usb start; " +#define BOOTENV_RUN_NET_USB_START "run boot_net_usb_start; " #define BOOTENV_SHARED_USB \ + "boot_net_usb_start=usb start\0" \ "usb_boot=" \ - BOOTENV_RUN_USB_INIT \ + "usb start; " \ BOOTENV_SHARED_BLKDEV_BODY(usb) #define BOOTENV_DEV_USB BOOTENV_DEV_BLKDEV #define BOOTENV_DEV_NAME_USB BOOTENV_DEV_NAME_BLKDEV #else -#define BOOTENV_RUN_USB_INIT +#define BOOTENV_RUN_NET_USB_START #define BOOTENV_SHARED_USB #define BOOTENV_DEV_USB \ BOOT_TARGET_DEVICES_references_USB_without_CONFIG_CMD_USB @@ -159,7 +160,7 @@ #if defined(CONFIG_CMD_DHCP) #define BOOTENV_DEV_DHCP(devtypeu, devtypel, instance) \ "bootcmd_dhcp=" \ - BOOTENV_RUN_USB_INIT \ + BOOTENV_RUN_NET_USB_START \ "if dhcp ${scriptaddr} ${boot_script_dhcp}; then " \ "source ${scriptaddr}; " \ "fi\0" @@ -175,7 +176,7 @@ #if defined(CONFIG_CMD_DHCP) && defined(CONFIG_CMD_PXE) #define BOOTENV_DEV_PXE(devtypeu, devtypel, instance) \ "bootcmd_pxe=" \ - BOOTENV_RUN_USB_INIT \ + BOOTENV_RUN_NET_USB_START \ "dhcp; " \ "if pxe get; then " \ "pxe boot; " \

On 26 January 2016 at 11:10, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
Currently, the distro boot commands always enumerate USB devices before performing network operations. However, depending on the board and end- user configuration, network devices may not be attached to USB, and so enumerating USB may not be necessary. Enhance the scripts to make this step optional, so that the user can decrease boot time if they don't need USB.
This change is performed by moving the "usb start" invocation into a standalone variable. If the user desires, they can replace that variable's value with some no-op command such as "true" instead.
Booting from a USB storage device always needs to enumerate USB devices, so this action is still hard-coded.
Signed-off-by: Stephen Warren swarren@nvidia.com
doc/README.distro | 7 +++++++ include/config_distro_bootcmd.h | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On 26 January 2016 at 12:59, Simon Glass sjg@chromium.org wrote:
On 26 January 2016 at 11:10, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
Currently, the distro boot commands always enumerate USB devices before performing network operations. However, depending on the board and end- user configuration, network devices may not be attached to USB, and so enumerating USB may not be necessary. Enhance the scripts to make this step optional, so that the user can decrease boot time if they don't need USB.
This change is performed by moving the "usb start" invocation into a standalone variable. If the user desires, they can replace that variable's value with some no-op command such as "true" instead.
Booting from a USB storage device always needs to enumerate USB devices, so this action is still hard-coded.
Signed-off-by: Stephen Warren swarren@nvidia.com
doc/README.distro | 7 +++++++ include/config_distro_bootcmd.h | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm, thanks!

From: Stephen Warren swarren@nvidia.com
The PCI bus must be enumerated before PCI devices, such as Ethernet devices, are known to U-Boot. Enhance the distro boot commands to perform PCI enumeration when needed.
Signed-off-by: Stephen Warren swarren@nvidia.com --- doc/README.distro | 8 ++++++++ include/config_distro_bootcmd.h | 12 ++++++++++++ 2 files changed, 20 insertions(+)
diff --git a/doc/README.distro b/doc/README.distro index 019903ea7d91..3715c8c3bad7 100644 --- a/doc/README.distro +++ b/doc/README.distro @@ -349,6 +349,14 @@ boot_net_usb_start: device is not attached to USB, and you wish to increase boot speed by avoiding unnecessary actions.
+boot_net_pci_enum: + + If you want to prevent PCI enumeration by distro boot commands which execute + network operations, set the value to something innocuous, e.g. setenv + boot_net_pci_enum true. This would be useful if you know your Ethernet + device is not attached to PCI, and you wish to increase boot speed by + avoiding unnecessary actions. + Interactively booting from a specific device at the u-boot prompt =================================================================
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index c027d8643967..37c6b438e29f 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -139,6 +139,15 @@ BOOT_TARGET_DEVICES_references_IDE_without_CONFIG_CMD_IDE #endif
+#if defined(CONFIG_CMD_PCI_ENUM) || defined(CONFIG_DM_PCI) +#define BOOTENV_RUN_NET_PCI_ENUM "run boot_net_pci_enum; " +#define BOOTENV_SHARED_PCI \ + "boot_net_pci_enum=pci enum\0" +#else +#define BOOTENV_RUN_NET_PCI_ENUM +#define BOOTENV_SHARED_PCI +#endif + #ifdef CONFIG_CMD_USB #define BOOTENV_RUN_NET_USB_START "run boot_net_usb_start; " #define BOOTENV_SHARED_USB \ @@ -161,6 +170,7 @@ #define BOOTENV_DEV_DHCP(devtypeu, devtypel, instance) \ "bootcmd_dhcp=" \ BOOTENV_RUN_NET_USB_START \ + BOOTENV_RUN_NET_PCI_ENUM \ "if dhcp ${scriptaddr} ${boot_script_dhcp}; then " \ "source ${scriptaddr}; " \ "fi\0" @@ -177,6 +187,7 @@ #define BOOTENV_DEV_PXE(devtypeu, devtypel, instance) \ "bootcmd_pxe=" \ BOOTENV_RUN_NET_USB_START \ + BOOTENV_RUN_NET_PCI_ENUM \ "dhcp; " \ "if pxe get; then " \ "pxe boot; " \ @@ -200,6 +211,7 @@ #define BOOTENV \ BOOTENV_SHARED_HOST \ BOOTENV_SHARED_MMC \ + BOOTENV_SHARED_PCI \ BOOTENV_SHARED_USB \ BOOTENV_SHARED_SATA \ BOOTENV_SHARED_SCSI \

Hi Stephen,
On 26 January 2016 at 11:10, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
The PCI bus must be enumerated before PCI devices, such as Ethernet devices, are known to U-Boot. Enhance the distro boot commands to perform PCI enumeration when needed.
Signed-off-by: Stephen Warren swarren@nvidia.com
doc/README.distro | 8 ++++++++ include/config_distro_bootcmd.h | 12 ++++++++++++ 2 files changed, 20 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
I wonder whether longer term we can invent something that 'knows' that USB and PCI are needed for particular features. This would have to be board-specific though, so probably isn't that different from what you have here.
Regards, Simon

On 26 January 2016 at 13:00, Simon Glass sjg@chromium.org wrote:
Hi Stephen,
On 26 January 2016 at 11:10, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
The PCI bus must be enumerated before PCI devices, such as Ethernet devices, are known to U-Boot. Enhance the distro boot commands to perform PCI enumeration when needed.
Signed-off-by: Stephen Warren swarren@nvidia.com
doc/README.distro | 8 ++++++++ include/config_distro_bootcmd.h | 12 ++++++++++++ 2 files changed, 20 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
I wonder whether longer term we can invent something that 'knows' that USB and PCI are needed for particular features. This would have to be board-specific though, so probably isn't that different from what you have here.
Regards, Simon
Applied to u-boot-dm, thanks!

From: Stephen Warren swarren@nvidia.com
The existing net test executes a list of commands supplied by boardenv variable env__net_pre_commands. The idea was that boardenv would know whether the Ethernet device was attached to USB, PCI, ... and hence was the best place to put any commands required to probe the device.
However, this approach doesn't scale well when attempting to use a single boardenv across multiple branches of U-Boot, some of which require "pci enum" to enumerate PCI and others of which don't, or don't /yet/ simply because various upstream changes haven't been merged down.
This patch updates the test to require that the boardenv state which HW features are required for Ethernet to work, and lets the test itself map that knowledge to the set of commands to execute. Since this mapping is part of the test script, which is part of the U-Boot code/branch, this approach is more scalable. It also feels cleaner, since again boardenv is only providing data, rather than test logic.
Signed-off-by: Stephen Warren swarren@nvidia.com --- test/py/tests/test_net.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/test/py/tests/test_net.py b/test/py/tests/test_net.py index c73854ea74e0..9c46551e8cbf 100644 --- a/test/py/tests/test_net.py +++ b/test/py/tests/test_net.py @@ -15,14 +15,15 @@ will be automatically skipped.
For example:
-# Any commands that need to be executed prior to testing, -# to get the network hardware into an operational state. -# -# If no commands are required, this variable may be omitted, or set to an -# empty list. -env__net_pre_commands = [ - "usb start", -] +# Boolean indicating whether the Ethernet device is attached to USB, and hence +# USB enumeration needs to be performed prior to network tests. +# This variable may be omitted if its value is False. +env__net_uses_usb = False + +# Boolean indicating whether the Ethernet device is attached to PCI, and hence +# PCI enumeration needs to be performed prior to network tests. +# This variable may be omitted if its value is False. +env__net_uses_pci = True
# True if a DHCP server is attached to the network, and should be tested. # If DHCP testing is not possible or desired, this variable may be omitted or @@ -56,12 +57,13 @@ def test_net_pre_commands(u_boot_console): beginning of this file. '''
- cmds = u_boot_console.config.env.get('env__net_pre_commands', None) - if not cmds: - pytest.skip('No network pre-commands defined') + init_usb = u_boot_console.config.env.get('env__net_uses_usb', False) + if init_usb: + u_boot_console.run_command('usb start')
- for cmd in cmds: - u_boot_console.run_command(cmd) + init_pci = u_boot_console.config.env.get('env__net_uses_pci', False) + if init_pci: + u_boot_console.run_command('pci enum')
@pytest.mark.buildconfigspec('cmd_dhcp') def test_net_dhcp(u_boot_console):

On 26 January 2016 at 11:10, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
The existing net test executes a list of commands supplied by boardenv variable env__net_pre_commands. The idea was that boardenv would know whether the Ethernet device was attached to USB, PCI, ... and hence was the best place to put any commands required to probe the device.
However, this approach doesn't scale well when attempting to use a single boardenv across multiple branches of U-Boot, some of which require "pci enum" to enumerate PCI and others of which don't, or don't /yet/ simply because various upstream changes haven't been merged down.
This patch updates the test to require that the boardenv state which HW features are required for Ethernet to work, and lets the test itself map that knowledge to the set of commands to execute. Since this mapping is part of the test script, which is part of the U-Boot code/branch, this approach is more scalable. It also feels cleaner, since again boardenv is only providing data, rather than test logic.
Signed-off-by: Stephen Warren swarren@nvidia.com
test/py/tests/test_net.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On 26 January 2016 at 13:00, Simon Glass sjg@chromium.org wrote:
On 26 January 2016 at 11:10, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
The existing net test executes a list of commands supplied by boardenv variable env__net_pre_commands. The idea was that boardenv would know whether the Ethernet device was attached to USB, PCI, ... and hence was the best place to put any commands required to probe the device.
However, this approach doesn't scale well when attempting to use a single boardenv across multiple branches of U-Boot, some of which require "pci enum" to enumerate PCI and others of which don't, or don't /yet/ simply because various upstream changes haven't been merged down.
This patch updates the test to require that the boardenv state which HW features are required for Ethernet to work, and lets the test itself map that knowledge to the set of commands to execute. Since this mapping is part of the test script, which is part of the U-Boot code/branch, this approach is more scalable. It also feels cleaner, since again boardenv is only providing data, rather than test logic.
Signed-off-by: Stephen Warren swarren@nvidia.com
test/py/tests/test_net.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot-dm, thanks!

On 26 January 2016 at 11:10, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
With CONFIG_DM_PCI enabled, PCI buses are not enumerated at boot, as they are without that config option enabled. No command exists to enumerate the PCI buses. Hence, unless some board-specific code causes PCI enumeration, PCI-based Ethernet devices are not detected, and network access is not available.
This patch implements "pci enum" in the CONFIG_DM_PCI case, thus giving a mechanism whereby PCI can be enumerated.
do_pci()'s handling of case 'e' is moved into a single location before the dev variable is assigned, in order to skip calculation of dev. The enum sub-command doesn't need the dev value, and skipping its calculation avoids an irrelevant error being printed.
Using a command to initialize PCI like this has a disadvantage relative to enumerating PCI at boot. In particular, Ethernet devices are not probed during PCI enumeration, but only when used. This defers setting variables such as ethact, ethaddr, etc. until the first network-related command is executed. Hopefully this will not cause further issues. Perhaps in the long term, we need a "net start/enum" command too?
Signed-off-by: Stephen Warren swarren@nvidia.com
This series naturally needs to be applied in order in a single branch. This series depends on all previous applied test/py patches.
common/cmd_pci.c | 18 +++++------------- drivers/pci/pci-uclass.c | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Wed, Jan 27, 2016 at 2:10 AM, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
With CONFIG_DM_PCI enabled, PCI buses are not enumerated at boot, as they are without that config option enabled. No command exists to enumerate the PCI buses. Hence, unless some board-specific code causes PCI enumeration, PCI-based Ethernet devices are not detected, and network access is not available.
This patch implements "pci enum" in the CONFIG_DM_PCI case, thus giving a mechanism whereby PCI can be enumerated.
do_pci()'s handling of case 'e' is moved into a single location before the dev variable is assigned, in order to skip calculation of dev. The enum sub-command doesn't need the dev value, and skipping its calculation avoids an irrelevant error being printed.
Using a command to initialize PCI like this has a disadvantage relative to enumerating PCI at boot. In particular, Ethernet devices are not probed during PCI enumeration, but only when used. This defers setting variables such as ethact, ethaddr, etc. until the first network-related command is executed. Hopefully this will not cause further issues. Perhaps in the long term, we need a "net start/enum" command too?
Signed-off-by: Stephen Warren swarren@nvidia.com
This series naturally needs to be applied in order in a single branch. This series depends on all previous applied test/py patches.
common/cmd_pci.c | 18 +++++------------- drivers/pci/pci-uclass.c | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On 26 January 2016 at 23:17, Bin Meng bmeng.cn@gmail.com wrote:
On Wed, Jan 27, 2016 at 2:10 AM, Stephen Warren swarren@wwwdotorg.org wrote:
From: Stephen Warren swarren@nvidia.com
With CONFIG_DM_PCI enabled, PCI buses are not enumerated at boot, as they are without that config option enabled. No command exists to enumerate the PCI buses. Hence, unless some board-specific code causes PCI enumeration, PCI-based Ethernet devices are not detected, and network access is not available.
This patch implements "pci enum" in the CONFIG_DM_PCI case, thus giving a mechanism whereby PCI can be enumerated.
do_pci()'s handling of case 'e' is moved into a single location before the dev variable is assigned, in order to skip calculation of dev. The enum sub-command doesn't need the dev value, and skipping its calculation avoids an irrelevant error being printed.
Using a command to initialize PCI like this has a disadvantage relative to enumerating PCI at boot. In particular, Ethernet devices are not probed during PCI enumeration, but only when used. This defers setting variables such as ethact, ethaddr, etc. until the first network-related command is executed. Hopefully this will not cause further issues. Perhaps in the long term, we need a "net start/enum" command too?
Signed-off-by: Stephen Warren swarren@nvidia.com
This series naturally needs to be applied in order in a single branch. This series depends on all previous applied test/py patches.
common/cmd_pci.c | 18 +++++------------- drivers/pci/pci-uclass.c | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Applied to u-boot-dm, thanks!
participants (3)
-
Bin Meng
-
Simon Glass
-
Stephen Warren