]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
OVMF BDS: Make use of NvVarsFileLib to make NV variable less volatile.
[mirror_edk2.git] / OvmfPkg / Library / PlatformBdsLib / BdsPlatform.c
index 8a93117f4dd23ecfa2b893b8f0aaac10baa8adc7..e7247ac262bd8784da1766b13eee219dc57a55c7 100644 (file)
 #include "BdsPlatform.h"\r
 \r
 \r
+//\r
+// Global data\r
+//\r
+\r
+VOID          *mEfiDevPathNotifyReg;\r
+EFI_EVENT     mEfiDevPathEvent;\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
+STATIC\r
+VOID\r
+LoadVideoRom (\r
+  VOID\r
+  );\r
+\r
+STATIC\r
+EFI_STATUS\r
+PciRomLoadEfiDriversFromRomImage (\r
+  IN EFI_PHYSICAL_ADDRESS    Rom,\r
+  IN UINTN                   RomSize\r
+  );\r
+\r
 //\r
 // BDS Platform Functions\r
 //\r
@@ -39,6 +108,8 @@ Returns:
 --*/\r
 {\r
   DEBUG ((EFI_D_INFO, "PlatformBdsInit\n"));\r
+  InstallDevicePathCallback ();\r
+  LoadVideoRom ();\r
 }\r
 \r
 \r
@@ -367,32 +438,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
@@ -401,7 +457,7 @@ Returns:
   HandleBuffer = NULL;\r
   Status = gBS->LocateHandleBuffer (\r
                   ByProtocol,\r
-                  &gEfiPciIoProtocolGuid,\r
+                  Id,\r
                   NULL,\r
                   &HandleCount,\r
                   &HandleBuffer\r
@@ -411,89 +467,167 @@ 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) 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*) 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
+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
@@ -532,8 +666,6 @@ Returns:
   //\r
   // Connect RootBridge\r
   //\r
-  ConnectRootBridge ();\r
-\r
   VarConout = BdsLibGetVariableAndSize (\r
                 VarConsoleOut,\r
                 &gEfiGlobalVariableGuid,\r
@@ -549,7 +681,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
@@ -574,7 +706,7 @@ Returns:
     //\r
     // Only detect VGA device and add them to ConOut\r
     //\r
-    DetectAndPreparePlatformPciDevicePath (TRUE);\r
+    DetectAndPreparePlatformPciDevicePaths (TRUE);\r
   }\r
 \r
   //\r
@@ -594,42 +726,131 @@ 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);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x09);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0b);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x09);\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), 0x0b);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01);\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), 0x0b);\r
-  PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3d), 0x01);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0b);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01);\r
+\r
+  //\r
+  // Bus 0, Device 4, Function 0 - RAM Memory\r
+  //\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3c), 0x09);\r
+  PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3d), 0x01);\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
+    DEBUG((\r
+      EFI_D_INFO,\r
+      "Found Mass Storage device: %s\n",\r
+      DevPathStr\r
+      ));\r
+    FreePool(DevPathStr);\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
+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
+  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
@@ -679,6 +900,11 @@ Returns:
   BdsLibConnectAll ();\r
 \r
   PciInitialization ();\r
+\r
+  //\r
+  // Clear the logo after all devices are connected.\r
+  //\r
+  gST->ConOut->ClearScreen (gST->ConOut);\r
 }\r
 \r
 VOID\r
@@ -709,7 +935,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
@@ -724,6 +951,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
@@ -741,11 +970,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
@@ -755,7 +984,7 @@ Returns:
   //\r
   // Perform system diagnostic\r
   //\r
-  Status = BdsMemoryTest (MemoryTestLevel);\r
+  Status = BaseMemoryTest (MemoryTestLevel);\r
 }\r
 \r
 \r
@@ -763,7 +992,9 @@ VOID
 EFIAPI\r
 PlatformBdsPolicyBehavior (\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
@@ -779,6 +1010,10 @@ Arguments:
 \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
@@ -797,6 +1032,14 @@ Returns:
 \r
   DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));\r
 \r
+  ConnectRootBridge ();\r
+\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
   // Init the time out value\r
   //\r
@@ -844,7 +1087,7 @@ 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
@@ -1035,12 +1278,306 @@ 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
+\r
+STATIC\r
+VOID\r
+LoadVideoRom (\r
+  VOID\r
+  )\r
+{\r
+  PCI_DATA_STRUCTURE            *Pcir;\r
+  UINTN                         RomSize;\r
+\r
+  //\r
+  // The virtual machines sometimes load the video rom image\r
+  // directly at the legacy video BIOS location of C000:0000,\r
+  // and do not implement the PCI expansion ROM feature.\r
+  //\r
+  Pcir = (PCI_DATA_STRUCTURE *) (UINTN) 0xc0000;\r
+  RomSize = Pcir->ImageLength * 512;\r
+  PciRomLoadEfiDriversFromRomImage (0xc0000, RomSize);\r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+PciRomLoadEfiDriversFromRomImage (\r
+  IN EFI_PHYSICAL_ADDRESS    Rom,\r
+  IN UINTN                   RomSize\r
+  )\r
+{\r
+  CHAR16                        *FileName;\r
+  EFI_PCI_EXPANSION_ROM_HEADER  *EfiRomHeader;\r
+  PCI_DATA_STRUCTURE            *Pcir;\r
+  UINTN                         ImageIndex;\r
+  UINTN                         RomOffset;\r
+  UINT32                        ImageSize;\r
+  UINT16                        ImageOffset;\r
+  EFI_HANDLE                    ImageHandle;\r
+  EFI_STATUS                    Status;\r
+  EFI_STATUS                    retStatus;\r
+  EFI_DEVICE_PATH_PROTOCOL      *FilePath;\r
+  BOOLEAN                       SkipImage;\r
+  UINT32                        DestinationSize;\r
+  UINT32                        ScratchSize;\r
+  UINT8                         *Scratch;\r
+  VOID                          *ImageBuffer;\r
+  VOID                          *DecompressedImageBuffer;\r
+  UINT32                        ImageLength;\r
+  EFI_DECOMPRESS_PROTOCOL       *Decompress;\r
+\r
+  FileName = L"PciRomInMemory";\r
+\r
+  //FileName = L"PciRom Addr=0000000000000000";\r
+  //HexToString (&FileName[12], Rom, 16);\r
+\r
+  ImageIndex    = 0;\r
+  retStatus     = EFI_NOT_FOUND;\r
+  RomOffset  = (UINTN) Rom;\r
+\r
+  do {\r
+\r
+    EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomOffset;\r
+\r
+    if (EfiRomHeader->Signature != 0xaa55) {\r
+      return retStatus;\r
+    }\r
+\r
+    Pcir      = (PCI_DATA_STRUCTURE *) (UINTN) (RomOffset + EfiRomHeader->PcirOffset);\r
+    ImageSize = Pcir->ImageLength * 512;\r
+\r
+    if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
+        (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {\r
+\r
+      if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
+          (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {\r
+\r
+        ImageOffset             = EfiRomHeader->EfiImageHeaderOffset;\r
+        ImageSize               = EfiRomHeader->InitializationSize * 512;\r
+\r
+        ImageBuffer             = (VOID *) (UINTN) (RomOffset + ImageOffset);\r
+        ImageLength             = ImageSize - ImageOffset;\r
+        DecompressedImageBuffer = NULL;\r
+\r
+        //\r
+        // decompress here if needed\r
+        //\r
+        SkipImage = FALSE;\r
+        if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+          SkipImage = TRUE;\r
+        }\r
+\r
+        if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+          Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
+          if (EFI_ERROR (Status)) {\r
+            SkipImage = TRUE;\r
+          } else {\r
+            SkipImage = TRUE;\r
+            Status = Decompress->GetInfo (\r
+                                  Decompress,\r
+                                  ImageBuffer,\r
+                                  ImageLength,\r
+                                  &DestinationSize,\r
+                                  &ScratchSize\r
+                                  );\r
+            if (!EFI_ERROR (Status)) {\r
+              DecompressedImageBuffer = NULL;\r
+              DecompressedImageBuffer = AllocatePool (DestinationSize);\r
+              if (DecompressedImageBuffer != NULL) {\r
+                Scratch = AllocatePool (ScratchSize);\r
+                if (Scratch != NULL) {\r
+                  Status = Decompress->Decompress (\r
+                                        Decompress,\r
+                                        ImageBuffer,\r
+                                        ImageLength,\r
+                                        DecompressedImageBuffer,\r
+                                        DestinationSize,\r
+                                        Scratch,\r
+                                        ScratchSize\r
+                                        );\r
+                  if (!EFI_ERROR (Status)) {\r
+                    ImageBuffer = DecompressedImageBuffer;\r
+                    ImageLength = DestinationSize;\r
+                    SkipImage   = FALSE;\r
+                  }\r
+\r
+                  gBS->FreePool (Scratch);\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+\r
+        if (!SkipImage) {\r
+\r
+          //\r
+          // load image and start image\r
+          //\r
+\r
+          FilePath = FileDevicePath (NULL, FileName);\r
+\r
+          Status = gBS->LoadImage (\r
+                          FALSE,\r
+                          gImageHandle,\r
+                          FilePath,\r
+                          ImageBuffer,\r
+                          ImageLength,\r
+                          &ImageHandle\r
+                          );\r
+          if (!EFI_ERROR (Status)) {\r
+            Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
+            if (!EFI_ERROR (Status)) {\r
+              retStatus = Status;\r
+            }\r
+          }\r
+          if (FilePath != NULL) {\r
+            gBS->FreePool (FilePath);\r
+          }\r
+        }\r
+\r
+        if (DecompressedImageBuffer != NULL) {\r
+          gBS->FreePool (DecompressedImageBuffer);\r
+        }\r
+\r
+      }\r
+    }\r
+\r
+    RomOffset = RomOffset + ImageSize;\r
+    ImageIndex++;\r
+  } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomOffset - (UINTN) Rom) < RomSize));\r
+\r
+  return retStatus;\r
+}\r
+\r
+\r