On Wed, 15 Jan 2020 at 13:50, Laszlo Ersek <ler...@redhat.com> wrote: > > Hi Ard, >
Hi Laszlo, Thanks for taking a look. > On 01/15/20 11:22, Ard Biesheuvel wrote: > > Currently, ArmPkg's implementation of PlatformBootManagerBeforeConsole() > > iterates over all PCI I/O handles in the database and connects the ones > > that may produce an instance of the Graphics Output Protocol (GOP) once > > connected. After that, it enumerates all the GOP instances and adds them > > to the stdout/stderr console variables so that they will be used for > > console output. > > > > At this point in the boot, the BDS has not dispatched drivers loaded via > > Driver#### options yet, making Driver#### options unsuitable for loading > > drivers that are needed to produce GOP consoles. This is unfortunate, since > > it prevents us from using commodity GFX hardware that ships without AARCH64 > > option ROMs on AARCH64 hardware and load the driver from the ESP. > > > > So let's fix this, by deferring the discovery of PCI backed GOP instances > > until PlatformBootManagerAfterConsole(). Note that non-PCI GOP instances > > are still connected in the original spot, so platform framebuffers will > > still work as before. Also note that the entire dance of connecting PCI > > root bridges and I/O handles, matching PCI class codes and updating console > > variables is all encapsulated in EfiBootManagerConnectVideoController(), > > so let's just call that from PlatformBootManagerAfterConsole(). > > I too have learned about the EfiBootManagerConnectVideoController() ACPI > just recently, when Ray mentioned it. > > (1) When we call EfiBootManagerConnectVideoController() with a NULL > parameter, it further calls BmGetVideoController(), which does the > "dance" you mention. This wasn't obvious to me from the commit message, > so I'd suggest mentioning BmGetVideoController() there, by name. > OK > > > > Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org> > > --- > > > > Tested on AMD Overdrive with an AMD Radeon GPU plugged in and the > > AARCH64 AmdGop.efi driver loaded via Driver0000. > > > > ArmPkg/Library/PlatformBootManagerLib/PlatformBm.c | 81 > > ++------------------ > > 1 file changed, 7 insertions(+), 74 deletions(-) > > > > diff --git a/ArmPkg/Library/PlatformBootManagerLib/PlatformBm.c > > b/ArmPkg/Library/PlatformBootManagerLib/PlatformBm.c > > index e6e788e0f107..7c63a7b98847 100644 > > --- a/ArmPkg/Library/PlatformBootManagerLib/PlatformBm.c > > +++ b/ArmPkg/Library/PlatformBootManagerLib/PlatformBm.c > > @@ -219,66 +219,6 @@ FilterAndProcess ( > > } > > > > > > -/** > > - This FILTER_FUNCTION checks if a handle corresponds to a PCI display > > device. > > -**/ > > -STATIC > > -BOOLEAN > > -EFIAPI > > -IsPciDisplay ( > > - IN EFI_HANDLE Handle, > > - IN CONST CHAR16 *ReportText > > - ) > > -{ > > - EFI_STATUS Status; > > - EFI_PCI_IO_PROTOCOL *PciIo; > > - PCI_TYPE00 Pci; > > - > > - Status = gBS->HandleProtocol (Handle, &gEfiPciIoProtocolGuid, > > - (VOID**)&PciIo); > > - if (EFI_ERROR (Status)) { > > - // > > - // This is not an error worth reporting. > > - // > > - return FALSE; > > - } > > - > > - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0 /* Offset */, > > - sizeof Pci / sizeof (UINT32), &Pci); > > - if (EFI_ERROR (Status)) { > > - DEBUG ((EFI_D_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, > > Status)); > > - return FALSE; > > - } > > - > > - return IS_PCI_DISPLAY (&Pci); > > -} > > - > > - > > -/** > > - This CALLBACK_FUNCTION attempts to connect a handle non-recursively, > > asking > > - the matching driver to produce all first-level child handles. > > -**/ > > -STATIC > > -VOID > > -EFIAPI > > -Connect ( > > - IN EFI_HANDLE Handle, > > - IN CONST CHAR16 *ReportText > > - ) > > -{ > > - EFI_STATUS Status; > > - > > - Status = gBS->ConnectController ( > > - Handle, // ControllerHandle > > - NULL, // DriverImageHandle > > - NULL, // RemainingDevicePath -- produce all children > > - FALSE // Recursive > > - ); > > - DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE, "%a: %s: %r\n", > > - __FUNCTION__, ReportText, Status)); > > -} > > - > > - > > /** > > This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the > > handle, and adds it to ConOut and ErrOut. > > @@ -554,20 +494,6 @@ PlatformBootManagerBeforeConsole ( > > // > > EfiBootManagerDispatchDeferredImages (); > > > > - // > > - // Locate the PCI root bridges and make the PCI bus driver connect each, > > - // non-recursively. This will produce a number of child handles with > > PciIo on > > - // them. > > - // > > - FilterAndProcess (&gEfiPciRootBridgeIoProtocolGuid, NULL, Connect); > > - > > - // > > - // Find all display class PCI devices (using the handles from the > > previous > > - // step), and connect them non-recursively. This should produce a number > > of > > - // child handles with GOPs on them. > > - // > > - FilterAndProcess (&gEfiPciIoProtocolGuid, IsPciDisplay, Connect); > > - > > // > > // Now add the device path of all handles with GOP on them to ConOut and > > // ErrOut. > > (2) Second, BmGetVideoController() differs from the logic that's being > removed here. I see two differences: > > (2a) the IsPciDisplay() helper function uses IS_PCI_DISPLAY(), while > BmGetVideoController() uses IS_PCI_VGA(). > > Interestingly, there is a comment: > > // TODO: use IS_PCI_DISPLAY?? > > If I understand correctly, IS_PCI_VGA() matches a subset of > IS_PCI_DISPLAY(), namely the such devices that offer legacy BIOS VGA > interfaces (IO ports and whatnot). In support of my understanding, > please see: > > - 4fdb585c69d6 ("OvmfPkg/PlatformBootManagerLib: relax device class > requirement for ConOut", 2016-09-01) > > - commit 70dbd16361ee ("OvmfPkg/QemuVideoDxe: Add SubClass field to > QEMU_VIDEO_CARD", 2018-05-17) > > Thus, IS_PCI_VGA() appears overly restrictive *especially* on AARCH64, > where you are more likely to encounter "VGA legacy"-free PCI graphics > cards than on x86. > > Now, this doesn't necessarily mean "ArmPkg/PlatformBmLib" needs to use > its own IS_PCI_DISPLAY logic -- we could also turn the comment in > BmGetVideoController() into actual code, as an alternative. > I think that would be a worthwhile separate change, although for bare metal platforms today, it doesn't really make a difference, given that, AFAICT, non-VGA PCI display controllers are rare, if they exist at all. > (2b) The other difference is that BmGetVideoController() only grabs the > first video controller it finds, and runs with it. Whereas, logic being > removed here would connect (and add, to ConOut/StdErr) *all* PCI video > controllers. I think that's nicer in a multi-controller setup. > True. > > @@ -674,6 +600,13 @@ PlatformBootManagerAfterConsole ( > > UINTN PosX; > > UINTN PosY; > > > > + // > > + // Defer this call to PlatformBootManagerAfterConsole () so that devices > > + // managed by drivers that were loaded via Driver#### options are covered > > + // as well. > > + // > > + EfiBootManagerConnectVideoController (NULL); > > + > > FirmwareVerLength = StrLen (PcdGetPtr (PcdFirmwareVersionString)); > > > > // > > > > (3) So how about the following approach: > > (3a) factor the following sequence: > > FilterAndProcess (&gEfiPciIoProtocolGuid, IsPciDisplay, Connect); > FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput); > > out to a helper function, > > (3b) call the extracted sequence in *both* its current place, *and* at > the top of PlatformBootManagerAfterConsole() (instead of > EfiBootManagerConnectVideoController())? > > ? > > I expect this should give you *some* consoles in BeforeConsole() (on > such PCI and non-PCI graphics controllers whose drivers are in the > platform firmware), just to be safe; and *all* the rest would be picked > up in AfterConsole(). > I wonder whether there is a point to doing it twice, regardless of whether we are talking about PCI or non-PCI. I experimented with just moving those calls to AfterConsole(), and I get basically the same behavior as with this patch. -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#53276): https://edk2.groups.io/g/devel/message/53276 Mute This Topic: https://groups.io/mt/69714171/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-