/** @file\r
*\r
-* Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
+* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
* \r
* This program and the accompanying materials \r
* are licensed and made available under the terms and conditions of the BSD License \r
}\r
UnicodeStrToAsciiStr (FilePathDevicePath->PathName, AsciiPathName);\r
\r
+ // Try to get the size (required the TFTP server to have "tsize" extension)\r
Status = Pxe->Mtftp (\r
Pxe,\r
EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,\r
NULL,\r
FALSE\r
);\r
- if (EFI_ERROR(Status)) {\r
+ // Pxe.Mtftp replies EFI_PROTOCOL_ERROR if tsize is not supported by the TFTP server\r
+ if (EFI_ERROR (Status) && (Status != EFI_PROTOCOL_ERROR)) {\r
if (Status == EFI_TFTP_ERROR) {\r
DEBUG((EFI_D_ERROR, "TFTP Error: Fail to get the size of the file\n"));\r
}\r
goto EXIT;\r
}\r
\r
- // Allocate a buffer to hold the whole file.\r
- Status = gBS->AllocatePages (\r
- Type,\r
- EfiBootServicesCode,\r
- EFI_SIZE_TO_PAGES (TftpBufferSize),\r
- Image\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Failed to allocate space for kernel image: %r\n", Status));\r
- goto EXIT;\r
- }\r
+ //\r
+ // Two cases:\r
+ // 1) the file size is unknown (tsize extension not supported)\r
+ // 2) tsize returned the file size\r
+ //\r
+ if (Status == EFI_PROTOCOL_ERROR) {\r
+ for (TftpBufferSize = SIZE_8MB; TftpBufferSize <= FixedPcdGet32 (PcdMaxTftpFileSize); TftpBufferSize += SIZE_8MB) {\r
+ // Allocate a buffer to hold the whole file.\r
+ Status = gBS->AllocatePages (\r
+ Type,\r
+ EfiBootServicesCode,\r
+ EFI_SIZE_TO_PAGES (TftpBufferSize),\r
+ Image\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Failed to allocate space for image: %r\n", Status));\r
+ goto EXIT;\r
+ }\r
\r
- Status = Pxe->Mtftp (\r
- Pxe,\r
- EFI_PXE_BASE_CODE_TFTP_READ_FILE,\r
- (VOID *)(UINTN)*Image,\r
- FALSE,\r
- &TftpBufferSize,\r
- NULL,\r
- &ServerIp,\r
- (UINT8*)AsciiPathName,\r
- NULL,\r
- FALSE\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));\r
+ Status = Pxe->Mtftp (\r
+ Pxe,\r
+ EFI_PXE_BASE_CODE_TFTP_READ_FILE,\r
+ (VOID *)(UINTN)*Image,\r
+ FALSE,\r
+ &TftpBufferSize,\r
+ NULL,\r
+ &ServerIp,\r
+ (UINT8*)AsciiPathName,\r
+ NULL,\r
+ FALSE\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));\r
+ } else {\r
+ *ImageSize = (UINTN)TftpBufferSize;\r
+ break;\r
+ }\r
+ }\r
} else {\r
- *ImageSize = (UINTN)TftpBufferSize;\r
+ // Allocate a buffer to hold the whole file.\r
+ Status = gBS->AllocatePages (\r
+ Type,\r
+ EfiBootServicesCode,\r
+ EFI_SIZE_TO_PAGES (TftpBufferSize),\r
+ Image\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Failed to allocate space for kernel image: %r\n", Status));\r
+ goto EXIT;\r
+ }\r
+\r
+ Status = Pxe->Mtftp (\r
+ Pxe,\r
+ EFI_PXE_BASE_CODE_TFTP_READ_FILE,\r
+ (VOID *)(UINTN)*Image,\r
+ FALSE,\r
+ &TftpBufferSize,\r
+ NULL,\r
+ &ServerIp,\r
+ (UINT8*)AsciiPathName,\r
+ NULL,\r
+ FALSE\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));\r
+ } else {\r
+ *ImageSize = (UINTN)TftpBufferSize;\r
+ }\r
}\r
\r
EXIT:\r