summaryrefslogtreecommitdiff
path: root/ArmPkg/Library/BdsLib/BdsFilePath.c
diff options
context:
space:
mode:
authoroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2013-03-12 01:04:10 +0000
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2013-03-12 01:04:10 +0000
commit2edb5ad38c9db213cc609ed55574504154fd2f52 (patch)
treeb5d54349f4b765170a8c101e5bf086ddc8a0ecca /ArmPkg/Library/BdsLib/BdsFilePath.c
parentecc62d1390402ea99a807679372c955286e295e0 (diff)
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
Diffstat (limited to 'ArmPkg/Library/BdsLib/BdsFilePath.c')
-rw-r--r--ArmPkg/Library/BdsLib/BdsFilePath.c73
1 files changed, 60 insertions, 13 deletions
diff --git a/ArmPkg/Library/BdsLib/BdsFilePath.c b/ArmPkg/Library/BdsLib/BdsFilePath.c
index 2f8788ad1f..25f92725f5 100644
--- a/ArmPkg/Library/BdsLib/BdsFilePath.c
+++ b/ArmPkg/Library/BdsLib/BdsFilePath.c
@@ -17,6 +17,7 @@
#include <Protocol/UsbIo.h>
#include <Protocol/DiskIo.h>
#include <Protocol/LoadedImage.h>
+#include <Protocol/SimpleNetwork.h>
#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))
@@ -661,6 +662,7 @@ BdsPxeLoadImage (
EFI_STATUS Status;
EFI_LOAD_FILE_PROTOCOL *LoadFileProtocol;
UINTN BufferSize;
+ EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
// Get Load File Protocol attached to the PXE protocol
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;
}
@@ -737,6 +748,8 @@ BdsTftpLoadImage (
IPv4_DEVICE_PATH* IPv4DevicePathNode;
FILEPATH_DEVICE_PATH* FilePathDevicePath;
EFI_IP_ADDRESS LocalIp;
+ CHAR8* AsciiPathName;
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
ASSERT(IS_DEVICE_PATH_NODE (RemainingDevicePath, MESSAGING_DEVICE_PATH, MSG_IPv4_DP));
@@ -753,18 +766,45 @@ BdsTftpLoadImage (
return Status;
}
- if (!IPv4DevicePathNode->StaticIpAddress) {
- Status = Pxe->Dhcp(Pxe, TRUE);
- } else {
- CopyMem (&LocalIp.v4, &IPv4DevicePathNode->LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
- Status = Pxe->SetStationIp (Pxe, &LocalIp, NULL);
- }
- if (EFI_ERROR (Status)) {
+ do {
+ if (!IPv4DevicePathNode->StaticIpAddress) {
+ Status = Pxe->Dhcp (Pxe, TRUE);
+ } else {
+ CopyMem (&LocalIp.v4, &IPv4DevicePathNode->LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
+ Status = Pxe->SetStationIp (Pxe, &LocalIp, NULL);
+ }
+
+ // 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;
}
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 (
Pxe,
EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
@@ -773,18 +813,22 @@ BdsTftpLoadImage (
&TftpBufferSize,
NULL,
&ServerIp,
- (UINT8 *)FilePathDevicePath->PathName,
+ (UINT8*)AsciiPathName,
NULL,
- TRUE
+ FALSE
);
- if (EFI_ERROR (Status)) {
- return Status;
+ if (EFI_ERROR(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.
TftpBuffer = AllocatePool (TftpBufferSize);
if (TftpBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
}
Status = Pxe->Mtftp (
@@ -795,16 +839,19 @@ BdsTftpLoadImage (
&TftpBufferSize,
NULL,
&ServerIp,
- (UINT8 *)FilePathDevicePath->PathName,
+ (UINT8*)AsciiPathName,
NULL,
FALSE
);
if (EFI_ERROR (Status)) {
FreePool (TftpBuffer);
} else if (ImageSize != NULL) {
+ *Image = (UINTN)TftpBuffer;
*ImageSize = (UINTN)TftpBufferSize;
}
+EXIT:
+ FreePool (AsciiPathName);
return Status;
}