TianoCore EDK2 master
Loading...
Searching...
No Matches
QemuFwCfgPei.c
Go to the documentation of this file.
1
12#include <PiPei.h>
13#include <Library/BaseLib.h>
14#include <Library/DebugLib.h>
15#include <Library/HobLib.h>
16#include <Library/IoLib.h>
19#include <WorkArea.h>
20
22
30BOOLEAN
32 VOID
33 )
34{
36
37 CcWorkAreaHeader = (CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
38 return (CcWorkAreaHeader != NULL && CcWorkAreaHeader->GuestType != CcGuestTypeNonEncrypted);
39}
40
51BOOLEAN
52EFIAPI
54 VOID
55 )
56{
58}
59
61VOID
62QemuFwCfgProbe (
63 BOOLEAN *Supported,
64 BOOLEAN *DmaSupported
65 )
66{
67 UINT32 Signature;
68 UINT32 Revision;
69 BOOLEAN CcGuest;
70
71 // Use direct Io* calls for probing to avoid recursion.
72 IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)QemuFwCfgItemSignature);
73 IoReadFifo8 (FW_CFG_IO_DATA, sizeof Signature, &Signature);
74 IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)QemuFwCfgItemInterfaceVersion);
75 IoReadFifo8 (FW_CFG_IO_DATA, sizeof Revision, &Revision);
76 CcGuest = QemuFwCfgIsCcGuest ();
77
78 *Supported = FALSE;
79 *DmaSupported = FALSE;
80 if ((Signature == SIGNATURE_32 ('Q', 'E', 'M', 'U')) && (Revision >= 1)) {
81 *Supported = TRUE;
82 if ((Revision & FW_CFG_F_DMA) && !CcGuest) {
83 *DmaSupported = TRUE;
84 }
85 }
86
87 DEBUG ((
88 DEBUG_INFO,
89 "%a: Supported %d, DMA %d\n",
90 __func__,
91 *Supported,
92 *DmaSupported
93 ));
94}
95
98QemuFwCfgGetPlatformInfo (
99 VOID
100 )
101{
102 EFI_HOB_PLATFORM_INFO *PlatformInfoHob;
103 EFI_HOB_GUID_TYPE *GuidHob;
104
105 GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid);
106 if (GuidHob == NULL) {
107 return NULL;
108 }
109
110 PlatformInfoHob = (EFI_HOB_PLATFORM_INFO *)GET_GUID_HOB_DATA (GuidHob);
111
112 if (!PlatformInfoHob->QemuFwCfgChecked) {
113 QemuFwCfgProbe (
114 &PlatformInfoHob->QemuFwCfgSupported,
115 &PlatformInfoHob->QemuFwCfgDmaSupported
116 );
117 PlatformInfoHob->QemuFwCfgChecked = TRUE;
118 }
119
120 return PlatformInfoHob;
121}
122
123RETURN_STATUS
124EFIAPI
125QemuFwCfgInitialize (
126 VOID
127 )
128{
129 return RETURN_SUCCESS;
130}
131
141BOOLEAN
143 VOID
144 )
145{
146 EFI_HOB_PLATFORM_INFO *PlatformInfoHob = QemuFwCfgGetPlatformInfo ();
147
148 return PlatformInfoHob->QemuFwCfgSupported;
149}
150
158BOOLEAN
160 VOID
161 )
162{
163 EFI_HOB_PLATFORM_INFO *PlatformInfoHob = QemuFwCfgGetPlatformInfo ();
164
165 return PlatformInfoHob->QemuFwCfgDmaSupported;
166}
167
183VOID
185 IN UINT32 Size,
186 IN OUT VOID *Buffer OPTIONAL,
187 IN UINT32 Control
188 )
189{
190 volatile FW_CFG_DMA_ACCESS Access;
191 UINT32 AccessHigh, AccessLow;
192 UINT32 Status;
193
194 ASSERT (
195 Control == FW_CFG_DMA_CTL_WRITE || Control == FW_CFG_DMA_CTL_READ ||
196 Control == FW_CFG_DMA_CTL_SKIP
197 );
198
199 if (Size == 0) {
200 return;
201 }
202
203 //
204 // TDX does not support DMA operations in PEI stage, we should
205 // not have reached here.
206 //
207 ASSERT (!QemuFwCfgIsCcGuest ());
208
209 Access.Control = SwapBytes32 (Control);
210 Access.Length = SwapBytes32 (Size);
211 Access.Address = SwapBytes64 ((UINTN)Buffer);
212
213 //
214 // Delimit the transfer from (a) modifications to Access, (b) in case of a
215 // write, from writes to Buffer by the caller.
216 //
217 MemoryFence ();
218
219 //
220 // Start the transfer.
221 //
222 AccessHigh = (UINT32)RShiftU64 ((UINTN)&Access, 32);
223 AccessLow = (UINT32)(UINTN)&Access;
224 IoWrite32 (FW_CFG_IO_DMA_ADDRESS, SwapBytes32 (AccessHigh));
225 IoWrite32 (FW_CFG_IO_DMA_ADDRESS + 4, SwapBytes32 (AccessLow));
226
227 //
228 // Don't look at Access.Control before starting the transfer.
229 //
230 MemoryFence ();
231
232 //
233 // Wait for the transfer to complete.
234 //
235 do {
236 Status = SwapBytes32 (Access.Control);
237 ASSERT ((Status & FW_CFG_DMA_CTL_ERROR) == 0);
238 } while (Status != 0);
239
240 //
241 // After a read, the caller will want to use Buffer.
242 //
243 MemoryFence ();
244}
UINT64 UINTN
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID EFIAPI MemoryFence(VOID)
Definition: CpuBreakpoint.c:42
UINT32 EFIAPI SwapBytes32(IN UINT32 Value)
Definition: SwapBytes32.c:25
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI SwapBytes64(IN UINT64 Value)
Definition: SwapBytes64.c:25
VOID EFIAPI IoReadFifo8(IN UINTN Port, IN UINTN Count, OUT VOID *Buffer)
Definition: IoLibArmVirt.c:380
UINT32 EFIAPI IoWrite32(IN UINTN Port, IN UINT32 Value)
Definition: IoLibArmVirt.c:300
UINT16 EFIAPI IoWrite16(IN UINTN Port, IN UINT16 Value)
Definition: IoLibArmVirt.c:250
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define SIGNATURE_32(A, B, C, D)
Definition: Base.h:1310
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define FixedPcdGet32(TokenName)
Definition: PcdLib.h:92
STATIC BOOLEAN QemuFwCfgIsCcGuest(VOID)
Definition: QemuFwCfgPei.c:31
BOOLEAN InternalQemuFwCfgIsAvailable(VOID)
Definition: QemuFwCfgPei.c:142
VOID InternalQemuFwCfgDmaBytes(IN UINT32 Size, IN OUT VOID *Buffer OPTIONAL, IN UINT32 Control)
Definition: QemuFwCfgPei.c:184
BOOLEAN InternalQemuFwCfgDmaIsAvailable(VOID)
Definition: QemuFwCfgPei.c:159
BOOLEAN EFIAPI QemuFwCfgIsAvailable(VOID)
Definition: QemuFwCfgPei.c:53