mirror of https://github.com/acidanthera/audk.git
ArmPkg/BdsLib: Fixed TFTP and PXE Boot
- An Ascii filename must be passed to the TFTP service (was a Unicode filename) - If the PXE service had already configured the connection we need to restart when we want to download a new file or do a do a PXE Boot. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14195 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
ecc62d1390
commit
2edb5ad38c
|
@ -17,6 +17,7 @@
|
||||||
#include <Protocol/UsbIo.h>
|
#include <Protocol/UsbIo.h>
|
||||||
#include <Protocol/DiskIo.h>
|
#include <Protocol/DiskIo.h>
|
||||||
#include <Protocol/LoadedImage.h>
|
#include <Protocol/LoadedImage.h>
|
||||||
|
#include <Protocol/SimpleNetwork.h>
|
||||||
|
|
||||||
#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))
|
#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))
|
||||||
|
|
||||||
|
@ -661,6 +662,7 @@ BdsPxeLoadImage (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_LOAD_FILE_PROTOCOL *LoadFileProtocol;
|
EFI_LOAD_FILE_PROTOCOL *LoadFileProtocol;
|
||||||
UINTN BufferSize;
|
UINTN BufferSize;
|
||||||
|
EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
|
||||||
|
|
||||||
// Get Load File Protocol attached to the PXE protocol
|
// Get Load File Protocol attached to the PXE protocol
|
||||||
Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID **)&LoadFileProtocol);
|
Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID **)&LoadFileProtocol);
|
||||||
|
@ -681,6 +683,15 @@ BdsPxeLoadImage (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Status == EFI_ALREADY_STARTED) {
|
||||||
|
Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);
|
||||||
|
if (!EFI_ERROR(Status)) {
|
||||||
|
// If PXE is already started, we stop it
|
||||||
|
Pxe->Stop (Pxe);
|
||||||
|
// And we try again
|
||||||
|
return BdsPxeLoadImage (DevicePath, Handle, RemainingDevicePath, Type, Image, ImageSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,6 +748,8 @@ BdsTftpLoadImage (
|
||||||
IPv4_DEVICE_PATH* IPv4DevicePathNode;
|
IPv4_DEVICE_PATH* IPv4DevicePathNode;
|
||||||
FILEPATH_DEVICE_PATH* FilePathDevicePath;
|
FILEPATH_DEVICE_PATH* FilePathDevicePath;
|
||||||
EFI_IP_ADDRESS LocalIp;
|
EFI_IP_ADDRESS LocalIp;
|
||||||
|
CHAR8* AsciiPathName;
|
||||||
|
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||||
|
|
||||||
ASSERT(IS_DEVICE_PATH_NODE (RemainingDevicePath, MESSAGING_DEVICE_PATH, MSG_IPv4_DP));
|
ASSERT(IS_DEVICE_PATH_NODE (RemainingDevicePath, MESSAGING_DEVICE_PATH, MSG_IPv4_DP));
|
||||||
|
|
||||||
|
@ -753,18 +766,45 @@ BdsTftpLoadImage (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IPv4DevicePathNode->StaticIpAddress) {
|
do {
|
||||||
Status = Pxe->Dhcp(Pxe, TRUE);
|
if (!IPv4DevicePathNode->StaticIpAddress) {
|
||||||
} else {
|
Status = Pxe->Dhcp (Pxe, TRUE);
|
||||||
CopyMem (&LocalIp.v4, &IPv4DevicePathNode->LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
|
} else {
|
||||||
Status = Pxe->SetStationIp (Pxe, &LocalIp, NULL);
|
CopyMem (&LocalIp.v4, &IPv4DevicePathNode->LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||||
}
|
Status = Pxe->SetStationIp (Pxe, &LocalIp, NULL);
|
||||||
if (EFI_ERROR (Status)) {
|
}
|
||||||
|
|
||||||
|
// If an IP Address has already been set and a different static IP address is requested then restart
|
||||||
|
// the Network service.
|
||||||
|
if (Status == EFI_ALREADY_STARTED) {
|
||||||
|
Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&Snp);
|
||||||
|
if (!EFI_ERROR (Status) && IPv4DevicePathNode->StaticIpAddress &&
|
||||||
|
(CompareMem (&Snp->Mode->CurrentAddress, &IPv4DevicePathNode->LocalIpAddress, sizeof(EFI_MAC_ADDRESS)) != 0))
|
||||||
|
{
|
||||||
|
Pxe->Stop (Pxe);
|
||||||
|
Status = Pxe->Start (Pxe, FALSE);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// After restarting the PXE protocol, we want to try again with our new IP Address
|
||||||
|
Status = EFI_ALREADY_STARTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (Status == EFI_ALREADY_STARTED);
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyMem (&ServerIp.v4, &IPv4DevicePathNode->RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS));
|
CopyMem (&ServerIp.v4, &IPv4DevicePathNode->RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
|
||||||
|
// Convert the Unicode PathName to Ascii
|
||||||
|
AsciiPathName = AllocatePool ((StrLen (FilePathDevicePath->PathName) + 1) * sizeof (CHAR8));
|
||||||
|
if (AsciiPathName == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
UnicodeStrToAsciiStr (FilePathDevicePath->PathName, AsciiPathName);
|
||||||
|
|
||||||
Status = Pxe->Mtftp (
|
Status = Pxe->Mtftp (
|
||||||
Pxe,
|
Pxe,
|
||||||
EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
|
EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
|
||||||
|
@ -773,18 +813,22 @@ BdsTftpLoadImage (
|
||||||
&TftpBufferSize,
|
&TftpBufferSize,
|
||||||
NULL,
|
NULL,
|
||||||
&ServerIp,
|
&ServerIp,
|
||||||
(UINT8 *)FilePathDevicePath->PathName,
|
(UINT8*)AsciiPathName,
|
||||||
NULL,
|
NULL,
|
||||||
TRUE
|
FALSE
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
return Status;
|
if (Status == EFI_TFTP_ERROR) {
|
||||||
|
DEBUG((EFI_D_ERROR, "TFTP Error: Fail to get the size of the file\n"));
|
||||||
|
}
|
||||||
|
goto EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a buffer to hold the whole file.
|
// Allocate a buffer to hold the whole file.
|
||||||
TftpBuffer = AllocatePool (TftpBufferSize);
|
TftpBuffer = AllocatePool (TftpBufferSize);
|
||||||
if (TftpBuffer == NULL) {
|
if (TftpBuffer == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = Pxe->Mtftp (
|
Status = Pxe->Mtftp (
|
||||||
|
@ -795,16 +839,19 @@ BdsTftpLoadImage (
|
||||||
&TftpBufferSize,
|
&TftpBufferSize,
|
||||||
NULL,
|
NULL,
|
||||||
&ServerIp,
|
&ServerIp,
|
||||||
(UINT8 *)FilePathDevicePath->PathName,
|
(UINT8*)AsciiPathName,
|
||||||
NULL,
|
NULL,
|
||||||
FALSE
|
FALSE
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
FreePool (TftpBuffer);
|
FreePool (TftpBuffer);
|
||||||
} else if (ImageSize != NULL) {
|
} else if (ImageSize != NULL) {
|
||||||
|
*Image = (UINTN)TftpBuffer;
|
||||||
*ImageSize = (UINTN)TftpBufferSize;
|
*ImageSize = (UINTN)TftpBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXIT:
|
||||||
|
FreePool (AsciiPathName);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
gEfiDiskIoProtocolGuid
|
gEfiDiskIoProtocolGuid
|
||||||
gEfiUsbIoProtocolGuid
|
gEfiUsbIoProtocolGuid
|
||||||
gEfiLoadedImageProtocolGuid
|
gEfiLoadedImageProtocolGuid
|
||||||
|
gEfiSimpleNetworkProtocolGuid
|
||||||
|
|
||||||
[FeaturePcd]
|
[FeaturePcd]
|
||||||
gArmTokenSpaceGuid.PcdArmPsciSupport
|
gArmTokenSpaceGuid.PcdArmPsciSupport
|
||||||
|
|
Loading…
Reference in New Issue