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