summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c')
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
new file mode 100644
index 0000000000..653b2c507c
--- /dev/null
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
@@ -0,0 +1,163 @@
+/** @file
+*
+* Copyright (c) 2012-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
+* 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 <Protocol/SimpleFileSystem.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+
+#include "BootMonFsInternal.h"
+
+EFIAPI
+EFI_STATUS
+BootMonFsReadFile (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ BOOTMON_FS_INSTANCE *Instance;
+ BOOTMON_FS_FILE *File;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ EFI_BLOCK_IO_MEDIA *Media;
+ UINT64 FileStart;
+ EFI_STATUS Status;
+ UINTN RemainingFileSize;
+
+ // Ensure the file has been written in Flash before reading it.
+ // This keeps the code simple and avoids having to manage a non-flushed file.
+ BootMonFsFlushFile (This);
+
+ File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+ if (File == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = File->Instance;
+ DiskIo = Instance->DiskIo;
+ Media = Instance->Media;
+ FileStart = (Media->LowestAlignedLba + File->HwDescription.BlockStart) * Media->BlockSize;
+
+ if (File->Position >= File->HwDescription.Region[0].Size) {
+ // The entire file has been read
+ *BufferSize = 0;
+ return EFI_DEVICE_ERROR;
+ }
+
+ // This driver assumes that the entire file is in region 0.
+ RemainingFileSize = File->HwDescription.Region[0].Size - File->Position;
+
+ // If read would go past end of file, truncate the read
+ if (*BufferSize > RemainingFileSize) {
+ *BufferSize = RemainingFileSize;
+ }
+
+ Status = DiskIo->ReadDisk (
+ DiskIo,
+ Media->MediaId,
+ FileStart + File->Position,
+ *BufferSize,
+ Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ *BufferSize = 0;
+ }
+
+ File->Position += *BufferSize;
+
+ return Status;
+}
+
+// Inserts an entry into the write chain
+EFIAPI
+EFI_STATUS
+BootMonFsWriteFile (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+{
+ BOOTMON_FS_FILE *File;
+ BOOTMON_FS_FILE_REGION *Region;
+
+ File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+ if (File == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ // Allocate and initialize the memory region
+ Region = (BOOTMON_FS_FILE_REGION*)AllocateZeroPool (sizeof (BOOTMON_FS_FILE_REGION));
+ if (Region == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Region->Buffer = AllocateCopyPool (*BufferSize, Buffer);
+ if (Region->Buffer == NULL) {
+ FreePool (Region);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Region->Size = *BufferSize;
+
+ Region->Offset = File->Position;
+
+ InsertTailList (&File->RegionToFlushLink, &Region->Link);
+
+ File->Position += *BufferSize;
+
+ return EFI_SUCCESS;
+}
+
+EFIAPI
+EFI_STATUS
+BootMonFsSetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ IN UINT64 Position
+ )
+{
+ BOOTMON_FS_FILE *File;
+
+ File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+
+ // UEFI Spec section 12.5:
+ // "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to
+ // be set to the end of the file."
+ if (Position == 0xFFFFFFFFFFFFFFFF) {
+ File->Position = BootMonFsGetImageLength (File);
+ } else {
+ // NB: Seeking past the end of the file is valid.
+ File->Position = Position;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFIAPI
+EFI_STATUS
+BootMonFsGetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT UINT64 *Position
+ ) {
+ BOOTMON_FS_FILE *File;
+
+ File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+
+ *Position = File->Position;
+ return EFI_SUCCESS;
+}