]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Bds/BootOption.c
Create boot option for all block IO devices no matter what the device path looks...
[mirror_edk2.git] / ArmPlatformPkg / Bds / BootOption.c
index 86f2ac2dcad1c9c2c7d82287275302176ec4240e..52c9d831b77bab7963ec90abdc8c9eb5830022ab 100644 (file)
@@ -1,6 +1,6 @@
 /** @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
@@ -12,6 +12,7 @@
 *\r
 **/\r
 \r
+#include <Guid/ArmGlobalVariableHob.h>\r
 #include "BdsInternal.h"\r
 \r
 extern EFI_HANDLE mImageHandle;\r
@@ -32,6 +33,7 @@ BootOptionStart (
   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
@@ -39,8 +41,10 @@ BootOptionStart (
     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
+      if ((BootOption->Attributes & LOAD_OPTION_CATEGORY_BOOT) == 0) {\r
+        // Need to connect every drivers to ensure no dependencies are missing for the application\r
+        BdsConnectAllDrivers ();\r
+      }\r
 \r
       Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList, 0, NULL);\r
     } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
@@ -54,10 +58,9 @@ BootOptionStart (
         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
@@ -76,16 +79,37 @@ BootOptionStart (
 \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
+      FreePool (DefaultFdtDevicePath);\r
+      FreePool (FdtDevicePath);\r
     }\r
   } else {\r
+    // Connect all the drivers if the EFI Application is not a EFI OS Loader\r
+    if ((BootOption->Attributes & LOAD_OPTION_CATEGORY_BOOT) == 0) {\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 (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
@@ -106,7 +130,7 @@ BootOptionList (
   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
@@ -120,6 +144,8 @@ BootOptionList (
     }\r
   }\r
 \r
+  FreePool (BootOrder);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -131,36 +157,37 @@ BootOptionSetFields (
   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
+  IN UINT8*                     OptionalData,\r
+  IN UINTN                      OptionalDataSize\r
   )\r
 {\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
+  ARM_BDS_LOADER_ARGUMENTS*     BootArguments;\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
+    FreePool (BootOption->LoadOption);\r
   }\r
 \r
   BootDescriptionSize = StrSize (BootDescription);\r
-  BootOptionalDataSize = sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER);\r
+\r
+  // Fixup the size in case of entry specific to ArmPlatformPkg/Bds\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
+    OptionalDataSize += sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER);\r
   }\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 + BootOptionalDataSize;\r
+  EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + OptionalDataSize;\r
   EfiLoadOption = (EFI_LOAD_OPTION)AllocatePool(EfiLoadOptionSize);\r
   EfiLoadOptionPtr = EfiLoadOption;\r
 \r
@@ -190,28 +217,29 @@ BootOptionSetFields (
 \r
   // Optional Data fields, Do unaligned writes\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
+    // Write the header\r
+    WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, ARM_BDS_OPTIONAL_DATA_SIGNATURE);\r
+    WriteUnaligned32 ((UINT32 *)(EfiLoadOptionPtr + 4), BootType);\r
+\r
+    BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)OptionalData;\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
     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
+  } else {\r
+    CopyMem (BootOption->OptionalData, OptionalData, OptionalDataSize);\r
   }\r
   BootOption->OptionalDataSize = OptionalDataSize;\r
 \r
@@ -234,7 +262,8 @@ BootOptionCreate (
   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
+  IN  UINT8*                    OptionalData,\r
+  IN  UINTN                     OptionalDataSize,\r
   OUT BDS_LOAD_OPTION**         BdsLoadOption\r
   )\r
 {\r
@@ -253,7 +282,7 @@ BootOptionCreate (
   BootOptionEntry->BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));\r
 \r
   BootOption = BootOptionEntry->BdsLoadOption;\r
-  BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, BootType, BootArguments);\r
+  BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize);\r
 \r
   //\r
   // Set the related environment variables\r
@@ -270,7 +299,7 @@ BootOptionCreate (
       );\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
@@ -291,6 +320,11 @@ 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
@@ -302,14 +336,15 @@ BootOptionUpdate (
   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
+  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, BootType, BootArguments);\r
+  BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize);\r
 \r
   // Update the related environment variables\r
   UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BdsLoadOption->LoadOptionIndex);\r
@@ -337,7 +372,7 @@ BootOptionDelete (
   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
@@ -346,7 +381,11 @@ BootOptionDelete (
       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
@@ -362,5 +401,7 @@ BootOptionDelete (
         );\r
   }\r
 \r
+  FreePool (BootOrder);\r
+\r
   return EFI_SUCCESS;\r
 }\r