11e57a46299244793beb27e74be171d1540606999oliviermartin/** @file 21e57a46299244793beb27e74be171d1540606999oliviermartin* 3c0b2e4775dcb06d9016f17f5d22e6276d9b58397oliviermartin* Copyright (c) 2011-2013, ARM Limited. All rights reserved. 41e57a46299244793beb27e74be171d1540606999oliviermartin* 51e57a46299244793beb27e74be171d1540606999oliviermartin* This program and the accompanying materials 61e57a46299244793beb27e74be171d1540606999oliviermartin* are licensed and made available under the terms and conditions of the BSD License 71e57a46299244793beb27e74be171d1540606999oliviermartin* which accompanies this distribution. The full text of the license may be found at 81e57a46299244793beb27e74be171d1540606999oliviermartin* http://opensource.org/licenses/bsd-license.php 91e57a46299244793beb27e74be171d1540606999oliviermartin* 101e57a46299244793beb27e74be171d1540606999oliviermartin* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 111e57a46299244793beb27e74be171d1540606999oliviermartin* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 121e57a46299244793beb27e74be171d1540606999oliviermartin* 131e57a46299244793beb27e74be171d1540606999oliviermartin**/ 141e57a46299244793beb27e74be171d1540606999oliviermartin 151e57a46299244793beb27e74be171d1540606999oliviermartin#include "BdsInternal.h" 161e57a46299244793beb27e74be171d1540606999oliviermartin 171e57a46299244793beb27e74be171d1540606999oliviermartinEFI_STATUS 181e57a46299244793beb27e74be171d1540606999oliviermartinBootOptionParseLoadOption ( 19459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel IN EFI_LOAD_OPTION *EfiLoadOption, 201e57a46299244793beb27e74be171d1540606999oliviermartin IN UINTN EfiLoadOptionSize, 211e57a46299244793beb27e74be171d1540606999oliviermartin IN OUT BDS_LOAD_OPTION **BdsLoadOption 221e57a46299244793beb27e74be171d1540606999oliviermartin ) 231e57a46299244793beb27e74be171d1540606999oliviermartin{ 241e57a46299244793beb27e74be171d1540606999oliviermartin BDS_LOAD_OPTION *LoadOption; 251e57a46299244793beb27e74be171d1540606999oliviermartin UINTN DescriptionLength; 26459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel UINTN EfiLoadOptionPtr; 271e57a46299244793beb27e74be171d1540606999oliviermartin 281e57a46299244793beb27e74be171d1540606999oliviermartin if (EfiLoadOption == NULL) { 291e57a46299244793beb27e74be171d1540606999oliviermartin return EFI_INVALID_PARAMETER; 301e57a46299244793beb27e74be171d1540606999oliviermartin } 311e57a46299244793beb27e74be171d1540606999oliviermartin 321e57a46299244793beb27e74be171d1540606999oliviermartin if (EfiLoadOptionSize < sizeof(UINT32) + sizeof(UINT16) + sizeof(CHAR16) + sizeof(EFI_DEVICE_PATH_PROTOCOL)) { 331e57a46299244793beb27e74be171d1540606999oliviermartin return EFI_BAD_BUFFER_SIZE; 341e57a46299244793beb27e74be171d1540606999oliviermartin } 351e57a46299244793beb27e74be171d1540606999oliviermartin 361e57a46299244793beb27e74be171d1540606999oliviermartin if (*BdsLoadOption == NULL) { 371e57a46299244793beb27e74be171d1540606999oliviermartin LoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION)); 381e57a46299244793beb27e74be171d1540606999oliviermartin if (LoadOption == NULL) { 391e57a46299244793beb27e74be171d1540606999oliviermartin return EFI_OUT_OF_RESOURCES; 401e57a46299244793beb27e74be171d1540606999oliviermartin } 411e57a46299244793beb27e74be171d1540606999oliviermartin } else { 421e57a46299244793beb27e74be171d1540606999oliviermartin LoadOption = *BdsLoadOption; 431e57a46299244793beb27e74be171d1540606999oliviermartin } 441e57a46299244793beb27e74be171d1540606999oliviermartin 45459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel EfiLoadOptionPtr = (UINTN)EfiLoadOption; 461e57a46299244793beb27e74be171d1540606999oliviermartin LoadOption->LoadOption = EfiLoadOption; 471e57a46299244793beb27e74be171d1540606999oliviermartin LoadOption->LoadOptionSize = EfiLoadOptionSize; 481e57a46299244793beb27e74be171d1540606999oliviermartin 49459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel LoadOption->Attributes = *(UINT32*)EfiLoadOptionPtr; 50459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel LoadOption->FilePathListLength = *(UINT16*)(EfiLoadOptionPtr + sizeof(UINT32)); 51459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel LoadOption->Description = (CHAR16*)(EfiLoadOptionPtr + sizeof(UINT32) + sizeof(UINT16)); 521e57a46299244793beb27e74be171d1540606999oliviermartin DescriptionLength = StrSize (LoadOption->Description); 53459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel LoadOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)(EfiLoadOptionPtr + sizeof(UINT32) + sizeof(UINT16) + DescriptionLength); 541e57a46299244793beb27e74be171d1540606999oliviermartin 551e57a46299244793beb27e74be171d1540606999oliviermartin // If ((End of EfiLoadOptiony - Start of EfiLoadOption) == EfiLoadOptionSize) then No Optional Data 56459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel if ((UINTN)((UINTN)LoadOption->FilePathList + LoadOption->FilePathListLength - EfiLoadOptionPtr) == EfiLoadOptionSize) { 571e57a46299244793beb27e74be171d1540606999oliviermartin LoadOption->OptionalData = NULL; 581e57a46299244793beb27e74be171d1540606999oliviermartin LoadOption->OptionalDataSize = 0; 591e57a46299244793beb27e74be171d1540606999oliviermartin } else { 601e57a46299244793beb27e74be171d1540606999oliviermartin LoadOption->OptionalData = (VOID*)((UINTN)(LoadOption->FilePathList) + LoadOption->FilePathListLength); 61459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel LoadOption->OptionalDataSize = EfiLoadOptionSize - ((UINTN)LoadOption->OptionalData - EfiLoadOptionPtr); 621e57a46299244793beb27e74be171d1540606999oliviermartin } 631e57a46299244793beb27e74be171d1540606999oliviermartin 641e57a46299244793beb27e74be171d1540606999oliviermartin if (*BdsLoadOption == NULL) { 651e57a46299244793beb27e74be171d1540606999oliviermartin *BdsLoadOption = LoadOption; 661e57a46299244793beb27e74be171d1540606999oliviermartin } 671e57a46299244793beb27e74be171d1540606999oliviermartin 681e57a46299244793beb27e74be171d1540606999oliviermartin return EFI_SUCCESS; 691e57a46299244793beb27e74be171d1540606999oliviermartin} 701e57a46299244793beb27e74be171d1540606999oliviermartin 711e57a46299244793beb27e74be171d1540606999oliviermartinEFI_STATUS 721e57a46299244793beb27e74be171d1540606999oliviermartinBootOptionFromLoadOptionVariable ( 731e57a46299244793beb27e74be171d1540606999oliviermartin IN CHAR16* BootVariableName, 741e57a46299244793beb27e74be171d1540606999oliviermartin OUT BDS_LOAD_OPTION** BdsLoadOption 751e57a46299244793beb27e74be171d1540606999oliviermartin ) 761e57a46299244793beb27e74be171d1540606999oliviermartin{ 771e57a46299244793beb27e74be171d1540606999oliviermartin EFI_STATUS Status; 78459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel EFI_LOAD_OPTION *EfiLoadOption; 791e57a46299244793beb27e74be171d1540606999oliviermartin UINTN EfiLoadOptionSize; 801e57a46299244793beb27e74be171d1540606999oliviermartin 81c0b2e4775dcb06d9016f17f5d22e6276d9b58397oliviermartin Status = GetGlobalEnvironmentVariable (BootVariableName, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption); 821e57a46299244793beb27e74be171d1540606999oliviermartin if (!EFI_ERROR(Status)) { 831e57a46299244793beb27e74be171d1540606999oliviermartin *BdsLoadOption = NULL; 841e57a46299244793beb27e74be171d1540606999oliviermartin Status = BootOptionParseLoadOption (EfiLoadOption, EfiLoadOptionSize, BdsLoadOption); 851e57a46299244793beb27e74be171d1540606999oliviermartin } 861e57a46299244793beb27e74be171d1540606999oliviermartin 871e57a46299244793beb27e74be171d1540606999oliviermartin return Status; 881e57a46299244793beb27e74be171d1540606999oliviermartin} 891e57a46299244793beb27e74be171d1540606999oliviermartin 901e57a46299244793beb27e74be171d1540606999oliviermartinEFI_STATUS 911e57a46299244793beb27e74be171d1540606999oliviermartinBootOptionFromLoadOptionIndex ( 921e57a46299244793beb27e74be171d1540606999oliviermartin IN UINT16 LoadOptionIndex, 931e57a46299244793beb27e74be171d1540606999oliviermartin OUT BDS_LOAD_OPTION **BdsLoadOption 941e57a46299244793beb27e74be171d1540606999oliviermartin ) 951e57a46299244793beb27e74be171d1540606999oliviermartin{ 961e57a46299244793beb27e74be171d1540606999oliviermartin CHAR16 BootVariableName[9]; 971e57a46299244793beb27e74be171d1540606999oliviermartin EFI_STATUS Status; 981e57a46299244793beb27e74be171d1540606999oliviermartin 991e57a46299244793beb27e74be171d1540606999oliviermartin UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", LoadOptionIndex); 1001e57a46299244793beb27e74be171d1540606999oliviermartin 1011e57a46299244793beb27e74be171d1540606999oliviermartin Status = BootOptionFromLoadOptionVariable (BootVariableName, BdsLoadOption); 1021e57a46299244793beb27e74be171d1540606999oliviermartin if (!EFI_ERROR(Status)) { 1031e57a46299244793beb27e74be171d1540606999oliviermartin (*BdsLoadOption)->LoadOptionIndex = LoadOptionIndex; 1041e57a46299244793beb27e74be171d1540606999oliviermartin } 1051e57a46299244793beb27e74be171d1540606999oliviermartin 1061e57a46299244793beb27e74be171d1540606999oliviermartin return Status; 1071e57a46299244793beb27e74be171d1540606999oliviermartin} 1081e57a46299244793beb27e74be171d1540606999oliviermartin 1091e57a46299244793beb27e74be171d1540606999oliviermartinEFI_STATUS 1101e57a46299244793beb27e74be171d1540606999oliviermartinBootOptionToLoadOptionVariable ( 1111e57a46299244793beb27e74be171d1540606999oliviermartin IN BDS_LOAD_OPTION* BdsLoadOption 1121e57a46299244793beb27e74be171d1540606999oliviermartin ) 1131e57a46299244793beb27e74be171d1540606999oliviermartin{ 1141e57a46299244793beb27e74be171d1540606999oliviermartin EFI_STATUS Status; 1151e57a46299244793beb27e74be171d1540606999oliviermartin UINTN DescriptionSize; 1161e57a46299244793beb27e74be171d1540606999oliviermartin //UINT16 FilePathListLength; 1171e57a46299244793beb27e74be171d1540606999oliviermartin EFI_DEVICE_PATH_PROTOCOL* DevicePathNode; 1181e57a46299244793beb27e74be171d1540606999oliviermartin UINTN NodeLength; 1191e57a46299244793beb27e74be171d1540606999oliviermartin UINT8* EfiLoadOptionPtr; 1201e57a46299244793beb27e74be171d1540606999oliviermartin VOID* OldLoadOption; 1211e57a46299244793beb27e74be171d1540606999oliviermartin CHAR16 BootVariableName[9]; 1221e57a46299244793beb27e74be171d1540606999oliviermartin UINTN BootOrderSize; 1231e57a46299244793beb27e74be171d1540606999oliviermartin UINT16* BootOrder; 1241e57a46299244793beb27e74be171d1540606999oliviermartin 1251e57a46299244793beb27e74be171d1540606999oliviermartin // If we are overwriting an existent Boot Option then we have to free previously allocated memory 1261e57a46299244793beb27e74be171d1540606999oliviermartin if (BdsLoadOption->LoadOptionSize > 0) { 1271e57a46299244793beb27e74be171d1540606999oliviermartin OldLoadOption = BdsLoadOption->LoadOption; 1281e57a46299244793beb27e74be171d1540606999oliviermartin } else { 1291e57a46299244793beb27e74be171d1540606999oliviermartin OldLoadOption = NULL; 1301e57a46299244793beb27e74be171d1540606999oliviermartin 1311e57a46299244793beb27e74be171d1540606999oliviermartin // If this function is called at the creation of the Boot Device entry (not at the update) the 1321e57a46299244793beb27e74be171d1540606999oliviermartin // BootOption->LoadOptionSize must be zero then we get a new BootIndex for this entry 1331e57a46299244793beb27e74be171d1540606999oliviermartin BdsLoadOption->LoadOptionIndex = BootOptionAllocateBootIndex (); 1341e57a46299244793beb27e74be171d1540606999oliviermartin 1351e57a46299244793beb27e74be171d1540606999oliviermartin //TODO: Add to the the Boot Entry List 1361e57a46299244793beb27e74be171d1540606999oliviermartin } 1371e57a46299244793beb27e74be171d1540606999oliviermartin 1381e57a46299244793beb27e74be171d1540606999oliviermartin DescriptionSize = StrSize(BdsLoadOption->Description); 1391e57a46299244793beb27e74be171d1540606999oliviermartin 1401e57a46299244793beb27e74be171d1540606999oliviermartin // Ensure the FilePathListLength information is correct 1411e57a46299244793beb27e74be171d1540606999oliviermartin ASSERT (GetDevicePathSize (BdsLoadOption->FilePathList) == BdsLoadOption->FilePathListLength); 1421e57a46299244793beb27e74be171d1540606999oliviermartin 1431e57a46299244793beb27e74be171d1540606999oliviermartin // Allocate the memory for the EFI Load Option 1441e57a46299244793beb27e74be171d1540606999oliviermartin BdsLoadOption->LoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + DescriptionSize + BdsLoadOption->FilePathListLength + BdsLoadOption->OptionalDataSize; 1451e57a46299244793beb27e74be171d1540606999oliviermartin 146459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel BdsLoadOption->LoadOption = (EFI_LOAD_OPTION *)AllocateZeroPool (BdsLoadOption->LoadOptionSize); 1471e57a46299244793beb27e74be171d1540606999oliviermartin if (BdsLoadOption->LoadOption == NULL) { 1481e57a46299244793beb27e74be171d1540606999oliviermartin return EFI_OUT_OF_RESOURCES; 1491e57a46299244793beb27e74be171d1540606999oliviermartin } 1501e57a46299244793beb27e74be171d1540606999oliviermartin 151459823d9b24cd27e91d264dbd23c9ab699c34307Ard Biesheuvel EfiLoadOptionPtr = (UINT8 *) BdsLoadOption->LoadOption; 1521e57a46299244793beb27e74be171d1540606999oliviermartin 1531e57a46299244793beb27e74be171d1540606999oliviermartin // 1541e57a46299244793beb27e74be171d1540606999oliviermartin // Populate the EFI Load Option and BDS Boot Option structures 1551e57a46299244793beb27e74be171d1540606999oliviermartin // 1561e57a46299244793beb27e74be171d1540606999oliviermartin 1571e57a46299244793beb27e74be171d1540606999oliviermartin // Attributes fields 1581e57a46299244793beb27e74be171d1540606999oliviermartin *(UINT32*)EfiLoadOptionPtr = BdsLoadOption->Attributes; 1591e57a46299244793beb27e74be171d1540606999oliviermartin EfiLoadOptionPtr += sizeof(UINT32); 1601e57a46299244793beb27e74be171d1540606999oliviermartin 1611e57a46299244793beb27e74be171d1540606999oliviermartin // FilePath List fields 1621e57a46299244793beb27e74be171d1540606999oliviermartin *(UINT16*)EfiLoadOptionPtr = BdsLoadOption->FilePathListLength; 1631e57a46299244793beb27e74be171d1540606999oliviermartin EfiLoadOptionPtr += sizeof(UINT16); 1641e57a46299244793beb27e74be171d1540606999oliviermartin 1651e57a46299244793beb27e74be171d1540606999oliviermartin // Boot description fields 1661e57a46299244793beb27e74be171d1540606999oliviermartin CopyMem (EfiLoadOptionPtr, BdsLoadOption->Description, DescriptionSize); 1671e57a46299244793beb27e74be171d1540606999oliviermartin EfiLoadOptionPtr += DescriptionSize; 1681e57a46299244793beb27e74be171d1540606999oliviermartin 1691e57a46299244793beb27e74be171d1540606999oliviermartin // File path fields 1701e57a46299244793beb27e74be171d1540606999oliviermartin DevicePathNode = BdsLoadOption->FilePathList; 1711e57a46299244793beb27e74be171d1540606999oliviermartin while (!IsDevicePathEndType (DevicePathNode)) { 1721e57a46299244793beb27e74be171d1540606999oliviermartin NodeLength = DevicePathNodeLength(DevicePathNode); 1731e57a46299244793beb27e74be171d1540606999oliviermartin CopyMem (EfiLoadOptionPtr, DevicePathNode, NodeLength); 1741e57a46299244793beb27e74be171d1540606999oliviermartin EfiLoadOptionPtr += NodeLength; 1751e57a46299244793beb27e74be171d1540606999oliviermartin DevicePathNode = NextDevicePathNode (DevicePathNode); 1761e57a46299244793beb27e74be171d1540606999oliviermartin } 1771e57a46299244793beb27e74be171d1540606999oliviermartin 1781e57a46299244793beb27e74be171d1540606999oliviermartin // Set the End Device Path Type 1791e57a46299244793beb27e74be171d1540606999oliviermartin SetDevicePathEndNode (EfiLoadOptionPtr); 1801e57a46299244793beb27e74be171d1540606999oliviermartin EfiLoadOptionPtr += sizeof(EFI_DEVICE_PATH); 1811e57a46299244793beb27e74be171d1540606999oliviermartin 1821e57a46299244793beb27e74be171d1540606999oliviermartin // Fill the Optional Data 1831e57a46299244793beb27e74be171d1540606999oliviermartin if (BdsLoadOption->OptionalDataSize > 0) { 1841e57a46299244793beb27e74be171d1540606999oliviermartin CopyMem (EfiLoadOptionPtr, BdsLoadOption->OptionalData, BdsLoadOption->OptionalDataSize); 1851e57a46299244793beb27e74be171d1540606999oliviermartin } 1861e57a46299244793beb27e74be171d1540606999oliviermartin 1871e57a46299244793beb27e74be171d1540606999oliviermartin // Case where the fields have been updated 1881e57a46299244793beb27e74be171d1540606999oliviermartin if (OldLoadOption) { 1891e57a46299244793beb27e74be171d1540606999oliviermartin // Now, the old data has been copied to the new allocated packed structure, we need to update the pointers of BdsLoadOption 1901e57a46299244793beb27e74be171d1540606999oliviermartin BootOptionParseLoadOption (BdsLoadOption->LoadOption, BdsLoadOption->LoadOptionSize, &BdsLoadOption); 1911e57a46299244793beb27e74be171d1540606999oliviermartin // Free the old packed structure 1921e57a46299244793beb27e74be171d1540606999oliviermartin FreePool (OldLoadOption); 1931e57a46299244793beb27e74be171d1540606999oliviermartin } 1941e57a46299244793beb27e74be171d1540606999oliviermartin 1951e57a46299244793beb27e74be171d1540606999oliviermartin // Create/Update Boot#### environment variable 1961e57a46299244793beb27e74be171d1540606999oliviermartin UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BdsLoadOption->LoadOptionIndex); 1971e57a46299244793beb27e74be171d1540606999oliviermartin Status = gRT->SetVariable ( 1981e57a46299244793beb27e74be171d1540606999oliviermartin BootVariableName, 1991e57a46299244793beb27e74be171d1540606999oliviermartin &gEfiGlobalVariableGuid, 2001e57a46299244793beb27e74be171d1540606999oliviermartin EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 2011e57a46299244793beb27e74be171d1540606999oliviermartin BdsLoadOption->LoadOptionSize, 2021e57a46299244793beb27e74be171d1540606999oliviermartin BdsLoadOption->LoadOption 2031e57a46299244793beb27e74be171d1540606999oliviermartin ); 2041e57a46299244793beb27e74be171d1540606999oliviermartin 2051e57a46299244793beb27e74be171d1540606999oliviermartin // When it is a new entry we must add the entry to the BootOrder 2061e57a46299244793beb27e74be171d1540606999oliviermartin if (OldLoadOption == NULL) { 2071e57a46299244793beb27e74be171d1540606999oliviermartin // Add the new Boot Index to the list 208c0b2e4775dcb06d9016f17f5d22e6276d9b58397oliviermartin Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); 2091e57a46299244793beb27e74be171d1540606999oliviermartin if (!EFI_ERROR(Status)) { 2101e57a46299244793beb27e74be171d1540606999oliviermartin BootOrder = ReallocatePool (BootOrderSize, BootOrderSize + sizeof(UINT16), BootOrder); 2111e57a46299244793beb27e74be171d1540606999oliviermartin // Add the new index at the end 2121e57a46299244793beb27e74be171d1540606999oliviermartin BootOrder[BootOrderSize / sizeof(UINT16)] = BdsLoadOption->LoadOptionIndex; 2131e57a46299244793beb27e74be171d1540606999oliviermartin BootOrderSize += sizeof(UINT16); 2141e57a46299244793beb27e74be171d1540606999oliviermartin } else { 2151e57a46299244793beb27e74be171d1540606999oliviermartin // BootOrder does not exist. Create it 2161e57a46299244793beb27e74be171d1540606999oliviermartin BootOrderSize = sizeof(UINT16); 2171e57a46299244793beb27e74be171d1540606999oliviermartin BootOrder = &(BdsLoadOption->LoadOptionIndex); 2181e57a46299244793beb27e74be171d1540606999oliviermartin } 2191e57a46299244793beb27e74be171d1540606999oliviermartin 2201e57a46299244793beb27e74be171d1540606999oliviermartin // Update (or Create) the BootOrder environment variable 2211e57a46299244793beb27e74be171d1540606999oliviermartin gRT->SetVariable ( 2221e57a46299244793beb27e74be171d1540606999oliviermartin L"BootOrder", 2231e57a46299244793beb27e74be171d1540606999oliviermartin &gEfiGlobalVariableGuid, 2241e57a46299244793beb27e74be171d1540606999oliviermartin EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 2251e57a46299244793beb27e74be171d1540606999oliviermartin BootOrderSize, 2261e57a46299244793beb27e74be171d1540606999oliviermartin BootOrder 2271e57a46299244793beb27e74be171d1540606999oliviermartin ); 2281e57a46299244793beb27e74be171d1540606999oliviermartin DEBUG((EFI_D_ERROR,"Create %s\n",BootVariableName)); 2291e57a46299244793beb27e74be171d1540606999oliviermartin 230c0b2e4775dcb06d9016f17f5d22e6276d9b58397oliviermartin // Free memory allocated by GetGlobalEnvironmentVariable 2311e57a46299244793beb27e74be171d1540606999oliviermartin if (!EFI_ERROR(Status)) { 2321e57a46299244793beb27e74be171d1540606999oliviermartin FreePool (BootOrder); 2331e57a46299244793beb27e74be171d1540606999oliviermartin } 2341e57a46299244793beb27e74be171d1540606999oliviermartin } else { 2351e57a46299244793beb27e74be171d1540606999oliviermartin DEBUG((EFI_D_ERROR,"Update %s\n",BootVariableName)); 2361e57a46299244793beb27e74be171d1540606999oliviermartin } 2371e57a46299244793beb27e74be171d1540606999oliviermartin 2381e57a46299244793beb27e74be171d1540606999oliviermartin return EFI_SUCCESS; 2391e57a46299244793beb27e74be171d1540606999oliviermartin} 2401e57a46299244793beb27e74be171d1540606999oliviermartin 2411e57a46299244793beb27e74be171d1540606999oliviermartinUINT16 2421e57a46299244793beb27e74be171d1540606999oliviermartinBootOptionAllocateBootIndex ( 2431e57a46299244793beb27e74be171d1540606999oliviermartin VOID 2441e57a46299244793beb27e74be171d1540606999oliviermartin ) 2451e57a46299244793beb27e74be171d1540606999oliviermartin{ 2461e57a46299244793beb27e74be171d1540606999oliviermartin EFI_STATUS Status; 2471e57a46299244793beb27e74be171d1540606999oliviermartin UINTN Index; 2481e57a46299244793beb27e74be171d1540606999oliviermartin UINT32 BootIndex; 2491e57a46299244793beb27e74be171d1540606999oliviermartin UINT16 *BootOrder; 2501e57a46299244793beb27e74be171d1540606999oliviermartin UINTN BootOrderSize; 2511e57a46299244793beb27e74be171d1540606999oliviermartin BOOLEAN Found; 2521e57a46299244793beb27e74be171d1540606999oliviermartin 2531e57a46299244793beb27e74be171d1540606999oliviermartin // Get the Boot Option Order from the environment variable 254c0b2e4775dcb06d9016f17f5d22e6276d9b58397oliviermartin Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); 2551e57a46299244793beb27e74be171d1540606999oliviermartin if (!EFI_ERROR(Status)) { 2561e57a46299244793beb27e74be171d1540606999oliviermartin for (BootIndex = 0; BootIndex <= 0xFFFF; BootIndex++) { 2571e57a46299244793beb27e74be171d1540606999oliviermartin Found = FALSE; 2581e57a46299244793beb27e74be171d1540606999oliviermartin for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) { 2591e57a46299244793beb27e74be171d1540606999oliviermartin if (BootOrder[Index] == BootIndex) { 2601e57a46299244793beb27e74be171d1540606999oliviermartin Found = TRUE; 2611e57a46299244793beb27e74be171d1540606999oliviermartin break; 2621e57a46299244793beb27e74be171d1540606999oliviermartin } 2631e57a46299244793beb27e74be171d1540606999oliviermartin } 2641e57a46299244793beb27e74be171d1540606999oliviermartin if (!Found) { 2651e57a46299244793beb27e74be171d1540606999oliviermartin return BootIndex; 2661e57a46299244793beb27e74be171d1540606999oliviermartin } 2671e57a46299244793beb27e74be171d1540606999oliviermartin } 2681e57a46299244793beb27e74be171d1540606999oliviermartin FreePool (BootOrder); 2691e57a46299244793beb27e74be171d1540606999oliviermartin } 2701e57a46299244793beb27e74be171d1540606999oliviermartin // Return the first index 2711e57a46299244793beb27e74be171d1540606999oliviermartin return 0; 2721e57a46299244793beb27e74be171d1540606999oliviermartin} 273