TianoCore EDK2 master
Loading...
Searching...
No Matches
UefiCapsule.c
Go to the documentation of this file.
1
11#include "Capsule.h"
12
13#define DEFAULT_SG_LIST_HEADS (20)
14
15#ifdef MDE_CPU_IA32
16//
17// Global Descriptor Table (GDT)
18//
19GLOBAL_REMOVE_IF_UNREFERENCED IA32_SEGMENT_DESCRIPTOR mGdtEntries[] = {
20 /* selector { Global Segment Descriptor } */
21 /* 0x00 */ {
22 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
23 }, // null descriptor
24 /* 0x08 */ {
25 { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
26 }, // linear data segment descriptor
27 /* 0x10 */ {
28 { 0xffff, 0, 0, 0xf, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
29 }, // linear code segment descriptor
30 /* 0x18 */ {
31 { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
32 }, // system data segment descriptor
33 /* 0x20 */ {
34 { 0xffff, 0, 0, 0xb, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
35 }, // system code segment descriptor
36 /* 0x28 */ {
37 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
38 }, // spare segment descriptor
39 /* 0x30 */ {
40 { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
41 }, // system data segment descriptor
42 /* 0x38 */ {
43 { 0xffff, 0, 0, 0xb, 1, 0, 1, 0xf, 0, 1, 0, 1, 0 }
44 }, // system code segment descriptor
45 /* 0x40 */ {
46 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
47 }, // spare segment descriptor
48};
49
50//
51// IA32 Gdt register
52//
53GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR mGdt = {
54 sizeof (mGdtEntries) - 1,
55 (UINTN)mGdtEntries
56};
57
65BOOLEAN
66IsPage1GSupport (
67 VOID
68 )
69{
70 UINT32 RegEax;
71 UINT32 RegEdx;
72 BOOLEAN Page1GSupport;
73
74 Page1GSupport = FALSE;
75 if (PcdGetBool (PcdUse1GPageTable)) {
76 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
77 if (RegEax >= 0x80000001) {
78 AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
79 if ((RegEdx & BIT26) != 0) {
80 Page1GSupport = TRUE;
81 }
82 }
83 }
84
85 return Page1GSupport;
86}
87
97CalculatePageTableSize (
98 IN BOOLEAN Page1GSupport
99 )
100{
101 UINTN ExtraPageTablePages;
102 UINTN TotalPagesNum;
103 UINT8 PhysicalAddressBits;
104 UINT32 NumberOfPml4EntriesNeeded;
105 UINT32 NumberOfPdpEntriesNeeded;
106
107 //
108 // Create 4G page table by default,
109 // and let PF handler to handle > 4G request.
110 //
111 PhysicalAddressBits = 32;
112 ExtraPageTablePages = EXTRA_PAGE_TABLE_PAGES;
113
114 //
115 // Calculate the table entries needed.
116 //
117 if (PhysicalAddressBits <= 39 ) {
118 NumberOfPml4EntriesNeeded = 1;
119 NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
120 } else {
121 NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
122 NumberOfPdpEntriesNeeded = 512;
123 }
124
125 if (!Page1GSupport) {
126 TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1;
127 } else {
128 TotalPagesNum = NumberOfPml4EntriesNeeded + 1;
129 }
130
131 TotalPagesNum += ExtraPageTablePages;
132
133 return EFI_PAGES_TO_SIZE (TotalPagesNum);
134}
135
144VOID
145Create4GPageTables (
146 IN EFI_PHYSICAL_ADDRESS PageTablesAddress,
147 IN BOOLEAN Page1GSupport
148 )
149{
150 UINT8 PhysicalAddressBits;
151 EFI_PHYSICAL_ADDRESS PageAddress;
152 UINTN IndexOfPml4Entries;
153 UINTN IndexOfPdpEntries;
154 UINTN IndexOfPageDirectoryEntries;
155 UINT32 NumberOfPml4EntriesNeeded;
156 UINT32 NumberOfPdpEntriesNeeded;
157 PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
159 PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
160 PAGE_TABLE_ENTRY *PageDirectoryEntry;
161 UINTN BigPageAddress;
162 PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
163 UINT64 AddressEncMask;
164
165 //
166 // Make sure AddressEncMask is contained to smallest supported address field.
167 //
168 AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
169
170 //
171 // Create 4G page table by default,
172 // and let PF handler to handle > 4G request.
173 //
174 PhysicalAddressBits = 32;
175
176 //
177 // Calculate the table entries needed.
178 //
179 if (PhysicalAddressBits <= 39 ) {
180 NumberOfPml4EntriesNeeded = 1;
181 NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
182 } else {
183 NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
184 NumberOfPdpEntriesNeeded = 512;
185 }
186
187 //
188 // Pre-allocate big pages to avoid later allocations.
189 //
190 BigPageAddress = (UINTN)PageTablesAddress;
191
192 //
193 // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
194 //
195 PageMap = (VOID *)BigPageAddress;
196 BigPageAddress += SIZE_4KB;
197
198 PageMapLevel4Entry = PageMap;
199 PageAddress = 0;
200 for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {
201 //
202 // Each PML4 entry points to a page of Page Directory Pointer entires.
203 // So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
204 //
205 PageDirectoryPointerEntry = (VOID *)BigPageAddress;
206 BigPageAddress += SIZE_4KB;
207
208 //
209 // Make a PML4 Entry
210 //
211 PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask;
212 PageMapLevel4Entry->Bits.ReadWrite = 1;
213 PageMapLevel4Entry->Bits.Present = 1;
214
215 if (Page1GSupport) {
216 PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry;
217
218 for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
219 //
220 // Fill in the Page Directory entries
221 //
222 PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask;
223 PageDirectory1GEntry->Bits.ReadWrite = 1;
224 PageDirectory1GEntry->Bits.Present = 1;
225 PageDirectory1GEntry->Bits.MustBe1 = 1;
226 }
227 } else {
228 for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
229 //
230 // Each Directory Pointer entries points to a page of Page Directory entires.
231 // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
232 //
233 PageDirectoryEntry = (VOID *)BigPageAddress;
234 BigPageAddress += SIZE_4KB;
235
236 //
237 // Fill in a Page Directory Pointer Entries
238 //
239 PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask;
240 PageDirectoryPointerEntry->Bits.ReadWrite = 1;
241 PageDirectoryPointerEntry->Bits.Present = 1;
242
243 for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
244 //
245 // Fill in the Page Directory entries
246 //
247 PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask;
248 PageDirectoryEntry->Bits.ReadWrite = 1;
249 PageDirectoryEntry->Bits.Present = 1;
250 PageDirectoryEntry->Bits.MustBe1 = 1;
251 }
252 }
253
254 for ( ; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
255 ZeroMem (
256 PageDirectoryPointerEntry,
258 );
259 }
260 }
261 }
262
263 //
264 // For the PML4 entries we are not using fill in a null entry.
265 //
266 for ( ; IndexOfPml4Entries < 512; IndexOfPml4Entries++, PageMapLevel4Entry++) {
267 ZeroMem (
268 PageMapLevel4Entry,
270 );
271 }
272}
273
281VOID
282ReturnFunction (
283 SWITCH_32_TO_64_CONTEXT *EntrypointContext,
284 SWITCH_64_TO_32_CONTEXT *ReturnContext
285 )
286{
287 //
288 // Restore original GDT
289 //
290 AsmWriteGdtr (&ReturnContext->Gdtr);
291
292 //
293 // return to original caller
294 //
295 LongJump ((BASE_LIBRARY_JUMP_BUFFER *)(UINTN)EntrypointContext->JumpBuffer, 1);
296
297 //
298 // never be here
299 //
300 ASSERT (FALSE);
301}
302
314Thunk32To64 (
315 EFI_PHYSICAL_ADDRESS PageTableAddress,
316 SWITCH_32_TO_64_CONTEXT *Context,
317 SWITCH_64_TO_32_CONTEXT *ReturnContext
318 )
319{
320 UINTN SetJumpFlag;
321 EFI_STATUS Status;
322
323 //
324 // Save return address, LongJump will return here then
325 //
326 SetJumpFlag = SetJump ((BASE_LIBRARY_JUMP_BUFFER *)(UINTN)Context->JumpBuffer);
327
328 if (SetJumpFlag == 0) {
329 //
330 // Build 4G Page Tables.
331 //
332 Create4GPageTables (PageTableAddress, Context->Page1GSupport);
333
334 //
335 // Create 64-bit GDT
336 //
337 AsmWriteGdtr (&mGdt);
338
339 //
340 // Write CR3
341 //
342 AsmWriteCr3 ((UINTN)PageTableAddress);
343
344 DEBUG ((
345 DEBUG_INFO,
346 "%a() Stack Base: 0x%lx, Stack Size: 0x%lx\n",
347 __func__,
348 Context->StackBufferBase,
349 Context->StackBufferLength
350 ));
351
352 //
353 // Disable interrupt of Debug timer, since the IDT table cannot work in long mode
354 //
356 //
357 // Transfer to long mode
358 //
360 0x38,
361 (UINT64)Context->EntryPoint,
362 (UINT64)(UINTN)Context,
363 (UINT64)(UINTN)ReturnContext,
364 Context->StackBufferBase + Context->StackBufferLength
365 );
366 }
367
368 //
369 // Convert to 32-bit Status and return
370 //
371 Status = EFI_SUCCESS;
372 if ((UINTN)ReturnContext->ReturnStatus != 0) {
373 Status = ENCODE_ERROR ((UINTN)ReturnContext->ReturnStatus);
374 }
375
376 return Status;
377}
378
394ModeSwitch (
395 IN EFI_CAPSULE_LONG_MODE_BUFFER *LongModeBuffer,
396 IN COALESCE_ENTRY CoalesceEntry,
397 IN EFI_PHYSICAL_ADDRESS BlockListAddr,
398 IN MEMORY_RESOURCE_DESCRIPTOR *MemoryResource,
399 IN OUT VOID **MemoryBase,
400 IN OUT UINTN *MemorySize
401 )
402{
403 EFI_STATUS Status;
404 EFI_PHYSICAL_ADDRESS MemoryBase64;
405 UINT64 MemorySize64;
406 EFI_PHYSICAL_ADDRESS MemoryEnd64;
407 SWITCH_32_TO_64_CONTEXT Context;
408 SWITCH_64_TO_32_CONTEXT ReturnContext;
409 BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
410 EFI_PHYSICAL_ADDRESS ReservedRangeBase;
411 EFI_PHYSICAL_ADDRESS ReservedRangeEnd;
412 BOOLEAN Page1GSupport;
413
414 ZeroMem (&Context, sizeof (SWITCH_32_TO_64_CONTEXT));
415 ZeroMem (&ReturnContext, sizeof (SWITCH_64_TO_32_CONTEXT));
416
417 MemoryBase64 = (UINT64)(UINTN)*MemoryBase;
418 MemorySize64 = (UINT64)(UINTN)*MemorySize;
419 MemoryEnd64 = MemoryBase64 + MemorySize64;
420
421 Page1GSupport = IsPage1GSupport ();
422
423 //
424 // Merge memory range reserved for stack and page table
425 //
426 if (LongModeBuffer->StackBaseAddress < LongModeBuffer->PageTableAddress) {
427 ReservedRangeBase = LongModeBuffer->StackBaseAddress;
428 ReservedRangeEnd = LongModeBuffer->PageTableAddress + CalculatePageTableSize (Page1GSupport);
429 } else {
430 ReservedRangeBase = LongModeBuffer->PageTableAddress;
431 ReservedRangeEnd = LongModeBuffer->StackBaseAddress + LongModeBuffer->StackSize;
432 }
433
434 //
435 // Check if memory range reserved is overlap with MemoryBase ~ MemoryBase + MemorySize.
436 // If they are overlapped, get a larger range to process capsule data.
437 //
438 if (ReservedRangeBase <= MemoryBase64) {
439 if (ReservedRangeEnd < MemoryEnd64) {
440 MemoryBase64 = ReservedRangeEnd;
441 } else {
442 DEBUG ((DEBUG_ERROR, "Memory is not enough to process capsule!\n"));
443 return EFI_OUT_OF_RESOURCES;
444 }
445 } else if (ReservedRangeBase < MemoryEnd64) {
446 if ((ReservedRangeEnd < MemoryEnd64) &&
447 (ReservedRangeBase - MemoryBase64 < MemoryEnd64 - ReservedRangeEnd))
448 {
449 MemoryBase64 = ReservedRangeEnd;
450 } else {
451 MemorySize64 = (UINT64)(UINTN)(ReservedRangeBase - MemoryBase64);
452 }
453 }
454
455 //
456 // Initialize context jumping to 64-bit enviroment
457 //
458 Context.JumpBuffer = (EFI_PHYSICAL_ADDRESS)(UINTN)&JumpBuffer;
459 Context.StackBufferBase = LongModeBuffer->StackBaseAddress;
460 Context.StackBufferLength = LongModeBuffer->StackSize;
461 Context.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)CoalesceEntry;
462 Context.BlockListAddr = BlockListAddr;
463 Context.MemoryResource = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryResource;
464 Context.MemoryBase64Ptr = (EFI_PHYSICAL_ADDRESS)(UINTN)&MemoryBase64;
465 Context.MemorySize64Ptr = (EFI_PHYSICAL_ADDRESS)(UINTN)&MemorySize64;
466 Context.Page1GSupport = Page1GSupport;
467 Context.AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
468
469 //
470 // Prepare data for return back
471 //
472 ReturnContext.ReturnCs = 0x10;
473 ReturnContext.ReturnEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)ReturnFunction;
474 //
475 // Will save the return status of processing capsule
476 //
477 ReturnContext.ReturnStatus = 0;
478
479 //
480 // Save original GDT
481 //
482 AsmReadGdtr ((IA32_DESCRIPTOR *)&ReturnContext.Gdtr);
483
484 Status = Thunk32To64 (LongModeBuffer->PageTableAddress, &Context, &ReturnContext);
485
486 if (!EFI_ERROR (Status)) {
487 *MemoryBase = (VOID *)(UINTN)MemoryBase64;
488 *MemorySize = (UINTN)MemorySize64;
489 }
490
491 return Status;
492}
493
505FindCapsuleCoalesceImage (
506 OUT EFI_PHYSICAL_ADDRESS *CoalesceImageEntryPoint,
507 OUT UINT16 *CoalesceImageMachineType
508 )
509{
510 EFI_STATUS Status;
511 UINTN Instance;
512 EFI_PEI_LOAD_FILE_PPI *LoadFile;
513 EFI_PEI_FV_HANDLE VolumeHandle;
514 EFI_PEI_FILE_HANDLE FileHandle;
515 EFI_PHYSICAL_ADDRESS CoalesceImageAddress;
516 UINT64 CoalesceImageSize;
517 UINT32 AuthenticationState;
518
519 Instance = 0;
520
521 while (TRUE) {
522 Status = PeiServicesFfsFindNextVolume (Instance++, &VolumeHandle);
523 if (EFI_ERROR (Status)) {
524 return Status;
525 }
526
527 Status = PeiServicesFfsFindFileByName (PcdGetPtr (PcdCapsuleCoalesceFile), VolumeHandle, &FileHandle);
528 if (!EFI_ERROR (Status)) {
529 Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, 0, NULL, (VOID **)&LoadFile);
530 ASSERT_EFI_ERROR (Status);
531
532 Status = LoadFile->LoadFile (
533 LoadFile,
534 FileHandle,
535 &CoalesceImageAddress,
536 &CoalesceImageSize,
537 CoalesceImageEntryPoint,
538 &AuthenticationState
539 );
540 if (EFI_ERROR (Status)) {
541 DEBUG ((DEBUG_ERROR, "Unable to find PE32 section in CapsuleX64 image ffs %r!\n", Status));
542 return Status;
543 }
544
545 *CoalesceImageMachineType = PeCoffLoaderGetMachineType ((VOID *)(UINTN)CoalesceImageAddress);
546 break;
547 } else {
548 continue;
549 }
550 }
551
552 return Status;
553}
554
565GetLongModeContext (
566 OUT EFI_CAPSULE_LONG_MODE_BUFFER *LongModeBuffer
567 )
568{
569 EFI_STATUS Status;
570 UINTN Size;
571 EFI_PEI_READ_ONLY_VARIABLE2_PPI *PPIVariableServices;
572
573 Status = PeiServicesLocatePpi (
574 &gEfiPeiReadOnlyVariable2PpiGuid,
575 0,
576 NULL,
577 (VOID **)&PPIVariableServices
578 );
579 ASSERT_EFI_ERROR (Status);
580
581 Size = sizeof (EFI_CAPSULE_LONG_MODE_BUFFER);
582 Status = PPIVariableServices->GetVariable (
583 PPIVariableServices,
584 EFI_CAPSULE_LONG_MODE_BUFFER_NAME,
585 &gEfiCapsuleVendorGuid,
586 NULL,
587 &Size,
588 LongModeBuffer
589 );
590 if (EFI_ERROR (Status)) {
591 DEBUG ((DEBUG_ERROR, "Error Get LongModeBuffer variable %r!\n", Status));
592 }
593
594 return Status;
595}
596
597#endif
598
599#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
600
607UINT8
608GetPhysicalAddressBits (
609 VOID
610 )
611{
612 UINT32 RegEax;
613 UINT8 PhysicalAddressBits;
614 VOID *Hob;
615
616 //
617 // Get physical address bits supported.
618 //
619 Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
620 if (Hob != NULL) {
621 PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
622 } else {
623 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
624 if (RegEax >= 0x80000008) {
625 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
626 PhysicalAddressBits = (UINT8)RegEax;
627 } else {
628 PhysicalAddressBits = 36;
629 }
630 }
631
632 //
633 // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
634 //
635 ASSERT (PhysicalAddressBits <= 52);
636 if (PhysicalAddressBits > 48) {
637 PhysicalAddressBits = 48;
638 }
639
640 return PhysicalAddressBits;
641}
642
643#endif
644
651VOID
653 IN OUT MEMORY_RESOURCE_DESCRIPTOR *MemoryResource
654 )
655{
656 MEMORY_RESOURCE_DESCRIPTOR *MemoryResourceEntry;
657 MEMORY_RESOURCE_DESCRIPTOR *NextMemoryResourceEntry;
658 MEMORY_RESOURCE_DESCRIPTOR TempMemoryResource;
659
660 MemoryResourceEntry = MemoryResource;
661 NextMemoryResourceEntry = MemoryResource + 1;
662 while (MemoryResourceEntry->ResourceLength != 0) {
663 while (NextMemoryResourceEntry->ResourceLength != 0) {
664 if (MemoryResourceEntry->PhysicalStart > NextMemoryResourceEntry->PhysicalStart) {
665 CopyMem (&TempMemoryResource, MemoryResourceEntry, sizeof (MEMORY_RESOURCE_DESCRIPTOR));
666 CopyMem (MemoryResourceEntry, NextMemoryResourceEntry, sizeof (MEMORY_RESOURCE_DESCRIPTOR));
667 CopyMem (NextMemoryResourceEntry, &TempMemoryResource, sizeof (MEMORY_RESOURCE_DESCRIPTOR));
668 }
669
670 NextMemoryResourceEntry = NextMemoryResourceEntry + 1;
671 }
672
673 MemoryResourceEntry = MemoryResourceEntry + 1;
674 NextMemoryResourceEntry = MemoryResourceEntry + 1;
675 }
676}
677
684VOID
686 IN OUT MEMORY_RESOURCE_DESCRIPTOR *MemoryResource
687 )
688{
689 MEMORY_RESOURCE_DESCRIPTOR *MemoryResourceEntry;
690 MEMORY_RESOURCE_DESCRIPTOR *NewMemoryResourceEntry;
691 MEMORY_RESOURCE_DESCRIPTOR *NextMemoryResourceEntry;
692 MEMORY_RESOURCE_DESCRIPTOR *MemoryResourceEnd;
693
694 MemoryResourceEntry = MemoryResource;
695 NewMemoryResourceEntry = MemoryResource;
696 while (MemoryResourceEntry->ResourceLength != 0) {
697 CopyMem (NewMemoryResourceEntry, MemoryResourceEntry, sizeof (MEMORY_RESOURCE_DESCRIPTOR));
698 NextMemoryResourceEntry = MemoryResourceEntry + 1;
699
700 while ((NextMemoryResourceEntry->ResourceLength != 0) &&
701 (NextMemoryResourceEntry->PhysicalStart == (MemoryResourceEntry->PhysicalStart + MemoryResourceEntry->ResourceLength)))
702 {
703 MemoryResourceEntry->ResourceLength += NextMemoryResourceEntry->ResourceLength;
704 if (NewMemoryResourceEntry != MemoryResourceEntry) {
705 NewMemoryResourceEntry->ResourceLength += NextMemoryResourceEntry->ResourceLength;
706 }
707
708 NextMemoryResourceEntry = NextMemoryResourceEntry + 1;
709 }
710
711 MemoryResourceEntry = NextMemoryResourceEntry;
712 NewMemoryResourceEntry = NewMemoryResourceEntry + 1;
713 }
714
715 //
716 // Set NULL terminate memory resource descriptor after merging.
717 //
718 MemoryResourceEnd = NewMemoryResourceEntry;
719 ZeroMem (MemoryResourceEnd, sizeof (MEMORY_RESOURCE_DESCRIPTOR));
720}
721
732 VOID
733 )
734{
736 UINTN Index;
737 EFI_HOB_RESOURCE_DESCRIPTOR *ResourceDescriptor;
738 MEMORY_RESOURCE_DESCRIPTOR *MemoryResource;
739 EFI_STATUS Status;
740
741 //
742 // Get the count of memory resource descriptor.
743 //
744 Index = 0;
745 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
746 while (Hob.Raw != NULL) {
747 ResourceDescriptor = (EFI_HOB_RESOURCE_DESCRIPTOR *)Hob.Raw;
748 if (ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
749 Index++;
750 }
751
752 Hob.Raw = GET_NEXT_HOB (Hob);
753 Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
754 }
755
756 if (Index == 0) {
757 DEBUG ((DEBUG_INFO | DEBUG_WARN, "No memory resource descriptor reported in HOB list before capsule Coalesce\n"));
758 #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
759 //
760 // Allocate memory to hold memory resource descriptor,
761 // include extra one NULL terminate memory resource descriptor.
762 //
763 Status = PeiServicesAllocatePool ((1 + 1) * sizeof (MEMORY_RESOURCE_DESCRIPTOR), (VOID **)&MemoryResource);
764 ASSERT_EFI_ERROR (Status);
765 ZeroMem (MemoryResource, (1 + 1) * sizeof (MEMORY_RESOURCE_DESCRIPTOR));
766
767 MemoryResource[0].PhysicalStart = 0;
768 MemoryResource[0].ResourceLength = LShiftU64 (1, GetPhysicalAddressBits ());
769 DEBUG ((
770 DEBUG_INFO,
771 "MemoryResource[0x0] - Start(0x%0lx) Length(0x%0lx)\n",
772 MemoryResource[0x0].PhysicalStart,
773 MemoryResource[0x0].ResourceLength
774 ));
775 return MemoryResource;
776 #else
777 return NULL;
778 #endif
779 }
780
781 //
782 // Allocate memory to hold memory resource descriptor,
783 // include extra one NULL terminate memory resource descriptor.
784 //
785 Status = PeiServicesAllocatePool ((Index + 1) * sizeof (MEMORY_RESOURCE_DESCRIPTOR), (VOID **)&MemoryResource);
786 ASSERT_EFI_ERROR (Status);
787 ZeroMem (MemoryResource, (Index + 1) * sizeof (MEMORY_RESOURCE_DESCRIPTOR));
788
789 //
790 // Get the content of memory resource descriptor.
791 //
792 Index = 0;
793 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
794 while (Hob.Raw != NULL) {
795 ResourceDescriptor = (EFI_HOB_RESOURCE_DESCRIPTOR *)Hob.Raw;
796 if (ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
797 DEBUG ((
798 DEBUG_INFO,
799 "MemoryResource[0x%x] - Start(0x%0lx) Length(0x%0lx)\n",
800 Index,
801 ResourceDescriptor->PhysicalStart,
802 ResourceDescriptor->ResourceLength
803 ));
804 MemoryResource[Index].PhysicalStart = ResourceDescriptor->PhysicalStart;
805 MemoryResource[Index].ResourceLength = ResourceDescriptor->ResourceLength;
806 Index++;
807 }
808
809 Hob.Raw = GET_NEXT_HOB (Hob);
810 Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
811 }
812
813 SortMemoryResourceDescriptor (MemoryResource);
814 MergeMemoryResourceDescriptor (MemoryResource);
815
816 DEBUG ((DEBUG_INFO, "Dump MemoryResource[] after sorted and merged\n"));
817 for (Index = 0; MemoryResource[Index].ResourceLength != 0; Index++) {
818 DEBUG ((
819 DEBUG_INFO,
820 " MemoryResource[0x%x] - Start(0x%0lx) Length(0x%0lx)\n",
821 Index,
822 MemoryResource[Index].PhysicalStart,
823 MemoryResource[Index].ResourceLength
824 ));
825 }
826
827 return MemoryResource;
828}
829
837BOOLEAN
839 VOID
840 )
841{
842 EFI_STATUS Status;
843 UINTN Size;
844 EFI_PEI_READ_ONLY_VARIABLE2_PPI *PPIVariableServices;
845 EFI_PHYSICAL_ADDRESS CapsuleDataPtr64;
846
847 CapsuleDataPtr64 = 0;
848
849 Status = PeiServicesLocatePpi (
850 &gEfiPeiReadOnlyVariable2PpiGuid,
851 0,
852 NULL,
853 (VOID **)&PPIVariableServices
854 );
855
856 if (EFI_ERROR (Status)) {
857 DEBUG ((DEBUG_ERROR, "Failed to find ReadOnlyVariable2PPI\n"));
858 return FALSE;
859 }
860
861 //
862 // Check for Update capsule
863 //
864 Size = sizeof (CapsuleDataPtr64);
865 Status = PPIVariableServices->GetVariable (
866 PPIVariableServices,
868 &gEfiCapsuleVendorGuid,
869 NULL,
870 &Size,
871 (VOID *)&CapsuleDataPtr64
872 );
873
874 if (!EFI_ERROR (Status)) {
875 return TRUE;
876 }
877
878 return FALSE;
879}
880
895 OUT UINTN *ListLength,
896 OUT EFI_PHYSICAL_ADDRESS **HeadList
897 )
898{
899 EFI_STATUS Status;
900 UINTN Size;
901 UINTN Index;
902 UINTN TempIndex;
903 UINTN ValidIndex;
904 BOOLEAN Flag;
905 CHAR16 CapsuleVarName[30];
906 CHAR16 *TempVarName;
907 EFI_PHYSICAL_ADDRESS CapsuleDataPtr64;
908 EFI_PEI_READ_ONLY_VARIABLE2_PPI *PPIVariableServices;
909 EFI_PHYSICAL_ADDRESS *TempList;
910 EFI_PHYSICAL_ADDRESS *EnlargedTempList;
911 UINTN TempListLength;
912
913 Index = 0;
914 TempVarName = NULL;
915 CapsuleVarName[0] = 0;
916 ValidIndex = 0;
917 CapsuleDataPtr64 = 0;
918
919 if ((ListLength == NULL) || (HeadList == NULL)) {
920 DEBUG ((DEBUG_ERROR, "%a Invalid parameters. Inputs can't be NULL\n", __func__));
921 ASSERT (ListLength != NULL);
922 ASSERT (HeadList != NULL);
923 return EFI_INVALID_PARAMETER;
924 }
925
926 *ListLength = 0;
927 *HeadList = NULL;
928
929 Status = PeiServicesLocatePpi (
930 &gEfiPeiReadOnlyVariable2PpiGuid,
931 0,
932 NULL,
933 (VOID **)&PPIVariableServices
934 );
935
936 if (EFI_ERROR (Status)) {
937 DEBUG ((DEBUG_ERROR, "Failed to find ReadOnlyVariable2PPI\n"));
938 return Status;
939 }
940
941 //
942 // Allocate memory for sg list head
943 //
944 TempListLength = DEFAULT_SG_LIST_HEADS * sizeof (EFI_PHYSICAL_ADDRESS);
945 TempList = AllocateZeroPool (TempListLength);
946 if (TempList == NULL) {
947 DEBUG ((DEBUG_ERROR, "Failed to allocate memory\n"));
948 return EFI_OUT_OF_RESOURCES;
949 }
950
951 //
952 // setup var name buffer for update capsules
953 //
954 StrCpyS (CapsuleVarName, sizeof (CapsuleVarName) / sizeof (CHAR16), EFI_CAPSULE_VARIABLE_NAME);
955 TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
956 while (TRUE) {
957 if (Index != 0) {
959 TempVarName,
960 (sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName)),
961 0,
962 Index,
963 0
964 );
965 }
966
967 Size = sizeof (CapsuleDataPtr64);
968 Status = PPIVariableServices->GetVariable (
969 PPIVariableServices,
970 CapsuleVarName,
971 &gEfiCapsuleVendorGuid,
972 NULL,
973 &Size,
974 (VOID *)&CapsuleDataPtr64
975 );
976
977 if (EFI_ERROR (Status)) {
978 if (Status != EFI_NOT_FOUND) {
979 DEBUG ((DEBUG_ERROR, "Unexpected error getting Capsule Update variable. Status = %r\n", Status));
980 }
981
982 break;
983 }
984
985 //
986 // If this BlockList has been linked before, skip this variable
987 //
988 Flag = FALSE;
989 for (TempIndex = 0; TempIndex < ValidIndex; TempIndex++) {
990 if (TempList[TempIndex] == CapsuleDataPtr64) {
991 Flag = TRUE;
992 break;
993 }
994 }
995
996 if (Flag) {
997 Index++;
998 continue;
999 }
1000
1001 //
1002 // The TempList is full, enlarge it
1003 //
1004 if ((ValidIndex + 1) >= TempListLength) {
1005 EnlargedTempList = AllocateZeroPool (TempListLength * 2);
1006 if (EnlargedTempList == NULL) {
1007 DEBUG ((DEBUG_ERROR, "Fail to allocate memory!\n"));
1008 return EFI_OUT_OF_RESOURCES;
1009 }
1010
1011 CopyMem (EnlargedTempList, TempList, TempListLength);
1012 FreePool (TempList);
1013 TempList = EnlargedTempList;
1014 TempListLength *= 2;
1015 }
1016
1017 //
1018 // add it to the cached list
1019 //
1020 TempList[ValidIndex++] = CapsuleDataPtr64;
1021 Index++;
1022 }
1023
1024 if (ValidIndex == 0) {
1025 DEBUG ((DEBUG_ERROR, "%a didn't find any SG lists in variables\n", __func__));
1026 return EFI_NOT_FOUND;
1027 }
1028
1029 *HeadList = AllocateZeroPool ((ValidIndex + 1) * sizeof (EFI_PHYSICAL_ADDRESS));
1030 if (*HeadList == NULL) {
1031 DEBUG ((DEBUG_ERROR, "Failed to allocate memory\n"));
1032 return EFI_OUT_OF_RESOURCES;
1033 }
1034
1035 CopyMem (*HeadList, TempList, (ValidIndex) * sizeof (EFI_PHYSICAL_ADDRESS));
1036 *ListLength = ValidIndex;
1037
1038 return EFI_SUCCESS;
1039}
1040
1065EFIAPI
1067 IN EFI_PEI_SERVICES **PeiServices,
1068 IN OUT VOID **MemoryBase,
1069 IN OUT UINTN *MemorySize
1070 )
1071{
1072 EFI_STATUS Status;
1073 EFI_BOOT_MODE BootMode;
1074 UINTN ListLength;
1075 EFI_PHYSICAL_ADDRESS *VariableArrayAddress;
1076 MEMORY_RESOURCE_DESCRIPTOR *MemoryResource;
1077
1078 #ifdef MDE_CPU_IA32
1079 UINT16 CoalesceImageMachineType;
1080 EFI_PHYSICAL_ADDRESS CoalesceImageEntryPoint;
1081 COALESCE_ENTRY CoalesceEntry;
1082 EFI_CAPSULE_LONG_MODE_BUFFER LongModeBuffer;
1083 #endif
1084
1085 ListLength = 0;
1086 VariableArrayAddress = NULL;
1087
1088 //
1089 // Someone should have already ascertained the boot mode. If it's not
1090 // capsule update, then return normally.
1091 //
1092 Status = PeiServicesGetBootMode (&BootMode);
1093 if (EFI_ERROR (Status) || (BootMode != BOOT_ON_FLASH_UPDATE)) {
1094 DEBUG ((DEBUG_ERROR, "Boot mode is not correct for capsule update path.\n"));
1095 Status = EFI_NOT_FOUND;
1096 goto Done;
1097 }
1098
1099 //
1100 // Get SG list entries
1101 //
1102 Status = GetScatterGatherHeadEntries (&ListLength, &VariableArrayAddress);
1103 if (EFI_ERROR (Status) || (VariableArrayAddress == NULL)) {
1104 DEBUG ((DEBUG_ERROR, "%a failed to get Scatter Gather List Head Entries. Status = %r\n", __func__, Status));
1105 goto Done;
1106 }
1107
1108 MemoryResource = BuildMemoryResourceDescriptor ();
1109
1110 #ifdef MDE_CPU_IA32
1111 if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
1112 //
1113 // Switch to 64-bit mode to process capsule data when:
1114 // 1. When DXE phase is 64-bit
1115 // 2. When the buffer for 64-bit transition exists
1116 // 3. When Capsule X64 image is built in BIOS image
1117 // In 64-bit mode, we can process capsule data above 4GB.
1118 //
1119 CoalesceImageEntryPoint = 0;
1120 Status = GetLongModeContext (&LongModeBuffer);
1121 if (EFI_ERROR (Status)) {
1122 DEBUG ((DEBUG_ERROR, "Fail to find the variable for long mode context!\n"));
1123 Status = EFI_NOT_FOUND;
1124 goto Done;
1125 }
1126
1127 Status = FindCapsuleCoalesceImage (&CoalesceImageEntryPoint, &CoalesceImageMachineType);
1128 if ((EFI_ERROR (Status)) || (CoalesceImageMachineType != EFI_IMAGE_MACHINE_X64)) {
1129 DEBUG ((DEBUG_ERROR, "Fail to find CapsuleX64 module in FV!\n"));
1130 Status = EFI_NOT_FOUND;
1131 goto Done;
1132 }
1133
1134 ASSERT (CoalesceImageEntryPoint != 0);
1135 CoalesceEntry = (COALESCE_ENTRY)(UINTN)CoalesceImageEntryPoint;
1136 Status = ModeSwitch (&LongModeBuffer, CoalesceEntry, (EFI_PHYSICAL_ADDRESS)(UINTN)VariableArrayAddress, MemoryResource, MemoryBase, MemorySize);
1137 } else {
1138 //
1139 // Capsule is processed in IA32 mode.
1140 //
1141 Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS *)(UINTN)VariableArrayAddress, MemoryResource, MemoryBase, MemorySize);
1142 }
1143
1144 #else
1145 //
1146 // Process capsule directly.
1147 //
1148 Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS *)(UINTN)VariableArrayAddress, MemoryResource, MemoryBase, MemorySize);
1149 #endif
1150
1151 DEBUG ((DEBUG_INFO, "Capsule Coalesce Status = %r!\n", Status));
1152
1153 if (Status == EFI_BUFFER_TOO_SMALL) {
1154 DEBUG ((DEBUG_ERROR, "There is not enough memory to process capsule!\n"));
1155 }
1156
1157 if (Status == EFI_NOT_FOUND) {
1158 DEBUG ((DEBUG_ERROR, "Fail to parse capsule descriptor in memory!\n"));
1160 EFI_ERROR_CODE | EFI_ERROR_MAJOR,
1161 (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR)
1162 );
1163 }
1164
1165Done:
1166 return Status;
1167}
1168
1179EFIAPI
1181 IN EFI_PEI_SERVICES **PeiServices
1182 )
1183{
1184 if (AreCapsulesStaged ()) {
1185 return EFI_SUCCESS;
1186 } else {
1187 return EFI_NOT_FOUND;
1188 }
1189}
1190
1203BOOLEAN
1205 IN EFI_PEI_SERVICES **PeiServices,
1206 IN VOID *CapsuleBase
1207 )
1208{
1209 UINT32 *TestPtr;
1210 UINT32 TestCounter;
1211 UINT32 TestSize;
1212 BOOLEAN RetValue;
1213
1214 RetValue = FALSE;
1215
1216 //
1217 // Look at the capsule data and determine if it's a test pattern. If it
1218 // is, then test it now.
1219 //
1220 TestPtr = (UINT32 *)CapsuleBase;
1221 //
1222 // 0x54534554 "TEST"
1223 //
1224 if (*TestPtr == 0x54534554) {
1225 RetValue = TRUE;
1226 DEBUG ((DEBUG_INFO, "Capsule test pattern mode activated...\n"));
1227 TestSize = TestPtr[1] / sizeof (UINT32);
1228 //
1229 // Skip over the signature and the size fields in the pattern data header
1230 //
1231 TestPtr += 2;
1232 TestCounter = 0;
1233 while (TestSize > 0) {
1234 if (*TestPtr != TestCounter) {
1235 DEBUG ((DEBUG_INFO, "Capsule test pattern mode FAILED: BaseAddr/FailAddr 0x%X 0x%X\n", (UINT32)(UINTN)(EFI_CAPSULE_PEIM_PRIVATE_DATA *)CapsuleBase, (UINT32)(UINTN)TestPtr));
1236 return TRUE;
1237 }
1238
1239 TestPtr++;
1240 TestCounter++;
1241 TestSize--;
1242 }
1243
1244 DEBUG ((DEBUG_INFO, "Capsule test pattern mode SUCCESS\n"));
1245 }
1246
1247 return RetValue;
1248}
1249
1268EFIAPI
1270 IN EFI_PEI_SERVICES **PeiServices,
1271 IN VOID *CapsuleBase,
1272 IN UINTN CapsuleSize
1273 )
1274{
1275 EFI_STATUS Status;
1276 EFI_CAPSULE_PEIM_PRIVATE_DATA *PrivateData;
1277 UINTN Size;
1278 EFI_PHYSICAL_ADDRESS NewBuffer;
1279 UINTN CapsuleNumber;
1280 UINT32 Index;
1281 EFI_PHYSICAL_ADDRESS BaseAddress;
1282 UINT64 Length;
1283
1284 PrivateData = (EFI_CAPSULE_PEIM_PRIVATE_DATA *)CapsuleBase;
1285 if (PrivateData->Signature != EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE) {
1286 return EFI_VOLUME_CORRUPTED;
1287 }
1288
1289 if (PrivateData->CapsuleAllImageSize >= MAX_ADDRESS) {
1290 DEBUG ((DEBUG_ERROR, "CapsuleAllImageSize too big - 0x%lx\n", PrivateData->CapsuleAllImageSize));
1291 return EFI_OUT_OF_RESOURCES;
1292 }
1293
1294 if (PrivateData->CapsuleNumber >= MAX_ADDRESS) {
1295 DEBUG ((DEBUG_ERROR, "CapsuleNumber too big - 0x%lx\n", PrivateData->CapsuleNumber));
1296 return EFI_OUT_OF_RESOURCES;
1297 }
1298
1299 //
1300 // Capsule Number and Capsule Offset is in the tail of Capsule data.
1301 //
1302 Size = (UINTN)PrivateData->CapsuleAllImageSize;
1303 CapsuleNumber = (UINTN)PrivateData->CapsuleNumber;
1304 //
1305 // Allocate the memory so that it gets preserved into DXE
1306 //
1307 Status = PeiServicesAllocatePages (
1309 EFI_SIZE_TO_PAGES (Size),
1310 &NewBuffer
1311 );
1312
1313 if (Status != EFI_SUCCESS) {
1314 DEBUG ((DEBUG_ERROR, "AllocatePages Failed!\n"));
1315 return Status;
1316 }
1317
1318 //
1319 // Copy to our new buffer for DXE
1320 //
1321 DEBUG ((DEBUG_INFO, "Capsule copy from 0x%8X to 0x%8X with size 0x%8X\n", (UINTN)((UINT8 *)PrivateData + sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof (UINT64)), (UINTN)NewBuffer, Size));
1322 CopyMem ((VOID *)(UINTN)NewBuffer, (VOID *)(UINTN)((UINT8 *)PrivateData + sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof (UINT64)), Size);
1323 //
1324 // Check for test data pattern. If it is the test pattern, then we'll
1325 // test it and still create the HOB so that it can be used to verify
1326 // that capsules don't get corrupted all the way into BDS. BDS will
1327 // still try to turn it into a firmware volume, but will think it's
1328 // corrupted so nothing will happen.
1329 //
1330 DEBUG_CODE (
1331 CapsuleTestPattern (PeiServices, (VOID *)(UINTN)NewBuffer);
1332 );
1333
1334 //
1335 // Build the UEFI Capsule Hob for each capsule image.
1336 //
1337 for (Index = 0; Index < CapsuleNumber; Index++) {
1338 BaseAddress = NewBuffer + PrivateData->CapsuleOffset[Index];
1339 Length = ((EFI_CAPSULE_HEADER *)((UINTN)BaseAddress))->CapsuleImageSize;
1340
1341 BuildCvHob (BaseAddress, Length);
1342 }
1343
1344 return EFI_SUCCESS;
1345}
1346
1347CONST EFI_PEI_CAPSULE_PPI mCapsulePpi = {
1351};
1352
1353CONST EFI_PEI_PPI_DESCRIPTOR mUefiPpiListCapsule = {
1354 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
1355 &gEfiPeiCapsulePpiGuid,
1356 (EFI_PEI_CAPSULE_PPI *)&mCapsulePpi
1357};
1358
1369EFIAPI
1371 IN EFI_PEI_FILE_HANDLE FileHandle,
1372 IN CONST EFI_PEI_SERVICES **PeiServices
1373 )
1374{
1375 //
1376 // Just produce our PPI
1377 //
1378 return PeiServicesInstallPpi (&mUefiPpiListCapsule);
1379}
UINT64 UINTN
#define MAX_ADDRESS
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
Definition: HobLib.c:142
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
VOID EFIAPI BuildCvHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: HobLib.c:494
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
RETURNS_TWICE UINTN EFIAPI SetJump(OUT BASE_LIBRARY_JUMP_BUFFER *JumpBuffer)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
VOID EFIAPI LongJump(IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, IN UINTN Value)
Definition: LongJump.c:29
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI CapsuleDataCoalesce(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PHYSICAL_ADDRESS *BlockListBuffer, IN MEMORY_RESOURCE_DESCRIPTOR *MemoryResource, IN OUT VOID **MemoryBase, IN OUT UINTN *MemorySize)
#define EFI_CAPSULE_VARIABLE_NAME
Definition: CapsuleVendor.h:33
BOOLEAN EFIAPI SaveAndSetDebugTimerInterrupt(IN BOOLEAN EnableStatus)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI PeiServicesFfsFindNextVolume(IN UINTN Instance, IN OUT EFI_PEI_FV_HANDLE *VolumeHandle)
EFI_STATUS EFIAPI PeiServicesGetBootMode(OUT EFI_BOOT_MODE *BootMode)
EFI_STATUS EFIAPI PeiServicesAllocatePool(IN UINTN Size, OUT VOID **Buffer)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesFfsFindFileByName(IN CONST EFI_GUID *FileName, IN CONST EFI_PEI_FV_HANDLE VolumeHandle, OUT EFI_PEI_FILE_HANDLE *FileHandle)
EFI_STATUS EFIAPI PeiServicesAllocatePages(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT EFI_PHYSICAL_ADDRESS *Memory)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
UINTN EFIAPI AsmWriteCr3(UINTN Cr3)
RETURN_STATUS EFIAPI UnicodeValueToStringS(IN OUT CHAR16 *Buffer, IN UINTN BufferSize, IN UINTN Flags, IN INT64 Value, IN UINTN Width)
Definition: PrintLib.c:652
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define ENCODE_ERROR(StatusCode)
Definition: Base.h:1037
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
#define REPORT_STATUS_CODE(Type, Value)
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuId.c:36
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
UINT32 EFI_BOOT_MODE
Definition: PiBootMode.h:18
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
VOID * EFI_PEI_FV_HANDLE
Definition: PiPeiCis.h:21
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_IMAGE_MACHINE_X64
Definition: UefiBaseType.h:233
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
MEMORY_RESOURCE_DESCRIPTOR * BuildMemoryResourceDescriptor(VOID)
Definition: UefiCapsule.c:731
EFI_STATUS EFIAPI CapsuleMain(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: UefiCapsule.c:1370
VOID MergeMemoryResourceDescriptor(IN OUT MEMORY_RESOURCE_DESCRIPTOR *MemoryResource)
Definition: UefiCapsule.c:685
EFI_STATUS EFIAPI CapsuleCoalesce(IN EFI_PEI_SERVICES **PeiServices, IN OUT VOID **MemoryBase, IN OUT UINTN *MemorySize)
Definition: UefiCapsule.c:1066
VOID SortMemoryResourceDescriptor(IN OUT MEMORY_RESOURCE_DESCRIPTOR *MemoryResource)
Definition: UefiCapsule.c:652
EFI_STATUS EFIAPI CreateState(IN EFI_PEI_SERVICES **PeiServices, IN VOID *CapsuleBase, IN UINTN CapsuleSize)
Definition: UefiCapsule.c:1269
EFI_STATUS EFIAPI CheckCapsuleUpdate(IN EFI_PEI_SERVICES **PeiServices)
Definition: UefiCapsule.c:1180
EFI_STATUS GetScatterGatherHeadEntries(OUT UINTN *ListLength, OUT EFI_PHYSICAL_ADDRESS **HeadList)
Definition: UefiCapsule.c:894
BOOLEAN CapsuleTestPattern(IN EFI_PEI_SERVICES **PeiServices, IN VOID *CapsuleBase)
Definition: UefiCapsule.c:1204
BOOLEAN AreCapsulesStaged(VOID)
Definition: UefiCapsule.c:838
@ EfiRuntimeServicesData
VOID EFIAPI AsmEnablePaging64(IN UINT16 Cs, IN UINT64 EntryPoint, IN UINT64 Context1 OPTIONAL, IN UINT64 Context2 OPTIONAL, IN UINT64 NewStack)
VOID EFIAPI AsmReadGdtr(OUT IA32_DESCRIPTOR *Gdtr)
Definition: X86ReadGdtr.c:24
VOID EFIAPI AsmWriteGdtr(IN CONST IA32_DESCRIPTOR *Gdtr)
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: PiHob.h:328
EFI_RESOURCE_TYPE ResourceType
Definition: PiHob.h:320
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: CommonHeader.h:40