diff options
Diffstat (limited to 'IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.c')
-rw-r--r-- | IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.c | 134 |
1 files changed, 93 insertions, 41 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.<BR>
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
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
@@ -872,17 +899,6 @@ BiosVideoChildHandleUninstall ( 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
//
Status = gBS->CloseProtocol (
@@ -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.
|