summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg/Bds/BootOptionSupport.c
diff options
context:
space:
mode:
authorRonald Cron <Ronald.Cron@arm.com>2014-12-12 19:14:22 +0000
committeroliviermartin <oliviermartin@Edk2>2014-12-12 19:14:22 +0000
commit061568e2d5f21aeafa942891b15768c57fa0ffac (patch)
treeffb6d8a8ee32c491b1b8f7bd086abe1d5280ad3f /ArmPlatformPkg/Bds/BootOptionSupport.c
parentb4c222655c8182febba890019367609ac278b1ba (diff)
downloadedk2-platforms-061568e2d5f21aeafa942891b15768c57fa0ffac.tar.xz
ArmPkg/BdsLib: Rework TFTP boot
Rework the downloading of an image from a TFTP server to do not depend on any "PXE specific" setting of the DHCP server. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ronald Cron <Ronald.Cron@arm.com> Reviewed-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16516 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPlatformPkg/Bds/BootOptionSupport.c')
-rw-r--r--ArmPlatformPkg/Bds/BootOptionSupport.c195
1 files changed, 146 insertions, 49 deletions
diff --git a/ArmPlatformPkg/Bds/BootOptionSupport.c b/ArmPlatformPkg/Bds/BootOptionSupport.c
index ee4281855e..974f220553 100644
--- a/ArmPlatformPkg/Bds/BootOptionSupport.c
+++ b/ArmPlatformPkg/Bds/BootOptionSupport.c
@@ -22,6 +22,8 @@
#include <Protocol/PxeBaseCode.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/SimpleNetwork.h>
+#include <Protocol/Dhcp4.h>
+#include <Protocol/Mtftp4.h>
#include <Guid/FileSystemInfo.h>
@@ -866,49 +868,96 @@ BdsLoadOptionPxeIsSupported (
}
}
+/**
+ Add to the list of boot devices the devices allowing a TFTP boot
+
+ @param[in] BdsLoadOptionList List of devices to boot from
+
+ @retval EFI_SUCCESS Update completed
+ @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource
+**/
EFI_STATUS
BdsLoadOptionTftpList (
IN OUT LIST_ENTRY* BdsLoadOptionList
)
{
- EFI_STATUS Status;
- UINTN HandleCount;
- EFI_HANDLE *HandleBuffer;
- UINTN Index;
- BDS_SUPPORTED_DEVICE *SupportedDevice;
- EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;
- EFI_SIMPLE_NETWORK_PROTOCOL* SimpleNet;
- CHAR16 DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX];
- EFI_MAC_ADDRESS *Mac;
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ EFI_HANDLE Handle;
+ UINTN Index;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol;
+ VOID *Interface;
+ EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetworkProtocol;
+ BDS_SUPPORTED_DEVICE *SupportedDevice;
+ EFI_MAC_ADDRESS *Mac;
- // List all the PXE Protocols
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer);
+ //
+ // List all the handles on which the Simple Network Protocol is installed.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSimpleNetworkProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
if (EFI_ERROR (Status)) {
return Status;
}
for (Index = 0; Index < HandleCount; Index++) {
- // 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)
- Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
- if (!EFI_ERROR(Status)) {
- // Allocate BDS Supported Device structure
- SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));
+ Handle = HandleBuffer[Index];
+ //
+ // We select the handles that support :
+ // . the Device Path Protocol
+ // . the MTFTP4 Protocol
+ //
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&DevicePathProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
- Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);
- if (!EFI_ERROR(Status)) {
- Mac = &SimpleNet->Mode->CurrentAddress;
- 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]);
- } else {
- Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription);
- ASSERT_EFI_ERROR (Status);
- }
- UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"TFTP on %s",DeviceDescription);
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiMtftp4ServiceBindingProtocolGuid,
+ &Interface
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
- SupportedDevice->DevicePathProtocol = DevicePathProtocol;
- SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP];
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiSimpleNetworkProtocolGuid,
+ (VOID **)&SimpleNetworkProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
- InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);
+ // Allocate BDS Supported Device structure
+ SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof (BDS_SUPPORTED_DEVICE));
+ if (SupportedDevice == NULL) {
+ continue;
}
+
+ Mac = &SimpleNetworkProtocol->Mode->CurrentAddress;
+ UnicodeSPrint (
+ SupportedDevice->Description,
+ BOOT_DEVICE_DESCRIPTION_MAX,
+ L"TFTP on 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]
+ );
+
+ SupportedDevice->DevicePathProtocol = DevicePathProtocol;
+ SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP];
+
+ InsertTailList (BdsLoadOptionList, &SupportedDevice->Link);
}
return EFI_SUCCESS;
@@ -920,38 +969,50 @@ BdsLoadOptionTftpCreateDevicePath (
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes
)
{
- EFI_STATUS Status;
- BOOLEAN IsDHCP;
- EFI_IP_ADDRESS LocalIp;
- EFI_IP_ADDRESS RemoteIp;
- IPv4_DEVICE_PATH* IPv4DevicePathNode;
- FILEPATH_DEVICE_PATH* FilePathDevicePath;
- CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];
- UINTN BootFilePathSize;
+ EFI_STATUS Status;
+ BOOLEAN IsDHCP;
+ EFI_IP_ADDRESS LocalIp;
+ EFI_IP_ADDRESS SubnetMask;
+ EFI_IP_ADDRESS GatewayIp;
+ EFI_IP_ADDRESS RemoteIp;
+ IPv4_DEVICE_PATH *IPv4DevicePathNode;
+ FILEPATH_DEVICE_PATH *FilePathDevicePath;
+ CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];
+ UINTN BootFilePathSize;
- Print(L"Get the IP address from DHCP: ");
+ Print (L"Get the IP address from DHCP: ");
Status = GetHIInputBoolean (&IsDHCP);
- if (EFI_ERROR(Status)) {
+ if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
if (!IsDHCP) {
- Print(L"Get the static IP address: ");
+ Print (L"Local static IP address: ");
Status = GetHIInputIP (&LocalIp);
- if (EFI_ERROR(Status)) {
+ if (EFI_ERROR (Status)) {
+ return EFI_ABORTED;
+ }
+ Print (L"Get the network mask: ");
+ Status = GetHIInputIP (&SubnetMask);
+ if (EFI_ERROR (Status)) {
+ return EFI_ABORTED;
+ }
+ Print (L"Get the gateway IP address: ");
+ Status = GetHIInputIP (&GatewayIp);
+ if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
}
- Print(L"Get the TFTP server IP address: ");
+ Print (L"Get the TFTP server IP address: ");
Status = GetHIInputIP (&RemoteIp);
- if (EFI_ERROR(Status)) {
+ if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
- Print(L"File path of the %s : ", FileName);
+ Print (L"File path of the %s : ", FileName);
Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);
- if (EFI_ERROR(Status)) {
+ if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
@@ -967,7 +1028,13 @@ BdsLoadOptionTftpCreateDevicePath (
IPv4DevicePathNode->Header.Type = MESSAGING_DEVICE_PATH;
IPv4DevicePathNode->Header.SubType = MSG_IPv4_DP;
SetDevicePathNodeLength (&IPv4DevicePathNode->Header, sizeof(IPv4_DEVICE_PATH));
- CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));
+
+ if (!IsDHCP) {
+ CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&IPv4DevicePathNode->SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&IPv4DevicePathNode->GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));
+ }
+
CopyMem (&IPv4DevicePathNode->RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));
IPv4DevicePathNode->LocalPort = 0;
IPv4DevicePathNode->RemotePort = 0;
@@ -1021,7 +1088,11 @@ BdsLoadOptionTftpUpdateDevicePath (
IPv4_DEVICE_PATH Ipv4Node;
BOOLEAN IsDHCP;
EFI_IP_ADDRESS OldIp;
+ EFI_IP_ADDRESS OldSubnetMask;
+ EFI_IP_ADDRESS OldGatewayIp;
EFI_IP_ADDRESS LocalIp;
+ EFI_IP_ADDRESS SubnetMask;
+ EFI_IP_ADDRESS GatewayIp;
EFI_IP_ADDRESS RemoteIp;
UINT8 *FileNodePtr;
CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];
@@ -1074,9 +1145,7 @@ BdsLoadOptionTftpUpdateDevicePath (
if (!IsDHCP) {
Print (L"Local static IP address: ");
if (Ipv4Node.StaticIpAddress) {
- // Copy local IPv4 address into IPv4 or IPv6 union
CopyMem (&OldIp.v4, &Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
-
Status = EditHIInputIP (&OldIp, &LocalIp);
} else {
Status = GetHIInputIP (&LocalIp);
@@ -1084,6 +1153,28 @@ BdsLoadOptionTftpUpdateDevicePath (
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
+
+ Print (L"Get the network mask: ");
+ if (Ipv4Node.StaticIpAddress) {
+ CopyMem (&OldSubnetMask.v4, &Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
+ Status = EditHIInputIP (&OldSubnetMask, &SubnetMask);
+ } else {
+ Status = GetHIInputIP (&SubnetMask);
+ }
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
+ Print (L"Get the gateway IP address: ");
+ if (Ipv4Node.StaticIpAddress) {
+ CopyMem (&OldGatewayIp.v4, &Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));
+ Status = EditHIInputIP (&OldGatewayIp, &GatewayIp);
+ } else {
+ Status = GetHIInputIP (&GatewayIp);
+ }
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
}
Print (L"TFTP server IP address: ");
@@ -1126,12 +1217,18 @@ BdsLoadOptionTftpUpdateDevicePath (
//
// Update the IPv4 node. IPv6 case not handled yet.
//
- if (IsDHCP == TRUE) {
+ if (IsDHCP) {
Ipv4Node.StaticIpAddress = FALSE;
+ ZeroMem (&Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
+ ZeroMem (&Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
+ ZeroMem (&Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));
} else {
Ipv4Node.StaticIpAddress = TRUE;
+ CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Ipv4Node.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Ipv4Node.GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));
}
- CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));
+
CopyMem (&Ipv4Node.RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));
CopyMem (Ipv4NodePtr, &Ipv4Node, sizeof (IPv4_DEVICE_PATH));