> On Feb 5, 2016, at 10:36 AM, Ryan Harkin <[email protected]> wrote: > > Hi Laszlo, > > On 5 February 2016 at 17:19, Laszlo Ersek <[email protected]> wrote: >> On 02/05/16 17:35, Ryan Harkin wrote: >>> Hello all, >>> >>> I'm having a problem that is platform specific, but perhaps more of a >>> generic problem. >>> >>> When ARM's Juno board boots, not all devices are connected. The first >>> boot creates the boot variables and sets their order, meaning that we >>> get the following list on the first attempt: >>> >>> EFI Misc Device >>> EFI Misc Device 1 >>> EFI Internal Shell >>> >>> Intel BDS then attempts to boot from one of the devices and ends up in >>> Shell. After exiting Shell, the Intel BDS console GUI comes up. >>> Selecting the Boot Manager option shows more devices being connected >>> and the list becomes longer: >>> >>> EFI Misc Device >>> EFI Misc Device 1 >>> EFI Internal Shell >>> EFI Hard Drive >>> EFI Network >>> >>> Subsequent boots will never attempt to boot from Hard Drive or Network >>> because Shell will always succeed. That is not good. >>> >>> Leif has a patch in his working tree that solves this problem [1] by >>> making the platform call BdsLibConnectAll() at init time. So now, the >>> first time boot order looks sane: >>> >>> EFI Misc Device >>> EFI Misc Device 1 >>> EFI Hard Drive >>> EFI Network >>> EFI Internal Shell >>> >>> However, then the board is booting, the "EFI Network" fails to boot >>> the first time and so the board drops back to Shell again: >>> >>> Warning: LAN9118 Driver in stopped state >>> Link timeout in auto-negotiation. >>> Lan9118: Auto Negociation not supported. >>> EhcExecTransfer: transfer failed with 2 >>> EhcControlTransfer: error - Device Error, transfer - 2 >>> Buffer: EFI Hard Drive >>> Booting EFI Misc Device >>> Booting EFI Misc Device 1 >>> Booting EFI Hard Drive >>> Booting EFI Network >>> Warning: LAN9118 Driver not initialized >>> Link timeout in auto-negotiation. >>> Lan9118: Auto Negociation not supported. >>> Booting EFI Internal Shell >>> >>> Exiting Shell drops the user back to the Intel BDS UI. Selecting >>> "Continue" then succeeds in booting from the EFI Network: >>> >>> Booting EFI Misc Device >>> Booting EFI Misc Device 1 >>> Booting EFI Hard Drive >>> Booting EFI Network >>> ..MnpFreeTxBuf: Duplicated recycle report from SNP. >>> MnpFreeTxBuf: Duplicated recycle report from SNP. >>> [snip repeated SNP errors] >>> >>> If I duplicate the call to BdsLibConnectAll() [2], then boot works as >>> expected. On first boot, the boot order is created correctly and EFI >>> Network pulls down a file and boots it. >>> >>> I'm assuming that the 2nd call is connecting things that didn't >>> connect the first time. And from that, I suspect/guess that perhaps >>> they didn't connect due to either ordering or timing. >>> >>> Is there a recommended way to set the order things are connected? Is >>> it even possible to specify dependencies or order? And if so, how do >>> we work out what the order should be? >> >> I cannot give a coherent answer, just a few thoughts. >> >> (1) I think BdsLibConnectAll() actually succeeds for the first time as >> well. All devices are enumerated, all drivers are connected, aren't >> they? The boot order is a separate question. >> > > Yes, you're right, they are all connected because they all appear in > the boot list. > > >> (2) The network, the NIC, or the NIC driver are more probable suspects. >> If I see right, you always have a misc / misc1 / hd / network sequence >> of attempts, it's just that on the first few occasions, the network >> fails. ("Link timeout in auto-negotiation".) >> > > Correct. > > >> (3) I think repeated BdsLibConnectAll() calls may only give more time to >> the NIC to bring itself into working shape. What if you keep only one >> BdsLibConnectAll(), and replace the second BdsLibConnectAll() with a >> sizeable gBS->Stall()? >> > > Eureka! I replace the 2nd BdsLibConnectAll() with > "gBS->Stall(500000);" (0.5 seconds) and this works every time also. > > So time to negociate (sic) would seem like the culprit. I suppose a > 2nd BdsLibConnectAll() buys the NIC some time. > > I'm left wondering if the "Boot EFI Network" option should actually be > waiting for negotiation, however. I'm sure it's common on first boot > that the network needs a little time to negotiate. I'll look into > that. Perhaps there is a setting or an override to tell it to be > patient? >
This is either a bug in the driver, or a bug in the config of the PXE server. Thanks, Andrew Fish > >> (4) What the boot order should be can be influenced by the platform BDS >> lib, in the PlatformBdsPolicyBehavior() function. >> >> Namely, the BdsEntry() function in >> "MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c" initializes the >> "BootOptionList" variable to an empty list. Then it calls >> PlatformBdsPolicyBehavior(), which takes "BootOptionList" as an >> input/output parameter -- if it wishes, it can populate it. >> >> In ArmVirtPkg and in OvmfPkg, we perform the following steps in >> PlatformBdsPolicyBehavior(): >> >> (a) connect the console(s) >> >> (b) BdsLibConnectAll() >> >> (c) BdsLibEnumerateAllBootOption (BootOptionList) -- this relies on the >> presence of all devices, from the previous step. This function (in >> "IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c") has extensive >> documentation in its leading comment. >> >> It will enumerate everything sensible (modifying BootOrder as well I >> think), and output a BootOptionList that contains all the possible boot >> options, in a sane order. Sanity means, if I remember correctly, that >> all options that existed previously and were referenced by BootOrder, >> retain their positions at the front of the list, and any new >> auto-detected boot options are tacked to the end. >> >> (d) SetBootOrderFromQemu (BootOptionList) -- this is the really platform >> specific part for massaging the boot order. We read through >> BootOptionList -- we don't modify it --, do various calculations, and >> then rewrite the BootOrder variable. Importantly, all Boot#### variables >> that become *unreferenced* by BootOrder as a result of this, must be >> deleted (otherwise they constitute a leak). Again, BootOptionList is not >> modified. >> >> (e) BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder") -- it >> rebuilds BootOptionList from the new BootOrder contents. (We are again >> in PlatformBdsPolicyBehavior(), where BootOptionList counts as >> input/output.) >> >> On a physical platform, I think you just go with (b) and (c), and then >> let the user customize the boot order. Next time you boot, (c) will >> respect that. >> > > Excellent answer, thanks. It looks like (c) is exactly the thing I'm > looking for. For example, make HDD boot before USB. That sort of > thing. > > I'm quite happy that once the default boot order has been set that it > stays that way unless the user changes it. I don't (think I) want to > customise the boot order after the initial boot. > > >> There are further possibilities; there is a "boot mode" HOB with which >> your low-level platform code can control your BDS policy, in order to >> speed up things. See BdsLibGetBootMode() and the macros in >> "MdePkg/Include/Pi/PiBootMode.h". Those macros are documented in one of >> the PI spec volumes. >> >> For example, I think BOOT_ASSUMING_NO_CONFIGURATION_CHANGES is meant to >> be very fast (no need to connect all devices to all drivers), but such a >> HOB must be produced by your own PEI phase somehow -- you must know for >> example that the chassis was never opened while the machine was off. >> >> FWIW, OVMF only uses BOOT_WITH_FULL_CONFIGURATION, and >> BOOT_ON_S3_RESUME, and these two are differentiated in OVMF's PEI phase >> by reading a CMOS register. >> >> Anyway, I think what you need is: >> - call BdsLibConnectAll() exactly once >> - give that NIC more time (?) >> - if you'd like to regenerate all possible boot options *at the end* of >> BootOrder that the user may have deleted (or have become available by >> installing new hardware), call BdsLibEnumerateAllBootOption() too. >> > > Yes, that sounds about right. I have concerns about the negotiation > timing, but the boot order hacking sounds like what I'm looking for. > > Thanks again, > Ryan. > > >> Laszlo >> >>> >>> Regards, >>> Ryan. >>> >>> [1] >>> https://git.linaro.org/uefi/linaro-edk2.git/commitdiff/bfbd0ef1a182e1baa120f66ad2c6838ef48ff48c >>> [2] >>> https://git.linaro.org/landing-teams/working/arm/edk2.git/commitdiff/25320ba4e447a843daaf7c603ec87afae3c2a120 >>> >> > _______________________________________________ > edk2-devel mailing list > [email protected] > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

