From eca7d27193f7789adca44c91c68fdfcdc824cde2 Mon Sep 17 00:00:00 2001 From: li-elvin Date: Fri, 4 May 2012 12:21:41 +0000 Subject: [PATCH] Currently restoring PCI attributes are put in child uninstall logic, if one child is uninstalled, PCI attributes are restored, it will bring problem for stopping the next child. we do not restore the PCI attributes until all child handles are uninstalled. Signed-off-by: Li Elvin Reviewed-by: Ruiyu Ni git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13275 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Csm/BiosThunk/VideoDxe/BiosVideo.c | 134 ++++++++++++------ .../Csm/BiosThunk/VideoDxe/BiosVideo.h | 23 +-- 2 files changed, 108 insertions(+), 49 deletions(-) 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