X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ArmPlatformPkg%2FBds%2FBootOption.c;h=bdd02b4ecda0c312c070427cb0b5e9bb9e4c420b;hb=8b129b7b390107d258bd004eda8514976534408a;hp=289d36a50badb9f44726380a96b53953a9961993;hpb=91213ad3dd948000e7764352533d60eb183aa234;p=mirror_edk2.git diff --git a/ArmPlatformPkg/Bds/BootOption.c b/ArmPlatformPkg/Bds/BootOption.c index 289d36a50b..bdd02b4ecd 100644 --- a/ArmPlatformPkg/Bds/BootOption.c +++ b/ArmPlatformPkg/Bds/BootOption.c @@ -1,6 +1,6 @@ /** @file * -* Copyright (c) 2011-2012, 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 @@ -12,95 +12,35 @@ * **/ +#include #include "BdsInternal.h" -extern EFI_HANDLE mImageHandle; - EFI_STATUS BootOptionStart ( IN BDS_LOAD_OPTION *BootOption ) { - EFI_STATUS Status; - EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; - UINT32 LoaderType; - ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData; - ARM_BDS_LINUX_ARGUMENTS* LinuxArguments; - EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath; - EFI_DEVICE_PATH_PROTOCOL* DefaultFdtDevicePath; - UINTN FdtDevicePathSize; - UINTN CmdLineSize; - UINTN InitrdSize; - EFI_DEVICE_PATH* Initrd; - UINT16 LoadOptionIndexSize; - - if (IS_ARM_BDS_BOOTENTRY (BootOption)) { - Status = EFI_UNSUPPORTED; - OptionalData = BootOption->OptionalData; - LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.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, 0, NULL); - } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) { - LinuxArguments = &(OptionalData->Arguments.LinuxArguments); - CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); - InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); - - if (InitrdSize > 0) { - Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); - } else { - Initrd = NULL; - } + EFI_STATUS Status; + UINT16 LoadOptionIndexSize; - Status = BdsBootLinuxAtag (BootOption->FilePathList, - Initrd, // Initrd - (CHAR8*)(LinuxArguments + 1)); // CmdLine - } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) { - LinuxArguments = &(OptionalData->Arguments.LinuxArguments); - CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); - InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); - - if (InitrdSize > 0) { - Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); - } else { - Initrd = NULL; - } + // 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 (); + } - // Get the default FDT device path - Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); - ASSERT_EFI_ERROR(Status); - DefaultFdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath)); + // Set BootCurrent variable + LoadOptionIndexSize = sizeof (UINT16); + gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + LoadOptionIndexSize, &(BootOption->LoadOptionIndex)); - // Get the FDT device path - FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath); - Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath); - ASSERT_EFI_ERROR(Status); + Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData); - Status = BdsBootLinuxFdt (BootOption->FilePathList, - Initrd, // Initrd - (CHAR8*)(LinuxArguments + 1), - FdtDevicePath); - - FreePool (FdtDevicePath); - } - } else { - // Set BootCurrent variable - LoadOptionIndexSize = sizeof(UINT16); - gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - LoadOptionIndexSize, &(BootOption->LoadOptionIndex)); - - Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData); - - // Clear BootCurrent variable - LoadOptionIndexSize = sizeof(UINT16); - gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - 0, NULL); - } + // Clear BootCurrent variable + LoadOptionIndexSize = sizeof (UINT16); + gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + 0, NULL); return Status; } @@ -120,7 +60,7 @@ BootOptionList ( 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; } @@ -146,39 +86,30 @@ BootOptionSetFields ( IN UINT32 Attributes, IN CHAR16* BootDescription, IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN ARM_BDS_LOADER_TYPE BootType, - IN ARM_BDS_LOADER_ARGUMENTS* BootArguments + IN UINT8* OptionalData, + IN UINTN OptionalDataSize ) { - EFI_LOAD_OPTION EfiLoadOption; + EFI_LOAD_OPTION *EfiLoadOption; UINTN EfiLoadOptionSize; UINTN BootDescriptionSize; - UINTN BootOptionalDataSize; UINT16 FilePathListLength; UINT8* EfiLoadOptionPtr; - UINT8* InitrdPathListPtr; - UINTN OptionalDataSize; - ARM_BDS_LINUX_ARGUMENTS* DestLinuxArguments; - ARM_BDS_LINUX_ARGUMENTS* SrcLinuxArguments; // 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(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER); - if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) { - BootOptionalDataSize += sizeof(ARM_BDS_LINUX_ARGUMENTS) + BootArguments->LinuxArguments.CmdLineSize + BootArguments->LinuxArguments.InitrdSize; - } // Compute the size of the FilePath list 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 @@ -206,29 +137,11 @@ BootOptionSetFields ( // Optional Data fields, Do unaligned writes BootOption->OptionalData = EfiLoadOptionPtr; - WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, ARM_BDS_OPTIONAL_DATA_SIGNATURE); - WriteUnaligned32 ((UINT32 *)(EfiLoadOptionPtr + 4), BootType); - - OptionalDataSize = sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER); - if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) { - SrcLinuxArguments = &(BootArguments->LinuxArguments); - DestLinuxArguments = &((ARM_BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments.LinuxArguments; - - WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->CmdLineSize), SrcLinuxArguments->CmdLineSize); - WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->InitrdSize), SrcLinuxArguments->InitrdSize); - OptionalDataSize += sizeof (ARM_BDS_LINUX_ARGUMENTS); - - if (SrcLinuxArguments->CmdLineSize > 0) { - CopyMem ((VOID*)(DestLinuxArguments + 1), (VOID*)(SrcLinuxArguments + 1), SrcLinuxArguments->CmdLineSize); - OptionalDataSize += SrcLinuxArguments->CmdLineSize; - } - - if (SrcLinuxArguments->InitrdSize > 0) { - InitrdPathListPtr = (UINT8*)((UINTN)(DestLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize); - CopyMem (InitrdPathListPtr, (VOID*)((UINTN)(SrcLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize), SrcLinuxArguments->InitrdSize); - } + if (OptionalData != NULL) { + CopyMem (BootOption->OptionalData, OptionalData, OptionalDataSize); } + BootOption->OptionalDataSize = OptionalDataSize; // If this function is called at the creation of the Boot Device entry (not at the update) the @@ -249,8 +162,8 @@ BootOptionCreate ( IN UINT32 Attributes, IN CHAR16* BootDescription, IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN ARM_BDS_LOADER_TYPE BootType, - IN ARM_BDS_LOADER_ARGUMENTS* BootArguments, + IN UINT8* OptionalData, + IN UINTN OptionalDataSize, OUT BDS_LOAD_OPTION** BdsLoadOption ) { @@ -269,7 +182,7 @@ BootOptionCreate ( BootOptionEntry->BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION)); BootOption = BootOptionEntry->BdsLoadOption; - BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, BootType, BootArguments); + BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize); // // Set the related environment variables @@ -286,7 +199,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 @@ -322,15 +235,15 @@ BootOptionUpdate ( IN UINT32 Attributes, IN CHAR16* BootDescription, IN EFI_DEVICE_PATH_PROTOCOL* DevicePath, - IN ARM_BDS_LOADER_TYPE BootType, - IN ARM_BDS_LOADER_ARGUMENTS* 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); @@ -355,10 +268,11 @@ BootOptionDelete ( 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); @@ -367,7 +281,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; } @@ -383,7 +301,17 @@ BootOptionDelete ( ); } + // 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 EFI_SUCCESS; + return Status; }