]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
OvmfPkg/QemuFlashFvbServicesRuntimeDxe: mark Flash memory range as MMIO
[mirror_edk2.git] / OvmfPkg / QemuFlashFvbServicesRuntimeDxe / FwBlockService.c
index 3e7fe6808169c1ffa2291f880bef2e276e27dfcd..b3f428bb4284c9f4c7ea4cfe4fc3687ae8abc1e3 100644 (file)
 \r
 **/\r
 \r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <PiDxe.h>\r
-\r
 //\r
 // The protocols, PPI and GUID defintions for this module\r
 //\r
-#include <Guid/EventGroup.h>\r
-#include <Protocol/FirmwareVolumeBlock.h>\r
 #include <Protocol/DevicePath.h>\r
+#include <Protocol/FirmwareVolumeBlock.h>\r
 \r
 //\r
 // The Library classes this module consumes\r
 //\r
-#include <Library/UefiLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
 #include <Library/BaseLib.h>\r
-#include <Library/DxeServicesTableLib.h>\r
-#include <Library/UefiRuntimeLib.h>\r
-#include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/DevicePathLib.h>\r
 \r
 #include "FwBlockService.h"\r
 #include "QemuFlash.h"\r
@@ -117,70 +108,11 @@ EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {
 };\r
 \r
 \r
-\r
-VOID\r
-EFIAPI\r
-FvbVirtualddressChangeEvent (\r
-  IN EFI_EVENT        Event,\r
-  IN VOID             *Context\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-\r
-    Fixup internal data so that EFI and SAL can be call in virtual mode.\r
-    Call the passed in Child Notify event and convert the mFvbModuleGlobal\r
-    date items to there virtual address.\r
-\r
-    mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]  - Physical copy of instance\r
-                                                  data\r
-    mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]   - Virtual pointer to common\r
-                                                  instance data.\r
-\r
-  Arguments:\r
-\r
-    (Standard EFI notify event - EFI_EVENT_NOTIFY)\r
-\r
-  Returns:\r
-\r
-    None\r
-\r
---*/\r
-{\r
-  EFI_FW_VOL_INSTANCE *FwhInstance;\r
-  UINTN               Index;\r
-\r
-  EfiConvertPointer (0x0,\r
-    (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]);\r
-\r
-  //\r
-  // Convert the base address of all the instances\r
-  //\r
-  Index       = 0;\r
-  FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];\r
-  while (Index < mFvbModuleGlobal->NumFv) {\r
-    EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]);\r
-    FwhInstance = (EFI_FW_VOL_INSTANCE *)\r
-      (\r
-        (UINTN) ((UINT8 *) FwhInstance) +\r
-        FwhInstance->VolumeHeader.HeaderLength +\r
-        (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))\r
-      );\r
-    Index++;\r
-  }\r
-\r
-  EfiConvertPointer (0x0,\r
-    (VOID **) &mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL]);\r
-  EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal);\r
-  QemuFlashConvertPointers ();\r
-}\r
-\r
 EFI_STATUS\r
 GetFvbInstance (\r
   IN  UINTN                               Instance,\r
   IN  ESAL_FWB_GLOBAL                     *Global,\r
-  OUT EFI_FW_VOL_INSTANCE                 **FwhInstance,\r
-  IN BOOLEAN                              Virtual\r
+  OUT EFI_FW_VOL_INSTANCE                 **FwhInstance\r
   )\r
 /*++\r
 \r
@@ -193,7 +125,6 @@ GetFvbInstance (
     Global                - Pointer to ESAL_FWB_GLOBAL that contains all\r
                             instance data\r
     FwhInstance           - The EFI_FW_VOL_INSTANCE fimrware instance structure\r
-    Virtual               - Whether CPU is in virtual or physical mode\r
 \r
   Returns:\r
     EFI_SUCCESS           - Successfully returns\r
@@ -210,7 +141,7 @@ GetFvbInstance (
   //\r
   // Find the right instance of the FVB private data\r
   //\r
-  FwhRecord = Global->FvInstance[Virtual];\r
+  FwhRecord = Global->FvInstance;\r
   while (Instance > 0) {\r
     FwhRecord = (EFI_FW_VOL_INSTANCE *)\r
       (\r
@@ -229,8 +160,7 @@ EFI_STATUS
 FvbGetPhysicalAddress (\r
   IN UINTN                                Instance,\r
   OUT EFI_PHYSICAL_ADDRESS                *Address,\r
-  IN ESAL_FWB_GLOBAL                      *Global,\r
-  IN BOOLEAN                              Virtual\r
+  IN ESAL_FWB_GLOBAL                      *Global\r
   )\r
 /*++\r
 \r
@@ -245,7 +175,6 @@ FvbGetPhysicalAddress (
                             address of the firmware volume.\r
     Global                - Pointer to ESAL_FWB_GLOBAL that contains all\r
                             instance data\r
-    Virtual               - Whether CPU is in virtual or physical mode\r
 \r
   Returns:\r
     EFI_SUCCESS           - Successfully returns\r
@@ -259,9 +188,9 @@ FvbGetPhysicalAddress (
   //\r
   // Find the right instance of the FVB private data\r
   //\r
-  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
+  Status = GetFvbInstance (Instance, Global, &FwhInstance);\r
   ASSERT_EFI_ERROR (Status);\r
-  *Address = FwhInstance->FvBase[Virtual];\r
+  *Address = FwhInstance->FvBase;\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -270,8 +199,7 @@ EFI_STATUS
 FvbGetVolumeAttributes (\r
   IN UINTN                                Instance,\r
   OUT EFI_FVB_ATTRIBUTES_2                *Attributes,\r
-  IN ESAL_FWB_GLOBAL                      *Global,\r
-  IN BOOLEAN                              Virtual\r
+  IN ESAL_FWB_GLOBAL                      *Global\r
   )\r
 /*++\r
 \r
@@ -285,7 +213,6 @@ FvbGetVolumeAttributes (
     Attributes            - Output buffer which contains attributes\r
     Global                - Pointer to ESAL_FWB_GLOBAL that contains all\r
                             instance data\r
-    Virtual               - Whether CPU is in virtual or physical mode\r
 \r
   Returns:\r
     EFI_SUCCESS           - Successfully returns\r
@@ -299,7 +226,7 @@ FvbGetVolumeAttributes (
   //\r
   // Find the right instance of the FVB private data\r
   //\r
-  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
+  Status = GetFvbInstance (Instance, Global, &FwhInstance);\r
   ASSERT_EFI_ERROR (Status);\r
   *Attributes = FwhInstance->VolumeHeader.Attributes;\r
 \r
@@ -313,8 +240,7 @@ FvbGetLbaAddress (
   OUT UINTN                               *LbaAddress,\r
   OUT UINTN                               *LbaLength,\r
   OUT UINTN                               *NumOfBlocks,\r
-  IN  ESAL_FWB_GLOBAL                     *Global,\r
-  IN  BOOLEAN                             Virtual\r
+  IN  ESAL_FWB_GLOBAL                     *Global\r
   )\r
 /*++\r
 \r
@@ -333,7 +259,6 @@ FvbGetLbaAddress (
                             BlockSize\r
     Global                - Pointer to ESAL_FWB_GLOBAL that contains all\r
                             instance data\r
-    Virtual               - Whether CPU is in virtual or physical mode\r
 \r
   Returns:\r
     EFI_SUCCESS           - Successfully returns\r
@@ -353,7 +278,7 @@ FvbGetLbaAddress (
   //\r
   // Find the right instance of the FVB private data\r
   //\r
-  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
+  Status = GetFvbInstance (Instance, Global, &FwhInstance);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   StartLba  = 0;\r
@@ -379,7 +304,7 @@ FvbGetLbaAddress (
     if (Lba >= StartLba && Lba < NextLba) {\r
       Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);\r
       if (LbaAddress != NULL) {\r
-        *LbaAddress = FwhInstance->FvBase[Virtual] + Offset;\r
+        *LbaAddress = FwhInstance->FvBase + Offset;\r
       }\r
 \r
       if (LbaLength != NULL) {\r
@@ -403,8 +328,7 @@ EFI_STATUS
 FvbSetVolumeAttributes (\r
   IN UINTN                                  Instance,\r
   IN OUT EFI_FVB_ATTRIBUTES_2               *Attributes,\r
-  IN ESAL_FWB_GLOBAL                        *Global,\r
-  IN BOOLEAN                                Virtual\r
+  IN ESAL_FWB_GLOBAL                        *Global\r
   )\r
 /*++\r
 \r
@@ -421,7 +345,6 @@ FvbSetVolumeAttributes (
                             of the firmware volume\r
     Global                - Pointer to ESAL_FWB_GLOBAL that contains all\r
                             instance data\r
-    Virtual               - Whether CPU is in virtual or physical mode\r
 \r
   Returns:\r
     EFI_SUCCESS           - Successfully returns\r
@@ -444,7 +367,7 @@ FvbSetVolumeAttributes (
   //\r
   // Find the right instance of the FVB private data\r
   //\r
-  Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
+  Status = GetFvbInstance (Instance, Global, &FwhInstance);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   AttribPtr     =\r
@@ -564,7 +487,7 @@ FvbProtocolGetPhysicalAddress (
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
   return FvbGetPhysicalAddress (FvbDevice->Instance, Address,\r
-           mFvbModuleGlobal, EfiGoneVirtual ());\r
+           mFvbModuleGlobal);\r
 }\r
 \r
 EFI_STATUS\r
@@ -606,8 +529,7 @@ FvbProtocolGetBlockSize (
           NULL,\r
           BlockSize,\r
           NumOfBlocks,\r
-          mFvbModuleGlobal,\r
-          EfiGoneVirtual ()\r
+          mFvbModuleGlobal\r
           );\r
 }\r
 \r
@@ -636,7 +558,7 @@ FvbProtocolGetAttributes (
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
   return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes,\r
-           mFvbModuleGlobal, EfiGoneVirtual ());\r
+           mFvbModuleGlobal);\r
 }\r
 \r
 EFI_STATUS\r
@@ -664,7 +586,7 @@ FvbProtocolSetAttributes (
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
   return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes,\r
-           mFvbModuleGlobal, EfiGoneVirtual ());\r
+           mFvbModuleGlobal);\r
 }\r
 \r
 EFI_STATUS\r
@@ -710,7 +632,7 @@ FvbProtocolEraseBlocks (
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
   Status    = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal,\r
-                &FwhInstance, EfiGoneVirtual ());\r
+                &FwhInstance);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   NumOfBlocks = FwhInstance->NumOfBlocks;\r
@@ -723,7 +645,7 @@ FvbProtocolEraseBlocks (
       break;\r
     }\r
 \r
-    NumOfLba = VA_ARG (args, UINT32);\r
+    NumOfLba = VA_ARG (args, UINTN);\r
 \r
     //\r
     // Check input parameters\r
@@ -743,7 +665,7 @@ FvbProtocolEraseBlocks (
       break;\r
     }\r
 \r
-    NumOfLba = VA_ARG (args, UINT32);\r
+    NumOfLba = VA_ARG (args, UINTN);\r
 \r
     while (NumOfLba > 0) {\r
       Status = QemuFlashEraseBlock (StartingLba);\r
@@ -909,12 +831,13 @@ ValidateFvHeader (
 \r
 STATIC\r
 EFI_STATUS\r
-MarkMemoryRangeForRuntimeAccess (\r
+MarkIoMemoryRangeForRuntimeAccess (\r
   EFI_PHYSICAL_ADDRESS                BaseAddress,\r
   UINTN                               Length\r
   )\r
 {\r
   EFI_STATUS                          Status;\r
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR     GcdDescriptor;\r
 \r
   //\r
   // Mark flash region as runtime memory\r
@@ -925,18 +848,31 @@ MarkMemoryRangeForRuntimeAccess (
                   );\r
 \r
   Status = gDS->AddMemorySpace (\r
-                  EfiGcdMemoryTypeSystemMemory,\r
+                  EfiGcdMemoryTypeMemoryMappedIo,\r
                   BaseAddress,\r
                   Length,\r
                   EFI_MEMORY_UC | EFI_MEMORY_RUNTIME\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  Status = gBS->AllocatePages (\r
-                  AllocateAddress,\r
-                  EfiRuntimeServicesData,\r
-                  EFI_SIZE_TO_PAGES (Length),\r
-                  &BaseAddress\r
+  Status = gDS->AllocateMemorySpace (\r
+                  EfiGcdAllocateAddress,\r
+                  EfiGcdMemoryTypeMemoryMappedIo,\r
+                  0,\r
+                  Length,\r
+                  &BaseAddress,\r
+                  gImageHandle,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = gDS->SetMemorySpaceAttributes (\r
+                  BaseAddress,\r
+                  Length,\r
+                  GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
@@ -1038,14 +974,12 @@ FvbInitialize (
   EFI_FIRMWARE_VOLUME_HEADER          *FwVolHeader;\r
   UINT32                              BufferSize;\r
   EFI_FV_BLOCK_MAP_ENTRY              *PtrBlockMapEntry;\r
-  EFI_HANDLE                          FwbHandle;\r
   EFI_FW_VOL_BLOCK_DEVICE             *FvbDevice;\r
-  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *OldFwbInterface;\r
   UINT32                              MaxLbaSize;\r
   EFI_PHYSICAL_ADDRESS                BaseAddress;\r
   UINTN                               Length;\r
   UINTN                               NumOfBlocks;\r
-  EFI_EVENT                           VirtualAddressChangeEvent;\r
+  RETURN_STATUS                       PcdStatus;\r
 \r
   if (EFI_ERROR (QemuFlashInitialize ())) {\r
     //\r
@@ -1090,21 +1024,10 @@ FvbInitialize (
                 FwVolHeader->HeaderLength -\r
                 sizeof (EFI_FIRMWARE_VOLUME_HEADER)\r
                 );\r
+  mFvbModuleGlobal->FvInstance = AllocateRuntimePool (BufferSize);\r
+  ASSERT (mFvbModuleGlobal->FvInstance != NULL);\r
 \r
-  //\r
-  // Only need to allocate once. There is only one copy of physical memory for\r
-  // the private data of each FV instance. But in virtual mode or in physical\r
-  // mode, the address of the the physical memory may be different.\r
-  //\r
-  mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] = AllocateRuntimePool (\r
-                                                 BufferSize);\r
-  ASSERT (mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] != NULL);\r
-\r
-  //\r
-  // Make a virtual copy of the FvInstance pointer.\r
-  //\r
-  FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];\r
-  mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;\r
+  FwhInstance = mFvbModuleGlobal->FvInstance;\r
 \r
   mFvbModuleGlobal->NumFv                   = 0;\r
   MaxLbaSize = 0;\r
@@ -1113,8 +1036,7 @@ FvbInitialize (
     (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)\r
       PcdGet32 (PcdOvmfFlashNvStorageVariableBase);\r
 \r
-  FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;\r
-  FwhInstance->FvBase[FVB_VIRTUAL]  = (UINTN) BaseAddress;\r
+  FwhInstance->FvBase = (UINTN) BaseAddress;\r
 \r
   CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader,\r
     FwVolHeader->HeaderLength);\r
@@ -1179,69 +1101,30 @@ FvbInitialize (
   }\r
 \r
   //\r
-  // Find a handle with a matching device path that has supports FW Block\r
-  // protocol\r
+  // Module type specific hook.\r
   //\r
-  Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid,\r
-                  &FvbDevice->DevicePath, &FwbHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // LocateDevicePath fails so install a new interface and device path\r
-    //\r
-    FwbHandle = NULL;\r
-    DEBUG ((EFI_D_INFO, "Installing QEMU flash FVB\n"));\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
-  } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {\r
-    //\r
-    // Device already exists, so reinstall the FVB protocol\r
-    //\r
-    Status = gBS->HandleProtocol (\r
-                    FwbHandle,\r
-                    &gEfiFirmwareVolumeBlockProtocolGuid,\r
-                    (VOID**)&OldFwbInterface\r
-                    );\r
-    ASSERT_EFI_ERROR (Status);\r
+  InstallProtocolInterfaces (FvbDevice);\r
 \r
-    DEBUG ((EFI_D_INFO, "Reinstalling FVB for QEMU flash region\n"));\r
-    Status = gBS->ReinstallProtocolInterface (\r
-                    FwbHandle,\r
-                    &gEfiFirmwareVolumeBlockProtocolGuid,\r
-                    OldFwbInterface,\r
-                    &FvbDevice->FwVolBlockInstance\r
-                    );\r
-    ASSERT_EFI_ERROR (Status);\r
-  } else {\r
-    //\r
-    // There was a FVB protocol on an End Device Path node\r
-    //\r
-    ASSERT (FALSE);\r
-  }\r
-\r
-  MarkMemoryRangeForRuntimeAccess (BaseAddress, Length);\r
+  MarkIoMemoryRangeForRuntimeAccess (BaseAddress, Length);\r
 \r
   //\r
   // Set several PCD values to point to flash\r
   //\r
-  PcdSet64 (\r
+  PcdStatus = PcdSet64S (\r
     PcdFlashNvStorageVariableBase64,\r
     (UINTN) PcdGet32 (PcdOvmfFlashNvStorageVariableBase)\r
     );\r
-  PcdSet32 (\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+  PcdStatus = PcdSet32S (\r
     PcdFlashNvStorageFtwWorkingBase,\r
     PcdGet32 (PcdOvmfFlashNvStorageFtwWorkingBase)\r
     );\r
-  PcdSet32 (\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+  PcdStatus = PcdSet32S (\r
     PcdFlashNvStorageFtwSpareBase,\r
     PcdGet32 (PcdOvmfFlashNvStorageFtwSpareBase)\r
     );\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
 \r
   FwhInstance = (EFI_FW_VOL_INSTANCE *)\r
     (\r
@@ -1249,17 +1132,12 @@ FvbInitialize (
       (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))\r
     );\r
 \r
-  VirtualAddressChangeEvent = NULL;\r
-  Status = gBS->CreateEventEx (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  FvbVirtualddressChangeEvent,\r
-                  NULL,\r
-                  &gEfiEventVirtualAddressChangeGuid,\r
-                  &VirtualAddressChangeEvent\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
+  //\r
+  // Module type specific hook.\r
+  //\r
+  InstallVirtualAddressChangeHandler ();\r
 \r
-  PcdSetBool (PcdOvmfFlashVariablesEnable, TRUE);\r
+  PcdStatus = PcdSetBoolS (PcdOvmfFlashVariablesEnable, TRUE);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
   return EFI_SUCCESS;\r
 }\r