/** Find the platform active active video controller and connect it. @retval EFI_NOT_FOUND There is no active video controller. @retval EFI_SUCCESS The video controller is connected. **/ EFI_STATUS ConnectVideoController ( VOID ) { EFI_HANDLE VideoController; EFI_DEVICE_PATH_PROTOCOL *Gop; // // Get the platform vga device // VideoController = GetVideoController (); if (VideoController == NULL) { return EFI_NOT_FOUND; } // // Try to connect the PCI device path, so that GOP dirver could start on this // device and create child handles with GraphicsOutput Protocol installed // on them, then we get device paths of these child handles and select // them as possible console device. // gBS->ConnectController (VideoController, NULL, NULL, FALSE); Gop = EfiBootManagerGetGopDevicePath (VideoController); if (Gop == NULL) { // // Last chance - just try VGA controller // Don't assume all VGA controller support GOP operation // DEBUG ((EFI_D_ERROR, "[Bds] GOP not found, try VGA device path!\n")); Gop = DuplicateDevicePath (DevicePathFromHandle (VideoController)); if (Gop == NULL) { return EFI_NOT_FOUND; } } EfiBootManagerUpdateConsoleVariable (ConOut, Gop, NULL); FreePool (Gop); // // Necessary for ConPlatform and ConSplitter driver to start up again after ConOut is updated. // return gBS->ConnectController (VideoController, NULL, NULL, TRUE); }
/** Connect the platform active active video controller. @param VideoController PCI handle of video controller. @retval EFI_NOT_FOUND There is no active video controller. @retval EFI_SUCCESS The video controller is connected. **/ EFI_STATUS EFIAPI EfiBootManagerConnectVideoController ( EFI_HANDLE VideoController OPTIONAL ) { EFI_DEVICE_PATH_PROTOCOL *Gop; if (VideoController == NULL) { // // Get the platform vga device // VideoController = BmGetVideoController (); } if (VideoController == NULL) { return EFI_NOT_FOUND; } // // Try to connect the PCI device path, so that GOP dirver could start on this // device and create child handles with GraphicsOutput Protocol installed // on them, then we get device paths of these child handles and select // them as possible console device. // gBS->ConnectController (VideoController, NULL, NULL, FALSE); Gop = EfiBootManagerGetGopDevicePath (VideoController); if (Gop == NULL) { return EFI_NOT_FOUND; } EfiBootManagerUpdateConsoleVariable (ConOut, Gop, NULL); FreePool (Gop); // // Necessary for ConPlatform and ConSplitter driver to start up again after ConOut is updated. // return gBS->ConnectController (VideoController, NULL, NULL, TRUE); }
VOID UpdateConOut ( VOID ) { EFI_HANDLE VideoController; EFI_DEVICE_PATH_PROTOCOL *Gop; EFI_HANDLE OnboardVideoController = NULL; EFI_HANDLE AddinVideoController = NULL; UINTN VideoSelect; // // Get the platform vga device // VideoController = PlatformGetVideoController (&OnboardVideoController, &AddinVideoController); if (VideoController == NULL) { return ; } // Force to Auto VideoSelect = 0; // If device selected by SystemConfig is not present, force to Auto if (VideoSelect == 1 && OnboardVideoController == NULL) { VideoSelect = 0; } if (VideoSelect == 2 && AddinVideoController == NULL) { VideoSelect = 0; } switch(VideoSelect) { case 1: // Onboard selected VideoController = OnboardVideoController; DEBUG((EFI_D_INFO, "Video select: Onboard\n")); break; case 2: // Add-in selected VideoController = AddinVideoController; DEBUG((EFI_D_INFO, "Video select: Add-in\n")); break; case 0: default: // Use first VideoController found, which is what GetVideoController returns as VideoController DEBUG((EFI_D_INFO, "Video select: Auto\n")); break; } // // Try to connect the PCI device path, so that GOP dirver could start on this // device and create child handles with GraphicsOutput Protocol installed // on them, then we get device paths of these child handles and select // them as possible console device. // gBS->ConnectController (VideoController, NULL, NULL, FALSE); Gop = EfiBootManagerGetGopDevicePath (VideoController); if (Gop == NULL) { return ; } // // Update ConOut variable to remove device path of on-board/add-in video controller // and add the device path of the specified video controller // EfiBootManagerUpdateConsoleVariable (ConOut, NULL, DevicePathFromHandle (OnboardVideoController)); EfiBootManagerUpdateConsoleVariable (ConOut, Gop, DevicePathFromHandle (AddinVideoController)); FreePool (Gop); }
EFIAPI EfiBootManagerGetGopDevicePath ( IN EFI_HANDLE VideoController ) { UINTN Index; EFI_STATUS Status; EFI_GUID **ProtocolBuffer; UINTN ProtocolBufferCount; UINTN ProtocolIndex; EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; UINTN EntryCount; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *Next; EFI_DEVICE_PATH_PROTOCOL *Previous; EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; EFI_DEVICE_PATH_PROTOCOL *GopPool; EFI_DEVICE_PATH_PROTOCOL *ReturnDevicePath; Status = gBS->ProtocolsPerHandle ( VideoController, &ProtocolBuffer, &ProtocolBufferCount ); if (EFI_ERROR (Status)) { return NULL; } GopPool = NULL; for (ProtocolIndex = 0; ProtocolIndex < ProtocolBufferCount; ProtocolIndex++) { Status = gBS->OpenProtocolInformation ( VideoController, ProtocolBuffer[ProtocolIndex], &OpenInfoBuffer, &EntryCount ); if (EFI_ERROR (Status)) { continue; } for (Index = 0; Index < EntryCount; Index++) { // // Query all the children // if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { Status = gBS->OpenProtocol ( OpenInfoBuffer[Index].ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { continue; } Previous = NULL; for (Next = DevicePath; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) { Previous = Next; } ASSERT (Previous != NULL); if (DevicePathType (Previous) == ACPI_DEVICE_PATH && DevicePathSubType (Previous) == ACPI_ADR_DP) { Status = gBS->OpenProtocol ( OpenInfoBuffer[Index].ControllerHandle, &gEfiGraphicsOutputProtocolGuid, NULL, NULL, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); if (!EFI_ERROR (Status)) { // // Append the device path to GOP pool when there is GOP protocol installed. // TempDevicePath = GopPool; GopPool = AppendDevicePathInstance (GopPool, DevicePath); gBS->FreePool (TempDevicePath); } } if (DevicePathType (Previous) == HARDWARE_DEVICE_PATH && DevicePathSubType (Previous) == HW_CONTROLLER_DP) { // // Recursively look for GOP child in this frame buffer handle // DEBUG ((EFI_D_INFO, "[Bds] Looking for GOP child deeper ... \n")); TempDevicePath = GopPool; ReturnDevicePath = EfiBootManagerGetGopDevicePath (OpenInfoBuffer[Index].ControllerHandle); GopPool = AppendDevicePathInstance (GopPool, ReturnDevicePath); gBS->FreePool (ReturnDevicePath); gBS->FreePool (TempDevicePath); } } } FreePool (OpenInfoBuffer); } FreePool (ProtocolBuffer); return GopPool; }