]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Bds/BootOption.c
ArmPlatformPkg/ArmJunoDxe: Set the platform dependent FDT device path
[mirror_edk2.git] / ArmPlatformPkg / Bds / BootOption.c
CommitLineData
ea46ebbe 1/** @file\r
2*\r
c3b6d975 3* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
ea46ebbe 4*\r
5* This program and the accompanying materials\r
6* are licensed and made available under the terms and conditions of the BSD License\r
7* which accompanies this distribution. The full text of the license may be found at\r
8* http://opensource.org/licenses/bsd-license.php\r
9*\r
10* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12*\r
13**/\r
14\r
c0b2e477 15#include <Guid/ArmGlobalVariableHob.h>\r
ea46ebbe 16#include "BdsInternal.h"\r
17\r
ea46ebbe 18EFI_STATUS\r
19BootOptionStart (\r
20 IN BDS_LOAD_OPTION *BootOption\r
21 )\r
22{\r
c60ea9a8 23 EFI_STATUS Status;\r
c60ea9a8 24 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol;\r
25 UINT32 LoaderType;\r
2ccfb71e 26 ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData;\r
27 ARM_BDS_LINUX_ARGUMENTS* LinuxArguments;\r
28 EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath;\r
29 EFI_DEVICE_PATH_PROTOCOL* DefaultFdtDevicePath;\r
30 UINTN FdtDevicePathSize;\r
31 UINTN CmdLineSize;\r
32 UINTN InitrdSize;\r
33 EFI_DEVICE_PATH* Initrd;\r
91213ad3 34 UINT16 LoadOptionIndexSize;\r
2ccfb71e 35\r
a6e97d28 36 if (IS_ARM_BDS_BOOTENTRY (BootOption)) {\r
2ccfb71e 37 Status = EFI_UNSUPPORTED;\r
38 OptionalData = BootOption->OptionalData;\r
39 LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);\r
40\r
41 if (LoaderType == BDS_LOADER_EFI_APPLICATION) {\r
5c670b21 42 if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) {\r
4c8bb1eb
OM
43 // Need to connect every drivers to ensure no dependencies are missing for the application\r
44 BdsConnectAllDrivers ();\r
45 }\r
2ccfb71e 46\r
c3b6d975 47 Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, 0, NULL);\r
2ccfb71e 48 } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {\r
49 LinuxArguments = &(OptionalData->Arguments.LinuxArguments);\r
50 CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);\r
51 InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);\r
52\r
53 if (InitrdSize > 0) {\r
54 Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));\r
55 } else {\r
56 Initrd = NULL;\r
57 }\r
ea46ebbe 58\r
76d17c31 59 Status = BdsBootLinuxAtag (BootOption->FilePathList,\r
2ccfb71e 60 Initrd, // Initrd\r
76d17c31 61 (CHAR8*)(LinuxArguments + 1)); // CmdLine\r
2ccfb71e 62 } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {\r
63 LinuxArguments = &(OptionalData->Arguments.LinuxArguments);\r
64 CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);\r
65 InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);\r
66\r
67 if (InitrdSize > 0) {\r
68 Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));\r
69 } else {\r
70 Initrd = NULL;\r
71 }\r
72\r
73 // Get the default FDT device path\r
74 Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);\r
75 ASSERT_EFI_ERROR(Status);\r
76 DefaultFdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath));\r
77\r
78 // Get the FDT device path\r
79 FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath);\r
c0b2e477 80 Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", &gArmGlobalVariableGuid,\r
81 DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath);\r
2ccfb71e 82 ASSERT_EFI_ERROR(Status);\r
83\r
76d17c31 84 Status = BdsBootLinuxFdt (BootOption->FilePathList,\r
2ccfb71e 85 Initrd, // Initrd\r
86 (CHAR8*)(LinuxArguments + 1),\r
87 FdtDevicePath);\r
b148591a 88\r
79480c8d 89 FreePool (DefaultFdtDevicePath);\r
b148591a 90 FreePool (FdtDevicePath);\r
a6e97d28 91 }\r
92 } else {\r
4c8bb1eb 93 // Connect all the drivers if the EFI Application is not a EFI OS Loader\r
5c670b21 94 if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) {\r
4c8bb1eb
OM
95 BdsConnectAllDrivers ();\r
96 }\r
97\r
91213ad3 98 // Set BootCurrent variable\r
99 LoadOptionIndexSize = sizeof(UINT16);\r
100 gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,\r
101 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
102 LoadOptionIndexSize, &(BootOption->LoadOptionIndex));\r
103\r
c3b6d975 104 Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData);\r
91213ad3 105\r
106 // Clear BootCurrent variable\r
107 LoadOptionIndexSize = sizeof(UINT16);\r
108 gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,\r
109 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
110 0, NULL);\r
a6e97d28 111 }\r
ea46ebbe 112\r
113 return Status;\r
114}\r
115\r
ea46ebbe 116EFI_STATUS\r
117BootOptionList (\r
118 IN OUT LIST_ENTRY *BootOptionList\r
119 )\r
120{\r
a6e97d28 121 EFI_STATUS Status;\r
122 UINTN Index;\r
123 UINT16* BootOrder;\r
124 UINTN BootOrderSize;\r
125 BDS_LOAD_OPTION* BdsLoadOption;\r
126 BDS_LOAD_OPTION_ENTRY* BdsLoadOptionEntry;\r
ea46ebbe 127\r
128 InitializeListHead (BootOptionList);\r
129\r
130 // Get the Boot Option Order from the environment variable\r
c0b2e477 131 Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
ea46ebbe 132 if (EFI_ERROR(Status)) {\r
133 return Status;\r
134 }\r
135\r
136 for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
4aa24170 137 Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption);\r
ea46ebbe 138 if (!EFI_ERROR(Status)) {\r
a6e97d28 139 BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool(sizeof(BDS_LOAD_OPTION_ENTRY));\r
140 BdsLoadOptionEntry->BdsLoadOption = BdsLoadOption;\r
141 InsertTailList (BootOptionList,&BdsLoadOptionEntry->Link);\r
ea46ebbe 142 }\r
143 }\r
144\r
b148591a 145 FreePool (BootOrder);\r
146\r
ea46ebbe 147 return EFI_SUCCESS;\r
148}\r
149\r
ea46ebbe 150STATIC\r
151EFI_STATUS\r
152BootOptionSetFields (\r
c60ea9a8 153 IN BDS_LOAD_OPTION* BootOption,\r
154 IN UINT32 Attributes,\r
155 IN CHAR16* BootDescription,\r
156 IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
2ccfb71e 157 IN ARM_BDS_LOADER_TYPE BootType,\r
90a44ec4
OM
158 IN UINT8* OptionalData,\r
159 IN UINTN OptionalDataSize\r
ea46ebbe 160 )\r
161{\r
2ccfb71e 162 EFI_LOAD_OPTION EfiLoadOption;\r
163 UINTN EfiLoadOptionSize;\r
164 UINTN BootDescriptionSize;\r
2ccfb71e 165 UINT16 FilePathListLength;\r
166 UINT8* EfiLoadOptionPtr;\r
167 UINT8* InitrdPathListPtr;\r
2ccfb71e 168 ARM_BDS_LINUX_ARGUMENTS* DestLinuxArguments;\r
169 ARM_BDS_LINUX_ARGUMENTS* SrcLinuxArguments;\r
90a44ec4 170 ARM_BDS_LOADER_ARGUMENTS* BootArguments;\r
ea46ebbe 171\r
172 // If we are overwriting an existent Boot Option then we have to free previously allocated memory\r
173 if (BootOption->LoadOption) {\r
90a44ec4 174 FreePool (BootOption->LoadOption);\r
ea46ebbe 175 }\r
176\r
2ccfb71e 177 BootDescriptionSize = StrSize (BootDescription);\r
90a44ec4
OM
178\r
179 // Fixup the size in case of entry specific to ArmPlatformPkg/Bds\r
2ccfb71e 180 if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
90a44ec4 181 OptionalDataSize += sizeof(ARM_BDS_LOADER_OPTIONAL_DATA_HEADER);\r
2ccfb71e 182 }\r
ea46ebbe 183\r
184 // Compute the size of the FilePath list\r
2ccfb71e 185 FilePathListLength = GetUnalignedDevicePathSize (DevicePath);\r
656416bc 186\r
ea46ebbe 187 // Allocate the memory for the EFI Load Option\r
90a44ec4 188 EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + OptionalDataSize;\r
ea46ebbe 189 EfiLoadOption = (EFI_LOAD_OPTION)AllocatePool(EfiLoadOptionSize);\r
190 EfiLoadOptionPtr = EfiLoadOption;\r
191\r
192 //\r
193 // Populate the EFI Load Option and BDS Boot Option structures\r
194 //\r
195\r
196 // Attributes fields\r
197 BootOption->Attributes = Attributes;\r
198 *(UINT32*)EfiLoadOptionPtr = Attributes;\r
199 EfiLoadOptionPtr += sizeof(UINT32);\r
200\r
201 // FilePath List fields\r
202 BootOption->FilePathListLength = FilePathListLength;\r
203 *(UINT16*)EfiLoadOptionPtr = FilePathListLength;\r
204 EfiLoadOptionPtr += sizeof(UINT16);\r
205\r
206 // Boot description fields\r
207 BootOption->Description = (CHAR16*)EfiLoadOptionPtr;\r
208 CopyMem (EfiLoadOptionPtr, BootDescription, BootDescriptionSize);\r
209 EfiLoadOptionPtr += BootDescriptionSize;\r
210\r
211 // File path fields\r
212 BootOption->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)EfiLoadOptionPtr;\r
2ccfb71e 213 CopyMem (EfiLoadOptionPtr, DevicePath, FilePathListLength);\r
214 EfiLoadOptionPtr += FilePathListLength;\r
ea46ebbe 215\r
216 // Optional Data fields, Do unaligned writes\r
2ccfb71e 217 BootOption->OptionalData = EfiLoadOptionPtr;\r
ea46ebbe 218\r
2ccfb71e 219 if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
90a44ec4
OM
220 // Write the header\r
221 WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, ARM_BDS_OPTIONAL_DATA_SIGNATURE);\r
222 WriteUnaligned32 ((UINT32 *)(EfiLoadOptionPtr + 4), BootType);\r
223\r
b4c22265
OM
224 // OptionalData should have been initialized by the caller of this function\r
225 ASSERT (OptionalData != NULL);\r
90a44ec4 226 BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)OptionalData;\r
2ccfb71e 227 SrcLinuxArguments = &(BootArguments->LinuxArguments);\r
228 DestLinuxArguments = &((ARM_BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments.LinuxArguments;\r
656416bc 229\r
2ccfb71e 230 WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->CmdLineSize), SrcLinuxArguments->CmdLineSize);\r
231 WriteUnaligned16 ((UINT16 *)&(DestLinuxArguments->InitrdSize), SrcLinuxArguments->InitrdSize);\r
656416bc 232\r
2ccfb71e 233 if (SrcLinuxArguments->CmdLineSize > 0) {\r
234 CopyMem ((VOID*)(DestLinuxArguments + 1), (VOID*)(SrcLinuxArguments + 1), SrcLinuxArguments->CmdLineSize);\r
2ccfb71e 235 }\r
656416bc 236\r
2ccfb71e 237 if (SrcLinuxArguments->InitrdSize > 0) {\r
238 InitrdPathListPtr = (UINT8*)((UINTN)(DestLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize);\r
239 CopyMem (InitrdPathListPtr, (VOID*)((UINTN)(SrcLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize), SrcLinuxArguments->InitrdSize);\r
656416bc 240 }\r
90a44ec4 241 } else {\r
b4c22265
OM
242 if (OptionalData != NULL) {\r
243 CopyMem (BootOption->OptionalData, OptionalData, OptionalDataSize);\r
244 }\r
656416bc 245 }\r
2ccfb71e 246 BootOption->OptionalDataSize = OptionalDataSize;\r
247\r
6bab33c7 248 // If this function is called at the creation of the Boot Device entry (not at the update) the\r
249 // BootOption->LoadOptionSize must be zero then we get a new BootIndex for this entry\r
250 if (BootOption->LoadOptionSize == 0) {\r
2ccfb71e 251 BootOption->LoadOptionIndex = BootOptionAllocateBootIndex ();\r
6bab33c7 252 }\r
253\r
ea46ebbe 254 // Fill the EFI Load option fields\r
ea46ebbe 255 BootOption->LoadOption = EfiLoadOption;\r
256 BootOption->LoadOptionSize = EfiLoadOptionSize;\r
257\r
258 return EFI_SUCCESS;\r
259}\r
260\r
261EFI_STATUS\r
262BootOptionCreate (\r
c60ea9a8 263 IN UINT32 Attributes,\r
264 IN CHAR16* BootDescription,\r
ea46ebbe 265 IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
2ccfb71e 266 IN ARM_BDS_LOADER_TYPE BootType,\r
90a44ec4
OM
267 IN UINT8* OptionalData,\r
268 IN UINTN OptionalDataSize,\r
a6e97d28 269 OUT BDS_LOAD_OPTION** BdsLoadOption\r
ea46ebbe 270 )\r
271{\r
a6e97d28 272 EFI_STATUS Status;\r
273 BDS_LOAD_OPTION_ENTRY* BootOptionEntry;\r
274 BDS_LOAD_OPTION* BootOption;\r
275 CHAR16 BootVariableName[9];\r
276 UINT16* BootOrder;\r
277 UINTN BootOrderSize;\r
ea46ebbe 278\r
279 //\r
280 // Allocate and fill the memory for the BDS Load Option structure\r
281 //\r
a6e97d28 282 BootOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof (BDS_LOAD_OPTION_ENTRY));\r
283 InitializeListHead (&BootOptionEntry->Link);\r
284 BootOptionEntry->BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));\r
ea46ebbe 285\r
a6e97d28 286 BootOption = BootOptionEntry->BdsLoadOption;\r
90a44ec4 287 BootOptionSetFields (BootOption, Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize);\r
ea46ebbe 288\r
289 //\r
290 // Set the related environment variables\r
291 //\r
292\r
293 // Create Boot#### environment variable\r
294 UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex);\r
295 Status = gRT->SetVariable (\r
296 BootVariableName,\r
297 &gEfiGlobalVariableGuid,\r
298 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
299 BootOption->LoadOptionSize,\r
300 BootOption->LoadOption\r
301 );\r
302\r
303 // Add the new Boot Index to the list\r
c0b2e477 304 Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
ea46ebbe 305 if (!EFI_ERROR(Status)) {\r
306 BootOrder = ReallocatePool (BootOrderSize, BootOrderSize + sizeof(UINT16), BootOrder);\r
307 // Add the new index at the end\r
308 BootOrder[BootOrderSize / sizeof(UINT16)] = BootOption->LoadOptionIndex;\r
309 BootOrderSize += sizeof(UINT16);\r
310 } else {\r
311 // BootOrder does not exist. Create it\r
312 BootOrderSize = sizeof(UINT16);\r
313 BootOrder = &(BootOption->LoadOptionIndex);\r
314 }\r
315\r
316 // Update (or Create) the BootOrder environment variable\r
317 Status = gRT->SetVariable (\r
318 L"BootOrder",\r
319 &gEfiGlobalVariableGuid,\r
320 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
321 BootOrderSize,\r
322 BootOrder\r
323 );\r
324\r
b148591a 325 // We only free it if the UEFI Variable 'BootOrder' was already existing\r
326 if (BootOrderSize > sizeof(UINT16)) {\r
327 FreePool (BootOrder);\r
328 }\r
329\r
ea46ebbe 330 *BdsLoadOption = BootOption;\r
331 return Status;\r
332}\r
333\r
334EFI_STATUS\r
335BootOptionUpdate (\r
2ccfb71e 336 IN BDS_LOAD_OPTION* BdsLoadOption,\r
337 IN UINT32 Attributes,\r
338 IN CHAR16* BootDescription,\r
ea46ebbe 339 IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
2ccfb71e 340 IN ARM_BDS_LOADER_TYPE BootType,\r
90a44ec4
OM
341 IN UINT8* OptionalData,\r
342 IN UINTN OptionalDataSize\r
ea46ebbe 343 )\r
344{\r
345 EFI_STATUS Status;\r
ea46ebbe 346 CHAR16 BootVariableName[9];\r
347\r
348 // Update the BDS Load Option structure\r
90a44ec4 349 BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize);\r
ea46ebbe 350\r
351 // Update the related environment variables\r
6bab33c7 352 UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BdsLoadOption->LoadOptionIndex);\r
353\r
ea46ebbe 354 Status = gRT->SetVariable (\r
355 BootVariableName,\r
356 &gEfiGlobalVariableGuid,\r
357 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
6bab33c7 358 BdsLoadOption->LoadOptionSize,\r
359 BdsLoadOption->LoadOption\r
ea46ebbe 360 );\r
361\r
362 return Status;\r
363}\r
364\r
365EFI_STATUS\r
366BootOptionDelete (\r
367 IN BDS_LOAD_OPTION *BootOption\r
368 )\r
369{\r
a6e97d28 370 UINTN Index;\r
371 UINTN BootOrderSize;\r
372 UINT16* BootOrder;\r
373 UINTN BootOrderCount;\r
c41bffd3 374 CHAR16 BootVariableName[9];\r
a6e97d28 375 EFI_STATUS Status;\r
ea46ebbe 376\r
377 // Remove the entry from the BootOrder environment variable\r
c0b2e477 378 Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);\r
ea46ebbe 379 if (!EFI_ERROR(Status)) {\r
380 BootOrderCount = BootOrderSize / sizeof(UINT16);\r
381\r
382 // Find the index of the removed entry\r
383 for (Index = 0; Index < BootOrderCount; Index++) {\r
384 if (BootOrder[Index] == BootOption->LoadOptionIndex) {\r
385 // If it the last entry we do not need to rearrange the BootOrder list\r
386 if (Index + 1 != BootOrderCount) {\r
9127a094 387 CopyMem (\r
388 &BootOrder[Index],\r
389 &BootOrder[Index + 1],\r
390 (BootOrderCount - (Index + 1)) * sizeof(UINT16)\r
391 );\r
ea46ebbe 392 }\r
393 break;\r
394 }\r
395 }\r
396\r
397 // Update the BootOrder environment variable\r
398 Status = gRT->SetVariable (\r
399 L"BootOrder",\r
400 &gEfiGlobalVariableGuid,\r
401 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
402 BootOrderSize - sizeof(UINT16),\r
403 BootOrder\r
404 );\r
405 }\r
406\r
c41bffd3
HL
407 // Delete Boot#### environment variable\r
408 UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex);\r
409 Status = gRT->SetVariable (\r
410 BootVariableName,\r
411 &gEfiGlobalVariableGuid,\r
412 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
413 0,\r
414 NULL\r
415 );\r
416\r
b148591a 417 FreePool (BootOrder);\r
418\r
c41bffd3 419 return Status;\r
ea46ebbe 420}\r