]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
ArmPlatformPkg/ArmJunoDxe: Fixed PCI Root bridge device path
[mirror_edk2.git] / ArmPlatformPkg / ArmJunoPkg / Drivers / ArmJunoDxe / ArmJunoDxe.c
CommitLineData
9f38945f
OM
1/** @file\r
2*\r
21a76332 3* Copyright (c) 2013-2015, ARM Limited. All rights reserved.\r
9f38945f
OM
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
15#include "ArmJunoDxeInternal.h"\r
c1fee786 16#include <ArmPlatform.h>\r
6d60dfea
OM
17\r
18#include <Protocol/DevicePathFromText.h>\r
1bb1f35f 19#include <Protocol/PciRootBridgeIo.h>\r
6d60dfea 20\r
1bb1f35f 21#include <Guid/EventGroup.h>\r
6d60dfea
OM
22#include <Guid/GlobalVariable.h>\r
23\r
9f38945f 24#include <Library/ArmShellCmdLib.h>\r
21a76332 25#include <Library/AcpiLib.h>\r
6d60dfea
OM
26#include <Library/BaseMemoryLib.h>\r
27#include <Library/DevicePathLib.h>\r
28#include <Library/MemoryAllocationLib.h>\r
29#include <Library/UefiRuntimeServicesTableLib.h>\r
c1fee786
RC
30#include <Library/IoLib.h>\r
31#include <Library/PrintLib.h>\r
32\r
33//\r
34// Size in number of characters of the Linux boot argument\r
35// passing the MAC address to be used by the PCI GigaByte\r
36// Ethernet device : " sky2.mac_address=0x11,0x22,0x33,0x44,0x55,0x66"\r
37//\r
38#define SKY2_MAC_ADDRESS_BOOTARG_LEN 47\r
39\r
40//\r
41// Hardware platform identifiers\r
42//\r
43typedef enum {\r
44 UNKNOWN,\r
45 JUNO_R0,\r
46 JUNO_R1\r
47} JUNO_REVISION;\r
48\r
49//\r
50// Function prototypes\r
51//\r
52STATIC EFI_STATUS SetJunoR1DefaultBootEntries (\r
53 VOID\r
54 );\r
9f38945f 55\r
05e56470
OM
56// This GUID must match the FILE_GUID in ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf\r
57STATIC CONST EFI_GUID mJunoAcpiTableFile = { 0xa1dd808e, 0x1e95, 0x4399, { 0xab, 0xc0, 0x65, 0x3c, 0x82, 0xe8, 0x53, 0x0c } };\r
58\r
1bb1f35f
OM
59typedef struct {\r
60 ACPI_HID_DEVICE_PATH AcpiDevicePath;\r
b5ec7f3c 61 PCI_DEVICE_PATH PciDevicePath;\r
1bb1f35f
OM
62 EFI_DEVICE_PATH_PROTOCOL EndDevicePath;\r
63} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;\r
64\r
65STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mPciRootComplexDevicePath = {\r
66 {\r
67 { ACPI_DEVICE_PATH,\r
68 ACPI_DP,\r
69 { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),\r
70 (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) }\r
71 },\r
72 EISA_PNP_ID (0x0A03),\r
73 0\r
74 },\r
b5ec7f3c
OM
75 {\r
76 { HARDWARE_DEVICE_PATH,\r
77 HW_PCI_DP,\r
78 { (UINT8) (sizeof (PCI_DEVICE_PATH)),\r
79 (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) }\r
80 },\r
81 0,\r
82 0\r
83 },\r
1bb1f35f
OM
84 {\r
85 END_DEVICE_PATH_TYPE,\r
86 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
87 { END_DEVICE_PATH_LENGTH, 0 }\r
88 }\r
89};\r
90\r
e0ae2761
OM
91EFI_EVENT mAcpiRegistration = NULL;\r
92\r
6d60dfea
OM
93/**\r
94 * Build and Set UEFI Variable Boot####\r
95 *\r
96 * @param BootVariableName Name of the UEFI Variable\r
97 * @param Attributes 'Attributes' for the Boot#### variable as per UEFI spec\r
98 * @param BootDescription Description of the Boot#### variable\r
99 * @param DevicePath EFI Device Path of the EFI Application to boot\r
100 * @param OptionalData Parameters to pass to the EFI application\r
101 * @param OptionalDataSize Size of the parameters to pass to the EFI application\r
102 *\r
103 * @return EFI_OUT_OF_RESOURCES A memory allocation failed\r
104 * @return Return value of RT.SetVariable\r
105 */\r
106STATIC\r
107EFI_STATUS\r
108BootOptionCreate (\r
109 IN CHAR16 BootVariableName[9],\r
110 IN UINT32 Attributes,\r
111 IN CHAR16* BootDescription,\r
112 IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
113 IN UINT8* OptionalData,\r
114 IN UINTN OptionalDataSize\r
115 )\r
116{\r
117 UINTN VariableSize;\r
118 UINT8 *Variable;\r
119 UINT8 *VariablePtr;\r
120 UINTN FilePathListLength;\r
121 UINTN BootDescriptionSize;\r
122\r
123 FilePathListLength = GetDevicePathSize (DevicePath);\r
124 BootDescriptionSize = StrSize (BootDescription);\r
125\r
126 // Each Boot#### variable is built as follow:\r
127 // UINT32 Attributes\r
128 // UINT16 FilePathListLength\r
129 // CHAR16* Description\r
130 // EFI_DEVICE_PATH_PROTOCOL FilePathList[]\r
131 // UINT8 OptionalData[]\r
132 VariableSize = sizeof (UINT32) + sizeof (UINT16) +\r
133 BootDescriptionSize + FilePathListLength + OptionalDataSize;\r
134 Variable = AllocateZeroPool (VariableSize);\r
135 if (Variable == NULL) {\r
136 return EFI_OUT_OF_RESOURCES;\r
137 }\r
138\r
139 // 'Attributes' field\r
140 *(UINT32*)Variable = Attributes;\r
141 // 'FilePathListLength' field\r
142 VariablePtr = Variable + sizeof (UINT32);\r
143 *(UINT16*)VariablePtr = FilePathListLength;\r
144 // 'Description' field\r
145 VariablePtr += sizeof (UINT16);\r
146 CopyMem (VariablePtr, BootDescription, BootDescriptionSize);\r
147 // 'FilePathList' field\r
148 VariablePtr += BootDescriptionSize;\r
149 CopyMem (VariablePtr, DevicePath, FilePathListLength);\r
150 // 'OptionalData' field\r
151 VariablePtr += FilePathListLength;\r
152 CopyMem (VariablePtr, OptionalData, OptionalDataSize);\r
153\r
154 return gRT->SetVariable (\r
155 BootVariableName,\r
156 &gEfiGlobalVariableGuid,\r
157 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
158 VariableSize, Variable\r
159 );\r
160}\r
161\r
1bb1f35f
OM
162/**\r
163 Notification function of the event defined as belonging to the\r
164 EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in\r
165 the entry point of the driver.\r
166\r
167 This function is called when an event belonging to the\r
168 EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an\r
169 event is signalled once at the end of the dispatching of all\r
170 drivers (end of the so called DXE phase).\r
171\r
172 @param[in] Event Event declared in the entry point of the driver whose\r
173 notification function is being invoked.\r
174 @param[in] Context NULL\r
175**/\r
176STATIC\r
177VOID\r
178OnEndOfDxe (\r
179 IN EFI_EVENT Event,\r
180 IN VOID *Context\r
181 )\r
182{\r
183 EFI_DEVICE_PATH_PROTOCOL* PciRootComplexDevicePath;\r
184 EFI_HANDLE Handle;\r
185 EFI_STATUS Status;\r
186\r
187 //\r
188 // PCI Root Complex initialization\r
189 // At the end of the DXE phase, we should get all the driver dispatched.\r
190 // Force the PCI Root Complex to be initialized. It allows the OS to skip\r
191 // this step.\r
192 //\r
193 PciRootComplexDevicePath = (EFI_DEVICE_PATH_PROTOCOL*) &mPciRootComplexDevicePath;\r
194 Status = gBS->LocateDevicePath (&gEfiPciRootBridgeIoProtocolGuid,\r
195 &PciRootComplexDevicePath,\r
196 &Handle);\r
197\r
198 Status = gBS->ConnectController (Handle, NULL, PciRootComplexDevicePath, FALSE);\r
199 ASSERT_EFI_ERROR (Status);\r
200}\r
201\r
e0ae2761
OM
202STATIC\r
203BOOLEAN\r
204AcpiTableJunoR0Check (\r
205 IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader\r
206 )\r
207{\r
208 return TRUE;\r
209}\r
210\r
211STATIC\r
212BOOLEAN\r
213AcpiTableJunoR1Check (\r
214 IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader\r
215 )\r
216{\r
217 return TRUE;\r
218}\r
219\r
9f38945f
OM
220EFI_STATUS\r
221EFIAPI\r
222ArmJunoEntryPoint (\r
223 IN EFI_HANDLE ImageHandle,\r
224 IN EFI_SYSTEM_TABLE *SystemTable\r
225 )\r
226{\r
7aec2926
RC
227 EFI_STATUS Status;\r
228 EFI_PHYSICAL_ADDRESS HypBase;\r
229 CHAR16 *TextDevicePath;\r
230 UINTN TextDevicePathSize;\r
231 VOID *Buffer;\r
232 UINT32 Midr;\r
233 UINT32 CpuType;\r
234 UINT32 CpuRev;\r
c1fee786 235 JUNO_REVISION JunoRevision;\r
30cfc3d0 236 EFI_EVENT EndOfDxeEvent;\r
9f38945f 237\r
c1fee786 238 JunoRevision = UNKNOWN;\r
9f38945f
OM
239 Status = PciEmulationEntryPoint ();\r
240 if (EFI_ERROR (Status)) {\r
241 return Status;\r
242 }\r
243\r
244 //\r
245 // If a hypervisor has been declared then we need to make sure its region is protected at runtime\r
246 //\r
247 // Note: This code is only a workaround for our dummy hypervisor (ArmPkg/Extra/AArch64ToAArch32Shim/)\r
248 // that does not set up (yet) the stage 2 translation table to hide its own memory to EL1.\r
249 //\r
250 if (FixedPcdGet32 (PcdHypFvSize) != 0) {\r
251 // Ensure the hypervisor region is strictly contained into a EFI_PAGE_SIZE-aligned region.\r
252 // The memory must be a multiple of EFI_PAGE_SIZE to ensure we do not reserve more memory than the hypervisor itself.\r
253 // A UEFI Runtime region size granularity cannot be smaller than EFI_PAGE_SIZE. If the hypervisor size is not rounded\r
254 // to this size then there is a risk some non-runtime memory could be visible to the OS view.\r
255 if (((FixedPcdGet32 (PcdHypFvSize) & EFI_PAGE_MASK) == 0) && ((FixedPcdGet32 (PcdHypFvBaseAddress) & EFI_PAGE_MASK) == 0)) {\r
256 // The memory needs to be declared because the DXE core marked it as reserved and removed it from the memory space\r
257 // as it contains the Firmware.\r
258 Status = gDS->AddMemorySpace (\r
259 EfiGcdMemoryTypeSystemMemory,\r
260 FixedPcdGet32 (PcdHypFvBaseAddress), FixedPcdGet32 (PcdHypFvSize),\r
261 EFI_MEMORY_WB | EFI_MEMORY_RUNTIME\r
262 );\r
263 if (!EFI_ERROR (Status)) {\r
264 // We allocate the memory to ensure it is marked as runtime memory\r
265 HypBase = FixedPcdGet32 (PcdHypFvBaseAddress);\r
266 Status = gBS->AllocatePages (AllocateAddress, EfiRuntimeServicesCode,\r
267 EFI_SIZE_TO_PAGES (FixedPcdGet32 (PcdHypFvSize)), &HypBase);\r
268 }\r
269 } else {\r
270 // The hypervisor must be contained into a EFI_PAGE_SIZE-aligned region and its size must also be aligned\r
271 // on a EFI_PAGE_SIZE boundary (ie: 4KB).\r
272 Status = EFI_UNSUPPORTED;\r
273 ASSERT_EFI_ERROR (Status);\r
274 }\r
275\r
276 if (EFI_ERROR (Status)) {\r
277 return Status;\r
278 }\r
279 }\r
280\r
1bb1f35f
OM
281 //\r
282 // Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.\r
283 // The "OnEndOfDxe()" function is declared as the call back function.\r
284 // It will be called at the end of the DXE phase when an event of the\r
285 // same group is signalled to inform about the end of the DXE phase.\r
286 // Install the INSTALL_FDT_PROTOCOL protocol.\r
287 //\r
288 Status = gBS->CreateEventEx (\r
289 EVT_NOTIFY_SIGNAL,\r
290 TPL_CALLBACK,\r
291 OnEndOfDxe,\r
292 NULL,\r
293 &gEfiEndOfDxeEventGroupGuid,\r
294 &EndOfDxeEvent\r
295 );\r
296\r
9f38945f
OM
297 // Install dynamic Shell command to run baremetal binaries.\r
298 Status = ShellDynCmdRunAxfInstall (ImageHandle);\r
299 if (EFI_ERROR (Status)) {\r
300 DEBUG ((EFI_D_ERROR, "ArmJunoDxe: Failed to install ShellDynCmdRunAxf\n"));\r
301 }\r
302\r
7aec2926 303 //\r
7aec2926
RC
304 // We detect whether we are running on a Juno r0 or Juno r1 board at\r
305 // runtime by checking the value of the MIDR register.\r
306 //\r
307\r
c1fee786
RC
308 Midr = ArmReadMidr ();\r
309 CpuType = (Midr >> ARM_CPU_TYPE_SHIFT) & ARM_CPU_TYPE_MASK;\r
310 CpuRev = Midr & ARM_CPU_REV_MASK;\r
7aec2926
RC
311\r
312 switch (CpuType) {\r
313 case ARM_CPU_TYPE_A53:\r
314 if (CpuRev == ARM_CPU_REV (0, 0)) {\r
c1fee786 315 JunoRevision = JUNO_R0;\r
7aec2926 316 } else if (CpuRev == ARM_CPU_REV (0, 3)) {\r
c1fee786 317 JunoRevision = JUNO_R1;\r
7aec2926
RC
318 }\r
319 break;\r
320\r
321 case ARM_CPU_TYPE_A57:\r
322 if (CpuRev == ARM_CPU_REV (0, 0)) {\r
c1fee786 323 JunoRevision = JUNO_R0;\r
7aec2926 324 } else if (CpuRev == ARM_CPU_REV (1, 1)) {\r
c1fee786
RC
325 JunoRevision = JUNO_R1;\r
326 }\r
327 }\r
328\r
329 //\r
e0ae2761 330 // Try to install the ACPI Tables\r
c1fee786 331 //\r
e0ae2761
OM
332 if (JunoRevision == JUNO_R0) {\r
333 Status = LocateAndInstallAcpiFromFvConditional (&mJunoAcpiTableFile, AcpiTableJunoR0Check);\r
334 } else if (JunoRevision == JUNO_R1) {\r
335 Status = LocateAndInstallAcpiFromFvConditional (&mJunoAcpiTableFile, AcpiTableJunoR1Check);\r
336 }\r
337 ASSERT_EFI_ERROR (Status);\r
338\r
c1fee786 339\r
e0ae2761
OM
340 //\r
341 // Set the R1 two boot options if not already done.\r
342 //\r
c1fee786
RC
343 if (JunoRevision == JUNO_R1) {\r
344 Status = SetJunoR1DefaultBootEntries ();\r
345 if (EFI_ERROR (Status)) {\r
346 return Status;\r
7aec2926 347 }\r
ad7d95ea
OM
348\r
349 // Enable PCI enumeration\r
350 PcdSetBool (PcdPciDisableBusEnumeration, FALSE);\r
e0ae2761
OM
351\r
352 // Declare the related ACPI Tables\r
353 EfiCreateProtocolNotifyEvent (\r
354 &gEfiAcpiTableProtocolGuid,\r
355 TPL_CALLBACK,\r
356 AcpiPciNotificationEvent,\r
357 NULL,\r
358 &mAcpiRegistration\r
359 );\r
7aec2926
RC
360 }\r
361\r
c1fee786
RC
362 //\r
363 // Set up the device path to the FDT.\r
364 //\r
365 switch (JunoRevision) {\r
366 case JUNO_R0:\r
367 TextDevicePath = (CHAR16*)FixedPcdGetPtr (PcdJunoR0FdtDevicePath);\r
368 break;\r
369\r
370 case JUNO_R1:\r
371 TextDevicePath = (CHAR16*)FixedPcdGetPtr (PcdJunoR1A57x2FdtDevicePath);\r
372 break;\r
373\r
374 default:\r
375 TextDevicePath = NULL;\r
376 }\r
377\r
7aec2926
RC
378 if (TextDevicePath != NULL) {\r
379 TextDevicePathSize = StrSize (TextDevicePath);\r
380 Buffer = PcdSetPtr (PcdFdtDevicePaths, &TextDevicePathSize, TextDevicePath);\r
381 Status = (Buffer != NULL) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;\r
382 } else {\r
383 Status = EFI_NOT_FOUND;\r
384 }\r
385\r
05e56470 386 if (EFI_ERROR (Status)) {\r
7aec2926
RC
387 DEBUG (\r
388 (EFI_D_ERROR,\r
389 "ArmJunoDxe: Setting of FDT device path in PcdFdtDevicePaths failed - %r\n", Status)\r
390 );\r
05e56470
OM
391 return Status;\r
392 }\r
21a76332 393\r
c1fee786
RC
394 return Status;\r
395}\r
396\r
397/**\r
398 * If no boot entry is currently defined, define the two default boot entries\r
399 * for Juno R1.\r
400 *\r
401 * @return EFI_SUCCESS Some boot entries were already defined or\r
402 * the default boot entries were set successfully.\r
403 * @return EFI_OUT_OF_RESOURCES A memory allocation failed.\r
404 * @return EFI_DEVICE_ERROR An UEFI variable could not be saved due to a hardware failure.\r
405 * @return EFI_WRITE_PROTECTED An UEFI variable is read-only.\r
406 * @return EFI_SECURITY_VIOLATION An UEFI variable could not be written.\r
407 */\r
408STATIC\r
409EFI_STATUS\r
410SetJunoR1DefaultBootEntries (\r
411 VOID\r
412 )\r
413{\r
414 EFI_STATUS Status;\r
1667d2e1 415 CONST CHAR16* ExtraBootArgument = L" dtb=r1a57a53.dtb";\r
c1fee786
RC
416 UINTN Size;\r
417 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;\r
418 EFI_DEVICE_PATH* BootDevicePath;\r
419 UINT32 SysPciGbeL;\r
420 UINT32 SysPciGbeH;\r
421 CHAR16* DefaultBootArgument;\r
422 CHAR16* DefaultBootArgument1;\r
423 UINTN DefaultBootArgument1Size;\r
424 CHAR16* DefaultBootArgument2;\r
425 UINTN DefaultBootArgument2Size;\r
426 UINT16 BootOrder[2];\r
427\r
428 BootDevicePath = NULL;\r
429 DefaultBootArgument1 = NULL;\r
430 DefaultBootArgument2 = NULL;\r
431\r
6d60dfea 432 //\r
c1fee786
RC
433 // Because the driver has a dependency on gEfiVariable(Write)ArchProtocolGuid\r
434 // (see [Depex] section of the INF file), we know we can safely access the\r
435 // UEFI Variable at that stage.\r
6d60dfea 436 //\r
c1fee786
RC
437 Size = 0;\r
438 Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL);\r
439 if (Status != EFI_NOT_FOUND) {\r
8debfa0c 440 return EFI_SUCCESS;\r
c1fee786
RC
441 }\r
442\r
443 Status = gBS->LocateProtocol (\r
444 &gEfiDevicePathFromTextProtocolGuid,\r
445 NULL,\r
446 (VOID **)&EfiDevicePathFromTextProtocol\r
447 );\r
448 if (EFI_ERROR (Status)) {\r
449 //\r
450 // You must provide an implementation of DevicePathFromTextProtocol\r
451 // in your firmware (eg: DevicePathDxe)\r
452 //\r
453 DEBUG ((EFI_D_ERROR, "Error: Require DevicePathFromTextProtocol\n"));\r
454 return Status;\r
455 }\r
456 //\r
457 // We use the same default kernel.\r
458 //\r
459 BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (\r
460 (CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath)\r
461 );\r
462 if (BootDevicePath == NULL) {\r
463 return EFI_UNSUPPORTED;\r
464 }\r
465\r
466 DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument);\r
467 DefaultBootArgument1Size = StrSize (DefaultBootArgument) +\r
468 (SKY2_MAC_ADDRESS_BOOTARG_LEN * sizeof (CHAR16));\r
469 DefaultBootArgument2Size = DefaultBootArgument1Size + StrSize (ExtraBootArgument);\r
470\r
471 Status = EFI_OUT_OF_RESOURCES;\r
472 DefaultBootArgument1 = AllocatePool (DefaultBootArgument1Size);\r
473 if (DefaultBootArgument1 == NULL) {\r
474 goto Error;\r
475 }\r
476 DefaultBootArgument2 = AllocatePool (DefaultBootArgument2Size);\r
477 if (DefaultBootArgument2 == NULL) {\r
478 goto Error;\r
479 }\r
480\r
481 SysPciGbeL = MmioRead32 (ARM_JUNO_SYS_PCIGBE_L);\r
482 SysPciGbeH = MmioRead32 (ARM_JUNO_SYS_PCIGBE_H);\r
483\r
484 UnicodeSPrint (\r
485 DefaultBootArgument1,\r
486 DefaultBootArgument1Size,\r
487 L"%s sky2.mac_address=0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x",\r
488 DefaultBootArgument,\r
489 (SysPciGbeH >> 8 ) & 0xFF, (SysPciGbeH ) & 0xFF,\r
490 (SysPciGbeL >> 24) & 0xFF, (SysPciGbeL >> 16) & 0xFF,\r
491 (SysPciGbeL >> 8 ) & 0xFF, (SysPciGbeL ) & 0xFF\r
492 );\r
493\r
494 CopyMem (DefaultBootArgument2, DefaultBootArgument1, DefaultBootArgument1Size);\r
495 CopyMem (\r
496 (UINT8*)DefaultBootArgument2 + DefaultBootArgument1Size - sizeof (CHAR16),\r
497 ExtraBootArgument,\r
498 StrSize (ExtraBootArgument)\r
499 );\r
500\r
501 //\r
502 // Create Boot0001 environment variable\r
503 //\r
504 Status = BootOptionCreate (\r
505 L"Boot0001", LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT,\r
506 L"Linux with A57x2", BootDevicePath,\r
507 (UINT8*)DefaultBootArgument1, DefaultBootArgument1Size\r
508 );\r
509 if (EFI_ERROR (Status)) {\r
8debfa0c 510 ASSERT_EFI_ERROR (Status);\r
c1fee786
RC
511 goto Error;\r
512 }\r
513\r
514 //\r
515 // Create Boot0002 environment variable\r
516 //\r
517 Status = BootOptionCreate (\r
518 L"Boot0002", LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT,\r
519 L"Linux with A57x2_A53x4", BootDevicePath,\r
520 (UINT8*)DefaultBootArgument2, DefaultBootArgument2Size\r
521 );\r
522 if (EFI_ERROR (Status)) {\r
8debfa0c 523 ASSERT_EFI_ERROR (Status);\r
c1fee786
RC
524 goto Error;\r
525 }\r
526\r
527 //\r
528 // Add the new Boot Index to the list\r
529 //\r
530 BootOrder[0] = 1; // Boot0001\r
531 BootOrder[1] = 2; // Boot0002\r
532 Status = gRT->SetVariable (\r
533 L"BootOrder",\r
534 &gEfiGlobalVariableGuid,\r
535 EFI_VARIABLE_NON_VOLATILE |\r
536 EFI_VARIABLE_BOOTSERVICE_ACCESS |\r
537 EFI_VARIABLE_RUNTIME_ACCESS,\r
538 sizeof (BootOrder),\r
539 BootOrder\r
540 );\r
541\r
8debfa0c 542Error:\r
c1fee786
RC
543 if (BootDevicePath != NULL) {\r
544 FreePool (BootDevicePath);\r
545 }\r
546 if (DefaultBootArgument1 != NULL) {\r
547 FreePool (DefaultBootArgument1);\r
548 }\r
549 if (DefaultBootArgument2 != NULL) {\r
550 FreePool (DefaultBootArgument2);\r
551 }\r
552\r
553 if (EFI_ERROR (Status)) {\r
554 DEBUG ((\r
555 EFI_D_ERROR,\r
556 "ArmJunoDxe - The setting of the default boot entries failed - %r\n",\r
557 Status\r
558 ));\r
6d60dfea
OM
559 }\r
560\r
9f38945f
OM
561 return Status;\r
562}\r