QemuFlashDxe.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /** @file
  2. OVMF support for QEMU system firmware flash device: functions specific to the
  3. runtime DXE driver build.
  4. Copyright (C) 2015, Red Hat, Inc.
  5. Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
  6. SPDX-License-Identifier: BSD-2-Clause-Patent
  7. **/
  8. #include <Library/UefiRuntimeLib.h>
  9. #include <Library/MemEncryptSevLib.h>
  10. #include <Library/CcExitLib.h>
  11. #include <Register/Amd/Msr.h>
  12. #include "QemuFlash.h"
  13. STATIC EFI_PHYSICAL_ADDRESS mSevEsFlashPhysBase;
  14. VOID
  15. QemuFlashConvertPointers (
  16. VOID
  17. )
  18. {
  19. if (MemEncryptSevEsIsEnabled ()) {
  20. mSevEsFlashPhysBase = (UINTN)mFlashBase;
  21. }
  22. EfiConvertPointer (0x0, (VOID **)&mFlashBase);
  23. }
  24. VOID
  25. QemuFlashBeforeProbe (
  26. IN EFI_PHYSICAL_ADDRESS BaseAddress,
  27. IN UINTN FdBlockSize,
  28. IN UINTN FdBlockCount
  29. )
  30. {
  31. //
  32. // Do nothing
  33. //
  34. }
  35. /**
  36. Write to QEMU Flash
  37. @param[in] Ptr Pointer to the location to write.
  38. @param[in] Value The value to write.
  39. **/
  40. VOID
  41. QemuFlashPtrWrite (
  42. IN volatile UINT8 *Ptr,
  43. IN UINT8 Value
  44. )
  45. {
  46. if (MemEncryptSevEsIsEnabled ()) {
  47. MSR_SEV_ES_GHCB_REGISTER Msr;
  48. GHCB *Ghcb;
  49. EFI_PHYSICAL_ADDRESS PhysAddr;
  50. BOOLEAN InterruptState;
  51. Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
  52. Ghcb = Msr.Ghcb;
  53. //
  54. // The MMIO write needs to be to the physical address of the flash pointer.
  55. // Since this service is available as part of the EFI runtime services,
  56. // account for a non-identity mapped VA after SetVirtualAddressMap().
  57. //
  58. if (mSevEsFlashPhysBase == 0) {
  59. PhysAddr = (UINTN)Ptr;
  60. } else {
  61. PhysAddr = mSevEsFlashPhysBase + (Ptr - mFlashBase);
  62. }
  63. //
  64. // Writing to flash is emulated by the hypervisor through the use of write
  65. // protection. This won't work for an SEV-ES guest because the write won't
  66. // be recognized as a true MMIO write, which would result in the required
  67. // #VC exception. Instead, use the VMGEXIT MMIO write support directly
  68. // to perform the update.
  69. //
  70. CcExitVmgInit (Ghcb, &InterruptState);
  71. Ghcb->SharedBuffer[0] = Value;
  72. Ghcb->SaveArea.SwScratch = (UINT64)(UINTN)Ghcb->SharedBuffer;
  73. CcExitVmgSetOffsetValid (Ghcb, GhcbSwScratch);
  74. CcExitVmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, PhysAddr, 1);
  75. CcExitVmgDone (Ghcb, InterruptState);
  76. } else {
  77. *Ptr = Value;
  78. }
  79. }