]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Bds/BootOption.c
ArmPlatformPkg/Bds: Add support for 'BootCurrent'
[mirror_edk2.git] / ArmPlatformPkg / Bds / BootOption.c
index a8ba23fe739ce0e9ca83bbcc23526ed7c19c8e95..289d36a50badb9f44726380a96b53953a9961993 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 *\r
-*  Copyright (c) 2011, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2011-2012, 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
@@ -21,94 +21,85 @@ BootOptionStart (
   IN BDS_LOAD_OPTION *BootOption\r
   )\r
 {\r
-  EFI_STATUS Status;\r
-  EFI_DEVICE_PATH* FdtDevicePath;\r
-  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;\r
-\r
-  Status = EFI_UNSUPPORTED;\r
-\r
-  if (BootOption->OptionalData->LoaderType == BDS_LOADER_EFI_APPLICATION) {\r
-    // Need to connect every drivers to ensure no dependencies are missing for the application\r
-    BdsConnectAllDrivers();\r
-\r
-    Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList);\r
-  } else if (BootOption->OptionalData->LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
-    Status = BdsBootLinux (BootOption->FilePathList, BootOption->OptionalData->Arguments, NULL);\r
-  } else if (BootOption->OptionalData->LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {\r
-    // Convert the FDT path into a Device Path\r
-    Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);\r
-    ASSERT_EFI_ERROR(Status);\r
-    FdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath));\r
-\r
-    Status = BdsBootLinux (BootOption->FilePathList, BootOption->OptionalData->Arguments, FdtDevicePath);\r
-    FreePool(FdtDevicePath);\r
-  }\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
+  EFI_STATUS                            Status;\r
+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL*   EfiDevicePathFromTextProtocol;\r
+  UINT32                                LoaderType;\r
+  ARM_BDS_LOADER_OPTIONAL_DATA*         OptionalData;\r
+  ARM_BDS_LINUX_ARGUMENTS*              LinuxArguments;\r
+  EFI_DEVICE_PATH_PROTOCOL*             FdtDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL*             DefaultFdtDevicePath;\r
+  UINTN                                 FdtDevicePathSize;\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
+\r
+    if (LoaderType == BDS_LOADER_EFI_APPLICATION) {\r
+      // Need to connect every drivers to ensure no dependencies are missing for the application\r
+      BdsConnectAllDrivers();\r
+\r
+      Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList, 0, NULL);\r
+    } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
+      LinuxArguments = &(OptionalData->Arguments.LinuxArguments);\r
+      CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);\r
+      InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);\r
+\r
+      if (InitrdSize > 0) {\r
+        Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));\r
+      } else {\r
+        Initrd = NULL;\r
+      }\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
+      Status = BdsBootLinuxAtag (BootOption->FilePathList,\r
+                                 Initrd, // Initrd\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
+      InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);\r
+\r
+      if (InitrdSize > 0) {\r
+        Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));\r
+      } else {\r
+        Initrd = NULL;\r
+      }\r
 \r
-  *BdsLoadOption = LoadOption;\r
-  return EFI_SUCCESS;\r
-}\r
+      // Get the default FDT device path\r
+      Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);\r
+      ASSERT_EFI_ERROR(Status);\r
+      DefaultFdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath));\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
+      // Get the FDT device path\r
+      FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath);\r
+      Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath);\r
+      ASSERT_EFI_ERROR(Status);\r
 \r
-  UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", LoadOptionIndex);\r
+      Status = BdsBootLinuxFdt (BootOption->FilePathList,\r
+                                Initrd, // Initrd\r
+                                (CHAR8*)(LinuxArguments + 1),\r
+                                FdtDevicePath);\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
@@ -119,11 +110,12 @@ BootOptionList (
   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
@@ -134,85 +126,54 @@ BootOptionList (
   }\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
 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  BDS_LOADER_TYPE   BootType,\r
-  IN  CHAR8*            BootArguments\r
+  IN BDS_LOAD_OPTION*           BootOption,\r
+  IN UINT32                     Attributes,\r
+  IN CHAR16*                    BootDescription,\r
+  IN EFI_DEVICE_PATH_PROTOCOL*  DevicePath,\r
+  IN ARM_BDS_LOADER_TYPE        BootType,\r
+  IN ARM_BDS_LOADER_ARGUMENTS*  BootArguments\r
   )\r
 {\r
-  EFI_LOAD_OPTION EfiLoadOption;\r
-  UINTN           EfiLoadOptionSize;\r
-  UINTN           BootDescriptionSize;\r
-  UINTN           BootOptionalDataSize;\r
-  UINT16          FilePathListLength;\r
-  EFI_DEVICE_PATH_PROTOCOL* DevicePathNode;\r
-  UINTN           NodeLength;\r
-  UINT8*          EfiLoadOptionPtr;\r
+  EFI_LOAD_OPTION               EfiLoadOption;\r
+  UINTN                         EfiLoadOptionSize;\r
+  UINTN                         BootDescriptionSize;\r
+  UINTN                         BootOptionalDataSize;\r
+  UINT16                        FilePathListLength;\r
+  UINT8*                        EfiLoadOptionPtr;\r
+  UINT8*                        InitrdPathListPtr;\r
+  UINTN                         OptionalDataSize;\r
+  ARM_BDS_LINUX_ARGUMENTS*      DestLinuxArguments;\r
+  ARM_BDS_LINUX_ARGUMENTS*      SrcLinuxArguments;\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
-  BootOptionalDataSize = sizeof(BDS_LOADER_OPTIONAL_DATA) +\r
-      (BootArguments == NULL ? 0 : AsciiStrSize(BootArguments));\r
+  BootDescriptionSize = StrSize (BootDescription);\r
+  BootOptionalDataSize = sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER);\r
+  if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
+    BootOptionalDataSize += sizeof(ARM_BDS_LINUX_ARGUMENTS) + BootArguments->LinuxArguments.CmdLineSize + BootArguments->LinuxArguments.InitrdSize;\r
+  }\r
 \r
   // Compute the size of the FilePath list\r
-  FilePathListLength = 0;\r
-  DevicePathNode = DevicePath;\r
-  while (!IsDevicePathEndType (DevicePathNode)) {\r
-    FilePathListLength += DevicePathNodeLength (DevicePathNode);\r
-    DevicePathNode = NextDevicePathNode (DevicePathNode);\r
-  }\r
-  // Add the length of the DevicePath EndType\r
-  FilePathListLength += DevicePathNodeLength (DevicePathNode);\r
+  FilePathListLength = GetUnalignedDevicePathSize (DevicePath);\r
 \r
   // Allocate the memory for the EFI Load Option\r
   EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + BootOptionalDataSize;\r
@@ -240,26 +201,43 @@ BootOptionSetFields (
 \r
   // File path fields\r
   BootOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)EfiLoadOptionPtr;\r
-  DevicePathNode = DevicePath;\r
-  while (!IsDevicePathEndType (DevicePathNode)) {\r
-    NodeLength = DevicePathNodeLength(DevicePathNode);\r
-    CopyMem (EfiLoadOptionPtr, DevicePathNode, NodeLength);\r
-    EfiLoadOptionPtr += NodeLength;\r
-    DevicePathNode = NextDevicePathNode (DevicePathNode);\r
-  }\r
-\r
-  // Set the End Device Path Type\r
-  SetDevicePathEndNode (EfiLoadOptionPtr);\r
-  EfiLoadOptionPtr = (UINT8 *)EfiLoadOptionPtr + sizeof(EFI_DEVICE_PATH);\r
+  CopyMem (EfiLoadOptionPtr, DevicePath, FilePathListLength);\r
+  EfiLoadOptionPtr += FilePathListLength;\r
 \r
   // Optional Data fields, Do unaligned writes\r
-  WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, BootType);\r
+  BootOption->OptionalData = EfiLoadOptionPtr;\r
+  WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, ARM_BDS_OPTIONAL_DATA_SIGNATURE);\r
+  WriteUnaligned32 ((UINT32 *)(EfiLoadOptionPtr + 4), BootType);\r
+\r
+  OptionalDataSize = sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER);\r
+\r
+  if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
+    SrcLinuxArguments = &(BootArguments->LinuxArguments);\r
+    DestLinuxArguments = &((ARM_BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments.LinuxArguments;\r
+\r
+    WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->CmdLineSize), SrcLinuxArguments->CmdLineSize);\r
+    WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->InitrdSize), SrcLinuxArguments->InitrdSize);\r
+    OptionalDataSize += sizeof (ARM_BDS_LINUX_ARGUMENTS);\r
 \r
-  CopyMem (&((BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments, BootArguments, AsciiStrSize(BootArguments));\r
-  BootOption->OptionalData = (BDS_LOADER_OPTIONAL_DATA *)EfiLoadOptionPtr;\r
+    if (SrcLinuxArguments->CmdLineSize > 0) {\r
+      CopyMem ((VOID*)(DestLinuxArguments + 1), (VOID*)(SrcLinuxArguments + 1), SrcLinuxArguments->CmdLineSize);\r
+      OptionalDataSize += SrcLinuxArguments->CmdLineSize;\r
+    }\r
+\r
+    if (SrcLinuxArguments->InitrdSize > 0) {\r
+      InitrdPathListPtr = (UINT8*)((UINTN)(DestLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize);\r
+      CopyMem (InitrdPathListPtr, (VOID*)((UINTN)(SrcLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize), SrcLinuxArguments->InitrdSize);\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->LoadOptionIndex = BootOptionAllocateBootIndex();\r
   BootOption->LoadOption = EfiLoadOption;\r
   BootOption->LoadOptionSize = EfiLoadOptionSize;\r
 \r
@@ -268,26 +246,29 @@ BootOptionSetFields (
 \r
 EFI_STATUS\r
 BootOptionCreate (\r
-  IN  UINT32 Attributes,\r
-  IN  CHAR16* BootDescription,\r
+  IN  UINT32                    Attributes,\r
+  IN  CHAR16*                   BootDescription,\r
   IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
-  IN  BDS_LOADER_TYPE   BootType,\r
-  IN  CHAR8*            BootArguments,\r
-  OUT BDS_LOAD_OPTION **BdsLoadOption\r
+  IN  ARM_BDS_LOADER_TYPE       BootType,\r
+  IN  ARM_BDS_LOADER_ARGUMENTS* BootArguments,\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
@@ -326,35 +307,40 @@ BootOptionCreate (
       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  BDS_LOAD_OPTION*          BdsLoadOption,\r
+  IN  UINT32                    Attributes,\r
+  IN  CHAR16*                   BootDescription,\r
   IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
-  IN  BDS_LOADER_TYPE   BootType,\r
-  IN  CHAR8*            BootArguments\r
+  IN  ARM_BDS_LOADER_TYPE       BootType,\r
+  IN  ARM_BDS_LOADER_ARGUMENTS* BootArguments\r
   )\r
 {\r
   EFI_STATUS      Status;\r
-  BDS_LOAD_OPTION *BootOption;\r
   CHAR16          BootVariableName[9];\r
 \r
   // Update the BDS Load Option structure\r
   BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, BootType, BootArguments);\r
 \r
   // Update the related environment variables\r
-  UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex);\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
-      BootOption->LoadOptionSize,\r
-      BootOption->LoadOption\r
+      BdsLoadOption->LoadOptionSize,\r
+      BdsLoadOption->LoadOption\r
       );\r
 \r
   return Status;\r
@@ -365,17 +351,11 @@ BootOptionDelete (
   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
@@ -403,5 +383,7 @@ BootOptionDelete (
         );\r
   }\r
 \r
+  FreePool (BootOrder);\r
+\r
   return EFI_SUCCESS;\r
 }\r