]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Update BiosVideo driver to produce GOP protocol but not UgaDraw protocol which is...
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Sun, 1 Mar 2009 04:47:53 +0000 (04:47 +0000)
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Sun, 1 Mar 2009 04:47:53 +0000 (04:47 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7737 6f19259b-4bc3-4df7-8a09-765794883524

DuetPkg/BiosVideoThunkDxe/BiosVideo.c
DuetPkg/BiosVideoThunkDxe/BiosVideo.h
DuetPkg/BiosVideoThunkDxe/BiosVideo.inf
DuetPkg/BiosVideoThunkDxe/LegacyBiosThunk.c [new file with mode: 0644]

index 8c5957cb9c6a6f00289435a702ce3696a228f2fa..0d8b0c65d12b3bd44efc18164267865c64027796 100644 (file)
@@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 Module Name:\r
 \r
   BiosVideo.c\r
-    \r
+\r
 Abstract:\r
 \r
   ConsoleOut Routines that speak VGA.\r
@@ -23,7 +23,6 @@ Revision History
 \r
 #include "BiosVideo.h"\r
 \r
-\r
 //\r
 // EFI Driver Binding Protocol Instance\r
 //\r
@@ -45,13 +44,7 @@ UINT8                       mVgaRightMaskTable[]  = { 0x80, 0xc0, 0xe0, 0xf0, 0x
 \r
 UINT8                       mVgaBitMaskTable[]    = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };\r
 \r
-THUNK_CONTEXT               mThunkContext;\r
-\r
-EFI_LEGACY_8259_PROTOCOL    *mLegacy8259 = NULL;\r
-\r
-#define EFI_CPU_EFLAGS_IF 0x200\r
-\r
-EFI_UGA_PIXEL               mVgaColorToUgaColor[] = {\r
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL  mVgaColorToGraphicsOutputColor[] = {\r
   {\r
     0x00,\r
     0x00,\r
@@ -150,23 +143,63 @@ EFI_UGA_PIXEL               mVgaColorToUgaColor[] = {
   }\r
 };\r
 \r
+//\r
+// Standard timing defined by VESA EDID\r
+//\r
+VESA_BIOS_EXTENSIONS_EDID_TIMING mEstablishedEdidTiming[] = {\r
+  //\r
+  // Established Timing I\r
+  //\r
+  {800, 600, 60},\r
+  {800, 600, 56},\r
+  {640, 480, 75},\r
+  {640, 480, 72},\r
+  {640, 480, 67},\r
+  {640, 480, 60},\r
+  {720, 400, 88},\r
+  {720, 400, 70},\r
+  //\r
+  // Established Timing II\r
+  //\r
+  {1280, 1024, 75},\r
+  {1024,  768, 75},\r
+  {1024,  768, 70},\r
+  {1024,  768, 60},\r
+  {1024,  768, 87},\r
+  {832,   624, 75},\r
+  {800,   600, 75},\r
+  {800,   600, 72},\r
+  //\r
+  // Established Timing III\r
+  //\r
+  {1152, 870, 75}\r
+};\r
+\r
+EFI_STATUS\r
+BiosVideoChildHandleInstall (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN  EFI_HANDLE                     ParentHandle,\r
+  IN  EFI_PCI_IO_PROTOCOL            *ParentPciIo,\r
+  IN  EFI_LEGACY_8259_PROTOCOL       *ParentLegacy8259,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL       *ParentDevicePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+BiosVideoChildHandleUninstall (\r
+  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  EFI_HANDLE                     Controller,\r
+  EFI_HANDLE                     Handle\r
+  )\r
+;\r
+\r
 VOID\r
-InitializeBiosIntCaller (\r
-  VOID\r
-  );\r
-  \r
-VOID\r
-InitializeInterruptRedirection (\r
-  VOID\r
-  );\r
-    \r
-BOOLEAN\r
-EFIAPI\r
-LegacyBiosInt86 (\r
-  IN  UINT8                           BiosInt,\r
-  IN  EFI_IA32_REGISTER_SET           *Regs\r
-  );\r
-    \r
+BiosVideoDeviceReleaseResource (\r
+  BIOS_VIDEO_DEV  *BiosVideoPrivate\r
+  )\r
+;\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 BiosVideoDriverEntryPoint (\r
@@ -174,20 +207,20 @@ BiosVideoDriverEntryPoint (
   IN EFI_SYSTEM_TABLE   *SystemTable\r
   )\r
 /*++\r
-  \r
+\r
   Routine Description:\r
-  \r
+\r
     Driver Entry Point.\r
-        \r
+\r
   Arguments:\r
-  \r
+\r
   ImageHandle - Handle of driver image.\r
   SystemTable - Pointer to system table.\r
-  \r
+\r
   Returns:\r
-  \r
+\r
     EFI_STATUS\r
-    \r
+\r
 --*/\r
 {\r
   EFI_STATUS  Status;\r
@@ -200,7 +233,7 @@ BiosVideoDriverEntryPoint (
             &gBiosVideoComponentName,\r
             &gBiosVideoComponentName2\r
             );\r
-\r
+            \r
   return Status;\r
 }\r
 \r
@@ -258,38 +291,37 @@ BiosVideoDriverBindingSupported (
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
   )\r
 /*++\r
-  \r
+\r
   Routine Description:\r
 \r
     Supported.\r
-    \r
+\r
   Arguments:\r
 \r
   This - Pointer to driver binding protocol\r
   Controller - Controller handle to connect\r
   RemainingDevicePath - A pointer to the remaining portion of a device path\r
-    \r
-    \r
+\r
+\r
   Returns:\r
 \r
   EFI_STATUS - EFI_SUCCESS:This controller can be managed by this driver,\r
                Otherwise, this controller cannot be managed by this driver\r
-  \r
+\r
 --*/\r
 {\r
-  EFI_STATUS                      Status;\r
-  EFI_LEGACY_8259_PROTOCOL        *Legacy8259;\r
-  EFI_PCI_IO_PROTOCOL             *PciIo;\r
-  \r
-  DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingSupported\n"));\r
+  EFI_STATUS                Status;\r
+  EFI_LEGACY_8259_PROTOCOL  *LegacyBios;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
 \r
   //\r
-  // See if the Legacy BIOS Protocol is available\r
+  // See if the Legacy 8259 Protocol is available\r
   //\r
-  Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &Legacy8259);\r
+  Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &LegacyBios);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+  \r
   //\r
   // Open the IO Abstraction(s) needed to perform the supported test\r
   //\r
@@ -302,21 +334,19 @@ BiosVideoDriverBindingSupported (
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingSupported: Fail to open PciIo protocol!\n"));\r
     return Status;\r
   }\r
-  \r
+\r
   if (!BiosVideoIsVga (PciIo)) {\r
-    DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingSupported: Is not VGA!\n"));\r
     Status = EFI_UNSUPPORTED;\r
   }\r
 \r
   gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiPciIoProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
+         Controller,\r
+         &gEfiPciIoProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
 \r
   return Status;\r
 }\r
@@ -329,97 +359,217 @@ BiosVideoDriverBindingStart (
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
   )\r
 /*++\r
-  \r
+\r
   Routine Description:\r
 \r
-    Install UGA Draw Protocol onto VGA device handles\r
-  \r
+    Install Graphics Output Protocol onto VGA device handles\r
+\r
   Arguments:\r
 \r
   This - Pointer to driver binding protocol\r
   Controller - Controller handle to connect\r
   RemainingDevicePath - A pointer to the remaining portion of a device path\r
-    \r
+\r
   Returns:\r
 \r
     EFI_STATUS\r
-    \r
+\r
 --*/\r
 {\r
-  EFI_STATUS      Status;\r
-  BIOS_VIDEO_DEV  *BiosVideoPrivate;\r
+  EFI_STATUS                      Status;\r
+  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;\r
+  EFI_PCI_IO_PROTOCOL             *PciIo;\r
+  EFI_LEGACY_8259_PROTOCOL        *Legacy8259;\r
 \r
-  DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart\n"));\r
+  PciIo = NULL;\r
   //\r
-  // Initialize local variables\r
+  // Prepare for status code\r
   //\r
-  BiosVideoPrivate = NULL;\r
+  Status = gBS->HandleProtocol (\r
+                  Controller,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
 \r
   //\r
-  // Allocate the private device structure\r
+  // Open the IO Abstraction(s) needed\r
   //\r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  sizeof (BIOS_VIDEO_DEV),\r
-                  (VOID**)&BiosVideoPrivate\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  (VOID **) &PciIo,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     goto Done;\r
   }\r
 \r
-  ZeroMem (BiosVideoPrivate, sizeof (BIOS_VIDEO_DEV));\r
-\r
   //\r
   // See if the Legacy BIOS Protocol is available\r
   //\r
-  Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &mLegacy8259);\r
+  Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &Legacy8259);\r
   if (EFI_ERROR (Status)) {\r
     goto Done;\r
   }\r
-  \r
+\r
+\r
   //\r
-  // Prepare for status code\r
+  // Create child handle and install GraphicsOutputProtocol on it\r
   //\r
-  Status = gBS->HandleProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID**)&BiosVideoPrivate->DevicePath\r
-                  );\r
+  Status = BiosVideoChildHandleInstall (\r
+             This,\r
+             Controller,\r
+             PciIo,\r
+             Legacy8259,\r
+             ParentDevicePath,\r
+             RemainingDevicePath\r
+             );\r
+\r
+Done:\r
   if (EFI_ERROR (Status)) {\r
-    goto Done;\r
+    if (PciIo != NULL) {\r
+      //\r
+      // Release PCI I/O Protocols on the controller handle.\r
+      //\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiPciIoProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    }\r
   }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+BiosVideoDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      Controller,\r
+  IN  UINTN                           NumberOfChildren,\r
+  IN  EFI_HANDLE                      *ChildHandleBuffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+\r
+    Stop.\r
+\r
+  Arguments:\r
+\r
+  This - Pointer to driver binding protocol\r
+  Controller - Controller handle to connect\r
+  NumberOfChilren - Number of children handle created by this driver\r
+  ChildHandleBuffer - Buffer containing child handle created\r
+\r
+  Returns:\r
+\r
+  EFI_SUCCESS - Driver disconnected successfully from controller\r
+  EFI_UNSUPPORTED - Cannot find BIOS_VIDEO_DEV structure\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                   Status;\r
+  BIOS_VIDEO_DEV               *BiosVideoPrivate;\r
+  BOOLEAN                      AllChildrenStopped;\r
+  UINTN                        Index;\r
+\r
+  BiosVideoPrivate = NULL;\r
+\r
+  if (NumberOfChildren == 0) {\r
+    //\r
+    // Close PCI I/O protocol on the controller handle\r
+    //\r
+    gBS->CloseProtocol (\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  AllChildrenStopped = TRUE;\r
+  for (Index = 0; Index < NumberOfChildren; Index++) {\r
+    Status = BiosVideoChildHandleUninstall (This, Controller, ChildHandleBuffer[Index]);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      AllChildrenStopped = FALSE;\r
+    }\r
+  }\r
+\r
+  if (!AllChildrenStopped) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+BiosVideoChildHandleInstall (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  IN  EFI_HANDLE                     ParentHandle,\r
+  IN  EFI_PCI_IO_PROTOCOL            *ParentPciIo,\r
+  IN  EFI_LEGACY_8259_PROTOCOL       *ParentLegacy8259,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL       *ParentDevicePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Install child handles if the Handle supports MBR format.\r
+\r
+Arguments:       \r
+  This       - Calling context.\r
+  Handle     - Parent Handle \r
+  PciIo      - Parent PciIo interface\r
+  LegacyBios  - Parent LegacyBios interface\r
+  DevicePath - Parent Device Path\r
+\r
+Returns:\r
+  EFI_SUCCESS - If a child handle was added\r
+  other       - A child handle was not added\r
+\r
+--*/\r
+{\r
+  EFI_STATUS               Status;\r
+  BIOS_VIDEO_DEV           *BiosVideoPrivate;\r
+  ACPI_ADR_DEVICE_PATH     AcpiDeviceNode;\r
+\r
   //\r
-  // Open the IO Abstraction(s) needed\r
+  // Allocate the private device structure for video device\r
   //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiPciIoProtocolGuid,\r
-                  (VOID **) &(BiosVideoPrivate->PciIo),\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+  Status = gBS->AllocatePool (\r
+                  EfiBootServicesData,\r
+                  sizeof (BIOS_VIDEO_DEV),\r
+                  &BiosVideoPrivate\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     goto Done;\r
   }\r
-  \r
-  DEBUG ((EFI_D_INFO, "InitializeBiosIntCaller\n"));\r
-  InitializeBiosIntCaller();\r
-  InitializeInterruptRedirection();\r
-  DEBUG ((EFI_D_INFO, "InitializeBiosIntCaller Finished!\n"));\r
-  \r
-  if (!BiosVideoIsVga (BiosVideoPrivate->PciIo)) {\r
-    DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: not VGA\n"));\r
+\r
+  ZeroMem (BiosVideoPrivate, sizeof (BIOS_VIDEO_DEV));\r
+\r
+  if (!BiosVideoIsVga (ParentPciIo)) {\r
     Status = EFI_UNSUPPORTED;\r
     goto Done;\r
   }\r
   \r
-  BiosVideoPrivate->VgaCompatible = TRUE; \r
+  BiosVideoPrivate->VgaCompatible = TRUE;\r
+\r
   //\r
-  // Initialize the private device structure\r
+  // Initialize the child private structure\r
   //\r
   BiosVideoPrivate->Signature = BIOS_VIDEO_DEV_SIGNATURE;\r
-  BiosVideoPrivate->Handle    = Controller;\r
+  BiosVideoPrivate->Handle = NULL;\r
 \r
   /**\r
   Status = gBS->CreateEvent (\r
@@ -435,11 +585,9 @@ BiosVideoDriverBindingStart (
   **/\r
   \r
   //\r
-  // Fill in UGA Draw specific mode structures\r
+  // Fill in Graphics Output specific mode structures\r
   //\r
   BiosVideoPrivate->HardwareNeedsStarting = TRUE;\r
-  BiosVideoPrivate->CurrentMode           = 0;\r
-  BiosVideoPrivate->MaxMode               = 0;\r
   BiosVideoPrivate->ModeData              = NULL;\r
   BiosVideoPrivate->LineBuffer            = NULL;\r
   BiosVideoPrivate->VgaFrameBuffer        = NULL;\r
@@ -457,22 +605,30 @@ BiosVideoDriverBindingStart (
   BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterBar       = EFI_PCI_IO_PASS_THROUGH_BAR;\r
 \r
   //\r
-  // Assume that UGA Draw will be produced until proven otherwise\r
+  // Assume that Graphics Output Protocol will be produced until proven otherwise\r
+  //\r
+  BiosVideoPrivate->ProduceGraphicsOutput = TRUE;\r
+\r
+  //\r
+  // Child handle need to consume the Legacy Bios protocol\r
   //\r
-  BiosVideoPrivate->ProduceUgaDraw = TRUE;\r
+  BiosVideoPrivate->Legacy8259 = ParentLegacy8259;\r
 \r
   //\r
-  // Check for VESA BIOS Extensions for modes that are compatible with UGA Draw\r
+  // When check for VBE, PCI I/O protocol is needed, so use parent's protocol interface temporally\r
+  //\r
+  BiosVideoPrivate->PciIo = ParentPciIo;\r
+\r
+  InitializeBiosIntCaller(BiosVideoPrivate);\r
+  InitializeInterruptRedirection(BiosVideoPrivate);\r
+\r
+  //\r
+  // Check for VESA BIOS Extensions for modes that are compatible with Graphics Output\r
   //\r
-  //CpuDeadLoop();\r
-  DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: Before check VBE!\n"));\r
   Status = BiosVideoCheckForVbe (BiosVideoPrivate);\r
-  DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: check VBE status=%r!\n", Status));\r
-  \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: Fail to check VBE!\n"));\r
     //\r
-    // The VESA BIOS Extensions are not compatible with UGA Draw, so check for support\r
+    // The VESA BIOS Extensions are not compatible with Graphics Output, so check for support\r
     // for the standard 640x480 16 color VGA mode\r
     //\r
     if (BiosVideoPrivate->VgaCompatible) {\r
@@ -482,9 +638,9 @@ BiosVideoDriverBindingStart (
     if (EFI_ERROR (Status)) {\r
       //\r
       // Neither VBE nor the standard 640x480 16 color VGA mode are supported, so do\r
-      // not produce the UGA Draw protocol.  Instead, produce the VGA MiniPort Protocol.\r
+      // not produce the Graphics Output protocol.  Instead, produce the VGA MiniPort Protocol.\r
       //\r
-      BiosVideoPrivate->ProduceUgaDraw = FALSE;\r
+      BiosVideoPrivate->ProduceGraphicsOutput = FALSE;\r
 \r
       //\r
       // INT services are available, so on the 80x25 and 80x50 text mode are supported\r
@@ -493,23 +649,60 @@ BiosVideoDriverBindingStart (
     }\r
   }\r
 \r
-  if (BiosVideoPrivate->ProduceUgaDraw) {\r
-    DEBUG ((EFI_D_INFO, "BiosVideoDriverBindingStart: Produce Uga Draw!\n"));\r
+  if (BiosVideoPrivate->ProduceGraphicsOutput) {\r
+    if (RemainingDevicePath == NULL) {\r
+      ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));\r
+      AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;\r
+      AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;\r
+      AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);\r
+      SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
+\r
+      BiosVideoPrivate->DevicePath = AppendDevicePathNode (\r
+                                       ParentDevicePath, \r
+                                       (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode\r
+                                       );\r
+    } else {\r
+      BiosVideoPrivate->DevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);\r
+    }\r
+\r
     //\r
-    // Install UGA Draw Protocol\r
+    // Creat child handle and install Graphics Output Protocol,EDID Discovered/Active Protocol\r
     //\r
     Status = gBS->InstallMultipleProtocolInterfaces (\r
-                    &Controller,\r
-                    &gEfiUgaDrawProtocolGuid,\r
-                    &BiosVideoPrivate->UgaDraw,\r
+                    &BiosVideoPrivate->Handle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    BiosVideoPrivate->DevicePath,\r
+                    &gEfiGraphicsOutputProtocolGuid,\r
+                    &BiosVideoPrivate->GraphicsOutput,\r
+                    &gEfiEdidDiscoveredProtocolGuid,\r
+                    &BiosVideoPrivate->EdidDiscovered,\r
+                    &gEfiEdidActiveProtocolGuid,\r
+                    &BiosVideoPrivate->EdidActive,\r
                     NULL\r
                     );\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Open the Parent Handle for the child\r
+      //\r
+      Status = gBS->OpenProtocol (\r
+                      ParentHandle,\r
+                      &gEfiPciIoProtocolGuid,\r
+                      (VOID **) &BiosVideoPrivate->PciIo,\r
+                      This->DriverBindingHandle,\r
+                      BiosVideoPrivate->Handle,\r
+                      EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+    }\r
   } else {\r
     //\r
     // Install VGA Mini Port Protocol\r
     //\r
     Status = gBS->InstallMultipleProtocolInterfaces (\r
-                    &Controller,\r
+                    &BiosVideoPrivate->Handle,\r
                     &gEfiVgaMiniPortProtocolGuid,\r
                     &BiosVideoPrivate->VgaMiniPort,\r
                     NULL\r
@@ -518,101 +711,66 @@ BiosVideoDriverBindingStart (
 \r
 Done:\r
   if (EFI_ERROR (Status)) {\r
-    if (BiosVideoPrivate != NULL) {\r
-      //\r
-      // Free mode data\r
-      //\r
-      if (BiosVideoPrivate->ModeData != NULL) {\r
-        gBS->FreePool (BiosVideoPrivate->ModeData);\r
-      }\r
-      //\r
-      // Free memory allocated below 1MB\r
-      //\r
-      if (BiosVideoPrivate->PagesBelow1MB != 0) {\r
-        gBS->FreePages (BiosVideoPrivate->PagesBelow1MB, BiosVideoPrivate->NumberOfPagesBelow1MB);\r
-      }\r
-\r
-      if (BiosVideoPrivate->PciIo != NULL) {\r
-        //\r
-        // Release PCI I/O and UGA Draw Protocols on the controller handle.\r
-        //\r
-        gBS->CloseProtocol (\r
-              Controller,\r
-              &gEfiPciIoProtocolGuid,\r
-              This->DriverBindingHandle,\r
-              Controller\r
-              );\r
-      }\r
-      //\r
-      // Close the ExitBootServices event\r
-      //\r
-      if (BiosVideoPrivate->ExitBootServicesEvent != NULL) {\r
-        gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent);\r
-      }\r
-      //\r
-      // Free private data structure\r
-      //\r
-      gBS->FreePool (BiosVideoPrivate);\r
-    }\r
+    //\r
+    // Free private data structure\r
+    //\r
+    BiosVideoDeviceReleaseResource (BiosVideoPrivate);\r
   }\r
 \r
   return Status;\r
 }\r
 \r
 EFI_STATUS\r
-EFIAPI\r
-BiosVideoDriverBindingStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
-  IN  EFI_HANDLE                      Controller,\r
-  IN  UINTN                           NumberOfChildren,\r
-  IN  EFI_HANDLE                      *ChildHandleBuffer\r
+BiosVideoChildHandleUninstall (\r
+  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  EFI_HANDLE                     Controller,\r
+  EFI_HANDLE                     Handle\r
   )\r
 /*++\r
-  \r
-  Routine Description:\r
 \r
-    Stop.\r
-  \r
-  Arguments:\r
+Routine Description:\r
 \r
-  This - Pointer to driver binding protocol\r
-  Controller - Controller handle to connect\r
-  NumberOfChilren - Number of children handle created by this driver\r
-  ChildHandleBuffer - Buffer containing child handle created\r
-  \r
-  Returns:\r
+  Deregister an video child handle and free resources\r
+\r
+Arguments:\r
+\r
+  This            - Protocol instance pointer.\r
+  Controller      - Video controller handle\r
+  Handle          - Video child handle\r
+\r
+Returns:\r
+\r
+  EFI_STATUS\r
 \r
-  EFI_SUCCESS - Driver disconnected successfully from controller\r
-  EFI_UNSUPPORTED - Cannot find BIOS_VIDEO_DEV structure\r
-  \r
 --*/\r
 {\r
-  EFI_STATUS                  Status;\r
-  EFI_UGA_DRAW_PROTOCOL       *Uga;\r
-  EFI_VGA_MINI_PORT_PROTOCOL  *VgaMiniPort;\r
-  BIOS_VIDEO_DEV              *BiosVideoPrivate;\r
-  EFI_IA32_REGISTER_SET       Regs;\r
+  EFI_STATUS                   Status;\r
+  EFI_IA32_REGISTER_SET        Regs;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
+  EFI_VGA_MINI_PORT_PROTOCOL   *VgaMiniPort;\r
+  BIOS_VIDEO_DEV               *BiosVideoPrivate;\r
+  EFI_PCI_IO_PROTOCOL          *PciIo;\r
 \r
   BiosVideoPrivate = NULL;\r
 \r
   Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiUgaDrawProtocolGuid,\r
-                  (VOID **) &Uga,\r
+                  Handle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  (VOID **) &GraphicsOutput,\r
                   This->DriverBindingHandle,\r
-                  Controller,\r
+                  Handle,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                   );\r
   if (!EFI_ERROR (Status)) {\r
-    BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (Uga);\r
+    BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);\r
   }\r
 \r
   Status = gBS->OpenProtocol (\r
-                  Controller,\r
+                  Handle,\r
                   &gEfiVgaMiniPortProtocolGuid,\r
                   (VOID **) &VgaMiniPort,\r
                   This->DriverBindingHandle,\r
-                  Controller,\r
+                  Handle,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                   );\r
   if (!EFI_ERROR (Status)) {\r
@@ -623,43 +781,105 @@ BiosVideoDriverBindingStop (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  if (BiosVideoPrivate->ProduceUgaDraw) {\r
+  //\r
+  // Close PCI I/O protocol that opened by child handle\r
+  //\r
+  Status = gBS->CloseProtocol (\r
+                  Controller,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  This->DriverBindingHandle,\r
+                  Handle\r
+                  );\r
+\r
+  //\r
+  // Uninstall protocols on child handle\r
+  //\r
+  if (BiosVideoPrivate->ProduceGraphicsOutput) {\r
     Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                    Controller,\r
-                    &gEfiUgaDrawProtocolGuid,\r
-                    &BiosVideoPrivate->UgaDraw,\r
+                    BiosVideoPrivate->Handle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    BiosVideoPrivate->DevicePath,\r
+                    &gEfiGraphicsOutputProtocolGuid,\r
+                    &BiosVideoPrivate->GraphicsOutput,\r
+                    &gEfiEdidDiscoveredProtocolGuid,\r
+                    &BiosVideoPrivate->EdidDiscovered,\r
+                    &gEfiEdidActiveProtocolGuid,\r
+                    &BiosVideoPrivate->EdidActive,\r
                     NULL\r
                     );\r
   } else {\r
     Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                    Controller,\r
+                    BiosVideoPrivate->Handle,\r
                     &gEfiVgaMiniPortProtocolGuid,\r
                     &BiosVideoPrivate->VgaMiniPort,\r
                     NULL\r
                     );\r
   }\r
-\r
   if (EFI_ERROR (Status)) {\r
+    gBS->OpenProtocol (\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           (VOID **) &PciIo,\r
+           This->DriverBindingHandle,\r
+           Handle,\r
+           EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+           );\r
     return Status;\r
   }\r
-  \r
-  gBS->SetMem (&Regs, sizeof (Regs), 0);  \r
-  \r
+\r
+  gBS->SetMem (&Regs, sizeof (Regs), 0);\r
+\r
   //\r
   // Set the 80x25 Text VGA Mode\r
   //\r
   Regs.H.AH = 0x00;\r
   Regs.H.AL = 0x03;\r
-  LegacyBiosInt86 (0x10, &Regs);\r
-\r
+  LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+  \r
   Regs.H.AH = 0x11;\r
   Regs.H.AL = 0x14;\r
   Regs.H.BL = 0;\r
-  LegacyBiosInt86 (0x10, &Regs);\r
-\r
+  LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+  \r
   //\r
   // Do not disable IO/memory decode since that would prevent legacy ROM from working\r
   //\r
+\r
+  //\r
+  // Release all allocated resources\r
+  //\r
+  BiosVideoDeviceReleaseResource (BiosVideoPrivate);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+VOID\r
+BiosVideoDeviceReleaseResource (\r
+  BIOS_VIDEO_DEV  *BiosVideoPrivate\r
+  )\r
+/*++\r
+Routing Description:\r
+\r
+  Release resources of an video child device before stopping it.\r
+\r
+Arguments:\r
+\r
+  BiosVideoPrivate  -  Video child device private data structure\r
+\r
+Returns:\r
+\r
+    NONE\r
+    \r
+---*/\r
+{\r
+  if (BiosVideoPrivate == NULL) {\r
+    return ;\r
+  }\r
+\r
+  //\r
+  // Release all the resourses occupied by the BIOS_VIDEO_DEV\r
+  //\r
+  \r
   //\r
   // Free VGA Frame Buffer\r
   //\r
@@ -695,26 +915,220 @@ BiosVideoDriverBindingStop (
     gBS->FreePages (BiosVideoPrivate->VbeSaveRestoreBuffer, BiosVideoPrivate->VbeSaveRestorePages);\r
   }\r
   //\r
-  // Release PCI I/O and UGA Draw Protocols on the controller handle.\r
+  // Free graphics output protocol occupied resource\r
   //\r
-  gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiPciIoProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
+  if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) {\r
+    if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) {\r
+        gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info);\r
+    }\r
+    gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode);\r
+  }\r
+  //\r
+  // Free EDID discovered protocol occupied resource\r
+  //\r
+  if (BiosVideoPrivate->EdidDiscovered.Edid != NULL) {\r
+    gBS->FreePool (BiosVideoPrivate->EdidDiscovered.Edid);\r
+  }\r
+  //\r
+  // Free EDID active protocol occupied resource\r
+  //\r
+  if (BiosVideoPrivate->EdidActive.Edid != NULL) {\r
+    gBS->FreePool (BiosVideoPrivate->EdidActive.Edid);\r
+  }\r
+\r
+  if (BiosVideoPrivate->DevicePath!= NULL) {\r
+    gBS->FreePool (BiosVideoPrivate->DevicePath);\r
+  }\r
 \r
   //\r
   // Close the ExitBootServices event\r
   //\r
-  gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent);\r
+  if (BiosVideoPrivate->ExitBootServicesEvent != NULL) {\r
+    gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent);\r
+  }\r
+\r
+  gBS->FreePool (BiosVideoPrivate);\r
+\r
+  return ;\r
+}\r
+\r
+STATIC\r
+UINT32\r
+CalculateEdidKey (\r
+  VESA_BIOS_EXTENSIONS_EDID_TIMING       *EdidTiming\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+\r
+  Generate a search key for a specified timing data.\r
+\r
+  Arguments:\r
+\r
+  EdidTiming       - Pointer to EDID timing\r
+\r
+  Returns:\r
+  The 32 bit unique key for search.\r
+\r
+--*/\r
+{\r
+  UINT32 Key;\r
 \r
   //\r
-  // Free private data structure\r
+  // Be sure no conflicts for all standard timing defined by VESA.\r
   //\r
-  gBS->FreePool (BiosVideoPrivate);\r
+  Key = (EdidTiming->HorizontalResolution * 2) + EdidTiming->VerticalResolution;\r
+  return Key;\r
+}\r
 \r
-  return EFI_SUCCESS;\r
+STATIC\r
+BOOLEAN\r
+ParseEdidData (\r
+  UINT8                                      *EdidBuffer,\r
+  VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING *ValidEdidTiming\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+\r
+  Parse the Established Timing and Standard Timing in EDID data block.\r
+\r
+  Arguments:\r
+\r
+  EdidBuffer       - Pointer to EDID data block\r
+  ValidEdidTiming  - Valid EDID timing information\r
+\r
+  Returns:\r
+  TRUE              - The EDID data is valid.\r
+  FALSE             - The EDID data is invalid.\r
+\r
+--*/\r
+{\r
+  UINT8  CheckSum;\r
+  UINT32 Index;\r
+  UINT32 ValidNumber;\r
+  UINT32 TimingBits;\r
+  UINT8  *BufferIndex;\r
+  UINT16 HorizontalResolution;\r
+  UINT16 VerticalResolution;\r
+  UINT8  AspectRatio;\r
+  UINT8  RefreshRate;\r
+  VESA_BIOS_EXTENSIONS_EDID_TIMING     TempTiming;\r
+  VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *EdidDataBlock;\r
+\r
+  EdidDataBlock = (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *) EdidBuffer;\r
+\r
+  //\r
+  // Check the checksum of EDID data\r
+  //\r
+  CheckSum = 0;\r
+  for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE; Index ++) {\r
+    CheckSum = CheckSum + EdidBuffer[Index];\r
+  }\r
+  if (CheckSum != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  ValidNumber = 0;\r
+  gBS->SetMem (ValidEdidTiming, sizeof (VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING), 0);\r
+\r
+  if ((EdidDataBlock->EstablishedTimings[0] != 0) ||\r
+      (EdidDataBlock->EstablishedTimings[1] != 0) ||\r
+      (EdidDataBlock->EstablishedTimings[2] != 0)\r
+      ) {\r
+    //\r
+    // Established timing data\r
+    //\r
+    TimingBits = EdidDataBlock->EstablishedTimings[0] |\r
+                 (EdidDataBlock->EstablishedTimings[1] << 8) |\r
+                 ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ;\r
+    for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) {\r
+      if (TimingBits & 0x1) {\r
+        ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&mEstablishedEdidTiming[Index]);\r
+        ValidNumber ++;\r
+      }\r
+      TimingBits = TimingBits >> 1;\r
+    }\r
+  } else {\r
+    //\r
+    // If no Established timing data, read the standard timing data\r
+    //\r
+    BufferIndex = &EdidDataBlock->StandardTimingIdentification[0];\r
+    for (Index = 0; Index < 8; Index ++) {\r
+      if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){\r
+        //\r
+        // A valid Standard Timing\r
+        //\r
+        HorizontalResolution = BufferIndex[0] * 8 + 248;\r
+        AspectRatio = BufferIndex[1] >> 6;\r
+        switch (AspectRatio) {\r
+          case 0:\r
+            VerticalResolution = HorizontalResolution / 16 * 10;\r
+            break;\r
+          case 1:\r
+            VerticalResolution = HorizontalResolution / 4 * 3;\r
+            break;\r
+          case 2:\r
+            VerticalResolution = HorizontalResolution / 5 * 4;\r
+            break;\r
+          case 3:\r
+            VerticalResolution = HorizontalResolution / 16 * 9;\r
+            break;\r
+          default:\r
+            VerticalResolution = HorizontalResolution / 4 * 3;\r
+            break;\r
+        }\r
+        RefreshRate = (BufferIndex[1] & 0x1f) + 60;\r
+        TempTiming.HorizontalResolution = HorizontalResolution;\r
+        TempTiming.VerticalResolution = VerticalResolution;\r
+        TempTiming.RefreshRate = RefreshRate;\r
+        ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming);\r
+        ValidNumber ++;\r
+      }\r
+      BufferIndex += 2;\r
+    }\r
+  }\r
+\r
+  ValidEdidTiming->ValidNumber = ValidNumber;\r
+  return TRUE;\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+SearchEdidTiming (\r
+  VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING *ValidEdidTiming,\r
+  VESA_BIOS_EXTENSIONS_EDID_TIMING       *EdidTiming\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+\r
+  Search a specified Timing in all the valid EDID timings.\r
+\r
+  Arguments:\r
+\r
+  ValidEdidTiming  - All valid EDID timing information.\r
+  EdidTiming       - The Timing to search for.\r
+\r
+  Returns:\r
+\r
+  TRUE  - Found.\r
+  FALSE - Not found.\r
+\r
+--*/\r
+{\r
+  UINT32 Index;\r
+  UINT32 Key;\r
+\r
+  Key = CalculateEdidKey (EdidTiming);\r
+\r
+  for (Index = 0; Index < ValidEdidTiming->ValidNumber; Index ++) {\r
+    if (Key == ValidEdidTiming->Key[Index]) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
 }\r
 \r
 #define PCI_DEVICE_ENABLED  (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE)\r
@@ -769,37 +1183,46 @@ BiosVideoIsVga (
 \r
 \r
 EFI_STATUS\r
+EFIAPI\r
 BiosVideoCheckForVbe (\r
-  IN OUT BIOS_VIDEO_DEV  *BiosVideoPrivate  \r
+  IN OUT BIOS_VIDEO_DEV  *BiosVideoPrivate\r
   )\r
 /*++\r
-  \r
+\r
   Routine Description:\r
 \r
-  Check for VBE device   \r
-  \r
+  Check for VBE device\r
+\r
   Arguments:\r
-  \r
+\r
   BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure\r
-  \r
+\r
   Returns:\r
-  \r
+\r
   EFI_SUCCESS - VBE device found\r
-  \r
+\r
 --*/\r
 {\r
-  EFI_STATUS            Status;\r
-  EFI_IA32_REGISTER_SET Regs;\r
-  UINT16                *ModeNumberPtr;\r
-  BOOLEAN               ModeFound;\r
-  BIOS_VIDEO_MODE_DATA  *ModeBuffer;\r
-  UINTN                 Index;\r
+  EFI_STATUS                             Status;\r
+  EFI_IA32_REGISTER_SET                  Regs;\r
+  UINT16                                 *ModeNumberPtr;\r
+  BOOLEAN                                ModeFound;\r
+  BOOLEAN                                EdidFound;\r
+  BIOS_VIDEO_MODE_DATA                   *ModeBuffer;\r
+  BIOS_VIDEO_MODE_DATA                   *CurrentModeData;\r
+  UINTN                                  PreferMode;\r
+  UINTN                                  ModeNumber;\r
+  VESA_BIOS_EXTENSIONS_EDID_TIMING       Timing;\r
+  VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING ValidEdidTiming;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE      *GraphicsOutputMode;\r
 \r
   //\r
   // Allocate buffer under 1MB for VBE data structures\r
   //\r
   BiosVideoPrivate->NumberOfPagesBelow1MB = EFI_SIZE_TO_PAGES (\r
-                                              sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK) + sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK) +\r
+                                              sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK) +\r
+                                              sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK) +\r
+                                              sizeof (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK) +\r
                                               sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK)\r
                                               );\r
 \r
@@ -814,19 +1237,24 @@ BiosVideoCheckForVbe (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+\r
+  ZeroMem (&ValidEdidTiming, sizeof (VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING));\r
+\r
   //\r
-  // Fill in the UGA Draw Protocol\r
+  // Fill in the Graphics Output Protocol\r
   //\r
-  BiosVideoPrivate->UgaDraw.GetMode = BiosVideoUgaDrawGetMode;\r
-  BiosVideoPrivate->UgaDraw.SetMode = BiosVideoUgaDrawSetMode;\r
-  BiosVideoPrivate->UgaDraw.Blt     = BiosVideoUgaDrawVbeBlt;\r
+  BiosVideoPrivate->GraphicsOutput.QueryMode = BiosVideoGraphicsOutputQueryMode;\r
+  BiosVideoPrivate->GraphicsOutput.SetMode = BiosVideoGraphicsOutputSetMode;\r
+  BiosVideoPrivate->GraphicsOutput.Blt     = BiosVideoGraphicsOutputVbeBlt;\r
+  BiosVideoPrivate->GraphicsOutput.Mode = NULL;\r
 \r
   //\r
   // Fill in the VBE related data structures\r
   //\r
   BiosVideoPrivate->VbeInformationBlock = (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK *) (UINTN) (BiosVideoPrivate->PagesBelow1MB);\r
   BiosVideoPrivate->VbeModeInformationBlock = (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeInformationBlock + 1);\r
-  BiosVideoPrivate->VbeCrtcInformationBlock = (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeModeInformationBlock + 1);\r
+  BiosVideoPrivate->VbeEdidDataBlock = (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *) (BiosVideoPrivate->VbeModeInformationBlock + 1);\r
+  BiosVideoPrivate->VbeCrtcInformationBlock = (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeEdidDataBlock + 1);\r
   BiosVideoPrivate->VbeSaveRestorePages   = 0;\r
   BiosVideoPrivate->VbeSaveRestoreBuffer  = 0;\r
 \r
@@ -837,11 +1265,11 @@ BiosVideoCheckForVbe (
   Regs.X.AX = VESA_BIOS_EXTENSIONS_RETURN_CONTROLLER_INFORMATION;\r
   gBS->SetMem (BiosVideoPrivate->VbeInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK), 0);\r
   BiosVideoPrivate->VbeInformationBlock->VESASignature  = VESA_BIOS_EXTENSIONS_VBE2_SIGNATURE;\r
-  Regs.X.ES = EFI_SEGMENT ((UINTN)BiosVideoPrivate->VbeInformationBlock);\r
-  Regs.X.DI = EFI_OFFSET ((UINTN)BiosVideoPrivate->VbeInformationBlock);\r
-\r
-  LegacyBiosInt86 (0x10, &Regs);\r
+  Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeInformationBlock);\r
+  Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeInformationBlock);\r
 \r
+  LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+  \r
   Status = EFI_DEVICE_ERROR;\r
 \r
   //\r
@@ -862,14 +1290,81 @@ BiosVideoCheckForVbe (
   if (BiosVideoPrivate->VbeInformationBlock->VESAVersion < VESA_BIOS_EXTENSIONS_VERSION_2_0) {\r
     return Status;\r
   }\r
+\r
+  //\r
+  // Read EDID information\r
+  //\r
+  gBS->SetMem (&Regs, sizeof (Regs), 0);\r
+  Regs.X.AX = VESA_BIOS_EXTENSIONS_EDID;\r
+  Regs.X.BX = 1;\r
+  Regs.X.CX = 0;\r
+  Regs.X.DX = 0;\r
+  Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeEdidDataBlock);\r
+  Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeEdidDataBlock);\r
+\r
+  LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+  \r
+  //\r
+  // See if the VESA call succeeded\r
+  //\r
+  EdidFound = FALSE;\r
+  if (Regs.X.AX == VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {\r
+    //\r
+    // Parse EDID data structure to retrieve modes supported by monitor\r
+    //\r
+    if (ParseEdidData ((UINT8 *) BiosVideoPrivate->VbeEdidDataBlock, &ValidEdidTiming) == TRUE) {\r
+      EdidFound = TRUE;\r
+\r
+      BiosVideoPrivate->EdidDiscovered.SizeOfEdid = VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE;\r
+      Status = gBS->AllocatePool (\r
+                      EfiBootServicesData,\r
+                      VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE,\r
+                      &BiosVideoPrivate->EdidDiscovered.Edid\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+      gBS->CopyMem (\r
+             BiosVideoPrivate->EdidDiscovered.Edid,\r
+             BiosVideoPrivate->VbeEdidDataBlock,\r
+             VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE\r
+             );\r
+\r
+      BiosVideoPrivate->EdidActive.SizeOfEdid = VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE;\r
+      Status = gBS->AllocatePool (\r
+                      EfiBootServicesData,\r
+                      VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE,\r
+                      &BiosVideoPrivate->EdidActive.Edid\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+      gBS->CopyMem (\r
+             BiosVideoPrivate->EdidActive.Edid,\r
+             BiosVideoPrivate->VbeEdidDataBlock,\r
+             VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE\r
+             );\r
+    } else {\r
+      BiosVideoPrivate->EdidDiscovered.SizeOfEdid = 0;\r
+      BiosVideoPrivate->EdidDiscovered.Edid = NULL;\r
+\r
+      BiosVideoPrivate->EdidActive.SizeOfEdid = 0;\r
+      BiosVideoPrivate->EdidActive.Edid = NULL;\r
+    }\r
+  }\r
+\r
   //\r
-  // Walk through the mode list to see if there is at least one mode the is compatible with the UGA_DRAW protocol\r
+  // Walk through the mode list to see if there is at least one mode the is compatible with the EDID mode\r
   //\r
   ModeNumberPtr = (UINT16 *)\r
     (\r
       (((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0xffff0000) >> 12) |\r
         ((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0x0000ffff)\r
     );\r
+\r
+  PreferMode = 0;\r
+  ModeNumber = 0;\r
+\r
   for (; *ModeNumberPtr != VESA_BIOS_EXTENSIONS_END_OF_MODE_LIST; ModeNumberPtr++) {\r
     //\r
     // Make sure this is a mode number defined by the VESA VBE specification.  If it isn'tm then skip this mode number.\r
@@ -884,11 +1379,11 @@ BiosVideoCheckForVbe (
     Regs.X.AX = VESA_BIOS_EXTENSIONS_RETURN_MODE_INFORMATION;\r
     Regs.X.CX = *ModeNumberPtr;\r
     gBS->SetMem (BiosVideoPrivate->VbeModeInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK), 0);\r
-    Regs.X.ES = EFI_SEGMENT ((UINTN)BiosVideoPrivate->VbeModeInformationBlock);\r
-    Regs.X.DI = EFI_OFFSET ((UINTN)BiosVideoPrivate->VbeModeInformationBlock);\r
-\r
-    LegacyBiosInt86 (0x10, &Regs);\r
+    Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeModeInformationBlock);\r
+    Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeModeInformationBlock);\r
 \r
+    LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+    \r
     //\r
     // See if the call succeeded.  If it didn't, then try the next mode.\r
     //\r
@@ -935,49 +1430,64 @@ BiosVideoCheckForVbe (
     if (BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr == 0) {\r
       continue;\r
     }\r
+\r
+    if (EdidFound && (ValidEdidTiming.ValidNumber > 0)) {\r
+      //\r
+      // EDID exist, check whether this mode match with any mode in EDID\r
+      //\r
+      Timing.HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution;\r
+      Timing.VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution;\r
+      if (SearchEdidTiming (&ValidEdidTiming, &Timing) == FALSE) {\r
+        continue;\r
+      }\r
+    }\r
+\r
     //\r
-    // See if the resolution is 1024x768, 800x600, or 640x480\r
+    // Select a reasonable mode to be set for current display mode\r
     //\r
     ModeFound = FALSE;\r
+\r
     if (BiosVideoPrivate->VbeModeInformationBlock->XResolution == 1024 &&\r
         BiosVideoPrivate->VbeModeInformationBlock->YResolution == 768\r
         ) {\r
       ModeFound = TRUE;\r
     }\r
-\r
     if (BiosVideoPrivate->VbeModeInformationBlock->XResolution == 800 &&\r
         BiosVideoPrivate->VbeModeInformationBlock->YResolution == 600\r
         ) {\r
       ModeFound = TRUE;\r
+      PreferMode = ModeNumber;\r
     }\r
-\r
     if (BiosVideoPrivate->VbeModeInformationBlock->XResolution == 640 &&\r
         BiosVideoPrivate->VbeModeInformationBlock->YResolution == 480\r
         ) {\r
       ModeFound = TRUE;\r
     }\r
-\r
-    if (!ModeFound) {\r
+    if ((!EdidFound) && (!ModeFound)) {\r
+      //\r
+      // When no EDID exist, only select three possible resolutions, i.e. 1024x768, 800x600, 640x480\r
+      //\r
       continue;\r
     }\r
+\r
     //\r
     // Add mode to the list of available modes\r
     //\r
-    BiosVideoPrivate->MaxMode++;\r
+    ModeNumber ++;\r
     Status = gBS->AllocatePool (\r
                     EfiBootServicesData,\r
-                    BiosVideoPrivate->MaxMode * sizeof (BIOS_VIDEO_MODE_DATA),\r
+                    ModeNumber * sizeof (BIOS_VIDEO_MODE_DATA),\r
                     (VOID **) &ModeBuffer\r
                     );\r
     if (EFI_ERROR (Status)) {\r
       goto Done;\r
     }\r
 \r
-    if (BiosVideoPrivate->MaxMode > 1) {\r
+    if (ModeNumber > 1) {\r
       gBS->CopyMem (\r
             ModeBuffer,\r
             BiosVideoPrivate->ModeData,\r
-            (BiosVideoPrivate->MaxMode - 1) * sizeof (BIOS_VIDEO_MODE_DATA)\r
+            (ModeNumber - 1) * sizeof (BIOS_VIDEO_MODE_DATA)\r
             );\r
     }\r
 \r
@@ -985,70 +1495,107 @@ BiosVideoCheckForVbe (
       gBS->FreePool (BiosVideoPrivate->ModeData);\r
     }\r
 \r
-    ModeBuffer[BiosVideoPrivate->MaxMode - 1].VbeModeNumber = *ModeNumberPtr;\r
+    CurrentModeData = &ModeBuffer[ModeNumber - 1];\r
+    CurrentModeData->VbeModeNumber = *ModeNumberPtr;\r
     if (BiosVideoPrivate->VbeInformationBlock->VESAVersion >= VESA_BIOS_EXTENSIONS_VERSION_3_0) {\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->LinBytesPerScanLine;\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Red.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRedFieldPosition;\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRedMaskSize) - 1);\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->LinBlueFieldPosition;\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinBlueMaskSize) - 1);\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Green.Position = BiosVideoPrivate->VbeModeInformationBlock->LinGreenFieldPosition;\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinGreenMaskSize) - 1);\r
-\r
+      CurrentModeData->BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->LinBytesPerScanLine;\r
+      CurrentModeData->Red.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRedFieldPosition;\r
+      CurrentModeData->Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRedMaskSize) - 1);\r
+      CurrentModeData->Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->LinBlueFieldPosition;\r
+      CurrentModeData->Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinBlueMaskSize) - 1);\r
+      CurrentModeData->Green.Position = BiosVideoPrivate->VbeModeInformationBlock->LinGreenFieldPosition;\r
+      CurrentModeData->Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinGreenMaskSize) - 1);\r
+      CurrentModeData->Reserved.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRsvdFieldPosition;\r
+      CurrentModeData->Reserved.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRsvdMaskSize) - 1);\r
     } else {\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->BytesPerScanLine;\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Red.Position = BiosVideoPrivate->VbeModeInformationBlock->RedFieldPosition;\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RedMaskSize) - 1);\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->BlueFieldPosition;\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->BlueMaskSize) - 1);\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Green.Position = BiosVideoPrivate->VbeModeInformationBlock->GreenFieldPosition;\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->GreenMaskSize) - 1);\r
-\r
+      CurrentModeData->BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->BytesPerScanLine;\r
+      CurrentModeData->Red.Position = BiosVideoPrivate->VbeModeInformationBlock->RedFieldPosition;\r
+      CurrentModeData->Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RedMaskSize) - 1);\r
+      CurrentModeData->Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->BlueFieldPosition;\r
+      CurrentModeData->Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->BlueMaskSize) - 1);\r
+      CurrentModeData->Green.Position = BiosVideoPrivate->VbeModeInformationBlock->GreenFieldPosition;\r
+      CurrentModeData->Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->GreenMaskSize) - 1);\r
+      CurrentModeData->Reserved.Position = BiosVideoPrivate->VbeModeInformationBlock->RsvdFieldPosition;\r
+      CurrentModeData->Reserved.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RsvdMaskSize) - 1);\r
     }\r
-\r
-    ModeBuffer[BiosVideoPrivate->MaxMode - 1].LinearFrameBuffer = (VOID *) (UINTN)BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr;\r
-    ModeBuffer[BiosVideoPrivate->MaxMode - 1].HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution;\r
-    ModeBuffer[BiosVideoPrivate->MaxMode - 1].VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution;\r
-\r
-    if (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel >= 24) {\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].ColorDepth = 32;\r
-    } else {\r
-      ModeBuffer[BiosVideoPrivate->MaxMode - 1].ColorDepth = BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel;\r
+    CurrentModeData->PixelFormat = PixelBitMask;\r
+    if ((BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel == 32) &&\r
+        (CurrentModeData->Red.Mask == 0xff) && (CurrentModeData->Green.Mask == 0xff) && (CurrentModeData->Blue.Mask == 0xff)) {\r
+      if ((CurrentModeData->Red.Position == 0) && (CurrentModeData->Green.Position == 8) && (CurrentModeData->Blue.Position == 16)) {\r
+        CurrentModeData->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;\r
+      } else if ((CurrentModeData->Blue.Position == 0) && (CurrentModeData->Green.Position == 8) && (CurrentModeData->Red.Position == 16)) {\r
+        CurrentModeData->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\r
+      }\r
     }\r
+    CurrentModeData->PixelBitMask.RedMask = ((UINT32) CurrentModeData->Red.Mask) << CurrentModeData->Red.Position;\r
+    CurrentModeData->PixelBitMask.GreenMask = ((UINT32) CurrentModeData->Green.Mask) << CurrentModeData->Green.Position;\r
+    CurrentModeData->PixelBitMask.BlueMask = ((UINT32) CurrentModeData->Blue.Mask) << CurrentModeData->Blue.Position;\r
+    CurrentModeData->PixelBitMask.ReservedMask = ((UINT32) CurrentModeData->Reserved.Mask) << CurrentModeData->Reserved.Position;\r
 \r
-    ModeBuffer[BiosVideoPrivate->MaxMode - 1].BitsPerPixel  = BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel;\r
+    CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN)BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr;\r
+    CurrentModeData->FrameBufferSize = BiosVideoPrivate->VbeInformationBlock->TotalMemory * 64 * 1024;\r
+    CurrentModeData->HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution;\r
+    CurrentModeData->VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution;\r
 \r
-    ModeBuffer[BiosVideoPrivate->MaxMode - 1].RefreshRate   = 60;\r
+    CurrentModeData->BitsPerPixel  = BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel;\r
 \r
     BiosVideoPrivate->ModeData = ModeBuffer;\r
   }\r
   //\r
-  // Check to see if we found any modes that are compatible with UGA DRAW\r
+  // Check to see if we found any modes that are compatible with GRAPHICS OUTPUT\r
   //\r
-  if (BiosVideoPrivate->MaxMode == 0) {\r
+  if (ModeNumber == 0) {\r
     Status = EFI_DEVICE_ERROR;\r
     goto Done;\r
   }\r
+\r
+  //\r
+  // Allocate buffer for Graphics Output Protocol mode information\r
+  //\r
+  Status = gBS->AllocatePool (\r
+                EfiBootServicesData,\r
+                sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),\r
+                (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode\r
+                );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+  GraphicsOutputMode = BiosVideoPrivate->GraphicsOutput.Mode;\r
+  Status = gBS->AllocatePool (\r
+                EfiBootServicesData,\r
+                sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),\r
+                (VOID **) &GraphicsOutputMode->Info\r
+                );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  GraphicsOutputMode->MaxMode = (UINT32) ModeNumber;\r
+  //\r
+  // Current mode is unknow till now, set it to an invalid mode.\r
+  //\r
+  GraphicsOutputMode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;\r
+\r
   //\r
   // Find the best mode to initialize\r
   //\r
-  Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 1024, 768, 32, 60);\r
-  //Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 800, 600, 32, 60);\r
+  Status = BiosVideoGraphicsOutputSetMode (&BiosVideoPrivate->GraphicsOutput, (UINT32) PreferMode);\r
   if (EFI_ERROR (Status)) {\r
-    Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 800, 600, 32, 60);\r
-    //Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 1024, 768, 32, 60);\r
-    if (EFI_ERROR (Status)) {\r
-      Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 640, 480, 32, 60);\r
-      for (Index = 0; EFI_ERROR (Status) && Index < BiosVideoPrivate->MaxMode; Index++) {\r
-        Status = BiosVideoUgaDrawSetMode (\r
-                  &BiosVideoPrivate->UgaDraw,\r
-                  BiosVideoPrivate->ModeData[Index].HorizontalResolution,\r
-                  BiosVideoPrivate->ModeData[Index].VerticalResolution,\r
-                  BiosVideoPrivate->ModeData[Index].ColorDepth,\r
-                  BiosVideoPrivate->ModeData[Index].RefreshRate\r
-                  );\r
+    for (PreferMode = 0; PreferMode < ModeNumber; PreferMode ++) {\r
+      Status = BiosVideoGraphicsOutputSetMode (\r
+                &BiosVideoPrivate->GraphicsOutput,\r
+                (UINT32) PreferMode\r
+                );\r
+      if (!EFI_ERROR (Status)) {\r
+        break;\r
       }\r
     }\r
+    if (PreferMode == ModeNumber) {\r
+      //\r
+      // None mode is set successfully.\r
+      //\r
+      goto Done;\r
+    }\r
   }\r
 \r
 Done:\r
@@ -1058,8 +1605,12 @@ Done:
   if (EFI_ERROR (Status)) {\r
     if (BiosVideoPrivate->ModeData != NULL) {\r
       gBS->FreePool (BiosVideoPrivate->ModeData);\r
-      BiosVideoPrivate->ModeData  = NULL;\r
-      BiosVideoPrivate->MaxMode   = 0;\r
+    }\r
+    if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) {\r
+      if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) {\r
+        gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info);\r
+      }\r
+      gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode);\r
     }\r
   }\r
 \r
@@ -1067,295 +1618,324 @@ Done:
 }\r
 \r
 EFI_STATUS\r
+EFIAPI\r
 BiosVideoCheckForVga (\r
-  IN OUT BIOS_VIDEO_DEV  *BiosVideoPrivate  \r
+  IN OUT BIOS_VIDEO_DEV  *BiosVideoPrivate\r
   )\r
 /*++\r
-  \r
+\r
   Routine Description:\r
 \r
     Check for VGA device\r
-  \r
+\r
   Arguments:\r
-  \r
+\r
     BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure\r
-  \r
+\r
   Returns:\r
-  \r
+\r
     EFI_SUCCESS - Standard VGA device found\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS            Status;\r
   BIOS_VIDEO_MODE_DATA  *ModeBuffer;\r
+  \r
+  //\r
+  // Fill in the Graphics Output Protocol\r
+  //\r
+  BiosVideoPrivate->GraphicsOutput.QueryMode = BiosVideoGraphicsOutputQueryMode;\r
+  BiosVideoPrivate->GraphicsOutput.SetMode = BiosVideoGraphicsOutputSetMode;\r
+  BiosVideoPrivate->GraphicsOutput.Blt     = BiosVideoGraphicsOutputVgaBlt;\r
 \r
   //\r
-  // Fill in the UGA Draw Protocol\r
+  // Allocate buffer for Graphics Output Protocol mode information\r
   //\r
-  BiosVideoPrivate->UgaDraw.GetMode = BiosVideoUgaDrawGetMode;\r
-  BiosVideoPrivate->UgaDraw.SetMode = BiosVideoUgaDrawSetMode;\r
-  BiosVideoPrivate->UgaDraw.Blt     = BiosVideoUgaDrawVgaBlt;\r
+  Status = gBS->AllocatePool (\r
+                EfiBootServicesData,\r
+                sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),\r
+                (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode\r
+                );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+  Status = gBS->AllocatePool (\r
+                EfiBootServicesData,\r
+                sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),\r
+                (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode->Info\r
+                );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
 \r
   //\r
   // Add mode to the list of available modes\r
   //\r
-  BiosVideoPrivate->MaxMode++;\r
+  BiosVideoPrivate->GraphicsOutput.Mode->MaxMode = 1;\r
+\r
   Status = gBS->AllocatePool (\r
                   EfiBootServicesData,\r
-                  BiosVideoPrivate->MaxMode * sizeof (BIOS_VIDEO_MODE_DATA),\r
+                  sizeof (BIOS_VIDEO_MODE_DATA),\r
                   (VOID **) &ModeBuffer\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  if (BiosVideoPrivate->MaxMode > 1) {\r
-    gBS->CopyMem (\r
-          ModeBuffer,\r
-          BiosVideoPrivate->ModeData,\r
-          (BiosVideoPrivate->MaxMode - 1) * sizeof (BIOS_VIDEO_MODE_DATA)\r
-          );\r
-  }\r
-\r
-  if (BiosVideoPrivate->ModeData != NULL) {\r
-    gBS->FreePool (BiosVideoPrivate->ModeData);\r
+    goto Done;\r
   }\r
 \r
-  ModeBuffer[BiosVideoPrivate->MaxMode - 1].VbeModeNumber         = 0x0012;\r
-  ModeBuffer[BiosVideoPrivate->MaxMode - 1].BytesPerScanLine      = 640;\r
-  ModeBuffer[BiosVideoPrivate->MaxMode - 1].LinearFrameBuffer     = (VOID *) (UINTN)(0xa0000);\r
-  ModeBuffer[BiosVideoPrivate->MaxMode - 1].HorizontalResolution  = 640;\r
-  ModeBuffer[BiosVideoPrivate->MaxMode - 1].VerticalResolution    = 480;\r
-  ModeBuffer[BiosVideoPrivate->MaxMode - 1].ColorDepth            = 32;\r
-  ModeBuffer[BiosVideoPrivate->MaxMode - 1].RefreshRate           = 60;\r
+  ModeBuffer->VbeModeNumber         = 0x0012;\r
+  ModeBuffer->BytesPerScanLine      = 640;\r
+  ModeBuffer->LinearFrameBuffer     = (VOID *) (UINTN) (0xa0000);\r
+  ModeBuffer->FrameBufferSize       = 0;\r
+  ModeBuffer->HorizontalResolution  = 640;\r
+  ModeBuffer->VerticalResolution    = 480;\r
+  ModeBuffer->BitsPerPixel          = 8;  \r
+  ModeBuffer->PixelFormat           = PixelBltOnly;\r
 \r
   BiosVideoPrivate->ModeData = ModeBuffer;\r
 \r
   //\r
   // Test to see if the Video Adapter support the 640x480 16 color mode\r
   //\r
-  Status = BiosVideoUgaDrawSetMode (&BiosVideoPrivate->UgaDraw, 640, 480, 32, 60);\r
+  BiosVideoPrivate->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;\r
+  Status = BiosVideoGraphicsOutputSetMode (&BiosVideoPrivate->GraphicsOutput, 0);\r
 \r
+Done:\r
   //\r
   // If there was an error, then free the mode structure\r
   //\r
   if (EFI_ERROR (Status)) {\r
-    BiosVideoPrivate->MaxMode = 0;\r
     if (BiosVideoPrivate->ModeData != NULL) {\r
       gBS->FreePool (BiosVideoPrivate->ModeData);\r
     }\r
+    if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) {\r
+      if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) {\r
+        gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info);\r
+      }\r
+      gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode);\r
+    }\r
   }\r
-\r
   return Status;\r
 }\r
 //\r
-// UGA Protocol Member Functions for VESA BIOS Extensions\r
+// Graphics Output Protocol Member Functions for VESA BIOS Extensions\r
 //\r
 EFI_STATUS\r
 EFIAPI\r
-BiosVideoUgaDrawGetMode (\r
-  IN  EFI_UGA_DRAW_PROTOCOL  *This,\r
-  OUT UINT32                 *HorizontalResolution,\r
-  OUT UINT32                 *VerticalResolution,\r
-  OUT UINT32                 *ColorDepth,\r
-  OUT UINT32                 *RefreshRate\r
+BiosVideoGraphicsOutputQueryMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,\r
+  IN  UINT32                                ModeNumber,\r
+  OUT UINTN                                 *SizeOfInfo,\r
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  UGA protocol interface to get video mode\r
-\r
-Arguments:\r
-\r
-  This                  - Pointer to UGA draw protocol instance\r
-  HorizontalResolution  - Horizontal Resolution, in pixels\r
-  VerticalResolution    - Vertical Resolution, in pixels\r
-  ColorDepth            - Bit number used to represent color value of a pixel \r
-  RefreshRate           - Refresh rate, in Hertz\r
+  Graphics Output protocol interface to get video mode\r
 \r
-Returns:\r
+  Arguments:\r
+    This                  - Protocol instance pointer.\r
+    ModeNumber            - The mode number to return information on.\r
+    Info                  - Caller allocated buffer that returns information about ModeNumber.\r
+    SizeOfInfo            - A pointer to the size, in bytes, of the Info buffer.\r
 \r
-  EFI_DEVICE_ERROR - Hardware need starting\r
-  EFI_INVALID_PARAMETER - Invalid parameter passed in\r
-  EFI_SUCCESS - Video mode query successfully\r
+  Returns:\r
+    EFI_SUCCESS           - Mode information returned.\r
+    EFI_DEVICE_ERROR      - A hardware error occurred trying to retrieve the video mode.\r
+    EFI_NOT_STARTED       - Video display is not initialized. Call SetMode ()\r
+    EFI_INVALID_PARAMETER - One of the input args was NULL.\r
 \r
 --*/\r
 {\r
-  BIOS_VIDEO_DEV  *BiosVideoPrivate;\r
+  BIOS_VIDEO_DEV        *BiosVideoPrivate;\r
+  EFI_STATUS            Status;\r
+  BIOS_VIDEO_MODE_DATA  *ModeData;\r
 \r
-  BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
+  BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
 \r
   if (BiosVideoPrivate->HardwareNeedsStarting) {\r
-    return EFI_DEVICE_ERROR;\r
+    return EFI_NOT_STARTED;\r
   }\r
 \r
-  if (HorizontalResolution == NULL || VerticalResolution == NULL || ColorDepth == NULL || RefreshRate == NULL) {\r
+  if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  *HorizontalResolution = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].HorizontalResolution;\r
-  *VerticalResolution   = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].VerticalResolution;\r
-  *ColorDepth           = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].ColorDepth;\r
-  *RefreshRate          = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].RefreshRate;\r
+  Status = gBS->AllocatePool (\r
+                  EfiBootServicesData,\r
+                  sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),\r
+                  Info\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+\r
+  ModeData = &BiosVideoPrivate->ModeData[ModeNumber];\r
+  (*Info)->Version = 0;\r
+  (*Info)->HorizontalResolution = ModeData->HorizontalResolution;\r
+  (*Info)->VerticalResolution   = ModeData->VerticalResolution;\r
+  (*Info)->PixelFormat = ModeData->PixelFormat;\r
+  (*Info)->PixelInformation = ModeData->PixelBitMask;\r
+\r
+  (*Info)->PixelsPerScanLine =  (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
 EFI_STATUS\r
 EFIAPI\r
-BiosVideoUgaDrawSetMode (\r
-  IN  EFI_UGA_DRAW_PROTOCOL  *This,\r
-  IN  UINT32                 HorizontalResolution,\r
-  IN  UINT32                 VerticalResolution,\r
-  IN  UINT32                 ColorDepth,\r
-  IN  UINT32                 RefreshRate\r
+BiosVideoGraphicsOutputSetMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL * This,\r
+  IN  UINT32                       ModeNumber\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  UGA draw protocol interface to set video mode\r
-\r
-Arguments:\r
-\r
-  This                  - Pointer to UGA draw protocol instance\r
-  HorizontalResolution  - Horizontal Resolution, in pixels\r
-  VerticalResolution    - Vertical Resolution, in pixels\r
-  ColorDepth            - Bit number used to represent color value of a pixel \r
-  RefreshRate           - Refresh rate, in Hertz\r
+  Graphics Output protocol interface to set video mode\r
 \r
-Returns:\r
+  Arguments:\r
+    This             - Protocol instance pointer.\r
+    ModeNumber       - The mode number to be set.\r
 \r
-  EFI_DEVICE_ERROR - Device error\r
-  EFI_SUCCESS - Video mode set successfully\r
-  EFI_UNSUPPORTED - Cannot support this video mode\r
+  Returns:\r
+    EFI_SUCCESS      - Graphics mode was changed.\r
+    EFI_DEVICE_ERROR - The device had an error and could not complete the request.\r
+    EFI_UNSUPPORTED  - ModeNumber is not supported by this device.\r
 \r
 --*/\r
 {\r
-  EFI_STATUS            Status;\r
-  BIOS_VIDEO_DEV        *BiosVideoPrivate;\r
-  UINTN                 Index;\r
-  EFI_IA32_REGISTER_SET Regs;\r
+  EFI_STATUS              Status;\r
+  BIOS_VIDEO_DEV          *BiosVideoPrivate;\r
+  EFI_IA32_REGISTER_SET   Regs;\r
+  BIOS_VIDEO_MODE_DATA    *ModeData;\r
 \r
-  BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
+  BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
 \r
-  for (Index = 0; Index < BiosVideoPrivate->MaxMode; Index++) {\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
-    if (HorizontalResolution != BiosVideoPrivate->ModeData[Index].HorizontalResolution) {\r
-      continue;\r
-    }\r
+  if (ModeNumber >= This->Mode->MaxMode) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
 \r
-    if (VerticalResolution != BiosVideoPrivate->ModeData[Index].VerticalResolution) {\r
-      continue;\r
-    }\r
+  if (ModeNumber == This->Mode->Mode) {\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
-    if (ColorDepth != BiosVideoPrivate->ModeData[Index].ColorDepth) {\r
-      continue;\r
-    }\r
+  ModeData = &BiosVideoPrivate->ModeData[ModeNumber];\r
 \r
-    if (RefreshRate != BiosVideoPrivate->ModeData[Index].RefreshRate) {\r
-      continue;\r
-    }\r
+  if (BiosVideoPrivate->LineBuffer) {\r
+    gBS->FreePool (BiosVideoPrivate->LineBuffer);\r
+  }\r
 \r
-    if (BiosVideoPrivate->LineBuffer) {\r
-      gBS->FreePool (BiosVideoPrivate->LineBuffer);\r
-    }\r
+  if (BiosVideoPrivate->VgaFrameBuffer) {\r
+    gBS->FreePool (BiosVideoPrivate->VgaFrameBuffer);\r
+  }\r
 \r
-    if (BiosVideoPrivate->VgaFrameBuffer) {\r
-      gBS->FreePool (BiosVideoPrivate->VgaFrameBuffer);\r
-    }\r
+  if (BiosVideoPrivate->VbeFrameBuffer) {\r
+    gBS->FreePool (BiosVideoPrivate->VbeFrameBuffer);\r
+  }\r
 \r
-    if (BiosVideoPrivate->VbeFrameBuffer) {\r
-      gBS->FreePool (BiosVideoPrivate->VbeFrameBuffer);\r
-    }\r
+  BiosVideoPrivate->LineBuffer = NULL;\r
+  Status = gBS->AllocatePool (\r
+                  EfiBootServicesData,\r
+                  ModeData->BytesPerScanLine,\r
+                  &BiosVideoPrivate->LineBuffer\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Clear all registers\r
+  //\r
+  gBS->SetMem (&Regs, sizeof (Regs), 0);\r
 \r
-    BiosVideoPrivate->LineBuffer = NULL;\r
+  if (ModeData->VbeModeNumber < 0x100) {\r
+    //\r
+    // Allocate a working buffer for BLT operations to the VGA frame buffer\r
+    //\r
+    BiosVideoPrivate->VgaFrameBuffer = NULL;\r
     Status = gBS->AllocatePool (\r
                     EfiBootServicesData,\r
-                    BiosVideoPrivate->ModeData[Index].BytesPerScanLine,\r
-                    (VOID**)&BiosVideoPrivate->LineBuffer\r
+                    4 * 480 * 80,\r
+                    &BiosVideoPrivate->VgaFrameBuffer\r
                     );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
     //\r
-    // Clear all registers\r
+    // Set VGA Mode\r
     //\r
-    gBS->SetMem (&Regs, sizeof (Regs), 0);\r
-\r
-    if (BiosVideoPrivate->ModeData[Index].VbeModeNumber < 0x100) {\r
-      //\r
-      // Allocate a working buffer for BLT operations to the VGA frame buffer\r
-      //\r
-      BiosVideoPrivate->VgaFrameBuffer = NULL;\r
-      Status = gBS->AllocatePool (\r
-                      EfiBootServicesData,\r
-                      4 * 480 * 80,\r
-                      (VOID**)&BiosVideoPrivate->VgaFrameBuffer\r
-                      );\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-      //\r
-      // Set VGA Mode\r
-      //\r
-      Regs.X.AX = BiosVideoPrivate->ModeData[Index].VbeModeNumber;\r
-      LegacyBiosInt86 (0x10, &Regs);\r
-\r
-    } else {\r
-      //\r
-      // Allocate a working buffer for BLT operations to the VBE frame buffer\r
-      //\r
-      BiosVideoPrivate->VbeFrameBuffer = NULL;\r
-      Status = gBS->AllocatePool (\r
-                      EfiBootServicesData,\r
-                      BiosVideoPrivate->ModeData[Index].BytesPerScanLine * BiosVideoPrivate->ModeData[Index].VerticalResolution,\r
-                      (VOID**)&BiosVideoPrivate->VbeFrameBuffer\r
-                      );\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-      //\r
-      // Set VBE mode\r
-      //\r
-      Regs.X.AX = VESA_BIOS_EXTENSIONS_SET_MODE;\r
-      Regs.X.BX = (UINT16) (BiosVideoPrivate->ModeData[Index].VbeModeNumber | VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER);\r
-      gBS->SetMem (BiosVideoPrivate->VbeCrtcInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK), 0);\r
-      Regs.X.ES = EFI_SEGMENT ((UINTN)BiosVideoPrivate->VbeCrtcInformationBlock);\r
-      Regs.X.DI = EFI_OFFSET ((UINTN)BiosVideoPrivate->VbeCrtcInformationBlock);\r
-      LegacyBiosInt86 (0x10, &Regs);\r
+    Regs.X.AX = ModeData->VbeModeNumber;\r
+    LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
 \r
-      //\r
-      // Check to see if the call succeeded\r
-      //\r
-      if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {\r
-        return EFI_DEVICE_ERROR;\r
-      }\r
-      //\r
-      // Initialize the state of the VbeFrameBuffer\r
-      //\r
-      Status = BiosVideoPrivate->PciIo->Mem.Read (\r
-                                              BiosVideoPrivate->PciIo,\r
-                                              EfiPciIoWidthUint32,\r
-                                              EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                                              (UINT64) (UINTN) BiosVideoPrivate->ModeData[Index].LinearFrameBuffer,\r
-                                              (BiosVideoPrivate->ModeData[Index].BytesPerScanLine * BiosVideoPrivate->ModeData[Index].VerticalResolution) >> 2,\r
-                                              BiosVideoPrivate->VbeFrameBuffer\r
-                                              );\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
+  } else {\r
+    //\r
+    // Allocate a working buffer for BLT operations to the VBE frame buffer\r
+    //\r
+    BiosVideoPrivate->VbeFrameBuffer = NULL;\r
+    Status = gBS->AllocatePool (\r
+                    EfiBootServicesData,\r
+                    ModeData->BytesPerScanLine * ModeData->VerticalResolution,\r
+                    &BiosVideoPrivate->VbeFrameBuffer\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    //\r
+    // Set VBE mode\r
+    //\r
+    Regs.X.AX = VESA_BIOS_EXTENSIONS_SET_MODE;\r
+    Regs.X.BX = (UINT16) (ModeData->VbeModeNumber | VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER);\r
+    gBS->SetMem (BiosVideoPrivate->VbeCrtcInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK), 0);\r
+    Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeCrtcInformationBlock);\r
+    Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeCrtcInformationBlock);\r
+    LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+    \r
+    //\r
+    // Check to see if the call succeeded\r
+    //\r
+    if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+    //\r
+    // Initialize the state of the VbeFrameBuffer\r
+    //\r
+    Status = BiosVideoPrivate->PciIo->Mem.Read (\r
+                                            BiosVideoPrivate->PciIo,\r
+                                            EfiPciIoWidthUint32,\r
+                                            EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                                            (UINT64) (UINTN) ModeData->LinearFrameBuffer,\r
+                                            (ModeData->BytesPerScanLine * ModeData->VerticalResolution) >> 2,\r
+                                            BiosVideoPrivate->VbeFrameBuffer\r
+                                            );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
     }\r
+  }\r
 \r
-    BiosVideoPrivate->CurrentMode           = Index;\r
+  This->Mode->Mode = ModeNumber;\r
+  This->Mode->Info->Version = 0;\r
+  This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
+  This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
+  This->Mode->Info->PixelFormat = ModeData->PixelFormat;\r
+  This->Mode->Info->PixelInformation = ModeData->PixelBitMask;\r
+  This->Mode->Info->PixelsPerScanLine =  (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel;\r
+  This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
 \r
-    BiosVideoPrivate->HardwareNeedsStarting = FALSE;\r
+  //\r
+  // Frame BufferSize remain unchanged\r
+  //\r
+  This->Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) ModeData->LinearFrameBuffer;\r
+  This->Mode->FrameBufferSize = ModeData->FrameBufferSize;\r
 \r
-    return EFI_SUCCESS;\r
-  }\r
+  BiosVideoPrivate->HardwareNeedsStarting = FALSE;\r
 \r
-  return EFI_UNSUPPORTED;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 VOID\r
@@ -1476,27 +2056,27 @@ Returns:
 //\r
 EFI_STATUS\r
 EFIAPI\r
-BiosVideoUgaDrawVbeBlt (\r
-  IN  EFI_UGA_DRAW_PROTOCOL  *This,\r
-  IN  EFI_UGA_PIXEL          *BltBuffer, OPTIONAL\r
-  IN  EFI_UGA_BLT_OPERATION  BltOperation,\r
-  IN  UINTN                  SourceX,\r
-  IN  UINTN                  SourceY,\r
-  IN  UINTN                  DestinationX,\r
-  IN  UINTN                  DestinationY,\r
-  IN  UINTN                  Width,\r
-  IN  UINTN                  Height,\r
-  IN  UINTN                  Delta\r
+BiosVideoGraphicsOutputVbeBlt (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL       *This,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer, OPTIONAL\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION  BltOperation,\r
+  IN  UINTN                              SourceX,\r
+  IN  UINTN                              SourceY,\r
+  IN  UINTN                              DestinationX,\r
+  IN  UINTN                              DestinationY,\r
+  IN  UINTN                              Width,\r
+  IN  UINTN                              Height,\r
+  IN  UINTN                              Delta\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  UGA draw protocol instance to block transfer for VBE device\r
+  Graphics Output protocol instance to block transfer for VBE device\r
 \r
 Arguments:\r
 \r
-  This          - Pointer to UGA draw protocol instance\r
+  This          - Pointer to Graphics Output protocol instance\r
   BltBuffer     - The data to transfer to screen\r
   BltOperation  - The operation to perform\r
   SourceX       - The X coordinate of the source for BltOperation\r
@@ -1505,9 +2085,9 @@ Arguments:
   DestinationY  - The Y coordinate of the destination for BltOperation\r
   Width         - The width of a rectangle in the blt rectangle in pixels\r
   Height        - The height of a rectangle in the blt rectangle in pixels\r
-  Delta         - Not used for EfiUgaVideoFill and EfiUgaVideoToVideo operation.\r
+  Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.\r
                   If a Delta of 0 is used, the entire BltBuffer will be operated on.\r
-                  If a subrectangle of the BltBuffer is used, then Delta represents \r
+                  If a subrectangle of the BltBuffer is used, then Delta represents\r
                   the number of bytes in a row of the BltBuffer.\r
 \r
 Returns:\r
@@ -1517,27 +2097,27 @@ Returns:
 \r
 --*/\r
 {\r
-  BIOS_VIDEO_DEV        *BiosVideoPrivate;\r
-  BIOS_VIDEO_MODE_DATA  *Mode;\r
-  EFI_PCI_IO_PROTOCOL   *PciIo;\r
-  EFI_TPL               OriginalTPL;\r
-  UINTN                 DstY;\r
-  UINTN                 SrcY;\r
-  UINTN                 DstX;\r
-  EFI_UGA_PIXEL         *Blt;\r
-  VOID                  *MemAddress;\r
-  EFI_UGA_PIXEL         *VbeFrameBuffer;\r
-  UINTN                 BytesPerScanLine;\r
-  UINTN                 Index;\r
-  UINT8                 *VbeBuffer;\r
-  UINT8                 *VbeBuffer1;\r
-  UINT8                 *BltUint8;\r
-  UINT32                VbePixelWidth;\r
-  UINT32                Pixel;\r
-  UINTN                 TotalBytes;\r
-\r
-  BiosVideoPrivate  = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
-  Mode              = &BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode];\r
+  BIOS_VIDEO_DEV                 *BiosVideoPrivate;\r
+  BIOS_VIDEO_MODE_DATA           *Mode;\r
+  EFI_PCI_IO_PROTOCOL            *PciIo;\r
+  EFI_TPL                        OriginalTPL;\r
+  UINTN                          DstY;\r
+  UINTN                          SrcY;\r
+  UINTN                          DstX;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Blt;\r
+  VOID                           *MemAddress;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *VbeFrameBuffer;\r
+  UINTN                          BytesPerScanLine;\r
+  UINTN                          Index;\r
+  UINT8                          *VbeBuffer;\r
+  UINT8                          *VbeBuffer1;\r
+  UINT8                          *BltUint8;\r
+  UINT32                         VbePixelWidth;\r
+  UINT32                         Pixel;\r
+  UINTN                          TotalBytes;\r
+\r
+  BiosVideoPrivate  = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
+  Mode              = &BiosVideoPrivate->ModeData[This->Mode->Mode];\r
   PciIo             = BiosVideoPrivate->PciIo;\r
 \r
   VbeFrameBuffer    = BiosVideoPrivate->VbeFrameBuffer;\r
@@ -1547,7 +2127,7 @@ Returns:
   BltUint8          = (UINT8 *) BltBuffer;\r
   TotalBytes        = Width * VbePixelWidth;\r
 \r
-  if ((BltOperation < EfiUgaVideoFill) || (BltOperation >= EfiUgaBltMax)) {\r
+  if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1559,7 +2139,7 @@ Returns:
   // The virtual screen is upside down, as the first row is the bootom row of\r
   // the image.\r
   //\r
-  if (BltOperation == EfiUgaVideoToBltBuffer) {\r
+  if (BltOperation == EfiBltVideoToBltBuffer) {\r
     //\r
     // Video to BltBuffer: Source is Video, destination is BltBuffer\r
     //\r
@@ -1588,7 +2168,7 @@ Returns:
   // the number of bytes in each row can be computed.\r
   //\r
   if (Delta == 0) {\r
-    Delta = Width * sizeof (EFI_UGA_PIXEL);\r
+    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
   }\r
   //\r
   // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
@@ -1598,11 +2178,11 @@ Returns:
   OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
 \r
   switch (BltOperation) {\r
-  case EfiUgaVideoToBltBuffer:\r
+  case EfiBltVideoToBltBuffer:\r
     for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {\r
-      Blt = (EFI_UGA_PIXEL *) (BltUint8 + DstY * Delta + DestinationX * sizeof (EFI_UGA_PIXEL));\r
+      Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + DstY * Delta + DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
       //\r
-      // Shuffle the packed bytes in the hardware buffer to match EFI_UGA_PIXEL\r
+      // Shuffle the packed bytes in the hardware buffer to match EFI_GRAPHICS_OUTPUT_BLT_PIXEL\r
       //\r
       VbeBuffer = ((UINT8 *) VbeFrameBuffer + (SrcY * BytesPerScanLine + SourceX * VbePixelWidth));\r
       for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {\r
@@ -1618,7 +2198,7 @@ Returns:
     }\r
     break;\r
 \r
-  case EfiUgaVideoToVideo:\r
+  case EfiBltVideoToVideo:\r
     for (Index = 0; Index < Height; Index++) {\r
       if (DestinationY <= SourceY) {\r
         SrcY  = SourceY + Index;\r
@@ -1653,11 +2233,11 @@ Returns:
     }\r
     break;\r
 \r
-  case EfiUgaVideoFill:\r
+  case EfiBltVideoFill:\r
     VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth);\r
-    Blt       = (EFI_UGA_PIXEL *) BltUint8;\r
+    Blt       = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltUint8;\r
     //\r
-    // Shuffle the RGB fields in EFI_UGA_PIXEL to match the hardware buffer\r
+    // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer\r
     //\r
     Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |\r
       (\r
@@ -1698,16 +2278,15 @@ Returns:
         BytesPerScanLine\r
         );\r
     }\r
-\r
     break;\r
 \r
-  case EfiUgaBltBufferToVideo:\r
+  case EfiBltBufferToVideo:\r
     for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {\r
-      Blt       = (EFI_UGA_PIXEL *) (BltUint8 + (SrcY * Delta) + (SourceX) * sizeof (EFI_UGA_PIXEL));\r
+      Blt       = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + (SrcY * Delta) + (SourceX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
       VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth));\r
       for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {\r
         //\r
-        // Shuffle the RGB fields in EFI_UGA_PIXEL to match the hardware buffer\r
+        // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer\r
         //\r
         Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |\r
           ((Blt->Green & Mode->Green.Mask) << Mode->Green.Position) |\r
@@ -1738,8 +2317,6 @@ Returns:
         );\r
     }\r
     break;\r
-  default:\r
-    break;\r
   }\r
 \r
   gBS->RestoreTPL (OriginalTPL);\r
@@ -1847,7 +2424,7 @@ Returns:
                   PciIo,\r
                   EfiPciIoWidthUint8,\r
                   EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                  (UINT64) (UINTN)Source,\r
+                  (UINT64) Source,\r
                   WidthInBytes,\r
                   (VOID *) Destination\r
                   );\r
@@ -1856,24 +2433,24 @@ Returns:
 }\r
 \r
 VOID\r
-VgaConvertToUgaColor (\r
-  UINT8          *MemoryBuffer,\r
-  UINTN          X,\r
-  UINTN          Y,\r
-  EFI_UGA_PIXEL  *BltBuffer\r
+VgaConvertToGraphicsOutputColor (\r
+  UINT8                          *MemoryBuffer,\r
+  UINTN                          X,\r
+  UINTN                          Y,\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  Internal routine to convert VGA color to UGA color\r
+  Internal routine to convert VGA color to Grahpics Output color\r
 \r
 Arguments:\r
 \r
   MemoryBuffer  - Buffer containing VGA color\r
   X             - The X coordinate of pixel on screen\r
   Y             - The Y coordinate of pixel on screen\r
-  BltBuffer     - Buffer to contain converted UGA color\r
+  BltBuffer     - Buffer to contain converted Grahpics Output color\r
 \r
 Returns:\r
 \r
@@ -1893,22 +2470,22 @@ Returns:
     }\r
   }\r
 \r
-  *BltBuffer = mVgaColorToUgaColor[Color];\r
+  *BltBuffer = mVgaColorToGraphicsOutputColor[Color];\r
 }\r
 \r
 UINT8\r
 VgaConvertColor (\r
-  IN  EFI_UGA_PIXEL          *BltBuffer\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL          *BltBuffer\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  Internal routine to convert UGA color to VGA color\r
+  Internal routine to convert Grahpics Output color to VGA color\r
 \r
 Arguments:\r
 \r
-  BltBuffer - buffer containing UGA color\r
+  BltBuffer - buffer containing Grahpics Output color\r
 \r
 Returns:\r
 \r
@@ -1928,27 +2505,27 @@ Returns:
 \r
 EFI_STATUS\r
 EFIAPI\r
-BiosVideoUgaDrawVgaBlt (\r
-  IN  EFI_UGA_DRAW_PROTOCOL  *This,\r
-  IN  EFI_UGA_PIXEL          *BltBuffer, OPTIONAL\r
-  IN  EFI_UGA_BLT_OPERATION  BltOperation,\r
-  IN  UINTN                  SourceX,\r
-  IN  UINTN                  SourceY,\r
-  IN  UINTN                  DestinationX,\r
-  IN  UINTN                  DestinationY,\r
-  IN  UINTN                  Width,\r
-  IN  UINTN                  Height,\r
-  IN  UINTN                  Delta\r
+BiosVideoGraphicsOutputVgaBlt (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL       *This,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer, OPTIONAL\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION  BltOperation,\r
+  IN  UINTN                              SourceX,\r
+  IN  UINTN                              SourceY,\r
+  IN  UINTN                              DestinationX,\r
+  IN  UINTN                              DestinationY,\r
+  IN  UINTN                              Width,\r
+  IN  UINTN                              Height,\r
+  IN  UINTN                              Delta\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  UGA draw protocol instance to block transfer for VGA device\r
+  Grahpics Output protocol instance to block transfer for VGA device\r
 \r
 Arguments:\r
 \r
-  This          - Pointer to UGA draw protocol instance\r
+  This          - Pointer to Grahpics Output protocol instance\r
   BltBuffer     - The data to transfer to screen\r
   BltOperation  - The operation to perform\r
   SourceX       - The X coordinate of the source for BltOperation\r
@@ -1957,9 +2534,9 @@ Arguments:
   DestinationY  - The Y coordinate of the destination for BltOperation\r
   Width         - The width of a rectangle in the blt rectangle in pixels\r
   Height        - The height of a rectangle in the blt rectangle in pixels\r
-  Delta         - Not used for EfiUgaVideoFill and EfiUgaVideoToVideo operation.\r
+  Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.\r
                   If a Delta of 0 is used, the entire BltBuffer will be operated on.\r
-                  If a subrectangle of the BltBuffer is used, then Delta represents \r
+                  If a subrectangle of the BltBuffer is used, then Delta represents\r
                   the number of bytes in a row of the BltBuffer.\r
 \r
 Returns:\r
@@ -1997,16 +2574,18 @@ Returns:
   UINTN               Columns;\r
   UINTN               X;\r
   UINTN               Y;\r
+  UINTN               CurrentMode;\r
 \r
-  BiosVideoPrivate  = BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS (This);\r
+  BiosVideoPrivate  = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
 \r
+  CurrentMode = This->Mode->Mode;\r
   PciIo             = BiosVideoPrivate->PciIo;\r
-  MemAddress        = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].LinearFrameBuffer;\r
-  BytesPerScanLine  = BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].BytesPerScanLine >> 3;\r
-  BytesPerBitPlane  = BytesPerScanLine * BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].VerticalResolution;\r
+  MemAddress        = BiosVideoPrivate->ModeData[CurrentMode].LinearFrameBuffer;\r
+  BytesPerScanLine  = BiosVideoPrivate->ModeData[CurrentMode].BytesPerScanLine >> 3;\r
+  BytesPerBitPlane  = BytesPerScanLine * BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution;\r
   VgaFrameBuffer    = BiosVideoPrivate->VgaFrameBuffer;\r
 \r
-  if ((BltOperation < EfiUgaVideoFill) || (BltOperation >= EfiUgaBltMax)) {\r
+  if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -2018,26 +2597,26 @@ Returns:
   // The virtual screen is upside down, as the first row is the bootom row of\r
   // the image.\r
   //\r
-  if (BltOperation == EfiUgaVideoToBltBuffer) {\r
+  if (BltOperation == EfiBltVideoToBltBuffer) {\r
     //\r
     // Video to BltBuffer: Source is Video, destination is BltBuffer\r
     //\r
-    if (SourceY + Height > BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].VerticalResolution) {\r
+    if (SourceY + Height > BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
 \r
-    if (SourceX + Width > BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].HorizontalResolution) {\r
+    if (SourceX + Width > BiosVideoPrivate->ModeData[CurrentMode].HorizontalResolution) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   } else {\r
     //\r
     // BltBuffer to Video: Source is BltBuffer, destination is Video\r
     //\r
-    if (DestinationY + Height > BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].VerticalResolution) {\r
+    if (DestinationY + Height > BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
 \r
-    if (DestinationX + Width > BiosVideoPrivate->ModeData[BiosVideoPrivate->CurrentMode].HorizontalResolution) {\r
+    if (DestinationX + Width > BiosVideoPrivate->ModeData[CurrentMode].HorizontalResolution) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
@@ -2047,7 +2626,7 @@ Returns:
   // the number of bytes in each row can be computed.\r
   //\r
   if (Delta == 0) {\r
-    Delta = Width * sizeof (EFI_UGA_PIXEL);\r
+    Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
   }\r
   //\r
   // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
@@ -2060,7 +2639,7 @@ Returns:
   // Compute some values we need for VGA\r
   //\r
   switch (BltOperation) {\r
-  case EfiUgaVideoToBltBuffer:\r
+  case EfiBltVideoToBltBuffer:\r
 \r
     SourceOffset  = (SourceY << 6) + (SourceY << 4) + (SourceX >> 3);\r
     SourceWidth   = ((SourceX + Width - 1) >> 3) - (SourceX >> 3) + 1;\r
@@ -2077,12 +2656,12 @@ Returns:
       );\r
 \r
     //\r
-    // Convert VGA Bit Planes to a UGA 32-bit color value\r
+    // Convert VGA Bit Planes to a Graphics Output 32-bit color value\r
     //\r
     BltBuffer += (DestinationY * (Delta >> 2) + DestinationX);\r
     for (Rows = 0, Y = SourceY; Rows < Height; Rows++, Y++, BltBuffer += (Delta >> 2)) {\r
       for (Columns = 0, X = SourceX; Columns < Width; Columns++, X++, BltBuffer++) {\r
-        VgaConvertToUgaColor (VgaFrameBuffer, X, Y, BltBuffer);\r
+        VgaConvertToGraphicsOutputColor (VgaFrameBuffer, X, Y, BltBuffer);\r
       }\r
 \r
       BltBuffer -= Width;\r
@@ -2090,7 +2669,7 @@ Returns:
 \r
     break;\r
 \r
-  case EfiUgaVideoToVideo:\r
+  case EfiBltVideoToVideo:\r
     //\r
     // Check for an aligned Video to Video operation\r
     //\r
@@ -2099,7 +2678,7 @@ Returns:
       // Program the Mode Register Write mode 1, Read mode 0\r
       //\r
       WriteGraphicsController (\r
-        BiosVideoPrivate->PciIo,\r
+        PciIo,\r
         VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,\r
         VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_1\r
         );\r
@@ -2112,9 +2691,9 @@ Returns:
                 PciIo,\r
                 EfiPciIoWidthUint8,\r
                 EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                (UINT64) ((UINTN)DestinationAddress + Offset),\r
+                (UINT64) (DestinationAddress + Offset),\r
                 EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                (UINT64) ((UINTN)SourceAddress + Offset),\r
+                (UINT64) (SourceAddress + Offset),\r
                 Bytes\r
                 );\r
       }\r
@@ -2136,7 +2715,7 @@ Returns:
 \r
     break;\r
 \r
-  case EfiUgaVideoFill:\r
+  case EfiBltVideoFill:\r
     StartAddress  = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3));\r
     Bytes         = ((DestinationX + Width - 1) >> 3) - (DestinationX >> 3);\r
     LeftMask      = mVgaLeftMaskTable[DestinationX & 0x07];\r
@@ -2163,7 +2742,7 @@ Returns:
     // Program the Mode Register Write mode 2, Read mode 0\r
     //\r
     WriteGraphicsController (\r
-      BiosVideoPrivate->PciIo,\r
+      PciIo,\r
       VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,\r
       VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2\r
       );\r
@@ -2172,7 +2751,7 @@ Returns:
     // Program the Data Rotate/Function Select Register to replace\r
     //\r
     WriteGraphicsController (\r
-      BiosVideoPrivate->PciIo,\r
+      PciIo,\r
       VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER,\r
       VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE\r
       );\r
@@ -2182,7 +2761,7 @@ Returns:
       // Program the BitMask register with the Left column mask\r
       //\r
       WriteGraphicsController (\r
-        BiosVideoPrivate->PciIo,\r
+        PciIo,\r
         VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
         LeftMask\r
         );\r
@@ -2218,7 +2797,7 @@ Returns:
       // Program the BitMask register with the middle column mask of 0xff\r
       //\r
       WriteGraphicsController (\r
-        BiosVideoPrivate->PciIo,\r
+        PciIo,\r
         VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
         0xff\r
         );\r
@@ -2240,7 +2819,7 @@ Returns:
       // Program the BitMask register with the Right column mask\r
       //\r
       WriteGraphicsController (\r
-        BiosVideoPrivate->PciIo,\r
+        PciIo,\r
         VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
         RightMask\r
         );\r
@@ -2272,7 +2851,7 @@ Returns:
     }\r
     break;\r
 \r
-  case EfiUgaBltBufferToVideo:\r
+  case EfiBltBufferToVideo:\r
     StartAddress  = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3));\r
     LeftMask      = mVgaBitMaskTable[DestinationX & 0x07];\r
 \r
@@ -2280,7 +2859,7 @@ Returns:
     // Program the Mode Register Write mode 2, Read mode 0\r
     //\r
     WriteGraphicsController (\r
-      BiosVideoPrivate->PciIo,\r
+      PciIo,\r
       VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,\r
       VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2\r
       );\r
@@ -2289,7 +2868,7 @@ Returns:
     // Program the Data Rotate/Function Select Register to replace\r
     //\r
     WriteGraphicsController (\r
-      BiosVideoPrivate->PciIo,\r
+      PciIo,\r
       VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER,\r
       VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE\r
       );\r
@@ -2305,7 +2884,7 @@ Returns:
         // Program the BitMask register with the Left column mask\r
         //\r
         WriteGraphicsController (\r
-          BiosVideoPrivate->PciIo,\r
+          PciIo,\r
           VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,\r
           LeftMask\r
           );\r
@@ -2318,7 +2897,7 @@ Returns:
                       PciIo,\r
                       EfiPciIoWidthUint8,\r
                       EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                      (UINT64) (UINTN) Address1,\r
+                      (UINT64) Address1,\r
                       1,\r
                       &Data\r
                       );\r
@@ -2327,7 +2906,7 @@ Returns:
                       PciIo,\r
                       EfiPciIoWidthUint8,\r
                       EFI_PCI_IO_PASS_THROUGH_BAR,\r
-                      (UINT64) (UINTN) Address1,\r
+                      (UINT64) Address1,\r
                       1,\r
                       &BiosVideoPrivate->LineBuffer[Index1]\r
                       );\r
@@ -2341,8 +2920,6 @@ Returns:
       }\r
     }\r
 \r
-    break;\r
-  default:\r
     break;\r
   }\r
 \r
@@ -2380,6 +2957,10 @@ Returns:
   BIOS_VIDEO_DEV        *BiosVideoPrivate;\r
   EFI_IA32_REGISTER_SET Regs;\r
 \r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   //\r
   // Make sure the ModeNumber is a valid value\r
   //\r
@@ -2390,7 +2971,7 @@ Returns:
   // Get the device structure for this device\r
   //\r
   BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (This);\r
-\r
+  \r
   gBS->SetMem (&Regs, sizeof (Regs), 0);\r
 \r
   switch (ModeNumber) {\r
@@ -2400,12 +2981,13 @@ Returns:
     //\r
     Regs.H.AH = 0x00;\r
     Regs.H.AL = 0x83;\r
-    LegacyBiosInt86 (0x10, &Regs);\r
-\r
+    LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+    \r
     Regs.H.AH = 0x11;\r
     Regs.H.AL = 0x14;\r
     Regs.H.BL = 0;\r
-    LegacyBiosInt86 (0x10, &Regs);\r
+    LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+    \r
     break;\r
 \r
   case 1:\r
@@ -2414,11 +2996,12 @@ Returns:
     //\r
     Regs.H.AH = 0x00;\r
     Regs.H.AL = 0x83;\r
-    LegacyBiosInt86 (0x10, &Regs);\r
+    LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
+    \r
     Regs.H.AH = 0x11;\r
     Regs.H.AL = 0x12;\r
     Regs.H.BL = 0;\r
-    LegacyBiosInt86 (0x10, &Regs);\r
+    LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);\r
     break;\r
 \r
   default:\r
@@ -2427,222 +3010,3 @@ Returns:
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
-VOID\r
-InitializeBiosIntCaller (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  UINT32                RealModeBufferSize;\r
-  UINT32                ExtraStackSize;\r
-  EFI_PHYSICAL_ADDRESS  LegacyRegionBase;\r
-  \r
-  //\r
-  // Get LegacyRegion\r
-  //\r
-  AsmGetThunk16Properties (&RealModeBufferSize, &ExtraStackSize);\r
-\r
-  LegacyRegionBase = 0x100000;\r
-  Status = gBS->AllocatePages (\r
-                  AllocateMaxAddress,\r
-                  EfiACPIMemoryNVS,\r
-                  EFI_SIZE_TO_PAGES(RealModeBufferSize + ExtraStackSize + 200),\r
-                  &LegacyRegionBase\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-  \r
-  mThunkContext.RealModeBuffer     = (VOID*)(UINTN)LegacyRegionBase;\r
-  mThunkContext.RealModeBufferSize = EFI_PAGES_TO_SIZE (RealModeBufferSize);\r
-  mThunkContext.ThunkAttributes    = 3;\r
-  AsmPrepareThunk16(&mThunkContext);\r
-  \r
-  //Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &mLegacy8259);\r
-  //ASSERT_EFI_ERROR (Status);  \r
-}\r
-\r
-VOID\r
-InitializeInterruptRedirection (\r
-  VOID\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Initialize interrupt redirection code and entries, because\r
-    IDT Vectors 0x68-0x6f must be redirected to IDT Vectors 0x08-0x0f.\r
-    Or the interrupt will lost when we do thunk.\r
-    NOTE: We do not reset 8259 vector base, because it will cause pending\r
-    interrupt lost.\r
-\r
-  Arguments:\r
-    NONE\r
-\r
-  Returns:\r
-    NONE\r
---*/\r
-{\r
-  EFI_STATUS            Status;\r
-  EFI_PHYSICAL_ADDRESS  LegacyRegionBase;\r
-  UINTN                 LegacyRegionLength;\r
-  UINT32                *IdtArray;\r
-  UINTN                 Index;\r
-  UINT8                 ProtectedModeBaseVector;\r
-  UINT32                InterruptRedirectionCode[] = {\r
-    0x90CF08CD, // INT8; IRET; NOP\r
-    0x90CF09CD, // INT9; IRET; NOP\r
-    0x90CF0ACD, // INTA; IRET; NOP\r
-    0x90CF0BCD, // INTB; IRET; NOP\r
-    0x90CF0CCD, // INTC; IRET; NOP\r
-    0x90CF0DCD, // INTD; IRET; NOP\r
-    0x90CF0ECD, // INTE; IRET; NOP\r
-    0x90CF0FCD  // INTF; IRET; NOP\r
-  };\r
-\r
-  //\r
-  // Get LegacyRegion\r
-  //\r
-  LegacyRegionLength = sizeof(InterruptRedirectionCode);\r
-  LegacyRegionBase = 0x100000;\r
-  Status = gBS->AllocatePages (\r
-                  AllocateMaxAddress,\r
-                  EfiACPIMemoryNVS,\r
-                  EFI_SIZE_TO_PAGES(LegacyRegionLength),\r
-                  &LegacyRegionBase\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Copy code to legacy region\r
-  //\r
-  CopyMem ((VOID *)(UINTN)LegacyRegionBase, InterruptRedirectionCode, sizeof (InterruptRedirectionCode));\r
-\r
-  //\r
-  // Get VectorBase, it should be 0x68\r
-  //\r
-  Status = mLegacy8259->GetVector (mLegacy8259, Efi8259Irq0, &ProtectedModeBaseVector);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Patch IVT 0x68 ~ 0x6f\r
-  //\r
-  IdtArray = (UINT32 *) 0;\r
-  for (Index = 0; Index < 8; Index++) {\r
-    IdtArray[ProtectedModeBaseVector + Index] = ((EFI_SEGMENT (LegacyRegionBase + Index * 4)) << 16) | (EFI_OFFSET (LegacyRegionBase + Index * 4));\r
-  }\r
-\r
-  return ;\r
-}\r
-\r
-BOOLEAN\r
-EFIAPI\r
-LegacyBiosInt86 (\r
-  IN  UINT8                           BiosInt,\r
-  IN  EFI_IA32_REGISTER_SET           *Regs\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Thunk to 16-bit real mode and execute a software interrupt with a vector \r
-    of BiosInt. Regs will contain the 16-bit register context on entry and \r
-    exit.\r
-\r
-  Arguments:\r
-    This    - Protocol instance pointer.\r
-    BiosInt - Processor interrupt vector to invoke\r
-    Reg     - Register contexted passed into (and returned) from thunk to \r
-              16-bit mode\r
-\r
-  Returns:\r
-    FALSE   - Thunk completed, and there were no BIOS errors in the target code.\r
-              See Regs for status.\r
-    TRUE    - There was a BIOS erro in the target code.\r
-\r
---*/\r
-{\r
-  UINTN                 Status;\r
-  UINTN                 Eflags;\r
-  IA32_REGISTER_SET     ThunkRegSet;\r
-  BOOLEAN               Ret;\r
-  UINT16                *Stack16;\r
-  \r
-  Regs->X.Flags.Reserved1 = 1;\r
-  Regs->X.Flags.Reserved2 = 0;\r
-  Regs->X.Flags.Reserved3 = 0;\r
-  Regs->X.Flags.Reserved4 = 0;\r
-  Regs->X.Flags.IOPL      = 3;\r
-  Regs->X.Flags.NT        = 0;\r
-  Regs->X.Flags.IF        = 1;\r
-  Regs->X.Flags.TF        = 0;\r
-  Regs->X.Flags.CF        = 0;\r
-\r
-  ZeroMem (&ThunkRegSet, sizeof (ThunkRegSet));\r
-  ThunkRegSet.E.EDI  = Regs->E.EDI;\r
-  ThunkRegSet.E.ESI  = Regs->E.ESI;\r
-  ThunkRegSet.E.EBP  = Regs->E.EBP;\r
-  ThunkRegSet.E.EBX  = Regs->E.EBX;\r
-  ThunkRegSet.E.EDX  = Regs->E.EDX;\r
-  ThunkRegSet.E.ECX  = Regs->E.ECX;\r
-  ThunkRegSet.E.EAX  = Regs->E.EAX;\r
-  ThunkRegSet.E.DS   = Regs->E.DS;\r
-  ThunkRegSet.E.ES   = Regs->E.ES;\r
-\r
-  CopyMem (&(ThunkRegSet.E.EFLAGS), &(Regs->E.EFlags), sizeof (UINT32));\r
\r
-  //\r
-  // The call to Legacy16 is a critical section to EFI\r
-  //\r
-  Eflags = AsmReadEflags ();\r
-  if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
-    DisableInterrupts ();\r
-  }\r
-\r
-  //\r
-  // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases.\r
-  //\r
-  Status = mLegacy8259->SetMode (mLegacy8259, Efi8259LegacyMode, NULL, NULL);\r
-  ASSERT_EFI_ERROR (Status);\r
-  \r
-  Stack16 = (UINT16 *)((UINT8 *) mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (UINT16));\r
-  Stack16 -= sizeof (ThunkRegSet.E.EFLAGS) / sizeof (UINT16);\r
-  CopyMem (Stack16, &ThunkRegSet.E.EFLAGS, sizeof (ThunkRegSet.E.EFLAGS));\r
-\r
-  ThunkRegSet.E.SS   = (UINT16) (((UINTN) Stack16 >> 16) << 12);\r
-  ThunkRegSet.E.ESP  = (UINT16) (UINTN) Stack16;\r
-  ThunkRegSet.E.Eip  = (UINT16)((UINT32 *)NULL)[BiosInt];\r
-  ThunkRegSet.E.CS   = (UINT16)(((UINT32 *)NULL)[BiosInt] >> 16);\r
-  mThunkContext.RealModeState = &ThunkRegSet;\r
-  AsmThunk16 (&mThunkContext);\r
-\r
-  //\r
-  // Restore protected mode interrupt state\r
-  //\r
-  Status = mLegacy8259->SetMode (mLegacy8259, Efi8259ProtectedMode, NULL, NULL);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // End critical section\r
-  //\r
-  if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
-    EnableInterrupts ();\r
-  }\r
-\r
-  Regs->E.EDI      = ThunkRegSet.E.EDI;      \r
-  Regs->E.ESI      = ThunkRegSet.E.ESI;  \r
-  Regs->E.EBP      = ThunkRegSet.E.EBP;  \r
-  Regs->E.EBX      = ThunkRegSet.E.EBX;  \r
-  Regs->E.EDX      = ThunkRegSet.E.EDX;  \r
-  Regs->E.ECX      = ThunkRegSet.E.ECX;  \r
-  Regs->E.EAX      = ThunkRegSet.E.EAX;\r
-  Regs->E.SS       = ThunkRegSet.E.SS;\r
-  Regs->E.CS       = ThunkRegSet.E.CS;  \r
-  Regs->E.DS       = ThunkRegSet.E.DS;  \r
-  Regs->E.ES       = ThunkRegSet.E.ES;\r
-\r
-  CopyMem (&(Regs->E.EFlags), &(ThunkRegSet.E.EFLAGS), sizeof (UINT32));\r
-\r
-  Ret = (BOOLEAN) (Regs->E.EFlags.CF == 1);\r
-\r
-  return Ret;\r
-}\r
-\r
-\r
index 2123090ddb6755234fb6fb5f473e2f490ce0cd34..c8a3f3c92d55bc32bf5157eb93829ab2045ee957 100644 (file)
@@ -11,15 +11,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 Module Name:\r
 \r
-  BiosVideo.h\r
+  UefiBiosVideo.h\r
     \r
 Abstract: \r
 \r
 Revision History\r
 --*/\r
 \r
-#ifndef _BIOS_UGA_H\r
-#define _BIOS_UGA_H\r
+#ifndef _BIOS_GRAPHICS_OUTPUT_H\r
+#define _BIOS_GRAPHICS_OUTPUT_H\r
 \r
 #include <Uefi.h>\r
 \r
@@ -34,24 +34,20 @@ Revision History
 #include <Protocol/UgaDraw.h>\r
 #include <Protocol/VgaMiniPort.h>\r
 #include <Protocol/Legacy8259.h>\r
+#include <Protocol/EdidActive.h>\r
+#include <Protocol/EdidDiscovered.h>\r
+#include <Protocol/DevicePath.h>\r
 #include <Protocol/LegacyBios.h>\r
 \r
 #include <Library/UefiLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
+#include <Library/DevicePathLib.h>\r
 \r
 #include <IndustryStandard/Pci22.h>\r
 \r
 #include "VesaBiosExtensions.h"\r
-//\r
-// Driver Produced Protocol Prototypes\r
-//\r
-//#include EFI_PROTOCOL_DEFINITION (DriverBinding)\r
-//#include EFI_PROTOCOL_DEFINITION (ComponentName)\r
-//#include EFI_PROTOCOL_DEFINITION (ComponentName2)\r
-//#include EFI_PROTOCOL_DEFINITION (UgaDraw)\r
-//#include EFI_PROTOCOL_DEFINITION (VgaMiniPort)\r
 \r
 //\r
 // Packed format support: The number of bits reserved for each of the colors and the actual\r
@@ -63,26 +59,29 @@ typedef struct {
 } BIOS_VIDEO_COLOR_PLACEMENT;\r
 \r
 //\r
-// BIOS UGA Draw Graphical Mode Data\r
+// BIOS Graphics Output Graphical Mode Data\r
 //\r
 typedef struct {\r
   UINT16                      VbeModeNumber;\r
   UINT16                      BytesPerScanLine;\r
   VOID                        *LinearFrameBuffer;\r
+  UINTN                       FrameBufferSize;\r
   UINT32                      HorizontalResolution;\r
   UINT32                      VerticalResolution;\r
-  UINT32                      ColorDepth;\r
   UINT32                      RefreshRate;\r
   UINT32                      BitsPerPixel;\r
   BIOS_VIDEO_COLOR_PLACEMENT  Red;\r
   BIOS_VIDEO_COLOR_PLACEMENT  Green;\r
   BIOS_VIDEO_COLOR_PLACEMENT  Blue;\r
+  BIOS_VIDEO_COLOR_PLACEMENT  Reserved;\r
+  EFI_GRAPHICS_PIXEL_FORMAT   PixelFormat;\r
+  EFI_PIXEL_BITMASK           PixelBitMask;\r
 } BIOS_VIDEO_MODE_DATA;\r
 \r
 //\r
-// BIOS UGA Device Structure\r
+// BIOS video child handle private data Structure\r
 //\r
-#define BIOS_VIDEO_DEV_SIGNATURE  SIGNATURE_32 ('B', 'V', 'M', 'p')\r
+#define BIOS_VIDEO_DEV_SIGNATURE    SIGNATURE_32 ('B', 'V', 'M', 'p')\r
 \r
 typedef struct {\r
   UINTN                                       Signature;\r
@@ -92,30 +91,30 @@ typedef struct {
   // Consumed Protocols\r
   //\r
   EFI_PCI_IO_PROTOCOL                         *PciIo;\r
-  //EFI_LEGACY_BIOS_THUNK_PROTOCOL              *LegacyBios;\r
+  EFI_LEGACY_8259_PROTOCOL                    *Legacy8259;\r
 \r
   //\r
   // Produced Protocols\r
   //\r
-  EFI_UGA_DRAW_PROTOCOL                       UgaDraw;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL                GraphicsOutput;\r
+  EFI_EDID_DISCOVERED_PROTOCOL                EdidDiscovered;\r
+  EFI_EDID_ACTIVE_PROTOCOL                    EdidActive;\r
   EFI_VGA_MINI_PORT_PROTOCOL                  VgaMiniPort;\r
 \r
   //\r
   // General fields\r
   //\r
-  EFI_EVENT                                   ExitBootServicesEvent;\r
   BOOLEAN                                     VgaCompatible;\r
-  BOOLEAN                                     ProduceUgaDraw;\r
+  BOOLEAN                                     ProduceGraphicsOutput;\r
+  EFI_EVENT                                   ExitBootServicesEvent;\r
 \r
   //\r
-  // UGA Draw related fields\r
+  // Graphics Output Protocol related fields\r
   //\r
   BOOLEAN                                     HardwareNeedsStarting;\r
-  UINTN                                       CurrentMode;\r
-  UINTN                                       MaxMode;\r
   BIOS_VIDEO_MODE_DATA                        *ModeData;\r
   UINT8                                       *LineBuffer;\r
-  EFI_UGA_PIXEL                               *VbeFrameBuffer;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL               *VbeFrameBuffer;\r
   UINT8                                       *VgaFrameBuffer;\r
 \r
   //\r
@@ -125,6 +124,7 @@ typedef struct {
   EFI_PHYSICAL_ADDRESS                        PagesBelow1MB;            // Buffer for all VBE Information Blocks\r
   VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK      *VbeInformationBlock;     // 0x200 bytes.  Must be allocated below 1MB\r
   VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *VbeModeInformationBlock; // 0x100 bytes.  Must be allocated below 1MB\r
+  VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK        *VbeEdidDataBlock;        // 0x80  bytes.  Must be allocated below 1MB\r
   VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *VbeCrtcInformationBlock; // 59 bytes.  Must be allocated below 1MB\r
   UINTN                                       VbeSaveRestorePages;      // Number of 4KB pages in VbeSaveRestoreBuffer\r
   EFI_PHYSICAL_ADDRESS                        VbeSaveRestoreBuffer;     // Must be allocated below 1MB\r
@@ -134,10 +134,12 @@ typedef struct {
   EFI_DEVICE_PATH_PROTOCOL                    *DevicePath;\r
 } BIOS_VIDEO_DEV;\r
 \r
-#define BIOS_VIDEO_DEV_FROM_UGA_DRAW_THIS(a)      CR (a, BIOS_VIDEO_DEV, UgaDraw, BIOS_VIDEO_DEV_SIGNATURE)\r
-\r
+#define BIOS_VIDEO_DEV_FROM_PCI_IO_THIS(a)      CR (a, BIOS_VIDEO_DEV, PciIo, BIOS_VIDEO_DEV_SIGNATURE)\r
+#define BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS(a)      CR (a, BIOS_VIDEO_DEV, GraphicsOutput, BIOS_VIDEO_DEV_SIGNATURE)\r
 #define BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS(a) CR (a, BIOS_VIDEO_DEV, VgaMiniPort, BIOS_VIDEO_DEV_SIGNATURE)\r
 \r
+#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER   0xffff\r
+\r
 //\r
 // Global Variables\r
 //\r
@@ -156,23 +158,21 @@ BiosVideoDriverBindingSupported (
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
   )\r
 /*++\r
-  \r
-  Routine Description:\r
 \r
-    Supported.\r
-    \r
-  Arguments:\r
+Routine Description:\r
 \r
-  This - Pointer to driver binding protocol\r
-  Controller - Controller handle to connect\r
-  RemainingDevicePath - A pointer to the remaining portion of a device path\r
-    \r
-    \r
-  Returns:\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  This                - GC_TODO: add argument description\r
+  Controller          - GC_TODO: add argument description\r
+  RemainingDevicePath - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
 \r
-  EFI_STATUS - EFI_SUCCESS:This controller can be managed by this driver,\r
-               Otherwise, this controller cannot be managed by this driver\r
-  \r
 --*/\r
 ;\r
 \r
@@ -184,21 +184,21 @@ BiosVideoDriverBindingStart (
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
   )\r
 /*++\r
-  \r
-  Routine Description:\r
 \r
-    Install UGA Draw Protocol onto VGA device handles\r
-  \r
-  Arguments:\r
+Routine Description:\r
 \r
-  This - Pointer to driver binding protocol\r
-  Controller - Controller handle to connect\r
-  RemainingDevicePath - A pointer to the remaining portion of a device path\r
-    \r
-  Returns:\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  This                - GC_TODO: add argument description\r
+  Controller          - GC_TODO: add argument description\r
+  RemainingDevicePath - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
 \r
-    EFI_STATUS\r
-    \r
 --*/\r
 ;\r
 \r
@@ -211,23 +211,22 @@ BiosVideoDriverBindingStop (
   IN  EFI_HANDLE                   *ChildHandleBuffer\r
   )\r
 /*++\r
-  \r
-  Routine Description:\r
 \r
-    Stop.\r
-  \r
-  Arguments:\r
+Routine Description:\r
 \r
-  This - Pointer to driver binding protocol\r
-  Controller - Controller handle to connect\r
-  NumberOfChilren - Number of children handle created by this driver\r
-  ChildHandleBuffer - Buffer containing child handle created\r
-  \r
-  Returns:\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  This              - GC_TODO: add argument description\r
+  Controller        - GC_TODO: add argument description\r
+  NumberOfChildren  - GC_TODO: add argument description\r
+  ChildHandleBuffer - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
 \r
-  EFI_SUCCESS - Driver disconnected successfully from controller\r
-  EFI_UNSUPPORTED - Cannot find BIOS_VIDEO_DEV structure\r
-  \r
 --*/\r
 ;\r
 \r
@@ -239,19 +238,19 @@ BiosVideoCheckForVbe (
   BIOS_VIDEO_DEV  *BiosVideoPrivate\r
   )\r
 /*++\r
-  \r
-  Routine Description:\r
 \r
-  Check for VBE device   \r
-  \r
-  Arguments:\r
-  \r
-  BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure\r
-  \r
-  Returns:\r
-  \r
-  EFI_SUCCESS - VBE device found\r
-  \r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  BiosVideoPrivate  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
 --*/\r
 ;\r
 \r
@@ -260,112 +259,148 @@ BiosVideoCheckForVga (
   BIOS_VIDEO_DEV  *BiosVideoPrivate\r
   )\r
 /*++\r
-  \r
-  Routine Description:\r
 \r
-    Check for VGA device\r
-  \r
-  Arguments:\r
-  \r
-    BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure\r
-  \r
-  Returns:\r
-  \r
-    EFI_SUCCESS - Standard VGA device found\r
-  \r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  BiosVideoPrivate  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
 --*/\r
 ;\r
 \r
-//\r
-// BIOS UGA Draw Protocol functions\r
-//\r
+STATIC\r
 EFI_STATUS\r
-EFIAPI\r
-BiosVideoUgaDrawGetMode (\r
-  IN  EFI_UGA_DRAW_PROTOCOL  *This,\r
-  OUT UINT32                 *HorizontalResolution,\r
-  OUT UINT32                 *VerticalResolution,\r
-  OUT UINT32                 *ColorDepth,\r
-  OUT UINT32                 *RefreshRate\r
+DeRegisterVideoChildHandle (\r
+  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
+  EFI_HANDLE                     Controller,\r
+  EFI_HANDLE                     Handle\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  UGA protocol interface to get video mode\r
+  Deregister an video child handle and free resources\r
 \r
 Arguments:\r
 \r
-  This                  - Pointer to UGA draw protocol instance\r
-  HorizontalResolution  - Horizontal Resolution, in pixels\r
-  VerticalResolution    - Vertical Resolution, in pixels\r
-  ColorDepth            - Bit number used to represent color value of a pixel \r
-  RefreshRate           - Refresh rate, in Hertz\r
+  This            - Protocol instance pointer.\r
+  Controller      - Video controller handle\r
+  Handle          - Video child handle\r
 \r
 Returns:\r
 \r
-  EFI_DEVICE_ERROR - Hardware need starting\r
-  EFI_INVALID_PARAMETER - Invalid parameter passed in\r
-  EFI_SUCCESS - Video mode query successfully\r
+  EFI_STATUS\r
 \r
 --*/\r
 ;\r
 \r
+VOID\r
+BiosVideoDeviceReleaseResource (\r
+  BIOS_VIDEO_DEV  *BiosVideoChildPrivate\r
+  )\r
+/*++\r
+Routing Description:\r
+\r
+  Release resources of a video child device before stopping it.\r
+\r
+Arguments:\r
+\r
+  BiosVideoChildPrivate  -  Video child device private data structure\r
+\r
+Returns:\r
+\r
+    NONE\r
+    \r
+---*/\r
+;\r
+\r
+//\r
+// BIOS Graphics Output Protocol functions\r
+//\r
 EFI_STATUS\r
 EFIAPI\r
-BiosVideoUgaDrawSetMode (\r
-  IN  EFI_UGA_DRAW_PROTOCOL  *This,\r
-  IN  UINT32                 HorizontalResolution,\r
-  IN  UINT32                 VerticalResolution,\r
-  IN  UINT32                 ColorDepth,\r
-  IN  UINT32                 RefreshRate\r
+BiosVideoGraphicsOutputQueryMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,\r
+  IN  UINT32                                ModeNumber,\r
+  OUT UINTN                                 *SizeOfInfo,\r
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  UGA draw protocol interface to set video mode\r
+  Graphics Output protocol interface to get video mode\r
 \r
-Arguments:\r
+  Arguments:\r
+    This                  - Protocol instance pointer.\r
+    ModeNumber            - The mode number to return information on.\r
+    Info                  - Caller allocated buffer that returns information about ModeNumber.\r
+    SizeOfInfo            - A pointer to the size, in bytes, of the Info buffer.\r
 \r
-  This                  - Pointer to UGA draw protocol instance\r
-  HorizontalResolution  - Horizontal Resolution, in pixels\r
-  VerticalResolution    - Vertical Resolution, in pixels\r
-  ColorDepth            - Bit number used to represent color value of a pixel \r
-  RefreshRate           - Refresh rate, in Hertz\r
+  Returns:\r
+    EFI_SUCCESS           - Mode information returned.\r
+    EFI_BUFFER_TOO_SMALL  - The Info buffer was too small.\r
+    EFI_DEVICE_ERROR      - A hardware error occurred trying to retrieve the video mode.\r
+    EFI_NOT_STARTED       - Video display is not initialized. Call SetMode ()\r
+    EFI_INVALID_PARAMETER - One of the input args was NULL.\r
 \r
-Returns:\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+BiosVideoGraphicsOutputSetMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL * This,\r
+  IN  UINT32                       ModeNumber\r
+  )\r
+/*++\r
 \r
-  EFI_DEVICE_ERROR - Device error\r
-  EFI_SUCCESS - Video mode set successfully\r
-  EFI_UNSUPPORTED - Cannot support this video mode\r
+Routine Description:\r
+\r
+  Graphics Output protocol interface to set video mode\r
+\r
+  Arguments:\r
+    This             - Protocol instance pointer.\r
+    ModeNumber       - The mode number to be set.\r
+\r
+  Returns:\r
+    EFI_SUCCESS      - Graphics mode was changed.\r
+    EFI_DEVICE_ERROR - The device had an error and could not complete the request.\r
+    EFI_UNSUPPORTED  - ModeNumber is not supported by this device.\r
 \r
 --*/\r
 ;\r
 \r
 EFI_STATUS\r
 EFIAPI\r
-BiosVideoUgaDrawVbeBlt (\r
-  IN  EFI_UGA_DRAW_PROTOCOL  *This,\r
-  IN  EFI_UGA_PIXEL          *BltBuffer, OPTIONAL\r
-  IN  EFI_UGA_BLT_OPERATION  BltOperation,\r
-  IN  UINTN                  SourceX,\r
-  IN  UINTN                  SourceY,\r
-  IN  UINTN                  DestinationX,\r
-  IN  UINTN                  DestinationY,\r
-  IN  UINTN                  Width,\r
-  IN  UINTN                  Height,\r
-  IN  UINTN                  Delta\r
+BiosVideoGraphicsOutputVbeBlt (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL       *This,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer, OPTIONAL\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION  BltOperation,\r
+  IN  UINTN                              SourceX,\r
+  IN  UINTN                              SourceY,\r
+  IN  UINTN                              DestinationX,\r
+  IN  UINTN                              DestinationY,\r
+  IN  UINTN                              Width,\r
+  IN  UINTN                              Height,\r
+  IN  UINTN                              Delta\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  UGA draw protocol instance to block transfer for VBE device\r
+  Graphics Output protocol instance to block transfer for VBE device\r
 \r
 Arguments:\r
 \r
-  This          - Pointer to UGA draw protocol instance\r
+  This          - Pointer to Graphics Output protocol instance\r
   BltBuffer     - The data to transfer to screen\r
   BltOperation  - The operation to perform\r
   SourceX       - The X coordinate of the source for BltOperation\r
@@ -374,9 +409,9 @@ Arguments:
   DestinationY  - The Y coordinate of the destination for BltOperation\r
   Width         - The width of a rectangle in the blt rectangle in pixels\r
   Height        - The height of a rectangle in the blt rectangle in pixels\r
-  Delta         - Not used for EfiUgaVideoFill and EfiUgaVideoToVideo operation.\r
+  Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.\r
                   If a Delta of 0 is used, the entire BltBuffer will be operated on.\r
-                  If a subrectangle of the BltBuffer is used, then Delta represents \r
+                  If a subrectangle of the BltBuffer is used, then Delta represents\r
                   the number of bytes in a row of the BltBuffer.\r
 \r
 Returns:\r
@@ -389,27 +424,27 @@ Returns:
 \r
 EFI_STATUS\r
 EFIAPI\r
-BiosVideoUgaDrawVgaBlt (\r
-  IN  EFI_UGA_DRAW_PROTOCOL  *This,\r
-  IN  EFI_UGA_PIXEL          *BltBuffer, OPTIONAL\r
-  IN  EFI_UGA_BLT_OPERATION  BltOperation,\r
-  IN  UINTN                  SourceX,\r
-  IN  UINTN                  SourceY,\r
-  IN  UINTN                  DestinationX,\r
-  IN  UINTN                  DestinationY,\r
-  IN  UINTN                  Width,\r
-  IN  UINTN                  Height,\r
-  IN  UINTN                  Delta\r
+BiosVideoGraphicsOutputVgaBlt (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL       *This,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer, OPTIONAL\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION  BltOperation,\r
+  IN  UINTN                              SourceX,\r
+  IN  UINTN                              SourceY,\r
+  IN  UINTN                              DestinationX,\r
+  IN  UINTN                              DestinationY,\r
+  IN  UINTN                              Width,\r
+  IN  UINTN                              Height,\r
+  IN  UINTN                              Delta\r
   )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  UGA draw protocol instance to block transfer for VGA device\r
+  Grahpics Output protocol instance to block transfer for VGA device\r
 \r
 Arguments:\r
 \r
-  This          - Pointer to UGA draw protocol instance\r
+  This          - Pointer to Grahpics Output protocol instance\r
   BltBuffer     - The data to transfer to screen\r
   BltOperation  - The operation to perform\r
   SourceX       - The X coordinate of the source for BltOperation\r
@@ -418,9 +453,9 @@ Arguments:
   DestinationY  - The Y coordinate of the destination for BltOperation\r
   Width         - The width of a rectangle in the blt rectangle in pixels\r
   Height        - The height of a rectangle in the blt rectangle in pixels\r
-  Delta         - Not used for EfiUgaVideoFill and EfiUgaVideoToVideo operation.\r
+  Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.\r
                   If a Delta of 0 is used, the entire BltBuffer will be operated on.\r
-                  If a subrectangle of the BltBuffer is used, then Delta represents \r
+                  If a subrectangle of the BltBuffer is used, then Delta represents\r
                   the number of bytes in a row of the BltBuffer.\r
 \r
 Returns:\r
@@ -508,4 +543,22 @@ BiosVideoIsVga (
 \r
 #define VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER         0x08\r
 \r
+VOID\r
+InitializeBiosIntCaller (\r
+  IN  BIOS_VIDEO_DEV                 *BiosDev\r
+  );\r
+  \r
+VOID\r
+InitializeInterruptRedirection (\r
+  IN  BIOS_VIDEO_DEV                 *BiosDev\r
+  );\r
+  \r
+BOOLEAN\r
+EFIAPI\r
+LegacyBiosInt86 (\r
+  IN  BIOS_VIDEO_DEV                 *BiosDev,\r
+  IN  UINT8                           BiosInt,\r
+  IN  EFI_IA32_REGISTER_SET           *Regs\r
+  );    \r
+  \r
 #endif\r
index d8ac37f34f6d12d7ef32b3778fdbdfdf5f8c8a82..93db736b0bfefadef9f438e683311e892ac5b63a 100644 (file)
   UefiBootServicesTableLib\r
   BaseMemoryLib\r
   UefiDriverEntryPoint\r
+  DevicePathLib\r
   \r
 [Sources.common]\r
   BiosVideo.h\r
   BiosVideo.c\r
   ComponentName.c\r
   VesaBiosExtensions.h\r
-\r
+  LegacyBiosThunk.c\r
+  \r
 [Protocols]\r
   gEfiPciIoProtocolGuid\r
   gEfiVgaMiniPortProtocolGuid\r
   gEfiLegacy8259ProtocolGuid\r
+  gEfiEdidDiscoveredProtocolGuid\r
+  gEfiEdidActiveProtocolGuid
\ No newline at end of file
diff --git a/DuetPkg/BiosVideoThunkDxe/LegacyBiosThunk.c b/DuetPkg/BiosVideoThunkDxe/LegacyBiosThunk.c
new file mode 100644 (file)
index 0000000..1f39066
--- /dev/null
@@ -0,0 +1,224 @@
+\r
+#include "BiosVideo.h"\r
+\r
+#define EFI_CPU_EFLAGS_IF 0x200\r
+\r
+THUNK_CONTEXT               mThunkContext;\r
+\r
+VOID\r
+InitializeBiosIntCaller (\r
+  IN  BIOS_VIDEO_DEV                 *BiosDev\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  UINT32                RealModeBufferSize;\r
+  UINT32                ExtraStackSize;\r
+  EFI_PHYSICAL_ADDRESS  LegacyRegionBase;\r
+  \r
+  //\r
+  // Get LegacyRegion\r
+  //\r
+  AsmGetThunk16Properties (&RealModeBufferSize, &ExtraStackSize);\r
+\r
+  LegacyRegionBase = 0x100000;\r
+  Status = gBS->AllocatePages (\r
+                  AllocateMaxAddress,\r
+                  EfiACPIMemoryNVS,\r
+                  EFI_SIZE_TO_PAGES(RealModeBufferSize + ExtraStackSize + 200),\r
+                  &LegacyRegionBase\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  mThunkContext.RealModeBuffer     = (VOID*)(UINTN)LegacyRegionBase;\r
+  mThunkContext.RealModeBufferSize = EFI_PAGES_TO_SIZE (RealModeBufferSize);\r
+  mThunkContext.ThunkAttributes    = 3;\r
+  AsmPrepareThunk16(&mThunkContext);\r
+  \r
+}\r
+\r
+VOID\r
+InitializeInterruptRedirection (\r
+  IN  BIOS_VIDEO_DEV                 *BiosDev\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Initialize interrupt redirection code and entries, because\r
+    IDT Vectors 0x68-0x6f must be redirected to IDT Vectors 0x08-0x0f.\r
+    Or the interrupt will lost when we do thunk.\r
+    NOTE: We do not reset 8259 vector base, because it will cause pending\r
+    interrupt lost.\r
+\r
+  Arguments:\r
+    NONE\r
+\r
+  Returns:\r
+    NONE\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  LegacyRegionBase;\r
+  UINTN                 LegacyRegionLength;\r
+  UINT32                *IdtArray;\r
+  UINTN                 Index;\r
+  UINT8                 ProtectedModeBaseVector;\r
+  UINT32                InterruptRedirectionCode[] = {\r
+    0x90CF08CD, // INT8; IRET; NOP\r
+    0x90CF09CD, // INT9; IRET; NOP\r
+    0x90CF0ACD, // INTA; IRET; NOP\r
+    0x90CF0BCD, // INTB; IRET; NOP\r
+    0x90CF0CCD, // INTC; IRET; NOP\r
+    0x90CF0DCD, // INTD; IRET; NOP\r
+    0x90CF0ECD, // INTE; IRET; NOP\r
+    0x90CF0FCD  // INTF; IRET; NOP\r
+  };\r
+\r
+  //\r
+  // Get LegacyRegion\r
+  //\r
+  LegacyRegionLength = sizeof(InterruptRedirectionCode);\r
+  LegacyRegionBase = 0x100000;\r
+  Status = gBS->AllocatePages (\r
+                  AllocateMaxAddress,\r
+                  EfiACPIMemoryNVS,\r
+                  EFI_SIZE_TO_PAGES(LegacyRegionLength),\r
+                  &LegacyRegionBase\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Copy code to legacy region\r
+  //\r
+  CopyMem ((VOID *)(UINTN)LegacyRegionBase, InterruptRedirectionCode, sizeof (InterruptRedirectionCode));\r
+\r
+  //\r
+  // Get VectorBase, it should be 0x68\r
+  //\r
+  Status = BiosDev->Legacy8259->GetVector (BiosDev->Legacy8259, Efi8259Irq0, &ProtectedModeBaseVector);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Patch IVT 0x68 ~ 0x6f\r
+  //\r
+  IdtArray = (UINT32 *) 0;\r
+  for (Index = 0; Index < 8; Index++) {\r
+    IdtArray[ProtectedModeBaseVector + Index] = ((EFI_SEGMENT (LegacyRegionBase + Index * 4)) << 16) | (EFI_OFFSET (LegacyRegionBase + Index * 4));\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+BOOLEAN\r
+EFIAPI\r
+LegacyBiosInt86 (\r
+  IN  BIOS_VIDEO_DEV                 *BiosDev,\r
+  IN  UINT8                           BiosInt,\r
+  IN  EFI_IA32_REGISTER_SET           *Regs\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Thunk to 16-bit real mode and execute a software interrupt with a vector \r
+    of BiosInt. Regs will contain the 16-bit register context on entry and \r
+    exit.\r
+\r
+  Arguments:\r
+    This    - Protocol instance pointer.\r
+    BiosInt - Processor interrupt vector to invoke\r
+    Reg     - Register contexted passed into (and returned) from thunk to \r
+              16-bit mode\r
+\r
+  Returns:\r
+    FALSE   - Thunk completed, and there were no BIOS errors in the target code.\r
+              See Regs for status.\r
+    TRUE    - There was a BIOS erro in the target code.\r
+\r
+--*/\r
+{\r
+  UINTN                 Status;\r
+  UINTN                 Eflags;\r
+  IA32_REGISTER_SET     ThunkRegSet;\r
+  BOOLEAN               Ret;\r
+  UINT16                *Stack16;\r
+  \r
+  Regs->X.Flags.Reserved1 = 1;\r
+  Regs->X.Flags.Reserved2 = 0;\r
+  Regs->X.Flags.Reserved3 = 0;\r
+  Regs->X.Flags.Reserved4 = 0;\r
+  Regs->X.Flags.IOPL      = 3;\r
+  Regs->X.Flags.NT        = 0;\r
+  Regs->X.Flags.IF        = 1;\r
+  Regs->X.Flags.TF        = 0;\r
+  Regs->X.Flags.CF        = 0;\r
+\r
+  ZeroMem (&ThunkRegSet, sizeof (ThunkRegSet));\r
+  ThunkRegSet.E.EDI  = Regs->E.EDI;\r
+  ThunkRegSet.E.ESI  = Regs->E.ESI;\r
+  ThunkRegSet.E.EBP  = Regs->E.EBP;\r
+  ThunkRegSet.E.EBX  = Regs->E.EBX;\r
+  ThunkRegSet.E.EDX  = Regs->E.EDX;\r
+  ThunkRegSet.E.ECX  = Regs->E.ECX;\r
+  ThunkRegSet.E.EAX  = Regs->E.EAX;\r
+  ThunkRegSet.E.DS   = Regs->E.DS;\r
+  ThunkRegSet.E.ES   = Regs->E.ES;\r
+\r
+  CopyMem (&(ThunkRegSet.E.EFLAGS), &(Regs->E.EFlags), sizeof (UINT32));\r
\r
+  //\r
+  // The call to Legacy16 is a critical section to EFI\r
+  //\r
+  Eflags = AsmReadEflags ();\r
+  if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
+    DisableInterrupts ();\r
+  }\r
+\r
+  //\r
+  // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases.\r
+  //\r
+  Status = BiosDev->Legacy8259->SetMode (BiosDev->Legacy8259, Efi8259LegacyMode, NULL, NULL);\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  Stack16 = (UINT16 *)((UINT8 *) mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (UINT16));\r
+  Stack16 -= sizeof (ThunkRegSet.E.EFLAGS) / sizeof (UINT16);\r
+  CopyMem (Stack16, &ThunkRegSet.E.EFLAGS, sizeof (ThunkRegSet.E.EFLAGS));\r
+\r
+  ThunkRegSet.E.SS   = (UINT16) (((UINTN) Stack16 >> 16) << 12);\r
+  ThunkRegSet.E.ESP  = (UINT16) (UINTN) Stack16;\r
+  ThunkRegSet.E.Eip  = (UINT16)((UINT32 *)NULL)[BiosInt];\r
+  ThunkRegSet.E.CS   = (UINT16)(((UINT32 *)NULL)[BiosInt] >> 16);\r
+  mThunkContext.RealModeState = &ThunkRegSet;\r
+  AsmThunk16 (&mThunkContext);\r
+\r
+  //\r
+  // Restore protected mode interrupt state\r
+  //\r
+  Status = BiosDev->Legacy8259->SetMode (BiosDev->Legacy8259, Efi8259ProtectedMode, NULL, NULL);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // End critical section\r
+  //\r
+  if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
+    EnableInterrupts ();\r
+  }\r
+\r
+  Regs->E.EDI      = ThunkRegSet.E.EDI;      \r
+  Regs->E.ESI      = ThunkRegSet.E.ESI;  \r
+  Regs->E.EBP      = ThunkRegSet.E.EBP;  \r
+  Regs->E.EBX      = ThunkRegSet.E.EBX;  \r
+  Regs->E.EDX      = ThunkRegSet.E.EDX;  \r
+  Regs->E.ECX      = ThunkRegSet.E.ECX;  \r
+  Regs->E.EAX      = ThunkRegSet.E.EAX;\r
+  Regs->E.SS       = ThunkRegSet.E.SS;\r
+  Regs->E.CS       = ThunkRegSet.E.CS;  \r
+  Regs->E.DS       = ThunkRegSet.E.DS;  \r
+  Regs->E.ES       = ThunkRegSet.E.ES;\r
+\r
+  CopyMem (&(Regs->E.EFlags), &(ThunkRegSet.E.EFLAGS), sizeof (UINT32));\r
+\r
+  Ret = (BOOLEAN) (Regs->E.EFlags.CF == 1);\r
+\r
+  return Ret;\r
+}\r
+\r
+\r