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