#include <Library/IoLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/QemuFwCfgLib.h>\r
-#include <Library/MemEncryptSevLib.h>\r
#include <WorkArea.h>\r
\r
#include "QemuFwCfgLibInternal.h"\r
@retval TRUE It is Tdx guest\r
@retval FALSE It is not Tdx guest\r
**/\r
+STATIC\r
BOOLEAN\r
-QemuFwCfgIsTdxGuest (\r
+QemuFwCfgIsCcGuest (\r
VOID\r
)\r
{\r
CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER *CcWorkAreaHeader;\r
\r
CcWorkAreaHeader = (CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER *)FixedPcdGet32 (PcdOvmfWorkAreaBase);\r
- return (CcWorkAreaHeader != NULL && CcWorkAreaHeader->GuestType == CcGuestTypeIntelTdx);\r
+ return (CcWorkAreaHeader != NULL && CcWorkAreaHeader->GuestType != CcGuestTypeNonEncrypted);\r
}\r
\r
/**\r
return InternalQemuFwCfgIsAvailable ();\r
}\r
\r
+STATIC\r
+VOID\r
+QemuFwCfgProbe (\r
+ BOOLEAN *Supported,\r
+ BOOLEAN *DmaSupported\r
+ )\r
+{\r
+ UINT32 Signature;\r
+ UINT32 Revision;\r
+ BOOLEAN CcGuest;\r
+\r
+ // Use direct Io* calls for probing to avoid recursion.\r
+ IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)QemuFwCfgItemSignature);\r
+ IoReadFifo8 (FW_CFG_IO_DATA, sizeof Signature, &Signature);\r
+ IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)QemuFwCfgItemInterfaceVersion);\r
+ IoReadFifo8 (FW_CFG_IO_DATA, sizeof Revision, &Revision);\r
+ CcGuest = QemuFwCfgIsCcGuest ();\r
+\r
+ *Supported = FALSE;\r
+ *DmaSupported = FALSE;\r
+ if ((Signature == SIGNATURE_32 ('Q', 'E', 'M', 'U')) && (Revision >= 1)) {\r
+ *Supported = TRUE;\r
+ if ((Revision & FW_CFG_F_DMA) && !CcGuest) {\r
+ *DmaSupported = TRUE;\r
+ }\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: Supported %d, DMA %d\n",\r
+ __func__,\r
+ *Supported,\r
+ *DmaSupported\r
+ ));\r
+}\r
+\r
RETURN_STATUS\r
EFIAPI\r
QemuFwCfgInitialize (\r
VOID\r
)\r
{\r
- UINT32 Signature;\r
- UINT32 Revision;\r
-\r
- //\r
- // Enable the access routines while probing to see if it is supported.\r
- // For probing we always use the IO Port (IoReadFifo8()) access method.\r
- //\r
- mQemuFwCfgSupported = TRUE;\r
- mQemuFwCfgDmaSupported = FALSE;\r
-\r
- QemuFwCfgSelectItem (QemuFwCfgItemSignature);\r
- Signature = QemuFwCfgRead32 ();\r
- DEBUG ((DEBUG_INFO, "FW CFG Signature: 0x%x\n", Signature));\r
- QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);\r
- Revision = QemuFwCfgRead32 ();\r
- DEBUG ((DEBUG_INFO, "FW CFG Revision: 0x%x\n", Revision));\r
- if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||\r
- (Revision < 1)\r
- )\r
- {\r
- DEBUG ((DEBUG_INFO, "QemuFwCfg interface not supported.\n"));\r
- mQemuFwCfgSupported = FALSE;\r
- return RETURN_SUCCESS;\r
- }\r
-\r
- if ((Revision & FW_CFG_F_DMA) == 0) {\r
- DEBUG ((DEBUG_INFO, "QemuFwCfg interface (IO Port) is supported.\n"));\r
- } else {\r
- //\r
- // If SEV is enabled then we do not support DMA operations in PEI phase.\r
- // This is mainly because DMA in SEV guest requires using bounce buffer\r
- // (which need to allocate dynamic memory and allocating a PAGE size'd\r
- // buffer can be challenge in PEI phase)\r
- //\r
- if (MemEncryptSevIsEnabled ()) {\r
- DEBUG ((DEBUG_INFO, "SEV: QemuFwCfg fallback to IO Port interface.\n"));\r
- } else if (QemuFwCfgIsTdxGuest ()) {\r
- //\r
- // If TDX is enabled then we do not support DMA operations in PEI phase.\r
- // This is mainly because DMA in TDX guest requires using bounce buffer\r
- // (which need to allocate dynamic memory and allocating a PAGE size'd\r
- // buffer can be challenge in PEI phase)\r
- //\r
- DEBUG ((DEBUG_INFO, "TDX: QemuFwCfg fallback to IO Port interface.\n"));\r
- } else {\r
- mQemuFwCfgDmaSupported = TRUE;\r
- DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));\r
- }\r
- }\r
-\r
+ QemuFwCfgProbe (&mQemuFwCfgSupported, &mQemuFwCfgDmaSupported);\r
return RETURN_SUCCESS;\r
}\r
\r
return;\r
}\r
\r
- //\r
- // SEV does not support DMA operations in PEI stage, we should\r
- // not have reached here.\r
- //\r
- ASSERT (!MemEncryptSevIsEnabled ());\r
-\r
//\r
// TDX does not support DMA operations in PEI stage, we should\r
// not have reached here.\r
//\r
- ASSERT (!QemuFwCfgIsTdxGuest ());\r
+ ASSERT (!QemuFwCfgIsCcGuest ());\r
\r
Access.Control = SwapBytes32 (Control);\r
Access.Length = SwapBytes32 (Size);\r