]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[mirror_edk2.git] / Vlv2TbltDevicePkg / FvbRuntimeDxe / FvbServiceDxe.c
diff --git a/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c b/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
new file mode 100644 (file)
index 0000000..3b45aa2
--- /dev/null
@@ -0,0 +1,204 @@
+/** @file\r
+  Firmware Volume Block Driver for Lakeport Platform.\r
+\r
+  Firmware volume block driver for FWH or SPI device.\r
+  It depends on which Flash Device Library to be linked with this driver.\r
+\r
+Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>\r
+                                                                                   \r\r
+  This program and the accompanying materials are licensed and made available under\r\r
+  the terms and conditions of the BSD License that accompanies this distribution.  \r\r
+  The full text of the license may be found at                                     \r\r
+  http://opensource.org/licenses/bsd-license.php.                                  \r\r
+                                                                                   \r\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,            \r\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.    \r\r
+                                                                                   \r\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+#include <Library/UefiRuntimeLib.h>\r
+#include "FvbService.h"\r
+\r
+extern FWB_GLOBAL              mFvbModuleGlobal;\r
+\r
+/**\r
+  Call back function on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
+\r
+  Fixup internal data so that the driver is callable in EFI runtime\r
+  in virtual mode. Convert the mFvbModuleGlobal date items to there\r
+  virtual address.\r
+\r
+  @param  Event     Event whose notification function is being invoked.\r
+  @param  Context   The context of the Notification context. Not used in\r
+                    this call back function.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FvbVirtualddressChangeEvent (\r
+  IN EFI_EVENT                          Event,\r
+  IN VOID                               *Context\r
+  )\r
+{\r
+  EFI_FW_VOL_INSTANCE                   *FwhInstance;\r
+  UINTN                                 Index;\r
+\r
+  //\r
+  // Convert the base address of all the instances.\r
+  //\r
+  for (Index = 0; Index < mFvbModuleGlobal.NumFv; Index++) {\r
+    FwhInstance = GetFvbInstance (Index);\r
+    EfiConvertPointer (0, (VOID **) &FwhInstance->FvBase);\r
+  }\r
+\r
+  EfiConvertPointer (0, (VOID **) &mFvbModuleGlobal.FvInstance);\r
+}\r
+\r
+\r
+/**\r
+  The function installs EFI_FIRMWARE_VOLUME_BLOCK protocol\r
+  for each FV in the system.\r
+\r
+  @param[in]  FwhInstance   The pointer to a FW volume instance structure,\r
+                            which contains the information about one FV.\r
+  @param[in]  InstanceNum   The instance number which can be used as a ID\r
+                            to locate this FwhInstance in other functions.\r
+\r
+  @retval     VOID\r
+\r
+**/\r
+VOID\r
+InstallFvbProtocol (\r
+  IN  EFI_FW_VOL_INSTANCE               *FwhInstance,\r
+  IN  UINTN                             InstanceNum\r
+  )\r
+{\r
+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;\r
+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
+  EFI_STATUS                            Status;\r
+  EFI_HANDLE                            FwbHandle;\r
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *OldFwbInterface;\r
+\r
+  FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *) AllocateRuntimeCopyPool (\r
+                                            sizeof (EFI_FW_VOL_BLOCK_DEVICE),\r
+                                            &mFvbDeviceTemplate\r
+                                            );\r
+  ASSERT (FvbDevice != NULL);\r
+\r
+  FvbDevice->Instance = InstanceNum;\r
+  FwVolHeader = &FwhInstance->VolumeHeader;\r
+\r
+  //\r
+  // Set up the devicepath.\r
+  //\r
+  DEBUG ((EFI_D_INFO, "FwBlockService.c: Setting up DevicePath for 0x%lx:\n", FwhInstance->FvBase));\r
+  if (FwVolHeader->ExtHeaderOffset == 0) {\r
+    //\r
+    // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH.\r
+    //\r
+    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);\r
+    ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = FwhInstance->FvBase;\r
+    ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress   = FwhInstance->FvBase + FwVolHeader->FvLength - 1;\r
+  } else {\r
+    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);\r
+    CopyGuid (\r
+      &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName,\r
+      (GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset)\r
+      );\r
+  }\r
+\r
+  //\r
+  // Find a handle with a matching device path that has supports FW Block protocol.\r
+  //\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiFirmwareVolumeBlockProtocolGuid,\r
+                  &FvbDevice->DevicePath,\r
+                  &FwbHandle\r
+                  );\r
+  if (EFI_ERROR (Status) ) {\r
+    //\r
+    // LocateDevicePath fails so install a new interface and device path.\r
+    //\r
+    DEBUG ((EFI_D_INFO, "FwBlockService.c: LocateDevicePath failed, install new interface 0x%lx:\n", FwhInstance->FvBase));\r
+    FwbHandle = NULL;\r
+    Status =  gBS->InstallMultipleProtocolInterfaces (\r
+                     &FwbHandle,\r
+                     &gEfiFirmwareVolumeBlockProtocolGuid,\r
+                     &FvbDevice->FwVolBlockInstance,\r
+                     &gEfiDevicePathProtocolGuid,\r
+                     FvbDevice->DevicePath,\r
+                     NULL\r
+                     );\r
+    ASSERT_EFI_ERROR (Status);\r
+    DEBUG ((EFI_D_INFO, "FwBlockService.c: IMPI FirmwareVolBlockProt, DevPath 0x%lx: %r\n", FwhInstance->FvBase, Status));\r
+\r
+  } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {\r
+    //\r
+    // Device allready exists, so reinstall the FVB protocol.\r
+    //\r
+    DEBUG ((EFI_D_ERROR, "FwBlockService.c: LocateDevicePath succeeded, reinstall interface 0x%lx:\n", FwhInstance->FvBase));\r
+    Status = gBS->HandleProtocol (\r
+                    FwbHandle,\r
+                    &gEfiFirmwareVolumeBlockProtocolGuid,\r
+                    (VOID **) &OldFwbInterface\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Status =  gBS->ReinstallProtocolInterface (\r
+                     FwbHandle,\r
+                     &gEfiFirmwareVolumeBlockProtocolGuid,\r
+                     OldFwbInterface,\r
+                     &FvbDevice->FwVolBlockInstance\r
+                     );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+  } else {\r
+    //\r
+    // There was a FVB protocol on an End Device Path node.\r
+    //\r
+    ASSERT (FALSE);\r
+  }\r
+\r
+}\r
+\r
+\r
+/**\r
+  The driver entry point for Firmware Volume Block Driver.\r
+\r
+  The function does the necessary initialization work for\r
+  Firmware Volume Block Driver.\r
+\r
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.\r
+  @param[in]  SystemTable       A pointer to the EFI system table.\r
+\r
+  @retval     EFI_SUCCESS       This funtion always return EFI_SUCCESS.\r
+                                It will ASSERT on errors.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeFvbInitialize (\r
+  IN EFI_HANDLE                         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                   *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_EVENT                             Event;\r
+\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  FvbVirtualddressChangeEvent,\r
+                  NULL,\r
+                  &gEfiEventVirtualAddressChangeGuid,\r
+                  &Event\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  FvbInitialize ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r