Home | History | Annotate | Download | only in Common
      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 *
    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 *
    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  *
    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
    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
    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
    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
    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
    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
    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