15c08e1173703234cc2913757f237ee916087498aklu/** @file
25c08e1173703234cc2913757f237ee916087498aklu  Misc BDS library function
35c08e1173703234cc2913757f237ee916087498aklu
4ed6d22e0f29b24ac39c6b442eab4bce1e0de2739Hao WuCopyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
5180a5a35cb49699bd249dee19e41cee34c856a58hhtianThis program and the accompanying materials
65c08e1173703234cc2913757f237ee916087498akluare licensed and made available under the terms and conditions of the BSD License
75c08e1173703234cc2913757f237ee916087498akluwhich accompanies this distribution.  The full text of the license may be found at
85c08e1173703234cc2913757f237ee916087498akluhttp://opensource.org/licenses/bsd-license.php
95c08e1173703234cc2913757f237ee916087498aklu
105c08e1173703234cc2913757f237ee916087498akluTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
115c08e1173703234cc2913757f237ee916087498akluWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
125c08e1173703234cc2913757f237ee916087498aklu
135c08e1173703234cc2913757f237ee916087498aklu**/
145c08e1173703234cc2913757f237ee916087498aklu
155c08e1173703234cc2913757f237ee916087498aklu#include "InternalBdsLib.h"
165c08e1173703234cc2913757f237ee916087498aklu
175c08e1173703234cc2913757f237ee916087498aklu
185c08e1173703234cc2913757f237ee916087498aklu#define MAX_STRING_LEN        200
195c08e1173703234cc2913757f237ee916087498aklu
205c08e1173703234cc2913757f237ee916087498akluBOOLEAN   mFeaturerSwitch = TRUE;
215c08e1173703234cc2913757f237ee916087498akluBOOLEAN   mResetRequired  = FALSE;
225c08e1173703234cc2913757f237ee916087498aklu
235c08e1173703234cc2913757f237ee916087498akluextern UINT16 gPlatformBootTimeOutDefault;
245c08e1173703234cc2913757f237ee916087498aklu
255c08e1173703234cc2913757f237ee916087498aklu/**
265c08e1173703234cc2913757f237ee916087498aklu  The function will go through the driver option link list, load and start
275c08e1173703234cc2913757f237ee916087498aklu  every driver the driver option device path point to.
285c08e1173703234cc2913757f237ee916087498aklu
295c08e1173703234cc2913757f237ee916087498aklu  @param  BdsDriverLists        The header of the current driver option link list
305c08e1173703234cc2913757f237ee916087498aklu
315c08e1173703234cc2913757f237ee916087498aklu**/
325c08e1173703234cc2913757f237ee916087498akluVOID
335c08e1173703234cc2913757f237ee916087498akluEFIAPI
345c08e1173703234cc2913757f237ee916087498akluBdsLibLoadDrivers (
355c08e1173703234cc2913757f237ee916087498aklu  IN LIST_ENTRY                   *BdsDriverLists
365c08e1173703234cc2913757f237ee916087498aklu  )
375c08e1173703234cc2913757f237ee916087498aklu{
385c08e1173703234cc2913757f237ee916087498aklu  EFI_STATUS                Status;
395c08e1173703234cc2913757f237ee916087498aklu  LIST_ENTRY                *Link;
405c08e1173703234cc2913757f237ee916087498aklu  BDS_COMMON_OPTION         *Option;
415c08e1173703234cc2913757f237ee916087498aklu  EFI_HANDLE                ImageHandle;
425c08e1173703234cc2913757f237ee916087498aklu  EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
435c08e1173703234cc2913757f237ee916087498aklu  UINTN                     ExitDataSize;
445c08e1173703234cc2913757f237ee916087498aklu  CHAR16                    *ExitData;
455c08e1173703234cc2913757f237ee916087498aklu  BOOLEAN                   ReconnectAll;
465c08e1173703234cc2913757f237ee916087498aklu
475c08e1173703234cc2913757f237ee916087498aklu  ReconnectAll = FALSE;
485c08e1173703234cc2913757f237ee916087498aklu
495c08e1173703234cc2913757f237ee916087498aklu  //
505c08e1173703234cc2913757f237ee916087498aklu  // Process the driver option
515c08e1173703234cc2913757f237ee916087498aklu  //
525c08e1173703234cc2913757f237ee916087498aklu  for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link->ForwardLink) {
535c08e1173703234cc2913757f237ee916087498aklu    Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
545c08e1173703234cc2913757f237ee916087498aklu
555c08e1173703234cc2913757f237ee916087498aklu    //
565c08e1173703234cc2913757f237ee916087498aklu    // If a load option is not marked as LOAD_OPTION_ACTIVE,
575c08e1173703234cc2913757f237ee916087498aklu    // the boot manager will not automatically load the option.
585c08e1173703234cc2913757f237ee916087498aklu    //
595c08e1173703234cc2913757f237ee916087498aklu    if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE)) {
605c08e1173703234cc2913757f237ee916087498aklu      continue;
615c08e1173703234cc2913757f237ee916087498aklu    }
625c08e1173703234cc2913757f237ee916087498aklu
635c08e1173703234cc2913757f237ee916087498aklu    //
645c08e1173703234cc2913757f237ee916087498aklu    // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
655c08e1173703234cc2913757f237ee916087498aklu    // then all of the EFI drivers in the system will be disconnected and
665c08e1173703234cc2913757f237ee916087498aklu    // reconnected after the last driver load option is processed.
675c08e1173703234cc2913757f237ee916087498aklu    //
685c08e1173703234cc2913757f237ee916087498aklu    if (IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_FORCE_RECONNECT)) {
695c08e1173703234cc2913757f237ee916087498aklu      ReconnectAll = TRUE;
705c08e1173703234cc2913757f237ee916087498aklu    }
715c08e1173703234cc2913757f237ee916087498aklu
725c08e1173703234cc2913757f237ee916087498aklu    //
735c08e1173703234cc2913757f237ee916087498aklu    // Make sure the driver path is connected.
745c08e1173703234cc2913757f237ee916087498aklu    //
755c08e1173703234cc2913757f237ee916087498aklu    BdsLibConnectDevicePath (Option->DevicePath);
765c08e1173703234cc2913757f237ee916087498aklu
775c08e1173703234cc2913757f237ee916087498aklu    //
785c08e1173703234cc2913757f237ee916087498aklu    // Load and start the image that Driver#### describes
795c08e1173703234cc2913757f237ee916087498aklu    //
805c08e1173703234cc2913757f237ee916087498aklu    Status = gBS->LoadImage (
815c08e1173703234cc2913757f237ee916087498aklu                    FALSE,
82fefefa4cb15eed75dbe3d4867768893bf6d96a30niruiyu                    gImageHandle,
835c08e1173703234cc2913757f237ee916087498aklu                    Option->DevicePath,
845c08e1173703234cc2913757f237ee916087498aklu                    NULL,
855c08e1173703234cc2913757f237ee916087498aklu                    0,
865c08e1173703234cc2913757f237ee916087498aklu                    &ImageHandle
875c08e1173703234cc2913757f237ee916087498aklu                    );
885c08e1173703234cc2913757f237ee916087498aklu
895c08e1173703234cc2913757f237ee916087498aklu    if (!EFI_ERROR (Status)) {
905c08e1173703234cc2913757f237ee916087498aklu      gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);
915c08e1173703234cc2913757f237ee916087498aklu
925c08e1173703234cc2913757f237ee916087498aklu      //
935c08e1173703234cc2913757f237ee916087498aklu      // Verify whether this image is a driver, if not,
945c08e1173703234cc2913757f237ee916087498aklu      // exit it and continue to parse next load option
955c08e1173703234cc2913757f237ee916087498aklu      //
965c08e1173703234cc2913757f237ee916087498aklu      if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {
975c08e1173703234cc2913757f237ee916087498aklu        gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);
985c08e1173703234cc2913757f237ee916087498aklu        continue;
995c08e1173703234cc2913757f237ee916087498aklu      }
1005c08e1173703234cc2913757f237ee916087498aklu
1015c08e1173703234cc2913757f237ee916087498aklu      if (Option->LoadOptionsSize != 0) {
1025c08e1173703234cc2913757f237ee916087498aklu        ImageInfo->LoadOptionsSize  = Option->LoadOptionsSize;
1035c08e1173703234cc2913757f237ee916087498aklu        ImageInfo->LoadOptions      = Option->LoadOptions;
1045c08e1173703234cc2913757f237ee916087498aklu      }
1055c08e1173703234cc2913757f237ee916087498aklu      //
1065c08e1173703234cc2913757f237ee916087498aklu      // Before calling the image, enable the Watchdog Timer for
1075c08e1173703234cc2913757f237ee916087498aklu      // the 5 Minute period
1085c08e1173703234cc2913757f237ee916087498aklu      //
1095c08e1173703234cc2913757f237ee916087498aklu      gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
1105c08e1173703234cc2913757f237ee916087498aklu
1115c08e1173703234cc2913757f237ee916087498aklu      Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
1125c08e1173703234cc2913757f237ee916087498aklu      DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Driver Return Status = %r\n", Status));
1135c08e1173703234cc2913757f237ee916087498aklu
1145c08e1173703234cc2913757f237ee916087498aklu      //
1155c08e1173703234cc2913757f237ee916087498aklu      // Clear the Watchdog Timer after the image returns
1165c08e1173703234cc2913757f237ee916087498aklu      //
1175c08e1173703234cc2913757f237ee916087498aklu      gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
1185c08e1173703234cc2913757f237ee916087498aklu    }
1195c08e1173703234cc2913757f237ee916087498aklu  }
1205c08e1173703234cc2913757f237ee916087498aklu
1215c08e1173703234cc2913757f237ee916087498aklu  //
1225c08e1173703234cc2913757f237ee916087498aklu  // Process the LOAD_OPTION_FORCE_RECONNECT driver option
1235c08e1173703234cc2913757f237ee916087498aklu  //
1245c08e1173703234cc2913757f237ee916087498aklu  if (ReconnectAll) {
1255c08e1173703234cc2913757f237ee916087498aklu    BdsLibDisconnectAllEfi ();
1265c08e1173703234cc2913757f237ee916087498aklu    BdsLibConnectAll ();
1275c08e1173703234cc2913757f237ee916087498aklu  }
1285c08e1173703234cc2913757f237ee916087498aklu
1295c08e1173703234cc2913757f237ee916087498aklu}
1305c08e1173703234cc2913757f237ee916087498aklu
1315c08e1173703234cc2913757f237ee916087498aklu/**
1325c08e1173703234cc2913757f237ee916087498aklu  Get the Option Number that does not used.
1335c08e1173703234cc2913757f237ee916087498aklu  Try to locate the specific option variable one by one utile find a free number.
1345c08e1173703234cc2913757f237ee916087498aklu
1355c08e1173703234cc2913757f237ee916087498aklu  @param  VariableName          Indicate if the boot#### or driver#### option
1365c08e1173703234cc2913757f237ee916087498aklu
1375c08e1173703234cc2913757f237ee916087498aklu  @return The Minimal Free Option Number
1385c08e1173703234cc2913757f237ee916087498aklu
1395c08e1173703234cc2913757f237ee916087498aklu**/
1405c08e1173703234cc2913757f237ee916087498akluUINT16
1415c08e1173703234cc2913757f237ee916087498akluBdsLibGetFreeOptionNumber (
1425c08e1173703234cc2913757f237ee916087498aklu  IN  CHAR16    *VariableName
1435c08e1173703234cc2913757f237ee916087498aklu  )
1445c08e1173703234cc2913757f237ee916087498aklu{
1455c08e1173703234cc2913757f237ee916087498aklu  UINTN         Index;
1465c08e1173703234cc2913757f237ee916087498aklu  CHAR16        StrTemp[10];
1475c08e1173703234cc2913757f237ee916087498aklu  UINT16        *OptionBuffer;
1485c08e1173703234cc2913757f237ee916087498aklu  UINTN         OptionSize;
1495c08e1173703234cc2913757f237ee916087498aklu
1505c08e1173703234cc2913757f237ee916087498aklu  //
1515c08e1173703234cc2913757f237ee916087498aklu  // Try to find the minimum free number from 0, 1, 2, 3....
1525c08e1173703234cc2913757f237ee916087498aklu  //
1535c08e1173703234cc2913757f237ee916087498aklu  Index = 0;
1545c08e1173703234cc2913757f237ee916087498aklu  do {
1555c08e1173703234cc2913757f237ee916087498aklu    if (*VariableName == 'B') {
1565c08e1173703234cc2913757f237ee916087498aklu      UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index);
1575c08e1173703234cc2913757f237ee916087498aklu    } else {
1585c08e1173703234cc2913757f237ee916087498aklu      UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Driver%04x", Index);
1595c08e1173703234cc2913757f237ee916087498aklu    }
1605c08e1173703234cc2913757f237ee916087498aklu    //
1615c08e1173703234cc2913757f237ee916087498aklu    // try if the option number is used
1625c08e1173703234cc2913757f237ee916087498aklu    //
1635c08e1173703234cc2913757f237ee916087498aklu    OptionBuffer = BdsLibGetVariableAndSize (
1645c08e1173703234cc2913757f237ee916087498aklu                     StrTemp,
1655c08e1173703234cc2913757f237ee916087498aklu                     &gEfiGlobalVariableGuid,
1665c08e1173703234cc2913757f237ee916087498aklu                     &OptionSize
1675c08e1173703234cc2913757f237ee916087498aklu                     );
1685c08e1173703234cc2913757f237ee916087498aklu    if (OptionBuffer == NULL) {
1695c08e1173703234cc2913757f237ee916087498aklu      break;
1705c08e1173703234cc2913757f237ee916087498aklu    }
17146737a64d0e8f5dcc525973d3313f95920155265Chen Fan    FreePool(OptionBuffer);
1725c08e1173703234cc2913757f237ee916087498aklu    Index++;
1735c08e1173703234cc2913757f237ee916087498aklu  } while (TRUE);
1745c08e1173703234cc2913757f237ee916087498aklu
1755c08e1173703234cc2913757f237ee916087498aklu  return ((UINT16) Index);
1765c08e1173703234cc2913757f237ee916087498aklu}
1775c08e1173703234cc2913757f237ee916087498aklu
1785c08e1173703234cc2913757f237ee916087498aklu
1795c08e1173703234cc2913757f237ee916087498aklu/**
1805c08e1173703234cc2913757f237ee916087498aklu  This function will register the new boot#### or driver#### option base on
1815c08e1173703234cc2913757f237ee916087498aklu  the VariableName. The new registered boot#### or driver#### will be linked
1825c08e1173703234cc2913757f237ee916087498aklu  to BdsOptionList and also update to the VariableName. After the boot#### or
1835c08e1173703234cc2913757f237ee916087498aklu  driver#### updated, the BootOrder or DriverOrder will also be updated.
1845c08e1173703234cc2913757f237ee916087498aklu
1855c08e1173703234cc2913757f237ee916087498aklu  @param  BdsOptionList         The header of the boot#### or driver#### link list
1865c08e1173703234cc2913757f237ee916087498aklu  @param  DevicePath            The device path which the boot#### or driver####
1875c08e1173703234cc2913757f237ee916087498aklu                                option present
1885c08e1173703234cc2913757f237ee916087498aklu  @param  String                The description of the boot#### or driver####
1895c08e1173703234cc2913757f237ee916087498aklu  @param  VariableName          Indicate if the boot#### or driver#### option
1905c08e1173703234cc2913757f237ee916087498aklu
1915c08e1173703234cc2913757f237ee916087498aklu  @retval EFI_SUCCESS           The boot#### or driver#### have been success
1925c08e1173703234cc2913757f237ee916087498aklu                                registered
1935c08e1173703234cc2913757f237ee916087498aklu  @retval EFI_STATUS            Return the status of gRT->SetVariable ().
1945c08e1173703234cc2913757f237ee916087498aklu
1955c08e1173703234cc2913757f237ee916087498aklu**/
1965c08e1173703234cc2913757f237ee916087498akluEFI_STATUS
1975c08e1173703234cc2913757f237ee916087498akluEFIAPI
1985c08e1173703234cc2913757f237ee916087498akluBdsLibRegisterNewOption (
1995c08e1173703234cc2913757f237ee916087498aklu  IN  LIST_ENTRY                     *BdsOptionList,
2005c08e1173703234cc2913757f237ee916087498aklu  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
2015c08e1173703234cc2913757f237ee916087498aklu  IN  CHAR16                         *String,
2025c08e1173703234cc2913757f237ee916087498aklu  IN  CHAR16                         *VariableName
2035c08e1173703234cc2913757f237ee916087498aklu  )
2045c08e1173703234cc2913757f237ee916087498aklu{
2055c08e1173703234cc2913757f237ee916087498aklu  EFI_STATUS                Status;
2065c08e1173703234cc2913757f237ee916087498aklu  UINTN                     Index;
2075c08e1173703234cc2913757f237ee916087498aklu  UINT16                    RegisterOptionNumber;
2085c08e1173703234cc2913757f237ee916087498aklu  UINT16                    *TempOptionPtr;
2095c08e1173703234cc2913757f237ee916087498aklu  UINTN                     TempOptionSize;
2105c08e1173703234cc2913757f237ee916087498aklu  UINT16                    *OptionOrderPtr;
2115c08e1173703234cc2913757f237ee916087498aklu  VOID                      *OptionPtr;
2125c08e1173703234cc2913757f237ee916087498aklu  UINTN                     OptionSize;
2135c08e1173703234cc2913757f237ee916087498aklu  UINT8                     *TempPtr;
2145c08e1173703234cc2913757f237ee916087498aklu  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;
2155c08e1173703234cc2913757f237ee916087498aklu  CHAR16                    *Description;
2165c08e1173703234cc2913757f237ee916087498aklu  CHAR16                    OptionName[10];
2175c08e1173703234cc2913757f237ee916087498aklu  BOOLEAN                   UpdateDescription;
2185c08e1173703234cc2913757f237ee916087498aklu  UINT16                    BootOrderEntry;
2195c08e1173703234cc2913757f237ee916087498aklu  UINTN                     OrderItemNum;
2205c08e1173703234cc2913757f237ee916087498aklu
221c4571f04794154d405a69b79babfd74bcf9fc63aRuiyu Ni  if (DevicePath == NULL) {
222c4571f04794154d405a69b79babfd74bcf9fc63aRuiyu Ni    return EFI_INVALID_PARAMETER;
223c4571f04794154d405a69b79babfd74bcf9fc63aRuiyu Ni  }
2245c08e1173703234cc2913757f237ee916087498aklu
2255c08e1173703234cc2913757f237ee916087498aklu  OptionPtr             = NULL;
2265c08e1173703234cc2913757f237ee916087498aklu  OptionSize            = 0;
2275c08e1173703234cc2913757f237ee916087498aklu  TempPtr               = NULL;
2285c08e1173703234cc2913757f237ee916087498aklu  OptionDevicePath      = NULL;
2295c08e1173703234cc2913757f237ee916087498aklu  Description           = NULL;
2305c08e1173703234cc2913757f237ee916087498aklu  OptionOrderPtr        = NULL;
2315c08e1173703234cc2913757f237ee916087498aklu  UpdateDescription     = FALSE;
2325c08e1173703234cc2913757f237ee916087498aklu  Status                = EFI_SUCCESS;
2335c08e1173703234cc2913757f237ee916087498aklu  ZeroMem (OptionName, sizeof (OptionName));
2345c08e1173703234cc2913757f237ee916087498aklu
2355c08e1173703234cc2913757f237ee916087498aklu  TempOptionSize = 0;
2365c08e1173703234cc2913757f237ee916087498aklu  TempOptionPtr = BdsLibGetVariableAndSize (
2375c08e1173703234cc2913757f237ee916087498aklu                    VariableName,
2385c08e1173703234cc2913757f237ee916087498aklu                    &gEfiGlobalVariableGuid,
2395c08e1173703234cc2913757f237ee916087498aklu                    &TempOptionSize
2405c08e1173703234cc2913757f237ee916087498aklu                    );
2415c08e1173703234cc2913757f237ee916087498aklu  //
2425c08e1173703234cc2913757f237ee916087498aklu  // Compare with current option variable if the previous option is set in global variable.
2435c08e1173703234cc2913757f237ee916087498aklu  //
2445c08e1173703234cc2913757f237ee916087498aklu  for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) {
2455c08e1173703234cc2913757f237ee916087498aklu    //
2465c08e1173703234cc2913757f237ee916087498aklu    // TempOptionPtr must not be NULL if we have non-zero TempOptionSize.
2475c08e1173703234cc2913757f237ee916087498aklu    //
2485c08e1173703234cc2913757f237ee916087498aklu    ASSERT (TempOptionPtr != NULL);
2495c08e1173703234cc2913757f237ee916087498aklu
2505c08e1173703234cc2913757f237ee916087498aklu    if (*VariableName == 'B') {
2515c08e1173703234cc2913757f237ee916087498aklu      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", TempOptionPtr[Index]);
2525c08e1173703234cc2913757f237ee916087498aklu    } else {
2535c08e1173703234cc2913757f237ee916087498aklu      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", TempOptionPtr[Index]);
2545c08e1173703234cc2913757f237ee916087498aklu    }
2555c08e1173703234cc2913757f237ee916087498aklu
2565c08e1173703234cc2913757f237ee916087498aklu    OptionPtr = BdsLibGetVariableAndSize (
2575c08e1173703234cc2913757f237ee916087498aklu                  OptionName,
2585c08e1173703234cc2913757f237ee916087498aklu                  &gEfiGlobalVariableGuid,
2595c08e1173703234cc2913757f237ee916087498aklu                  &OptionSize
2605c08e1173703234cc2913757f237ee916087498aklu                  );
2615c08e1173703234cc2913757f237ee916087498aklu    if (OptionPtr == NULL) {
2625c08e1173703234cc2913757f237ee916087498aklu      continue;
2635c08e1173703234cc2913757f237ee916087498aklu    }
2648c08a567c64814f36f7261ca5652ef0350ca660eydong
2658c08a567c64814f36f7261ca5652ef0350ca660eydong    //
2668c08a567c64814f36f7261ca5652ef0350ca660eydong    // Validate the variable.
2678c08a567c64814f36f7261ca5652ef0350ca660eydong    //
2688c08a567c64814f36f7261ca5652ef0350ca660eydong    if (!ValidateOption(OptionPtr, OptionSize)) {
26946737a64d0e8f5dcc525973d3313f95920155265Chen Fan      FreePool(OptionPtr);
2708c08a567c64814f36f7261ca5652ef0350ca660eydong      continue;
2718c08a567c64814f36f7261ca5652ef0350ca660eydong    }
2728c08a567c64814f36f7261ca5652ef0350ca660eydong
2735c08e1173703234cc2913757f237ee916087498aklu    TempPtr         =   OptionPtr;
2745c08e1173703234cc2913757f237ee916087498aklu    TempPtr         +=  sizeof (UINT32) + sizeof (UINT16);
2755c08e1173703234cc2913757f237ee916087498aklu    Description     =   (CHAR16 *) TempPtr;
2765c08e1173703234cc2913757f237ee916087498aklu    TempPtr         +=  StrSize ((CHAR16 *) TempPtr);
2775c08e1173703234cc2913757f237ee916087498aklu    OptionDevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
2785c08e1173703234cc2913757f237ee916087498aklu
2795c08e1173703234cc2913757f237ee916087498aklu    //
2805c08e1173703234cc2913757f237ee916087498aklu    // Notes: the description may will change base on the GetStringToken
2815c08e1173703234cc2913757f237ee916087498aklu    //
2825c08e1173703234cc2913757f237ee916087498aklu    if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize (OptionDevicePath)) == 0) {
2835c08e1173703234cc2913757f237ee916087498aklu      if (CompareMem (Description, String, StrSize (Description)) == 0) {
2845c08e1173703234cc2913757f237ee916087498aklu        //
2855c08e1173703234cc2913757f237ee916087498aklu        // Got the option, so just return
2865c08e1173703234cc2913757f237ee916087498aklu        //
2875c08e1173703234cc2913757f237ee916087498aklu        FreePool (OptionPtr);
2885c08e1173703234cc2913757f237ee916087498aklu        FreePool (TempOptionPtr);
2895c08e1173703234cc2913757f237ee916087498aklu        return EFI_SUCCESS;
2905c08e1173703234cc2913757f237ee916087498aklu      } else {
2915c08e1173703234cc2913757f237ee916087498aklu        //
2925c08e1173703234cc2913757f237ee916087498aklu        // Option description changed, need update.
2935c08e1173703234cc2913757f237ee916087498aklu        //
2945c08e1173703234cc2913757f237ee916087498aklu        UpdateDescription = TRUE;
2955c08e1173703234cc2913757f237ee916087498aklu        FreePool (OptionPtr);
2965c08e1173703234cc2913757f237ee916087498aklu        break;
2975c08e1173703234cc2913757f237ee916087498aklu      }
2985c08e1173703234cc2913757f237ee916087498aklu    }
2995c08e1173703234cc2913757f237ee916087498aklu
3005c08e1173703234cc2913757f237ee916087498aklu    FreePool (OptionPtr);
3015c08e1173703234cc2913757f237ee916087498aklu  }
3025c08e1173703234cc2913757f237ee916087498aklu
3035c08e1173703234cc2913757f237ee916087498aklu  OptionSize          = sizeof (UINT32) + sizeof (UINT16) + StrSize (String);
3045c08e1173703234cc2913757f237ee916087498aklu  OptionSize          += GetDevicePathSize (DevicePath);
3055c08e1173703234cc2913757f237ee916087498aklu  OptionPtr           = AllocateZeroPool (OptionSize);
3065c08e1173703234cc2913757f237ee916087498aklu  ASSERT (OptionPtr != NULL);
3075c08e1173703234cc2913757f237ee916087498aklu
3085c08e1173703234cc2913757f237ee916087498aklu  TempPtr             = OptionPtr;
3095c08e1173703234cc2913757f237ee916087498aklu  *(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE;
3105c08e1173703234cc2913757f237ee916087498aklu  TempPtr             += sizeof (UINT32);
3115c08e1173703234cc2913757f237ee916087498aklu  *(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath);
3125c08e1173703234cc2913757f237ee916087498aklu  TempPtr             += sizeof (UINT16);
3135c08e1173703234cc2913757f237ee916087498aklu  CopyMem (TempPtr, String, StrSize (String));
3145c08e1173703234cc2913757f237ee916087498aklu  TempPtr             += StrSize (String);
3155c08e1173703234cc2913757f237ee916087498aklu  CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath));
3165c08e1173703234cc2913757f237ee916087498aklu
3175c08e1173703234cc2913757f237ee916087498aklu  if (UpdateDescription) {
3185c08e1173703234cc2913757f237ee916087498aklu    //
3195c08e1173703234cc2913757f237ee916087498aklu    // The number in option#### to be updated.
3205c08e1173703234cc2913757f237ee916087498aklu    // In this case, we must have non-NULL TempOptionPtr.
3215c08e1173703234cc2913757f237ee916087498aklu    //
3225c08e1173703234cc2913757f237ee916087498aklu    ASSERT (TempOptionPtr != NULL);
3235c08e1173703234cc2913757f237ee916087498aklu    RegisterOptionNumber = TempOptionPtr[Index];
3245c08e1173703234cc2913757f237ee916087498aklu  } else {
3255c08e1173703234cc2913757f237ee916087498aklu    //
3265c08e1173703234cc2913757f237ee916087498aklu    // The new option#### number
3275c08e1173703234cc2913757f237ee916087498aklu    //
3285c08e1173703234cc2913757f237ee916087498aklu    RegisterOptionNumber = BdsLibGetFreeOptionNumber(VariableName);
3295c08e1173703234cc2913757f237ee916087498aklu  }
3305c08e1173703234cc2913757f237ee916087498aklu
3315c08e1173703234cc2913757f237ee916087498aklu  if (*VariableName == 'B') {
3325c08e1173703234cc2913757f237ee916087498aklu    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", RegisterOptionNumber);
3335c08e1173703234cc2913757f237ee916087498aklu  } else {
3345c08e1173703234cc2913757f237ee916087498aklu    UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", RegisterOptionNumber);
3355c08e1173703234cc2913757f237ee916087498aklu  }
3365c08e1173703234cc2913757f237ee916087498aklu
3375c08e1173703234cc2913757f237ee916087498aklu  Status = gRT->SetVariable (
3385c08e1173703234cc2913757f237ee916087498aklu                  OptionName,
3395c08e1173703234cc2913757f237ee916087498aklu                  &gEfiGlobalVariableGuid,
3405c08e1173703234cc2913757f237ee916087498aklu                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
3415c08e1173703234cc2913757f237ee916087498aklu                  OptionSize,
3425c08e1173703234cc2913757f237ee916087498aklu                  OptionPtr
3435c08e1173703234cc2913757f237ee916087498aklu                  );
3445c08e1173703234cc2913757f237ee916087498aklu  //
3455c08e1173703234cc2913757f237ee916087498aklu  // Return if only need to update a changed description or fail to set option.
3465c08e1173703234cc2913757f237ee916087498aklu  //
3475c08e1173703234cc2913757f237ee916087498aklu  if (EFI_ERROR (Status) || UpdateDescription) {
3485c08e1173703234cc2913757f237ee916087498aklu    FreePool (OptionPtr);
3495c08e1173703234cc2913757f237ee916087498aklu    if (TempOptionPtr != NULL) {
3505c08e1173703234cc2913757f237ee916087498aklu      FreePool (TempOptionPtr);
3515c08e1173703234cc2913757f237ee916087498aklu    }
3525c08e1173703234cc2913757f237ee916087498aklu    return Status;
3535c08e1173703234cc2913757f237ee916087498aklu  }
3545c08e1173703234cc2913757f237ee916087498aklu
3555c08e1173703234cc2913757f237ee916087498aklu  FreePool (OptionPtr);
3565c08e1173703234cc2913757f237ee916087498aklu
3575c08e1173703234cc2913757f237ee916087498aklu  //
3585c08e1173703234cc2913757f237ee916087498aklu  // Update the option order variable
3595c08e1173703234cc2913757f237ee916087498aklu  //
3605c08e1173703234cc2913757f237ee916087498aklu
3615c08e1173703234cc2913757f237ee916087498aklu  //
3625c08e1173703234cc2913757f237ee916087498aklu  // If no option order
3635c08e1173703234cc2913757f237ee916087498aklu  //
3645c08e1173703234cc2913757f237ee916087498aklu  if (TempOptionSize == 0) {
3655c08e1173703234cc2913757f237ee916087498aklu    BootOrderEntry = 0;
3665c08e1173703234cc2913757f237ee916087498aklu    Status = gRT->SetVariable (
3675c08e1173703234cc2913757f237ee916087498aklu                    VariableName,
3685c08e1173703234cc2913757f237ee916087498aklu                    &gEfiGlobalVariableGuid,
3695c08e1173703234cc2913757f237ee916087498aklu                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
3705c08e1173703234cc2913757f237ee916087498aklu                    sizeof (UINT16),
3715c08e1173703234cc2913757f237ee916087498aklu                    &BootOrderEntry
3725c08e1173703234cc2913757f237ee916087498aklu                    );
3735c08e1173703234cc2913757f237ee916087498aklu    if (TempOptionPtr != NULL) {
3745c08e1173703234cc2913757f237ee916087498aklu      FreePool (TempOptionPtr);
3755c08e1173703234cc2913757f237ee916087498aklu    }
3765c08e1173703234cc2913757f237ee916087498aklu    return Status;
3775c08e1173703234cc2913757f237ee916087498aklu  }
3785c08e1173703234cc2913757f237ee916087498aklu
3795c08e1173703234cc2913757f237ee916087498aklu  //
3805c08e1173703234cc2913757f237ee916087498aklu  // TempOptionPtr must not be NULL if TempOptionSize is not zero.
3815c08e1173703234cc2913757f237ee916087498aklu  //
3825c08e1173703234cc2913757f237ee916087498aklu  ASSERT (TempOptionPtr != NULL);
3835c08e1173703234cc2913757f237ee916087498aklu  //
3845c08e1173703234cc2913757f237ee916087498aklu  // Append the new option number to the original option order
3855c08e1173703234cc2913757f237ee916087498aklu  //
3865c08e1173703234cc2913757f237ee916087498aklu  OrderItemNum = (TempOptionSize / sizeof (UINT16)) + 1 ;
3875c08e1173703234cc2913757f237ee916087498aklu  OptionOrderPtr = AllocateZeroPool ( OrderItemNum * sizeof (UINT16));
3885c08e1173703234cc2913757f237ee916087498aklu  ASSERT (OptionOrderPtr!= NULL);
3895c08e1173703234cc2913757f237ee916087498aklu  CopyMem (OptionOrderPtr, TempOptionPtr, (OrderItemNum - 1) * sizeof (UINT16));
3905c08e1173703234cc2913757f237ee916087498aklu
3915c08e1173703234cc2913757f237ee916087498aklu  OptionOrderPtr[Index] = RegisterOptionNumber;
3925c08e1173703234cc2913757f237ee916087498aklu
3935c08e1173703234cc2913757f237ee916087498aklu  Status = gRT->SetVariable (
3945c08e1173703234cc2913757f237ee916087498aklu                  VariableName,
3955c08e1173703234cc2913757f237ee916087498aklu                  &gEfiGlobalVariableGuid,
3965c08e1173703234cc2913757f237ee916087498aklu                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
3975c08e1173703234cc2913757f237ee916087498aklu                  OrderItemNum * sizeof (UINT16),
3985c08e1173703234cc2913757f237ee916087498aklu                  OptionOrderPtr
3995c08e1173703234cc2913757f237ee916087498aklu                  );
4005c08e1173703234cc2913757f237ee916087498aklu  FreePool (TempOptionPtr);
4015c08e1173703234cc2913757f237ee916087498aklu  FreePool (OptionOrderPtr);
4025c08e1173703234cc2913757f237ee916087498aklu
4035c08e1173703234cc2913757f237ee916087498aklu  return Status;
4045c08e1173703234cc2913757f237ee916087498aklu}
4055c08e1173703234cc2913757f237ee916087498aklu
406b16cc38bf3d74e7b781022aad96f28b3f8507fddydong/**
407b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  Returns the size of a device path in bytes.
408b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
409b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  This function returns the size, in bytes, of the device path data structure
410b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  specified by DevicePath including the end of device path node. If DevicePath
411b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  is NULL, then 0 is returned. If the length of the device path is bigger than
412b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  MaxSize, also return 0 to indicate this is an invalidate device path.
413b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
414b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  @param  DevicePath         A pointer to a device path data structure.
415b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  @param  MaxSize            Max valid device path size. If big than this size,
416b16cc38bf3d74e7b781022aad96f28b3f8507fddydong                             return error.
417b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
418b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  @retval 0                  An invalid device path.
419b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  @retval Others             The size of a device path in bytes.
420b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
421b16cc38bf3d74e7b781022aad96f28b3f8507fddydong**/
422b16cc38bf3d74e7b781022aad96f28b3f8507fddydongUINTN
423b16cc38bf3d74e7b781022aad96f28b3f8507fddydongGetDevicePathSizeEx (
424b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
425b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  IN UINTN                           MaxSize
426b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  )
427b16cc38bf3d74e7b781022aad96f28b3f8507fddydong{
428b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  UINTN  Size;
429b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  UINTN  NodeSize;
430b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
431b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  if (DevicePath == NULL) {
432b16cc38bf3d74e7b781022aad96f28b3f8507fddydong    return 0;
433b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  }
434b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
435b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  //
436b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  // Search for the end of the device path structure
437b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  //
438b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  Size = 0;
439b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  while (!IsDevicePathEnd (DevicePath)) {
440b16cc38bf3d74e7b781022aad96f28b3f8507fddydong    NodeSize = DevicePathNodeLength (DevicePath);
4418c08a567c64814f36f7261ca5652ef0350ca660eydong    if (NodeSize < END_DEVICE_PATH_LENGTH) {
442b16cc38bf3d74e7b781022aad96f28b3f8507fddydong      return 0;
443b16cc38bf3d74e7b781022aad96f28b3f8507fddydong    }
444b16cc38bf3d74e7b781022aad96f28b3f8507fddydong    Size += NodeSize;
445b16cc38bf3d74e7b781022aad96f28b3f8507fddydong    if (Size > MaxSize) {
446b16cc38bf3d74e7b781022aad96f28b3f8507fddydong      return 0;
447b16cc38bf3d74e7b781022aad96f28b3f8507fddydong    }
448b16cc38bf3d74e7b781022aad96f28b3f8507fddydong    DevicePath = NextDevicePathNode (DevicePath);
449b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  }
450b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  Size += DevicePathNodeLength (DevicePath);
451b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  if (Size > MaxSize) {
452b16cc38bf3d74e7b781022aad96f28b3f8507fddydong    return 0;
453b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  }
454b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
455b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  return Size;
456b16cc38bf3d74e7b781022aad96f28b3f8507fddydong}
457b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
458b16cc38bf3d74e7b781022aad96f28b3f8507fddydong/**
459b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  Returns the length of a Null-terminated Unicode string. If the length is
460b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  bigger than MaxStringLen, return length 0 to indicate that this is an
461b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  invalidate string.
462b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
4633e8670718dc8d10266a5bedfad2bc1de1ec3149aydong  This function returns the byte length of Unicode characters in the Null-terminated
464b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  Unicode string specified by String.
465b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
466b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  If String is NULL, then ASSERT().
467b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  If String is not aligned on a 16-bit boundary, then ASSERT().
468b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
469b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  @param  String           A pointer to a Null-terminated Unicode string.
470b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  @param  MaxStringLen     Max string len in this string.
471b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
472b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  @retval 0                An invalid string.
473b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  @retval Others           The length of String.
474b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
475b16cc38bf3d74e7b781022aad96f28b3f8507fddydong**/
476b16cc38bf3d74e7b781022aad96f28b3f8507fddydongUINTN
477b16cc38bf3d74e7b781022aad96f28b3f8507fddydongStrSizeEx (
478b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  IN      CONST CHAR16              *String,
479b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  IN      UINTN                     MaxStringLen
480b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  )
481b16cc38bf3d74e7b781022aad96f28b3f8507fddydong{
482b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  UINTN                             Length;
483b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
484b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  ASSERT (String != NULL && MaxStringLen != 0);
485b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  ASSERT (((UINTN) String & BIT0) == 0);
486b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
4873e8670718dc8d10266a5bedfad2bc1de1ec3149aydong  for (Length = 0; *String != L'\0' && MaxStringLen != Length; String++, Length+=2);
488b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
489b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  if (*String != L'\0' && MaxStringLen == Length) {
490b16cc38bf3d74e7b781022aad96f28b3f8507fddydong    return 0;
491b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  }
492b16cc38bf3d74e7b781022aad96f28b3f8507fddydong
4933e8670718dc8d10266a5bedfad2bc1de1ec3149aydong  return Length + 2;
494b16cc38bf3d74e7b781022aad96f28b3f8507fddydong}
4955c08e1173703234cc2913757f237ee916087498aklu
4965c08e1173703234cc2913757f237ee916087498aklu/**
4978c08a567c64814f36f7261ca5652ef0350ca660eydong  Validate the EFI Boot#### variable (VendorGuid/Name)
4988c08a567c64814f36f7261ca5652ef0350ca660eydong
4998c08a567c64814f36f7261ca5652ef0350ca660eydong  @param  Variable              Boot#### variable data.
5008c08a567c64814f36f7261ca5652ef0350ca660eydong  @param  VariableSize          Returns the size of the EFI variable that was read
5018c08a567c64814f36f7261ca5652ef0350ca660eydong
5028c08a567c64814f36f7261ca5652ef0350ca660eydong  @retval TRUE                  The variable data is correct.
5038c08a567c64814f36f7261ca5652ef0350ca660eydong  @retval FALSE                 The variable data is corrupted.
5048c08a567c64814f36f7261ca5652ef0350ca660eydong
5058c08a567c64814f36f7261ca5652ef0350ca660eydong**/
5068c08a567c64814f36f7261ca5652ef0350ca660eydongBOOLEAN
5078c08a567c64814f36f7261ca5652ef0350ca660eydongValidateOption (
5088c08a567c64814f36f7261ca5652ef0350ca660eydong  UINT8                     *Variable,
5098c08a567c64814f36f7261ca5652ef0350ca660eydong  UINTN                     VariableSize
5108c08a567c64814f36f7261ca5652ef0350ca660eydong  )
5118c08a567c64814f36f7261ca5652ef0350ca660eydong{
5128c08a567c64814f36f7261ca5652ef0350ca660eydong  UINT16                    FilePathSize;
5138c08a567c64814f36f7261ca5652ef0350ca660eydong  UINT8                     *TempPtr;
5148c08a567c64814f36f7261ca5652ef0350ca660eydong  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
5158c08a567c64814f36f7261ca5652ef0350ca660eydong  UINTN                     TempSize;
5168c08a567c64814f36f7261ca5652ef0350ca660eydong
5173e8670718dc8d10266a5bedfad2bc1de1ec3149aydong  if (VariableSize <= sizeof (UINT16) + sizeof (UINT32)) {
5183e8670718dc8d10266a5bedfad2bc1de1ec3149aydong    return FALSE;
5193e8670718dc8d10266a5bedfad2bc1de1ec3149aydong  }
5203e8670718dc8d10266a5bedfad2bc1de1ec3149aydong
5218c08a567c64814f36f7261ca5652ef0350ca660eydong  //
5228c08a567c64814f36f7261ca5652ef0350ca660eydong  // Skip the option attribute
5238c08a567c64814f36f7261ca5652ef0350ca660eydong  //
5248c08a567c64814f36f7261ca5652ef0350ca660eydong  TempPtr    = Variable;
5258c08a567c64814f36f7261ca5652ef0350ca660eydong  TempPtr   += sizeof (UINT32);
5268c08a567c64814f36f7261ca5652ef0350ca660eydong
5278c08a567c64814f36f7261ca5652ef0350ca660eydong  //
5288c08a567c64814f36f7261ca5652ef0350ca660eydong  // Get the option's device path size
5298c08a567c64814f36f7261ca5652ef0350ca660eydong  //
5308c08a567c64814f36f7261ca5652ef0350ca660eydong  FilePathSize  = *(UINT16 *) TempPtr;
5318c08a567c64814f36f7261ca5652ef0350ca660eydong  TempPtr      += sizeof (UINT16);
5328c08a567c64814f36f7261ca5652ef0350ca660eydong
5338c08a567c64814f36f7261ca5652ef0350ca660eydong  //
5348c08a567c64814f36f7261ca5652ef0350ca660eydong  // Get the option's description string size
5358c08a567c64814f36f7261ca5652ef0350ca660eydong  //
5363e8670718dc8d10266a5bedfad2bc1de1ec3149aydong  TempSize = StrSizeEx ((CHAR16 *) TempPtr, VariableSize - sizeof (UINT16) - sizeof (UINT32));
5378c08a567c64814f36f7261ca5652ef0350ca660eydong  TempPtr += TempSize;
5388c08a567c64814f36f7261ca5652ef0350ca660eydong
5398c08a567c64814f36f7261ca5652ef0350ca660eydong  //
5408c08a567c64814f36f7261ca5652ef0350ca660eydong  // Get the option's device path
5418c08a567c64814f36f7261ca5652ef0350ca660eydong  //
5428c08a567c64814f36f7261ca5652ef0350ca660eydong  DevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
5433e8670718dc8d10266a5bedfad2bc1de1ec3149aydong  TempPtr   += FilePathSize;
5448c08a567c64814f36f7261ca5652ef0350ca660eydong
5458c08a567c64814f36f7261ca5652ef0350ca660eydong  //
5468c08a567c64814f36f7261ca5652ef0350ca660eydong  // Validation boot option variable.
5478c08a567c64814f36f7261ca5652ef0350ca660eydong  //
5488c08a567c64814f36f7261ca5652ef0350ca660eydong  if ((FilePathSize == 0) || (TempSize == 0)) {
5498c08a567c64814f36f7261ca5652ef0350ca660eydong    return FALSE;
5508c08a567c64814f36f7261ca5652ef0350ca660eydong  }
5518c08a567c64814f36f7261ca5652ef0350ca660eydong
5523e8670718dc8d10266a5bedfad2bc1de1ec3149aydong  if (TempSize + FilePathSize + sizeof (UINT16) + sizeof (UINT32) > VariableSize) {
5538c08a567c64814f36f7261ca5652ef0350ca660eydong    return FALSE;
5548c08a567c64814f36f7261ca5652ef0350ca660eydong  }
5558c08a567c64814f36f7261ca5652ef0350ca660eydong
55697627ad45ab9951d83f3f73a4541e95697afec56ydong  return (BOOLEAN) (GetDevicePathSizeEx (DevicePath, FilePathSize) != 0);
5578c08a567c64814f36f7261ca5652ef0350ca660eydong}
5588c08a567c64814f36f7261ca5652ef0350ca660eydong
5598c08a567c64814f36f7261ca5652ef0350ca660eydong/**
560c1e2752c99eacd81b4860091947584c8190914a2ydong  Convert a single character to number.
561c1e2752c99eacd81b4860091947584c8190914a2ydong  It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'
562c1e2752c99eacd81b4860091947584c8190914a2ydong
563c1e2752c99eacd81b4860091947584c8190914a2ydong  @param Char    The input char which need to change to a hex number.
564c1e2752c99eacd81b4860091947584c8190914a2ydong
565c1e2752c99eacd81b4860091947584c8190914a2ydong**/
566c1e2752c99eacd81b4860091947584c8190914a2ydongUINTN
567c1e2752c99eacd81b4860091947584c8190914a2ydongCharToUint (
568c1e2752c99eacd81b4860091947584c8190914a2ydong  IN CHAR16                           Char
569c1e2752c99eacd81b4860091947584c8190914a2ydong  )
570c1e2752c99eacd81b4860091947584c8190914a2ydong{
571c1e2752c99eacd81b4860091947584c8190914a2ydong  if ((Char >= L'0') && (Char <= L'9')) {
572c1e2752c99eacd81b4860091947584c8190914a2ydong    return (UINTN) (Char - L'0');
573c1e2752c99eacd81b4860091947584c8190914a2ydong  }
574c1e2752c99eacd81b4860091947584c8190914a2ydong
575c1e2752c99eacd81b4860091947584c8190914a2ydong  if ((Char >= L'A') && (Char <= L'F')) {
576c1e2752c99eacd81b4860091947584c8190914a2ydong    return (UINTN) (Char - L'A' + 0xA);
577c1e2752c99eacd81b4860091947584c8190914a2ydong  }
578c1e2752c99eacd81b4860091947584c8190914a2ydong
579c1e2752c99eacd81b4860091947584c8190914a2ydong  ASSERT (FALSE);
580c1e2752c99eacd81b4860091947584c8190914a2ydong  return 0;
581c1e2752c99eacd81b4860091947584c8190914a2ydong}
582c1e2752c99eacd81b4860091947584c8190914a2ydong
583c1e2752c99eacd81b4860091947584c8190914a2ydong/**
5845c08e1173703234cc2913757f237ee916087498aklu  Build the boot#### or driver#### option from the VariableName, the
5855c08e1173703234cc2913757f237ee916087498aklu  build boot#### or driver#### will also be linked to BdsCommonOptionList.
5865c08e1173703234cc2913757f237ee916087498aklu
5875c08e1173703234cc2913757f237ee916087498aklu  @param  BdsCommonOptionList   The header of the boot#### or driver#### option
5885c08e1173703234cc2913757f237ee916087498aklu                                link list
5895c08e1173703234cc2913757f237ee916087498aklu  @param  VariableName          EFI Variable name indicate if it is boot#### or
5905c08e1173703234cc2913757f237ee916087498aklu                                driver####
5915c08e1173703234cc2913757f237ee916087498aklu
5925c08e1173703234cc2913757f237ee916087498aklu  @retval BDS_COMMON_OPTION     Get the option just been created
5935c08e1173703234cc2913757f237ee916087498aklu  @retval NULL                  Failed to get the new option
5945c08e1173703234cc2913757f237ee916087498aklu
5955c08e1173703234cc2913757f237ee916087498aklu**/
5965c08e1173703234cc2913757f237ee916087498akluBDS_COMMON_OPTION *
5975c08e1173703234cc2913757f237ee916087498akluEFIAPI
5985c08e1173703234cc2913757f237ee916087498akluBdsLibVariableToOption (
5995c08e1173703234cc2913757f237ee916087498aklu  IN OUT LIST_ENTRY                   *BdsCommonOptionList,
6005c08e1173703234cc2913757f237ee916087498aklu  IN  CHAR16                          *VariableName
6015c08e1173703234cc2913757f237ee916087498aklu  )
6025c08e1173703234cc2913757f237ee916087498aklu{
6035c08e1173703234cc2913757f237ee916087498aklu  UINT32                    Attribute;
6045c08e1173703234cc2913757f237ee916087498aklu  UINT16                    FilePathSize;
6055c08e1173703234cc2913757f237ee916087498aklu  UINT8                     *Variable;
6065c08e1173703234cc2913757f237ee916087498aklu  UINT8                     *TempPtr;
6075c08e1173703234cc2913757f237ee916087498aklu  UINTN                     VariableSize;
6085c08e1173703234cc2913757f237ee916087498aklu  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
6095c08e1173703234cc2913757f237ee916087498aklu  BDS_COMMON_OPTION         *Option;
6105c08e1173703234cc2913757f237ee916087498aklu  VOID                      *LoadOptions;
6115c08e1173703234cc2913757f237ee916087498aklu  UINT32                    LoadOptionsSize;
6125c08e1173703234cc2913757f237ee916087498aklu  CHAR16                    *Description;
6135c08e1173703234cc2913757f237ee916087498aklu  UINT8                     NumOff;
6143e8670718dc8d10266a5bedfad2bc1de1ec3149aydong
6155c08e1173703234cc2913757f237ee916087498aklu  //
6165c08e1173703234cc2913757f237ee916087498aklu  // Read the variable. We will never free this data.
6175c08e1173703234cc2913757f237ee916087498aklu  //
6185c08e1173703234cc2913757f237ee916087498aklu  Variable = BdsLibGetVariableAndSize (
6195c08e1173703234cc2913757f237ee916087498aklu              VariableName,
6205c08e1173703234cc2913757f237ee916087498aklu              &gEfiGlobalVariableGuid,
6215c08e1173703234cc2913757f237ee916087498aklu              &VariableSize
6225c08e1173703234cc2913757f237ee916087498aklu              );
6235c08e1173703234cc2913757f237ee916087498aklu  if (Variable == NULL) {
6245c08e1173703234cc2913757f237ee916087498aklu    return NULL;
6255c08e1173703234cc2913757f237ee916087498aklu  }
6268c08a567c64814f36f7261ca5652ef0350ca660eydong
6278c08a567c64814f36f7261ca5652ef0350ca660eydong  //
6288c08a567c64814f36f7261ca5652ef0350ca660eydong  // Validate Boot#### variable data.
6298c08a567c64814f36f7261ca5652ef0350ca660eydong  //
6308c08a567c64814f36f7261ca5652ef0350ca660eydong  if (!ValidateOption(Variable, VariableSize)) {
63146737a64d0e8f5dcc525973d3313f95920155265Chen Fan    FreePool (Variable);
6328c08a567c64814f36f7261ca5652ef0350ca660eydong    return NULL;
6338c08a567c64814f36f7261ca5652ef0350ca660eydong  }
6348c08a567c64814f36f7261ca5652ef0350ca660eydong
6355c08e1173703234cc2913757f237ee916087498aklu  //
6365c08e1173703234cc2913757f237ee916087498aklu  // Notes: careful defined the variable of Boot#### or
6375c08e1173703234cc2913757f237ee916087498aklu  // Driver####, consider use some macro to abstract the code
6385c08e1173703234cc2913757f237ee916087498aklu  //
6395c08e1173703234cc2913757f237ee916087498aklu  //
6405c08e1173703234cc2913757f237ee916087498aklu  // Get the option attribute
6415c08e1173703234cc2913757f237ee916087498aklu  //
6425c08e1173703234cc2913757f237ee916087498aklu  TempPtr   =  Variable;
6435c08e1173703234cc2913757f237ee916087498aklu  Attribute =  *(UINT32 *) Variable;
6445c08e1173703234cc2913757f237ee916087498aklu  TempPtr   += sizeof (UINT32);
6455c08e1173703234cc2913757f237ee916087498aklu
6465c08e1173703234cc2913757f237ee916087498aklu  //
6475c08e1173703234cc2913757f237ee916087498aklu  // Get the option's device path size
6485c08e1173703234cc2913757f237ee916087498aklu  //
6495c08e1173703234cc2913757f237ee916087498aklu  FilePathSize =  *(UINT16 *) TempPtr;
6505c08e1173703234cc2913757f237ee916087498aklu  TempPtr      += sizeof (UINT16);
6515c08e1173703234cc2913757f237ee916087498aklu
6525c08e1173703234cc2913757f237ee916087498aklu  //
6535c08e1173703234cc2913757f237ee916087498aklu  // Get the option's description string
6545c08e1173703234cc2913757f237ee916087498aklu  //
6555c08e1173703234cc2913757f237ee916087498aklu  Description = (CHAR16 *) TempPtr;
6565c08e1173703234cc2913757f237ee916087498aklu
6575c08e1173703234cc2913757f237ee916087498aklu  //
6585c08e1173703234cc2913757f237ee916087498aklu  // Get the option's description string size
6595c08e1173703234cc2913757f237ee916087498aklu  //
6603e8670718dc8d10266a5bedfad2bc1de1ec3149aydong  TempPtr += StrSize((CHAR16 *) TempPtr);
6615c08e1173703234cc2913757f237ee916087498aklu
6625c08e1173703234cc2913757f237ee916087498aklu  //
6635c08e1173703234cc2913757f237ee916087498aklu  // Get the option's device path
6645c08e1173703234cc2913757f237ee916087498aklu  //
6655c08e1173703234cc2913757f237ee916087498aklu  DevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
6665c08e1173703234cc2913757f237ee916087498aklu  TempPtr    += FilePathSize;
6675c08e1173703234cc2913757f237ee916087498aklu
668b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  //
669b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  // Get load opion data.
670b16cc38bf3d74e7b781022aad96f28b3f8507fddydong  //
6715c08e1173703234cc2913757f237ee916087498aklu  LoadOptions     = TempPtr;
6725c08e1173703234cc2913757f237ee916087498aklu  LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));
6735c08e1173703234cc2913757f237ee916087498aklu
6745c08e1173703234cc2913757f237ee916087498aklu  //
6755c08e1173703234cc2913757f237ee916087498aklu  // The Console variables may have multiple device paths, so make
6765c08e1173703234cc2913757f237ee916087498aklu  // an Entry for each one.
6775c08e1173703234cc2913757f237ee916087498aklu  //
6785c08e1173703234cc2913757f237ee916087498aklu  Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION));
6795c08e1173703234cc2913757f237ee916087498aklu  if (Option == NULL) {
68046737a64d0e8f5dcc525973d3313f95920155265Chen Fan    FreePool (Variable);
6815c08e1173703234cc2913757f237ee916087498aklu    return NULL;
6825c08e1173703234cc2913757f237ee916087498aklu  }
6835c08e1173703234cc2913757f237ee916087498aklu
6845c08e1173703234cc2913757f237ee916087498aklu  Option->Signature   = BDS_LOAD_OPTION_SIGNATURE;
6855c08e1173703234cc2913757f237ee916087498aklu  Option->DevicePath  = AllocateZeroPool (GetDevicePathSize (DevicePath));
6865c08e1173703234cc2913757f237ee916087498aklu  ASSERT(Option->DevicePath != NULL);
6875c08e1173703234cc2913757f237ee916087498aklu  CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));
6885c08e1173703234cc2913757f237ee916087498aklu
6895c08e1173703234cc2913757f237ee916087498aklu  Option->Attribute   = Attribute;
6905c08e1173703234cc2913757f237ee916087498aklu  Option->Description = AllocateZeroPool (StrSize (Description));
6915c08e1173703234cc2913757f237ee916087498aklu  ASSERT(Option->Description != NULL);
6925c08e1173703234cc2913757f237ee916087498aklu  CopyMem (Option->Description, Description, StrSize (Description));
6935c08e1173703234cc2913757f237ee916087498aklu
6945c08e1173703234cc2913757f237ee916087498aklu  Option->LoadOptions = AllocateZeroPool (LoadOptionsSize);
6955c08e1173703234cc2913757f237ee916087498aklu  ASSERT(Option->LoadOptions != NULL);
6965c08e1173703234cc2913757f237ee916087498aklu  CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);
6975c08e1173703234cc2913757f237ee916087498aklu  Option->LoadOptionsSize = LoadOptionsSize;
6985c08e1173703234cc2913757f237ee916087498aklu
6995c08e1173703234cc2913757f237ee916087498aklu  //
7005c08e1173703234cc2913757f237ee916087498aklu  // Get the value from VariableName Unicode string
7015c08e1173703234cc2913757f237ee916087498aklu  // since the ISO standard assumes ASCII equivalent abbreviations, we can be safe in converting this
7025c08e1173703234cc2913757f237ee916087498aklu  // Unicode stream to ASCII without any loss in meaning.
7035c08e1173703234cc2913757f237ee916087498aklu  //
7045c08e1173703234cc2913757f237ee916087498aklu  if (*VariableName == 'B') {
705c1e2752c99eacd81b4860091947584c8190914a2ydong    NumOff = (UINT8) (sizeof (L"Boot") / sizeof (CHAR16) - 1);
706c1e2752c99eacd81b4860091947584c8190914a2ydong    Option->BootCurrent = (UINT16) (CharToUint (VariableName[NumOff+0]) * 0x1000)
707c1e2752c99eacd81b4860091947584c8190914a2ydong               + (UINT16) (CharToUint (VariableName[NumOff+1]) * 0x100)
708c1e2752c99eacd81b4860091947584c8190914a2ydong               + (UINT16) (CharToUint (VariableName[NumOff+2]) * 0x10)
709c1e2752c99eacd81b4860091947584c8190914a2ydong               + (UINT16) (CharToUint (VariableName[NumOff+3]) * 0x1);
7105c08e1173703234cc2913757f237ee916087498aklu  }
71116e5944abde9ea3f01c9ccff2a86a41e5a6a1dd0niruiyu  InsertTailList (BdsCommonOptionList, &Option->Link);
7125c08e1173703234cc2913757f237ee916087498aklu  FreePool (Variable);
71316e5944abde9ea3f01c9ccff2a86a41e5a6a1dd0niruiyu  return Option;
7145c08e1173703234cc2913757f237ee916087498aklu}
7155c08e1173703234cc2913757f237ee916087498aklu
7165c08e1173703234cc2913757f237ee916087498aklu/**
7175c08e1173703234cc2913757f237ee916087498aklu  Process BootOrder, or DriverOrder variables, by calling
7185c08e1173703234cc2913757f237ee916087498aklu  BdsLibVariableToOption () for each UINT16 in the variables.
7195c08e1173703234cc2913757f237ee916087498aklu
7205c08e1173703234cc2913757f237ee916087498aklu  @param  BdsCommonOptionList   The header of the option list base on variable
7215c08e1173703234cc2913757f237ee916087498aklu                                VariableName
7225c08e1173703234cc2913757f237ee916087498aklu  @param  VariableName          EFI Variable name indicate the BootOrder or
7235c08e1173703234cc2913757f237ee916087498aklu                                DriverOrder
7245c08e1173703234cc2913757f237ee916087498aklu
7255c08e1173703234cc2913757f237ee916087498aklu  @retval EFI_SUCCESS           Success create the boot option or driver option
7265c08e1173703234cc2913757f237ee916087498aklu                                list
7275c08e1173703234cc2913757f237ee916087498aklu  @retval EFI_OUT_OF_RESOURCES  Failed to get the boot option or driver option list
7285c08e1173703234cc2913757f237ee916087498aklu
7295c08e1173703234cc2913757f237ee916087498aklu**/
7305c08e1173703234cc2913757f237ee916087498akluEFI_STATUS
7315c08e1173703234cc2913757f237ee916087498akluEFIAPI
7325c08e1173703234cc2913757f237ee916087498akluBdsLibBuildOptionFromVar (
7335c08e1173703234cc2913757f237ee916087498aklu  IN  LIST_ENTRY                      *BdsCommonOptionList,
7345c08e1173703234cc2913757f237ee916087498aklu  IN  CHAR16                          *VariableName
7355c08e1173703234cc2913757f237ee916087498aklu  )
7365c08e1173703234cc2913757f237ee916087498aklu{
7375c08e1173703234cc2913757f237ee916087498aklu  UINT16            *OptionOrder;
7385c08e1173703234cc2913757f237ee916087498aklu  UINTN             OptionOrderSize;
7395c08e1173703234cc2913757f237ee916087498aklu  UINTN             Index;
7405c08e1173703234cc2913757f237ee916087498aklu  BDS_COMMON_OPTION *Option;
7415c08e1173703234cc2913757f237ee916087498aklu  CHAR16            OptionName[20];
7425c08e1173703234cc2913757f237ee916087498aklu
7435c08e1173703234cc2913757f237ee916087498aklu  //
7445c08e1173703234cc2913757f237ee916087498aklu  // Zero Buffer in order to get all BOOT#### variables
7455c08e1173703234cc2913757f237ee916087498aklu  //
7465c08e1173703234cc2913757f237ee916087498aklu  ZeroMem (OptionName, sizeof (OptionName));
7475c08e1173703234cc2913757f237ee916087498aklu
7485c08e1173703234cc2913757f237ee916087498aklu  //
7495c08e1173703234cc2913757f237ee916087498aklu  // Read the BootOrder, or DriverOrder variable.
7505c08e1173703234cc2913757f237ee916087498aklu  //
7515c08e1173703234cc2913757f237ee916087498aklu  OptionOrder = BdsLibGetVariableAndSize (
7525c08e1173703234cc2913757f237ee916087498aklu                  VariableName,
7535c08e1173703234cc2913757f237ee916087498aklu                  &gEfiGlobalVariableGuid,
7545c08e1173703234cc2913757f237ee916087498aklu                  &OptionOrderSize
7555c08e1173703234cc2913757f237ee916087498aklu                  );
7565c08e1173703234cc2913757f237ee916087498aklu  if (OptionOrder == NULL) {
7575c08e1173703234cc2913757f237ee916087498aklu    return EFI_OUT_OF_RESOURCES;
7585c08e1173703234cc2913757f237ee916087498aklu  }
7595c08e1173703234cc2913757f237ee916087498aklu
7605c08e1173703234cc2913757f237ee916087498aklu  for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {
7615c08e1173703234cc2913757f237ee916087498aklu    if (*VariableName == 'B') {
7625c08e1173703234cc2913757f237ee916087498aklu      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]);
7635c08e1173703234cc2913757f237ee916087498aklu    } else {
7645c08e1173703234cc2913757f237ee916087498aklu      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]);
7655c08e1173703234cc2913757f237ee916087498aklu    }
7665c08e1173703234cc2913757f237ee916087498aklu
7675c08e1173703234cc2913757f237ee916087498aklu    Option              = BdsLibVariableToOption (BdsCommonOptionList, OptionName);
7687490e2bed8141f4edce22a4facf5cba4e2f93129rsun    if (Option != NULL) {
7697490e2bed8141f4edce22a4facf5cba4e2f93129rsun      Option->BootCurrent = OptionOrder[Index];
7707490e2bed8141f4edce22a4facf5cba4e2f93129rsun    }
7715c08e1173703234cc2913757f237ee916087498aklu  }
7725c08e1173703234cc2913757f237ee916087498aklu
7735c08e1173703234cc2913757f237ee916087498aklu  FreePool (OptionOrder);
7745c08e1173703234cc2913757f237ee916087498aklu
7755c08e1173703234cc2913757f237ee916087498aklu  return EFI_SUCCESS;
7765c08e1173703234cc2913757f237ee916087498aklu}
7775c08e1173703234cc2913757f237ee916087498aklu
7785c08e1173703234cc2913757f237ee916087498aklu/**
7795c08e1173703234cc2913757f237ee916087498aklu  Get boot mode by looking up configuration table and parsing HOB list
7805c08e1173703234cc2913757f237ee916087498aklu
7815c08e1173703234cc2913757f237ee916087498aklu  @param  BootMode              Boot mode from PEI handoff HOB.
7825c08e1173703234cc2913757f237ee916087498aklu
7835c08e1173703234cc2913757f237ee916087498aklu  @retval EFI_SUCCESS           Successfully get boot mode
7845c08e1173703234cc2913757f237ee916087498aklu
7855c08e1173703234cc2913757f237ee916087498aklu**/
7865c08e1173703234cc2913757f237ee916087498akluEFI_STATUS
7875c08e1173703234cc2913757f237ee916087498akluEFIAPI
7885c08e1173703234cc2913757f237ee916087498akluBdsLibGetBootMode (
7895c08e1173703234cc2913757f237ee916087498aklu  OUT EFI_BOOT_MODE       *BootMode
7905c08e1173703234cc2913757f237ee916087498aklu  )
7915c08e1173703234cc2913757f237ee916087498aklu{
7925c08e1173703234cc2913757f237ee916087498aklu  *BootMode = GetBootModeHob ();
7935c08e1173703234cc2913757f237ee916087498aklu
7945c08e1173703234cc2913757f237ee916087498aklu  return EFI_SUCCESS;
7955c08e1173703234cc2913757f237ee916087498aklu}
7965c08e1173703234cc2913757f237ee916087498aklu
7975c08e1173703234cc2913757f237ee916087498aklu/**
7985c08e1173703234cc2913757f237ee916087498aklu  Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
7995c08e1173703234cc2913757f237ee916087498aklu  buffer, and the size of the buffer. If failure return NULL.
8005c08e1173703234cc2913757f237ee916087498aklu
8015c08e1173703234cc2913757f237ee916087498aklu  @param  Name                  String part of EFI variable name
8025c08e1173703234cc2913757f237ee916087498aklu  @param  VendorGuid            GUID part of EFI variable name
8035c08e1173703234cc2913757f237ee916087498aklu  @param  VariableSize          Returns the size of the EFI variable that was read
8045c08e1173703234cc2913757f237ee916087498aklu
8055c08e1173703234cc2913757f237ee916087498aklu  @return                       Dynamically allocated memory that contains a copy of the EFI variable
8065c08e1173703234cc2913757f237ee916087498aklu                                Caller is responsible freeing the buffer.
8075c08e1173703234cc2913757f237ee916087498aklu  @retval NULL                  Variable was not read
8085c08e1173703234cc2913757f237ee916087498aklu
8095c08e1173703234cc2913757f237ee916087498aklu**/
8105c08e1173703234cc2913757f237ee916087498akluVOID *
8115c08e1173703234cc2913757f237ee916087498akluEFIAPI
8125c08e1173703234cc2913757f237ee916087498akluBdsLibGetVariableAndSize (
8135c08e1173703234cc2913757f237ee916087498aklu  IN  CHAR16              *Name,
8145c08e1173703234cc2913757f237ee916087498aklu  IN  EFI_GUID            *VendorGuid,
8155c08e1173703234cc2913757f237ee916087498aklu  OUT UINTN               *VariableSize
8165c08e1173703234cc2913757f237ee916087498aklu  )
8175c08e1173703234cc2913757f237ee916087498aklu{
8185c08e1173703234cc2913757f237ee916087498aklu  EFI_STATUS  Status;
8195c08e1173703234cc2913757f237ee916087498aklu  UINTN       BufferSize;
8205c08e1173703234cc2913757f237ee916087498aklu  VOID        *Buffer;
8215c08e1173703234cc2913757f237ee916087498aklu
8225c08e1173703234cc2913757f237ee916087498aklu  Buffer = NULL;
8235c08e1173703234cc2913757f237ee916087498aklu
8245c08e1173703234cc2913757f237ee916087498aklu  //
8255c08e1173703234cc2913757f237ee916087498aklu  // Pass in a zero size buffer to find the required buffer size.
8265c08e1173703234cc2913757f237ee916087498aklu  //
8275c08e1173703234cc2913757f237ee916087498aklu  BufferSize  = 0;
8285c08e1173703234cc2913757f237ee916087498aklu  Status      = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
8295c08e1173703234cc2913757f237ee916087498aklu  if (Status == EFI_BUFFER_TOO_SMALL) {
8305c08e1173703234cc2913757f237ee916087498aklu    //
8315c08e1173703234cc2913757f237ee916087498aklu    // Allocate the buffer to return
8325c08e1173703234cc2913757f237ee916087498aklu    //
8335c08e1173703234cc2913757f237ee916087498aklu    Buffer = AllocateZeroPool (BufferSize);
8345c08e1173703234cc2913757f237ee916087498aklu    if (Buffer == NULL) {
8352d1f3dd497f343bc54b4a164d4e9f015ae04f7dcniruiyu      *VariableSize = 0;
8365c08e1173703234cc2913757f237ee916087498aklu      return NULL;
8375c08e1173703234cc2913757f237ee916087498aklu    }
8385c08e1173703234cc2913757f237ee916087498aklu    //
8395c08e1173703234cc2913757f237ee916087498aklu    // Read variable into the allocated buffer.
8405c08e1173703234cc2913757f237ee916087498aklu    //
8415c08e1173703234cc2913757f237ee916087498aklu    Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
8425c08e1173703234cc2913757f237ee916087498aklu    if (EFI_ERROR (Status)) {
8432d1f3dd497f343bc54b4a164d4e9f015ae04f7dcniruiyu      FreePool (Buffer);
8445c08e1173703234cc2913757f237ee916087498aklu      BufferSize = 0;
8452d1f3dd497f343bc54b4a164d4e9f015ae04f7dcniruiyu      Buffer     = NULL;
8465c08e1173703234cc2913757f237ee916087498aklu    }
8475c08e1173703234cc2913757f237ee916087498aklu  }
8485c08e1173703234cc2913757f237ee916087498aklu
8492d1f3dd497f343bc54b4a164d4e9f015ae04f7dcniruiyu  ASSERT (((Buffer == NULL) && (BufferSize == 0)) ||
8502d1f3dd497f343bc54b4a164d4e9f015ae04f7dcniruiyu          ((Buffer != NULL) && (BufferSize != 0))
8512d1f3dd497f343bc54b4a164d4e9f015ae04f7dcniruiyu          );
8525c08e1173703234cc2913757f237ee916087498aklu  *VariableSize = BufferSize;
8535c08e1173703234cc2913757f237ee916087498aklu  return Buffer;
8545c08e1173703234cc2913757f237ee916087498aklu}
8555c08e1173703234cc2913757f237ee916087498aklu
8565c08e1173703234cc2913757f237ee916087498aklu/**
8575c08e1173703234cc2913757f237ee916087498aklu  Delete the instance in Multi which matches partly with Single instance
8585c08e1173703234cc2913757f237ee916087498aklu
8595c08e1173703234cc2913757f237ee916087498aklu  @param  Multi                 A pointer to a multi-instance device path data
8605c08e1173703234cc2913757f237ee916087498aklu                                structure.
8615c08e1173703234cc2913757f237ee916087498aklu  @param  Single                A pointer to a single-instance device path data
8625c08e1173703234cc2913757f237ee916087498aklu                                structure.
8635c08e1173703234cc2913757f237ee916087498aklu
8645c08e1173703234cc2913757f237ee916087498aklu  @return This function will remove the device path instances in Multi which partly
8655c08e1173703234cc2913757f237ee916087498aklu          match with the Single, and return the result device path. If there is no
8665c08e1173703234cc2913757f237ee916087498aklu          remaining device path as a result, this function will return NULL.
8675c08e1173703234cc2913757f237ee916087498aklu
8685c08e1173703234cc2913757f237ee916087498aklu**/
8695c08e1173703234cc2913757f237ee916087498akluEFI_DEVICE_PATH_PROTOCOL *
8705c08e1173703234cc2913757f237ee916087498akluEFIAPI
8715c08e1173703234cc2913757f237ee916087498akluBdsLibDelPartMatchInstance (
8725c08e1173703234cc2913757f237ee916087498aklu  IN     EFI_DEVICE_PATH_PROTOCOL  *Multi,
8735c08e1173703234cc2913757f237ee916087498aklu  IN     EFI_DEVICE_PATH_PROTOCOL  *Single
8745c08e1173703234cc2913757f237ee916087498aklu  )
8755c08e1173703234cc2913757f237ee916087498aklu{
8765c08e1173703234cc2913757f237ee916087498aklu  EFI_DEVICE_PATH_PROTOCOL  *Instance;
8775c08e1173703234cc2913757f237ee916087498aklu  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
8785c08e1173703234cc2913757f237ee916087498aklu  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
8795c08e1173703234cc2913757f237ee916087498aklu  UINTN                     InstanceSize;
8805c08e1173703234cc2913757f237ee916087498aklu  UINTN                     SingleDpSize;
8815c08e1173703234cc2913757f237ee916087498aklu  UINTN                     Size;
8825c08e1173703234cc2913757f237ee916087498aklu
8835c08e1173703234cc2913757f237ee916087498aklu  NewDevicePath     = NULL;
8845c08e1173703234cc2913757f237ee916087498aklu  TempNewDevicePath = NULL;
8855c08e1173703234cc2913757f237ee916087498aklu
8865c08e1173703234cc2913757f237ee916087498aklu  if (Multi == NULL || Single == NULL) {
8875c08e1173703234cc2913757f237ee916087498aklu    return Multi;
8885c08e1173703234cc2913757f237ee916087498aklu  }
8895c08e1173703234cc2913757f237ee916087498aklu
8905c08e1173703234cc2913757f237ee916087498aklu  Instance        =  GetNextDevicePathInstance (&Multi, &InstanceSize);
8915c08e1173703234cc2913757f237ee916087498aklu  SingleDpSize    =  GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;
8925c08e1173703234cc2913757f237ee916087498aklu  InstanceSize    -= END_DEVICE_PATH_LENGTH;
8935c08e1173703234cc2913757f237ee916087498aklu
8945c08e1173703234cc2913757f237ee916087498aklu  while (Instance != NULL) {
8955c08e1173703234cc2913757f237ee916087498aklu
8965c08e1173703234cc2913757f237ee916087498aklu    Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize;
8975c08e1173703234cc2913757f237ee916087498aklu
8985c08e1173703234cc2913757f237ee916087498aklu    if ((CompareMem (Instance, Single, Size) != 0)) {
8995c08e1173703234cc2913757f237ee916087498aklu      //
9005c08e1173703234cc2913757f237ee916087498aklu      // Append the device path instance which does not match with Single
9015c08e1173703234cc2913757f237ee916087498aklu      //
9025c08e1173703234cc2913757f237ee916087498aklu      TempNewDevicePath = NewDevicePath;
9035c08e1173703234cc2913757f237ee916087498aklu      NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
9045c08e1173703234cc2913757f237ee916087498aklu      if (TempNewDevicePath != NULL) {
9055c08e1173703234cc2913757f237ee916087498aklu        FreePool(TempNewDevicePath);
9065c08e1173703234cc2913757f237ee916087498aklu      }
9075c08e1173703234cc2913757f237ee916087498aklu    }
9085c08e1173703234cc2913757f237ee916087498aklu    FreePool(Instance);
9095c08e1173703234cc2913757f237ee916087498aklu    Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
9105c08e1173703234cc2913757f237ee916087498aklu    InstanceSize  -= END_DEVICE_PATH_LENGTH;
9115c08e1173703234cc2913757f237ee916087498aklu  }
9125c08e1173703234cc2913757f237ee916087498aklu
9135c08e1173703234cc2913757f237ee916087498aklu  return NewDevicePath;
9145c08e1173703234cc2913757f237ee916087498aklu}
9155c08e1173703234cc2913757f237ee916087498aklu
9165c08e1173703234cc2913757f237ee916087498aklu/**
9175c08e1173703234cc2913757f237ee916087498aklu  Function compares a device path data structure to that of all the nodes of a
9185c08e1173703234cc2913757f237ee916087498aklu  second device path instance.
9195c08e1173703234cc2913757f237ee916087498aklu
9205c08e1173703234cc2913757f237ee916087498aklu  @param  Multi                 A pointer to a multi-instance device path data
9215c08e1173703234cc2913757f237ee916087498aklu                                structure.
9225c08e1173703234cc2913757f237ee916087498aklu  @param  Single                A pointer to a single-instance device path data
9235c08e1173703234cc2913757f237ee916087498aklu                                structure.
9245c08e1173703234cc2913757f237ee916087498aklu
9255c08e1173703234cc2913757f237ee916087498aklu  @retval TRUE                  If the Single device path is contained within Multi device path.
9265c08e1173703234cc2913757f237ee916087498aklu  @retval FALSE                 The Single device path is not match within Multi device path.
9275c08e1173703234cc2913757f237ee916087498aklu
9285c08e1173703234cc2913757f237ee916087498aklu**/
9295c08e1173703234cc2913757f237ee916087498akluBOOLEAN
9305c08e1173703234cc2913757f237ee916087498akluEFIAPI
9315c08e1173703234cc2913757f237ee916087498akluBdsLibMatchDevicePaths (
9325c08e1173703234cc2913757f237ee916087498aklu  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,
9335c08e1173703234cc2913757f237ee916087498aklu  IN  EFI_DEVICE_PATH_PROTOCOL  *Single
9345c08e1173703234cc2913757f237ee916087498aklu  )
9355c08e1173703234cc2913757f237ee916087498aklu{
9365c08e1173703234cc2913757f237ee916087498aklu  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
9375c08e1173703234cc2913757f237ee916087498aklu  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
9385c08e1173703234cc2913757f237ee916087498aklu  UINTN                     Size;
9395c08e1173703234cc2913757f237ee916087498aklu
9405c08e1173703234cc2913757f237ee916087498aklu  if (Multi == NULL || Single  == NULL) {
9415c08e1173703234cc2913757f237ee916087498aklu    return FALSE;
9425c08e1173703234cc2913757f237ee916087498aklu  }
9435c08e1173703234cc2913757f237ee916087498aklu
9445c08e1173703234cc2913757f237ee916087498aklu  DevicePath      = Multi;
9455c08e1173703234cc2913757f237ee916087498aklu  DevicePathInst  = GetNextDevicePathInstance (&DevicePath, &Size);
9465c08e1173703234cc2913757f237ee916087498aklu
9475c08e1173703234cc2913757f237ee916087498aklu  //
9485c08e1173703234cc2913757f237ee916087498aklu  // Search for the match of 'Single' in 'Multi'
9495c08e1173703234cc2913757f237ee916087498aklu  //
9505c08e1173703234cc2913757f237ee916087498aklu  while (DevicePathInst != NULL) {
9515c08e1173703234cc2913757f237ee916087498aklu    //
9525c08e1173703234cc2913757f237ee916087498aklu    // If the single device path is found in multiple device paths,
9535c08e1173703234cc2913757f237ee916087498aklu    // return success
9545c08e1173703234cc2913757f237ee916087498aklu    //
9555c08e1173703234cc2913757f237ee916087498aklu    if (CompareMem (Single, DevicePathInst, Size) == 0) {
9565c08e1173703234cc2913757f237ee916087498aklu      FreePool (DevicePathInst);
9575c08e1173703234cc2913757f237ee916087498aklu      return TRUE;
9585c08e1173703234cc2913757f237ee916087498aklu    }
9595c08e1173703234cc2913757f237ee916087498aklu
9605c08e1173703234cc2913757f237ee916087498aklu    FreePool (DevicePathInst);
9615c08e1173703234cc2913757f237ee916087498aklu    DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
9625c08e1173703234cc2913757f237ee916087498aklu  }
9635c08e1173703234cc2913757f237ee916087498aklu
9645c08e1173703234cc2913757f237ee916087498aklu  return FALSE;
9655c08e1173703234cc2913757f237ee916087498aklu}
9665c08e1173703234cc2913757f237ee916087498aklu
9675c08e1173703234cc2913757f237ee916087498aklu/**
9685c08e1173703234cc2913757f237ee916087498aklu  This function prints a series of strings.
9695c08e1173703234cc2913757f237ee916087498aklu
9705c08e1173703234cc2913757f237ee916087498aklu  @param  ConOut                Pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
9715c08e1173703234cc2913757f237ee916087498aklu  @param  ...                   A variable argument list containing series of
9725c08e1173703234cc2913757f237ee916087498aklu                                strings, the last string must be NULL.
9735c08e1173703234cc2913757f237ee916087498aklu
9745c08e1173703234cc2913757f237ee916087498aklu  @retval EFI_SUCCESS           Success print out the string using ConOut.
9755c08e1173703234cc2913757f237ee916087498aklu  @retval EFI_STATUS            Return the status of the ConOut->OutputString ().
9765c08e1173703234cc2913757f237ee916087498aklu
9775c08e1173703234cc2913757f237ee916087498aklu**/
9785c08e1173703234cc2913757f237ee916087498akluEFI_STATUS
9795c08e1173703234cc2913757f237ee916087498akluEFIAPI
9805c08e1173703234cc2913757f237ee916087498akluBdsLibOutputStrings (
9815c08e1173703234cc2913757f237ee916087498aklu  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *ConOut,
9825c08e1173703234cc2913757f237ee916087498aklu  ...
9835c08e1173703234cc2913757f237ee916087498aklu  )
9845c08e1173703234cc2913757f237ee916087498aklu{
9855c08e1173703234cc2913757f237ee916087498aklu  VA_LIST     Args;
9865c08e1173703234cc2913757f237ee916087498aklu  EFI_STATUS  Status;
9875c08e1173703234cc2913757f237ee916087498aklu  CHAR16      *String;
9885c08e1173703234cc2913757f237ee916087498aklu
9895c08e1173703234cc2913757f237ee916087498aklu  Status = EFI_SUCCESS;
9905c08e1173703234cc2913757f237ee916087498aklu  VA_START (Args, ConOut);
9915c08e1173703234cc2913757f237ee916087498aklu
9925c08e1173703234cc2913757f237ee916087498aklu  while (!EFI_ERROR (Status)) {
9935c08e1173703234cc2913757f237ee916087498aklu    //
9945c08e1173703234cc2913757f237ee916087498aklu    // If String is NULL, then it's the end of the list
9955c08e1173703234cc2913757f237ee916087498aklu    //
9965c08e1173703234cc2913757f237ee916087498aklu    String = VA_ARG (Args, CHAR16 *);
99731b440cfa6115cb63c2f57d1af5c56b59d665126eric_tian    if (String == NULL) {
9985c08e1173703234cc2913757f237ee916087498aklu      break;
9995c08e1173703234cc2913757f237ee916087498aklu    }
10005c08e1173703234cc2913757f237ee916087498aklu
10015c08e1173703234cc2913757f237ee916087498aklu    Status = ConOut->OutputString (ConOut, String);
10025c08e1173703234cc2913757f237ee916087498aklu
10035c08e1173703234cc2913757f237ee916087498aklu    if (EFI_ERROR (Status)) {
10045c08e1173703234cc2913757f237ee916087498aklu      break;
10055c08e1173703234cc2913757f237ee916087498aklu    }
10065c08e1173703234cc2913757f237ee916087498aklu  }
10075c08e1173703234cc2913757f237ee916087498aklu
10085c08e1173703234cc2913757f237ee916087498aklu  VA_END(Args);
10095c08e1173703234cc2913757f237ee916087498aklu  return Status;
10105c08e1173703234cc2913757f237ee916087498aklu}
10115c08e1173703234cc2913757f237ee916087498aklu
10125c08e1173703234cc2913757f237ee916087498aklu//
10138d3b5aff68cef02a1fdb650d009b9aa6b83d6040gikidy//  Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
10145c08e1173703234cc2913757f237ee916087498aklu//  Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser  if
10155c08e1173703234cc2913757f237ee916087498aklu//  user change any option setting which needs a reset to be effective, and  the reset will be applied according to  the user selection.
10165c08e1173703234cc2913757f237ee916087498aklu//
10175c08e1173703234cc2913757f237ee916087498aklu
10185c08e1173703234cc2913757f237ee916087498aklu
10195c08e1173703234cc2913757f237ee916087498aklu/**
10205c08e1173703234cc2913757f237ee916087498aklu  Enable the setup browser reset reminder feature.
10215c08e1173703234cc2913757f237ee916087498aklu  This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.
10225c08e1173703234cc2913757f237ee916087498aklu
10235c08e1173703234cc2913757f237ee916087498aklu**/
10245c08e1173703234cc2913757f237ee916087498akluVOID
10255c08e1173703234cc2913757f237ee916087498akluEFIAPI
10265c08e1173703234cc2913757f237ee916087498akluEnableResetReminderFeature (
10275c08e1173703234cc2913757f237ee916087498aklu  VOID
10285c08e1173703234cc2913757f237ee916087498aklu  )
10295c08e1173703234cc2913757f237ee916087498aklu{
10305c08e1173703234cc2913757f237ee916087498aklu  mFeaturerSwitch = TRUE;
10315c08e1173703234cc2913757f237ee916087498aklu}
10325c08e1173703234cc2913757f237ee916087498aklu
10335c08e1173703234cc2913757f237ee916087498aklu
10345c08e1173703234cc2913757f237ee916087498aklu/**
10355c08e1173703234cc2913757f237ee916087498aklu  Disable the setup browser reset reminder feature.
10365c08e1173703234cc2913757f237ee916087498aklu  This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.
10375c08e1173703234cc2913757f237ee916087498aklu
10385c08e1173703234cc2913757f237ee916087498aklu**/
10395c08e1173703234cc2913757f237ee916087498akluVOID
10405c08e1173703234cc2913757f237ee916087498akluEFIAPI
10415c08e1173703234cc2913757f237ee916087498akluDisableResetReminderFeature (
10425c08e1173703234cc2913757f237ee916087498aklu  VOID
10435c08e1173703234cc2913757f237ee916087498aklu  )
10445c08e1173703234cc2913757f237ee916087498aklu{
10455c08e1173703234cc2913757f237ee916087498aklu  mFeaturerSwitch = FALSE;
10465c08e1173703234cc2913757f237ee916087498aklu}
10475c08e1173703234cc2913757f237ee916087498aklu
10485c08e1173703234cc2913757f237ee916087498aklu
10495c08e1173703234cc2913757f237ee916087498aklu/**
10505c08e1173703234cc2913757f237ee916087498aklu  Record the info that  a reset is required.
10515c08e1173703234cc2913757f237ee916087498aklu  A  module boolean variable is used to record whether a reset is required.
10525c08e1173703234cc2913757f237ee916087498aklu
10535c08e1173703234cc2913757f237ee916087498aklu**/
10545c08e1173703234cc2913757f237ee916087498akluVOID
10555c08e1173703234cc2913757f237ee916087498akluEFIAPI
10565c08e1173703234cc2913757f237ee916087498akluEnableResetRequired (
10575c08e1173703234cc2913757f237ee916087498aklu  VOID
10585c08e1173703234cc2913757f237ee916087498aklu  )
10595c08e1173703234cc2913757f237ee916087498aklu{
10605c08e1173703234cc2913757f237ee916087498aklu  mResetRequired = TRUE;
10615c08e1173703234cc2913757f237ee916087498aklu}
10625c08e1173703234cc2913757f237ee916087498aklu
10635c08e1173703234cc2913757f237ee916087498aklu
10645c08e1173703234cc2913757f237ee916087498aklu/**
10655c08e1173703234cc2913757f237ee916087498aklu  Record the info that  no reset is required.
10665c08e1173703234cc2913757f237ee916087498aklu  A  module boolean variable is used to record whether a reset is required.
10675c08e1173703234cc2913757f237ee916087498aklu
10685c08e1173703234cc2913757f237ee916087498aklu**/
10695c08e1173703234cc2913757f237ee916087498akluVOID
10705c08e1173703234cc2913757f237ee916087498akluEFIAPI
10715c08e1173703234cc2913757f237ee916087498akluDisableResetRequired (
10725c08e1173703234cc2913757f237ee916087498aklu  VOID
10735c08e1173703234cc2913757f237ee916087498aklu  )
10745c08e1173703234cc2913757f237ee916087498aklu{
10755c08e1173703234cc2913757f237ee916087498aklu  mResetRequired = FALSE;
10765c08e1173703234cc2913757f237ee916087498aklu}
10775c08e1173703234cc2913757f237ee916087498aklu
10785c08e1173703234cc2913757f237ee916087498aklu
10795c08e1173703234cc2913757f237ee916087498aklu/**
10805c08e1173703234cc2913757f237ee916087498aklu  Check whether platform policy enable the reset reminder feature. The default is enabled.
10815c08e1173703234cc2913757f237ee916087498aklu
10825c08e1173703234cc2913757f237ee916087498aklu**/
10835c08e1173703234cc2913757f237ee916087498akluBOOLEAN
10845c08e1173703234cc2913757f237ee916087498akluEFIAPI
10855c08e1173703234cc2913757f237ee916087498akluIsResetReminderFeatureEnable (
10865c08e1173703234cc2913757f237ee916087498aklu  VOID
10875c08e1173703234cc2913757f237ee916087498aklu  )
10885c08e1173703234cc2913757f237ee916087498aklu{
10895c08e1173703234cc2913757f237ee916087498aklu  return mFeaturerSwitch;
10905c08e1173703234cc2913757f237ee916087498aklu}
10915c08e1173703234cc2913757f237ee916087498aklu
10925c08e1173703234cc2913757f237ee916087498aklu
10935c08e1173703234cc2913757f237ee916087498aklu/**
10945c08e1173703234cc2913757f237ee916087498aklu  Check if  user changed any option setting which needs a system reset to be effective.
10955c08e1173703234cc2913757f237ee916087498aklu
10965c08e1173703234cc2913757f237ee916087498aklu**/
10975c08e1173703234cc2913757f237ee916087498akluBOOLEAN
10985c08e1173703234cc2913757f237ee916087498akluEFIAPI
10995c08e1173703234cc2913757f237ee916087498akluIsResetRequired (
11005c08e1173703234cc2913757f237ee916087498aklu  VOID
11015c08e1173703234cc2913757f237ee916087498aklu  )
11025c08e1173703234cc2913757f237ee916087498aklu{
11035c08e1173703234cc2913757f237ee916087498aklu  return mResetRequired;
11045c08e1173703234cc2913757f237ee916087498aklu}
11055c08e1173703234cc2913757f237ee916087498aklu
11065c08e1173703234cc2913757f237ee916087498aklu
11075c08e1173703234cc2913757f237ee916087498aklu/**
11085c08e1173703234cc2913757f237ee916087498aklu  Check whether a reset is needed, and finish the reset reminder feature.
11095c08e1173703234cc2913757f237ee916087498aklu  If a reset is needed, Popup a menu to notice user, and finish the feature
11105c08e1173703234cc2913757f237ee916087498aklu  according to the user selection.
11115c08e1173703234cc2913757f237ee916087498aklu
11125c08e1173703234cc2913757f237ee916087498aklu**/
11135c08e1173703234cc2913757f237ee916087498akluVOID
11145c08e1173703234cc2913757f237ee916087498akluEFIAPI
11155c08e1173703234cc2913757f237ee916087498akluSetupResetReminder (
11165c08e1173703234cc2913757f237ee916087498aklu  VOID
11175c08e1173703234cc2913757f237ee916087498aklu  )
11185c08e1173703234cc2913757f237ee916087498aklu{
11195c08e1173703234cc2913757f237ee916087498aklu  EFI_INPUT_KEY                 Key;
11205c08e1173703234cc2913757f237ee916087498aklu  CHAR16                        *StringBuffer1;
11215c08e1173703234cc2913757f237ee916087498aklu  CHAR16                        *StringBuffer2;
11225c08e1173703234cc2913757f237ee916087498aklu
11235c08e1173703234cc2913757f237ee916087498aklu
11245c08e1173703234cc2913757f237ee916087498aklu  //
11255c08e1173703234cc2913757f237ee916087498aklu  //check any reset required change is applied? if yes, reset system
11265c08e1173703234cc2913757f237ee916087498aklu  //
11275c08e1173703234cc2913757f237ee916087498aklu  if (IsResetReminderFeatureEnable ()) {
11285c08e1173703234cc2913757f237ee916087498aklu    if (IsResetRequired ()) {
11295c08e1173703234cc2913757f237ee916087498aklu
1130885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu      StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
11315c08e1173703234cc2913757f237ee916087498aklu      ASSERT (StringBuffer1 != NULL);
1132885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu      StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
11335c08e1173703234cc2913757f237ee916087498aklu      ASSERT (StringBuffer2 != NULL);
1134885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu      StrCpyS (
1135885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu        StringBuffer1,
1136885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu        MAX_STRING_LEN,
1137885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu        L"Configuration changed. Reset to apply it Now."
1138885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu        );
1139885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu      StrCpyS (
1140885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu        StringBuffer2,
1141885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu        MAX_STRING_LEN,
1142885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu        L"Press ENTER to reset"
1143885c3060c193c9f4c3e3430c82c8c3e8fc574398Hao Wu        );
11445c08e1173703234cc2913757f237ee916087498aklu      //
11455c08e1173703234cc2913757f237ee916087498aklu      // Popup a menu to notice user
11465c08e1173703234cc2913757f237ee916087498aklu      //
11475c08e1173703234cc2913757f237ee916087498aklu      do {
1148e3b236c8eed7aed0227f71e564f843e13f18d803lgao        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
114963588e6106aa37452e386eb8504875cdb7da6139ydong      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
11505c08e1173703234cc2913757f237ee916087498aklu
11515c08e1173703234cc2913757f237ee916087498aklu      FreePool (StringBuffer1);
11525c08e1173703234cc2913757f237ee916087498aklu      FreePool (StringBuffer2);
115363588e6106aa37452e386eb8504875cdb7da6139ydong
115463588e6106aa37452e386eb8504875cdb7da6139ydong      gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
11555c08e1173703234cc2913757f237ee916087498aklu    }
11565c08e1173703234cc2913757f237ee916087498aklu  }
11575c08e1173703234cc2913757f237ee916087498aklu}
11585c08e1173703234cc2913757f237ee916087498aklu
11595c08e1173703234cc2913757f237ee916087498aklu/**
11605c08e1173703234cc2913757f237ee916087498aklu  Get the headers (dos, image, optional header) from an image
11615c08e1173703234cc2913757f237ee916087498aklu
11625c08e1173703234cc2913757f237ee916087498aklu  @param  Device                SimpleFileSystem device handle
11635c08e1173703234cc2913757f237ee916087498aklu  @param  FileName              File name for the image
11645c08e1173703234cc2913757f237ee916087498aklu  @param  DosHeader             Pointer to dos header
11655c08e1173703234cc2913757f237ee916087498aklu  @param  Hdr                   The buffer in which to return the PE32, PE32+, or TE header.
11665c08e1173703234cc2913757f237ee916087498aklu
11675c08e1173703234cc2913757f237ee916087498aklu  @retval EFI_SUCCESS           Successfully get the machine type.
11685c08e1173703234cc2913757f237ee916087498aklu  @retval EFI_NOT_FOUND         The file is not found.
11695c08e1173703234cc2913757f237ee916087498aklu  @retval EFI_LOAD_ERROR        File is not a valid image file.
11705c08e1173703234cc2913757f237ee916087498aklu
11715c08e1173703234cc2913757f237ee916087498aklu**/
11725c08e1173703234cc2913757f237ee916087498akluEFI_STATUS
11735c08e1173703234cc2913757f237ee916087498akluEFIAPI
11745c08e1173703234cc2913757f237ee916087498akluBdsLibGetImageHeader (
11755c08e1173703234cc2913757f237ee916087498aklu  IN  EFI_HANDLE                  Device,
11765c08e1173703234cc2913757f237ee916087498aklu  IN  CHAR16                      *FileName,
11775c08e1173703234cc2913757f237ee916087498aklu  OUT EFI_IMAGE_DOS_HEADER        *DosHeader,
11785c08e1173703234cc2913757f237ee916087498aklu  OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr
11795c08e1173703234cc2913757f237ee916087498aklu  )
11805c08e1173703234cc2913757f237ee916087498aklu{
11815c08e1173703234cc2913757f237ee916087498aklu  EFI_STATUS                       Status;
11825c08e1173703234cc2913757f237ee916087498aklu  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Volume;
11835c08e1173703234cc2913757f237ee916087498aklu  EFI_FILE_HANDLE                  Root;
11845c08e1173703234cc2913757f237ee916087498aklu  EFI_FILE_HANDLE                  ThisFile;
11855c08e1173703234cc2913757f237ee916087498aklu  UINTN                            BufferSize;
11865c08e1173703234cc2913757f237ee916087498aklu  UINT64                           FileSize;
11875c08e1173703234cc2913757f237ee916087498aklu  EFI_FILE_INFO                    *Info;
11885c08e1173703234cc2913757f237ee916087498aklu
11895c08e1173703234cc2913757f237ee916087498aklu  Root     = NULL;
11905c08e1173703234cc2913757f237ee916087498aklu  ThisFile = NULL;
11915c08e1173703234cc2913757f237ee916087498aklu  //
11925c08e1173703234cc2913757f237ee916087498aklu  // Handle the file system interface to the device
11935c08e1173703234cc2913757f237ee916087498aklu  //
11945c08e1173703234cc2913757f237ee916087498aklu  Status = gBS->HandleProtocol (
11955c08e1173703234cc2913757f237ee916087498aklu                  Device,
11965c08e1173703234cc2913757f237ee916087498aklu                  &gEfiSimpleFileSystemProtocolGuid,
11975c08e1173703234cc2913757f237ee916087498aklu                  (VOID *) &Volume
11985c08e1173703234cc2913757f237ee916087498aklu                  );
11995c08e1173703234cc2913757f237ee916087498aklu  if (EFI_ERROR (Status)) {
12005c08e1173703234cc2913757f237ee916087498aklu    goto Done;
12015c08e1173703234cc2913757f237ee916087498aklu  }
12025c08e1173703234cc2913757f237ee916087498aklu
12035c08e1173703234cc2913757f237ee916087498aklu  Status = Volume->OpenVolume (
12045c08e1173703234cc2913757f237ee916087498aklu                     Volume,
12055c08e1173703234cc2913757f237ee916087498aklu                     &Root
12065c08e1173703234cc2913757f237ee916087498aklu                     );
12075c08e1173703234cc2913757f237ee916087498aklu  if (EFI_ERROR (Status)) {
12085c08e1173703234cc2913757f237ee916087498aklu    Root = NULL;
12095c08e1173703234cc2913757f237ee916087498aklu    goto Done;
12105c08e1173703234cc2913757f237ee916087498aklu  }
1211da166a5dbd9fbd560ddf21eedcbffe571281f7c5xli  ASSERT (Root != NULL);
12125c08e1173703234cc2913757f237ee916087498aklu  Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
12135c08e1173703234cc2913757f237ee916087498aklu  if (EFI_ERROR (Status)) {
12145c08e1173703234cc2913757f237ee916087498aklu    goto Done;
12155c08e1173703234cc2913757f237ee916087498aklu  }
1216da166a5dbd9fbd560ddf21eedcbffe571281f7c5xli  ASSERT (ThisFile != NULL);
12175c08e1173703234cc2913757f237ee916087498aklu
12185c08e1173703234cc2913757f237ee916087498aklu  //
12195c08e1173703234cc2913757f237ee916087498aklu  // Get file size
12205c08e1173703234cc2913757f237ee916087498aklu  //
12215c08e1173703234cc2913757f237ee916087498aklu  BufferSize  = SIZE_OF_EFI_FILE_INFO + 200;
12225c08e1173703234cc2913757f237ee916087498aklu  do {
12235c08e1173703234cc2913757f237ee916087498aklu    Info   = NULL;
12245c08e1173703234cc2913757f237ee916087498aklu    Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info);
12255c08e1173703234cc2913757f237ee916087498aklu    if (EFI_ERROR (Status)) {
12265c08e1173703234cc2913757f237ee916087498aklu      goto Done;
12275c08e1173703234cc2913757f237ee916087498aklu    }
12285c08e1173703234cc2913757f237ee916087498aklu    Status = ThisFile->GetInfo (
12295c08e1173703234cc2913757f237ee916087498aklu                         ThisFile,
12305c08e1173703234cc2913757f237ee916087498aklu                         &gEfiFileInfoGuid,
12315c08e1173703234cc2913757f237ee916087498aklu                         &BufferSize,
12325c08e1173703234cc2913757f237ee916087498aklu                         Info
12335c08e1173703234cc2913757f237ee916087498aklu                         );
12345c08e1173703234cc2913757f237ee916087498aklu    if (!EFI_ERROR (Status)) {
12355c08e1173703234cc2913757f237ee916087498aklu      break;
12365c08e1173703234cc2913757f237ee916087498aklu    }
12375c08e1173703234cc2913757f237ee916087498aklu    if (Status != EFI_BUFFER_TOO_SMALL) {
12385c08e1173703234cc2913757f237ee916087498aklu      FreePool (Info);
12395c08e1173703234cc2913757f237ee916087498aklu      goto Done;
12405c08e1173703234cc2913757f237ee916087498aklu    }
12415c08e1173703234cc2913757f237ee916087498aklu    FreePool (Info);
12425c08e1173703234cc2913757f237ee916087498aklu  } while (TRUE);
12435c08e1173703234cc2913757f237ee916087498aklu
12445c08e1173703234cc2913757f237ee916087498aklu  FileSize = Info->FileSize;
12455c08e1173703234cc2913757f237ee916087498aklu  FreePool (Info);
12465c08e1173703234cc2913757f237ee916087498aklu
12475c08e1173703234cc2913757f237ee916087498aklu  //
12485c08e1173703234cc2913757f237ee916087498aklu  // Read dos header
12495c08e1173703234cc2913757f237ee916087498aklu  //
12505c08e1173703234cc2913757f237ee916087498aklu  BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);
12515c08e1173703234cc2913757f237ee916087498aklu  Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader);
12525c08e1173703234cc2913757f237ee916087498aklu  if (EFI_ERROR (Status) ||
12535c08e1173703234cc2913757f237ee916087498aklu      BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) ||
12545c08e1173703234cc2913757f237ee916087498aklu      FileSize <= DosHeader->e_lfanew ||
12555c08e1173703234cc2913757f237ee916087498aklu      DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
12565c08e1173703234cc2913757f237ee916087498aklu    Status = EFI_LOAD_ERROR;
12575c08e1173703234cc2913757f237ee916087498aklu    goto Done;
12585c08e1173703234cc2913757f237ee916087498aklu  }
12595c08e1173703234cc2913757f237ee916087498aklu
12605c08e1173703234cc2913757f237ee916087498aklu  //
12615c08e1173703234cc2913757f237ee916087498aklu  // Move to PE signature
12625c08e1173703234cc2913757f237ee916087498aklu  //
12635c08e1173703234cc2913757f237ee916087498aklu  Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew);
12645c08e1173703234cc2913757f237ee916087498aklu  if (EFI_ERROR (Status)) {
12655c08e1173703234cc2913757f237ee916087498aklu    Status = EFI_LOAD_ERROR;
12665c08e1173703234cc2913757f237ee916087498aklu    goto Done;
12675c08e1173703234cc2913757f237ee916087498aklu  }
12685c08e1173703234cc2913757f237ee916087498aklu
12695c08e1173703234cc2913757f237ee916087498aklu  //
12705c08e1173703234cc2913757f237ee916087498aklu  // Read and check PE signature
12715c08e1173703234cc2913757f237ee916087498aklu  //
12725c08e1173703234cc2913757f237ee916087498aklu  BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
12735c08e1173703234cc2913757f237ee916087498aklu  Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32);
12745c08e1173703234cc2913757f237ee916087498aklu  if (EFI_ERROR (Status) ||
12755c08e1173703234cc2913757f237ee916087498aklu      BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) ||
12765c08e1173703234cc2913757f237ee916087498aklu      Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
12775c08e1173703234cc2913757f237ee916087498aklu    Status = EFI_LOAD_ERROR;
12785c08e1173703234cc2913757f237ee916087498aklu    goto Done;
12795c08e1173703234cc2913757f237ee916087498aklu  }
12805c08e1173703234cc2913757f237ee916087498aklu
12815c08e1173703234cc2913757f237ee916087498aklu  //
12825c08e1173703234cc2913757f237ee916087498aklu  // Check PE32 or PE32+ magic
12835c08e1173703234cc2913757f237ee916087498aklu  //
12845c08e1173703234cc2913757f237ee916087498aklu  if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
12855c08e1173703234cc2913757f237ee916087498aklu      Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
12865c08e1173703234cc2913757f237ee916087498aklu    Status = EFI_LOAD_ERROR;
12875c08e1173703234cc2913757f237ee916087498aklu    goto Done;
12885c08e1173703234cc2913757f237ee916087498aklu  }
12895c08e1173703234cc2913757f237ee916087498aklu
12905c08e1173703234cc2913757f237ee916087498aklu Done:
12915c08e1173703234cc2913757f237ee916087498aklu  if (ThisFile != NULL) {
12925c08e1173703234cc2913757f237ee916087498aklu    ThisFile->Close (ThisFile);
12935c08e1173703234cc2913757f237ee916087498aklu  }
12945c08e1173703234cc2913757f237ee916087498aklu  if (Root != NULL) {
12955c08e1173703234cc2913757f237ee916087498aklu    Root->Close (Root);
12965c08e1173703234cc2913757f237ee916087498aklu  }
12975c08e1173703234cc2913757f237ee916087498aklu  return Status;
12985c08e1173703234cc2913757f237ee916087498aklu}
12995c08e1173703234cc2913757f237ee916087498aklu
13005c08e1173703234cc2913757f237ee916087498aklu/**
13013999f1feef2134f1bb7dc6f89dcb01e49765b392niruiyu  This routine adjust the memory information for different memory type and
13023999f1feef2134f1bb7dc6f89dcb01e49765b392niruiyu  save them into the variables for next boot.
13035c08e1173703234cc2913757f237ee916087498aklu**/
13045c08e1173703234cc2913757f237ee916087498akluVOID
13055c08e1173703234cc2913757f237ee916087498akluBdsSetMemoryTypeInformationVariable (
13067caf72a907ef9b71e7c8f1c27c5b4eda98225689niruiyu  VOID
13075c08e1173703234cc2913757f237ee916087498aklu  )
13085c08e1173703234cc2913757f237ee916087498aklu{
13095c08e1173703234cc2913757f237ee916087498aklu  EFI_STATUS                   Status;
13105c08e1173703234cc2913757f237ee916087498aklu  EFI_MEMORY_TYPE_INFORMATION  *PreviousMemoryTypeInformation;
13115c08e1173703234cc2913757f237ee916087498aklu  EFI_MEMORY_TYPE_INFORMATION  *CurrentMemoryTypeInformation;
13125c08e1173703234cc2913757f237ee916087498aklu  UINTN                        VariableSize;
13135c08e1173703234cc2913757f237ee916087498aklu  UINTN                        Index;
13145c08e1173703234cc2913757f237ee916087498aklu  UINTN                        Index1;
13155c08e1173703234cc2913757f237ee916087498aklu  UINT32                       Previous;
13165c08e1173703234cc2913757f237ee916087498aklu  UINT32                       Current;
13175c08e1173703234cc2913757f237ee916087498aklu  UINT32                       Next;
13185c08e1173703234cc2913757f237ee916087498aklu  EFI_HOB_GUID_TYPE            *GuidHob;
13197bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu  BOOLEAN                      MemoryTypeInformationModified;
1320a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney  BOOLEAN                      MemoryTypeInformationVariableExists;
13218c716296fac241627e9e5ad5ed64f73b18447978erictian  EFI_BOOT_MODE                BootMode;
1322a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney
13237bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu  MemoryTypeInformationModified       = FALSE;
1324a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney  MemoryTypeInformationVariableExists = FALSE;
1325a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney
13268c716296fac241627e9e5ad5ed64f73b18447978erictian
13278c716296fac241627e9e5ad5ed64f73b18447978erictian  BootMode = GetBootModeHob ();
13288c716296fac241627e9e5ad5ed64f73b18447978erictian  //
13298c716296fac241627e9e5ad5ed64f73b18447978erictian  // In BOOT_IN_RECOVERY_MODE, Variable region is not reliable.
13308c716296fac241627e9e5ad5ed64f73b18447978erictian  //
13318c716296fac241627e9e5ad5ed64f73b18447978erictian  if (BootMode == BOOT_IN_RECOVERY_MODE) {
13328c716296fac241627e9e5ad5ed64f73b18447978erictian    return;
13338c716296fac241627e9e5ad5ed64f73b18447978erictian  }
13348c716296fac241627e9e5ad5ed64f73b18447978erictian
13357bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu  //
1336a97a859621e2f480b4cd12e32162ac60305ede22niruiyu  // Only check the the Memory Type Information variable in the boot mode
13377bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu  // other than BOOT_WITH_DEFAULT_SETTINGS because the Memory Type
13387bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu  // Information is not valid in this boot mode.
13397bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu  //
13408c716296fac241627e9e5ad5ed64f73b18447978erictian  if (BootMode != BOOT_WITH_DEFAULT_SETTINGS) {
1341a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney    VariableSize = 0;
1342a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney    Status = gRT->GetVariable (
1343a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney                    EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
1344a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney                    &gEfiMemoryTypeInformationGuid,
1345a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney                    NULL,
1346a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney                    &VariableSize,
1347a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney                    NULL
1348a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney                    );
1349a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney    if (Status == EFI_BUFFER_TOO_SMALL) {
1350a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney      MemoryTypeInformationVariableExists = TRUE;
1351a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney    }
1352a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney  }
13535c08e1173703234cc2913757f237ee916087498aklu
13545c08e1173703234cc2913757f237ee916087498aklu  //
13555c08e1173703234cc2913757f237ee916087498aklu  // Retrieve the current memory usage statistics.  If they are not found, then
13565c08e1173703234cc2913757f237ee916087498aklu  // no adjustments can be made to the Memory Type Information variable.
13575c08e1173703234cc2913757f237ee916087498aklu  //
13585c08e1173703234cc2913757f237ee916087498aklu  Status = EfiGetSystemConfigurationTable (
13595c08e1173703234cc2913757f237ee916087498aklu             &gEfiMemoryTypeInformationGuid,
13605c08e1173703234cc2913757f237ee916087498aklu             (VOID **) &CurrentMemoryTypeInformation
13615c08e1173703234cc2913757f237ee916087498aklu             );
13625c08e1173703234cc2913757f237ee916087498aklu  if (EFI_ERROR (Status) || CurrentMemoryTypeInformation == NULL) {
13635c08e1173703234cc2913757f237ee916087498aklu    return;
13645c08e1173703234cc2913757f237ee916087498aklu  }
13655c08e1173703234cc2913757f237ee916087498aklu
13665c08e1173703234cc2913757f237ee916087498aklu  //
13675c08e1173703234cc2913757f237ee916087498aklu  // Get the Memory Type Information settings from Hob if they exist,
13685c08e1173703234cc2913757f237ee916087498aklu  // PEI is responsible for getting them from variable and build a Hob to save them.
13695c08e1173703234cc2913757f237ee916087498aklu  // If the previous Memory Type Information is not available, then set defaults
13705c08e1173703234cc2913757f237ee916087498aklu  //
13715c08e1173703234cc2913757f237ee916087498aklu  GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid);
13725c08e1173703234cc2913757f237ee916087498aklu  if (GuidHob == NULL) {
13735c08e1173703234cc2913757f237ee916087498aklu    //
13745c08e1173703234cc2913757f237ee916087498aklu    // If Platform has not built Memory Type Info into the Hob, just return.
13755c08e1173703234cc2913757f237ee916087498aklu    //
13765c08e1173703234cc2913757f237ee916087498aklu    return;
13775c08e1173703234cc2913757f237ee916087498aklu  }
13785c08e1173703234cc2913757f237ee916087498aklu  PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob);
13795c08e1173703234cc2913757f237ee916087498aklu  VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
13805c08e1173703234cc2913757f237ee916087498aklu
13815c08e1173703234cc2913757f237ee916087498aklu  //
13825c08e1173703234cc2913757f237ee916087498aklu  // Use a heuristic to adjust the Memory Type Information for the next boot
13835c08e1173703234cc2913757f237ee916087498aklu  //
1384a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney  DEBUG ((EFI_D_INFO, "Memory  Previous  Current    Next   \n"));
1385a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney  DEBUG ((EFI_D_INFO, " Type    Pages     Pages     Pages  \n"));
1386a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney  DEBUG ((EFI_D_INFO, "======  ========  ========  ========\n"));
1387a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney
13885c08e1173703234cc2913757f237ee916087498aklu  for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {
13895c08e1173703234cc2913757f237ee916087498aklu
13905c08e1173703234cc2913757f237ee916087498aklu    for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) {
13915c08e1173703234cc2913757f237ee916087498aklu      if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) {
13925c08e1173703234cc2913757f237ee916087498aklu        break;
13935c08e1173703234cc2913757f237ee916087498aklu      }
13945c08e1173703234cc2913757f237ee916087498aklu    }
13955c08e1173703234cc2913757f237ee916087498aklu    if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) {
13965c08e1173703234cc2913757f237ee916087498aklu      continue;
13975c08e1173703234cc2913757f237ee916087498aklu    }
13985c08e1173703234cc2913757f237ee916087498aklu
1399a97a859621e2f480b4cd12e32162ac60305ede22niruiyu    //
1400a97a859621e2f480b4cd12e32162ac60305ede22niruiyu    // Previous is the number of pages pre-allocated
1401a97a859621e2f480b4cd12e32162ac60305ede22niruiyu    // Current is the number of pages actually needed
1402a97a859621e2f480b4cd12e32162ac60305ede22niruiyu    //
14035c08e1173703234cc2913757f237ee916087498aklu    Previous = PreviousMemoryTypeInformation[Index].NumberOfPages;
1404a97a859621e2f480b4cd12e32162ac60305ede22niruiyu    Current  = CurrentMemoryTypeInformation[Index1].NumberOfPages;
1405a97a859621e2f480b4cd12e32162ac60305ede22niruiyu    Next     = Previous;
14065c08e1173703234cc2913757f237ee916087498aklu
14075c08e1173703234cc2913757f237ee916087498aklu    //
14083999f1feef2134f1bb7dc6f89dcb01e49765b392niruiyu    // Inconsistent Memory Reserved across bootings may lead to S4 fail
14093999f1feef2134f1bb7dc6f89dcb01e49765b392niruiyu    // Write next varible to 125% * current when the pre-allocated memory is:
14103999f1feef2134f1bb7dc6f89dcb01e49765b392niruiyu    //  1. More than 150% of needed memory and boot mode is BOOT_WITH_DEFAULT_SETTING
14113999f1feef2134f1bb7dc6f89dcb01e49765b392niruiyu    //  2. Less than the needed memory
14125c08e1173703234cc2913757f237ee916087498aklu    //
14133999f1feef2134f1bb7dc6f89dcb01e49765b392niruiyu    if ((Current + (Current >> 1)) < Previous) {
1414a97a859621e2f480b4cd12e32162ac60305ede22niruiyu      if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
1415a97a859621e2f480b4cd12e32162ac60305ede22niruiyu        Next = Current + (Current >> 2);
1416a97a859621e2f480b4cd12e32162ac60305ede22niruiyu      }
1417a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney    } else if (Current > Previous) {
14185c08e1173703234cc2913757f237ee916087498aklu      Next = Current + (Current >> 2);
14195c08e1173703234cc2913757f237ee916087498aklu    }
14205c08e1173703234cc2913757f237ee916087498aklu    if (Next > 0 && Next < 4) {
14215c08e1173703234cc2913757f237ee916087498aklu      Next = 4;
14225c08e1173703234cc2913757f237ee916087498aklu    }
14235c08e1173703234cc2913757f237ee916087498aklu
14245c08e1173703234cc2913757f237ee916087498aklu    if (Next != Previous) {
14255c08e1173703234cc2913757f237ee916087498aklu      PreviousMemoryTypeInformation[Index].NumberOfPages = Next;
14267bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu      MemoryTypeInformationModified = TRUE;
14275c08e1173703234cc2913757f237ee916087498aklu    }
14285c08e1173703234cc2913757f237ee916087498aklu
1429a4e9b4f6e3a06ab21c434787714ce5fa5755492bmdkinney    DEBUG ((EFI_D_INFO, "  %02x    %08x  %08x  %08x\n", PreviousMemoryTypeInformation[Index].Type, Previous, Current, Next));
14305c08e1173703234cc2913757f237ee916087498aklu  }
14315c08e1173703234cc2913757f237ee916087498aklu
14325c08e1173703234cc2913757f237ee916087498aklu  //
14337bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu  // If any changes were made to the Memory Type Information settings, then set the new variable value;
14347bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu  // Or create the variable in first boot.
14355c08e1173703234cc2913757f237ee916087498aklu  //
14367bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu  if (MemoryTypeInformationModified || !MemoryTypeInformationVariableExists) {
143769fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni    Status = SetVariableAndReportStatusCodeOnError (
143869fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni               EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
143969fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni               &gEfiMemoryTypeInformationGuid,
144069fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni               EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS,
144169fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni               VariableSize,
144269fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni               PreviousMemoryTypeInformation
144369fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni               );
14447bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu
1445e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni    if (!EFI_ERROR (Status)) {
1446e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni      //
1447e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni      // If the Memory Type Information settings have been modified, then reset the platform
1448e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni      // so the new Memory Type Information setting will be used to guarantee that an S4
1449e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni      // entry/resume cycle will not fail.
1450e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni      //
1451e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni      if (MemoryTypeInformationModified && PcdGetBool (PcdResetOnMemoryTypeInformationChange)) {
1452e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni        DEBUG ((EFI_D_INFO, "Memory Type Information settings change. Warm Reset!!!\n"));
1453e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni        gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
1454e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni      }
1455e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni    } else {
1456e609aef97a174455a79f339b15f83713b99e3b03Ruiyu Ni      DEBUG ((EFI_D_ERROR, "Memory Type Information settings cannot be saved. OS S4 may fail!\n"));
14577bee5a761f4cbafd1e1805dfd99255a0353bbf88niruiyu    }
14585c08e1173703234cc2913757f237ee916087498aklu  }
14595c08e1173703234cc2913757f237ee916087498aklu}
14605c08e1173703234cc2913757f237ee916087498aklu
14615c08e1173703234cc2913757f237ee916087498aklu/**
14627caf72a907ef9b71e7c8f1c27c5b4eda98225689niruiyu  This routine is kept for backward compatibility.
14635c08e1173703234cc2913757f237ee916087498aklu**/
14645c08e1173703234cc2913757f237ee916087498akluVOID
14655c08e1173703234cc2913757f237ee916087498akluEFIAPI
14665c08e1173703234cc2913757f237ee916087498akluBdsLibSaveMemoryTypeInformation (
14675c08e1173703234cc2913757f237ee916087498aklu  VOID
14685c08e1173703234cc2913757f237ee916087498aklu  )
14695c08e1173703234cc2913757f237ee916087498aklu{
14705c08e1173703234cc2913757f237ee916087498aklu}
14715c08e1173703234cc2913757f237ee916087498aklu
14725c08e1173703234cc2913757f237ee916087498aklu
1473337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong/**
1474337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  Identify a user and, if authenticated, returns the current user profile handle.
1475337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong
1476337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  @param[out]  User           Point to user profile handle.
1477337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong
1478337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  @retval EFI_SUCCESS         User is successfully identified, or user identification
1479337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong                              is not supported.
1480337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  @retval EFI_ACCESS_DENIED   User is not successfully identified
1481337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong
1482337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong**/
1483337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdongEFI_STATUS
1484337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdongEFIAPI
1485337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdongBdsLibUserIdentify (
1486337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  OUT EFI_USER_PROFILE_HANDLE         *User
1487337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  )
1488337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong{
1489337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  EFI_STATUS                          Status;
1490337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  EFI_USER_MANAGER_PROTOCOL           *Manager;
1491337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong
1492337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  Status = gBS->LocateProtocol (
1493337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong                  &gEfiUserManagerProtocolGuid,
1494337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong                  NULL,
1495337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong                  (VOID **) &Manager
1496337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong                  );
1497337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  if (EFI_ERROR (Status)) {
1498337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong    return EFI_SUCCESS;
1499337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  }
1500337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong
1501337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong  return Manager->Identify (Manager, User);
1502337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong}
1503337661bb8c981400d3a0c93d0d49a65f2e4eed8cgdong
150469fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni/**
150569fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  Set the variable and report the error through status code upon failure.
150669fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni
150769fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @param  VariableName           A Null-terminated string that is the name of the vendor's variable.
150869fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 Each VariableName is unique for each VendorGuid. VariableName must
150969fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 contain 1 or more characters. If VariableName is an empty string,
151069fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 then EFI_INVALID_PARAMETER is returned.
151169fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @param  VendorGuid             A unique identifier for the vendor.
151269fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @param  Attributes             Attributes bitmask to set for the variable.
151369fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @param  DataSize               The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
151469fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or
151569fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
151669fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
151769fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 set, then a SetVariable() call with a DataSize of zero will not cause any change to
151869fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 the variable value (the timestamp associated with the variable may be updated however
151969fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 even if no new data value is provided,see the description of the
152069fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
152169fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
152269fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @param  Data                   The contents for the variable.
152369fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni
152469fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @retval EFI_SUCCESS            The firmware has successfully stored the variable and its data as
152569fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 defined by the Attributes.
152669fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @retval EFI_INVALID_PARAMETER  An invalid combination of attribute bits, name, and GUID was supplied, or the
152769fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 DataSize exceeds the maximum allowed.
152869fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
152969fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
153069fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
153169fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
153269fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @retval EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
153369fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
153469fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo
153569fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                                 does NOT pass the validation check carried out by the firmware.
153669fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni
153769fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  @retval EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
153869fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni**/
153969fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu NiEFI_STATUS
154069fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu NiSetVariableAndReportStatusCodeOnError (
154169fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  IN CHAR16     *VariableName,
154269fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  IN EFI_GUID   *VendorGuid,
154369fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  IN UINT32     Attributes,
154469fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  IN UINTN      DataSize,
154569fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  IN VOID       *Data
154669fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  )
154769fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni{
154869fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  EFI_STATUS                 Status;
154969fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  EDKII_SET_VARIABLE_STATUS  *SetVariableStatus;
155069fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  UINTN                      NameSize;
155169fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni
155269fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  Status = gRT->SetVariable (
155369fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                  VariableName,
155469fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                  VendorGuid,
155569fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                  Attributes,
155669fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                  DataSize,
155769fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                  Data
155869fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni                  );
155969fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  if (EFI_ERROR (Status)) {
156069fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni    NameSize = StrSize (VariableName);
156169fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni    SetVariableStatus = AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize);
156269fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni    if (SetVariableStatus != NULL) {
156369fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni      CopyGuid (&SetVariableStatus->Guid, VendorGuid);
156469fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni      SetVariableStatus->NameSize   = NameSize;
156569fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni      SetVariableStatus->DataSize   = DataSize;
156669fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni      SetVariableStatus->SetStatus  = Status;
156769fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni      SetVariableStatus->Attributes = Attributes;
156869fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni      CopyMem (SetVariableStatus + 1,                          VariableName, NameSize);
1569c4571f04794154d405a69b79babfd74bcf9fc63aRuiyu Ni      if ((Data != NULL) && (DataSize != 0)) {
1570c4571f04794154d405a69b79babfd74bcf9fc63aRuiyu Ni        CopyMem (((UINT8 *) (SetVariableStatus + 1)) + NameSize, Data,         DataSize);
1571c4571f04794154d405a69b79babfd74bcf9fc63aRuiyu Ni      }
157269fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni
157369fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni      REPORT_STATUS_CODE_EX (
157469fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni        EFI_ERROR_CODE,
157569fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni        PcdGet32 (PcdErrorCodeSetVariable),
157669fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni        0,
157769fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni        NULL,
157869fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni        &gEdkiiStatusCodeDataTypeVariableGuid,
157969fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni        SetVariableStatus,
158069fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni        sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize
158169fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni        );
158269fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni
158369fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni      FreePool (SetVariableStatus);
158469fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni    }
158569fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  }
158669fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni
158769fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni  return Status;
158869fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni}
158969fc8f080e07ea026e8fbb8610cfb89c099d6db2Ruiyu Ni
1590