]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / QemuFlashFvbServicesRuntimeDxe / QemuFlashDxe.c
index 332ceafd3f788ff88967cb39182ba625bb01e345..9e074c29bb2bd2f3ae729904ee5ca56c4b336a61 100644 (file)
@@ -5,36 +5,90 @@
   Copyright (C) 2015, Red Hat, Inc.\r
   Copyright (c) 2009 - 2013, 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
 \r
 #include <Library/UefiRuntimeLib.h>\r
+#include <Library/MemEncryptSevLib.h>\r
+#include <Library/VmgExitLib.h>\r
+#include <Register/Amd/Msr.h>\r
 \r
 #include "QemuFlash.h"\r
 \r
+STATIC EFI_PHYSICAL_ADDRESS  mSevEsFlashPhysBase;\r
+\r
 VOID\r
 QemuFlashConvertPointers (\r
   VOID\r
   )\r
 {\r
-  EfiConvertPointer (0x0, (VOID **) &mFlashBase);\r
+  if (MemEncryptSevEsIsEnabled ()) {\r
+    mSevEsFlashPhysBase = (UINTN)mFlashBase;\r
+  }\r
+\r
+  EfiConvertPointer (0x0, (VOID **)&mFlashBase);\r
 }\r
 \r
 VOID\r
 QemuFlashBeforeProbe (\r
-  IN  EFI_PHYSICAL_ADDRESS    BaseAddress,\r
-  IN  UINTN                   FdBlockSize,\r
-  IN  UINTN                   FdBlockCount\r
+  IN  EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN  UINTN                 FdBlockSize,\r
+  IN  UINTN                 FdBlockCount\r
   )\r
 {\r
   //\r
   // Do nothing\r
   //\r
 }\r
+\r
+/**\r
+  Write to QEMU Flash\r
+\r
+  @param[in] Ptr    Pointer to the location to write.\r
+  @param[in] Value  The value to write.\r
+\r
+**/\r
+VOID\r
+QemuFlashPtrWrite (\r
+  IN        volatile UINT8  *Ptr,\r
+  IN        UINT8           Value\r
+  )\r
+{\r
+  if (MemEncryptSevEsIsEnabled ()) {\r
+    MSR_SEV_ES_GHCB_REGISTER  Msr;\r
+    GHCB                      *Ghcb;\r
+    EFI_PHYSICAL_ADDRESS      PhysAddr;\r
+    BOOLEAN                   InterruptState;\r
+\r
+    Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);\r
+    Ghcb                    = Msr.Ghcb;\r
+\r
+    //\r
+    // The MMIO write needs to be to the physical address of the flash pointer.\r
+    // Since this service is available as part of the EFI runtime services,\r
+    // account for a non-identity mapped VA after SetVirtualAddressMap().\r
+    //\r
+    if (mSevEsFlashPhysBase == 0) {\r
+      PhysAddr = (UINTN)Ptr;\r
+    } else {\r
+      PhysAddr = mSevEsFlashPhysBase + (Ptr - mFlashBase);\r
+    }\r
+\r
+    //\r
+    // Writing to flash is emulated by the hypervisor through the use of write\r
+    // protection. This won't work for an SEV-ES guest because the write won't\r
+    // be recognized as a true MMIO write, which would result in the required\r
+    // #VC exception. Instead, use the the VMGEXIT MMIO write support directly\r
+    // to perform the update.\r
+    //\r
+    VmgInit (Ghcb, &InterruptState);\r
+    Ghcb->SharedBuffer[0]    = Value;\r
+    Ghcb->SaveArea.SwScratch = (UINT64)(UINTN)Ghcb->SharedBuffer;\r
+    VmgSetOffsetValid (Ghcb, GhcbSwScratch);\r
+    VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, PhysAddr, 1);\r
+    VmgDone (Ghcb, InterruptState);\r
+  } else {\r
+    *Ptr = Value;\r
+  }\r
+}\r