X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ArmPlatformPkg%2FBds%2FBootOption.c;h=32a5679762f91f4328ea1ac4f0ede5434c6ecf14;hb=a115a9efaade48982d7a9545644f75c2f1ccd0e6;hp=dba0d0f639a66815fbdf2f108ebbe12cacd5b9c7;hpb=c60ea9a873b8fe0c4b9409b28d1608f7f80c9c22;p=mirror_edk2.git diff --git a/ArmPlatformPkg/Bds/BootOption.c b/ArmPlatformPkg/Bds/BootOption.c index dba0d0f639..32a5679762 100644 --- a/ArmPlatformPkg/Bds/BootOption.c +++ b/ArmPlatformPkg/Bds/BootOption.c @@ -1,6 +1,6 @@ /** @file * -* Copyright (c) 2011, ARM Limited. All rights reserved. +* Copyright (c) 2011-2015, ARM Limited. All rights reserved. * * This program and the accompanying materials * are licensed and made available under the terms and conditions of the BSD License @@ -14,104 +14,32 @@ #include "BdsInternal.h" -extern EFI_HANDLE mImageHandle; - EFI_STATUS BootOptionStart ( IN BDS_LOAD_OPTION *BootOption ) { - EFI_STATUS Status; - EFI_DEVICE_PATH* FdtDevicePath; - EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; - UINT32 LoaderType; - - Status = EFI_UNSUPPORTED; - LoaderType = ReadUnaligned32 (&BootOption->OptionalData->LoaderType); - - if (LoaderType == BDS_LOADER_EFI_APPLICATION) { - // Need to connect every drivers to ensure no dependencies are missing for the application - BdsConnectAllDrivers(); - - Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList); - } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) { - Status = BdsBootLinux (BootOption->FilePathList, BootOption->OptionalData->Arguments, NULL); - } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) { - // Convert the FDT path into a Device Path - Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); - ASSERT_EFI_ERROR(Status); - FdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath)); - - Status = BdsBootLinux (BootOption->FilePathList, BootOption->OptionalData->Arguments, FdtDevicePath); - FreePool(FdtDevicePath); - } - - return Status; -} - -EFI_STATUS -BootOptionParseLoadOption ( - IN EFI_LOAD_OPTION EfiLoadOption, - IN UINTN EfiLoadOptionSize, - OUT BDS_LOAD_OPTION **BdsLoadOption - ) -{ - BDS_LOAD_OPTION *LoadOption; - UINTN FilePathListLength; - UINTN DescriptionLength; - - if (EfiLoadOption == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (EfiLoadOptionSize < sizeof(UINT32) + sizeof(UINT16) + sizeof(CHAR16) + sizeof(EFI_DEVICE_PATH_PROTOCOL)) { - return EFI_BAD_BUFFER_SIZE; - } + EFI_STATUS Status; + UINT16 LoadOptionIndexSize; - LoadOption = (BDS_LOAD_OPTION*)AllocatePool(sizeof(BDS_LOAD_OPTION)); - if (LoadOption == NULL) { - return EFI_OUT_OF_RESOURCES; + // Connect all the drivers if the EFI Application is not a EFI OS Loader + if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) { + BdsConnectAllDrivers (); } - LoadOption->LoadOption = EfiLoadOption; - LoadOption->LoadOptionSize = EfiLoadOptionSize; + // Set BootCurrent variable + LoadOptionIndexSize = sizeof (UINT16); + gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + LoadOptionIndexSize, &(BootOption->LoadOptionIndex)); - LoadOption->Attributes = *(UINT32*)EfiLoadOption; - FilePathListLength = *(UINT16*)(EfiLoadOption + sizeof(UINT32)); - LoadOption->Description = (CHAR16*)(EfiLoadOption + sizeof(UINT32) + sizeof(UINT16)); - DescriptionLength = StrSize (LoadOption->Description); - LoadOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)(EfiLoadOption + sizeof(UINT32) + sizeof(UINT16) + DescriptionLength); + Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData); - if ((UINTN)((UINT8*)LoadOption->FilePathList + FilePathListLength - EfiLoadOption) == EfiLoadOptionSize) { - LoadOption->OptionalData = NULL; - } else { - LoadOption->OptionalData = (BDS_LOADER_OPTIONAL_DATA *)((UINT8*)LoadOption->FilePathList + FilePathListLength); - } - - *BdsLoadOption = LoadOption; - return EFI_SUCCESS; -} - -EFI_STATUS -BootOptionFromLoadOptionVariable ( - IN UINT16 LoadOptionIndex, - OUT BDS_LOAD_OPTION **BdsLoadOption - ) -{ - EFI_STATUS Status; - CHAR16 BootVariableName[9]; - EFI_LOAD_OPTION EfiLoadOption; - UINTN EfiLoadOptionSize; - - UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", LoadOptionIndex); - - Status = GetEnvironmentVariable (BootVariableName, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption); - if (!EFI_ERROR(Status)) { - Status = BootOptionParseLoadOption (EfiLoadOption,EfiLoadOptionSize,BdsLoadOption); - if (!EFI_ERROR(Status)) { - (*BdsLoadOption)->LoadOptionIndex = LoadOptionIndex; - } - } + // Clear BootCurrent variable + LoadOptionIndexSize = sizeof (UINT16); + gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + 0, NULL); return Status; } @@ -121,60 +49,33 @@ BootOptionList ( IN OUT LIST_ENTRY *BootOptionList ) { - EFI_STATUS Status; - UINTN Index; - UINT16 *BootOrder; - UINTN BootOrderSize; - BDS_LOAD_OPTION *BdsLoadOption; + EFI_STATUS Status; + UINTN Index; + UINT16* BootOrder; + UINTN BootOrderSize; + BDS_LOAD_OPTION* BdsLoadOption; + BDS_LOAD_OPTION_ENTRY* BdsLoadOptionEntry; InitializeListHead (BootOptionList); // Get the Boot Option Order from the environment variable - Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); + Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); if (EFI_ERROR(Status)) { return Status; } for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) { - Status = BootOptionFromLoadOptionVariable (BootOrder[Index],&BdsLoadOption); + Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption); if (!EFI_ERROR(Status)) { - InsertTailList (BootOptionList,&BdsLoadOption->Link); + BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool(sizeof(BDS_LOAD_OPTION_ENTRY)); + BdsLoadOptionEntry->BdsLoadOption = BdsLoadOption; + InsertTailList (BootOptionList,&BdsLoadOptionEntry->Link); } } - return EFI_SUCCESS; -} + FreePool (BootOrder); -UINT16 -BootOptionAllocateBootIndex ( - VOID - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT32 BootIndex; - UINT16 *BootOrder; - UINTN BootOrderSize; - BOOLEAN Found; - - // Get the Boot Option Order from the environment variable - Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); - if (!EFI_ERROR(Status)) { - for (BootIndex = 0; BootIndex <= 0xFFFF; BootIndex++) { - Found = FALSE; - for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) { - if (BootOrder[Index] == BootIndex) { - Found = TRUE; - break; - } - } - if (!Found) { - return BootIndex; - } - } - } - // Return the first index - return 0; + return EFI_SUCCESS; } STATIC @@ -184,42 +85,30 @@ BootOptionSetFields ( IN UINT32 Attributes, IN CHAR16* BootDescription, IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN BDS_LOADER_TYPE BootType, - IN CHAR8* BootArguments + IN UINT8* OptionalData, + IN UINTN OptionalDataSize ) { - EFI_LOAD_OPTION EfiLoadOption; - UINTN EfiLoadOptionSize; - UINTN BootDescriptionSize; - UINTN BootOptionalDataSize; - UINT16 FilePathListLength; - EFI_DEVICE_PATH_PROTOCOL* DevicePathNode; - UINTN NodeLength; - UINT8* EfiLoadOptionPtr; + EFI_LOAD_OPTION *EfiLoadOption; + UINTN EfiLoadOptionSize; + UINTN BootDescriptionSize; + UINT16 FilePathListLength; + UINT8* EfiLoadOptionPtr; // If we are overwriting an existent Boot Option then we have to free previously allocated memory if (BootOption->LoadOption) { - FreePool(BootOption->LoadOption); + FreePool (BootOption->LoadOption); } - BootDescriptionSize = StrSize(BootDescription); - BootOptionalDataSize = sizeof(BDS_LOADER_OPTIONAL_DATA) + - (BootArguments == NULL ? 0 : AsciiStrSize(BootArguments)); + BootDescriptionSize = StrSize (BootDescription); // Compute the size of the FilePath list - FilePathListLength = 0; - DevicePathNode = DevicePath; - while (!IsDevicePathEndType (DevicePathNode)) { - FilePathListLength += DevicePathNodeLength (DevicePathNode); - DevicePathNode = NextDevicePathNode (DevicePathNode); - } - // Add the length of the DevicePath EndType - FilePathListLength += DevicePathNodeLength (DevicePathNode); + FilePathListLength = GetUnalignedDevicePathSize (DevicePath); // Allocate the memory for the EFI Load Option - EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + BootOptionalDataSize; - EfiLoadOption = (EFI_LOAD_OPTION)AllocatePool(EfiLoadOptionSize); - EfiLoadOptionPtr = EfiLoadOption; + EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + OptionalDataSize; + EfiLoadOption = (EFI_LOAD_OPTION *)AllocatePool(EfiLoadOptionSize); + EfiLoadOptionPtr = (UINT8 *)EfiLoadOption; // // Populate the EFI Load Option and BDS Boot Option structures @@ -242,28 +131,22 @@ BootOptionSetFields ( // File path fields BootOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)EfiLoadOptionPtr; - DevicePathNode = DevicePath; - while (!IsDevicePathEndType (DevicePathNode)) { - NodeLength = DevicePathNodeLength(DevicePathNode); - CopyMem (EfiLoadOptionPtr, DevicePathNode, NodeLength); - EfiLoadOptionPtr += NodeLength; - DevicePathNode = NextDevicePathNode (DevicePathNode); - } - - // Set the End Device Path Type - SetDevicePathEndNode (EfiLoadOptionPtr); - EfiLoadOptionPtr = (UINT8 *)EfiLoadOptionPtr + sizeof(EFI_DEVICE_PATH); + CopyMem (EfiLoadOptionPtr, DevicePath, FilePathListLength); + EfiLoadOptionPtr += FilePathListLength; // Optional Data fields, Do unaligned writes - WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, BootType); + BootOption->OptionalData = EfiLoadOptionPtr; + + if (OptionalData != NULL) { + CopyMem (BootOption->OptionalData, OptionalData, OptionalDataSize); + } - CopyMem (&((BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments, BootArguments, AsciiStrSize(BootArguments)); - BootOption->OptionalData = (BDS_LOADER_OPTIONAL_DATA *)EfiLoadOptionPtr; + BootOption->OptionalDataSize = OptionalDataSize; // If this function is called at the creation of the Boot Device entry (not at the update) the // BootOption->LoadOptionSize must be zero then we get a new BootIndex for this entry if (BootOption->LoadOptionSize == 0) { - BootOption->LoadOptionIndex = BootOptionAllocateBootIndex(); + BootOption->LoadOptionIndex = BootOptionAllocateBootIndex (); } // Fill the EFI Load option fields @@ -278,24 +161,27 @@ BootOptionCreate ( IN UINT32 Attributes, IN CHAR16* BootDescription, IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN BDS_LOADER_TYPE BootType, - IN CHAR8* BootArguments, - OUT BDS_LOAD_OPTION **BdsLoadOption + IN UINT8* OptionalData, + IN UINTN OptionalDataSize, + OUT BDS_LOAD_OPTION** BdsLoadOption ) { - EFI_STATUS Status; - BDS_LOAD_OPTION *BootOption; - CHAR16 BootVariableName[9]; - UINT16 *BootOrder; - UINTN BootOrderSize; + EFI_STATUS Status; + BDS_LOAD_OPTION_ENTRY* BootOptionEntry; + BDS_LOAD_OPTION* BootOption; + CHAR16 BootVariableName[9]; + UINT16* BootOrder; + UINTN BootOrderSize; // // Allocate and fill the memory for the BDS Load Option structure // - BootOption = (BDS_LOAD_OPTION*)AllocateZeroPool(sizeof(BDS_LOAD_OPTION)); + BootOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof (BDS_LOAD_OPTION_ENTRY)); + InitializeListHead (&BootOptionEntry->Link); + BootOptionEntry->BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION)); - InitializeListHead (&BootOption->Link); - BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, BootType, BootArguments); + BootOption = BootOptionEntry->BdsLoadOption; + BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize); // // Set the related environment variables @@ -312,7 +198,7 @@ BootOptionCreate ( ); // Add the new Boot Index to the list - Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); + Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); if (!EFI_ERROR(Status)) { BootOrder = ReallocatePool (BootOrderSize, BootOrderSize + sizeof(UINT16), BootOrder); // Add the new index at the end @@ -333,25 +219,30 @@ BootOptionCreate ( BootOrder ); + // We only free it if the UEFI Variable 'BootOrder' was already existing + if (BootOrderSize > sizeof(UINT16)) { + FreePool (BootOrder); + } + *BdsLoadOption = BootOption; return Status; } EFI_STATUS BootOptionUpdate ( - IN BDS_LOAD_OPTION *BdsLoadOption, - IN UINT32 Attributes, - IN CHAR16* BootDescription, + IN BDS_LOAD_OPTION* BdsLoadOption, + IN UINT32 Attributes, + IN CHAR16* BootDescription, IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN BDS_LOADER_TYPE BootType, - IN CHAR8* BootArguments + IN UINT8* OptionalData, + IN UINTN OptionalDataSize ) { EFI_STATUS Status; CHAR16 BootVariableName[9]; // Update the BDS Load Option structure - BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, BootType, BootArguments); + BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize); // Update the related environment variables UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BdsLoadOption->LoadOptionIndex); @@ -372,20 +263,15 @@ BootOptionDelete ( IN BDS_LOAD_OPTION *BootOption ) { - UINTN Index; - UINTN BootOrderSize; - UINT16* BootOrder; - UINTN BootOrderCount; - EFI_STATUS Status; - - // If the Boot Optiono was attached to a list remove it - if (!IsListEmpty (&BootOption->Link)) { - // Remove the entry from the list - RemoveEntryList (&BootOption->Link); - } + UINTN Index; + UINTN BootOrderSize; + UINT16* BootOrder; + UINTN BootOrderCount; + CHAR16 BootVariableName[9]; + EFI_STATUS Status; // Remove the entry from the BootOrder environment variable - Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); + Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); if (!EFI_ERROR(Status)) { BootOrderCount = BootOrderSize / sizeof(UINT16); @@ -394,7 +280,11 @@ BootOptionDelete ( if (BootOrder[Index] == BootOption->LoadOptionIndex) { // If it the last entry we do not need to rearrange the BootOrder list if (Index + 1 != BootOrderCount) { - CopyMem (&BootOrder[Index],&BootOrder[Index+1], BootOrderCount - (Index + 1)); + CopyMem ( + &BootOrder[Index], + &BootOrder[Index + 1], + (BootOrderCount - (Index + 1)) * sizeof(UINT16) + ); } break; } @@ -410,5 +300,17 @@ BootOptionDelete ( ); } - return EFI_SUCCESS; + // Delete Boot#### environment variable + UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex); + Status = gRT->SetVariable ( + BootVariableName, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + 0, + NULL + ); + + FreePool (BootOrder); + + return Status; }