]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
Fix VS2013 build failure.
[mirror_edk2.git] / OvmfPkg / Library / PlatformBdsLib / BdsPlatform.c
index 0afec23606dfea17982c8e90d64416d523b31197..2a1ca88c2c13ed4be225fd2d16b1b509d9e424e3 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   Platform BDS customizations.\r
 \r
-  Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
-  All rights reserved. This program and the accompanying materials\r
+  Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
   http://opensource.org/licenses/bsd-license.php\r
 **/\r
 \r
 #include "BdsPlatform.h"\r
+#include "QemuBootOrder.h"\r
 \r
 \r
+//\r
+// Global data\r
+//\r
+\r
+VOID          *mEfiDevPathNotifyReg;\r
+EFI_EVENT     mEfiDevPathEvent;\r
+VOID          *mEmuVariableEventReg;\r
+EFI_EVENT     mEmuVariableEvent;\r
+BOOLEAN       mDetectVgaOnly;\r
+\r
+\r
+//\r
+// Type definitions\r
+//\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(\r
+  IN EFI_HANDLE           Handle,\r
+  IN VOID                 *Instance,\r
+  IN VOID                 *Context\r
+  );\r
+\r
+/**\r
+  @param[in]  Handle - Handle of PCI device instance\r
+  @param[in]  PciIo - PCI IO protocol instance\r
+  @param[in]  Pci - PCI Header register block\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(\r
+  IN EFI_HANDLE           Handle,\r
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN PCI_TYPE00           *Pci\r
+  );\r
+\r
+\r
+//\r
+// Function prototypes\r
+//\r
+\r
+EFI_STATUS\r
+VisitAllInstancesOfProtocol (\r
+  IN EFI_GUID                    *Id,\r
+  IN PROTOCOL_INSTANCE_CALLBACK  CallBackFunction,\r
+  IN VOID                        *Context\r
+  );\r
+\r
+EFI_STATUS\r
+VisitAllPciInstancesOfProtocol (\r
+  IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
+  );\r
+\r
+VOID\r
+InstallDevicePathCallback (\r
+  VOID\r
+  );\r
+\r
 //\r
 // BDS Platform Functions\r
 //\r
 VOID\r
 EFIAPI\r
 PlatformBdsInit (\r
-  IN EFI_BDS_ARCH_PROTOCOL_INSTANCE  *PrivateData\r
+  VOID\r
   )\r
 /*++\r
 \r
@@ -32,8 +91,6 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  PrivateData  - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance\r
-\r
 Returns:\r
 \r
   None.\r
@@ -41,6 +98,7 @@ Returns:
 --*/\r
 {\r
   DEBUG ((EFI_D_INFO, "PlatformBdsInit\n"));\r
+  InstallDevicePathCallback ();\r
 }\r
 \r
 \r
@@ -151,14 +209,16 @@ Returns:
   // Print Device Path\r
   //\r
   DevPathStr = DevicePathToStr(DevicePath);\r
-  DEBUG((\r
-    EFI_D_INFO,\r
-    "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
-    __LINE__,\r
-    gPnp16550ComPortDeviceNode.UID + 1,\r
-    DevPathStr\r
-    ));\r
-  FreePool(DevPathStr);\r
+  if (DevPathStr != NULL) {\r
+    DEBUG((\r
+      EFI_D_INFO,\r
+      "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
+      __LINE__,\r
+      gPnp16550ComPortDeviceNode.UID + 1,\r
+      DevPathStr\r
+      ));\r
+    FreePool(DevPathStr);\r
+  }\r
 \r
   BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
   BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
@@ -178,14 +238,16 @@ Returns:
   // Print Device Path\r
   //\r
   DevPathStr = DevicePathToStr(DevicePath);\r
-  DEBUG((\r
-    EFI_D_INFO,\r
-    "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
-    __LINE__,\r
-    gPnp16550ComPortDeviceNode.UID + 1,\r
-    DevPathStr\r
-    ));\r
-  FreePool(DevPathStr);\r
+  if (DevPathStr != NULL) {\r
+    DEBUG((\r
+      EFI_D_INFO,\r
+      "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
+      __LINE__,\r
+      gPnp16550ComPortDeviceNode.UID + 1,\r
+      DevPathStr\r
+      ));\r
+    FreePool(DevPathStr);\r
+  }\r
 \r
   BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
   BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
@@ -305,7 +367,8 @@ Returns:
   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
   EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;\r
 \r
-  DevicePath = NULL;\r
+  DevicePath    = NULL;\r
+  GopDevicePath = NULL;\r
   Status = gBS->HandleProtocol (\r
                   DeviceHandle,\r
                   &gEfiDevicePathProtocolGuid,\r
@@ -369,32 +432,17 @@ Returns:
 }\r
 \r
 EFI_STATUS\r
-DetectAndPreparePlatformPciDevicePath (\r
-  BOOLEAN DetectVgaOnly\r
+VisitAllInstancesOfProtocol (\r
+  IN EFI_GUID                    *Id,\r
+  IN PROTOCOL_INSTANCE_CALLBACK  CallBackFunction,\r
+  IN VOID                        *Context\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
-\r
-Arguments:\r
-\r
-  DetectVgaOnly           - Only detect VGA device if it's TRUE.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS             - PCI Device check and Console variable update successfully.\r
-  EFI_STATUS              - PCI Device check or Console variable update fail.\r
-\r
---*/\r
 {\r
   EFI_STATUS                Status;\r
   UINTN                     HandleCount;\r
   EFI_HANDLE                *HandleBuffer;\r
   UINTN                     Index;\r
-  EFI_PCI_IO_PROTOCOL       *PciIo;\r
-  PCI_TYPE00                Pci;\r
+  VOID                      *Instance;\r
 \r
   //\r
   // Start to check all the PciIo to find all possible device\r
@@ -403,7 +451,7 @@ Returns:
   HandleBuffer = NULL;\r
   Status = gBS->LocateHandleBuffer (\r
                   ByProtocol,\r
-                  &gEfiPciIoProtocolGuid,\r
+                  Id,\r
                   NULL,\r
                   &HandleCount,\r
                   &HandleBuffer\r
@@ -413,89 +461,168 @@ Returns:
   }\r
 \r
   for (Index = 0; Index < HandleCount; Index++) {\r
-    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID*)&PciIo);\r
+    Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);\r
     if (EFI_ERROR (Status)) {\r
       continue;\r
     }\r
 \r
+    Status = (*CallBackFunction) (\r
+               HandleBuffer[Index],\r
+               Instance,\r
+               Context\r
+               );\r
+  }\r
+\r
+  gBS->FreePool (HandleBuffer);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VisitingAPciInstance (\r
+  IN EFI_HANDLE  Handle,\r
+  IN VOID        *Instance,\r
+  IN VOID        *Context\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
+  PCI_TYPE00                Pci;\r
+\r
+  PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;\r
+\r
+  //\r
+  // Check for all PCI device\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                    PciIo,\r
+                    EfiPciIoWidthUint32,\r
+                    0,\r
+                    sizeof (Pci) / sizeof (UINT32),\r
+                    &Pci\r
+                    );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (\r
+           Handle,\r
+           PciIo,\r
+           &Pci\r
+           );\r
+\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+VisitAllPciInstances (\r
+  IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
+  )\r
+{\r
+  return VisitAllInstancesOfProtocol (\r
+           &gEfiPciIoProtocolGuid,\r
+           VisitingAPciInstance,\r
+           (VOID*)(UINTN) CallBackFunction\r
+           );\r
+}\r
+\r
+\r
+/**\r
+  Do platform specific PCI Device check and add them to\r
+  ConOut, ConIn, ErrOut.\r
+\r
+  @param[in]  Handle - Handle of PCI device instance\r
+  @param[in]  PciIo - PCI IO protocol instance\r
+  @param[in]  Pci - PCI Header register block\r
+\r
+  @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
+  @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DetectAndPreparePlatformPciDevicePath (\r
+  IN EFI_HANDLE           Handle,\r
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN PCI_TYPE00           *Pci\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+\r
+  Status = PciIo->Attributes (\r
+    PciIo,\r
+    EfiPciIoAttributeOperationEnable,\r
+    EFI_PCI_DEVICE_ENABLE,\r
+    NULL\r
+    );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  if (!mDetectVgaOnly) {\r
     //\r
-    // Check for all PCI device\r
+    // Here we decide whether it is LPC Bridge\r
     //\r
-    Status = PciIo->Pci.Read (\r
-                      PciIo,\r
-                      EfiPciIoWidthUint32,\r
-                      0,\r
-                      sizeof (Pci) / sizeof (UINT32),\r
-                      &Pci\r
-                      );\r
-    if (EFI_ERROR (Status)) {\r
-      continue;\r
-    }\r
-\r
-    if (!DetectVgaOnly) {\r
-      //\r
-      // Here we decide whether it is LPC Bridge\r
-      //\r
-      if ((IS_PCI_LPC (&Pci)) ||\r
-          ((IS_PCI_ISA_PDECODE (&Pci)) &&\r
-           (Pci.Hdr.VendorId == 0x8086) &&\r
-           (Pci.Hdr.DeviceId == 0x7000)\r
-          )\r
-         ) {\r
-        Status = PciIo->Attributes (\r
-          PciIo,\r
-          EfiPciIoAttributeOperationEnable,\r
-          EFI_PCI_DEVICE_ENABLE,\r
-          NULL\r
-          );\r
-        //\r
-        // Add IsaKeyboard to ConIn,\r
-        // add IsaSerial to ConOut, ConIn, ErrOut\r
-        //\r
-        DEBUG ((EFI_D_INFO, "Find the LPC Bridge device\n"));\r
-        PrepareLpcBridgeDevicePath (HandleBuffer[Index]);\r
-        continue;\r
-      }\r
+    if ((IS_PCI_LPC (Pci)) ||\r
+        ((IS_PCI_ISA_PDECODE (Pci)) &&\r
+         (Pci->Hdr.VendorId == 0x8086) &&\r
+         (Pci->Hdr.DeviceId == 0x7000)\r
+        )\r
+       ) {\r
       //\r
-      // Here we decide which Serial device to enable in PCI bus\r
+      // Add IsaKeyboard to ConIn,\r
+      // add IsaSerial to ConOut, ConIn, ErrOut\r
       //\r
-      if (IS_PCI_16550SERIAL (&Pci)) {\r
-        //\r
-        // Add them to ConOut, ConIn, ErrOut.\r
-        //\r
-        DEBUG ((EFI_D_INFO, "Find the 16550 SERIAL device\n"));\r
-        PreparePciSerialDevicePath (HandleBuffer[Index]);\r
-        continue;\r
-      }\r
+      DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));\r
+      PrepareLpcBridgeDevicePath (Handle);\r
+      return EFI_SUCCESS;\r
     }\r
-\r
-    if ((Pci.Hdr.VendorId == 0x8086) &&\r
-        (Pci.Hdr.DeviceId == 0x7010)\r
-       ) {\r
-      Status = PciIo->Attributes (\r
-        PciIo,\r
-        EfiPciIoAttributeOperationEnable,\r
-        EFI_PCI_DEVICE_ENABLE,\r
-        NULL\r
-        );\r
-     }\r
-\r
     //\r
-    // Here we decide which VGA device to enable in PCI bus\r
+    // Here we decide which Serial device to enable in PCI bus\r
     //\r
-    if (IS_PCI_VGA (&Pci)) {\r
+    if (IS_PCI_16550SERIAL (Pci)) {\r
       //\r
-      // Add them to ConOut.\r
+      // Add them to ConOut, ConIn, ErrOut.\r
       //\r
-      DEBUG ((EFI_D_INFO, "Find the VGA device\n"));\r
-      PreparePciVgaDevicePath (HandleBuffer[Index]);\r
-      continue;\r
+      DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));\r
+      PreparePciSerialDevicePath (Handle);\r
+      return EFI_SUCCESS;\r
     }\r
   }\r
 \r
-  gBS->FreePool (HandleBuffer);\r
+  //\r
+  // Here we decide which VGA device to enable in PCI bus\r
+  //\r
+  if (IS_PCI_VGA (Pci)) {\r
+    //\r
+    // Add them to ConOut.\r
+    //\r
+    DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));\r
+    PreparePciVgaDevicePath (Handle);\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
-  return EFI_SUCCESS;\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
+\r
+  @param[in]  DetectVgaOnly - Only detect VGA device if it's TRUE.\r
+\r
+  @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
+  @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
+\r
+**/\r
+EFI_STATUS\r
+DetectAndPreparePlatformPciDevicePaths (\r
+  BOOLEAN DetectVgaOnly\r
+  )\r
+{\r
+  mDetectVgaOnly = DetectVgaOnly;\r
+  return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);\r
 }\r
 \r
 \r
@@ -534,8 +661,6 @@ Returns:
   //\r
   // Connect RootBridge\r
   //\r
-  ConnectRootBridge ();\r
-\r
   VarConout = BdsLibGetVariableAndSize (\r
                 VarConsoleOut,\r
                 &gEfiGlobalVariableGuid,\r
@@ -551,7 +676,7 @@ Returns:
     //\r
     // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
     //\r
-    DetectAndPreparePlatformPciDevicePath (FALSE);\r
+    DetectAndPreparePlatformPciDevicePaths (FALSE);\r
 \r
     //\r
     // Have chance to connect the platform default console,\r
@@ -576,7 +701,7 @@ Returns:
     //\r
     // Only detect VGA device and add them to ConOut\r
     //\r
-    DetectAndPreparePlatformPciDevicePath (TRUE);\r
+    DetectAndPreparePlatformPciDevicePaths (TRUE);\r
   }\r
 \r
   //\r
@@ -596,42 +721,175 @@ PciInitialization (
   )\r
 {\r
   //\r
-  // Device 0 Function 0\r
+  // Bus 0, Device 0, Function 0 - Host to PCI Bridge\r
   //\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,0,0,0x3c), 0x00);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);\r
 \r
   //\r
-  // Device 1 Function 0\r
+  // Bus 0, Device 1, Function 0 - PCI to ISA Bridge\r
   //\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x3c), 0x00);\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x60), 0x8b);\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x61), 0x89);\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x62), 0x0a);\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x63), 0x89);\r
-  //PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x82), 0x02);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // LNKA routing target\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // LNKB routing target\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // LNKC routing target\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // LNKD routing target\r
 \r
   //\r
-  // Device 1 Function 1\r
+  // Bus 0, Device 1, Function 1 - IDE Controller\r
   //\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,1,1,0x3c), 0x00);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);\r
 \r
   //\r
-  // Device 1 Function 3\r
+  // Bus 0, Device 1, Function 3 - Power Managment Controller\r
   //\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x3c), 0x0b);\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x3d), 0x01);\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x5f), 0x90);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x09);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01); // INTA\r
 \r
   //\r
-  // Device 2 Function 0\r
+  // Bus 0, Device 2, Function 0 - Video Controller\r
   //\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,2,0,0x3c), 0x00);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);\r
 \r
   //\r
-  // Device 3 Function 0\r
+  // Bus 0, Device 3, Function 0 - Network Controller\r
+  //\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0a);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01); // INTA (-> LNKC)\r
+\r
+  //\r
+  // Bus 0, Device 5, Function 0 - RAM Memory\r
+  //\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3c), 0x0b);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3d), 0x01); // INTA (-> LNKA)\r
+}\r
+\r
+\r
+VOID\r
+AcpiInitialization (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Set ACPI SCI_EN bit in PMCNTRL\r
   //\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3c), 0x0b);\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3d), 0x01);\r
+  IoOr16 ((PciRead32 (PCI_LIB_ADDRESS (0, 1, 3, 0x40)) & ~BIT0) + 4, BIT0);\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConnectRecursivelyIfPciMassStorage (\r
+  IN EFI_HANDLE           Handle,\r
+  IN EFI_PCI_IO_PROTOCOL  *Instance,\r
+  IN PCI_TYPE00           *PciHeader\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  CHAR16                    *DevPathStr;\r
+\r
+  if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {\r
+    DevicePath = NULL;\r
+    Status = gBS->HandleProtocol (\r
+                    Handle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    (VOID*)&DevicePath\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Print Device Path\r
+    //\r
+    DevPathStr = DevicePathToStr (DevicePath);\r
+    if (DevPathStr != NULL) {\r
+      DEBUG((\r
+        EFI_D_INFO,\r
+        "Found Mass Storage device: %s\n",\r
+        DevPathStr\r
+        ));\r
+      FreePool(DevPathStr);\r
+    }\r
+\r
+    Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  This notification function is invoked when the\r
+  EMU Variable FVB has been changed.\r
+\r
+  @param  Event                 The event that occured\r
+  @param  Context               For EFI compatiblity.  Not used.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EmuVariablesUpdatedCallback (\r
+  IN  EFI_EVENT Event,\r
+  IN  VOID      *Context\r
+  )\r
+{\r
+  DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n"));\r
+  UpdateNvVarsOnFileSystem ();\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VisitingFileSystemInstance (\r
+  IN EFI_HANDLE  Handle,\r
+  IN VOID        *Instance,\r
+  IN VOID        *Context\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  STATIC BOOLEAN  ConnectedToFileSystem = FALSE;\r
+\r
+  if (ConnectedToFileSystem) {\r
+    return EFI_ALREADY_STARTED;\r
+  }\r
+\r
+  Status = ConnectNvVarsToFileSystem (Handle);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  ConnectedToFileSystem = TRUE;\r
+  mEmuVariableEvent =\r
+    EfiCreateProtocolNotifyEvent (\r
+      &gEfiDevicePathProtocolGuid,\r
+      TPL_CALLBACK,\r
+      EmuVariablesUpdatedCallback,\r
+      NULL,\r
+      &mEmuVariableEventReg\r
+      );\r
+  PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+VOID\r
+PlatformBdsRestoreNvVarsFromHardDisk (\r
+  )\r
+{\r
+  VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage);\r
+  VisitAllInstancesOfProtocol (\r
+    &gEfiSimpleFileSystemProtocolGuid,\r
+    VisitingFileSystemInstance,\r
+    NULL\r
+    );\r
+\r
 }\r
 \r
 \r
@@ -681,6 +939,12 @@ Returns:
   BdsLibConnectAll ();\r
 \r
   PciInitialization ();\r
+  AcpiInitialization ();\r
+\r
+  //\r
+  // Clear the logo after all devices are connected.\r
+  //\r
+  gST->ConOut->ClearScreen (gST->ConOut);\r
 }\r
 \r
 VOID\r
@@ -711,7 +975,8 @@ Returns:
 VOID\r
 PlatformBdsDiagnostics (\r
   IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,\r
-  IN BOOLEAN                     QuietBoot\r
+  IN BOOLEAN                     QuietBoot,\r
+  IN BASEM_MEMORY_TEST           BaseMemoryTest\r
   )\r
 /*++\r
 \r
@@ -726,6 +991,8 @@ Arguments:
 \r
   QuietBoot        - Indicate if need to enable the quiet boot\r
 \r
+  BaseMemoryTest   - A pointer to BaseMemoryTest()\r
+\r
 Returns:\r
 \r
   None.\r
@@ -743,11 +1010,11 @@ Returns:
   // from the graphic lib\r
   //\r
   if (QuietBoot) {\r
-    EnableQuietBoot (&gEfiDefaultBmpLogoGuid);\r
+    EnableQuietBoot (PcdGetPtr(PcdLogoFile));\r
     //\r
     // Perform system diagnostic\r
     //\r
-    Status = BdsMemoryTest (MemoryTestLevel);\r
+    Status = BaseMemoryTest (MemoryTestLevel);\r
     if (EFI_ERROR (Status)) {\r
       DisableQuietBoot ();\r
     }\r
@@ -757,16 +1024,17 @@ Returns:
   //\r
   // Perform system diagnostic\r
   //\r
-  Status = BdsMemoryTest (MemoryTestLevel);\r
+  Status = BaseMemoryTest (MemoryTestLevel);\r
 }\r
 \r
 \r
 VOID\r
 EFIAPI\r
 PlatformBdsPolicyBehavior (\r
-  IN EFI_BDS_ARCH_PROTOCOL_INSTANCE  *PrivateData,\r
   IN OUT LIST_ENTRY                  *DriverOptionList,\r
-  IN OUT LIST_ENTRY                  *BootOptionList\r
+  IN OUT LIST_ENTRY                  *BootOptionList,\r
+  IN PROCESS_CAPSULES                ProcessCapsules,\r
+  IN BASEM_MEMORY_TEST               BaseMemoryTest\r
   )\r
 /*++\r
 \r
@@ -778,12 +1046,14 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  PrivateData      - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance\r
-\r
   DriverOptionList - The header of the driver option link list\r
 \r
   BootOptionList   - The header of the boot option link list\r
 \r
+  ProcessCapsules  - A pointer to ProcessCapsules()\r
+\r
+  BaseMemoryTest   - A pointer to BaseMemoryTest()\r
+\r
 Returns:\r
 \r
   None.\r
@@ -798,9 +1068,23 @@ Returns:
   UINTN                              Index;\r
   EFI_INPUT_KEY                      Key;\r
   EFI_TPL                            OldTpl;\r
+  EFI_BOOT_MODE                      BootMode;\r
 \r
   DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));\r
 \r
+  ConnectRootBridge ();\r
+\r
+  if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {\r
+    DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "\r
+      "from disk since flash variables appear to be supported.\n"));\r
+  } else {\r
+    //\r
+    // Try to restore variables from the hard disk early so\r
+    // they can be used for the other BDS connect operations.\r
+    //\r
+    PlatformBdsRestoreNvVarsFromHardDisk ();\r
+  }\r
+\r
   //\r
   // Init the time out value\r
   //\r
@@ -814,14 +1098,14 @@ Returns:
   //\r
   // Get current Boot Mode\r
   //\r
-  Status = BdsLibGetBootMode (&PrivateData->BootMode);\r
-  DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", PrivateData->BootMode));\r
+  Status = BdsLibGetBootMode (&BootMode);\r
+  DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));\r
 \r
   //\r
   // Go the different platform policy with different boot mode\r
   // Notes: this part code can be change with the table policy\r
   //\r
-  ASSERT (PrivateData->BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
+  ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
   //\r
   // Connect platform console\r
   //\r
@@ -848,13 +1132,18 @@ Returns:
   //\r
   // Memory test and Logo show\r
   //\r
-  PlatformBdsDiagnostics (IGNORE, TRUE);\r
+  PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);\r
 \r
   //\r
   // Perform some platform specific connect sequence\r
   //\r
   PlatformBdsConnectSequence ();\r
 \r
+  //\r
+  // Process QEMU's -kernel command line option\r
+  //\r
+  TryRunningQemuKernel ();\r
+\r
   //\r
   // Give one chance to enter the setup if we\r
   // have the time out\r
@@ -867,24 +1156,12 @@ Returns:
   BdsLibConnectAll ();\r
   BdsLibEnumerateAllBootOption (BootOptionList);\r
 \r
+  SetBootOrderFromQemu (BootOptionList);\r
   //\r
-  // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot\r
-  // checking code in real production tip.\r
+  // The BootOrder variable may have changed, reload the in-memory list with\r
+  // it.\r
   //\r
-  // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device\r
-  // and do enumerate all the default boot options. But in development system board, the boot mode\r
-  // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box\r
-  // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.\r
-  //\r
-  Status = BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
-  if (EFI_ERROR(Status)) {\r
-    //\r
-    // If cannot find "BootOrder" variable,  it may be first boot.\r
-    // Try to connect all devices and enumerate all boot options here.\r
-    //\r
-    BdsLibConnectAll ();\r
-    BdsLibEnumerateAllBootOption (BootOptionList);\r
-  }\r
+  BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
 \r
   //\r
   // To give the User a chance to enter Setup here, if user set TimeOut is 0.\r
@@ -1039,12 +1316,134 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
+VOID\r
 EFIAPI\r
 PlatformBdsLockNonUpdatableFlash (\r
   VOID\r
   )\r
 {\r
   DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));\r
-  return EFI_SUCCESS;\r
+  return;\r
 }\r
+\r
+\r
+/**\r
+  This notification function is invoked when an instance of the\r
+  EFI_DEVICE_PATH_PROTOCOL is produced.\r
+\r
+  @param  Event                 The event that occured\r
+  @param  Context               For EFI compatiblity.  Not used.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+NotifyDevPath (\r
+  IN  EFI_EVENT Event,\r
+  IN  VOID      *Context\r
+  )\r
+{\r
+  EFI_HANDLE                            Handle;\r
+  EFI_STATUS                            Status;\r
+  UINTN                                 BufferSize;\r
+  EFI_DEVICE_PATH_PROTOCOL             *DevPathNode;\r
+  ATAPI_DEVICE_PATH                    *Atapi;\r
+\r
+  //\r
+  // Examine all new handles\r
+  //\r
+  for (;;) {\r
+    //\r
+    // Get the next handle\r
+    //\r
+    BufferSize = sizeof (Handle);\r
+    Status = gBS->LocateHandle (\r
+              ByRegisterNotify,\r
+              NULL,\r
+              mEfiDevPathNotifyReg,\r
+              &BufferSize,\r
+              &Handle\r
+              );\r
+\r
+    //\r
+    // If not found, we're done\r
+    //\r
+    if (EFI_NOT_FOUND == Status) {\r
+      break;\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Get the DevicePath protocol on that handle\r
+    //\r
+    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    while (!IsDevicePathEnd (DevPathNode)) {\r
+      //\r
+      // Find the handler to dump this device path node\r
+      //\r
+      if (\r
+           (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&\r
+           (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)\r
+         ) {\r
+        Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;\r
+        PciOr16 (\r
+          PCI_LIB_ADDRESS (\r
+            0,\r
+            1,\r
+            1,\r
+            (Atapi->PrimarySecondary == 1) ? 0x42: 0x40\r
+            ),\r
+          BIT15\r
+          );\r
+      }\r
+\r
+      //\r
+      // Next device path node\r
+      //\r
+      DevPathNode = NextDevicePathNode (DevPathNode);\r
+    }\r
+  }\r
+\r
+  return;\r
+}\r
+\r
+\r
+VOID\r
+InstallDevicePathCallback (\r
+  VOID\r
+  )\r
+{\r
+  DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));\r
+  mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (\r
+                          &gEfiDevicePathProtocolGuid,\r
+                          TPL_CALLBACK,\r
+                          NotifyDevPath,\r
+                          NULL,\r
+                          &mEfiDevPathNotifyReg\r
+                          );\r
+}\r
+\r
+/**\r
+  Lock the ConsoleIn device in system table. All key\r
+  presses will be ignored until the Password is typed in. The only way to\r
+  disable the password is to type it in to a ConIn device.\r
+\r
+  @param  Password        Password used to lock ConIn device.\r
+\r
+  @retval EFI_SUCCESS     lock the Console In Spliter virtual handle successfully.\r
+  @retval EFI_UNSUPPORTED Password not found\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LockKeyboards (\r
+  IN  CHAR16    *Password\r
+  )\r
+{\r
+    return EFI_UNSUPPORTED;\r
+}\r
+\r