BdsMisc.c revision 5c08e1173703234cc2913757f237ee916087498a
15c08e1173703234cc2913757f237ee916087498aklu/** @file 25c08e1173703234cc2913757f237ee916087498aklu Misc BDS library function 35c08e1173703234cc2913757f237ee916087498aklu 45c08e1173703234cc2913757f237ee916087498akluCopyright (c) 2004 - 2008, Intel Corporation. <BR> 55c08e1173703234cc2913757f237ee916087498akluAll rights reserved. This 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/** 275c08e1173703234cc2913757f237ee916087498aklu Return the default value for system Timeout variable. 285c08e1173703234cc2913757f237ee916087498aklu 295c08e1173703234cc2913757f237ee916087498aklu @return Timeout value. 305c08e1173703234cc2913757f237ee916087498aklu 315c08e1173703234cc2913757f237ee916087498aklu**/ 325c08e1173703234cc2913757f237ee916087498akluUINT16 335c08e1173703234cc2913757f237ee916087498akluEFIAPI 345c08e1173703234cc2913757f237ee916087498akluBdsLibGetTimeout ( 355c08e1173703234cc2913757f237ee916087498aklu VOID 365c08e1173703234cc2913757f237ee916087498aklu ) 375c08e1173703234cc2913757f237ee916087498aklu{ 385c08e1173703234cc2913757f237ee916087498aklu UINT16 Timeout; 395c08e1173703234cc2913757f237ee916087498aklu UINTN Size; 405c08e1173703234cc2913757f237ee916087498aklu EFI_STATUS Status; 415c08e1173703234cc2913757f237ee916087498aklu 425c08e1173703234cc2913757f237ee916087498aklu // 435c08e1173703234cc2913757f237ee916087498aklu // Return Timeout variable or 0xffff if no valid 445c08e1173703234cc2913757f237ee916087498aklu // Timeout variable exists. 455c08e1173703234cc2913757f237ee916087498aklu // 465c08e1173703234cc2913757f237ee916087498aklu Size = sizeof (UINT16); 475c08e1173703234cc2913757f237ee916087498aklu Status = gRT->GetVariable (L"Timeout", &gEfiGlobalVariableGuid, NULL, &Size, &Timeout); 485c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status)) { 495c08e1173703234cc2913757f237ee916087498aklu // 505c08e1173703234cc2913757f237ee916087498aklu // According to UEFI 2.0 spec, it should treat the Timeout value as 0xffff 515c08e1173703234cc2913757f237ee916087498aklu // (default value PcdPlatformBootTimeOutDefault) when L"Timeout" variable is not present. 525c08e1173703234cc2913757f237ee916087498aklu // To make the current EFI Automatic-Test activity possible, platform can choose other value 535c08e1173703234cc2913757f237ee916087498aklu // for automatic boot when the variable is not present. 545c08e1173703234cc2913757f237ee916087498aklu // 555c08e1173703234cc2913757f237ee916087498aklu Timeout = PcdGet16 (PcdPlatformBootTimeOutDefault); 565c08e1173703234cc2913757f237ee916087498aklu } 575c08e1173703234cc2913757f237ee916087498aklu 585c08e1173703234cc2913757f237ee916087498aklu return Timeout; 595c08e1173703234cc2913757f237ee916087498aklu} 605c08e1173703234cc2913757f237ee916087498aklu 615c08e1173703234cc2913757f237ee916087498aklu/** 625c08e1173703234cc2913757f237ee916087498aklu The function will go through the driver option link list, load and start 635c08e1173703234cc2913757f237ee916087498aklu every driver the driver option device path point to. 645c08e1173703234cc2913757f237ee916087498aklu 655c08e1173703234cc2913757f237ee916087498aklu @param BdsDriverLists The header of the current driver option link list 665c08e1173703234cc2913757f237ee916087498aklu 675c08e1173703234cc2913757f237ee916087498aklu**/ 685c08e1173703234cc2913757f237ee916087498akluVOID 695c08e1173703234cc2913757f237ee916087498akluEFIAPI 705c08e1173703234cc2913757f237ee916087498akluBdsLibLoadDrivers ( 715c08e1173703234cc2913757f237ee916087498aklu IN LIST_ENTRY *BdsDriverLists 725c08e1173703234cc2913757f237ee916087498aklu ) 735c08e1173703234cc2913757f237ee916087498aklu{ 745c08e1173703234cc2913757f237ee916087498aklu EFI_STATUS Status; 755c08e1173703234cc2913757f237ee916087498aklu LIST_ENTRY *Link; 765c08e1173703234cc2913757f237ee916087498aklu BDS_COMMON_OPTION *Option; 775c08e1173703234cc2913757f237ee916087498aklu EFI_HANDLE ImageHandle; 785c08e1173703234cc2913757f237ee916087498aklu EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; 795c08e1173703234cc2913757f237ee916087498aklu UINTN ExitDataSize; 805c08e1173703234cc2913757f237ee916087498aklu CHAR16 *ExitData; 815c08e1173703234cc2913757f237ee916087498aklu BOOLEAN ReconnectAll; 825c08e1173703234cc2913757f237ee916087498aklu 835c08e1173703234cc2913757f237ee916087498aklu ReconnectAll = FALSE; 845c08e1173703234cc2913757f237ee916087498aklu 855c08e1173703234cc2913757f237ee916087498aklu // 865c08e1173703234cc2913757f237ee916087498aklu // Process the driver option 875c08e1173703234cc2913757f237ee916087498aklu // 885c08e1173703234cc2913757f237ee916087498aklu for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link->ForwardLink) { 895c08e1173703234cc2913757f237ee916087498aklu Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE); 905c08e1173703234cc2913757f237ee916087498aklu 915c08e1173703234cc2913757f237ee916087498aklu // 925c08e1173703234cc2913757f237ee916087498aklu // If a load option is not marked as LOAD_OPTION_ACTIVE, 935c08e1173703234cc2913757f237ee916087498aklu // the boot manager will not automatically load the option. 945c08e1173703234cc2913757f237ee916087498aklu // 955c08e1173703234cc2913757f237ee916087498aklu if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE)) { 965c08e1173703234cc2913757f237ee916087498aklu continue; 975c08e1173703234cc2913757f237ee916087498aklu } 985c08e1173703234cc2913757f237ee916087498aklu 995c08e1173703234cc2913757f237ee916087498aklu // 1005c08e1173703234cc2913757f237ee916087498aklu // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT, 1015c08e1173703234cc2913757f237ee916087498aklu // then all of the EFI drivers in the system will be disconnected and 1025c08e1173703234cc2913757f237ee916087498aklu // reconnected after the last driver load option is processed. 1035c08e1173703234cc2913757f237ee916087498aklu // 1045c08e1173703234cc2913757f237ee916087498aklu if (IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_FORCE_RECONNECT)) { 1055c08e1173703234cc2913757f237ee916087498aklu ReconnectAll = TRUE; 1065c08e1173703234cc2913757f237ee916087498aklu } 1075c08e1173703234cc2913757f237ee916087498aklu 1085c08e1173703234cc2913757f237ee916087498aklu // 1095c08e1173703234cc2913757f237ee916087498aklu // Make sure the driver path is connected. 1105c08e1173703234cc2913757f237ee916087498aklu // 1115c08e1173703234cc2913757f237ee916087498aklu BdsLibConnectDevicePath (Option->DevicePath); 1125c08e1173703234cc2913757f237ee916087498aklu 1135c08e1173703234cc2913757f237ee916087498aklu // 1145c08e1173703234cc2913757f237ee916087498aklu // Load and start the image that Driver#### describes 1155c08e1173703234cc2913757f237ee916087498aklu // 1165c08e1173703234cc2913757f237ee916087498aklu Status = gBS->LoadImage ( 1175c08e1173703234cc2913757f237ee916087498aklu FALSE, 1185c08e1173703234cc2913757f237ee916087498aklu mBdsImageHandle, 1195c08e1173703234cc2913757f237ee916087498aklu Option->DevicePath, 1205c08e1173703234cc2913757f237ee916087498aklu NULL, 1215c08e1173703234cc2913757f237ee916087498aklu 0, 1225c08e1173703234cc2913757f237ee916087498aklu &ImageHandle 1235c08e1173703234cc2913757f237ee916087498aklu ); 1245c08e1173703234cc2913757f237ee916087498aklu 1255c08e1173703234cc2913757f237ee916087498aklu if (!EFI_ERROR (Status)) { 1265c08e1173703234cc2913757f237ee916087498aklu gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo); 1275c08e1173703234cc2913757f237ee916087498aklu 1285c08e1173703234cc2913757f237ee916087498aklu // 1295c08e1173703234cc2913757f237ee916087498aklu // Verify whether this image is a driver, if not, 1305c08e1173703234cc2913757f237ee916087498aklu // exit it and continue to parse next load option 1315c08e1173703234cc2913757f237ee916087498aklu // 1325c08e1173703234cc2913757f237ee916087498aklu if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) { 1335c08e1173703234cc2913757f237ee916087498aklu gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL); 1345c08e1173703234cc2913757f237ee916087498aklu continue; 1355c08e1173703234cc2913757f237ee916087498aklu } 1365c08e1173703234cc2913757f237ee916087498aklu 1375c08e1173703234cc2913757f237ee916087498aklu if (Option->LoadOptionsSize != 0) { 1385c08e1173703234cc2913757f237ee916087498aklu ImageInfo->LoadOptionsSize = Option->LoadOptionsSize; 1395c08e1173703234cc2913757f237ee916087498aklu ImageInfo->LoadOptions = Option->LoadOptions; 1405c08e1173703234cc2913757f237ee916087498aklu } 1415c08e1173703234cc2913757f237ee916087498aklu // 1425c08e1173703234cc2913757f237ee916087498aklu // Before calling the image, enable the Watchdog Timer for 1435c08e1173703234cc2913757f237ee916087498aklu // the 5 Minute period 1445c08e1173703234cc2913757f237ee916087498aklu // 1455c08e1173703234cc2913757f237ee916087498aklu gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL); 1465c08e1173703234cc2913757f237ee916087498aklu 1475c08e1173703234cc2913757f237ee916087498aklu Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData); 1485c08e1173703234cc2913757f237ee916087498aklu DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Driver Return Status = %r\n", Status)); 1495c08e1173703234cc2913757f237ee916087498aklu 1505c08e1173703234cc2913757f237ee916087498aklu // 1515c08e1173703234cc2913757f237ee916087498aklu // Clear the Watchdog Timer after the image returns 1525c08e1173703234cc2913757f237ee916087498aklu // 1535c08e1173703234cc2913757f237ee916087498aklu gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); 1545c08e1173703234cc2913757f237ee916087498aklu } 1555c08e1173703234cc2913757f237ee916087498aklu } 1565c08e1173703234cc2913757f237ee916087498aklu 1575c08e1173703234cc2913757f237ee916087498aklu // 1585c08e1173703234cc2913757f237ee916087498aklu // Process the LOAD_OPTION_FORCE_RECONNECT driver option 1595c08e1173703234cc2913757f237ee916087498aklu // 1605c08e1173703234cc2913757f237ee916087498aklu if (ReconnectAll) { 1615c08e1173703234cc2913757f237ee916087498aklu BdsLibDisconnectAllEfi (); 1625c08e1173703234cc2913757f237ee916087498aklu BdsLibConnectAll (); 1635c08e1173703234cc2913757f237ee916087498aklu } 1645c08e1173703234cc2913757f237ee916087498aklu 1655c08e1173703234cc2913757f237ee916087498aklu} 1665c08e1173703234cc2913757f237ee916087498aklu 1675c08e1173703234cc2913757f237ee916087498aklu/** 1685c08e1173703234cc2913757f237ee916087498aklu Get the Option Number that does not used. 1695c08e1173703234cc2913757f237ee916087498aklu Try to locate the specific option variable one by one utile find a free number. 1705c08e1173703234cc2913757f237ee916087498aklu 1715c08e1173703234cc2913757f237ee916087498aklu @param VariableName Indicate if the boot#### or driver#### option 1725c08e1173703234cc2913757f237ee916087498aklu 1735c08e1173703234cc2913757f237ee916087498aklu @return The Minimal Free Option Number 1745c08e1173703234cc2913757f237ee916087498aklu 1755c08e1173703234cc2913757f237ee916087498aklu**/ 1765c08e1173703234cc2913757f237ee916087498akluUINT16 1775c08e1173703234cc2913757f237ee916087498akluBdsLibGetFreeOptionNumber ( 1785c08e1173703234cc2913757f237ee916087498aklu IN CHAR16 *VariableName 1795c08e1173703234cc2913757f237ee916087498aklu ) 1805c08e1173703234cc2913757f237ee916087498aklu{ 1815c08e1173703234cc2913757f237ee916087498aklu UINTN Index; 1825c08e1173703234cc2913757f237ee916087498aklu CHAR16 StrTemp[10]; 1835c08e1173703234cc2913757f237ee916087498aklu UINT16 *OptionBuffer; 1845c08e1173703234cc2913757f237ee916087498aklu UINTN OptionSize; 1855c08e1173703234cc2913757f237ee916087498aklu 1865c08e1173703234cc2913757f237ee916087498aklu // 1875c08e1173703234cc2913757f237ee916087498aklu // Try to find the minimum free number from 0, 1, 2, 3.... 1885c08e1173703234cc2913757f237ee916087498aklu // 1895c08e1173703234cc2913757f237ee916087498aklu Index = 0; 1905c08e1173703234cc2913757f237ee916087498aklu do { 1915c08e1173703234cc2913757f237ee916087498aklu if (*VariableName == 'B') { 1925c08e1173703234cc2913757f237ee916087498aklu UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index); 1935c08e1173703234cc2913757f237ee916087498aklu } else { 1945c08e1173703234cc2913757f237ee916087498aklu UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Driver%04x", Index); 1955c08e1173703234cc2913757f237ee916087498aklu } 1965c08e1173703234cc2913757f237ee916087498aklu // 1975c08e1173703234cc2913757f237ee916087498aklu // try if the option number is used 1985c08e1173703234cc2913757f237ee916087498aklu // 1995c08e1173703234cc2913757f237ee916087498aklu OptionBuffer = BdsLibGetVariableAndSize ( 2005c08e1173703234cc2913757f237ee916087498aklu StrTemp, 2015c08e1173703234cc2913757f237ee916087498aklu &gEfiGlobalVariableGuid, 2025c08e1173703234cc2913757f237ee916087498aklu &OptionSize 2035c08e1173703234cc2913757f237ee916087498aklu ); 2045c08e1173703234cc2913757f237ee916087498aklu if (OptionBuffer == NULL) { 2055c08e1173703234cc2913757f237ee916087498aklu break; 2065c08e1173703234cc2913757f237ee916087498aklu } 2075c08e1173703234cc2913757f237ee916087498aklu Index++; 2085c08e1173703234cc2913757f237ee916087498aklu } while (TRUE); 2095c08e1173703234cc2913757f237ee916087498aklu 2105c08e1173703234cc2913757f237ee916087498aklu return ((UINT16) Index); 2115c08e1173703234cc2913757f237ee916087498aklu} 2125c08e1173703234cc2913757f237ee916087498aklu 2135c08e1173703234cc2913757f237ee916087498aklu 2145c08e1173703234cc2913757f237ee916087498aklu/** 2155c08e1173703234cc2913757f237ee916087498aklu This function will register the new boot#### or driver#### option base on 2165c08e1173703234cc2913757f237ee916087498aklu the VariableName. The new registered boot#### or driver#### will be linked 2175c08e1173703234cc2913757f237ee916087498aklu to BdsOptionList and also update to the VariableName. After the boot#### or 2185c08e1173703234cc2913757f237ee916087498aklu driver#### updated, the BootOrder or DriverOrder will also be updated. 2195c08e1173703234cc2913757f237ee916087498aklu 2205c08e1173703234cc2913757f237ee916087498aklu @param BdsOptionList The header of the boot#### or driver#### link list 2215c08e1173703234cc2913757f237ee916087498aklu @param DevicePath The device path which the boot#### or driver#### 2225c08e1173703234cc2913757f237ee916087498aklu option present 2235c08e1173703234cc2913757f237ee916087498aklu @param String The description of the boot#### or driver#### 2245c08e1173703234cc2913757f237ee916087498aklu @param VariableName Indicate if the boot#### or driver#### option 2255c08e1173703234cc2913757f237ee916087498aklu 2265c08e1173703234cc2913757f237ee916087498aklu @retval EFI_SUCCESS The boot#### or driver#### have been success 2275c08e1173703234cc2913757f237ee916087498aklu registered 2285c08e1173703234cc2913757f237ee916087498aklu @retval EFI_STATUS Return the status of gRT->SetVariable (). 2295c08e1173703234cc2913757f237ee916087498aklu 2305c08e1173703234cc2913757f237ee916087498aklu**/ 2315c08e1173703234cc2913757f237ee916087498akluEFI_STATUS 2325c08e1173703234cc2913757f237ee916087498akluEFIAPI 2335c08e1173703234cc2913757f237ee916087498akluBdsLibRegisterNewOption ( 2345c08e1173703234cc2913757f237ee916087498aklu IN LIST_ENTRY *BdsOptionList, 2355c08e1173703234cc2913757f237ee916087498aklu IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, 2365c08e1173703234cc2913757f237ee916087498aklu IN CHAR16 *String, 2375c08e1173703234cc2913757f237ee916087498aklu IN CHAR16 *VariableName 2385c08e1173703234cc2913757f237ee916087498aklu ) 2395c08e1173703234cc2913757f237ee916087498aklu{ 2405c08e1173703234cc2913757f237ee916087498aklu EFI_STATUS Status; 2415c08e1173703234cc2913757f237ee916087498aklu UINTN Index; 2425c08e1173703234cc2913757f237ee916087498aklu UINT16 RegisterOptionNumber; 2435c08e1173703234cc2913757f237ee916087498aklu UINT16 *TempOptionPtr; 2445c08e1173703234cc2913757f237ee916087498aklu UINTN TempOptionSize; 2455c08e1173703234cc2913757f237ee916087498aklu UINT16 *OptionOrderPtr; 2465c08e1173703234cc2913757f237ee916087498aklu VOID *OptionPtr; 2475c08e1173703234cc2913757f237ee916087498aklu UINTN OptionSize; 2485c08e1173703234cc2913757f237ee916087498aklu UINT8 *TempPtr; 2495c08e1173703234cc2913757f237ee916087498aklu EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath; 2505c08e1173703234cc2913757f237ee916087498aklu CHAR16 *Description; 2515c08e1173703234cc2913757f237ee916087498aklu CHAR16 OptionName[10]; 2525c08e1173703234cc2913757f237ee916087498aklu BOOLEAN UpdateDescription; 2535c08e1173703234cc2913757f237ee916087498aklu UINT16 BootOrderEntry; 2545c08e1173703234cc2913757f237ee916087498aklu UINTN OrderItemNum; 2555c08e1173703234cc2913757f237ee916087498aklu 2565c08e1173703234cc2913757f237ee916087498aklu 2575c08e1173703234cc2913757f237ee916087498aklu OptionPtr = NULL; 2585c08e1173703234cc2913757f237ee916087498aklu OptionSize = 0; 2595c08e1173703234cc2913757f237ee916087498aklu TempPtr = NULL; 2605c08e1173703234cc2913757f237ee916087498aklu OptionDevicePath = NULL; 2615c08e1173703234cc2913757f237ee916087498aklu Description = NULL; 2625c08e1173703234cc2913757f237ee916087498aklu OptionOrderPtr = NULL; 2635c08e1173703234cc2913757f237ee916087498aklu UpdateDescription = FALSE; 2645c08e1173703234cc2913757f237ee916087498aklu Status = EFI_SUCCESS; 2655c08e1173703234cc2913757f237ee916087498aklu ZeroMem (OptionName, sizeof (OptionName)); 2665c08e1173703234cc2913757f237ee916087498aklu 2675c08e1173703234cc2913757f237ee916087498aklu TempOptionSize = 0; 2685c08e1173703234cc2913757f237ee916087498aklu TempOptionPtr = BdsLibGetVariableAndSize ( 2695c08e1173703234cc2913757f237ee916087498aklu VariableName, 2705c08e1173703234cc2913757f237ee916087498aklu &gEfiGlobalVariableGuid, 2715c08e1173703234cc2913757f237ee916087498aklu &TempOptionSize 2725c08e1173703234cc2913757f237ee916087498aklu ); 2735c08e1173703234cc2913757f237ee916087498aklu // 2745c08e1173703234cc2913757f237ee916087498aklu // Compare with current option variable if the previous option is set in global variable. 2755c08e1173703234cc2913757f237ee916087498aklu // 2765c08e1173703234cc2913757f237ee916087498aklu for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) { 2775c08e1173703234cc2913757f237ee916087498aklu // 2785c08e1173703234cc2913757f237ee916087498aklu // TempOptionPtr must not be NULL if we have non-zero TempOptionSize. 2795c08e1173703234cc2913757f237ee916087498aklu // 2805c08e1173703234cc2913757f237ee916087498aklu ASSERT (TempOptionPtr != NULL); 2815c08e1173703234cc2913757f237ee916087498aklu 2825c08e1173703234cc2913757f237ee916087498aklu if (*VariableName == 'B') { 2835c08e1173703234cc2913757f237ee916087498aklu UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", TempOptionPtr[Index]); 2845c08e1173703234cc2913757f237ee916087498aklu } else { 2855c08e1173703234cc2913757f237ee916087498aklu UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", TempOptionPtr[Index]); 2865c08e1173703234cc2913757f237ee916087498aklu } 2875c08e1173703234cc2913757f237ee916087498aklu 2885c08e1173703234cc2913757f237ee916087498aklu OptionPtr = BdsLibGetVariableAndSize ( 2895c08e1173703234cc2913757f237ee916087498aklu OptionName, 2905c08e1173703234cc2913757f237ee916087498aklu &gEfiGlobalVariableGuid, 2915c08e1173703234cc2913757f237ee916087498aklu &OptionSize 2925c08e1173703234cc2913757f237ee916087498aklu ); 2935c08e1173703234cc2913757f237ee916087498aklu if (OptionPtr == NULL) { 2945c08e1173703234cc2913757f237ee916087498aklu continue; 2955c08e1173703234cc2913757f237ee916087498aklu } 2965c08e1173703234cc2913757f237ee916087498aklu TempPtr = OptionPtr; 2975c08e1173703234cc2913757f237ee916087498aklu TempPtr += sizeof (UINT32) + sizeof (UINT16); 2985c08e1173703234cc2913757f237ee916087498aklu Description = (CHAR16 *) TempPtr; 2995c08e1173703234cc2913757f237ee916087498aklu TempPtr += StrSize ((CHAR16 *) TempPtr); 3005c08e1173703234cc2913757f237ee916087498aklu OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; 3015c08e1173703234cc2913757f237ee916087498aklu 3025c08e1173703234cc2913757f237ee916087498aklu // 3035c08e1173703234cc2913757f237ee916087498aklu // Notes: the description may will change base on the GetStringToken 3045c08e1173703234cc2913757f237ee916087498aklu // 3055c08e1173703234cc2913757f237ee916087498aklu if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize (OptionDevicePath)) == 0) { 3065c08e1173703234cc2913757f237ee916087498aklu if (CompareMem (Description, String, StrSize (Description)) == 0) { 3075c08e1173703234cc2913757f237ee916087498aklu // 3085c08e1173703234cc2913757f237ee916087498aklu // Got the option, so just return 3095c08e1173703234cc2913757f237ee916087498aklu // 3105c08e1173703234cc2913757f237ee916087498aklu FreePool (OptionPtr); 3115c08e1173703234cc2913757f237ee916087498aklu FreePool (TempOptionPtr); 3125c08e1173703234cc2913757f237ee916087498aklu return EFI_SUCCESS; 3135c08e1173703234cc2913757f237ee916087498aklu } else { 3145c08e1173703234cc2913757f237ee916087498aklu // 3155c08e1173703234cc2913757f237ee916087498aklu // Option description changed, need update. 3165c08e1173703234cc2913757f237ee916087498aklu // 3175c08e1173703234cc2913757f237ee916087498aklu UpdateDescription = TRUE; 3185c08e1173703234cc2913757f237ee916087498aklu FreePool (OptionPtr); 3195c08e1173703234cc2913757f237ee916087498aklu break; 3205c08e1173703234cc2913757f237ee916087498aklu } 3215c08e1173703234cc2913757f237ee916087498aklu } 3225c08e1173703234cc2913757f237ee916087498aklu 3235c08e1173703234cc2913757f237ee916087498aklu FreePool (OptionPtr); 3245c08e1173703234cc2913757f237ee916087498aklu } 3255c08e1173703234cc2913757f237ee916087498aklu 3265c08e1173703234cc2913757f237ee916087498aklu OptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (String); 3275c08e1173703234cc2913757f237ee916087498aklu OptionSize += GetDevicePathSize (DevicePath); 3285c08e1173703234cc2913757f237ee916087498aklu OptionPtr = AllocateZeroPool (OptionSize); 3295c08e1173703234cc2913757f237ee916087498aklu ASSERT (OptionPtr != NULL); 3305c08e1173703234cc2913757f237ee916087498aklu 3315c08e1173703234cc2913757f237ee916087498aklu TempPtr = OptionPtr; 3325c08e1173703234cc2913757f237ee916087498aklu *(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE; 3335c08e1173703234cc2913757f237ee916087498aklu TempPtr += sizeof (UINT32); 3345c08e1173703234cc2913757f237ee916087498aklu *(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath); 3355c08e1173703234cc2913757f237ee916087498aklu TempPtr += sizeof (UINT16); 3365c08e1173703234cc2913757f237ee916087498aklu CopyMem (TempPtr, String, StrSize (String)); 3375c08e1173703234cc2913757f237ee916087498aklu TempPtr += StrSize (String); 3385c08e1173703234cc2913757f237ee916087498aklu CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath)); 3395c08e1173703234cc2913757f237ee916087498aklu 3405c08e1173703234cc2913757f237ee916087498aklu if (UpdateDescription) { 3415c08e1173703234cc2913757f237ee916087498aklu // 3425c08e1173703234cc2913757f237ee916087498aklu // The number in option#### to be updated. 3435c08e1173703234cc2913757f237ee916087498aklu // In this case, we must have non-NULL TempOptionPtr. 3445c08e1173703234cc2913757f237ee916087498aklu // 3455c08e1173703234cc2913757f237ee916087498aklu ASSERT (TempOptionPtr != NULL); 3465c08e1173703234cc2913757f237ee916087498aklu RegisterOptionNumber = TempOptionPtr[Index]; 3475c08e1173703234cc2913757f237ee916087498aklu } else { 3485c08e1173703234cc2913757f237ee916087498aklu // 3495c08e1173703234cc2913757f237ee916087498aklu // The new option#### number 3505c08e1173703234cc2913757f237ee916087498aklu // 3515c08e1173703234cc2913757f237ee916087498aklu RegisterOptionNumber = BdsLibGetFreeOptionNumber(VariableName); 3525c08e1173703234cc2913757f237ee916087498aklu } 3535c08e1173703234cc2913757f237ee916087498aklu 3545c08e1173703234cc2913757f237ee916087498aklu if (*VariableName == 'B') { 3555c08e1173703234cc2913757f237ee916087498aklu UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", RegisterOptionNumber); 3565c08e1173703234cc2913757f237ee916087498aklu } else { 3575c08e1173703234cc2913757f237ee916087498aklu UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", RegisterOptionNumber); 3585c08e1173703234cc2913757f237ee916087498aklu } 3595c08e1173703234cc2913757f237ee916087498aklu 3605c08e1173703234cc2913757f237ee916087498aklu Status = gRT->SetVariable ( 3615c08e1173703234cc2913757f237ee916087498aklu OptionName, 3625c08e1173703234cc2913757f237ee916087498aklu &gEfiGlobalVariableGuid, 3635c08e1173703234cc2913757f237ee916087498aklu EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 3645c08e1173703234cc2913757f237ee916087498aklu OptionSize, 3655c08e1173703234cc2913757f237ee916087498aklu OptionPtr 3665c08e1173703234cc2913757f237ee916087498aklu ); 3675c08e1173703234cc2913757f237ee916087498aklu // 3685c08e1173703234cc2913757f237ee916087498aklu // Return if only need to update a changed description or fail to set option. 3695c08e1173703234cc2913757f237ee916087498aklu // 3705c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status) || UpdateDescription) { 3715c08e1173703234cc2913757f237ee916087498aklu FreePool (OptionPtr); 3725c08e1173703234cc2913757f237ee916087498aklu if (TempOptionPtr != NULL) { 3735c08e1173703234cc2913757f237ee916087498aklu FreePool (TempOptionPtr); 3745c08e1173703234cc2913757f237ee916087498aklu } 3755c08e1173703234cc2913757f237ee916087498aklu return Status; 3765c08e1173703234cc2913757f237ee916087498aklu } 3775c08e1173703234cc2913757f237ee916087498aklu 3785c08e1173703234cc2913757f237ee916087498aklu FreePool (OptionPtr); 3795c08e1173703234cc2913757f237ee916087498aklu 3805c08e1173703234cc2913757f237ee916087498aklu // 3815c08e1173703234cc2913757f237ee916087498aklu // Update the option order variable 3825c08e1173703234cc2913757f237ee916087498aklu // 3835c08e1173703234cc2913757f237ee916087498aklu 3845c08e1173703234cc2913757f237ee916087498aklu // 3855c08e1173703234cc2913757f237ee916087498aklu // If no option order 3865c08e1173703234cc2913757f237ee916087498aklu // 3875c08e1173703234cc2913757f237ee916087498aklu if (TempOptionSize == 0) { 3885c08e1173703234cc2913757f237ee916087498aklu BootOrderEntry = 0; 3895c08e1173703234cc2913757f237ee916087498aklu Status = gRT->SetVariable ( 3905c08e1173703234cc2913757f237ee916087498aklu VariableName, 3915c08e1173703234cc2913757f237ee916087498aklu &gEfiGlobalVariableGuid, 3925c08e1173703234cc2913757f237ee916087498aklu EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 3935c08e1173703234cc2913757f237ee916087498aklu sizeof (UINT16), 3945c08e1173703234cc2913757f237ee916087498aklu &BootOrderEntry 3955c08e1173703234cc2913757f237ee916087498aklu ); 3965c08e1173703234cc2913757f237ee916087498aklu if (TempOptionPtr != NULL) { 3975c08e1173703234cc2913757f237ee916087498aklu FreePool (TempOptionPtr); 3985c08e1173703234cc2913757f237ee916087498aklu } 3995c08e1173703234cc2913757f237ee916087498aklu return Status; 4005c08e1173703234cc2913757f237ee916087498aklu } 4015c08e1173703234cc2913757f237ee916087498aklu 4025c08e1173703234cc2913757f237ee916087498aklu // 4035c08e1173703234cc2913757f237ee916087498aklu // TempOptionPtr must not be NULL if TempOptionSize is not zero. 4045c08e1173703234cc2913757f237ee916087498aklu // 4055c08e1173703234cc2913757f237ee916087498aklu ASSERT (TempOptionPtr != NULL); 4065c08e1173703234cc2913757f237ee916087498aklu // 4075c08e1173703234cc2913757f237ee916087498aklu // Append the new option number to the original option order 4085c08e1173703234cc2913757f237ee916087498aklu // 4095c08e1173703234cc2913757f237ee916087498aklu OrderItemNum = (TempOptionSize / sizeof (UINT16)) + 1 ; 4105c08e1173703234cc2913757f237ee916087498aklu OptionOrderPtr = AllocateZeroPool ( OrderItemNum * sizeof (UINT16)); 4115c08e1173703234cc2913757f237ee916087498aklu ASSERT (OptionOrderPtr!= NULL); 4125c08e1173703234cc2913757f237ee916087498aklu CopyMem (OptionOrderPtr, TempOptionPtr, (OrderItemNum - 1) * sizeof (UINT16)); 4135c08e1173703234cc2913757f237ee916087498aklu 4145c08e1173703234cc2913757f237ee916087498aklu OptionOrderPtr[Index] = RegisterOptionNumber; 4155c08e1173703234cc2913757f237ee916087498aklu 4165c08e1173703234cc2913757f237ee916087498aklu Status = gRT->SetVariable ( 4175c08e1173703234cc2913757f237ee916087498aklu VariableName, 4185c08e1173703234cc2913757f237ee916087498aklu &gEfiGlobalVariableGuid, 4195c08e1173703234cc2913757f237ee916087498aklu EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 4205c08e1173703234cc2913757f237ee916087498aklu OrderItemNum * sizeof (UINT16), 4215c08e1173703234cc2913757f237ee916087498aklu OptionOrderPtr 4225c08e1173703234cc2913757f237ee916087498aklu ); 4235c08e1173703234cc2913757f237ee916087498aklu FreePool (TempOptionPtr); 4245c08e1173703234cc2913757f237ee916087498aklu FreePool (OptionOrderPtr); 4255c08e1173703234cc2913757f237ee916087498aklu 4265c08e1173703234cc2913757f237ee916087498aklu return Status; 4275c08e1173703234cc2913757f237ee916087498aklu} 4285c08e1173703234cc2913757f237ee916087498aklu 4295c08e1173703234cc2913757f237ee916087498aklu 4305c08e1173703234cc2913757f237ee916087498aklu/** 4315c08e1173703234cc2913757f237ee916087498aklu Build the boot#### or driver#### option from the VariableName, the 4325c08e1173703234cc2913757f237ee916087498aklu build boot#### or driver#### will also be linked to BdsCommonOptionList. 4335c08e1173703234cc2913757f237ee916087498aklu 4345c08e1173703234cc2913757f237ee916087498aklu @param BdsCommonOptionList The header of the boot#### or driver#### option 4355c08e1173703234cc2913757f237ee916087498aklu link list 4365c08e1173703234cc2913757f237ee916087498aklu @param VariableName EFI Variable name indicate if it is boot#### or 4375c08e1173703234cc2913757f237ee916087498aklu driver#### 4385c08e1173703234cc2913757f237ee916087498aklu 4395c08e1173703234cc2913757f237ee916087498aklu @retval BDS_COMMON_OPTION Get the option just been created 4405c08e1173703234cc2913757f237ee916087498aklu @retval NULL Failed to get the new option 4415c08e1173703234cc2913757f237ee916087498aklu 4425c08e1173703234cc2913757f237ee916087498aklu**/ 4435c08e1173703234cc2913757f237ee916087498akluBDS_COMMON_OPTION * 4445c08e1173703234cc2913757f237ee916087498akluEFIAPI 4455c08e1173703234cc2913757f237ee916087498akluBdsLibVariableToOption ( 4465c08e1173703234cc2913757f237ee916087498aklu IN OUT LIST_ENTRY *BdsCommonOptionList, 4475c08e1173703234cc2913757f237ee916087498aklu IN CHAR16 *VariableName 4485c08e1173703234cc2913757f237ee916087498aklu ) 4495c08e1173703234cc2913757f237ee916087498aklu{ 4505c08e1173703234cc2913757f237ee916087498aklu UINT32 Attribute; 4515c08e1173703234cc2913757f237ee916087498aklu UINT16 FilePathSize; 4525c08e1173703234cc2913757f237ee916087498aklu UINT8 *Variable; 4535c08e1173703234cc2913757f237ee916087498aklu UINT8 *TempPtr; 4545c08e1173703234cc2913757f237ee916087498aklu UINTN VariableSize; 4555c08e1173703234cc2913757f237ee916087498aklu EFI_DEVICE_PATH_PROTOCOL *DevicePath; 4565c08e1173703234cc2913757f237ee916087498aklu BDS_COMMON_OPTION *Option; 4575c08e1173703234cc2913757f237ee916087498aklu VOID *LoadOptions; 4585c08e1173703234cc2913757f237ee916087498aklu UINT32 LoadOptionsSize; 4595c08e1173703234cc2913757f237ee916087498aklu CHAR16 *Description; 4605c08e1173703234cc2913757f237ee916087498aklu UINT8 NumOff; 4615c08e1173703234cc2913757f237ee916087498aklu // 4625c08e1173703234cc2913757f237ee916087498aklu // Read the variable. We will never free this data. 4635c08e1173703234cc2913757f237ee916087498aklu // 4645c08e1173703234cc2913757f237ee916087498aklu Variable = BdsLibGetVariableAndSize ( 4655c08e1173703234cc2913757f237ee916087498aklu VariableName, 4665c08e1173703234cc2913757f237ee916087498aklu &gEfiGlobalVariableGuid, 4675c08e1173703234cc2913757f237ee916087498aklu &VariableSize 4685c08e1173703234cc2913757f237ee916087498aklu ); 4695c08e1173703234cc2913757f237ee916087498aklu if (Variable == NULL) { 4705c08e1173703234cc2913757f237ee916087498aklu return NULL; 4715c08e1173703234cc2913757f237ee916087498aklu } 4725c08e1173703234cc2913757f237ee916087498aklu // 4735c08e1173703234cc2913757f237ee916087498aklu // Notes: careful defined the variable of Boot#### or 4745c08e1173703234cc2913757f237ee916087498aklu // Driver####, consider use some macro to abstract the code 4755c08e1173703234cc2913757f237ee916087498aklu // 4765c08e1173703234cc2913757f237ee916087498aklu // 4775c08e1173703234cc2913757f237ee916087498aklu // Get the option attribute 4785c08e1173703234cc2913757f237ee916087498aklu // 4795c08e1173703234cc2913757f237ee916087498aklu TempPtr = Variable; 4805c08e1173703234cc2913757f237ee916087498aklu Attribute = *(UINT32 *) Variable; 4815c08e1173703234cc2913757f237ee916087498aklu TempPtr += sizeof (UINT32); 4825c08e1173703234cc2913757f237ee916087498aklu 4835c08e1173703234cc2913757f237ee916087498aklu // 4845c08e1173703234cc2913757f237ee916087498aklu // Get the option's device path size 4855c08e1173703234cc2913757f237ee916087498aklu // 4865c08e1173703234cc2913757f237ee916087498aklu FilePathSize = *(UINT16 *) TempPtr; 4875c08e1173703234cc2913757f237ee916087498aklu TempPtr += sizeof (UINT16); 4885c08e1173703234cc2913757f237ee916087498aklu 4895c08e1173703234cc2913757f237ee916087498aklu // 4905c08e1173703234cc2913757f237ee916087498aklu // Get the option's description string 4915c08e1173703234cc2913757f237ee916087498aklu // 4925c08e1173703234cc2913757f237ee916087498aklu Description = (CHAR16 *) TempPtr; 4935c08e1173703234cc2913757f237ee916087498aklu 4945c08e1173703234cc2913757f237ee916087498aklu // 4955c08e1173703234cc2913757f237ee916087498aklu // Get the option's description string size 4965c08e1173703234cc2913757f237ee916087498aklu // 4975c08e1173703234cc2913757f237ee916087498aklu TempPtr += StrSize ((CHAR16 *) TempPtr); 4985c08e1173703234cc2913757f237ee916087498aklu 4995c08e1173703234cc2913757f237ee916087498aklu // 5005c08e1173703234cc2913757f237ee916087498aklu // Get the option's device path 5015c08e1173703234cc2913757f237ee916087498aklu // 5025c08e1173703234cc2913757f237ee916087498aklu DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; 5035c08e1173703234cc2913757f237ee916087498aklu TempPtr += FilePathSize; 5045c08e1173703234cc2913757f237ee916087498aklu 5055c08e1173703234cc2913757f237ee916087498aklu LoadOptions = TempPtr; 5065c08e1173703234cc2913757f237ee916087498aklu LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable)); 5075c08e1173703234cc2913757f237ee916087498aklu 5085c08e1173703234cc2913757f237ee916087498aklu // 5095c08e1173703234cc2913757f237ee916087498aklu // The Console variables may have multiple device paths, so make 5105c08e1173703234cc2913757f237ee916087498aklu // an Entry for each one. 5115c08e1173703234cc2913757f237ee916087498aklu // 5125c08e1173703234cc2913757f237ee916087498aklu Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION)); 5135c08e1173703234cc2913757f237ee916087498aklu if (Option == NULL) { 5145c08e1173703234cc2913757f237ee916087498aklu return NULL; 5155c08e1173703234cc2913757f237ee916087498aklu } 5165c08e1173703234cc2913757f237ee916087498aklu 5175c08e1173703234cc2913757f237ee916087498aklu Option->Signature = BDS_LOAD_OPTION_SIGNATURE; 5185c08e1173703234cc2913757f237ee916087498aklu Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath)); 5195c08e1173703234cc2913757f237ee916087498aklu ASSERT(Option->DevicePath != NULL); 5205c08e1173703234cc2913757f237ee916087498aklu CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath)); 5215c08e1173703234cc2913757f237ee916087498aklu 5225c08e1173703234cc2913757f237ee916087498aklu Option->Attribute = Attribute; 5235c08e1173703234cc2913757f237ee916087498aklu Option->Description = AllocateZeroPool (StrSize (Description)); 5245c08e1173703234cc2913757f237ee916087498aklu ASSERT(Option->Description != NULL); 5255c08e1173703234cc2913757f237ee916087498aklu CopyMem (Option->Description, Description, StrSize (Description)); 5265c08e1173703234cc2913757f237ee916087498aklu 5275c08e1173703234cc2913757f237ee916087498aklu Option->LoadOptions = AllocateZeroPool (LoadOptionsSize); 5285c08e1173703234cc2913757f237ee916087498aklu ASSERT(Option->LoadOptions != NULL); 5295c08e1173703234cc2913757f237ee916087498aklu CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize); 5305c08e1173703234cc2913757f237ee916087498aklu Option->LoadOptionsSize = LoadOptionsSize; 5315c08e1173703234cc2913757f237ee916087498aklu 5325c08e1173703234cc2913757f237ee916087498aklu // 5335c08e1173703234cc2913757f237ee916087498aklu // Get the value from VariableName Unicode string 5345c08e1173703234cc2913757f237ee916087498aklu // since the ISO standard assumes ASCII equivalent abbreviations, we can be safe in converting this 5355c08e1173703234cc2913757f237ee916087498aklu // Unicode stream to ASCII without any loss in meaning. 5365c08e1173703234cc2913757f237ee916087498aklu // 5375c08e1173703234cc2913757f237ee916087498aklu if (*VariableName == 'B') { 5385c08e1173703234cc2913757f237ee916087498aklu NumOff = sizeof (L"Boot")/sizeof(CHAR16) -1 ; 5395c08e1173703234cc2913757f237ee916087498aklu Option->BootCurrent = (UINT16) ((VariableName[NumOff] -'0') * 0x1000); 5405c08e1173703234cc2913757f237ee916087498aklu Option->BootCurrent = (UINT16) (Option->BootCurrent + ((VariableName[NumOff+1]-'0') * 0x100)); 5415c08e1173703234cc2913757f237ee916087498aklu Option->BootCurrent = (UINT16) (Option->BootCurrent + ((VariableName[NumOff+2]-'0') * 0x10)); 5425c08e1173703234cc2913757f237ee916087498aklu Option->BootCurrent = (UINT16) (Option->BootCurrent + ((VariableName[NumOff+3]-'0'))); 5435c08e1173703234cc2913757f237ee916087498aklu } 5445c08e1173703234cc2913757f237ee916087498aklu // 5455c08e1173703234cc2913757f237ee916087498aklu // Insert active entry to BdsDeviceList 5465c08e1173703234cc2913757f237ee916087498aklu // 5475c08e1173703234cc2913757f237ee916087498aklu if ((Option->Attribute & LOAD_OPTION_ACTIVE) == LOAD_OPTION_ACTIVE) { 5485c08e1173703234cc2913757f237ee916087498aklu InsertTailList (BdsCommonOptionList, &Option->Link); 5495c08e1173703234cc2913757f237ee916087498aklu FreePool (Variable); 5505c08e1173703234cc2913757f237ee916087498aklu return Option; 5515c08e1173703234cc2913757f237ee916087498aklu } 5525c08e1173703234cc2913757f237ee916087498aklu 5535c08e1173703234cc2913757f237ee916087498aklu FreePool (Variable); 5545c08e1173703234cc2913757f237ee916087498aklu FreePool (Option); 5555c08e1173703234cc2913757f237ee916087498aklu return NULL; 5565c08e1173703234cc2913757f237ee916087498aklu 5575c08e1173703234cc2913757f237ee916087498aklu} 5585c08e1173703234cc2913757f237ee916087498aklu 5595c08e1173703234cc2913757f237ee916087498aklu/** 5605c08e1173703234cc2913757f237ee916087498aklu Process BootOrder, or DriverOrder variables, by calling 5615c08e1173703234cc2913757f237ee916087498aklu BdsLibVariableToOption () for each UINT16 in the variables. 5625c08e1173703234cc2913757f237ee916087498aklu 5635c08e1173703234cc2913757f237ee916087498aklu @param BdsCommonOptionList The header of the option list base on variable 5645c08e1173703234cc2913757f237ee916087498aklu VariableName 5655c08e1173703234cc2913757f237ee916087498aklu @param VariableName EFI Variable name indicate the BootOrder or 5665c08e1173703234cc2913757f237ee916087498aklu DriverOrder 5675c08e1173703234cc2913757f237ee916087498aklu 5685c08e1173703234cc2913757f237ee916087498aklu @retval EFI_SUCCESS Success create the boot option or driver option 5695c08e1173703234cc2913757f237ee916087498aklu list 5705c08e1173703234cc2913757f237ee916087498aklu @retval EFI_OUT_OF_RESOURCES Failed to get the boot option or driver option list 5715c08e1173703234cc2913757f237ee916087498aklu 5725c08e1173703234cc2913757f237ee916087498aklu**/ 5735c08e1173703234cc2913757f237ee916087498akluEFI_STATUS 5745c08e1173703234cc2913757f237ee916087498akluEFIAPI 5755c08e1173703234cc2913757f237ee916087498akluBdsLibBuildOptionFromVar ( 5765c08e1173703234cc2913757f237ee916087498aklu IN LIST_ENTRY *BdsCommonOptionList, 5775c08e1173703234cc2913757f237ee916087498aklu IN CHAR16 *VariableName 5785c08e1173703234cc2913757f237ee916087498aklu ) 5795c08e1173703234cc2913757f237ee916087498aklu{ 5805c08e1173703234cc2913757f237ee916087498aklu UINT16 *OptionOrder; 5815c08e1173703234cc2913757f237ee916087498aklu UINTN OptionOrderSize; 5825c08e1173703234cc2913757f237ee916087498aklu UINTN Index; 5835c08e1173703234cc2913757f237ee916087498aklu BDS_COMMON_OPTION *Option; 5845c08e1173703234cc2913757f237ee916087498aklu CHAR16 OptionName[20]; 5855c08e1173703234cc2913757f237ee916087498aklu 5865c08e1173703234cc2913757f237ee916087498aklu // 5875c08e1173703234cc2913757f237ee916087498aklu // Zero Buffer in order to get all BOOT#### variables 5885c08e1173703234cc2913757f237ee916087498aklu // 5895c08e1173703234cc2913757f237ee916087498aklu ZeroMem (OptionName, sizeof (OptionName)); 5905c08e1173703234cc2913757f237ee916087498aklu 5915c08e1173703234cc2913757f237ee916087498aklu // 5925c08e1173703234cc2913757f237ee916087498aklu // Read the BootOrder, or DriverOrder variable. 5935c08e1173703234cc2913757f237ee916087498aklu // 5945c08e1173703234cc2913757f237ee916087498aklu OptionOrder = BdsLibGetVariableAndSize ( 5955c08e1173703234cc2913757f237ee916087498aklu VariableName, 5965c08e1173703234cc2913757f237ee916087498aklu &gEfiGlobalVariableGuid, 5975c08e1173703234cc2913757f237ee916087498aklu &OptionOrderSize 5985c08e1173703234cc2913757f237ee916087498aklu ); 5995c08e1173703234cc2913757f237ee916087498aklu if (OptionOrder == NULL) { 6005c08e1173703234cc2913757f237ee916087498aklu return EFI_OUT_OF_RESOURCES; 6015c08e1173703234cc2913757f237ee916087498aklu } 6025c08e1173703234cc2913757f237ee916087498aklu 6035c08e1173703234cc2913757f237ee916087498aklu for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) { 6045c08e1173703234cc2913757f237ee916087498aklu if (*VariableName == 'B') { 6055c08e1173703234cc2913757f237ee916087498aklu UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]); 6065c08e1173703234cc2913757f237ee916087498aklu } else { 6075c08e1173703234cc2913757f237ee916087498aklu UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]); 6085c08e1173703234cc2913757f237ee916087498aklu } 6095c08e1173703234cc2913757f237ee916087498aklu 6105c08e1173703234cc2913757f237ee916087498aklu Option = BdsLibVariableToOption (BdsCommonOptionList, OptionName); 6115c08e1173703234cc2913757f237ee916087498aklu ASSERT (Option != NULL); 6125c08e1173703234cc2913757f237ee916087498aklu Option->BootCurrent = OptionOrder[Index]; 6135c08e1173703234cc2913757f237ee916087498aklu 6145c08e1173703234cc2913757f237ee916087498aklu } 6155c08e1173703234cc2913757f237ee916087498aklu 6165c08e1173703234cc2913757f237ee916087498aklu FreePool (OptionOrder); 6175c08e1173703234cc2913757f237ee916087498aklu 6185c08e1173703234cc2913757f237ee916087498aklu return EFI_SUCCESS; 6195c08e1173703234cc2913757f237ee916087498aklu} 6205c08e1173703234cc2913757f237ee916087498aklu 6215c08e1173703234cc2913757f237ee916087498aklu/** 6225c08e1173703234cc2913757f237ee916087498aklu Get boot mode by looking up configuration table and parsing HOB list 6235c08e1173703234cc2913757f237ee916087498aklu 6245c08e1173703234cc2913757f237ee916087498aklu @param BootMode Boot mode from PEI handoff HOB. 6255c08e1173703234cc2913757f237ee916087498aklu 6265c08e1173703234cc2913757f237ee916087498aklu @retval EFI_SUCCESS Successfully get boot mode 6275c08e1173703234cc2913757f237ee916087498aklu 6285c08e1173703234cc2913757f237ee916087498aklu**/ 6295c08e1173703234cc2913757f237ee916087498akluEFI_STATUS 6305c08e1173703234cc2913757f237ee916087498akluEFIAPI 6315c08e1173703234cc2913757f237ee916087498akluBdsLibGetBootMode ( 6325c08e1173703234cc2913757f237ee916087498aklu OUT EFI_BOOT_MODE *BootMode 6335c08e1173703234cc2913757f237ee916087498aklu ) 6345c08e1173703234cc2913757f237ee916087498aklu{ 6355c08e1173703234cc2913757f237ee916087498aklu *BootMode = GetBootModeHob (); 6365c08e1173703234cc2913757f237ee916087498aklu 6375c08e1173703234cc2913757f237ee916087498aklu return EFI_SUCCESS; 6385c08e1173703234cc2913757f237ee916087498aklu} 6395c08e1173703234cc2913757f237ee916087498aklu 6405c08e1173703234cc2913757f237ee916087498aklu/** 6415c08e1173703234cc2913757f237ee916087498aklu Read the EFI variable (VendorGuid/Name) and return a dynamically allocated 6425c08e1173703234cc2913757f237ee916087498aklu buffer, and the size of the buffer. If failure return NULL. 6435c08e1173703234cc2913757f237ee916087498aklu 6445c08e1173703234cc2913757f237ee916087498aklu @param Name String part of EFI variable name 6455c08e1173703234cc2913757f237ee916087498aklu @param VendorGuid GUID part of EFI variable name 6465c08e1173703234cc2913757f237ee916087498aklu @param VariableSize Returns the size of the EFI variable that was read 6475c08e1173703234cc2913757f237ee916087498aklu 6485c08e1173703234cc2913757f237ee916087498aklu @return Dynamically allocated memory that contains a copy of the EFI variable 6495c08e1173703234cc2913757f237ee916087498aklu Caller is responsible freeing the buffer. 6505c08e1173703234cc2913757f237ee916087498aklu @retval NULL Variable was not read 6515c08e1173703234cc2913757f237ee916087498aklu 6525c08e1173703234cc2913757f237ee916087498aklu**/ 6535c08e1173703234cc2913757f237ee916087498akluVOID * 6545c08e1173703234cc2913757f237ee916087498akluEFIAPI 6555c08e1173703234cc2913757f237ee916087498akluBdsLibGetVariableAndSize ( 6565c08e1173703234cc2913757f237ee916087498aklu IN CHAR16 *Name, 6575c08e1173703234cc2913757f237ee916087498aklu IN EFI_GUID *VendorGuid, 6585c08e1173703234cc2913757f237ee916087498aklu OUT UINTN *VariableSize 6595c08e1173703234cc2913757f237ee916087498aklu ) 6605c08e1173703234cc2913757f237ee916087498aklu{ 6615c08e1173703234cc2913757f237ee916087498aklu EFI_STATUS Status; 6625c08e1173703234cc2913757f237ee916087498aklu UINTN BufferSize; 6635c08e1173703234cc2913757f237ee916087498aklu VOID *Buffer; 6645c08e1173703234cc2913757f237ee916087498aklu 6655c08e1173703234cc2913757f237ee916087498aklu Buffer = NULL; 6665c08e1173703234cc2913757f237ee916087498aklu 6675c08e1173703234cc2913757f237ee916087498aklu // 6685c08e1173703234cc2913757f237ee916087498aklu // Pass in a zero size buffer to find the required buffer size. 6695c08e1173703234cc2913757f237ee916087498aklu // 6705c08e1173703234cc2913757f237ee916087498aklu BufferSize = 0; 6715c08e1173703234cc2913757f237ee916087498aklu Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer); 6725c08e1173703234cc2913757f237ee916087498aklu if (Status == EFI_BUFFER_TOO_SMALL) { 6735c08e1173703234cc2913757f237ee916087498aklu // 6745c08e1173703234cc2913757f237ee916087498aklu // Allocate the buffer to return 6755c08e1173703234cc2913757f237ee916087498aklu // 6765c08e1173703234cc2913757f237ee916087498aklu Buffer = AllocateZeroPool (BufferSize); 6775c08e1173703234cc2913757f237ee916087498aklu if (Buffer == NULL) { 6785c08e1173703234cc2913757f237ee916087498aklu return NULL; 6795c08e1173703234cc2913757f237ee916087498aklu } 6805c08e1173703234cc2913757f237ee916087498aklu // 6815c08e1173703234cc2913757f237ee916087498aklu // Read variable into the allocated buffer. 6825c08e1173703234cc2913757f237ee916087498aklu // 6835c08e1173703234cc2913757f237ee916087498aklu Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer); 6845c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status)) { 6855c08e1173703234cc2913757f237ee916087498aklu BufferSize = 0; 6865c08e1173703234cc2913757f237ee916087498aklu } 6875c08e1173703234cc2913757f237ee916087498aklu } 6885c08e1173703234cc2913757f237ee916087498aklu 6895c08e1173703234cc2913757f237ee916087498aklu *VariableSize = BufferSize; 6905c08e1173703234cc2913757f237ee916087498aklu return Buffer; 6915c08e1173703234cc2913757f237ee916087498aklu} 6925c08e1173703234cc2913757f237ee916087498aklu 6935c08e1173703234cc2913757f237ee916087498aklu/** 6945c08e1173703234cc2913757f237ee916087498aklu Delete the instance in Multi which matches partly with Single instance 6955c08e1173703234cc2913757f237ee916087498aklu 6965c08e1173703234cc2913757f237ee916087498aklu @param Multi A pointer to a multi-instance device path data 6975c08e1173703234cc2913757f237ee916087498aklu structure. 6985c08e1173703234cc2913757f237ee916087498aklu @param Single A pointer to a single-instance device path data 6995c08e1173703234cc2913757f237ee916087498aklu structure. 7005c08e1173703234cc2913757f237ee916087498aklu 7015c08e1173703234cc2913757f237ee916087498aklu @return This function will remove the device path instances in Multi which partly 7025c08e1173703234cc2913757f237ee916087498aklu match with the Single, and return the result device path. If there is no 7035c08e1173703234cc2913757f237ee916087498aklu remaining device path as a result, this function will return NULL. 7045c08e1173703234cc2913757f237ee916087498aklu 7055c08e1173703234cc2913757f237ee916087498aklu**/ 7065c08e1173703234cc2913757f237ee916087498akluEFI_DEVICE_PATH_PROTOCOL * 7075c08e1173703234cc2913757f237ee916087498akluEFIAPI 7085c08e1173703234cc2913757f237ee916087498akluBdsLibDelPartMatchInstance ( 7095c08e1173703234cc2913757f237ee916087498aklu IN EFI_DEVICE_PATH_PROTOCOL *Multi, 7105c08e1173703234cc2913757f237ee916087498aklu IN EFI_DEVICE_PATH_PROTOCOL *Single 7115c08e1173703234cc2913757f237ee916087498aklu ) 7125c08e1173703234cc2913757f237ee916087498aklu{ 7135c08e1173703234cc2913757f237ee916087498aklu EFI_DEVICE_PATH_PROTOCOL *Instance; 7145c08e1173703234cc2913757f237ee916087498aklu EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; 7155c08e1173703234cc2913757f237ee916087498aklu EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath; 7165c08e1173703234cc2913757f237ee916087498aklu UINTN InstanceSize; 7175c08e1173703234cc2913757f237ee916087498aklu UINTN SingleDpSize; 7185c08e1173703234cc2913757f237ee916087498aklu UINTN Size; 7195c08e1173703234cc2913757f237ee916087498aklu 7205c08e1173703234cc2913757f237ee916087498aklu NewDevicePath = NULL; 7215c08e1173703234cc2913757f237ee916087498aklu TempNewDevicePath = NULL; 7225c08e1173703234cc2913757f237ee916087498aklu 7235c08e1173703234cc2913757f237ee916087498aklu if (Multi == NULL || Single == NULL) { 7245c08e1173703234cc2913757f237ee916087498aklu return Multi; 7255c08e1173703234cc2913757f237ee916087498aklu } 7265c08e1173703234cc2913757f237ee916087498aklu 7275c08e1173703234cc2913757f237ee916087498aklu Instance = GetNextDevicePathInstance (&Multi, &InstanceSize); 7285c08e1173703234cc2913757f237ee916087498aklu SingleDpSize = GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH; 7295c08e1173703234cc2913757f237ee916087498aklu InstanceSize -= END_DEVICE_PATH_LENGTH; 7305c08e1173703234cc2913757f237ee916087498aklu 7315c08e1173703234cc2913757f237ee916087498aklu while (Instance != NULL) { 7325c08e1173703234cc2913757f237ee916087498aklu 7335c08e1173703234cc2913757f237ee916087498aklu Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize; 7345c08e1173703234cc2913757f237ee916087498aklu 7355c08e1173703234cc2913757f237ee916087498aklu if ((CompareMem (Instance, Single, Size) != 0)) { 7365c08e1173703234cc2913757f237ee916087498aklu // 7375c08e1173703234cc2913757f237ee916087498aklu // Append the device path instance which does not match with Single 7385c08e1173703234cc2913757f237ee916087498aklu // 7395c08e1173703234cc2913757f237ee916087498aklu TempNewDevicePath = NewDevicePath; 7405c08e1173703234cc2913757f237ee916087498aklu NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance); 7415c08e1173703234cc2913757f237ee916087498aklu if (TempNewDevicePath != NULL) { 7425c08e1173703234cc2913757f237ee916087498aklu FreePool(TempNewDevicePath); 7435c08e1173703234cc2913757f237ee916087498aklu } 7445c08e1173703234cc2913757f237ee916087498aklu } 7455c08e1173703234cc2913757f237ee916087498aklu FreePool(Instance); 7465c08e1173703234cc2913757f237ee916087498aklu Instance = GetNextDevicePathInstance (&Multi, &InstanceSize); 7475c08e1173703234cc2913757f237ee916087498aklu InstanceSize -= END_DEVICE_PATH_LENGTH; 7485c08e1173703234cc2913757f237ee916087498aklu } 7495c08e1173703234cc2913757f237ee916087498aklu 7505c08e1173703234cc2913757f237ee916087498aklu return NewDevicePath; 7515c08e1173703234cc2913757f237ee916087498aklu} 7525c08e1173703234cc2913757f237ee916087498aklu 7535c08e1173703234cc2913757f237ee916087498aklu/** 7545c08e1173703234cc2913757f237ee916087498aklu Function compares a device path data structure to that of all the nodes of a 7555c08e1173703234cc2913757f237ee916087498aklu second device path instance. 7565c08e1173703234cc2913757f237ee916087498aklu 7575c08e1173703234cc2913757f237ee916087498aklu @param Multi A pointer to a multi-instance device path data 7585c08e1173703234cc2913757f237ee916087498aklu structure. 7595c08e1173703234cc2913757f237ee916087498aklu @param Single A pointer to a single-instance device path data 7605c08e1173703234cc2913757f237ee916087498aklu structure. 7615c08e1173703234cc2913757f237ee916087498aklu 7625c08e1173703234cc2913757f237ee916087498aklu @retval TRUE If the Single device path is contained within Multi device path. 7635c08e1173703234cc2913757f237ee916087498aklu @retval FALSE The Single device path is not match within Multi device path. 7645c08e1173703234cc2913757f237ee916087498aklu 7655c08e1173703234cc2913757f237ee916087498aklu**/ 7665c08e1173703234cc2913757f237ee916087498akluBOOLEAN 7675c08e1173703234cc2913757f237ee916087498akluEFIAPI 7685c08e1173703234cc2913757f237ee916087498akluBdsLibMatchDevicePaths ( 7695c08e1173703234cc2913757f237ee916087498aklu IN EFI_DEVICE_PATH_PROTOCOL *Multi, 7705c08e1173703234cc2913757f237ee916087498aklu IN EFI_DEVICE_PATH_PROTOCOL *Single 7715c08e1173703234cc2913757f237ee916087498aklu ) 7725c08e1173703234cc2913757f237ee916087498aklu{ 7735c08e1173703234cc2913757f237ee916087498aklu EFI_DEVICE_PATH_PROTOCOL *DevicePath; 7745c08e1173703234cc2913757f237ee916087498aklu EFI_DEVICE_PATH_PROTOCOL *DevicePathInst; 7755c08e1173703234cc2913757f237ee916087498aklu UINTN Size; 7765c08e1173703234cc2913757f237ee916087498aklu 7775c08e1173703234cc2913757f237ee916087498aklu if (Multi == NULL || Single == NULL) { 7785c08e1173703234cc2913757f237ee916087498aklu return FALSE; 7795c08e1173703234cc2913757f237ee916087498aklu } 7805c08e1173703234cc2913757f237ee916087498aklu 7815c08e1173703234cc2913757f237ee916087498aklu DevicePath = Multi; 7825c08e1173703234cc2913757f237ee916087498aklu DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size); 7835c08e1173703234cc2913757f237ee916087498aklu 7845c08e1173703234cc2913757f237ee916087498aklu // 7855c08e1173703234cc2913757f237ee916087498aklu // Search for the match of 'Single' in 'Multi' 7865c08e1173703234cc2913757f237ee916087498aklu // 7875c08e1173703234cc2913757f237ee916087498aklu while (DevicePathInst != NULL) { 7885c08e1173703234cc2913757f237ee916087498aklu // 7895c08e1173703234cc2913757f237ee916087498aklu // If the single device path is found in multiple device paths, 7905c08e1173703234cc2913757f237ee916087498aklu // return success 7915c08e1173703234cc2913757f237ee916087498aklu // 7925c08e1173703234cc2913757f237ee916087498aklu if (CompareMem (Single, DevicePathInst, Size) == 0) { 7935c08e1173703234cc2913757f237ee916087498aklu FreePool (DevicePathInst); 7945c08e1173703234cc2913757f237ee916087498aklu return TRUE; 7955c08e1173703234cc2913757f237ee916087498aklu } 7965c08e1173703234cc2913757f237ee916087498aklu 7975c08e1173703234cc2913757f237ee916087498aklu FreePool (DevicePathInst); 7985c08e1173703234cc2913757f237ee916087498aklu DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size); 7995c08e1173703234cc2913757f237ee916087498aklu } 8005c08e1173703234cc2913757f237ee916087498aklu 8015c08e1173703234cc2913757f237ee916087498aklu return FALSE; 8025c08e1173703234cc2913757f237ee916087498aklu} 8035c08e1173703234cc2913757f237ee916087498aklu 8045c08e1173703234cc2913757f237ee916087498aklu/** 8055c08e1173703234cc2913757f237ee916087498aklu This function prints a series of strings. 8065c08e1173703234cc2913757f237ee916087498aklu 8075c08e1173703234cc2913757f237ee916087498aklu @param ConOut Pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL 8085c08e1173703234cc2913757f237ee916087498aklu @param ... A variable argument list containing series of 8095c08e1173703234cc2913757f237ee916087498aklu strings, the last string must be NULL. 8105c08e1173703234cc2913757f237ee916087498aklu 8115c08e1173703234cc2913757f237ee916087498aklu @retval EFI_SUCCESS Success print out the string using ConOut. 8125c08e1173703234cc2913757f237ee916087498aklu @retval EFI_STATUS Return the status of the ConOut->OutputString (). 8135c08e1173703234cc2913757f237ee916087498aklu 8145c08e1173703234cc2913757f237ee916087498aklu**/ 8155c08e1173703234cc2913757f237ee916087498akluEFI_STATUS 8165c08e1173703234cc2913757f237ee916087498akluEFIAPI 8175c08e1173703234cc2913757f237ee916087498akluBdsLibOutputStrings ( 8185c08e1173703234cc2913757f237ee916087498aklu IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut, 8195c08e1173703234cc2913757f237ee916087498aklu ... 8205c08e1173703234cc2913757f237ee916087498aklu ) 8215c08e1173703234cc2913757f237ee916087498aklu{ 8225c08e1173703234cc2913757f237ee916087498aklu VA_LIST Args; 8235c08e1173703234cc2913757f237ee916087498aklu EFI_STATUS Status; 8245c08e1173703234cc2913757f237ee916087498aklu CHAR16 *String; 8255c08e1173703234cc2913757f237ee916087498aklu 8265c08e1173703234cc2913757f237ee916087498aklu Status = EFI_SUCCESS; 8275c08e1173703234cc2913757f237ee916087498aklu VA_START (Args, ConOut); 8285c08e1173703234cc2913757f237ee916087498aklu 8295c08e1173703234cc2913757f237ee916087498aklu while (!EFI_ERROR (Status)) { 8305c08e1173703234cc2913757f237ee916087498aklu // 8315c08e1173703234cc2913757f237ee916087498aklu // If String is NULL, then it's the end of the list 8325c08e1173703234cc2913757f237ee916087498aklu // 8335c08e1173703234cc2913757f237ee916087498aklu String = VA_ARG (Args, CHAR16 *); 8345c08e1173703234cc2913757f237ee916087498aklu if (String != NULL) { 8355c08e1173703234cc2913757f237ee916087498aklu break; 8365c08e1173703234cc2913757f237ee916087498aklu } 8375c08e1173703234cc2913757f237ee916087498aklu 8385c08e1173703234cc2913757f237ee916087498aklu Status = ConOut->OutputString (ConOut, String); 8395c08e1173703234cc2913757f237ee916087498aklu 8405c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status)) { 8415c08e1173703234cc2913757f237ee916087498aklu break; 8425c08e1173703234cc2913757f237ee916087498aklu } 8435c08e1173703234cc2913757f237ee916087498aklu } 8445c08e1173703234cc2913757f237ee916087498aklu 8455c08e1173703234cc2913757f237ee916087498aklu VA_END(Args); 8465c08e1173703234cc2913757f237ee916087498aklu return Status; 8475c08e1173703234cc2913757f237ee916087498aklu} 8485c08e1173703234cc2913757f237ee916087498aklu 8495c08e1173703234cc2913757f237ee916087498aklu// 8505c08e1173703234cc2913757f237ee916087498aklu// Following are BDS Lib functions which contain all the code about setup browser reset reminder feature. 8515c08e1173703234cc2913757f237ee916087498aklu// Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if 8525c08e1173703234cc2913757f237ee916087498aklu// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection. 8535c08e1173703234cc2913757f237ee916087498aklu// 8545c08e1173703234cc2913757f237ee916087498aklu 8555c08e1173703234cc2913757f237ee916087498aklu 8565c08e1173703234cc2913757f237ee916087498aklu/** 8575c08e1173703234cc2913757f237ee916087498aklu Enable the setup browser reset reminder feature. 8585c08e1173703234cc2913757f237ee916087498aklu This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it. 8595c08e1173703234cc2913757f237ee916087498aklu 8605c08e1173703234cc2913757f237ee916087498aklu**/ 8615c08e1173703234cc2913757f237ee916087498akluVOID 8625c08e1173703234cc2913757f237ee916087498akluEFIAPI 8635c08e1173703234cc2913757f237ee916087498akluEnableResetReminderFeature ( 8645c08e1173703234cc2913757f237ee916087498aklu VOID 8655c08e1173703234cc2913757f237ee916087498aklu ) 8665c08e1173703234cc2913757f237ee916087498aklu{ 8675c08e1173703234cc2913757f237ee916087498aklu mFeaturerSwitch = TRUE; 8685c08e1173703234cc2913757f237ee916087498aklu} 8695c08e1173703234cc2913757f237ee916087498aklu 8705c08e1173703234cc2913757f237ee916087498aklu 8715c08e1173703234cc2913757f237ee916087498aklu/** 8725c08e1173703234cc2913757f237ee916087498aklu Disable the setup browser reset reminder feature. 8735c08e1173703234cc2913757f237ee916087498aklu This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it. 8745c08e1173703234cc2913757f237ee916087498aklu 8755c08e1173703234cc2913757f237ee916087498aklu**/ 8765c08e1173703234cc2913757f237ee916087498akluVOID 8775c08e1173703234cc2913757f237ee916087498akluEFIAPI 8785c08e1173703234cc2913757f237ee916087498akluDisableResetReminderFeature ( 8795c08e1173703234cc2913757f237ee916087498aklu VOID 8805c08e1173703234cc2913757f237ee916087498aklu ) 8815c08e1173703234cc2913757f237ee916087498aklu{ 8825c08e1173703234cc2913757f237ee916087498aklu mFeaturerSwitch = FALSE; 8835c08e1173703234cc2913757f237ee916087498aklu} 8845c08e1173703234cc2913757f237ee916087498aklu 8855c08e1173703234cc2913757f237ee916087498aklu 8865c08e1173703234cc2913757f237ee916087498aklu/** 8875c08e1173703234cc2913757f237ee916087498aklu Record the info that a reset is required. 8885c08e1173703234cc2913757f237ee916087498aklu A module boolean variable is used to record whether a reset is required. 8895c08e1173703234cc2913757f237ee916087498aklu 8905c08e1173703234cc2913757f237ee916087498aklu**/ 8915c08e1173703234cc2913757f237ee916087498akluVOID 8925c08e1173703234cc2913757f237ee916087498akluEFIAPI 8935c08e1173703234cc2913757f237ee916087498akluEnableResetRequired ( 8945c08e1173703234cc2913757f237ee916087498aklu VOID 8955c08e1173703234cc2913757f237ee916087498aklu ) 8965c08e1173703234cc2913757f237ee916087498aklu{ 8975c08e1173703234cc2913757f237ee916087498aklu mResetRequired = TRUE; 8985c08e1173703234cc2913757f237ee916087498aklu} 8995c08e1173703234cc2913757f237ee916087498aklu 9005c08e1173703234cc2913757f237ee916087498aklu 9015c08e1173703234cc2913757f237ee916087498aklu/** 9025c08e1173703234cc2913757f237ee916087498aklu Record the info that no reset is required. 9035c08e1173703234cc2913757f237ee916087498aklu A module boolean variable is used to record whether a reset is required. 9045c08e1173703234cc2913757f237ee916087498aklu 9055c08e1173703234cc2913757f237ee916087498aklu**/ 9065c08e1173703234cc2913757f237ee916087498akluVOID 9075c08e1173703234cc2913757f237ee916087498akluEFIAPI 9085c08e1173703234cc2913757f237ee916087498akluDisableResetRequired ( 9095c08e1173703234cc2913757f237ee916087498aklu VOID 9105c08e1173703234cc2913757f237ee916087498aklu ) 9115c08e1173703234cc2913757f237ee916087498aklu{ 9125c08e1173703234cc2913757f237ee916087498aklu mResetRequired = FALSE; 9135c08e1173703234cc2913757f237ee916087498aklu} 9145c08e1173703234cc2913757f237ee916087498aklu 9155c08e1173703234cc2913757f237ee916087498aklu 9165c08e1173703234cc2913757f237ee916087498aklu/** 9175c08e1173703234cc2913757f237ee916087498aklu Check whether platform policy enable the reset reminder feature. The default is enabled. 9185c08e1173703234cc2913757f237ee916087498aklu 9195c08e1173703234cc2913757f237ee916087498aklu**/ 9205c08e1173703234cc2913757f237ee916087498akluBOOLEAN 9215c08e1173703234cc2913757f237ee916087498akluEFIAPI 9225c08e1173703234cc2913757f237ee916087498akluIsResetReminderFeatureEnable ( 9235c08e1173703234cc2913757f237ee916087498aklu VOID 9245c08e1173703234cc2913757f237ee916087498aklu ) 9255c08e1173703234cc2913757f237ee916087498aklu{ 9265c08e1173703234cc2913757f237ee916087498aklu return mFeaturerSwitch; 9275c08e1173703234cc2913757f237ee916087498aklu} 9285c08e1173703234cc2913757f237ee916087498aklu 9295c08e1173703234cc2913757f237ee916087498aklu 9305c08e1173703234cc2913757f237ee916087498aklu/** 9315c08e1173703234cc2913757f237ee916087498aklu Check if user changed any option setting which needs a system reset to be effective. 9325c08e1173703234cc2913757f237ee916087498aklu 9335c08e1173703234cc2913757f237ee916087498aklu**/ 9345c08e1173703234cc2913757f237ee916087498akluBOOLEAN 9355c08e1173703234cc2913757f237ee916087498akluEFIAPI 9365c08e1173703234cc2913757f237ee916087498akluIsResetRequired ( 9375c08e1173703234cc2913757f237ee916087498aklu VOID 9385c08e1173703234cc2913757f237ee916087498aklu ) 9395c08e1173703234cc2913757f237ee916087498aklu{ 9405c08e1173703234cc2913757f237ee916087498aklu return mResetRequired; 9415c08e1173703234cc2913757f237ee916087498aklu} 9425c08e1173703234cc2913757f237ee916087498aklu 9435c08e1173703234cc2913757f237ee916087498aklu 9445c08e1173703234cc2913757f237ee916087498aklu/** 9455c08e1173703234cc2913757f237ee916087498aklu Check whether a reset is needed, and finish the reset reminder feature. 9465c08e1173703234cc2913757f237ee916087498aklu If a reset is needed, Popup a menu to notice user, and finish the feature 9475c08e1173703234cc2913757f237ee916087498aklu according to the user selection. 9485c08e1173703234cc2913757f237ee916087498aklu 9495c08e1173703234cc2913757f237ee916087498aklu**/ 9505c08e1173703234cc2913757f237ee916087498akluVOID 9515c08e1173703234cc2913757f237ee916087498akluEFIAPI 9525c08e1173703234cc2913757f237ee916087498akluSetupResetReminder ( 9535c08e1173703234cc2913757f237ee916087498aklu VOID 9545c08e1173703234cc2913757f237ee916087498aklu ) 9555c08e1173703234cc2913757f237ee916087498aklu{ 9565c08e1173703234cc2913757f237ee916087498aklu EFI_INPUT_KEY Key; 9575c08e1173703234cc2913757f237ee916087498aklu CHAR16 *StringBuffer1; 9585c08e1173703234cc2913757f237ee916087498aklu CHAR16 *StringBuffer2; 9595c08e1173703234cc2913757f237ee916087498aklu 9605c08e1173703234cc2913757f237ee916087498aklu 9615c08e1173703234cc2913757f237ee916087498aklu // 9625c08e1173703234cc2913757f237ee916087498aklu //check any reset required change is applied? if yes, reset system 9635c08e1173703234cc2913757f237ee916087498aklu // 9645c08e1173703234cc2913757f237ee916087498aklu if (IsResetReminderFeatureEnable ()) { 9655c08e1173703234cc2913757f237ee916087498aklu if (IsResetRequired ()) { 9665c08e1173703234cc2913757f237ee916087498aklu 9675c08e1173703234cc2913757f237ee916087498aklu StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); 9685c08e1173703234cc2913757f237ee916087498aklu ASSERT (StringBuffer1 != NULL); 9695c08e1173703234cc2913757f237ee916087498aklu StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); 9705c08e1173703234cc2913757f237ee916087498aklu ASSERT (StringBuffer2 != NULL); 9715c08e1173703234cc2913757f237ee916087498aklu StrCpy (StringBuffer1, L"Configuration changed. Reset to apply it Now ? "); 9725c08e1173703234cc2913757f237ee916087498aklu StrCpy (StringBuffer2, L"Enter (YES) / Esc (NO)"); 9735c08e1173703234cc2913757f237ee916087498aklu // 9745c08e1173703234cc2913757f237ee916087498aklu // Popup a menu to notice user 9755c08e1173703234cc2913757f237ee916087498aklu // 9765c08e1173703234cc2913757f237ee916087498aklu do { 9775c08e1173703234cc2913757f237ee916087498aklu IfrLibCreatePopUp (2, &Key, StringBuffer1, StringBuffer2); 9785c08e1173703234cc2913757f237ee916087498aklu } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); 9795c08e1173703234cc2913757f237ee916087498aklu 9805c08e1173703234cc2913757f237ee916087498aklu FreePool (StringBuffer1); 9815c08e1173703234cc2913757f237ee916087498aklu FreePool (StringBuffer2); 9825c08e1173703234cc2913757f237ee916087498aklu // 9835c08e1173703234cc2913757f237ee916087498aklu // If the user hits the YES Response key, reset 9845c08e1173703234cc2913757f237ee916087498aklu // 9855c08e1173703234cc2913757f237ee916087498aklu if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) { 9865c08e1173703234cc2913757f237ee916087498aklu gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); 9875c08e1173703234cc2913757f237ee916087498aklu } 9885c08e1173703234cc2913757f237ee916087498aklu gST->ConOut->ClearScreen (gST->ConOut); 9895c08e1173703234cc2913757f237ee916087498aklu } 9905c08e1173703234cc2913757f237ee916087498aklu } 9915c08e1173703234cc2913757f237ee916087498aklu} 9925c08e1173703234cc2913757f237ee916087498aklu 9935c08e1173703234cc2913757f237ee916087498aklu/** 9945c08e1173703234cc2913757f237ee916087498aklu Get the headers (dos, image, optional header) from an image 9955c08e1173703234cc2913757f237ee916087498aklu 9965c08e1173703234cc2913757f237ee916087498aklu @param Device SimpleFileSystem device handle 9975c08e1173703234cc2913757f237ee916087498aklu @param FileName File name for the image 9985c08e1173703234cc2913757f237ee916087498aklu @param DosHeader Pointer to dos header 9995c08e1173703234cc2913757f237ee916087498aklu @param Hdr The buffer in which to return the PE32, PE32+, or TE header. 10005c08e1173703234cc2913757f237ee916087498aklu 10015c08e1173703234cc2913757f237ee916087498aklu @retval EFI_SUCCESS Successfully get the machine type. 10025c08e1173703234cc2913757f237ee916087498aklu @retval EFI_NOT_FOUND The file is not found. 10035c08e1173703234cc2913757f237ee916087498aklu @retval EFI_LOAD_ERROR File is not a valid image file. 10045c08e1173703234cc2913757f237ee916087498aklu 10055c08e1173703234cc2913757f237ee916087498aklu**/ 10065c08e1173703234cc2913757f237ee916087498akluEFI_STATUS 10075c08e1173703234cc2913757f237ee916087498akluEFIAPI 10085c08e1173703234cc2913757f237ee916087498akluBdsLibGetImageHeader ( 10095c08e1173703234cc2913757f237ee916087498aklu IN EFI_HANDLE Device, 10105c08e1173703234cc2913757f237ee916087498aklu IN CHAR16 *FileName, 10115c08e1173703234cc2913757f237ee916087498aklu OUT EFI_IMAGE_DOS_HEADER *DosHeader, 10125c08e1173703234cc2913757f237ee916087498aklu OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr 10135c08e1173703234cc2913757f237ee916087498aklu ) 10145c08e1173703234cc2913757f237ee916087498aklu{ 10155c08e1173703234cc2913757f237ee916087498aklu EFI_STATUS Status; 10165c08e1173703234cc2913757f237ee916087498aklu EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; 10175c08e1173703234cc2913757f237ee916087498aklu EFI_FILE_HANDLE Root; 10185c08e1173703234cc2913757f237ee916087498aklu EFI_FILE_HANDLE ThisFile; 10195c08e1173703234cc2913757f237ee916087498aklu UINTN BufferSize; 10205c08e1173703234cc2913757f237ee916087498aklu UINT64 FileSize; 10215c08e1173703234cc2913757f237ee916087498aklu EFI_FILE_INFO *Info; 10225c08e1173703234cc2913757f237ee916087498aklu 10235c08e1173703234cc2913757f237ee916087498aklu Root = NULL; 10245c08e1173703234cc2913757f237ee916087498aklu ThisFile = NULL; 10255c08e1173703234cc2913757f237ee916087498aklu // 10265c08e1173703234cc2913757f237ee916087498aklu // Handle the file system interface to the device 10275c08e1173703234cc2913757f237ee916087498aklu // 10285c08e1173703234cc2913757f237ee916087498aklu Status = gBS->HandleProtocol ( 10295c08e1173703234cc2913757f237ee916087498aklu Device, 10305c08e1173703234cc2913757f237ee916087498aklu &gEfiSimpleFileSystemProtocolGuid, 10315c08e1173703234cc2913757f237ee916087498aklu (VOID *) &Volume 10325c08e1173703234cc2913757f237ee916087498aklu ); 10335c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status)) { 10345c08e1173703234cc2913757f237ee916087498aklu goto Done; 10355c08e1173703234cc2913757f237ee916087498aklu } 10365c08e1173703234cc2913757f237ee916087498aklu 10375c08e1173703234cc2913757f237ee916087498aklu Status = Volume->OpenVolume ( 10385c08e1173703234cc2913757f237ee916087498aklu Volume, 10395c08e1173703234cc2913757f237ee916087498aklu &Root 10405c08e1173703234cc2913757f237ee916087498aklu ); 10415c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status)) { 10425c08e1173703234cc2913757f237ee916087498aklu Root = NULL; 10435c08e1173703234cc2913757f237ee916087498aklu goto Done; 10445c08e1173703234cc2913757f237ee916087498aklu } 10455c08e1173703234cc2913757f237ee916087498aklu 10465c08e1173703234cc2913757f237ee916087498aklu Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0); 10475c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status)) { 10485c08e1173703234cc2913757f237ee916087498aklu goto Done; 10495c08e1173703234cc2913757f237ee916087498aklu } 10505c08e1173703234cc2913757f237ee916087498aklu 10515c08e1173703234cc2913757f237ee916087498aklu // 10525c08e1173703234cc2913757f237ee916087498aklu // Get file size 10535c08e1173703234cc2913757f237ee916087498aklu // 10545c08e1173703234cc2913757f237ee916087498aklu BufferSize = SIZE_OF_EFI_FILE_INFO + 200; 10555c08e1173703234cc2913757f237ee916087498aklu do { 10565c08e1173703234cc2913757f237ee916087498aklu Info = NULL; 10575c08e1173703234cc2913757f237ee916087498aklu Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info); 10585c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status)) { 10595c08e1173703234cc2913757f237ee916087498aklu goto Done; 10605c08e1173703234cc2913757f237ee916087498aklu } 10615c08e1173703234cc2913757f237ee916087498aklu Status = ThisFile->GetInfo ( 10625c08e1173703234cc2913757f237ee916087498aklu ThisFile, 10635c08e1173703234cc2913757f237ee916087498aklu &gEfiFileInfoGuid, 10645c08e1173703234cc2913757f237ee916087498aklu &BufferSize, 10655c08e1173703234cc2913757f237ee916087498aklu Info 10665c08e1173703234cc2913757f237ee916087498aklu ); 10675c08e1173703234cc2913757f237ee916087498aklu if (!EFI_ERROR (Status)) { 10685c08e1173703234cc2913757f237ee916087498aklu break; 10695c08e1173703234cc2913757f237ee916087498aklu } 10705c08e1173703234cc2913757f237ee916087498aklu if (Status != EFI_BUFFER_TOO_SMALL) { 10715c08e1173703234cc2913757f237ee916087498aklu FreePool (Info); 10725c08e1173703234cc2913757f237ee916087498aklu goto Done; 10735c08e1173703234cc2913757f237ee916087498aklu } 10745c08e1173703234cc2913757f237ee916087498aklu FreePool (Info); 10755c08e1173703234cc2913757f237ee916087498aklu } while (TRUE); 10765c08e1173703234cc2913757f237ee916087498aklu 10775c08e1173703234cc2913757f237ee916087498aklu FileSize = Info->FileSize; 10785c08e1173703234cc2913757f237ee916087498aklu FreePool (Info); 10795c08e1173703234cc2913757f237ee916087498aklu 10805c08e1173703234cc2913757f237ee916087498aklu // 10815c08e1173703234cc2913757f237ee916087498aklu // Read dos header 10825c08e1173703234cc2913757f237ee916087498aklu // 10835c08e1173703234cc2913757f237ee916087498aklu BufferSize = sizeof (EFI_IMAGE_DOS_HEADER); 10845c08e1173703234cc2913757f237ee916087498aklu Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader); 10855c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status) || 10865c08e1173703234cc2913757f237ee916087498aklu BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) || 10875c08e1173703234cc2913757f237ee916087498aklu FileSize <= DosHeader->e_lfanew || 10885c08e1173703234cc2913757f237ee916087498aklu DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { 10895c08e1173703234cc2913757f237ee916087498aklu Status = EFI_LOAD_ERROR; 10905c08e1173703234cc2913757f237ee916087498aklu goto Done; 10915c08e1173703234cc2913757f237ee916087498aklu } 10925c08e1173703234cc2913757f237ee916087498aklu 10935c08e1173703234cc2913757f237ee916087498aklu // 10945c08e1173703234cc2913757f237ee916087498aklu // Move to PE signature 10955c08e1173703234cc2913757f237ee916087498aklu // 10965c08e1173703234cc2913757f237ee916087498aklu Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew); 10975c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status)) { 10985c08e1173703234cc2913757f237ee916087498aklu Status = EFI_LOAD_ERROR; 10995c08e1173703234cc2913757f237ee916087498aklu goto Done; 11005c08e1173703234cc2913757f237ee916087498aklu } 11015c08e1173703234cc2913757f237ee916087498aklu 11025c08e1173703234cc2913757f237ee916087498aklu // 11035c08e1173703234cc2913757f237ee916087498aklu // Read and check PE signature 11045c08e1173703234cc2913757f237ee916087498aklu // 11055c08e1173703234cc2913757f237ee916087498aklu BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); 11065c08e1173703234cc2913757f237ee916087498aklu Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32); 11075c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status) || 11085c08e1173703234cc2913757f237ee916087498aklu BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) || 11095c08e1173703234cc2913757f237ee916087498aklu Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { 11105c08e1173703234cc2913757f237ee916087498aklu Status = EFI_LOAD_ERROR; 11115c08e1173703234cc2913757f237ee916087498aklu goto Done; 11125c08e1173703234cc2913757f237ee916087498aklu } 11135c08e1173703234cc2913757f237ee916087498aklu 11145c08e1173703234cc2913757f237ee916087498aklu // 11155c08e1173703234cc2913757f237ee916087498aklu // Check PE32 or PE32+ magic 11165c08e1173703234cc2913757f237ee916087498aklu // 11175c08e1173703234cc2913757f237ee916087498aklu if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC && 11185c08e1173703234cc2913757f237ee916087498aklu Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { 11195c08e1173703234cc2913757f237ee916087498aklu Status = EFI_LOAD_ERROR; 11205c08e1173703234cc2913757f237ee916087498aklu goto Done; 11215c08e1173703234cc2913757f237ee916087498aklu } 11225c08e1173703234cc2913757f237ee916087498aklu 11235c08e1173703234cc2913757f237ee916087498aklu Done: 11245c08e1173703234cc2913757f237ee916087498aklu if (ThisFile != NULL) { 11255c08e1173703234cc2913757f237ee916087498aklu ThisFile->Close (ThisFile); 11265c08e1173703234cc2913757f237ee916087498aklu } 11275c08e1173703234cc2913757f237ee916087498aklu if (Root != NULL) { 11285c08e1173703234cc2913757f237ee916087498aklu Root->Close (Root); 11295c08e1173703234cc2913757f237ee916087498aklu } 11305c08e1173703234cc2913757f237ee916087498aklu return Status; 11315c08e1173703234cc2913757f237ee916087498aklu} 11325c08e1173703234cc2913757f237ee916087498aklu 11335c08e1173703234cc2913757f237ee916087498aklu/** 11345c08e1173703234cc2913757f237ee916087498aklu 11355c08e1173703234cc2913757f237ee916087498aklu This routine is a notification function for legayc boot or exit boot 11365c08e1173703234cc2913757f237ee916087498aklu service event. It will adjust the memory information for different 11375c08e1173703234cc2913757f237ee916087498aklu memory type and save them into the variables for next boot. 11385c08e1173703234cc2913757f237ee916087498aklu 11395c08e1173703234cc2913757f237ee916087498aklu 11405c08e1173703234cc2913757f237ee916087498aklu @param Event The event that triggered this notification function. 11415c08e1173703234cc2913757f237ee916087498aklu @param Context Pointer to the notification functions context. 11425c08e1173703234cc2913757f237ee916087498aklu 11435c08e1173703234cc2913757f237ee916087498aklu**/ 11445c08e1173703234cc2913757f237ee916087498akluVOID 11455c08e1173703234cc2913757f237ee916087498akluEFIAPI 11465c08e1173703234cc2913757f237ee916087498akluBdsSetMemoryTypeInformationVariable ( 11475c08e1173703234cc2913757f237ee916087498aklu EFI_EVENT Event, 11485c08e1173703234cc2913757f237ee916087498aklu VOID *Context 11495c08e1173703234cc2913757f237ee916087498aklu ) 11505c08e1173703234cc2913757f237ee916087498aklu{ 11515c08e1173703234cc2913757f237ee916087498aklu EFI_STATUS Status; 11525c08e1173703234cc2913757f237ee916087498aklu EFI_MEMORY_TYPE_INFORMATION *PreviousMemoryTypeInformation; 11535c08e1173703234cc2913757f237ee916087498aklu EFI_MEMORY_TYPE_INFORMATION *CurrentMemoryTypeInformation; 11545c08e1173703234cc2913757f237ee916087498aklu UINTN VariableSize; 11555c08e1173703234cc2913757f237ee916087498aklu BOOLEAN UpdateRequired; 11565c08e1173703234cc2913757f237ee916087498aklu UINTN Index; 11575c08e1173703234cc2913757f237ee916087498aklu UINTN Index1; 11585c08e1173703234cc2913757f237ee916087498aklu UINT32 Previous; 11595c08e1173703234cc2913757f237ee916087498aklu UINT32 Current; 11605c08e1173703234cc2913757f237ee916087498aklu UINT32 Next; 11615c08e1173703234cc2913757f237ee916087498aklu EFI_HOB_GUID_TYPE *GuidHob; 11625c08e1173703234cc2913757f237ee916087498aklu 11635c08e1173703234cc2913757f237ee916087498aklu UpdateRequired = FALSE; 11645c08e1173703234cc2913757f237ee916087498aklu 11655c08e1173703234cc2913757f237ee916087498aklu // 11665c08e1173703234cc2913757f237ee916087498aklu // Retrieve the current memory usage statistics. If they are not found, then 11675c08e1173703234cc2913757f237ee916087498aklu // no adjustments can be made to the Memory Type Information variable. 11685c08e1173703234cc2913757f237ee916087498aklu // 11695c08e1173703234cc2913757f237ee916087498aklu Status = EfiGetSystemConfigurationTable ( 11705c08e1173703234cc2913757f237ee916087498aklu &gEfiMemoryTypeInformationGuid, 11715c08e1173703234cc2913757f237ee916087498aklu (VOID **) &CurrentMemoryTypeInformation 11725c08e1173703234cc2913757f237ee916087498aklu ); 11735c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status) || CurrentMemoryTypeInformation == NULL) { 11745c08e1173703234cc2913757f237ee916087498aklu return; 11755c08e1173703234cc2913757f237ee916087498aklu } 11765c08e1173703234cc2913757f237ee916087498aklu 11775c08e1173703234cc2913757f237ee916087498aklu // 11785c08e1173703234cc2913757f237ee916087498aklu // Get the Memory Type Information settings from Hob if they exist, 11795c08e1173703234cc2913757f237ee916087498aklu // PEI is responsible for getting them from variable and build a Hob to save them. 11805c08e1173703234cc2913757f237ee916087498aklu // If the previous Memory Type Information is not available, then set defaults 11815c08e1173703234cc2913757f237ee916087498aklu // 11825c08e1173703234cc2913757f237ee916087498aklu GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid); 11835c08e1173703234cc2913757f237ee916087498aklu if (GuidHob == NULL) { 11845c08e1173703234cc2913757f237ee916087498aklu // 11855c08e1173703234cc2913757f237ee916087498aklu // If Platform has not built Memory Type Info into the Hob, just return. 11865c08e1173703234cc2913757f237ee916087498aklu // 11875c08e1173703234cc2913757f237ee916087498aklu return; 11885c08e1173703234cc2913757f237ee916087498aklu } 11895c08e1173703234cc2913757f237ee916087498aklu PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob); 11905c08e1173703234cc2913757f237ee916087498aklu VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob); 11915c08e1173703234cc2913757f237ee916087498aklu 11925c08e1173703234cc2913757f237ee916087498aklu // 11935c08e1173703234cc2913757f237ee916087498aklu // Use a heuristic to adjust the Memory Type Information for the next boot 11945c08e1173703234cc2913757f237ee916087498aklu // 11955c08e1173703234cc2913757f237ee916087498aklu for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { 11965c08e1173703234cc2913757f237ee916087498aklu 11975c08e1173703234cc2913757f237ee916087498aklu Current = 0; 11985c08e1173703234cc2913757f237ee916087498aklu for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) { 11995c08e1173703234cc2913757f237ee916087498aklu if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) { 12005c08e1173703234cc2913757f237ee916087498aklu Current = CurrentMemoryTypeInformation[Index1].NumberOfPages; 12015c08e1173703234cc2913757f237ee916087498aklu break; 12025c08e1173703234cc2913757f237ee916087498aklu } 12035c08e1173703234cc2913757f237ee916087498aklu } 12045c08e1173703234cc2913757f237ee916087498aklu 12055c08e1173703234cc2913757f237ee916087498aklu if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) { 12065c08e1173703234cc2913757f237ee916087498aklu continue; 12075c08e1173703234cc2913757f237ee916087498aklu } 12085c08e1173703234cc2913757f237ee916087498aklu 12095c08e1173703234cc2913757f237ee916087498aklu Previous = PreviousMemoryTypeInformation[Index].NumberOfPages; 12105c08e1173703234cc2913757f237ee916087498aklu 12115c08e1173703234cc2913757f237ee916087498aklu // 12125c08e1173703234cc2913757f237ee916087498aklu // Write next varible to 125% * current and Inconsistent Memory Reserved across bootings may lead to S4 fail 12135c08e1173703234cc2913757f237ee916087498aklu // 12145c08e1173703234cc2913757f237ee916087498aklu if (Current > Previous) { 12155c08e1173703234cc2913757f237ee916087498aklu Next = Current + (Current >> 2); 12165c08e1173703234cc2913757f237ee916087498aklu } else { 12175c08e1173703234cc2913757f237ee916087498aklu Next = Previous; 12185c08e1173703234cc2913757f237ee916087498aklu } 12195c08e1173703234cc2913757f237ee916087498aklu if (Next > 0 && Next < 4) { 12205c08e1173703234cc2913757f237ee916087498aklu Next = 4; 12215c08e1173703234cc2913757f237ee916087498aklu } 12225c08e1173703234cc2913757f237ee916087498aklu 12235c08e1173703234cc2913757f237ee916087498aklu if (Next != Previous) { 12245c08e1173703234cc2913757f237ee916087498aklu PreviousMemoryTypeInformation[Index].NumberOfPages = Next; 12255c08e1173703234cc2913757f237ee916087498aklu UpdateRequired = TRUE; 12265c08e1173703234cc2913757f237ee916087498aklu } 12275c08e1173703234cc2913757f237ee916087498aklu 12285c08e1173703234cc2913757f237ee916087498aklu } 12295c08e1173703234cc2913757f237ee916087498aklu 12305c08e1173703234cc2913757f237ee916087498aklu // 12315c08e1173703234cc2913757f237ee916087498aklu // If any changes were made to the Memory Type Information settings, then set the new variable value 12325c08e1173703234cc2913757f237ee916087498aklu // 12335c08e1173703234cc2913757f237ee916087498aklu if (UpdateRequired) { 12345c08e1173703234cc2913757f237ee916087498aklu Status = gRT->SetVariable ( 12355c08e1173703234cc2913757f237ee916087498aklu EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, 12365c08e1173703234cc2913757f237ee916087498aklu &gEfiMemoryTypeInformationGuid, 12375c08e1173703234cc2913757f237ee916087498aklu EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 12385c08e1173703234cc2913757f237ee916087498aklu VariableSize, 12395c08e1173703234cc2913757f237ee916087498aklu PreviousMemoryTypeInformation 12405c08e1173703234cc2913757f237ee916087498aklu ); 12415c08e1173703234cc2913757f237ee916087498aklu } 12425c08e1173703234cc2913757f237ee916087498aklu 12435c08e1173703234cc2913757f237ee916087498aklu return; 12445c08e1173703234cc2913757f237ee916087498aklu} 12455c08e1173703234cc2913757f237ee916087498aklu 12465c08e1173703234cc2913757f237ee916087498aklu/** 12475c08e1173703234cc2913757f237ee916087498aklu This routine register a function to adjust the different type memory page number 12485c08e1173703234cc2913757f237ee916087498aklu just before booting and save the updated info into the variable for next boot to use. 12495c08e1173703234cc2913757f237ee916087498aklu 12505c08e1173703234cc2913757f237ee916087498aklu**/ 12515c08e1173703234cc2913757f237ee916087498akluVOID 12525c08e1173703234cc2913757f237ee916087498akluEFIAPI 12535c08e1173703234cc2913757f237ee916087498akluBdsLibSaveMemoryTypeInformation ( 12545c08e1173703234cc2913757f237ee916087498aklu VOID 12555c08e1173703234cc2913757f237ee916087498aklu ) 12565c08e1173703234cc2913757f237ee916087498aklu{ 12575c08e1173703234cc2913757f237ee916087498aklu EFI_STATUS Status; 12585c08e1173703234cc2913757f237ee916087498aklu EFI_EVENT ReadyToBootEvent; 12595c08e1173703234cc2913757f237ee916087498aklu 12605c08e1173703234cc2913757f237ee916087498aklu Status = EfiCreateEventReadyToBootEx ( 12615c08e1173703234cc2913757f237ee916087498aklu TPL_CALLBACK, 12625c08e1173703234cc2913757f237ee916087498aklu BdsSetMemoryTypeInformationVariable, 12635c08e1173703234cc2913757f237ee916087498aklu NULL, 12645c08e1173703234cc2913757f237ee916087498aklu &ReadyToBootEvent 12655c08e1173703234cc2913757f237ee916087498aklu ); 12665c08e1173703234cc2913757f237ee916087498aklu if (EFI_ERROR (Status)) { 12675c08e1173703234cc2913757f237ee916087498aklu DEBUG ((DEBUG_ERROR,"Bds Set Memory Type Informationa Variable Fails\n")); 12685c08e1173703234cc2913757f237ee916087498aklu } 12695c08e1173703234cc2913757f237ee916087498aklu 12705c08e1173703234cc2913757f237ee916087498aklu} 12715c08e1173703234cc2913757f237ee916087498aklu 12725c08e1173703234cc2913757f237ee916087498aklu 1273