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
// 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
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
}\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
\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
);\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