31#define EXTRA_PAGE_TABLE_PAGES 8
56 Status =
gBS->AllocatePages (
64 Buffer = (VOID *)(
UINTN)Address;
90 Status =
gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid,
NULL, (VOID **)&VariableLock);
91 if (!EFI_ERROR (Status)) {
92 Status = VariableLock->RequestToLock (VariableLock, EFI_CAPSULE_LONG_MODE_BUFFER_NAME, &gEfiCapsuleVendorGuid);
108 UINTN ExtraPageTablePages;
112 UINT8 PhysicalAddressBits;
113 UINT32 NumberOfPml4EntriesNeeded;
114 UINT32 NumberOfPdpEntriesNeeded;
115 BOOLEAN Page1GSupport;
123 Page1GSupport =
FALSE;
126 if (RegEax >= 0x80000001) {
128 if ((RegEdx & BIT26) != 0) {
129 Page1GSupport =
TRUE;
138 PhysicalAddressBits = 32;
139 ExtraPageTablePages = EXTRA_PAGE_TABLE_PAGES;
144 if (PhysicalAddressBits <= 39 ) {
145 NumberOfPml4EntriesNeeded = 1;
146 NumberOfPdpEntriesNeeded = (UINT32)
LShiftU64 (1, (PhysicalAddressBits - 30));
148 NumberOfPml4EntriesNeeded = (UINT32)
LShiftU64 (1, (PhysicalAddressBits - 39));
149 NumberOfPdpEntriesNeeded = 512;
152 if (!Page1GSupport) {
153 TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1;
155 TotalPagesNum = NumberOfPml4EntriesNeeded + 1;
158 TotalPagesNum += ExtraPageTablePages;
159 DEBUG ((DEBUG_INFO,
"CapsuleRuntimeDxe X64 TotalPagesNum - 0x%x pages\n", TotalPagesNum));
162 ASSERT (LongModeBuffer.PageTableAddress != 0);
167 LongModeBuffer.StackSize =
PcdGet32 (PcdCapsulePeiLongModeStackSize);
169 ASSERT (LongModeBuffer.StackBaseAddress != 0);
171 Status =
gRT->SetVariable (
172 EFI_CAPSULE_LONG_MODE_BUFFER_NAME,
173 &gEfiCapsuleVendorGuid,
178 if (!EFI_ERROR (Status)) {
184 &gEdkiiVariableLockProtocolGuid,
191 DEBUG ((DEBUG_ERROR,
"FATAL ERROR: CapsuleLongModeBuffer cannot be saved: %r. Capsule in PEI may fail!\n", Status));
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_RUNTIME_SERVICES * gRT
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
#define PcdGet32(TokenName)
#define PcdGetBool(TokenName)
#define FeaturePcdGet(TokenName)
VOID SaveLongModeContext(VOID)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
#define EFI_VARIABLE_NON_VOLATILE
VOID * AllocateReservedMemoryBelow4G(IN UINTN Size)
VOID EFIAPI VariableLockCapsuleLongModeBufferVariable(IN EFI_EVENT Event, IN VOID *Context)
VOID EFIAPI PrepareContextForCapsulePei(VOID)