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 <elvin.li@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13275 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
li-elvin
2012-05-04 12:21:41 +00:00
parent 490173cecf
commit eca7d27193
2 changed files with 108 additions and 49 deletions

View File

@ -1,7 +1,7 @@
/** @file /** @file
ConsoleOut Routines that speak VGA. ConsoleOut Routines that speak VGA.
Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR> Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions 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 }; 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[] = { EFI_GRAPHICS_OUTPUT_BLT_PIXEL mVgaColorToGraphicsOutputColor[] = {
{ 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 },
{ 0x98, 0x00, 0x00, 0x00 }, { 0x98, 0x00, 0x00, 0x00 },
@ -235,9 +241,7 @@ BiosVideoDriverBindingStart (
EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_IO_PROTOCOL *PciIo;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
UINTN Flags; UINTN Flags;
UINT64 OriginalPciAttributes;
UINT64 Supports; UINT64 Supports;
BOOLEAN PciAttributesSaved;
// //
// Initialize local variables // Initialize local variables
@ -281,21 +285,22 @@ BiosVideoDriverBindingStart (
return Status; return Status;
} }
PciAttributesSaved = FALSE;
// //
// Save original PCI attributes // Save original PCI attributes
// //
if (!mPciAttributesSaved) {
Status = PciIo->Attributes ( Status = PciIo->Attributes (
PciIo, PciIo,
EfiPciIoAttributeOperationGet, EfiPciIoAttributeOperationGet,
0, 0,
&OriginalPciAttributes &mOriginalPciAttributes
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto Done; goto Done;
} }
PciAttributesSaved = TRUE; mPciAttributesSaved = TRUE;
}
// //
// Get supported PCI attributes // Get supported PCI attributes
@ -398,8 +403,7 @@ BiosVideoDriverBindingStart (
PciIo, PciIo,
LegacyBios, LegacyBios,
ParentDevicePath, ParentDevicePath,
RemainingDevicePath, RemainingDevicePath
OriginalPciAttributes
); );
Done: Done:
@ -415,17 +419,19 @@ Done:
EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED, EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED,
ParentDevicePath ParentDevicePath
); );
if (PciAttributesSaved) { if (!HasChildHandle (Controller)) {
if (mPciAttributesSaved) {
// //
// Restore original PCI attributes // Restore original PCI attributes
// //
PciIo->Attributes ( PciIo->Attributes (
PciIo, PciIo,
EfiPciIoAttributeOperationSet, EfiPciIoAttributeOperationSet,
OriginalPciAttributes, mOriginalPciAttributes,
NULL NULL
); );
} }
}
// //
// Release PCI I/O Protocols on the controller handle. // Release PCI I/O Protocols on the controller handle.
// //
@ -465,6 +471,7 @@ BiosVideoDriverBindingStop (
EFI_STATUS Status; EFI_STATUS Status;
BOOLEAN AllChildrenStopped; BOOLEAN AllChildrenStopped;
UINTN Index; UINTN Index;
EFI_PCI_IO_PROTOCOL *PciIo;
AllChildrenStopped = TRUE; AllChildrenStopped = TRUE;
@ -494,6 +501,29 @@ BiosVideoDriverBindingStop (
return EFI_DEVICE_ERROR; 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; return EFI_SUCCESS;
} }
@ -507,7 +537,6 @@ BiosVideoDriverBindingStop (
@param ParentLegacyBios Parent LegacyBios interface @param ParentLegacyBios Parent LegacyBios interface
@param ParentDevicePath Parent Device Path @param ParentDevicePath Parent Device Path
@param RemainingDevicePath Remaining Device Path @param RemainingDevicePath Remaining Device Path
@param OriginalPciAttributes Original PCI Attributes
@retval EFI_SUCCESS If a child handle was added @retval EFI_SUCCESS If a child handle was added
@retval other A child handle was not added @retval other A child handle was not added
@ -520,8 +549,7 @@ BiosVideoChildHandleInstall (
IN EFI_PCI_IO_PROTOCOL *ParentPciIo, IN EFI_PCI_IO_PROTOCOL *ParentPciIo,
IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios, IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
IN UINT64 OriginalPciAttributes
) )
{ {
EFI_STATUS Status; 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 // When check for VBE, PCI I/O protocol is needed, so use parent's protocol interface temporally
// //
BiosVideoPrivate->PciIo = ParentPciIo; BiosVideoPrivate->PciIo = ParentPciIo;
BiosVideoPrivate->OriginalPciAttributes = OriginalPciAttributes;
// //
// Check for VESA BIOS Extensions for modes that are compatible with Graphics Output // Check for VESA BIOS Extensions for modes that are compatible with Graphics Output
@ -871,17 +898,6 @@ BiosVideoChildHandleUninstall (
Regs.H.BL = 0; Regs.H.BL = 0;
BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); 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 // Close PCI I/O protocol that opened by child handle
// //
@ -1193,6 +1209,42 @@ SearchEdidTiming (
return FALSE; 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. Check for VBE device.

View File

@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@ -88,10 +88,6 @@ typedef struct {
// //
EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_IO_PROTOCOL *PciIo;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
//
// Original PCI attributes
//
UINT64 OriginalPciAttributes;
// //
// Produced Protocols // Produced Protocols
@ -484,7 +480,6 @@ BiosVideoNotifyExitBootServices (
@param ParentLegacyBios Parent LegacyBios interface @param ParentLegacyBios Parent LegacyBios interface
@param ParentDevicePath Parent Device Path @param ParentDevicePath Parent Device Path
@param RemainingDevicePath Remaining Device Path @param RemainingDevicePath Remaining Device Path
@param OriginalPciAttributes Original PCI Attributes
@retval EFI_SUCCESS If a child handle was added @retval EFI_SUCCESS If a child handle was added
@retval other A child handle was not added @retval other A child handle was not added
@ -497,8 +492,7 @@ BiosVideoChildHandleInstall (
IN EFI_PCI_IO_PROTOCOL *ParentPciIo, IN EFI_PCI_IO_PROTOCOL *ParentPciIo,
IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios, IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
IN UINT64 OriginalPciAttributes
); );
/** /**
@ -529,4 +523,17 @@ BiosVideoDeviceReleaseResource (
BIOS_VIDEO_DEV *BiosVideoPrivate 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 #endif