diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.c b/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.c index ceb362798c..fa8f4fde04 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.c +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.c @@ -1,7 +1,7 @@ /** @file ConsoleOut Routines that speak VGA. -Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions @@ -37,6 +37,12 @@ UINT8 mVgaRightMaskTable[] = { 0x80, 0xc0, 0xe0, 0xf0, UINT8 mVgaBitMaskTable[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; +// +// Save controller attributes during first start +// +UINT64 mOriginalPciAttributes; +BOOLEAN mPciAttributesSaved = FALSE; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL mVgaColorToGraphicsOutputColor[] = { { 0x00, 0x00, 0x00, 0x00 }, { 0x98, 0x00, 0x00, 0x00 }, @@ -235,9 +241,7 @@ BiosVideoDriverBindingStart ( EFI_PCI_IO_PROTOCOL *PciIo; EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; UINTN Flags; - UINT64 OriginalPciAttributes; UINT64 Supports; - BOOLEAN PciAttributesSaved; // // Initialize local variables @@ -281,21 +285,22 @@ BiosVideoDriverBindingStart ( return Status; } - PciAttributesSaved = FALSE; // // Save original PCI attributes // - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationGet, - 0, - &OriginalPciAttributes - ); - - if (EFI_ERROR (Status)) { - goto Done; + if (!mPciAttributesSaved) { + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationGet, + 0, + &mOriginalPciAttributes + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + mPciAttributesSaved = TRUE; } - PciAttributesSaved = TRUE; // // Get supported PCI attributes @@ -398,8 +403,7 @@ BiosVideoDriverBindingStart ( PciIo, LegacyBios, ParentDevicePath, - RemainingDevicePath, - OriginalPciAttributes + RemainingDevicePath ); Done: @@ -415,16 +419,18 @@ Done: EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED, ParentDevicePath ); - if (PciAttributesSaved) { - // - // Restore original PCI attributes - // - PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSet, - OriginalPciAttributes, - NULL - ); + if (!HasChildHandle (Controller)) { + if (mPciAttributesSaved) { + // + // Restore original PCI attributes + // + PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSet, + mOriginalPciAttributes, + NULL + ); + } } // // Release PCI I/O Protocols on the controller handle. @@ -465,6 +471,7 @@ BiosVideoDriverBindingStop ( EFI_STATUS Status; BOOLEAN AllChildrenStopped; UINTN Index; + EFI_PCI_IO_PROTOCOL *PciIo; AllChildrenStopped = TRUE; @@ -494,6 +501,29 @@ BiosVideoDriverBindingStop ( return EFI_DEVICE_ERROR; } + if (!HasChildHandle (Controller)) { + if (mPciAttributesSaved) { + Status = gBS->HandleProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo + ); + ASSERT_EFI_ERROR (Status); + + // + // Restore original PCI attributes + // + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSet, + mOriginalPciAttributes, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + } + + return EFI_SUCCESS; } @@ -507,7 +537,6 @@ BiosVideoDriverBindingStop ( @param ParentLegacyBios Parent LegacyBios interface @param ParentDevicePath Parent Device Path @param RemainingDevicePath Remaining Device Path - @param OriginalPciAttributes Original PCI Attributes @retval EFI_SUCCESS If a child handle was added @retval other A child handle was not added @@ -520,8 +549,7 @@ BiosVideoChildHandleInstall ( IN EFI_PCI_IO_PROTOCOL *ParentPciIo, IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios, IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - IN UINT64 OriginalPciAttributes + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; @@ -684,7 +712,6 @@ BiosVideoChildHandleInstall ( // When check for VBE, PCI I/O protocol is needed, so use parent's protocol interface temporally // BiosVideoPrivate->PciIo = ParentPciIo; - BiosVideoPrivate->OriginalPciAttributes = OriginalPciAttributes; // // Check for VESA BIOS Extensions for modes that are compatible with Graphics Output @@ -871,17 +898,6 @@ BiosVideoChildHandleUninstall ( Regs.H.BL = 0; BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); - // - // Restore original PCI attributes - // - Status = BiosVideoPrivate->PciIo->Attributes ( - BiosVideoPrivate->PciIo, - EfiPciIoAttributeOperationSet, - BiosVideoPrivate->OriginalPciAttributes, - NULL - ); - ASSERT_EFI_ERROR (Status); - // // Close PCI I/O protocol that opened by child handle // @@ -1193,6 +1209,42 @@ SearchEdidTiming ( return FALSE; } +/** + Check if all video child handles have been uninstalled. + + @param Controller Video controller handle + + @return TRUE Child handles exist. + @return FALSE All video child handles have been uninstalled. + +**/ +BOOLEAN +HasChildHandle ( + IN EFI_HANDLE Controller + ) +{ + UINTN Index; + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; + UINTN EntryCount; + BOOLEAN HasChild; + EFI_STATUS Status; + + EntryCount = 0; + HasChild = FALSE; + Status = gBS->OpenProtocolInformation ( + Controller, + &gEfiPciIoProtocolGuid, + &OpenInfoBuffer, + &EntryCount + ); + for (Index = 0; Index < EntryCount; Index++) { + if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { + HasChild = TRUE; + } + } + + return HasChild; +} /** Check for VBE device. diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.h b/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.h index 45a75b9cd0..88ab1d7cf4 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.h +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions @@ -88,10 +88,6 @@ typedef struct { // EFI_PCI_IO_PROTOCOL *PciIo; EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; - // - // Original PCI attributes - // - UINT64 OriginalPciAttributes; // // Produced Protocols @@ -484,7 +480,6 @@ BiosVideoNotifyExitBootServices ( @param ParentLegacyBios Parent LegacyBios interface @param ParentDevicePath Parent Device Path @param RemainingDevicePath Remaining Device Path - @param OriginalPciAttributes Original PCI Attributes @retval EFI_SUCCESS If a child handle was added @retval other A child handle was not added @@ -497,8 +492,7 @@ BiosVideoChildHandleInstall ( IN EFI_PCI_IO_PROTOCOL *ParentPciIo, IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios, IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - IN UINT64 OriginalPciAttributes + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ); /** @@ -529,4 +523,17 @@ BiosVideoDeviceReleaseResource ( BIOS_VIDEO_DEV *BiosVideoPrivate ); +/** + Check if all video child handles have been uninstalled. + + @param Controller Video controller handle + + @return TRUE Child handles exist. + @return FALSE All video child handles have been uninstalled. + +**/ +BOOLEAN +HasChildHandle ( + IN EFI_HANDLE Controller + ); #endif