summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg/Library/ArmShellCmdRunAxf/BootMonFsLoader.c
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPlatformPkg/Library/ArmShellCmdRunAxf/BootMonFsLoader.c')
-rw-r--r--ArmPlatformPkg/Library/ArmShellCmdRunAxf/BootMonFsLoader.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/ArmPlatformPkg/Library/ArmShellCmdRunAxf/BootMonFsLoader.c b/ArmPlatformPkg/Library/ArmShellCmdRunAxf/BootMonFsLoader.c
new file mode 100644
index 000000000..0bce037dc
--- /dev/null
+++ b/ArmPlatformPkg/Library/ArmShellCmdRunAxf/BootMonFsLoader.c
@@ -0,0 +1,154 @@
+/** @file
+*
+* Copyright (c) 2014, ARM Ltd. All rights reserved.
+*
+* This program and the accompanying materials are licensed and made available
+* under the terms and conditions of the BSD License which accompanies this
+* distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+* WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <Guid/BootMonFsFileInfo.h>
+#include <Protocol/SimpleFileSystem.h> // EFI_FILE_HANDLE
+
+#include "ArmShellCmdRunAxf.h"
+#include "BootMonFsLoader.h"
+
+/**
+ Check that loading the file is supported.
+
+ Not all information is checked, only the properties that matters to us in
+ our simplified loader.
+
+ BootMonFS file properties is not in a file header but in the file-system
+ metadata, so we need to pass a handle to the file to allow access to the
+ information.
+
+ @param[in] FileHandle Handle of the file to check.
+
+ @retval EFI_SUCCESS on success.
+ @retval EFI_INVALID_PARAMETER if the header is invalid.
+ @retval EFI_UNSUPPORTED if the file type/platform is not supported.
+**/
+EFI_STATUS
+BootMonFsCheckFile (
+ IN CONST EFI_FILE_HANDLE FileHandle
+ )
+{
+ EFI_STATUS Status;
+ BOOTMON_FS_FILE_INFO Info;
+ UINTN InfoSize;
+ UINTN Index;
+
+ ASSERT (FileHandle != NULL);
+
+ // Try to load the file information as BootMonFS executable.
+ InfoSize = sizeof (Info);
+ // Get BootMon File info and see if it gives us what we need to load the file.
+ Status = FileHandle->GetInfo (FileHandle, &gArmBootMonFsFileInfoGuid,
+ &InfoSize, &Info);
+
+ if (!EFI_ERROR (Status)) {
+ // Check the values return to see if they look reasonable.
+ // Do we have a good entrypoint and at least one good load region?
+ // We assume here that we cannot load to address 0x0.
+ if ((Info.Size == 0) || (Info.EntryPoint == 0) || (Info.RegionCount == 0) ||
+ (Info.RegionCount > BOOTMONFS_IMAGE_DESCRIPTION_REGION_MAX)) {
+ // The file does not seem to be of the right type.
+ Status = EFI_UNSUPPORTED;
+ } else {
+ // Check load regions. We just check for valid numbers, we dont do the
+ // checksums. Info.Offset can be zero if it loads from the start of the
+ // file.
+ for (Index = 0; Index < Info.RegionCount; Index++) {
+ if ((Info.Region[Index].LoadAddress == 0) || (Info.Region[Index].Size == 0)) {
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Load a binary file from BootMonFS.
+
+ @param[in] FileHandle Handle of the file to load.
+
+ @param[in] FileData Address of the file data in memory.
+
+ @param[out] EntryPoint Will be filled with the ELF entry point address.
+
+ @param[out] ImageSize Will be filled with the file size in memory. This
+ will effectively be equal to the sum of the load
+ region sizes.
+
+ This function assumes the file is valid and supported as checked with
+ BootMonFsCheckFile().
+
+ @retval EFI_SUCCESS on success.
+ @retval EFI_INVALID_PARAMETER if the file is invalid.
+**/
+EFI_STATUS
+BootMonFsLoadFile (
+ IN CONST EFI_FILE_HANDLE FileHandle,
+ IN CONST VOID *FileData,
+ OUT VOID **EntryPoint,
+ OUT LIST_ENTRY *LoadList
+ )
+{
+ EFI_STATUS Status;
+ BOOTMON_FS_FILE_INFO Info;
+ UINTN InfoSize;
+ UINTN Index;
+ UINTN ImageSize;
+ RUNAXF_LOAD_LIST *LoadNode;
+
+ ASSERT (FileHandle != NULL);
+ ASSERT (FileData != NULL);
+ ASSERT (EntryPoint != NULL);
+ ASSERT (LoadList != NULL);
+
+ ImageSize = 0;
+
+ InfoSize = sizeof (Info);
+ Status = FileHandle->GetInfo (FileHandle, &gArmBootMonFsFileInfoGuid,
+ &InfoSize, &Info);
+
+ if (!EFI_ERROR (Status)) {
+ *EntryPoint = (VOID*)((UINTN)Info.EntryPoint);
+ // Load all the regions to run-time memory
+ for (Index = 0; Index < Info.RegionCount; Index++) {
+ LoadNode = AllocateRuntimeZeroPool (sizeof (RUNAXF_LOAD_LIST));
+ if (LoadNode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ LoadNode->MemOffset = (UINTN)Info.Region[Index].LoadAddress;
+ LoadNode->FileOffset = (UINTN)FileData + Info.Region[Index].Offset;
+ LoadNode->Length = (UINTN)Info.Region[Index].Size;
+ InsertTailList (LoadList, &LoadNode->Link);
+
+ ImageSize += LoadNode->Length;
+ }
+ }
+
+ if ((!EFI_ERROR (Status)) && (ImageSize == 0)) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ return Status;
+}