+++ /dev/null
-/** @file\r
-*\r
-* Copyright (c) 2011-2015, ARM Limited. All rights reserved.\r
-*\r
-* This program and the accompanying materials\r
-* are licensed and made available under the terms and conditions of the BSD License\r
-* which accompanies this distribution. The full text of the license may be found at\r
-* http://opensource.org/licenses/bsd-license.php\r
-*\r
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-*\r
-**/\r
-\r
-#include "BdsInternal.h"\r
-\r
-EFI_STATUS\r
-BootOptionStart (\r
- IN BDS_LOAD_OPTION *BootOption\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT16 LoadOptionIndexSize;\r
-\r
- // Connect all the drivers if the EFI Application is not a EFI OS Loader\r
- if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) {\r
- BdsConnectAllDrivers ();\r
- }\r
-\r
- // Set BootCurrent variable\r
- LoadOptionIndexSize = sizeof (UINT16);\r
- gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- LoadOptionIndexSize, &(BootOption->LoadOptionIndex));\r
-\r
- Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData);\r
-\r
- // Clear BootCurrent variable\r
- LoadOptionIndexSize = sizeof (UINT16);\r
- gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- 0, NULL);\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-BootOptionList (\r
- IN OUT LIST_ENTRY *BootOptionList\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINT16* BootOrder;\r
- UINTN BootOrderSize;\r
- BDS_LOAD_OPTION* BdsLoadOption;\r
- BDS_LOAD_OPTION_ENTRY* BdsLoadOptionEntry;\r
-\r
- InitializeListHead (BootOptionList);\r
-\r
- // Get the Boot Option Order from the environment variable\r
- Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
- Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption);\r
- if (!EFI_ERROR(Status)) {\r
- BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool(sizeof(BDS_LOAD_OPTION_ENTRY));\r
- BdsLoadOptionEntry->BdsLoadOption = BdsLoadOption;\r
- InsertTailList (BootOptionList,&BdsLoadOptionEntry->Link);\r
- }\r
- }\r
-\r
- FreePool (BootOrder);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-BootOptionSetFields (\r
- IN BDS_LOAD_OPTION* BootOption,\r
- IN UINT32 Attributes,\r
- IN CHAR16* BootDescription,\r
- IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
- IN UINT8* OptionalData,\r
- IN UINTN OptionalDataSize\r
- )\r
-{\r
- EFI_LOAD_OPTION *EfiLoadOption;\r
- UINTN EfiLoadOptionSize;\r
- UINTN BootDescriptionSize;\r
- UINT16 FilePathListLength;\r
- UINT8* EfiLoadOptionPtr;\r
-\r
- // If we are overwriting an existent Boot Option then we have to free previously allocated memory\r
- if (BootOption->LoadOption) {\r
- FreePool (BootOption->LoadOption);\r
- }\r
-\r
- BootDescriptionSize = StrSize (BootDescription);\r
-\r
- // Compute the size of the FilePath list\r
- FilePathListLength = GetUnalignedDevicePathSize (DevicePath);\r
-\r
- // Allocate the memory for the EFI Load Option\r
- EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + OptionalDataSize;\r
- EfiLoadOption = (EFI_LOAD_OPTION *)AllocatePool(EfiLoadOptionSize);\r
- EfiLoadOptionPtr = (UINT8 *)EfiLoadOption;\r
-\r
- //\r
- // Populate the EFI Load Option and BDS Boot Option structures\r
- //\r
-\r
- // Attributes fields\r
- BootOption->Attributes = Attributes;\r
- *(UINT32*)EfiLoadOptionPtr = Attributes;\r
- EfiLoadOptionPtr += sizeof(UINT32);\r
-\r
- // FilePath List fields\r
- BootOption->FilePathListLength = FilePathListLength;\r
- *(UINT16*)EfiLoadOptionPtr = FilePathListLength;\r
- EfiLoadOptionPtr += sizeof(UINT16);\r
-\r
- // Boot description fields\r
- BootOption->Description = (CHAR16*)EfiLoadOptionPtr;\r
- CopyMem (EfiLoadOptionPtr, BootDescription, BootDescriptionSize);\r
- EfiLoadOptionPtr += BootDescriptionSize;\r
-\r
- // File path fields\r
- BootOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)EfiLoadOptionPtr;\r
- CopyMem (EfiLoadOptionPtr, DevicePath, FilePathListLength);\r
- EfiLoadOptionPtr += FilePathListLength;\r
-\r
- // Optional Data fields, Do unaligned writes\r
- BootOption->OptionalData = EfiLoadOptionPtr;\r
-\r
- if (OptionalData != NULL) {\r
- CopyMem (BootOption->OptionalData, OptionalData, OptionalDataSize);\r
- }\r
-\r
- BootOption->OptionalDataSize = OptionalDataSize;\r
-\r
- // If this function is called at the creation of the Boot Device entry (not at the update) the\r
- // BootOption->LoadOptionSize must be zero then we get a new BootIndex for this entry\r
- if (BootOption->LoadOptionSize == 0) {\r
- BootOption->LoadOptionIndex = BootOptionAllocateBootIndex ();\r
- }\r
-\r
- // Fill the EFI Load option fields\r
- BootOption->LoadOption = EfiLoadOption;\r
- BootOption->LoadOptionSize = EfiLoadOptionSize;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BootOptionCreate (\r
- IN UINT32 Attributes,\r
- IN CHAR16* BootDescription,\r
- IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
- IN UINT8* OptionalData,\r
- IN UINTN OptionalDataSize,\r
- OUT BDS_LOAD_OPTION** BdsLoadOption\r
- )\r
-{\r
- EFI_STATUS Status;\r
- BDS_LOAD_OPTION_ENTRY* BootOptionEntry;\r
- BDS_LOAD_OPTION* BootOption;\r
- CHAR16 BootVariableName[9];\r
- UINT16* BootOrder;\r
- UINTN BootOrderSize;\r
-\r
- //\r
- // Allocate and fill the memory for the BDS Load Option structure\r
- //\r
- BootOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof (BDS_LOAD_OPTION_ENTRY));\r
- InitializeListHead (&BootOptionEntry->Link);\r
- BootOptionEntry->BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));\r
-\r
- BootOption = BootOptionEntry->BdsLoadOption;\r
- BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize);\r
-\r
- //\r
- // Set the related environment variables\r
- //\r
-\r
- // Create Boot#### environment variable\r
- UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex);\r
- Status = gRT->SetVariable (\r
- BootVariableName,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- BootOption->LoadOptionSize,\r
- BootOption->LoadOption\r
- );\r
-\r
- // Add the new Boot Index to the list\r
- Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
- if (!EFI_ERROR(Status)) {\r
- BootOrder = ReallocatePool (BootOrderSize, BootOrderSize + sizeof(UINT16), BootOrder);\r
- // Add the new index at the end\r
- BootOrder[BootOrderSize / sizeof(UINT16)] = BootOption->LoadOptionIndex;\r
- BootOrderSize += sizeof(UINT16);\r
- } else {\r
- // BootOrder does not exist. Create it\r
- BootOrderSize = sizeof(UINT16);\r
- BootOrder = &(BootOption->LoadOptionIndex);\r
- }\r
-\r
- // Update (or Create) the BootOrder environment variable\r
- Status = gRT->SetVariable (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- BootOrderSize,\r
- BootOrder\r
- );\r
-\r
- // We only free it if the UEFI Variable 'BootOrder' was already existing\r
- if (BootOrderSize > sizeof(UINT16)) {\r
- FreePool (BootOrder);\r
- }\r
-\r
- *BdsLoadOption = BootOption;\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-BootOptionUpdate (\r
- IN BDS_LOAD_OPTION* BdsLoadOption,\r
- IN UINT32 Attributes,\r
- IN CHAR16* BootDescription,\r
- IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
- IN UINT8* OptionalData,\r
- IN UINTN OptionalDataSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR16 BootVariableName[9];\r
-\r
- // Update the BDS Load Option structure\r
- BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize);\r
-\r
- // Update the related environment variables\r
- UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BdsLoadOption->LoadOptionIndex);\r
-\r
- Status = gRT->SetVariable (\r
- BootVariableName,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- BdsLoadOption->LoadOptionSize,\r
- BdsLoadOption->LoadOption\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-BootOptionDelete (\r
- IN BDS_LOAD_OPTION *BootOption\r
- )\r
-{\r
- UINTN Index;\r
- UINTN BootOrderSize;\r
- UINT16* BootOrder;\r
- UINTN BootOrderCount;\r
- CHAR16 BootVariableName[9];\r
- EFI_STATUS Status;\r
-\r
- // Remove the entry from the BootOrder environment variable\r
- Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
- if (!EFI_ERROR(Status)) {\r
- BootOrderCount = BootOrderSize / sizeof(UINT16);\r
-\r
- // Find the index of the removed entry\r
- for (Index = 0; Index < BootOrderCount; Index++) {\r
- if (BootOrder[Index] == BootOption->LoadOptionIndex) {\r
- // If it the last entry we do not need to rearrange the BootOrder list\r
- if (Index + 1 != BootOrderCount) {\r
- CopyMem (\r
- &BootOrder[Index],\r
- &BootOrder[Index + 1],\r
- (BootOrderCount - (Index + 1)) * sizeof(UINT16)\r
- );\r
- }\r
- break;\r
- }\r
- }\r
-\r
- // Update the BootOrder environment variable\r
- Status = gRT->SetVariable (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- BootOrderSize - sizeof(UINT16),\r
- BootOrder\r
- );\r
- }\r
-\r
- // Delete Boot#### environment variable\r
- UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex);\r
- Status = gRT->SetVariable (\r
- BootVariableName,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- 0,\r
- NULL\r
- );\r
-\r
- FreePool (BootOrder);\r
-\r
- return Status;\r
-}\r