]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / OvmfPkg / QemuFlashFvbServicesRuntimeDxe / FwBlockServiceDxe.c
index 63b308658e36b4ef91f1e098f01e504c965fead7..61e1f2e196e5c264de935223f67c5aa20a8e8786 100644 (file)
@@ -5,18 +5,14 @@
   Copyright (C) 2015, Red Hat, Inc.\r
   Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
 \r
-  This program and the accompanying materials are licensed and made available\r
-  under the terms and conditions of the BSD License which accompanies this\r
-  distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 **/\r
 \r
 #include <Guid/EventGroup.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/DevicePathLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
+#include <Library/MemEncryptSevLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiRuntimeLib.h>\r
 \r
 VOID\r
 InstallProtocolInterfaces (\r
-  IN EFI_FW_VOL_BLOCK_DEVICE *FvbDevice\r
+  IN EFI_FW_VOL_BLOCK_DEVICE  *FvbDevice\r
   )\r
 {\r
-  EFI_STATUS                         Status;\r
-  EFI_HANDLE                         FwbHandle;\r
-  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface;\r
+  EFI_STATUS                          Status;\r
+  EFI_HANDLE                          FwbHandle;\r
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *OldFwbInterface;\r
 \r
   ASSERT (!FeaturePcdGet (PcdSmmSmramRequire));\r
 \r
@@ -41,14 +37,17 @@ InstallProtocolInterfaces (
   // Find a handle with a matching device path that has supports FW Block\r
   // protocol\r
   //\r
-  Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid,\r
-                  &FvbDevice->DevicePath, &FwbHandle);\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
     FwbHandle = NULL;\r
-    DEBUG ((EFI_D_INFO, "Installing QEMU flash FVB\n"));\r
+    DEBUG ((DEBUG_INFO, "Installing QEMU flash FVB\n"));\r
     Status = gBS->InstallMultipleProtocolInterfaces (\r
                     &FwbHandle,\r
                     &gEfiFirmwareVolumeBlockProtocolGuid,\r
@@ -65,11 +64,11 @@ InstallProtocolInterfaces (
     Status = gBS->HandleProtocol (\r
                     FwbHandle,\r
                     &gEfiFirmwareVolumeBlockProtocolGuid,\r
-                    (VOID**)&OldFwbInterface\r
+                    (VOID **)&OldFwbInterface\r
                     );\r
     ASSERT_EFI_ERROR (Status);\r
 \r
-    DEBUG ((EFI_D_INFO, "Reinstalling FVB for QEMU flash region\n"));\r
+    DEBUG ((DEBUG_INFO, "Reinstalling FVB for QEMU flash region\n"));\r
     Status = gBS->ReinstallProtocolInterface (\r
                     FwbHandle,\r
                     &gEfiFirmwareVolumeBlockProtocolGuid,\r
@@ -85,14 +84,14 @@ InstallProtocolInterfaces (
   }\r
 }\r
 \r
-\r
 STATIC\r
 VOID\r
 EFIAPI\r
 FvbVirtualAddressChangeEvent (\r
-  IN EFI_EVENT        Event,\r
-  IN VOID             *Context\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
   )\r
+\r
 /*++\r
 \r
   Routine Description:\r
@@ -111,39 +110,38 @@ FvbVirtualAddressChangeEvent (
 \r
 --*/\r
 {\r
-  EFI_FW_VOL_INSTANCE *FwhInstance;\r
-  UINTN               Index;\r
+  EFI_FW_VOL_INSTANCE  *FwhInstance;\r
+  UINTN                Index;\r
 \r
   FwhInstance = mFvbModuleGlobal->FvInstance;\r
-  EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance);\r
+  EfiConvertPointer (0x0, (VOID **)&mFvbModuleGlobal->FvInstance);\r
 \r
   //\r
   // Convert the base address of all the instances\r
   //\r
-  Index       = 0;\r
+  Index = 0;\r
   while (Index < mFvbModuleGlobal->NumFv) {\r
-    EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase);\r
+    EfiConvertPointer (0x0, (VOID **)&FwhInstance->FvBase);\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
+                  (\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, (VOID **) &mFvbModuleGlobal);\r
+  EfiConvertPointer (0x0, (VOID **)&mFvbModuleGlobal);\r
   QemuFlashConvertPointers ();\r
 }\r
 \r
-\r
 VOID\r
 InstallVirtualAddressChangeHandler (\r
   VOID\r
   )\r
 {\r
-  EFI_STATUS Status;\r
-  EFI_EVENT  VirtualAddressChangeEvent;\r
+  EFI_STATUS  Status;\r
+  EFI_EVENT   VirtualAddressChangeEvent;\r
 \r
   Status = gBS->CreateEventEx (\r
                   EVT_NOTIFY_SIGNAL,\r
@@ -155,3 +153,94 @@ InstallVirtualAddressChangeHandler (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 }\r
+\r
+EFI_STATUS\r
+MarkIoMemoryRangeForRuntimeAccess (\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN 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
+  //\r
+  Status = gDS->RemoveMemorySpace (\r
+                  BaseAddress,\r
+                  Length\r
+                  );\r
+\r
+  Status = gDS->AddMemorySpace (\r
+                  EfiGcdMemoryTypeMemoryMappedIo,\r
+                  BaseAddress,\r
+                  Length,\r
+                  EFI_MEMORY_UC | EFI_MEMORY_RUNTIME\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\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
+  //\r
+  // When SEV is active, AmdSevDxe mapped the BaseAddress with C=0 but\r
+  // SetMemorySpaceAttributes() remaps the range with C=1. Let's restore\r
+  // the mapping so that both guest and hyervisor can access the flash\r
+  // memory range.\r
+  //\r
+  if (MemEncryptSevIsEnabled ()) {\r
+    Status = MemEncryptSevClearMmioPageEncMask (\r
+               0,\r
+               BaseAddress,\r
+               EFI_SIZE_TO_PAGES (Length)\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+VOID\r
+SetPcdFlashNvStorageBaseAddresses (\r
+  VOID\r
+  )\r
+{\r
+  RETURN_STATUS  PcdStatus;\r
+\r
+  //\r
+  // Set several PCD values to point to flash\r
+  //\r
+  PcdStatus = PcdSet64S (\r
+                PcdFlashNvStorageVariableBase64,\r
+                (UINTN)PcdGet32 (PcdOvmfFlashNvStorageVariableBase)\r
+                );\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+  PcdStatus = PcdSet32S (\r
+                PcdFlashNvStorageFtwWorkingBase,\r
+                PcdGet32 (PcdOvmfFlashNvStorageFtwWorkingBase)\r
+                );\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+  PcdStatus = PcdSet32S (\r
+                PcdFlashNvStorageFtwSpareBase,\r
+                PcdGet32 (PcdOvmfFlashNvStorageFtwSpareBase)\r
+                );\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+}\r