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