/** @file\r
*\r
-* Copyright (c) 2011, ARM Limited. All rights reserved.\r
+* Copyright (c) 2011-2013, 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
*\r
**/\r
\r
+#include <Guid/ArmGlobalVariableHob.h>\r
#include "BdsInternal.h"\r
\r
extern EFI_HANDLE mImageHandle;\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_DEVICE_PATH* FdtDevicePath;\r
EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol;\r
UINT32 LoaderType;\r
ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData;\r
UINTN CmdLineSize;\r
UINTN InitrdSize;\r
EFI_DEVICE_PATH* Initrd;\r
+ UINT16 LoadOptionIndexSize;\r
\r
+ if (IS_ARM_BDS_BOOTENTRY (BootOption)) {\r
Status = EFI_UNSUPPORTED;\r
OptionalData = BootOption->OptionalData;\r
LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);\r
Initrd = NULL;\r
}\r
\r
- Status = BdsBootLinux (BootOption->FilePathList,\r
+ Status = BdsBootLinuxAtag (BootOption->FilePathList,\r
Initrd, // Initrd\r
- (CHAR8*)(LinuxArguments + 1), // CmdLine\r
- NULL);\r
+ (CHAR8*)(LinuxArguments + 1)); // CmdLine\r
} else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {\r
LinuxArguments = &(OptionalData->Arguments.LinuxArguments);\r
CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);\r
\r
// Get the FDT device path\r
FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath);\r
- Status = GetEnvironmentVariable ((CHAR16 *)L"FDT", DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath);\r
+ Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", &gArmGlobalVariableGuid,\r
+ DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath);\r
ASSERT_EFI_ERROR(Status);\r
\r
- Status = BdsBootLinux (BootOption->FilePathList,\r
+ Status = BdsBootLinuxFdt (BootOption->FilePathList,\r
Initrd, // Initrd\r
(CHAR8*)(LinuxArguments + 1),\r
FdtDevicePath);\r
\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-BootOptionParseLoadOption (\r
- IN EFI_LOAD_OPTION EfiLoadOption,\r
- IN UINTN EfiLoadOptionSize,\r
- OUT BDS_LOAD_OPTION **BdsLoadOption\r
- )\r
-{\r
- BDS_LOAD_OPTION *LoadOption;\r
- UINTN FilePathListLength;\r
- UINTN DescriptionLength;\r
-\r
- if (EfiLoadOption == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (EfiLoadOptionSize < sizeof(UINT32) + sizeof(UINT16) + sizeof(CHAR16) + sizeof(EFI_DEVICE_PATH_PROTOCOL)) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- LoadOption = (BDS_LOAD_OPTION*)AllocatePool(sizeof(BDS_LOAD_OPTION));\r
- if (LoadOption == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- LoadOption->LoadOption = EfiLoadOption;\r
- LoadOption->LoadOptionSize = EfiLoadOptionSize;\r
-\r
- LoadOption->Attributes = *(UINT32*)EfiLoadOption;\r
- FilePathListLength = *(UINT16*)(EfiLoadOption + sizeof(UINT32));\r
- LoadOption->Description = (CHAR16*)(EfiLoadOption + sizeof(UINT32) + sizeof(UINT16));\r
- DescriptionLength = StrSize (LoadOption->Description);\r
- LoadOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)(EfiLoadOption + sizeof(UINT32) + sizeof(UINT16) + DescriptionLength);\r
-\r
- if ((UINTN)((UINT8*)LoadOption->FilePathList + FilePathListLength - EfiLoadOption) == EfiLoadOptionSize) {\r
- LoadOption->OptionalData = NULL;\r
- } else {\r
- LoadOption->OptionalData = (BDS_LOADER_OPTIONAL_DATA *)((UINT8*)LoadOption->FilePathList + FilePathListLength);\r
- }\r
-\r
- *BdsLoadOption = LoadOption;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BootOptionFromLoadOptionVariable (\r
- IN UINT16 LoadOptionIndex,\r
- OUT BDS_LOAD_OPTION **BdsLoadOption\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR16 BootVariableName[9];\r
- EFI_LOAD_OPTION EfiLoadOption;\r
- UINTN EfiLoadOptionSize;\r
-\r
- UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", LoadOptionIndex);\r
-\r
- Status = GetEnvironmentVariable (BootVariableName, NULL, &EfiLoadOptionSize, (VOID**)&EfiLoadOption);\r
- if (!EFI_ERROR(Status)) {\r
- Status = BootOptionParseLoadOption (EfiLoadOption,EfiLoadOptionSize,BdsLoadOption);\r
- if (!EFI_ERROR(Status)) {\r
- (*BdsLoadOption)->LoadOptionIndex = LoadOptionIndex;\r
+ FreePool (FdtDevicePath);\r
}\r
+ } else {\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 (mImageHandle, 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
\r
return Status;\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
+ 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 = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\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 = BootOptionFromLoadOptionVariable (BootOrder[Index],&BdsLoadOption);\r
+ Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption);\r
if (!EFI_ERROR(Status)) {\r
- InsertTailList (BootOptionList,&BdsLoadOption->Link);\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
- return EFI_SUCCESS;\r
-}\r
-\r
-UINT16\r
-BootOptionAllocateBootIndex (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINT32 BootIndex;\r
- UINT16 *BootOrder;\r
- UINTN BootOrderSize;\r
- BOOLEAN Found;\r
+ FreePool (BootOrder);\r
\r
- // Get the Boot Option Order from the environment variable\r
- Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
- if (!EFI_ERROR(Status)) {\r
- for (BootIndex = 0; BootIndex <= 0xFFFF; BootIndex++) {\r
- Found = FALSE;\r
- for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
- if (BootOrder[Index] == BootIndex) {\r
- Found = TRUE;\r
- break;\r
- }\r
- }\r
- if (!Found) {\r
- return BootIndex;\r
- }\r
- }\r
- }\r
- // Return the first index\r
- return 0;\r
+ return EFI_SUCCESS;\r
}\r
\r
STATIC\r
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
IN ARM_BDS_LOADER_TYPE BootType,\r
IN ARM_BDS_LOADER_ARGUMENTS* BootArguments,\r
- OUT BDS_LOAD_OPTION **BdsLoadOption\r
+ OUT BDS_LOAD_OPTION** BdsLoadOption\r
)\r
{\r
- EFI_STATUS Status;\r
- BDS_LOAD_OPTION *BootOption;\r
- CHAR16 BootVariableName[9];\r
- UINT16 *BootOrder;\r
- UINTN BootOrderSize;\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
- BootOption = (BDS_LOAD_OPTION*)AllocateZeroPool(sizeof(BDS_LOAD_OPTION));\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
- InitializeListHead (&BootOption->Link);\r
+ BootOption = BootOptionEntry->BdsLoadOption;\r
BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, BootType, BootArguments);\r
\r
//\r
);\r
\r
// Add the new Boot Index to the list\r
- Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\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\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
IN BDS_LOAD_OPTION *BootOption\r
)\r
{\r
- UINTN Index;\r
- UINTN BootOrderSize;\r
- UINT16* BootOrder;\r
- UINTN BootOrderCount;\r
- EFI_STATUS Status;\r
-\r
- // If the Boot Optiono was attached to a list remove it\r
- if (!IsListEmpty (&BootOption->Link)) {\r
- // Remove the entry from the list\r
- RemoveEntryList (&BootOption->Link);\r
- }\r
+ UINTN Index;\r
+ UINTN BootOrderSize;\r
+ UINT16* BootOrder;\r
+ UINTN BootOrderCount;\r
+ EFI_STATUS Status;\r
\r
// Remove the entry from the BootOrder environment variable\r
- Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
+ Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
if (!EFI_ERROR(Status)) {\r
BootOrderCount = BootOrderSize / sizeof(UINT16);\r
\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 (&BootOrder[Index],&BootOrder[Index+1], BootOrderCount - (Index + 1));\r
+ CopyMem (\r
+ &BootOrder[Index],\r
+ &BootOrder[Index + 1],\r
+ (BootOrderCount - (Index + 1)) * sizeof(UINT16)\r
+ );\r
}\r
break;\r
}\r
);\r
}\r
\r
+ FreePool (BootOrder);\r
+\r
return EFI_SUCCESS;\r
}\r