1 /** @file
2   The logic to process capsule.
3 
4   Caution: This module requires additional review when modified.
5   This driver will have external input - capsule image.
6   This external input must be validated carefully to avoid security issue like
7   buffer overflow, integer overflow.
8 
9   CapsuleDataCoalesce() will do basic validation before coalesce capsule data
10   into memory.
11 
12 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
13 Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
14 This program and the accompanying materials
15 are licensed and made available under the terms and conditions of the BSD License
16 which accompanies this distribution.  The full text of the license may be found at
17 http://opensource.org/licenses/bsd-license.php
18 
19 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 
22 **/
23 
24 #include <Uefi.h>
25 #include <PiPei.h>
26 
27 #include <Guid/CapsuleVendor.h>
28 
29 #include <Library/BaseMemoryLib.h>
30 #include <Library/DebugLib.h>
31 #include <Library/PrintLib.h>
32 #include <Library/BaseLib.h>
33 
34 #include "CommonHeader.h"
35 
36 #define MIN_COALESCE_ADDR                     (1024 * 1024)
37 
38 /**
39   Given a pointer to the capsule block list, info on the available system
40   memory, and the size of a buffer, find a free block of memory where a
41   buffer of the given size can be copied to safely.
42 
43   @param BlockList   Pointer to head of capsule block descriptors
44   @param MemBase     Pointer to the base of memory in which we want to find free space
45   @param MemSize     The size of the block of memory pointed to by MemBase
46   @param DataSize    How big a free block we want to find
47 
48   @return A pointer to a memory block of at least DataSize that lies somewhere
49           between MemBase and (MemBase + MemSize). The memory pointed to does not
50           contain any of the capsule block descriptors or capsule blocks pointed to
51           by the BlockList.
52 
53 **/
54 UINT8 *
55 FindFreeMem (
56   EFI_CAPSULE_BLOCK_DESCRIPTOR     *BlockList,
57   UINT8                            *MemBase,
58   UINTN                             MemSize,
59   UINTN                             DataSize
60   );
61 
62 /**
63   Check the integrity of the capsule descriptors.
64 
65   @param BlockList    Pointer to the capsule descriptors
66 
67   @retval NULL           BlockList is not valid.
68   @retval LastBlockDesc  Last one Block in BlockList
69 
70 **/
71 EFI_CAPSULE_BLOCK_DESCRIPTOR *
72 ValidateCapsuleIntegrity (
73   IN EFI_CAPSULE_BLOCK_DESCRIPTOR    *BlockList
74   );
75 
76 /**
77   The capsule block descriptors may be fragmented and spread all over memory.
78   To simplify the coalescing of capsule blocks, first coalesce all the
79   capsule block descriptors low in memory.
80 
81   The descriptors passed in can be fragmented throughout memory. Here
82   they are relocated into memory to turn them into a contiguous (null
83   terminated) array.
84 
85   @param PeiServices    pointer to PEI services table
86   @param BlockList      pointer to the capsule block descriptors
87   @param NumDescriptors number of capsule data block descriptors, whose Length is non-zero.
88   @param MemBase        base of system memory in which we can work
89   @param MemSize        size of the system memory pointed to by MemBase
90 
91   @retval NULL    could not relocate the descriptors
92   @retval Pointer to the base of the successfully-relocated block descriptors.
93 
94 **/
95 EFI_CAPSULE_BLOCK_DESCRIPTOR *
96 RelocateBlockDescriptors (
97   IN EFI_PEI_SERVICES                  **PeiServices,
98   IN EFI_CAPSULE_BLOCK_DESCRIPTOR      *BlockList,
99   IN UINTN                              NumDescriptors,
100   IN UINT8                             *MemBase,
101   IN UINTN                             MemSize
102   );
103 
104 /**
105   Check every capsule header.
106 
107   @param CapsuleHeader   The pointer to EFI_CAPSULE_HEADER
108 
109   @retval FALSE  Capsule is OK
110   @retval TRUE   Capsule is corrupted
111 
112 **/
113 BOOLEAN
114 IsCapsuleCorrupted (
115   IN EFI_CAPSULE_HEADER       *CapsuleHeader
116   );
117 
118 /**
119   Determine if two buffers overlap in memory.
120 
121   @param Buff1   pointer to first buffer
122   @param Size1   size of Buff1
123   @param Buff2   pointer to second buffer
124   @param Size2   size of Buff2
125 
126   @retval TRUE    Buffers overlap in memory.
127   @retval FALSE   Buffer doesn't overlap.
128 
129 **/
130 BOOLEAN
131 IsOverlapped (
132   UINT8     *Buff1,
133   UINTN     Size1,
134   UINT8     *Buff2,
135   UINTN     Size2
136   );
137 
138 /**
139   Given a pointer to a capsule block descriptor, traverse the list to figure
140   out how many legitimate descriptors there are, and how big the capsule it
141   refers to is.
142 
143   @param Desc            Pointer to the capsule block descriptors
144   @param NumDescriptors  Optional pointer to where to return the number of capsule data descriptors, whose Length is non-zero.
145   @param CapsuleSize     Optional pointer to where to return the capsule image size
146   @param CapsuleNumber   Optional pointer to where to return the number of capsule
147 
148   @retval EFI_NOT_FOUND   No descriptors containing data in the list
149   @retval EFI_SUCCESS     Return data is valid
150 
151 **/
152 EFI_STATUS
153 GetCapsuleInfo (
154   IN EFI_CAPSULE_BLOCK_DESCRIPTOR   *Desc,
155   IN OUT UINTN                      *NumDescriptors OPTIONAL,
156   IN OUT UINTN                      *CapsuleSize OPTIONAL,
157   IN OUT UINTN                      *CapsuleNumber OPTIONAL
158   );
159 
160 /**
161   Given a pointer to the capsule block list, info on the available system
162   memory, and the size of a buffer, find a free block of memory where a
163   buffer of the given size can be copied to safely.
164 
165   @param BlockList   Pointer to head of capsule block descriptors
166   @param MemBase     Pointer to the base of memory in which we want to find free space
167   @param MemSize     The size of the block of memory pointed to by MemBase
168   @param DataSize    How big a free block we want to find
169 
170   @return A pointer to a memory block of at least DataSize that lies somewhere
171           between MemBase and (MemBase + MemSize). The memory pointed to does not
172           contain any of the capsule block descriptors or capsule blocks pointed to
173           by the BlockList.
174 
175 **/
176 UINT8 *
FindFreeMem(EFI_CAPSULE_BLOCK_DESCRIPTOR * BlockList,UINT8 * MemBase,UINTN MemSize,UINTN DataSize)177 FindFreeMem (
178   EFI_CAPSULE_BLOCK_DESCRIPTOR      *BlockList,
179   UINT8                             *MemBase,
180   UINTN                             MemSize,
181   UINTN                             DataSize
182   )
183 {
184   UINTN                           Size;
185   EFI_CAPSULE_BLOCK_DESCRIPTOR    *CurrDesc;
186   EFI_CAPSULE_BLOCK_DESCRIPTOR    *TempDesc;
187   UINT8                           *MemEnd;
188   BOOLEAN                         Failed;
189 
190   //
191   // Need at least enough to copy the data to at the end of the buffer, so
192   // say the end is less the data size for easy comparisons here.
193   //
194   MemEnd    = MemBase + MemSize - DataSize;
195   CurrDesc  = BlockList;
196   //
197   // Go through all the descriptor blocks and see if any obstruct the range
198   //
199   while (CurrDesc != NULL) {
200     //
201     // Get the size of this block list and see if it's in the way
202     //
203     Failed    = FALSE;
204     TempDesc  = CurrDesc;
205     Size      = sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
206     while (TempDesc->Length != 0) {
207       Size += sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
208       TempDesc++;
209     }
210 
211     if (IsOverlapped (MemBase, DataSize, (UINT8 *) CurrDesc, Size)) {
212       //
213       // Set our new base to the end of this block list and start all over
214       //
215       MemBase   = (UINT8 *) CurrDesc + Size;
216       CurrDesc  = BlockList;
217       if (MemBase > MemEnd) {
218         return NULL;
219       }
220 
221       Failed = TRUE;
222     }
223     //
224     // Now go through all the blocks and make sure none are in the way
225     //
226     while ((CurrDesc->Length != 0) && (!Failed)) {
227       if (IsOverlapped (MemBase, DataSize, (UINT8 *) (UINTN) CurrDesc->Union.DataBlock, (UINTN) CurrDesc->Length)) {
228         //
229         // Set our new base to the end of this block and start all over
230         //
231         Failed    = TRUE;
232         MemBase   = (UINT8 *) ((UINTN) CurrDesc->Union.DataBlock) + CurrDesc->Length;
233         CurrDesc  = BlockList;
234         if (MemBase > MemEnd) {
235           return NULL;
236         }
237       }
238       CurrDesc++;
239     }
240     //
241     // Normal continuation -- jump to next block descriptor list
242     //
243     if (!Failed) {
244       CurrDesc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) CurrDesc->Union.ContinuationPointer;
245     }
246   }
247   return MemBase;
248 }
249 
250 /**
251   Check the integrity of the capsule descriptors.
252 
253   @param BlockList    Pointer to the capsule descriptors
254 
255   @retval NULL           BlockList is not valid.
256   @retval LastBlockDesc  Last one Block in BlockList
257 
258 **/
259 EFI_CAPSULE_BLOCK_DESCRIPTOR *
ValidateCapsuleIntegrity(IN EFI_CAPSULE_BLOCK_DESCRIPTOR * BlockList)260 ValidateCapsuleIntegrity (
261   IN EFI_CAPSULE_BLOCK_DESCRIPTOR    *BlockList
262   )
263 {
264   EFI_CAPSULE_HEADER             *CapsuleHeader;
265   UINT64                         CapsuleSize;
266   UINTN                          CapsuleCount;
267   EFI_CAPSULE_BLOCK_DESCRIPTOR   *Ptr;
268 
269   DEBUG ((EFI_D_INFO, "ValidateCapsuleIntegrity\n"));
270 
271   //
272   // Go through the list to look for inconsistencies. Check for:
273   //   * misaligned block descriptors.
274   //   * The first capsule header guid
275   //   * The first capsule header flag
276   //   * The first capsule header HeaderSize
277   //   * Length > MAX_ADDRESS
278   //   * ContinuationPointer > MAX_ADDRESS
279   //   * DataBlock + Length > MAX_ADDRESS
280   //
281   CapsuleSize  = 0;
282   CapsuleCount = 0;
283   Ptr = BlockList;
284 
285   DEBUG ((EFI_D_INFO, "Ptr - 0x%x\n", Ptr));
286   DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length));
287   DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n", Ptr->Union.ContinuationPointer));
288   while ((Ptr->Length != 0) || (Ptr->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
289     //
290     // Make sure the descriptor is aligned at UINT64 in memory
291     //
292     if ((UINTN) Ptr & (sizeof(UINT64) - 1)) {
293       DEBUG ((EFI_D_ERROR, "ERROR: BlockList address failed alignment check\n"));
294       return NULL;
295     }
296     //
297     // Sanity Check
298     //
299     if (Ptr->Length > MAX_ADDRESS) {
300       DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Length(0x%lx) > MAX_ADDRESS\n", Ptr->Length));
301       return NULL;
302     }
303 
304     if (Ptr->Length == 0) {
305       //
306       // Sanity Check
307       //
308       if (Ptr->Union.ContinuationPointer > MAX_ADDRESS) {
309         DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Union.ContinuationPointer(0x%lx) > MAX_ADDRESS\n", Ptr->Union.ContinuationPointer));
310         return NULL;
311       }
312       //
313       // Descriptor points to another list of block descriptors somewhere
314       // else.
315       //
316       Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) Ptr->Union.ContinuationPointer;
317       DEBUG ((EFI_D_INFO, "Ptr(C) - 0x%x\n", Ptr));
318       DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length));
319       DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n", Ptr->Union.ContinuationPointer));
320     } else {
321       //
322       // Sanity Check
323       //
324       if (Ptr->Union.DataBlock > (MAX_ADDRESS - (UINTN)Ptr->Length)) {
325         DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Union.DataBlock(0x%lx) > (MAX_ADDRESS - (UINTN)Ptr->Length(0x%lx))\n", Ptr->Union.DataBlock, Ptr->Length));
326         return NULL;
327       }
328 
329       //
330       //To enhance the reliability of check-up, the first capsule's header is checked here.
331       //More reliabilities check-up will do later.
332       //
333       if (CapsuleSize == 0) {
334         //
335         //Move to the first capsule to check its header.
336         //
337         CapsuleHeader = (EFI_CAPSULE_HEADER*)((UINTN)Ptr->Union.DataBlock);
338         //
339         // Sanity check
340         //
341         if (Ptr->Length < sizeof(EFI_CAPSULE_HEADER)) {
342           DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Length(0x%lx) < sizeof(EFI_CAPSULE_HEADER)\n", Ptr->Length));
343           return NULL;
344         }
345         //
346         // Make sure HeaderSize field is valid
347         //
348         if (CapsuleHeader->HeaderSize > CapsuleHeader->CapsuleImageSize) {
349           DEBUG ((EFI_D_ERROR, "ERROR: CapsuleHeader->HeaderSize(0x%x) > CapsuleHeader->CapsuleImageSize(0x%x)\n", CapsuleHeader->HeaderSize, CapsuleHeader->CapsuleImageSize));
350           return NULL;
351         }
352         if (IsCapsuleCorrupted (CapsuleHeader)) {
353           return NULL;
354         }
355         CapsuleCount ++;
356         CapsuleSize = CapsuleHeader->CapsuleImageSize;
357       }
358 
359       if (CapsuleSize >= Ptr->Length) {
360         CapsuleSize = CapsuleSize - Ptr->Length;
361       } else {
362         DEBUG ((EFI_D_ERROR, "ERROR: CapsuleSize(0x%lx) < Ptr->Length(0x%lx)\n", CapsuleSize, Ptr->Length));
363         //
364         // Sanity check
365         //
366         return NULL;
367       }
368 
369       //
370       // Move to next BLOCK descriptor
371       //
372       Ptr++;
373       DEBUG ((EFI_D_INFO, "Ptr(B) - 0x%x\n", Ptr));
374       DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length));
375       DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n", Ptr->Union.ContinuationPointer));
376     }
377   }
378 
379   if (CapsuleCount == 0) {
380     //
381     // No any capsule is found in BlockList
382     //
383     DEBUG ((EFI_D_ERROR, "ERROR: CapsuleCount(0x%x) == 0\n", CapsuleCount));
384     return NULL;
385   }
386 
387   if (CapsuleSize != 0) {
388     //
389     // Capsule data is incomplete.
390     //
391     DEBUG ((EFI_D_ERROR, "ERROR: CapsuleSize(0x%lx) != 0\n", CapsuleSize));
392     return NULL;
393   }
394 
395   return Ptr;
396 }
397 
398 /**
399   The capsule block descriptors may be fragmented and spread all over memory.
400   To simplify the coalescing of capsule blocks, first coalesce all the
401   capsule block descriptors low in memory.
402 
403   The descriptors passed in can be fragmented throughout memory. Here
404   they are relocated into memory to turn them into a contiguous (null
405   terminated) array.
406 
407   @param PeiServices    pointer to PEI services table
408   @param BlockList      pointer to the capsule block descriptors
409   @param NumDescriptors number of capsule data block descriptors, whose Length is non-zero.
410   @param MemBase        base of system memory in which we can work
411   @param MemSize        size of the system memory pointed to by MemBase
412 
413   @retval NULL    could not relocate the descriptors
414   @retval Pointer to the base of the successfully-relocated block descriptors.
415 
416 **/
417 EFI_CAPSULE_BLOCK_DESCRIPTOR  *
RelocateBlockDescriptors(IN EFI_PEI_SERVICES ** PeiServices,IN EFI_CAPSULE_BLOCK_DESCRIPTOR * BlockList,IN UINTN NumDescriptors,IN UINT8 * MemBase,IN UINTN MemSize)418 RelocateBlockDescriptors (
419   IN EFI_PEI_SERVICES                   **PeiServices,
420   IN EFI_CAPSULE_BLOCK_DESCRIPTOR       *BlockList,
421   IN UINTN                              NumDescriptors,
422   IN UINT8                              *MemBase,
423   IN UINTN                              MemSize
424   )
425 {
426   EFI_CAPSULE_BLOCK_DESCRIPTOR   *NewBlockList;
427   EFI_CAPSULE_BLOCK_DESCRIPTOR   *CurrBlockDescHead;
428   EFI_CAPSULE_BLOCK_DESCRIPTOR   *TempBlockDesc;
429   EFI_CAPSULE_BLOCK_DESCRIPTOR   *PrevBlockDescTail;
430   UINTN                          BufferSize;
431   UINT8                          *RelocBuffer;
432   UINTN                          BlockListSize;
433 
434   //
435   // Get the info on the blocks and descriptors. Since we're going to move
436   // the descriptors low in memory, adjust the base/size values accordingly here.
437   // NumDescriptors is the number of legit data descriptors, so add one for
438   // a terminator. (Already done by caller, no check is needed.)
439   //
440 
441   BufferSize    = NumDescriptors * sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
442   NewBlockList  = (EFI_CAPSULE_BLOCK_DESCRIPTOR *) MemBase;
443   if (MemSize < BufferSize) {
444     return NULL;
445   }
446 
447   MemSize -= BufferSize;
448   MemBase += BufferSize;
449   //
450   // Go through all the blocks and make sure none are in the way
451   //
452   TempBlockDesc = BlockList;
453   while (TempBlockDesc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) {
454     if (TempBlockDesc->Length == 0) {
455       //
456       // Next block of descriptors
457       //
458       TempBlockDesc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) TempBlockDesc->Union.ContinuationPointer;
459     } else {
460       //
461       // If the capsule data pointed to by this descriptor is in the way,
462       // move it.
463       //
464       if (IsOverlapped (
465             (UINT8 *) NewBlockList,
466             BufferSize,
467             (UINT8 *) (UINTN) TempBlockDesc->Union.DataBlock,
468             (UINTN) TempBlockDesc->Length
469             )) {
470         //
471         // Relocate the block
472         //
473         RelocBuffer = FindFreeMem (BlockList, MemBase, MemSize, (UINTN) TempBlockDesc->Length);
474         if (RelocBuffer == NULL) {
475           return NULL;
476         }
477 
478         CopyMem ((VOID *) RelocBuffer, (VOID *) (UINTN) TempBlockDesc->Union.DataBlock, (UINTN) TempBlockDesc->Length);
479         DEBUG ((EFI_D_INFO, "Capsule relocate descriptors from/to/size  0x%lX 0x%lX 0x%lX\n", TempBlockDesc->Union.DataBlock, (UINT64)(UINTN)RelocBuffer, TempBlockDesc->Length));
480         TempBlockDesc->Union.DataBlock = (EFI_PHYSICAL_ADDRESS) (UINTN) RelocBuffer;
481       }
482       TempBlockDesc++;
483     }
484   }
485   //
486   // Now go through all the block descriptors to make sure that they're not
487   // in the memory region we want to copy them to.
488   //
489   CurrBlockDescHead = BlockList;
490   PrevBlockDescTail = NULL;
491   while ((CurrBlockDescHead != NULL) && (CurrBlockDescHead->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
492     //
493     // Get the size of this list then see if it overlaps our low region
494     //
495     TempBlockDesc = CurrBlockDescHead;
496     BlockListSize = sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
497     while (TempBlockDesc->Length != 0) {
498       BlockListSize += sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
499       TempBlockDesc++;
500     }
501 
502     if (IsOverlapped (
503           (UINT8 *) NewBlockList,
504           BufferSize,
505           (UINT8 *) CurrBlockDescHead,
506           BlockListSize
507           )) {
508       //
509       // Overlaps, so move it out of the way
510       //
511       RelocBuffer = FindFreeMem (BlockList, MemBase, MemSize, BlockListSize);
512       if (RelocBuffer == NULL) {
513         return NULL;
514       }
515       CopyMem ((VOID *) RelocBuffer, (VOID *) CurrBlockDescHead, BlockListSize);
516       DEBUG ((EFI_D_INFO, "Capsule reloc descriptor block #2\n"));
517       //
518       // Point the previous block's next point to this copied version. If
519       // the tail pointer is null, then this is the first descriptor block.
520       //
521       if (PrevBlockDescTail == NULL) {
522         BlockList = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) RelocBuffer;
523       } else {
524         PrevBlockDescTail->Union.DataBlock = (EFI_PHYSICAL_ADDRESS) (UINTN) RelocBuffer;
525       }
526     }
527     //
528     // Save our new tail and jump to the next block list
529     //
530     PrevBlockDescTail = TempBlockDesc;
531     CurrBlockDescHead = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) TempBlockDesc->Union.ContinuationPointer;
532   }
533   //
534   // Cleared out low memory. Now copy the descriptors down there.
535   //
536   TempBlockDesc     = BlockList;
537   CurrBlockDescHead = NewBlockList;
538   while ((TempBlockDesc != NULL) && (TempBlockDesc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
539     if (TempBlockDesc->Length != 0) {
540       CurrBlockDescHead->Union.DataBlock = TempBlockDesc->Union.DataBlock;
541       CurrBlockDescHead->Length = TempBlockDesc->Length;
542       CurrBlockDescHead++;
543       TempBlockDesc++;
544     } else {
545       TempBlockDesc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) TempBlockDesc->Union.ContinuationPointer;
546     }
547   }
548   //
549   // Null terminate
550   //
551   CurrBlockDescHead->Union.ContinuationPointer   = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
552   CurrBlockDescHead->Length = 0;
553   return NewBlockList;
554 }
555 
556 /**
557   Determine if two buffers overlap in memory.
558 
559   @param Buff1   pointer to first buffer
560   @param Size1   size of Buff1
561   @param Buff2   pointer to second buffer
562   @param Size2   size of Buff2
563 
564   @retval TRUE    Buffers overlap in memory.
565   @retval FALSE   Buffer doesn't overlap.
566 
567 **/
568 BOOLEAN
IsOverlapped(UINT8 * Buff1,UINTN Size1,UINT8 * Buff2,UINTN Size2)569 IsOverlapped (
570   UINT8     *Buff1,
571   UINTN     Size1,
572   UINT8     *Buff2,
573   UINTN     Size2
574   )
575 {
576   //
577   // If buff1's end is less than the start of buff2, then it's ok.
578   // Also, if buff1's start is beyond buff2's end, then it's ok.
579   //
580   if (((Buff1 + Size1) <= Buff2) || (Buff1 >= (Buff2 + Size2))) {
581     return FALSE;
582   }
583 
584   return TRUE;
585 }
586 
587 /**
588   Given a pointer to a capsule block descriptor, traverse the list to figure
589   out how many legitimate descriptors there are, and how big the capsule it
590   refers to is.
591 
592   @param Desc            Pointer to the capsule block descriptors
593   @param NumDescriptors  Optional pointer to where to return the number of capsule data descriptors, whose Length is non-zero.
594   @param CapsuleSize     Optional pointer to where to return the capsule image size
595   @param CapsuleNumber   Optional pointer to where to return the number of capsule
596 
597   @retval EFI_NOT_FOUND   No descriptors containing data in the list
598   @retval EFI_SUCCESS     Return data is valid
599 
600 **/
601 EFI_STATUS
GetCapsuleInfo(IN EFI_CAPSULE_BLOCK_DESCRIPTOR * Desc,IN OUT UINTN * NumDescriptors OPTIONAL,IN OUT UINTN * CapsuleSize OPTIONAL,IN OUT UINTN * CapsuleNumber OPTIONAL)602 GetCapsuleInfo (
603   IN EFI_CAPSULE_BLOCK_DESCRIPTOR   *Desc,
604   IN OUT UINTN                      *NumDescriptors OPTIONAL,
605   IN OUT UINTN                      *CapsuleSize OPTIONAL,
606   IN OUT UINTN                      *CapsuleNumber OPTIONAL
607   )
608 {
609   UINTN                          Count;
610   UINTN                          Size;
611   UINTN                          Number;
612   UINTN                          ThisCapsuleImageSize;
613   EFI_CAPSULE_HEADER             *CapsuleHeader;
614 
615   DEBUG ((EFI_D_INFO, "GetCapsuleInfo enter\n"));
616 
617   ASSERT (Desc != NULL);
618 
619   Count = 0;
620   Size  = 0;
621   Number = 0;
622   ThisCapsuleImageSize = 0;
623 
624   while (Desc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) {
625     if (Desc->Length == 0) {
626       //
627       // Descriptor points to another list of block descriptors somewhere
628       //
629       Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) Desc->Union.ContinuationPointer;
630     } else {
631       //
632       // Sanity Check
633       // It is needed, because ValidateCapsuleIntegrity() only validate one individual capsule Size.
634       // While here we need check all capsules size.
635       //
636       if (Desc->Length >= (MAX_ADDRESS - Size)) {
637         DEBUG ((EFI_D_ERROR, "ERROR: Desc->Length(0x%lx) >= (MAX_ADDRESS - Size(0x%x))\n", Desc->Length, Size));
638         return EFI_OUT_OF_RESOURCES;
639       }
640       Size += (UINTN) Desc->Length;
641       Count++;
642 
643       //
644       // See if this is first capsule's header
645       //
646       if (ThisCapsuleImageSize == 0) {
647         CapsuleHeader = (EFI_CAPSULE_HEADER*)((UINTN)Desc->Union.DataBlock);
648         //
649         // This has been checked in ValidateCapsuleIntegrity()
650         //
651         Number ++;
652         ThisCapsuleImageSize = CapsuleHeader->CapsuleImageSize;
653       }
654 
655       //
656       // This has been checked in ValidateCapsuleIntegrity()
657       //
658       ASSERT (ThisCapsuleImageSize >= Desc->Length);
659       ThisCapsuleImageSize = (UINTN)(ThisCapsuleImageSize - Desc->Length);
660 
661       //
662       // Move to next
663       //
664       Desc++;
665     }
666   }
667   //
668   // If no descriptors, then fail
669   //
670   if (Count == 0) {
671     DEBUG ((EFI_D_ERROR, "ERROR: Count == 0\n"));
672     return EFI_NOT_FOUND;
673   }
674 
675   //
676   // checked in ValidateCapsuleIntegrity()
677   //
678   ASSERT (ThisCapsuleImageSize == 0);
679 
680   if (NumDescriptors != NULL) {
681     *NumDescriptors = Count;
682   }
683 
684   if (CapsuleSize != NULL) {
685     *CapsuleSize = Size;
686   }
687 
688   if (CapsuleNumber != NULL) {
689     *CapsuleNumber = Number;
690   }
691 
692   return EFI_SUCCESS;
693 }
694 
695 /**
696   Check every capsule header.
697 
698   @param CapsuleHeader   The pointer to EFI_CAPSULE_HEADER
699 
700   @retval FALSE  Capsule is OK
701   @retval TRUE   Capsule is corrupted
702 
703 **/
704 BOOLEAN
IsCapsuleCorrupted(IN EFI_CAPSULE_HEADER * CapsuleHeader)705 IsCapsuleCorrupted (
706   IN EFI_CAPSULE_HEADER       *CapsuleHeader
707   )
708 {
709   //
710   //A capsule to be updated across a system reset should contain CAPSULE_FLAGS_PERSIST_ACROSS_RESET.
711   //
712   if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) == 0) {
713     return TRUE;
714   }
715   //
716   //Make sure the flags combination is supported by the platform.
717   //
718   if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
719     return TRUE;
720   }
721   if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
722     return TRUE;
723   }
724 
725   return FALSE;
726 }
727 
728 /**
729   Try to verify the integrity of a capsule test pattern before the
730   capsule gets coalesced. This can be useful in narrowing down
731   where capsule data corruption occurs.
732 
733   The test pattern mode fills in memory with a counting UINT32 value.
734   If the capsule is not divided up in a multiple of 4-byte blocks, then
735   things get messy doing the check. Therefore there are some cases
736   here where we just give up and skip the pre-coalesce check.
737 
738   @param PeiServices  PEI services table
739   @param Desc         Pointer to capsule descriptors
740 **/
741 VOID
CapsuleTestPatternPreCoalesce(IN EFI_PEI_SERVICES ** PeiServices,IN EFI_CAPSULE_BLOCK_DESCRIPTOR * Desc)742 CapsuleTestPatternPreCoalesce (
743   IN EFI_PEI_SERVICES              **PeiServices,
744   IN EFI_CAPSULE_BLOCK_DESCRIPTOR  *Desc
745   )
746 {
747   UINT32  *TestPtr;
748   UINT32  TestCounter;
749   UINT32  TestSize;
750 
751   DEBUG ((EFI_D_INFO, "CapsuleTestPatternPreCoalesce\n"));
752 
753   //
754   // Find first data descriptor
755   //
756   while ((Desc->Length == 0) && (Desc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
757     Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) Desc->Union.ContinuationPointer;
758   }
759 
760   if (Desc->Union.ContinuationPointer == 0) {
761     return ;
762   }
763   //
764   // First one better be long enough to at least hold the test signature
765   //
766   if (Desc->Length < sizeof (UINT32)) {
767     DEBUG ((EFI_D_INFO, "Capsule test pattern pre-coalesce punted #1\n"));
768     return ;
769   }
770 
771   TestPtr = (UINT32 *) (UINTN) Desc->Union.DataBlock;
772   //
773   // 0x54534554 "TEST"
774   //
775   if (*TestPtr != 0x54534554) {
776     return ;
777   }
778 
779   TestCounter = 0;
780   TestSize    = (UINT32) Desc->Length - 2 * sizeof (UINT32);
781   //
782   // Skip over the signature and the size fields in the pattern data header
783   //
784   TestPtr += 2;
785   while (1) {
786     if ((TestSize & 0x03) != 0) {
787       DEBUG ((EFI_D_INFO, "Capsule test pattern pre-coalesce punted #2\n"));
788       return ;
789     }
790 
791     while (TestSize > 0) {
792       if (*TestPtr != TestCounter) {
793         DEBUG ((EFI_D_INFO, "Capsule test pattern pre-coalesce failed data corruption check\n"));
794         return ;
795       }
796 
797       TestSize -= sizeof (UINT32);
798       TestCounter++;
799       TestPtr++;
800     }
801     Desc++;
802     while ((Desc->Length == 0) && (Desc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
803       Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) Desc->Union.ContinuationPointer;
804     }
805 
806     if (Desc->Union.ContinuationPointer == (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) {
807       return ;
808     }
809     TestSize = (UINT32) Desc->Length;
810     TestPtr  = (UINT32 *) (UINTN) Desc->Union.DataBlock;
811   }
812 }
813 
814 /**
815   Checks for the presence of capsule descriptors.
816   Get capsule descriptors from variable CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
817 
818   @param BlockListBuffer            Pointer to the buffer of capsule descriptors variables
819   @param BlockDescriptorList        Pointer to the capsule descriptors list
820 
821   @retval EFI_SUCCESS               a valid capsule is present
822   @retval EFI_NOT_FOUND             if a valid capsule is not present
823 **/
824 EFI_STATUS
BuildCapsuleDescriptors(IN EFI_PHYSICAL_ADDRESS * BlockListBuffer,OUT EFI_CAPSULE_BLOCK_DESCRIPTOR ** BlockDescriptorList)825 BuildCapsuleDescriptors (
826   IN  EFI_PHYSICAL_ADDRESS            *BlockListBuffer,
827   OUT EFI_CAPSULE_BLOCK_DESCRIPTOR    **BlockDescriptorList
828   )
829 {
830   UINTN                            Index;
831   EFI_CAPSULE_BLOCK_DESCRIPTOR     *LastBlock;
832   EFI_CAPSULE_BLOCK_DESCRIPTOR     *TempBlock;
833   EFI_CAPSULE_BLOCK_DESCRIPTOR     *HeadBlock;
834 
835   DEBUG ((EFI_D_INFO, "BuildCapsuleDescriptors enter\n"));
836 
837   LastBlock         = NULL;
838   HeadBlock         = NULL;
839   TempBlock         = NULL;
840   Index             = 0;
841 
842   while (BlockListBuffer[Index] != 0) {
843     //
844     // Test integrity of descriptors.
845     //
846     if (BlockListBuffer[Index] < MAX_ADDRESS) {
847       TempBlock = ValidateCapsuleIntegrity ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index]);
848       if (TempBlock != NULL) {
849         if (LastBlock == NULL) {
850           LastBlock = TempBlock;
851 
852           //
853           // Return the base of the block descriptors
854           //
855           HeadBlock = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index];
856         } else {
857           //
858           // Combine the different BlockList into single BlockList.
859           //
860           LastBlock->Union.DataBlock = (EFI_PHYSICAL_ADDRESS)(UINTN)BlockListBuffer[Index];
861           LastBlock->Length          = 0;
862           LastBlock                  = TempBlock;
863         }
864       }
865     } else {
866       DEBUG ((EFI_D_ERROR, "ERROR: BlockListBuffer[Index](0x%lx) < MAX_ADDRESS\n", BlockListBuffer[Index]));
867     }
868     Index ++;
869   }
870 
871   if (HeadBlock != NULL) {
872     *BlockDescriptorList = HeadBlock;
873     return EFI_SUCCESS;
874   }
875   return EFI_NOT_FOUND;
876 }
877 
878 /**
879   The function to coalesce a fragmented capsule in memory.
880 
881   Memory Map for coalesced capsule:
882   MemBase +   ---->+---------------------------+<-----------+
883   MemSize          | ------------------------- |            |
884                    | |  Capsule [Num-1]      | |            |
885                    | ------------------------- |            |
886                    | |  ................     | |            |
887                    | ------------------------- |            |
888                    | |  Capsule [1]          | |            |
889                    | ------------------------- |            |
890                    | |  Capsule [0]          | |            |
891                    | ------------------------- |            |
892                    |    Capsule Image          |            |
893 CapsuleImageBase-->+---------------------------+
894                    | ------------------------- |            |
895                    | |  CapsuleOffset[Num-1] | |            |
896                    | ------------------------- |            |
897                    | |  ................     | |        CapsuleSize
898                    | ------------------------- |            |
899                    | |  CapsuleOffset[1]     | |            |
900                    | ------------------------- |            |
901                    | |  CapsuleOffset[0]     | |            |
902                    |---------------------------|            |
903                    | |  CapsuleNumber        | |            |
904                    | ------------------------- |            |
905                    | |  CapsuleAllImageSize  | |            |
906                    | ------------------------- |            |
907                    |    PrivateData            |            |
908      DestPtr  ---->+---------------------------+<-----------+
909                    |                           |            |
910                    |     FreeMem               |        FreeMemSize
911                    |                           |            |
912    FreeMemBase --->+---------------------------+<-----------+
913                    |    Terminator             |
914                    +---------------------------+
915                    |    BlockDescriptor n      |
916                    +---------------------------+
917                    |    .................      |
918                    +---------------------------+
919                    |    BlockDescriptor 1      |
920                    +---------------------------+
921                    |    BlockDescriptor 0      |
922                    +---------------------------+
923                    |    PrivateDataDesc 0      |
924       MemBase ---->+---------------------------+<----- BlockList
925 
926   Caution: This function may receive untrusted input.
927   The capsule data is external input, so this routine will do basic validation before
928   coalesce capsule data into memory.
929 
930   @param PeiServices        General purpose services available to every PEIM.
931   @param BlockListBuffer    Point to the buffer of Capsule Descriptor Variables.
932   @param MemoryBase         Pointer to the base of a block of memory that we can walk
933                             all over while trying to coalesce our buffers.
934                             On output, this variable will hold the base address of
935                             a coalesced capsule.
936   @param MemorySize         Size of the memory region pointed to by MemoryBase.
937                             On output, this variable will contain the size of the
938                             coalesced capsule.
939 
940   @retval EFI_NOT_FOUND     If we could not find the capsule descriptors.
941 
942   @retval EFI_BUFFER_TOO_SMALL
943                             If we could not coalesce the capsule in the memory
944                             region provided to us.
945 
946   @retval EFI_SUCCESS       Processed the capsule successfully.
947 **/
948 EFI_STATUS
949 EFIAPI
CapsuleDataCoalesce(IN EFI_PEI_SERVICES ** PeiServices,IN EFI_PHYSICAL_ADDRESS * BlockListBuffer,IN OUT VOID ** MemoryBase,IN OUT UINTN * MemorySize)950 CapsuleDataCoalesce (
951   IN EFI_PEI_SERVICES                **PeiServices,
952   IN EFI_PHYSICAL_ADDRESS            *BlockListBuffer,
953   IN OUT VOID                        **MemoryBase,
954   IN OUT UINTN                       *MemorySize
955   )
956 {
957   VOID                           *NewCapsuleBase;
958   VOID                           *CapsuleImageBase;
959   UINTN                          CapsuleIndex;
960   UINT8                          *FreeMemBase;
961   UINT8                          *DestPtr;
962   UINTN                          DestLength;
963   UINT8                          *RelocPtr;
964   UINTN                          CapsuleTimes;
965   UINT64                         SizeLeft;
966   UINT64                         CapsuleImageSize;
967   UINTN                          CapsuleSize;
968   UINTN                          CapsuleNumber;
969   UINTN                          DescriptorsSize;
970   UINTN                          FreeMemSize;
971   UINTN                          NumDescriptors;
972   BOOLEAN                        CapsuleBeginFlag;
973   EFI_STATUS                     Status;
974   EFI_CAPSULE_HEADER             *CapsuleHeader;
975   EFI_CAPSULE_PEIM_PRIVATE_DATA  PrivateData;
976   EFI_CAPSULE_PEIM_PRIVATE_DATA  *PrivateDataPtr;
977   EFI_CAPSULE_BLOCK_DESCRIPTOR   *BlockList;
978   EFI_CAPSULE_BLOCK_DESCRIPTOR   *CurrentBlockDesc;
979   EFI_CAPSULE_BLOCK_DESCRIPTOR   *TempBlockDesc;
980   EFI_CAPSULE_BLOCK_DESCRIPTOR   PrivateDataDesc[2];
981 
982   DEBUG ((EFI_D_INFO, "CapsuleDataCoalesce enter\n"));
983 
984   CapsuleIndex     = 0;
985   SizeLeft         = 0;
986   CapsuleTimes     = 0;
987   CapsuleImageSize = 0;
988   PrivateDataPtr   = NULL;
989   CapsuleHeader    = NULL;
990   CapsuleBeginFlag = TRUE;
991   CapsuleSize      = 0;
992   NumDescriptors   = 0;
993 
994   //
995   // Build capsule descriptors list
996   //
997   Status = BuildCapsuleDescriptors (BlockListBuffer, &BlockList);
998   if (EFI_ERROR (Status)) {
999     return Status;
1000   }
1001 
1002   DEBUG_CODE (
1003     CapsuleTestPatternPreCoalesce (PeiServices, BlockList);
1004   );
1005 
1006   //
1007   // Get the size of our descriptors and the capsule size. GetCapsuleInfo()
1008   // returns the number of descriptors that actually point to data, so add
1009   // one for a terminator. Do that below.
1010   //
1011   Status = GetCapsuleInfo (BlockList, &NumDescriptors, &CapsuleSize, &CapsuleNumber);
1012   if (EFI_ERROR (Status)) {
1013     return Status;
1014   }
1015   DEBUG ((EFI_D_INFO, "CapsuleSize - 0x%x\n", CapsuleSize));
1016   DEBUG ((EFI_D_INFO, "CapsuleNumber - 0x%x\n", CapsuleNumber));
1017   DEBUG ((EFI_D_INFO, "NumDescriptors - 0x%x\n", NumDescriptors));
1018   if ((CapsuleSize == 0) || (NumDescriptors == 0) || (CapsuleNumber == 0)) {
1019     return EFI_NOT_FOUND;
1020   }
1021 
1022   if (CapsuleNumber - 1 >= (MAX_ADDRESS - (sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA)  + sizeof(UINT64))) / sizeof(UINT64)) {
1023     DEBUG ((EFI_D_ERROR, "ERROR: CapsuleNumber - 0x%x\n", CapsuleNumber));
1024     return EFI_BUFFER_TOO_SMALL;
1025   }
1026 
1027   //
1028   // Initialize our local copy of private data. When we're done, we'll create a
1029   // descriptor for it as well so that it can be put into free memory without
1030   // trashing anything.
1031   //
1032   PrivateData.Signature           = EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE;
1033   PrivateData.CapsuleAllImageSize = (UINT64) CapsuleSize;
1034   PrivateData.CapsuleNumber       = (UINT64) CapsuleNumber;
1035   PrivateData.CapsuleOffset[0]    = 0;
1036   //
1037   // NOTE: Only data in sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) is valid, CapsuleOffset field is unitialized at this moment.
1038   // The code sets partial length here for Descriptor.Length check, but later it will use full length to reserve those PrivateData region.
1039   //
1040   PrivateDataDesc[0].Union.DataBlock  = (EFI_PHYSICAL_ADDRESS) (UINTN) &PrivateData;
1041   PrivateDataDesc[0].Length           = sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA);
1042   PrivateDataDesc[1].Union.DataBlock  = (EFI_PHYSICAL_ADDRESS) (UINTN) BlockList;
1043   PrivateDataDesc[1].Length           = 0;
1044   //
1045   // Add PrivateDataDesc[0] in beginning beginning, as it is new descriptor. PrivateDataDesc[1] is NOT needed.
1046   // In addition, one NULL terminator is added in the end. See RelocateBlockDescriptors().
1047   //
1048   NumDescriptors  += 2;
1049   //
1050   // Sandity check
1051   //
1052   if (CapsuleSize >= (MAX_ADDRESS - (sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64) + sizeof(UINT64)))) {
1053     DEBUG ((EFI_D_ERROR, "ERROR: CapsuleSize - 0x%x\n", CapsuleSize));
1054     return EFI_BUFFER_TOO_SMALL;
1055   }
1056   //
1057   // Need add sizeof(UINT64) for PrivateData alignment
1058   //
1059   CapsuleSize     += sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64) + sizeof(UINT64);
1060   BlockList        = PrivateDataDesc;
1061   //
1062   // Sandity check
1063   //
1064   if (NumDescriptors >= (MAX_ADDRESS / sizeof(EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
1065     DEBUG ((EFI_D_ERROR, "ERROR: NumDescriptors - 0x%x\n", NumDescriptors));
1066     return EFI_BUFFER_TOO_SMALL;
1067   }
1068   DescriptorsSize  = NumDescriptors * sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
1069   //
1070   // Sandity check
1071   //
1072   if (DescriptorsSize >= (MAX_ADDRESS - CapsuleSize)) {
1073     DEBUG ((EFI_D_ERROR, "ERROR: DescriptorsSize - 0x%lx, CapsuleSize - 0x%lx\n", (UINT64)DescriptorsSize, (UINT64)CapsuleSize));
1074     return EFI_BUFFER_TOO_SMALL;
1075   }
1076 
1077   //
1078   // Don't go below some min address. If the base is below it,
1079   // then move it up and adjust the size accordingly.
1080   //
1081   DEBUG ((EFI_D_INFO, "Capsule Memory range from 0x%8X to 0x%8X\n", (UINTN) *MemoryBase, (UINTN)*MemoryBase + *MemorySize));
1082   if ((UINTN)*MemoryBase < (UINTN) MIN_COALESCE_ADDR) {
1083     if (((UINTN)*MemoryBase + *MemorySize) < (UINTN) MIN_COALESCE_ADDR) {
1084       DEBUG ((EFI_D_ERROR, "ERROR: *MemoryBase + *MemorySize - 0x%x\n", (UINTN)*MemoryBase + *MemorySize));
1085       return EFI_BUFFER_TOO_SMALL;
1086     } else {
1087       *MemorySize = *MemorySize - ((UINTN) MIN_COALESCE_ADDR - (UINTN) *MemoryBase);
1088       *MemoryBase = (VOID *) (UINTN) MIN_COALESCE_ADDR;
1089     }
1090   }
1091 
1092   if (*MemorySize <= (CapsuleSize + DescriptorsSize)) {
1093     DEBUG ((EFI_D_ERROR, "ERROR: CapsuleSize + DescriptorsSize - 0x%x\n", CapsuleSize + DescriptorsSize));
1094     return EFI_BUFFER_TOO_SMALL;
1095   }
1096 
1097   FreeMemBase = *MemoryBase;
1098   FreeMemSize = *MemorySize;
1099   DEBUG ((EFI_D_INFO, "Capsule Free Memory from 0x%8X to 0x%8X\n", (UINTN) FreeMemBase, (UINTN) FreeMemBase + FreeMemSize));
1100 
1101   //
1102   // Relocate all the block descriptors to low memory to make further
1103   // processing easier.
1104   //
1105   BlockList = RelocateBlockDescriptors (PeiServices, BlockList, NumDescriptors, FreeMemBase, FreeMemSize);
1106   if (BlockList == NULL) {
1107     //
1108     // Not enough room to relocate the descriptors
1109     //
1110     return EFI_BUFFER_TOO_SMALL;
1111   }
1112 
1113   //
1114   // Take the top of memory for the capsule. UINT64 align up.
1115   //
1116   DestPtr         = FreeMemBase + FreeMemSize - CapsuleSize;
1117   DestPtr         = (UINT8 *) (((UINTN)DestPtr + sizeof (UINT64) - 1) & ~(sizeof (UINT64) - 1));
1118   FreeMemBase     = (UINT8 *) BlockList + DescriptorsSize;
1119   FreeMemSize     = (UINTN) DestPtr - (UINTN) FreeMemBase;
1120   NewCapsuleBase  = (VOID *) DestPtr;
1121   CapsuleImageBase = (UINT8 *)NewCapsuleBase + sizeof(EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64);
1122 
1123   PrivateDataPtr = (EFI_CAPSULE_PEIM_PRIVATE_DATA *) NewCapsuleBase;
1124 
1125   //
1126   // Move all the blocks to the top (high) of memory.
1127   // Relocate all the obstructing blocks. Note that the block descriptors
1128   // were coalesced when they were relocated, so we can just ++ the pointer.
1129   //
1130   CurrentBlockDesc = BlockList;
1131   while ((CurrentBlockDesc->Length != 0) || (CurrentBlockDesc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
1132     if (CapsuleTimes == 0) {
1133       //
1134       // The first entry is the block descriptor for EFI_CAPSULE_PEIM_PRIVATE_DATA.
1135       // CapsuleOffset field is uninitialized at this time. No need copy it, but need to reserve for future use.
1136       //
1137       ASSERT (CurrentBlockDesc->Union.DataBlock == (UINT64)(UINTN)&PrivateData);
1138       DestLength = sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64);
1139     } else {
1140       DestLength = (UINTN)CurrentBlockDesc->Length;
1141     }
1142     //
1143     // See if any of the remaining capsule blocks are in the way
1144     //
1145     TempBlockDesc = CurrentBlockDesc;
1146     while (TempBlockDesc->Length != 0) {
1147       //
1148       // Is this block in the way of where we want to copy the current descriptor to?
1149       //
1150       if (IsOverlapped (
1151             (UINT8 *) DestPtr,
1152             (UINTN) DestLength,
1153             (UINT8 *) (UINTN) TempBlockDesc->Union.DataBlock,
1154             (UINTN) TempBlockDesc->Length
1155             )) {
1156         //
1157         // Relocate the block
1158         //
1159         RelocPtr = FindFreeMem (BlockList, FreeMemBase, FreeMemSize, (UINTN) TempBlockDesc->Length);
1160         if (RelocPtr == NULL) {
1161           return EFI_BUFFER_TOO_SMALL;
1162         }
1163 
1164         CopyMem ((VOID *) RelocPtr, (VOID *) (UINTN) TempBlockDesc->Union.DataBlock, (UINTN) TempBlockDesc->Length);
1165         DEBUG ((EFI_D_INFO, "Capsule reloc data block from 0x%8X to 0x%8X with size 0x%8X\n",
1166                 (UINTN) TempBlockDesc->Union.DataBlock, (UINTN) RelocPtr, (UINTN) TempBlockDesc->Length));
1167 
1168         TempBlockDesc->Union.DataBlock = (EFI_PHYSICAL_ADDRESS) (UINTN) RelocPtr;
1169       }
1170       //
1171       // Next descriptor
1172       //
1173       TempBlockDesc++;
1174     }
1175     //
1176     // Ok, we made it through. Copy the block.
1177     // we just support greping one capsule from the lists of block descs list.
1178     //
1179     CapsuleTimes ++;
1180     //
1181     //Skip the first block descriptor that filled with EFI_CAPSULE_PEIM_PRIVATE_DATA
1182     //
1183     if (CapsuleTimes > 1) {
1184       //
1185       //For every capsule entry point, check its header to determine whether to relocate it.
1186       //If it is invalid, skip it and move on to the next capsule. If it is valid, relocate it.
1187       //
1188       if (CapsuleBeginFlag) {
1189         CapsuleBeginFlag  = FALSE;
1190         CapsuleHeader     = (EFI_CAPSULE_HEADER*)(UINTN)CurrentBlockDesc->Union.DataBlock;
1191         SizeLeft          = CapsuleHeader->CapsuleImageSize;
1192 
1193         //
1194         // No more check here is needed, because IsCapsuleCorrupted() already in ValidateCapsuleIntegrity()
1195         //
1196         ASSERT (CapsuleIndex < CapsuleNumber);
1197 
1198         //
1199         // Relocate this capsule
1200         //
1201         CapsuleImageSize += SizeLeft;
1202         //
1203         // Cache the begin offset of this capsule
1204         //
1205         ASSERT (PrivateDataPtr->Signature == EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE);
1206         ASSERT ((UINTN)DestPtr >= (UINTN)CapsuleImageBase);
1207         PrivateDataPtr->CapsuleOffset[CapsuleIndex++] = (UINT64)((UINTN)DestPtr - (UINTN)CapsuleImageBase);
1208       }
1209 
1210       //
1211       // Below ASSERT is checked in ValidateCapsuleIntegrity()
1212       //
1213       ASSERT (CurrentBlockDesc->Length <= SizeLeft);
1214 
1215       CopyMem ((VOID *) DestPtr, (VOID *) (UINTN) (CurrentBlockDesc->Union.DataBlock), (UINTN)CurrentBlockDesc->Length);
1216       DEBUG ((EFI_D_INFO, "Capsule coalesce block no.0x%lX from 0x%lX to 0x%lX with size 0x%lX\n",(UINT64)CapsuleTimes,
1217              CurrentBlockDesc->Union.DataBlock, (UINT64)(UINTN)DestPtr, CurrentBlockDesc->Length));
1218       DestPtr += CurrentBlockDesc->Length;
1219       SizeLeft -= CurrentBlockDesc->Length;
1220 
1221       if (SizeLeft == 0) {
1222         //
1223         //Here is the end of the current capsule image.
1224         //
1225         CapsuleBeginFlag = TRUE;
1226       }
1227     } else {
1228       //
1229       // The first entry is the block descriptor for EFI_CAPSULE_PEIM_PRIVATE_DATA.
1230       // CapsuleOffset field is uninitialized at this time. No need copy it, but need to reserve for future use.
1231       //
1232       ASSERT (CurrentBlockDesc->Length == sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA));
1233       ASSERT ((UINTN)DestPtr == (UINTN)NewCapsuleBase);
1234       CopyMem ((VOID *) DestPtr, (VOID *) (UINTN) CurrentBlockDesc->Union.DataBlock, (UINTN) CurrentBlockDesc->Length);
1235       DestPtr += sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64);
1236     }
1237     //
1238     //Walk through the block descriptor list.
1239     //
1240     CurrentBlockDesc++;
1241   }
1242   //
1243   // We return the base of memory we want reserved, and the size.
1244   // The memory peim should handle it appropriately from there.
1245   //
1246   *MemorySize = (UINTN) CapsuleSize;
1247   *MemoryBase = (VOID *) NewCapsuleBase;
1248 
1249   ASSERT (PrivateDataPtr->Signature == EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE);
1250   ASSERT (PrivateDataPtr->CapsuleAllImageSize == CapsuleImageSize);
1251   ASSERT (PrivateDataPtr->CapsuleNumber == CapsuleIndex);
1252 
1253   return EFI_SUCCESS;
1254 }
1255