TianoCore EDK2 master
Loading...
Searching...
No Matches
FwBlockServiceDxe.c
Go to the documentation of this file.
1
11#include <Guid/EventGroup.h>
12#include <Library/DebugLib.h>
16#include <Library/PcdLib.h>
19#include <Protocol/DevicePath.h>
21
22#include "FwBlockService.h"
23#include "QemuFlash.h"
24
25VOID
26InstallProtocolInterfaces (
28 )
29{
30 EFI_STATUS Status;
31 EFI_HANDLE FwbHandle;
33
34 ASSERT (!FeaturePcdGet (PcdSmmSmramRequire));
35
36 //
37 // Find a handle with a matching device path that has supports FW Block
38 // protocol
39 //
40 Status = gBS->LocateDevicePath (
41 &gEfiFirmwareVolumeBlockProtocolGuid,
42 &FvbDevice->DevicePath,
43 &FwbHandle
44 );
45 if (EFI_ERROR (Status)) {
46 //
47 // LocateDevicePath fails so install a new interface and device path
48 //
49 FwbHandle = NULL;
50 DEBUG ((DEBUG_INFO, "Installing QEMU flash FVB\n"));
51 Status = gBS->InstallMultipleProtocolInterfaces (
52 &FwbHandle,
53 &gEfiFirmwareVolumeBlockProtocolGuid,
54 &FvbDevice->FwVolBlockInstance,
55 &gEfiDevicePathProtocolGuid,
56 FvbDevice->DevicePath,
57 NULL
58 );
59 ASSERT_EFI_ERROR (Status);
60 } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {
61 //
62 // Device already exists, so reinstall the FVB protocol
63 //
64 Status = gBS->HandleProtocol (
65 FwbHandle,
66 &gEfiFirmwareVolumeBlockProtocolGuid,
67 (VOID **)&OldFwbInterface
68 );
69 ASSERT_EFI_ERROR (Status);
70
71 DEBUG ((DEBUG_INFO, "Reinstalling FVB for QEMU flash region\n"));
72 Status = gBS->ReinstallProtocolInterface (
73 FwbHandle,
74 &gEfiFirmwareVolumeBlockProtocolGuid,
75 OldFwbInterface,
76 &FvbDevice->FwVolBlockInstance
77 );
78 ASSERT_EFI_ERROR (Status);
79 } else {
80 //
81 // There was a FVB protocol on an End Device Path node
82 //
83 ASSERT (FALSE);
84 }
85}
86
88VOID
89EFIAPI
91 IN EFI_EVENT Event,
92 IN VOID *Context
93 )
94
95/*++
96
97 Routine Description:
98
99 Fixup internal data so that EFI and SAL can be call in virtual mode.
100 Call the passed in Child Notify event and convert the mFvbModuleGlobal
101 date items to there virtual address.
102
103 Arguments:
104
105 (Standard EFI notify event - EFI_EVENT_NOTIFY)
106
107 Returns:
108
109 None
110
111--*/
112{
113 EFI_FW_VOL_INSTANCE *FwhInstance;
114 UINTN Index;
115
116 FwhInstance = mFvbModuleGlobal->FvInstance;
117 EfiConvertPointer (0x0, (VOID **)&mFvbModuleGlobal->FvInstance);
118
119 //
120 // Convert the base address of all the instances
121 //
122 Index = 0;
123 while (Index < mFvbModuleGlobal->NumFv) {
124 EfiConvertPointer (0x0, (VOID **)&FwhInstance->FvBase);
125 FwhInstance = (EFI_FW_VOL_INSTANCE *)
126 (
127 (UINTN)((UINT8 *)FwhInstance) +
128 FwhInstance->VolumeHeader.HeaderLength +
130 );
131 Index++;
132 }
133
134 EfiConvertPointer (0x0, (VOID **)&mFvbModuleGlobal);
135 QemuFlashConvertPointers ();
136}
137
138VOID
139InstallVirtualAddressChangeHandler (
140 VOID
141 )
142{
143 EFI_STATUS Status;
144 EFI_EVENT VirtualAddressChangeEvent;
145
146 Status = gBS->CreateEventEx (
147 EVT_NOTIFY_SIGNAL,
148 TPL_NOTIFY,
149 FvbVirtualAddressChangeEvent,
150 NULL,
151 &gEfiEventVirtualAddressChangeGuid,
152 &VirtualAddressChangeEvent
153 );
154 ASSERT_EFI_ERROR (Status);
155}
156
158MarkIoMemoryRangeForRuntimeAccess (
159 IN EFI_PHYSICAL_ADDRESS BaseAddress,
160 IN UINTN Length
161 )
162{
163 EFI_STATUS Status;
165
166 //
167 // Mark flash region as runtime memory
168 //
169 Status = gDS->RemoveMemorySpace (
170 BaseAddress,
171 Length
172 );
173
174 Status = gDS->AddMemorySpace (
176 BaseAddress,
177 Length,
178 EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
179 );
180 ASSERT_EFI_ERROR (Status);
181
182 Status = gDS->AllocateMemorySpace (
185 0,
186 Length,
187 &BaseAddress,
189 NULL
190 );
191 ASSERT_EFI_ERROR (Status);
192
193 Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);
194 ASSERT_EFI_ERROR (Status);
195
196 Status = gDS->SetMemorySpaceAttributes (
197 BaseAddress,
198 Length,
199 GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME
200 );
201 ASSERT_EFI_ERROR (Status);
202
203 //
204 // When SEV is active, AmdSevDxe mapped the BaseAddress with C=0 but
205 // SetMemorySpaceAttributes() remaps the range with C=1. Let's restore
206 // the mapping so that both guest and hyervisor can access the flash
207 // memory range.
208 //
209 if (MemEncryptSevIsEnabled ()) {
211 0,
212 BaseAddress,
213 EFI_SIZE_TO_PAGES (Length)
214 );
215 ASSERT_EFI_ERROR (Status);
216 }
217
218 return Status;
219}
220
221VOID
222SetPcdFlashNvStorageBaseAddresses (
223 VOID
224 )
225{
226 RETURN_STATUS PcdStatus;
227
228 //
229 // Set several PCD values to point to flash
230 //
231 PcdStatus = PcdSet64S (
232 PcdFlashNvStorageVariableBase64,
233 (UINTN)PcdGet32 (PcdOvmfFlashNvStorageVariableBase)
234 );
235 ASSERT_RETURN_ERROR (PcdStatus);
236 PcdStatus = PcdSet32S (
237 PcdFlashNvStorageFtwWorkingBase,
238 PcdGet32 (PcdOvmfFlashNvStorageFtwWorkingBase)
239 );
240 ASSERT_RETURN_ERROR (PcdStatus);
241 PcdStatus = PcdSet32S (
242 PcdFlashNvStorageFtwSpareBase,
243 PcdGet32 (PcdOvmfFlashNvStorageFtwSpareBase)
244 );
245 ASSERT_RETURN_ERROR (PcdStatus);
246}
UINT64 UINTN
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DXE_SERVICES * gDS
VOID EFIAPI FvbVirtualAddressChangeEvent(IN EFI_EVENT Event, IN VOID *Context)
Definition: Fvb.c:97
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define ASSERT_RETURN_ERROR(StatusParameter)
Definition: DebugLib.h:493
#define DEBUG(Expression)
Definition: DebugLib.h:434
BOOLEAN EFIAPI MemEncryptSevIsEnabled(VOID)
RETURN_STATUS EFIAPI MemEncryptSevClearMmioPageEncMask(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdSet64S(TokenName, Value)
Definition: PcdLib.h:511
#define PcdSet32S(TokenName, Value)
Definition: PcdLib.h:497
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
@ EfiGcdMemoryTypeMemoryMappedIo
Definition: PiDxeCis.h:44
@ EfiGcdAllocateAddress
Definition: PiDxeCis.h:107
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiConvertPointer(IN UINTN DebugDisposition, IN OUT VOID **Address)
Definition: RuntimeLib.c:561