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 (
37 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
,
38 OUT ARM_BDS_LOADER_TYPE
*BootType
,
39 OUT UINT32
*Attributes
43 BdsLoadOptionFileSystemUpdateDevicePath (
44 IN EFI_DEVICE_PATH
*OldDevicePath
,
46 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
,
47 OUT ARM_BDS_LOADER_TYPE
*BootType
,
48 OUT UINT32
*Attributes
52 BdsLoadOptionFileSystemIsSupported (
53 IN EFI_DEVICE_PATH
*DevicePath
57 BdsLoadOptionMemMapList (
58 IN OUT LIST_ENTRY
* BdsLoadOptionList
62 BdsLoadOptionMemMapCreateDevicePath (
64 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
,
65 OUT ARM_BDS_LOADER_TYPE
*BootType
,
66 OUT UINT32
*Attributes
70 BdsLoadOptionMemMapUpdateDevicePath (
71 IN EFI_DEVICE_PATH
*OldDevicePath
,
73 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
,
74 OUT ARM_BDS_LOADER_TYPE
*BootType
,
75 OUT UINT32
*Attributes
79 BdsLoadOptionMemMapIsSupported (
80 IN EFI_DEVICE_PATH
*DevicePath
84 BdsLoadOptionPxeList (
85 IN OUT LIST_ENTRY
* BdsLoadOptionList
89 BdsLoadOptionPxeCreateDevicePath (
91 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
,
92 OUT ARM_BDS_LOADER_TYPE
*BootType
,
93 OUT UINT32
*Attributes
97 BdsLoadOptionPxeUpdateDevicePath (
98 IN EFI_DEVICE_PATH
*OldDevicePath
,
100 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
,
101 OUT ARM_BDS_LOADER_TYPE
*BootType
,
102 OUT UINT32
*Attributes
106 BdsLoadOptionPxeIsSupported (
107 IN EFI_DEVICE_PATH
*DevicePath
111 BdsLoadOptionTftpList (
112 IN OUT LIST_ENTRY
* BdsLoadOptionList
116 BdsLoadOptionTftpCreateDevicePath (
118 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
,
119 OUT ARM_BDS_LOADER_TYPE
*BootType
,
120 OUT UINT32
*Attributes
124 BdsLoadOptionTftpUpdateDevicePath (
125 IN EFI_DEVICE_PATH
*OldDevicePath
,
127 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
,
128 OUT ARM_BDS_LOADER_TYPE
*BootType
,
129 OUT UINT32
*Attributes
133 BdsLoadOptionTftpIsSupported (
134 IN EFI_DEVICE_PATH
*DevicePath
137 BDS_LOAD_OPTION_SUPPORT BdsLoadOptionSupportList
[] = {
139 BDS_DEVICE_FILESYSTEM
,
140 BdsLoadOptionFileSystemList
,
141 BdsLoadOptionFileSystemIsSupported
,
142 BdsLoadOptionFileSystemCreateDevicePath
,
143 BdsLoadOptionFileSystemUpdateDevicePath
147 BdsLoadOptionMemMapList
,
148 BdsLoadOptionMemMapIsSupported
,
149 BdsLoadOptionMemMapCreateDevicePath
,
150 BdsLoadOptionMemMapUpdateDevicePath
154 BdsLoadOptionPxeList
,
155 BdsLoadOptionPxeIsSupported
,
156 BdsLoadOptionPxeCreateDevicePath
,
157 BdsLoadOptionPxeUpdateDevicePath
161 BdsLoadOptionTftpList
,
162 BdsLoadOptionTftpIsSupported
,
163 BdsLoadOptionTftpCreateDevicePath
,
164 BdsLoadOptionTftpUpdateDevicePath
169 BootDeviceListSupportedInit (
170 IN OUT LIST_ENTRY
*SupportedDeviceList
175 // Initialize list of supported devices
176 InitializeListHead (SupportedDeviceList
);
178 for (Index
= 0; Index
< BDS_DEVICE_MAX
; Index
++) {
179 BdsLoadOptionSupportList
[Index
].ListDevices (SupportedDeviceList
);
186 BootDeviceListSupportedFree (
187 IN LIST_ENTRY
*SupportedDeviceList
,
188 IN BDS_SUPPORTED_DEVICE
*Except
192 BDS_SUPPORTED_DEVICE
* SupportedDevice
;
194 Entry
= GetFirstNode (SupportedDeviceList
);
195 while (Entry
!= SupportedDeviceList
) {
196 SupportedDevice
= SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry
);
197 Entry
= RemoveEntryList (Entry
);
198 if (SupportedDevice
!= Except
) {
199 FreePool (SupportedDevice
);
207 BootDeviceGetDeviceSupport (
208 IN EFI_DEVICE_PATH
*DevicePath
,
209 OUT BDS_LOAD_OPTION_SUPPORT
**DeviceSupport
214 // Find which supported device is the most appropriate
215 for (Index
= 0; Index
< BDS_DEVICE_MAX
; Index
++) {
216 if (BdsLoadOptionSupportList
[Index
].IsSupported (DevicePath
)) {
217 *DeviceSupport
= &BdsLoadOptionSupportList
[Index
];
222 return EFI_UNSUPPORTED
;
229 OUT ARM_BDS_LOADER_TYPE
*BootType
,
230 OUT UINT32
*Attributes
235 BOOLEAN IsBootLoader
;
236 BOOLEAN HasFDTSupport
;
238 if (FileName
== NULL
) {
239 Print(L
"Is an EFI Application? ");
240 Status
= GetHIInputBoolean (&IsEfiApp
);
241 if (EFI_ERROR(Status
)) {
244 } else if (HasFilePathEfiExtension(FileName
)) {
251 Print(L
"Is your application is an OS loader? ");
252 Status
= GetHIInputBoolean (&IsBootLoader
);
253 if (EFI_ERROR(Status
)) {
257 *Attributes
|= LOAD_OPTION_CATEGORY_APP
;
259 *BootType
= BDS_LOADER_EFI_APPLICATION
;
261 Print(L
"Has FDT support? ");
262 Status
= GetHIInputBoolean (&HasFDTSupport
);
263 if (EFI_ERROR(Status
)) {
267 *BootType
= BDS_LOADER_KERNEL_LINUX_FDT
;
269 *BootType
= BDS_LOADER_KERNEL_LINUX_ATAG
;
277 BdsLoadOptionFileSystemList (
278 IN OUT LIST_ENTRY
* BdsLoadOptionList
283 EFI_HANDLE
*HandleBuffer
;
285 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
286 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
* FileProtocol
;
289 EFI_FILE_SYSTEM_INFO
* FsInfo
;
290 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
292 // List all the Simple File System Protocols
293 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiSimpleFileSystemProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
294 if (EFI_ERROR (Status
)) {
298 for (Index
= 0; Index
< HandleCount
; Index
++) {
299 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
300 if (!EFI_ERROR(Status
)) {
301 // Allocate BDS Supported Device structure
302 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool (sizeof(BDS_SUPPORTED_DEVICE
));
305 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)&FileProtocol
);
306 ASSERT_EFI_ERROR(Status
);
308 FileProtocol
->OpenVolume (FileProtocol
, &Fs
);
310 // Generate a Description from the file system
313 Status
= Fs
->GetInfo (Fs
, &gEfiFileSystemInfoGuid
, &Size
, FsInfo
);
314 if (Status
== EFI_BUFFER_TOO_SMALL
) {
315 FsInfo
= AllocatePool (Size
);
316 Status
= Fs
->GetInfo (Fs
, &gEfiFileSystemInfoGuid
, &Size
, FsInfo
);
318 UnicodeSPrint (SupportedDevice
->Description
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"%s (%d MB)",FsInfo
->VolumeLabel
,(UINT32
)(FsInfo
->VolumeSize
/ (1024 * 1024)));
322 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
323 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_FILESYSTEM
];
325 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
333 BdsLoadOptionFileSystemCreateDevicePath (
335 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
,
336 OUT ARM_BDS_LOADER_TYPE
*BootType
,
337 OUT UINT32
*Attributes
341 FILEPATH_DEVICE_PATH
* FilePathDevicePath
;
342 CHAR16 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
];
343 UINTN BootFilePathSize
;
345 Print(L
"File path of the %s: ", FileName
);
346 Status
= GetHIInputStr (BootFilePath
, BOOT_DEVICE_FILEPATH_MAX
);
347 if (EFI_ERROR(Status
)) {
351 BootFilePathSize
= StrSize (BootFilePath
);
352 if (BootFilePathSize
== 2) {
353 *DevicePathNodes
= NULL
;
354 return EFI_NOT_FOUND
;
357 // Create the FilePath Device Path node
358 FilePathDevicePath
= (FILEPATH_DEVICE_PATH
*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
+ END_DEVICE_PATH_LENGTH
);
359 FilePathDevicePath
->Header
.Type
= MEDIA_DEVICE_PATH
;
360 FilePathDevicePath
->Header
.SubType
= MEDIA_FILEPATH_DP
;
361 SetDevicePathNodeLength (FilePathDevicePath
, SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
362 CopyMem (FilePathDevicePath
->PathName
, BootFilePath
, BootFilePathSize
);
363 SetDevicePathEndNode ((VOID
*)((UINTN
)FilePathDevicePath
+ SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
));
365 if (BootType
!= NULL
|| Attributes
!= NULL
) {
366 Status
= BootDeviceGetType (FilePathDevicePath
->PathName
, BootType
, Attributes
);
369 if (EFI_ERROR(Status
)) {
370 FreePool (FilePathDevicePath
);
372 *DevicePathNodes
= (EFI_DEVICE_PATH_PROTOCOL
*)FilePathDevicePath
;
379 BdsLoadOptionFileSystemUpdateDevicePath (
380 IN EFI_DEVICE_PATH
*OldDevicePath
,
382 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
,
383 OUT ARM_BDS_LOADER_TYPE
*BootType
,
384 OUT UINT32
*Attributes
388 CHAR16 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
];
389 UINTN BootFilePathSize
;
390 FILEPATH_DEVICE_PATH
* EndingDevicePath
;
391 FILEPATH_DEVICE_PATH
* FilePathDevicePath
;
392 EFI_DEVICE_PATH
* DevicePath
;
394 DevicePath
= DuplicateDevicePath (OldDevicePath
);
396 EndingDevicePath
= (FILEPATH_DEVICE_PATH
*)GetLastDevicePathNode (DevicePath
);
398 Print(L
"File path of the %s: ", FileName
);
399 StrnCpy (BootFilePath
, EndingDevicePath
->PathName
, BOOT_DEVICE_FILEPATH_MAX
);
400 Status
= EditHIInputStr (BootFilePath
, BOOT_DEVICE_FILEPATH_MAX
);
401 if (EFI_ERROR(Status
)) {
405 BootFilePathSize
= StrSize(BootFilePath
);
406 if (BootFilePathSize
== 2) {
407 *NewDevicePath
= NULL
;
408 return EFI_NOT_FOUND
;
411 // Create the FilePath Device Path node
412 FilePathDevicePath
= (FILEPATH_DEVICE_PATH
*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
413 FilePathDevicePath
->Header
.Type
= MEDIA_DEVICE_PATH
;
414 FilePathDevicePath
->Header
.SubType
= MEDIA_FILEPATH_DP
;
415 SetDevicePathNodeLength (FilePathDevicePath
, SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
416 CopyMem (FilePathDevicePath
->PathName
, BootFilePath
, BootFilePathSize
);
418 // Generate the new Device Path by replacing the last node by the updated node
419 SetDevicePathEndNode (EndingDevicePath
);
420 *NewDevicePath
= AppendDevicePathNode (DevicePath
, (CONST EFI_DEVICE_PATH_PROTOCOL
*)FilePathDevicePath
);
421 FreePool(DevicePath
);
423 if (BootType
!= NULL
|| Attributes
!= NULL
) {
424 return BootDeviceGetType (FilePathDevicePath
->PathName
, BootType
, Attributes
);
431 BdsLoadOptionFileSystemIsSupported (
432 IN EFI_DEVICE_PATH
*DevicePath
435 EFI_DEVICE_PATH
* DevicePathNode
;
437 DevicePathNode
= GetLastDevicePathNode (DevicePath
);
439 return IS_DEVICE_PATH_NODE(DevicePathNode
,MEDIA_DEVICE_PATH
,MEDIA_FILEPATH_DP
);
445 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
446 IN EFI_DEVICE_PATH_PROTOCOL
*ChildDevicePath
452 ParentSize
= GetDevicePathSize (ParentDevicePath
);
453 ChildSize
= GetDevicePathSize (ChildDevicePath
);
455 if (ParentSize
> ChildSize
) {
459 if (CompareMem (ParentDevicePath
, ChildDevicePath
, ParentSize
- END_DEVICE_PATH_LENGTH
) != 0) {
467 BdsLoadOptionMemMapList (
468 IN OUT LIST_ENTRY
* BdsLoadOptionList
473 EFI_HANDLE
*HandleBuffer
;
474 UINTN DevicePathHandleCount
;
475 EFI_HANDLE
*DevicePathHandleBuffer
;
479 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
480 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
481 EFI_DEVICE_PATH
* DevicePath
;
483 // List all the BlockIo Protocols
484 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiBlockIoProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
485 if (EFI_ERROR (Status
)) {
489 for (Index
= 0; Index
< HandleCount
; Index
++) {
490 // We only select the handle WITH a Device Path AND not part of Media (to avoid duplication with HardDisk, CDROM, etc)
491 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
492 if (!EFI_ERROR(Status
)) {
493 // BlockIo is not part of Media Device Path
494 DevicePath
= DevicePathProtocol
;
495 while (!IsDevicePathEndType (DevicePath
) && (DevicePathType (DevicePath
) != MEDIA_DEVICE_PATH
)) {
496 DevicePath
= NextDevicePathNode (DevicePath
);
498 if (DevicePathType (DevicePath
) == MEDIA_DEVICE_PATH
) {
502 // Open all the handle supporting the DevicePath protocol and verify this handle has not got any child
503 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiDevicePathProtocolGuid
, NULL
, &DevicePathHandleCount
, &DevicePathHandleBuffer
);
504 ASSERT_EFI_ERROR (Status
);
506 for (Index2
= 0; (Index2
< DevicePathHandleCount
) && !IsParent
; Index2
++) {
507 if (HandleBuffer
[Index
] != DevicePathHandleBuffer
[Index2
]) {
508 gBS
->HandleProtocol (DevicePathHandleBuffer
[Index2
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePath
);
509 if (IsParentDevicePath (DevicePathProtocol
, DevicePath
)) {
518 // Allocate BDS Supported Device structure
519 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE
));
521 Status
= GenerateDeviceDescriptionName (HandleBuffer
[Index
], SupportedDevice
->Description
);
522 ASSERT_EFI_ERROR (Status
);
524 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
525 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_MEMMAP
];
527 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
535 BdsLoadOptionMemMapCreateDevicePath (
537 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
,
538 OUT ARM_BDS_LOADER_TYPE
*BootType
,
539 OUT UINT32
*Attributes
543 MEMMAP_DEVICE_PATH
*MemMapDevicePath
;
544 CHAR16 StrStartingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
545 CHAR16 StrEndingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
547 Print(L
"Starting Address of the %s: ", FileName
);
548 Status
= GetHIInputStr (StrStartingAddress
, BOOT_DEVICE_ADDRESS_MAX
);
549 if (EFI_ERROR(Status
)) {
553 Print(L
"Ending Address of the %s: ", FileName
);
554 Status
= GetHIInputStr (StrEndingAddress
, BOOT_DEVICE_ADDRESS_MAX
);
555 if (EFI_ERROR(Status
)) {
559 // Create the MemMap Device Path Node
560 MemMapDevicePath
= (MEMMAP_DEVICE_PATH
*)AllocatePool (sizeof(MEMMAP_DEVICE_PATH
) + END_DEVICE_PATH_LENGTH
);
561 MemMapDevicePath
->Header
.Type
= HARDWARE_DEVICE_PATH
;
562 MemMapDevicePath
->Header
.SubType
= HW_MEMMAP_DP
;
563 SetDevicePathNodeLength (MemMapDevicePath
, sizeof(MEMMAP_DEVICE_PATH
));
564 MemMapDevicePath
->MemoryType
= EfiBootServicesData
;
565 MemMapDevicePath
->StartingAddress
= StrHexToUint64 (StrStartingAddress
);
566 MemMapDevicePath
->EndingAddress
= StrHexToUint64 (StrEndingAddress
);
568 // Set a Device Path End Node after the Memory Map Device Path Node
569 SetDevicePathEndNode (MemMapDevicePath
+ 1);
571 if (BootType
!= NULL
|| Attributes
!= NULL
) {
572 Status
= BootDeviceGetType (NULL
, BootType
, Attributes
);
575 if (EFI_ERROR(Status
)) {
576 FreePool (MemMapDevicePath
);
578 *DevicePathNodes
= (EFI_DEVICE_PATH_PROTOCOL
*)MemMapDevicePath
;
585 BdsLoadOptionMemMapUpdateDevicePath (
586 IN EFI_DEVICE_PATH
*OldDevicePath
,
588 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
,
589 OUT ARM_BDS_LOADER_TYPE
*BootType
,
590 OUT UINT32
*Attributes
594 CHAR16 StrStartingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
595 CHAR16 StrEndingAddress
[BOOT_DEVICE_ADDRESS_MAX
];
596 MEMMAP_DEVICE_PATH
* EndingDevicePath
;
597 EFI_DEVICE_PATH
* DevicePath
;
599 DevicePath
= DuplicateDevicePath (OldDevicePath
);
600 EndingDevicePath
= (MEMMAP_DEVICE_PATH
*)GetLastDevicePathNode (DevicePath
);
602 Print(L
"Starting Address of the %s: ", FileName
);
603 UnicodeSPrint (StrStartingAddress
, BOOT_DEVICE_ADDRESS_MAX
, L
"0x%X", (UINTN
)EndingDevicePath
->StartingAddress
);
604 Status
= EditHIInputStr (StrStartingAddress
, BOOT_DEVICE_ADDRESS_MAX
);
605 if (EFI_ERROR(Status
)) {
609 Print(L
"Ending Address of the %s: ", FileName
);
610 UnicodeSPrint (StrEndingAddress
, BOOT_DEVICE_ADDRESS_MAX
, L
"0x%X", (UINTN
)EndingDevicePath
->EndingAddress
);
611 Status
= EditHIInputStr (StrEndingAddress
, BOOT_DEVICE_ADDRESS_MAX
);
612 if (EFI_ERROR(Status
)) {
616 EndingDevicePath
->StartingAddress
= StrHexToUint64 (StrStartingAddress
);
617 EndingDevicePath
->EndingAddress
= StrHexToUint64 (StrEndingAddress
);
619 if (BootType
!= NULL
|| Attributes
!= NULL
) {
620 Status
= BootDeviceGetType (NULL
, BootType
, Attributes
);
623 if (EFI_ERROR(Status
)) {
624 FreePool(DevicePath
);
626 *NewDevicePath
= DevicePath
;
633 BdsLoadOptionMemMapIsSupported (
634 IN EFI_DEVICE_PATH
*DevicePath
637 EFI_DEVICE_PATH
* DevicePathNode
;
639 DevicePathNode
= GetLastDevicePathNode (DevicePath
);
641 return IS_DEVICE_PATH_NODE(DevicePathNode
,HARDWARE_DEVICE_PATH
,HW_MEMMAP_DP
);
645 BdsLoadOptionPxeList (
646 IN OUT LIST_ENTRY
* BdsLoadOptionList
651 EFI_HANDLE
*HandleBuffer
;
653 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
654 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
655 EFI_SIMPLE_NETWORK_PROTOCOL
* SimpleNet
;
656 CHAR16 DeviceDescription
[BOOT_DEVICE_DESCRIPTION_MAX
];
657 EFI_MAC_ADDRESS
*Mac
;
659 // List all the PXE Protocols
660 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiPxeBaseCodeProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
661 if (EFI_ERROR (Status
)) {
665 for (Index
= 0; Index
< HandleCount
; Index
++) {
666 // We only select the handle WITH a Device Path AND the PXE Protocol
667 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
668 if (!EFI_ERROR(Status
)) {
669 // Allocate BDS Supported Device structure
670 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE
));
672 Status
= gBS
->LocateProtocol (&gEfiSimpleNetworkProtocolGuid
, NULL
, (VOID
**)&SimpleNet
);
673 if (!EFI_ERROR(Status
)) {
674 Mac
= &SimpleNet
->Mode
->CurrentAddress
;
675 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]);
677 Status
= GenerateDeviceDescriptionName (HandleBuffer
[Index
], DeviceDescription
);
678 ASSERT_EFI_ERROR (Status
);
680 UnicodeSPrint (SupportedDevice
->Description
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"PXE on %s",DeviceDescription
);
682 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
683 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_PXE
];
685 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
693 BdsLoadOptionPxeCreateDevicePath (
695 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
,
696 OUT ARM_BDS_LOADER_TYPE
*BootType
,
697 OUT UINT32
*Attributes
700 *DevicePathNodes
= (EFI_DEVICE_PATH_PROTOCOL
*) AllocatePool (END_DEVICE_PATH_LENGTH
);
701 SetDevicePathEndNode (*DevicePathNodes
);
702 *BootType
= BDS_LOADER_EFI_APPLICATION
;
707 BdsLoadOptionPxeUpdateDevicePath (
708 IN EFI_DEVICE_PATH
*OldDevicePath
,
710 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
,
711 OUT ARM_BDS_LOADER_TYPE
*BootType
,
712 OUT UINT32
*Attributes
720 BdsLoadOptionPxeIsSupported (
721 IN EFI_DEVICE_PATH
*DevicePath
726 EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
;
727 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBcProtocol
;
729 Status
= BdsConnectDevicePath (DevicePath
, &Handle
, &RemainingDevicePath
);
730 if (EFI_ERROR(Status
)) {
734 if (!IsDevicePathEnd(RemainingDevicePath
)) {
738 Status
= gBS
->HandleProtocol (Handle
, &gEfiPxeBaseCodeProtocolGuid
, (VOID
**)&PxeBcProtocol
);
739 if (EFI_ERROR (Status
)) {
747 BdsLoadOptionTftpList (
748 IN OUT LIST_ENTRY
* BdsLoadOptionList
753 EFI_HANDLE
*HandleBuffer
;
755 BDS_SUPPORTED_DEVICE
*SupportedDevice
;
756 EFI_DEVICE_PATH_PROTOCOL
* DevicePathProtocol
;
757 EFI_SIMPLE_NETWORK_PROTOCOL
* SimpleNet
;
758 CHAR16 DeviceDescription
[BOOT_DEVICE_DESCRIPTION_MAX
];
759 EFI_MAC_ADDRESS
*Mac
;
761 // List all the PXE Protocols
762 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiPxeBaseCodeProtocolGuid
, NULL
, &HandleCount
, &HandleBuffer
);
763 if (EFI_ERROR (Status
)) {
767 for (Index
= 0; Index
< HandleCount
; Index
++) {
768 // 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)
769 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePathProtocol
);
770 if (!EFI_ERROR(Status
)) {
771 // Allocate BDS Supported Device structure
772 SupportedDevice
= (BDS_SUPPORTED_DEVICE
*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE
));
774 Status
= gBS
->LocateProtocol (&gEfiSimpleNetworkProtocolGuid
, NULL
, (VOID
**)&SimpleNet
);
775 if (!EFI_ERROR(Status
)) {
776 Mac
= &SimpleNet
->Mode
->CurrentAddress
;
777 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]);
779 Status
= GenerateDeviceDescriptionName (HandleBuffer
[Index
], DeviceDescription
);
780 ASSERT_EFI_ERROR (Status
);
782 UnicodeSPrint (SupportedDevice
->Description
,BOOT_DEVICE_DESCRIPTION_MAX
,L
"TFTP on %s",DeviceDescription
);
784 SupportedDevice
->DevicePathProtocol
= DevicePathProtocol
;
785 SupportedDevice
->Support
= &BdsLoadOptionSupportList
[BDS_DEVICE_TFTP
];
787 InsertTailList (BdsLoadOptionList
,&SupportedDevice
->Link
);
795 BdsLoadOptionTftpCreateDevicePath (
797 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePathNodes
,
798 OUT ARM_BDS_LOADER_TYPE
*BootType
,
799 OUT UINT32
*Attributes
804 EFI_IP_ADDRESS LocalIp
;
805 EFI_IP_ADDRESS RemoteIp
;
806 IPv4_DEVICE_PATH
* IPv4DevicePathNode
;
807 FILEPATH_DEVICE_PATH
* FilePathDevicePath
;
808 CHAR16 BootFilePath
[BOOT_DEVICE_FILEPATH_MAX
];
809 UINTN BootFilePathSize
;
811 Print(L
"Get the IP address from DHCP: ");
812 Status
= GetHIInputBoolean (&IsDHCP
);
813 if (EFI_ERROR(Status
)) {
818 Print(L
"Get the static IP address: ");
819 Status
= GetHIInputIP (&LocalIp
);
820 if (EFI_ERROR(Status
)) {
825 Print(L
"Get the TFTP server IP address: ");
826 Status
= GetHIInputIP (&RemoteIp
);
827 if (EFI_ERROR(Status
)) {
831 Print(L
"File path of the %s : ", FileName
);
832 Status
= GetHIInputStr (BootFilePath
, BOOT_DEVICE_FILEPATH_MAX
);
833 if (EFI_ERROR(Status
)) {
837 BootFilePathSize
= StrSize(BootFilePath
);
838 if (BootFilePathSize
== 2) {
839 return EFI_NOT_FOUND
;
842 // Allocate the memory for the IPv4 + File Path Device Path Nodes
843 IPv4DevicePathNode
= (IPv4_DEVICE_PATH
*)AllocatePool(sizeof(IPv4_DEVICE_PATH
) + SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
+ END_DEVICE_PATH_LENGTH
);
845 // Create the IPv4 Device Path
846 IPv4DevicePathNode
->Header
.Type
= MESSAGING_DEVICE_PATH
;
847 IPv4DevicePathNode
->Header
.SubType
= MSG_IPv4_DP
;
848 SetDevicePathNodeLength (&IPv4DevicePathNode
->Header
, sizeof(IPv4_DEVICE_PATH
));
849 CopyMem (&IPv4DevicePathNode
->LocalIpAddress
, &LocalIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
850 CopyMem (&IPv4DevicePathNode
->RemoteIpAddress
, &RemoteIp
.v4
, sizeof (EFI_IPv4_ADDRESS
));
851 IPv4DevicePathNode
->LocalPort
= 0;
852 IPv4DevicePathNode
->RemotePort
= 0;
853 IPv4DevicePathNode
->Protocol
= EFI_IP_PROTO_TCP
;
854 IPv4DevicePathNode
->StaticIpAddress
= (IsDHCP
!= TRUE
);
856 // Create the FilePath Device Path node
857 FilePathDevicePath
= (FILEPATH_DEVICE_PATH
*)(IPv4DevicePathNode
+ 1);
858 FilePathDevicePath
->Header
.Type
= MEDIA_DEVICE_PATH
;
859 FilePathDevicePath
->Header
.SubType
= MEDIA_FILEPATH_DP
;
860 SetDevicePathNodeLength (FilePathDevicePath
, SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
);
861 CopyMem (FilePathDevicePath
->PathName
, BootFilePath
, BootFilePathSize
);
863 // Set the End Device Path Node
864 SetDevicePathEndNode ((VOID
*)((UINTN
)FilePathDevicePath
+ SIZE_OF_FILEPATH_DEVICE_PATH
+ BootFilePathSize
));
866 if (BootType
!= NULL
|| Attributes
!= NULL
) {
867 Status
= BootDeviceGetType (NULL
, BootType
, Attributes
);
870 if (EFI_ERROR(Status
)) {
871 FreePool (IPv4DevicePathNode
);
873 *DevicePathNodes
= (EFI_DEVICE_PATH_PROTOCOL
*)IPv4DevicePathNode
;
880 BdsLoadOptionTftpUpdateDevicePath (
881 IN EFI_DEVICE_PATH
*OldDevicePath
,
883 OUT EFI_DEVICE_PATH_PROTOCOL
**NewDevicePath
,
884 OUT ARM_BDS_LOADER_TYPE
*BootType
,
885 OUT UINT32
*Attributes
893 BdsLoadOptionTftpIsSupported (
894 IN EFI_DEVICE_PATH
*DevicePath
899 EFI_DEVICE_PATH
*RemainingDevicePath
;
900 EFI_DEVICE_PATH
*NextDevicePath
;
901 EFI_PXE_BASE_CODE_PROTOCOL
*PxeBcProtocol
;
903 Status
= BdsConnectDevicePath (DevicePath
, &Handle
, &RemainingDevicePath
);
904 if (EFI_ERROR(Status
)) {
908 // Validate the Remaining Device Path
909 if (IsDevicePathEnd(RemainingDevicePath
)) {
912 if (!IS_DEVICE_PATH_NODE(RemainingDevicePath
,MESSAGING_DEVICE_PATH
,MSG_IPv4_DP
) &&
913 !IS_DEVICE_PATH_NODE(RemainingDevicePath
,MESSAGING_DEVICE_PATH
,MSG_IPv6_DP
)) {
916 NextDevicePath
= NextDevicePathNode (RemainingDevicePath
);
917 if (IsDevicePathEnd(NextDevicePath
)) {
920 if (!IS_DEVICE_PATH_NODE(NextDevicePath
,MEDIA_DEVICE_PATH
,MEDIA_FILEPATH_DP
)) {
924 Status
= gBS
->HandleProtocol (Handle
, &gEfiPxeBaseCodeProtocolGuid
, (VOID
**)&PxeBcProtocol
);
925 if (EFI_ERROR (Status
)) {