3 * Copyright (c) 2011, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BdsInternal.h"
17 #include <Library/NetLib.h>
19 #include <Protocol/BlockIo.h>
20 #include <Protocol/DevicePathToText.h>
21 #include <Protocol/PxeBaseCode.h>
22 #include <Protocol/SimpleFileSystem.h>
23 #include <Protocol/SimpleNetwork.h>
25 #include <Guid/FileSystemInfo.h>
27 #define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))
30 BdsLoadOptionFileSystemList (
31 IN OUT LIST_ENTRY
* BdsLoadOptionList
35 BdsLoadOptionFileSystemCreateDevicePath (
36 IN BDS_SUPPORTED_DEVICE
* BdsLoadOption
,
37 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNode
,
38 OUT ARM_BDS_LOADER_TYPE
*BootType
,
39 OUT UINT32
*Attributes
43 BdsLoadOptionFileSystemUpdateDevicePath (
44 IN EFI_DEVICE_PATH
*OldDevicePath
,
45 OUT EFI_DEVICE_PATH_PROTOCOL
** NewDevicePath
,
46 OUT ARM_BDS_LOADER_TYPE
*BootType
,
47 OUT UINT32
*Attributes
51 BdsLoadOptionFileSystemIsSupported (
52 IN BDS_LOAD_OPTION
* BdsLoadOption
56 BdsLoadOptionMemMapList (
57 IN OUT LIST_ENTRY
* BdsLoadOptionList
61 BdsLoadOptionMemMapCreateDevicePath (
62 IN BDS_SUPPORTED_DEVICE
* BdsLoadOption
,
63 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNode
,
64 OUT ARM_BDS_LOADER_TYPE
*BootType
,
65 OUT UINT32
*Attributes
69 BdsLoadOptionMemMapUpdateDevicePath (
70 IN EFI_DEVICE_PATH
*OldDevicePath
,
71 OUT EFI_DEVICE_PATH_PROTOCOL
** NewDevicePath
,
72 OUT ARM_BDS_LOADER_TYPE
*BootType
,
73 OUT UINT32
*Attributes
77 BdsLoadOptionMemMapIsSupported (
78 IN BDS_LOAD_OPTION
* BdsLoadOption
82 BdsLoadOptionPxeList (
83 IN OUT LIST_ENTRY
* BdsLoadOptionList
87 BdsLoadOptionPxeCreateDevicePath (
88 IN BDS_SUPPORTED_DEVICE
* BdsLoadOption
,
89 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNode
,
90 OUT ARM_BDS_LOADER_TYPE
*BootType
,
91 OUT UINT32
*Attributes
95 BdsLoadOptionPxeUpdateDevicePath (
96 IN EFI_DEVICE_PATH
*OldDevicePath
,
97 OUT EFI_DEVICE_PATH_PROTOCOL
** NewDevicePath
,
98 OUT ARM_BDS_LOADER_TYPE
*BootType
,
99 OUT UINT32
*Attributes
103 BdsLoadOptionPxeIsSupported (
104 IN BDS_LOAD_OPTION
* BdsLoadOption
108 BdsLoadOptionTftpList (
109 IN OUT LIST_ENTRY
* BdsLoadOptionList
113 BdsLoadOptionTftpCreateDevicePath (
114 IN BDS_SUPPORTED_DEVICE
* BdsLoadOption
,
115 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNode
,
116 OUT ARM_BDS_LOADER_TYPE
*BootType
,
117 OUT UINT32
*Attributes
121 BdsLoadOptionTftpUpdateDevicePath (
122 IN EFI_DEVICE_PATH
*OldDevicePath
,
123 OUT EFI_DEVICE_PATH_PROTOCOL
** NewDevicePath
,
124 OUT ARM_BDS_LOADER_TYPE
*BootType
,
125 OUT UINT32
*Attributes
129 BdsLoadOptionTftpIsSupported (
130 IN BDS_LOAD_OPTION
* BdsLoadOption
133 BDS_LOAD_OPTION_SUPPORT BdsLoadOptionSupportList
[] = {
135 BDS_DEVICE_FILESYSTEM
,
136 BdsLoadOptionFileSystemList
,
137 BdsLoadOptionFileSystemIsSupported
,
138 BdsLoadOptionFileSystemCreateDevicePath
,
139 BdsLoadOptionFileSystemUpdateDevicePath
143 BdsLoadOptionMemMapList
,
144 BdsLoadOptionMemMapIsSupported
,
145 BdsLoadOptionMemMapCreateDevicePath
,
146 BdsLoadOptionMemMapUpdateDevicePath
150 BdsLoadOptionPxeList
,
151 BdsLoadOptionPxeIsSupported
,
152 BdsLoadOptionPxeCreateDevicePath
,
153 BdsLoadOptionPxeUpdateDevicePath
157 BdsLoadOptionTftpList
,
158 BdsLoadOptionTftpIsSupported
,
159 BdsLoadOptionTftpCreateDevicePath
,
160 BdsLoadOptionTftpUpdateDevicePath
165 BootDeviceListSupportedInit (
166 IN OUT LIST_ENTRY
*SupportedDeviceList
171 // Initialize list of supported devices
172 InitializeListHead (SupportedDeviceList
);
174 for (Index
= 0; Index
< BDS_DEVICE_MAX
; Index
++) {
175 BdsLoadOptionSupportList
[Index
].ListDevices (SupportedDeviceList
);
182 BootDeviceListSupportedFree (
183 IN LIST_ENTRY
*SupportedDeviceList
,
184 IN BDS_SUPPORTED_DEVICE
*Except
188 BDS_SUPPORTED_DEVICE
* SupportedDevice
;
190 Entry
= GetFirstNode (SupportedDeviceList
);
191 while (Entry
!= SupportedDeviceList
) {
192 SupportedDevice
= SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry
);
193 Entry
= RemoveEntryList (Entry
);
194 if (SupportedDevice
!= Except
) {
195 FreePool (SupportedDevice
);
203 BootDeviceGetDeviceSupport (
204 IN BDS_LOAD_OPTION
*BootOption
,
205 OUT BDS_LOAD_OPTION_SUPPORT
** DeviceSupport
210 // Find which supported device is the most appropriate
211 for (Index
= 0; Index
< BDS_DEVICE_MAX
; Index
++) {
212 if (BdsLoadOptionSupportList
[Index
].IsSupported(BootOption
)) {
213 *DeviceSupport
= &BdsLoadOptionSupportList
[Index
];
218 return EFI_UNSUPPORTED
;
225 OUT ARM_BDS_LOADER_TYPE
*BootType
,
226 OUT UINT32
*Attributes
231 BOOLEAN IsBootLoader
;
232 BOOLEAN HasFDTSupport
;
234 if (FileName
== NULL
) {
235 Print(L
"Is an EFI Application? ");
236 Status
= GetHIInputBoolean (&IsEfiApp
);
237 if (EFI_ERROR(Status
)) {
240 } else if (HasFilePathEfiExtension(FileName
)) {
247 Print(L
"Is your application is an OS loader? ");
248 Status
= GetHIInputBoolean (&IsBootLoader
);
249 if (EFI_ERROR(Status
)) {
253 *Attributes
|= LOAD_OPTION_CATEGORY_APP
;
255 *BootType
= BDS_LOADER_EFI_APPLICATION
;
257 Print(L
"Has FDT support? ");
258 Status
= GetHIInputBoolean (&HasFDTSupport
);
259 if (EFI_ERROR(Status
)) {
263 *BootType
= BDS_LOADER_KERNEL_LINUX_FDT
;
265 *BootType
= BDS_LOADER_KERNEL_LINUX_ATAG
;
273 BdsLoadOptionFileSystemList (
274 IN OUT LIST_ENTRY
* BdsLoadOptionList
279 EFI_HANDLE
*HandleBuffer
;
281 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
282 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
* FileProtocol
;
285 EFI_FILE_SYSTEM_INFO
* FsInfo
;
286 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
288 // List all the Simple File System Protocols
289 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiSimpleFileSystemProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
290 if (EFI_ERROR (Status
)) {
294 for (Index
= 0; Index
< HandleCount
; Index
++) {
295 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
296 if (!EFI_ERROR(Status
)) {
297 // Allocate BDS Supported Device structure
298 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool (sizeof(BDS_SUPPORTED_DEVICE
));
301 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)&FileProtocol
);
302 ASSERT_EFI_ERROR(Status
);
304 FileProtocol
->OpenVolume (FileProtocol
, &Fs
);
306 // Generate a Description from the file system
309 Status
= Fs
->GetInfo (Fs
, &gEfiFileSystemInfoGuid
, &Size
, FsInfo
);
310 if (Status
== EFI_BUFFER_TOO_SMALL
) {
311 FsInfo
= AllocatePool (Size
);
312 Status
= Fs
->GetInfo (Fs
, &gEfiFileSystemInfoGuid
, &Size
, FsInfo
);
314 UnicodeSPrint (SupportedDevice
->Description
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"%s (%d MB)",FsInfo
->VolumeLabel
,(UINT32
)(FsInfo
->VolumeSize
/ (1024 * 1024)));
318 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
319 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_FILESYSTEM
];
321 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
329 BdsLoadOptionFileSystemCreateDevicePath (
330 IN BDS_SUPPORTED_DEVICE
* BdsLoadOption
,
331 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNode
,
332 OUT ARM_BDS_LOADER_TYPE
*BootType
,
333 OUT UINT32
*Attributes
337 FILEPATH_DEVICE_PATH
* FilePathDevicePath
;
338 CHAR16 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
];
339 UINTN BootFilePathSize
;
341 Status
= GetHIInputStr (BootFilePath
, BOOT_DEVICE_FILEPATH_MAX
);
342 if (EFI_ERROR(Status
)) {
346 BootFilePathSize
= StrSize (BootFilePath
);
347 if (BootFilePathSize
== 2) {
348 *DevicePathNode
= NULL
;
349 return EFI_NOT_FOUND
;
352 // Create the FilePath Device Path node
353 FilePathDevicePath
= (FILEPATH_DEVICE_PATH
*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
354 FilePathDevicePath
->Header
.Type
= MEDIA_DEVICE_PATH
;
355 FilePathDevicePath
->Header
.SubType
= MEDIA_FILEPATH_DP
;
356 SetDevicePathNodeLength (FilePathDevicePath
, SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
357 CopyMem (FilePathDevicePath
->PathName
, BootFilePath
, BootFilePathSize
);
359 if (BootType
!= NULL
|| Attributes
!= NULL
) {
360 Status
= BootDeviceGetType (FilePathDevicePath
->PathName
, BootType
, Attributes
);
363 if (EFI_ERROR(Status
)) {
364 FreePool (FilePathDevicePath
);
366 *DevicePathNode
= (EFI_DEVICE_PATH_PROTOCOL
*)FilePathDevicePath
;
373 BdsLoadOptionFileSystemUpdateDevicePath (
374 IN EFI_DEVICE_PATH
*OldDevicePath
,
375 OUT EFI_DEVICE_PATH_PROTOCOL
** NewDevicePath
,
376 OUT ARM_BDS_LOADER_TYPE
*BootType
,
377 OUT UINT32
*Attributes
381 CHAR16 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
];
382 UINTN BootFilePathSize
;
383 FILEPATH_DEVICE_PATH
* EndingDevicePath
;
384 FILEPATH_DEVICE_PATH
* FilePathDevicePath
;
385 EFI_DEVICE_PATH
* DevicePath
;
387 DevicePath
= DuplicateDevicePath(OldDevicePath
);
389 EndingDevicePath
= (FILEPATH_DEVICE_PATH
*)GetLastDevicePathNode (DevicePath
);
391 StrnCpy (BootFilePath
, EndingDevicePath
->PathName
, BOOT_DEVICE_FILEPATH_MAX
);
392 Status
= EditHIInputStr (BootFilePath
, BOOT_DEVICE_FILEPATH_MAX
);
393 if (EFI_ERROR(Status
)) {
397 BootFilePathSize
= StrSize(BootFilePath
);
398 if (BootFilePathSize
== 2) {
399 *NewDevicePath
= NULL
;
400 return EFI_NOT_FOUND
;
403 // Create the FilePath Device Path node
404 FilePathDevicePath
= (FILEPATH_DEVICE_PATH
*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
405 FilePathDevicePath
->Header
.Type
= MEDIA_DEVICE_PATH
;
406 FilePathDevicePath
->Header
.SubType
= MEDIA_FILEPATH_DP
;
407 SetDevicePathNodeLength (FilePathDevicePath
, SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
408 CopyMem (FilePathDevicePath
->PathName
, BootFilePath
, BootFilePathSize
);
410 // Generate the new Device Path by replacing the last node by the updated node
411 SetDevicePathEndNode (EndingDevicePath
);
412 *NewDevicePath
= AppendDevicePathNode (DevicePath
, (CONST EFI_DEVICE_PATH_PROTOCOL
*)FilePathDevicePath
);
413 FreePool(DevicePath
);
415 if (BootType
!= NULL
|| Attributes
!= NULL
) {
416 return BootDeviceGetType (FilePathDevicePath
->PathName
, BootType
, Attributes
);
423 BdsLoadOptionFileSystemIsSupported (
424 IN BDS_LOAD_OPTION
* BdsLoadOption
427 EFI_DEVICE_PATH
* DevicePathNode
;
429 DevicePathNode
= GetLastDevicePathNode (BdsLoadOption
->FilePathList
);
431 return IS_DEVICE_PATH_NODE(DevicePathNode
,MEDIA_DEVICE_PATH
,MEDIA_FILEPATH_DP
);
437 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
438 IN EFI_DEVICE_PATH_PROTOCOL
*ChildDevicePath
444 ParentSize
= GetDevicePathSize (ParentDevicePath
);
445 ChildSize
= GetDevicePathSize (ChildDevicePath
);
447 if (ParentSize
> ChildSize
) {
451 if (CompareMem (ParentDevicePath
, ChildDevicePath
, ParentSize
- END_DEVICE_PATH_LENGTH
) != 0) {
459 BdsLoadOptionMemMapList (
460 IN OUT LIST_ENTRY
* BdsLoadOptionList
465 EFI_HANDLE
*HandleBuffer
;
466 UINTN DevicePathHandleCount
;
467 EFI_HANDLE
*DevicePathHandleBuffer
;
471 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
472 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
473 EFI_DEVICE_PATH
* DevicePath
;
475 // List all the BlockIo Protocols
476 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiBlockIoProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
477 if (EFI_ERROR (Status
)) {
481 for (Index
= 0; Index
< HandleCount
; Index
++) {
482 // We only select the handle WITH a Device Path AND not part of Media (to avoid duplication with HardDisk, CDROM, etc)
483 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
484 if (!EFI_ERROR(Status
)) {
485 // BlockIo is not part of Media Device Path
486 DevicePath
= DevicePathProtocol
;
487 while (!IsDevicePathEndType (DevicePath
) && (DevicePathType (DevicePath
) != MEDIA_DEVICE_PATH
)) {
488 DevicePath
= NextDevicePathNode (DevicePath
);
490 if (DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) {
494 // Open all the handle supporting the DevicePath protocol and verify this handle has not got any child
495 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiDevicePathProtocolGuid
, NULL
, &DevicePathHandleCount
, &DevicePathHandleBuffer
);
496 ASSERT_EFI_ERROR (Status
);
498 for (Index2
= 0; (Index2
< DevicePathHandleCount
) && !IsParent
; Index2
++) {
499 if (HandleBuffer
[Index
] != DevicePathHandleBuffer
[Index2
]) {
500 gBS
->HandleProtocol (DevicePathHandleBuffer
[Index2
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePath
);
501 if (IsParentDevicePath (DevicePathProtocol
, DevicePath
)) {
510 // Allocate BDS Supported Device structure
511 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE
));
513 Status
= GenerateDeviceDescriptionName (HandleBuffer
[Index
], SupportedDevice
->Description
);
514 ASSERT_EFI_ERROR (Status
);
516 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
517 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_MEMMAP
];
519 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
527 BdsLoadOptionMemMapCreateDevicePath (
528 IN BDS_SUPPORTED_DEVICE
* BdsLoadOption
,
529 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNode
,
530 OUT ARM_BDS_LOADER_TYPE
*BootType
,
531 OUT UINT32
*Attributes
535 MEMMAP_DEVICE_PATH
* MemMapDevicePath
;
536 CHAR16 StrStartingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
537 CHAR16 StrEndingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
539 Print(L
"Starting Address of the binary: ");
540 Status
= GetHIInputStr (StrStartingAddress
,BOOT_DEVICE_ADDRESS_MAX
);
541 if (EFI_ERROR(Status
)) {
545 Print(L
"Ending Address of the binary: ");
546 Status
= GetHIInputStr (StrEndingAddress
,BOOT_DEVICE_ADDRESS_MAX
);
547 if (EFI_ERROR(Status
)) {
551 // Create the MemMap Device Path Node
552 MemMapDevicePath
= (MEMMAP_DEVICE_PATH
*)AllocatePool (sizeof(MEMMAP_DEVICE_PATH
));
553 MemMapDevicePath
->Header
.Type
= HARDWARE_DEVICE_PATH
;
554 MemMapDevicePath
->Header
.SubType
= HW_MEMMAP_DP
;
555 MemMapDevicePath
->MemoryType
= EfiBootServicesData
;
556 MemMapDevicePath
->StartingAddress
= StrHexToUint64 (StrStartingAddress
);
557 MemMapDevicePath
->EndingAddress
= StrHexToUint64 (StrEndingAddress
);
559 Status
= BootDeviceGetType (NULL
, BootType
, Attributes
);
560 if (EFI_ERROR(Status
)) {
561 FreePool (MemMapDevicePath
);
563 *DevicePathNode
= (EFI_DEVICE_PATH_PROTOCOL
*)MemMapDevicePath
;
570 BdsLoadOptionMemMapUpdateDevicePath (
571 IN EFI_DEVICE_PATH
*OldDevicePath
,
572 OUT EFI_DEVICE_PATH_PROTOCOL
** NewDevicePath
,
573 OUT ARM_BDS_LOADER_TYPE
*BootType
,
574 OUT UINT32
*Attributes
578 CHAR16 StrStartingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
579 CHAR16 StrEndingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
580 MEMMAP_DEVICE_PATH
* EndingDevicePath
;
581 EFI_DEVICE_PATH
* DevicePath
;
583 DevicePath
= DuplicateDevicePath (OldDevicePath
);
584 EndingDevicePath
= (MEMMAP_DEVICE_PATH
*)GetLastDevicePathNode (DevicePath
);
586 Print(L
"Starting Address of the binary: ");
587 UnicodeSPrint (StrStartingAddress
, BOOT_DEVICE_ADDRESS_MAX
, L
"0x%X", (UINTN
)EndingDevicePath
->StartingAddress
);
588 Status
= EditHIInputStr (StrStartingAddress
, BOOT_DEVICE_ADDRESS_MAX
);
589 if (EFI_ERROR(Status
)) {
593 Print(L
"Ending Address of the binary: ");
594 UnicodeSPrint (StrEndingAddress
, BOOT_DEVICE_ADDRESS_MAX
, L
"0x%X", (UINTN
)EndingDevicePath
->EndingAddress
);
595 Status
= EditHIInputStr (StrEndingAddress
, BOOT_DEVICE_ADDRESS_MAX
);
596 if (EFI_ERROR(Status
)) {
600 EndingDevicePath
->StartingAddress
= StrHexToUint64 (StrStartingAddress
);
601 EndingDevicePath
->EndingAddress
= StrHexToUint64 (StrEndingAddress
);
603 Status
= BootDeviceGetType (NULL
, BootType
, Attributes
);
604 if (EFI_ERROR(Status
)) {
605 FreePool(DevicePath
);
607 *NewDevicePath
= DevicePath
;
614 BdsLoadOptionMemMapIsSupported (
615 IN BDS_LOAD_OPTION
* BdsLoadOption
618 EFI_DEVICE_PATH
* DevicePathNode
;
620 DevicePathNode
= GetLastDevicePathNode (BdsLoadOption
->FilePathList
);
622 return IS_DEVICE_PATH_NODE(DevicePathNode
,HARDWARE_DEVICE_PATH
,HW_MEMMAP_DP
);
626 BdsLoadOptionPxeList (
627 IN OUT LIST_ENTRY
* BdsLoadOptionList
632 EFI_HANDLE
*HandleBuffer
;
634 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
635 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
636 EFI_SIMPLE_NETWORK_PROTOCOL
* SimpleNet
;
637 CHAR16 DeviceDescription
[BOOT_DEVICE_DESCRIPTION_MAX
];
638 EFI_MAC_ADDRESS
*Mac
;
640 // List all the PXE Protocols
641 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiPxeBaseCodeProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
642 if (EFI_ERROR (Status
)) {
646 for (Index
= 0; Index
< HandleCount
; Index
++) {
647 // We only select the handle WITH a Device Path AND the PXE Protocol
648 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
649 if (!EFI_ERROR(Status
)) {
650 // Allocate BDS Supported Device structure
651 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE
));
653 Status
= gBS
->LocateProtocol (&gEfiSimpleNetworkProtocolGuid
, NULL
, (VOID
**)&SimpleNet
);
654 if (!EFI_ERROR(Status
)) {
655 Mac
= &SimpleNet
->Mode
->CurrentAddress
;
656 UnicodeSPrint (DeviceDescription
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac
->Addr
[0], Mac
->Addr
[1], Mac
->Addr
[2], Mac
->Addr
[3], Mac
->Addr
[4], Mac
->Addr
[5]);
658 Status
= GenerateDeviceDescriptionName (HandleBuffer
[Index
], DeviceDescription
);
659 ASSERT_EFI_ERROR (Status
);
661 UnicodeSPrint (SupportedDevice
->Description
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"PXE on %s",DeviceDescription
);
663 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
664 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_PXE
];
666 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
674 BdsLoadOptionPxeCreateDevicePath (
675 IN BDS_SUPPORTED_DEVICE
* BdsLoadOption
,
676 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNode
,
677 OUT ARM_BDS_LOADER_TYPE
*BootType
,
678 OUT UINT32
*Attributes
681 *DevicePathNode
= (EFI_DEVICE_PATH_PROTOCOL
*) AllocatePool (END_DEVICE_PATH_LENGTH
);
682 SetDevicePathEndNode (*DevicePathNode
);
683 *BootType
= BDS_LOADER_EFI_APPLICATION
;
688 BdsLoadOptionPxeUpdateDevicePath (
689 IN EFI_DEVICE_PATH
*OldDevicePath
,
690 OUT EFI_DEVICE_PATH_PROTOCOL
** NewDevicePath
,
691 OUT ARM_BDS_LOADER_TYPE
*BootType
,
692 OUT UINT32
*Attributes
700 BdsLoadOptionPxeIsSupported (
701 IN BDS_LOAD_OPTION
* BdsLoadOption
706 EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
;
707 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBcProtocol
;
709 Status
= BdsConnectDevicePath (BdsLoadOption
->FilePathList
, &Handle
, &RemainingDevicePath
);
710 if (EFI_ERROR(Status
)) {
714 if (!IsDevicePathEnd(RemainingDevicePath
)) {
718 Status
= gBS
->HandleProtocol (Handle
, &gEfiPxeBaseCodeProtocolGuid
, (VOID
**)&PxeBcProtocol
);
719 if (EFI_ERROR (Status
)) {
727 BdsLoadOptionTftpList (
728 IN OUT LIST_ENTRY
* BdsLoadOptionList
733 EFI_HANDLE
*HandleBuffer
;
735 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
736 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
737 EFI_SIMPLE_NETWORK_PROTOCOL
* SimpleNet
;
738 CHAR16 DeviceDescription
[BOOT_DEVICE_DESCRIPTION_MAX
];
739 EFI_MAC_ADDRESS
*Mac
;
741 // List all the PXE Protocols
742 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiPxeBaseCodeProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
743 if (EFI_ERROR (Status
)) {
747 for (Index
= 0; Index
< HandleCount
; Index
++) {
748 // We only select the handle WITH a Device Path AND the PXE Protocol AND the TFTP Protocol (the TFTP protocol is required to start PXE)
749 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
750 if (!EFI_ERROR(Status
)) {
751 // Allocate BDS Supported Device structure
752 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE
));
754 Status
= gBS
->LocateProtocol (&gEfiSimpleNetworkProtocolGuid
, NULL
, (VOID
**)&SimpleNet
);
755 if (!EFI_ERROR(Status
)) {
756 Mac
= &SimpleNet
->Mode
->CurrentAddress
;
757 UnicodeSPrint (DeviceDescription
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac
->Addr
[0], Mac
->Addr
[1], Mac
->Addr
[2], Mac
->Addr
[3], Mac
->Addr
[4], Mac
->Addr
[5]);
759 Status
= GenerateDeviceDescriptionName (HandleBuffer
[Index
], DeviceDescription
);
760 ASSERT_EFI_ERROR (Status
);
762 UnicodeSPrint (SupportedDevice
->Description
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"TFP on %s",DeviceDescription
);
764 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
765 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_TFTP
];
767 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
775 BdsLoadOptionTftpCreateDevicePath (
776 IN BDS_SUPPORTED_DEVICE
* BdsLoadOption
,
777 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNode
,
778 OUT ARM_BDS_LOADER_TYPE
*BootType
,
779 OUT UINT32
*Attributes
784 EFI_IP_ADDRESS LocalIp
;
785 EFI_IP_ADDRESS RemoteIp
;
786 IPv4_DEVICE_PATH
* IPv4DevicePathNode
;
787 FILEPATH_DEVICE_PATH
* FilePathDevicePath
;
788 CHAR16 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
];
789 UINTN BootFilePathSize
;
791 Print(L
"Get the IP address from DHCP: ");
792 Status
= GetHIInputBoolean (&IsDHCP
);
793 if (EFI_ERROR(Status
)) {
798 Print(L
"Get the static IP address: ");
799 Status
= GetHIInputIP (&LocalIp
);
800 if (EFI_ERROR(Status
)) {
805 Print(L
"Get the TFTP server IP address: ");
806 Status
= GetHIInputIP (&RemoteIp
);
807 if (EFI_ERROR(Status
)) {
811 Print(L
"File path of the EFI Application or the kernel : ");
812 Status
= GetHIInputStr (BootFilePath
, BOOT_DEVICE_FILEPATH_MAX
);
813 if (EFI_ERROR(Status
)) {
817 BootFilePathSize
= StrSize(BootFilePath
);
818 if (BootFilePathSize
== 2) {
819 return EFI_NOT_FOUND
;
822 // Allocate the memory for the IPv4 + File Path Device Path Nodes
823 IPv4DevicePathNode
= (IPv4_DEVICE_PATH
*)AllocatePool(sizeof(IPv4_DEVICE_PATH
) + SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
825 // Create the IPv4 Device Path
826 IPv4DevicePathNode
->Header
.Type
= MESSAGING_DEVICE_PATH
;
827 IPv4DevicePathNode
->Header
.SubType
= MSG_IPv4_DP
;
828 SetDevicePathNodeLength (&IPv4DevicePathNode
->Header
, sizeof(IPv4_DEVICE_PATH
));
829 CopyMem (&IPv4DevicePathNode
->LocalIpAddress
, &LocalIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
830 CopyMem (&IPv4DevicePathNode
->RemoteIpAddress
, &RemoteIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
831 IPv4DevicePathNode
->LocalPort
= 0;
832 IPv4DevicePathNode
->RemotePort
= 0;
833 IPv4DevicePathNode
->Protocol
= EFI_IP_PROTO_TCP
;
834 IPv4DevicePathNode
->StaticIpAddress
= (IsDHCP
!= TRUE
);
836 // Create the FilePath Device Path node
837 FilePathDevicePath
= (FILEPATH_DEVICE_PATH
*)(IPv4DevicePathNode
+ 1);
838 FilePathDevicePath
->Header
.Type
= MEDIA_DEVICE_PATH
;
839 FilePathDevicePath
->Header
.SubType
= MEDIA_FILEPATH_DP
;
840 SetDevicePathNodeLength (FilePathDevicePath
, SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
841 CopyMem (FilePathDevicePath
->PathName
, BootFilePath
, BootFilePathSize
);
843 Status
= BootDeviceGetType (NULL
, BootType
, Attributes
);
844 if (EFI_ERROR(Status
)) {
845 FreePool (IPv4DevicePathNode
);
847 *DevicePathNode
= (EFI_DEVICE_PATH_PROTOCOL
*)IPv4DevicePathNode
;
854 BdsLoadOptionTftpUpdateDevicePath (
855 IN EFI_DEVICE_PATH
*OldDevicePath
,
856 OUT EFI_DEVICE_PATH_PROTOCOL
** NewDevicePath
,
857 OUT ARM_BDS_LOADER_TYPE
*BootType
,
858 OUT UINT32
*Attributes
866 BdsLoadOptionTftpIsSupported (
867 IN BDS_LOAD_OPTION
* BdsLoadOption
872 EFI_DEVICE_PATH
*RemainingDevicePath
;
873 EFI_DEVICE_PATH
*NextDevicePath
;
874 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBcProtocol
;
876 Status
= BdsConnectDevicePath (BdsLoadOption
->FilePathList
, &Handle
, &RemainingDevicePath
);
877 if (EFI_ERROR(Status
)) {
881 // Validate the Remaining Device Path
882 if (IsDevicePathEnd(RemainingDevicePath
)) {
885 if (!IS_DEVICE_PATH_NODE(RemainingDevicePath
,MESSAGING_DEVICE_PATH
,MSG_IPv4_DP
) &&
886 !IS_DEVICE_PATH_NODE(RemainingDevicePath
,MESSAGING_DEVICE_PATH
,MSG_IPv6_DP
)) {
889 NextDevicePath
= NextDevicePathNode (RemainingDevicePath
);
890 if (IsDevicePathEnd(NextDevicePath
)) {
893 if (!IS_DEVICE_PATH_NODE(NextDevicePath
,MEDIA_DEVICE_PATH
,MEDIA_FILEPATH_DP
)) {
897 Status
= gBS
->HandleProtocol (Handle
, &gEfiPxeBaseCodeProtocolGuid
, (VOID
**)&PxeBcProtocol
);
898 if (EFI_ERROR (Status
)) {