FwBlockServiceDxe.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /**@file
  2. Functions related to the Firmware Volume Block service whose
  3. implementation is specific to the runtime DXE driver build.
  4. Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
  5. Copyright (C) 2015, Red Hat, Inc.
  6. Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
  7. SPDX-License-Identifier: BSD-2-Clause-Patent
  8. **/
  9. #include <Guid/EventGroup.h>
  10. #include <Library/DebugLib.h>
  11. #include <Library/DevicePathLib.h>
  12. #include <Library/PcdLib.h>
  13. #include <Library/UefiBootServicesTableLib.h>
  14. #include <Library/UefiRuntimeLib.h>
  15. #include <Protocol/DevicePath.h>
  16. #include <Protocol/FirmwareVolumeBlock.h>
  17. #include "FwBlockService.h"
  18. #include "RamFlash.h"
  19. VOID
  20. InstallProtocolInterfaces (
  21. IN EFI_FW_VOL_BLOCK_DEVICE *FvbDevice
  22. )
  23. {
  24. EFI_STATUS Status;
  25. EFI_HANDLE FwbHandle;
  26. EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface;
  27. //
  28. // Find a handle with a matching device path that has supports FW Block
  29. // protocol
  30. //
  31. Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid,
  32. &FvbDevice->DevicePath, &FwbHandle);
  33. if (EFI_ERROR (Status)) {
  34. //
  35. // LocateDevicePath fails so install a new interface and device path
  36. //
  37. FwbHandle = NULL;
  38. DEBUG ((DEBUG_INFO, "Installing RAM FVB\n"));
  39. Status = gBS->InstallMultipleProtocolInterfaces (
  40. &FwbHandle,
  41. &gEfiFirmwareVolumeBlockProtocolGuid,
  42. &FvbDevice->FwVolBlockInstance,
  43. &gEfiDevicePathProtocolGuid,
  44. FvbDevice->DevicePath,
  45. NULL
  46. );
  47. ASSERT_EFI_ERROR (Status);
  48. } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {
  49. //
  50. // Device already exists, so reinstall the FVB protocol
  51. //
  52. Status = gBS->HandleProtocol (
  53. FwbHandle,
  54. &gEfiFirmwareVolumeBlockProtocolGuid,
  55. (VOID**)&OldFwbInterface
  56. );
  57. ASSERT_EFI_ERROR (Status);
  58. DEBUG ((DEBUG_INFO, "Reinstalling FVB for Ram flash region\n"));
  59. Status = gBS->ReinstallProtocolInterface (
  60. FwbHandle,
  61. &gEfiFirmwareVolumeBlockProtocolGuid,
  62. OldFwbInterface,
  63. &FvbDevice->FwVolBlockInstance
  64. );
  65. ASSERT_EFI_ERROR (Status);
  66. } else {
  67. //
  68. // There was a FVB protocol on an End Device Path node
  69. //
  70. ASSERT (FALSE);
  71. }
  72. }
  73. /*++
  74. Routine Description:
  75. Fixup internal data so that EFI and SAL can be call in virtual mode.
  76. Call the passed in Child Notify event and convert the mFvbModuleGlobal
  77. date items to there virtual address.
  78. Arguments:
  79. (Standard EFI notify event - EFI_EVENT_NOTIFY)
  80. Returns:
  81. None
  82. --*/
  83. STATIC
  84. VOID
  85. EFIAPI
  86. FvbVirtualAddressChangeEvent (
  87. IN EFI_EVENT Event,
  88. IN VOID *Context
  89. )
  90. {
  91. EFI_FW_VOL_INSTANCE *FwhInstance;
  92. UINTN Index;
  93. FwhInstance = mFvbModuleGlobal->FvInstance;
  94. EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance);
  95. //
  96. // Convert the base address of all the instances
  97. //
  98. Index = 0;
  99. while (Index < mFvbModuleGlobal->NumFv) {
  100. EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase);
  101. FwhInstance = (EFI_FW_VOL_INSTANCE *)
  102. (
  103. (UINTN)FwhInstance +
  104. FwhInstance->VolumeHeader.HeaderLength +
  105. (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
  106. );
  107. Index++;
  108. }
  109. EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal);
  110. RamFlashConvertPointers ();
  111. }
  112. VOID
  113. InstallVirtualAddressChangeHandler (
  114. VOID
  115. )
  116. {
  117. EFI_STATUS Status;
  118. EFI_EVENT VirtualAddressChangeEvent;
  119. Status = gBS->CreateEventEx (
  120. EVT_NOTIFY_SIGNAL,
  121. TPL_NOTIFY,
  122. FvbVirtualAddressChangeEvent,
  123. NULL,
  124. &gEfiEventVirtualAddressChangeGuid,
  125. &VirtualAddressChangeEvent
  126. );
  127. ASSERT_EFI_ERROR (Status);
  128. }