From 061568e2d5f21aeafa942891b15768c57fa0ffac Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 12 Dec 2014 19:14:22 +0000 Subject: 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 Reviewed-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16516 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPlatformPkg/Bds/BootOptionSupport.c | 195 ++++++++++++++++++++++++--------- 1 file changed, 146 insertions(+), 49 deletions(-) (limited to 'ArmPlatformPkg/Bds/BootOptionSupport.c') 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 #include #include +#include +#include #include @@ -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)); -- cgit v1.2.3