summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Martin <olivier.martin@arm.com>2014-05-19 16:41:25 +0000
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2014-05-19 16:41:25 +0000
commitd8f36fb56834e26a03e8993ca76d2f3870dd0b39 (patch)
tree8104343338398f7bf079a432b5caebfef3cfeb2e
parent6b5f577faf259dcb0955eb2263d34e7ebe773ff8 (diff)
ArmPkg/BdsLib: Added support for TFTP servers without 'tsize' extension
Some TFTP servers do not have 'tsize' extension. This change allows to download files from TFTP servers that do not have this extension by trying to download the file into a pre-allocated buffer. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15539 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--ArmPkg/ArmPkg.dec2
-rw-r--r--ArmPkg/Library/BdsLib/BdsFilePath.c98
-rw-r--r--ArmPkg/Library/BdsLib/BdsLib.inf4
3 files changed, 75 insertions, 29 deletions
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index 5efef7c9d..14f16b851 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -133,6 +133,8 @@
gArmTokenSpaceGuid.PcdArmMachineType|0|UINT32|0x0000001E
# The compressed Linux kernel is expected to be under 128MB from the beginning of the System Memory
gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset|0x08000000|UINT32|0x0000001F
+ # Maximum file size for TFTP servers that do not support 'tsize' extension
+ gArmTokenSpaceGuid.PcdMaxTftpFileSize|0x01000000|UINT32|0x00000000
#
# ARM Architectural Timer
diff --git a/ArmPkg/Library/BdsLib/BdsFilePath.c b/ArmPkg/Library/BdsLib/BdsFilePath.c
index 90be9c1e1..f3fa44565 100644
--- a/ArmPkg/Library/BdsLib/BdsFilePath.c
+++ b/ArmPkg/Library/BdsLib/BdsFilePath.c
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
@@ -817,6 +817,7 @@ BdsTftpLoadImage (
}
UnicodeStrToAsciiStr (FilePathDevicePath->PathName, AsciiPathName);
+ // Try to get the size (required the TFTP server to have "tsize" extension)
Status = Pxe->Mtftp (
Pxe,
EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
@@ -829,41 +830,82 @@ BdsTftpLoadImage (
NULL,
FALSE
);
- if (EFI_ERROR(Status)) {
+ // Pxe.Mtftp replies EFI_PROTOCOL_ERROR if tsize is not supported by the TFTP server
+ if (EFI_ERROR (Status) && (Status != EFI_PROTOCOL_ERROR)) {
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.
- Status = gBS->AllocatePages (
- Type,
- EfiBootServicesCode,
- EFI_SIZE_TO_PAGES (TftpBufferSize),
- Image
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Failed to allocate space for kernel image: %r\n", Status));
- goto EXIT;
- }
+ //
+ // Two cases:
+ // 1) the file size is unknown (tsize extension not supported)
+ // 2) tsize returned the file size
+ //
+ if (Status == EFI_PROTOCOL_ERROR) {
+ for (TftpBufferSize = SIZE_8MB; TftpBufferSize <= FixedPcdGet32 (PcdMaxTftpFileSize); TftpBufferSize += SIZE_8MB) {
+ // Allocate a buffer to hold the whole file.
+ Status = gBS->AllocatePages (
+ Type,
+ EfiBootServicesCode,
+ EFI_SIZE_TO_PAGES (TftpBufferSize),
+ Image
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate space for image: %r\n", Status));
+ goto EXIT;
+ }
- Status = Pxe->Mtftp (
- Pxe,
- EFI_PXE_BASE_CODE_TFTP_READ_FILE,
- (VOID *)(UINTN)*Image,
- FALSE,
- &TftpBufferSize,
- NULL,
- &ServerIp,
- (UINT8*)AsciiPathName,
- NULL,
- FALSE
- );
- if (EFI_ERROR (Status)) {
- gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));
+ Status = Pxe->Mtftp (
+ Pxe,
+ EFI_PXE_BASE_CODE_TFTP_READ_FILE,
+ (VOID *)(UINTN)*Image,
+ FALSE,
+ &TftpBufferSize,
+ NULL,
+ &ServerIp,
+ (UINT8*)AsciiPathName,
+ NULL,
+ FALSE
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));
+ } else {
+ *ImageSize = (UINTN)TftpBufferSize;
+ break;
+ }
+ }
} else {
- *ImageSize = (UINTN)TftpBufferSize;
+ // Allocate a buffer to hold the whole file.
+ Status = gBS->AllocatePages (
+ Type,
+ EfiBootServicesCode,
+ EFI_SIZE_TO_PAGES (TftpBufferSize),
+ Image
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate space for kernel image: %r\n", Status));
+ goto EXIT;
+ }
+
+ Status = Pxe->Mtftp (
+ Pxe,
+ EFI_PXE_BASE_CODE_TFTP_READ_FILE,
+ (VOID *)(UINTN)*Image,
+ FALSE,
+ &TftpBufferSize,
+ NULL,
+ &ServerIp,
+ (UINT8*)AsciiPathName,
+ NULL,
+ FALSE
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));
+ } else {
+ *ImageSize = (UINTN)TftpBufferSize;
+ }
}
EXIT:
diff --git a/ArmPkg/Library/BdsLib/BdsLib.inf b/ArmPkg/Library/BdsLib/BdsLib.inf
index 30746f69a..6158fba59 100644
--- a/ArmPkg/Library/BdsLib/BdsLib.inf
+++ b/ArmPkg/Library/BdsLib/BdsLib.inf
@@ -1,6 +1,6 @@
#/* @file
#
-# Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+# Copyright (c) 2011-2014, ARM Limited. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -86,6 +86,8 @@
gArmTokenSpaceGuid.PcdArmLinuxFdtAlignment
gArmTokenSpaceGuid.PcdArmLinuxKernelMaxOffset
+ gArmTokenSpaceGuid.PcdMaxTftpFileSize
+
[FixedPcd.ARM]
gArmTokenSpaceGuid.PcdArmLinuxAtagMaxOffset