]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
BaseTools/Upt: Fix several bugs
[mirror_edk2.git] / ArmPlatformPkg / FileSystem / BootMonFs / BootMonFsReadWrite.c
CommitLineData
94e0955d
OM
1/** @file\r
2*\r
3* Copyright (c) 2012-2014, ARM Limited. All rights reserved.\r
4*\r
5* This program and the accompanying materials\r
6* are licensed and made available under the terms and conditions of the BSD License\r
7* which accompanies this distribution. The full text of the license may be found at\r
8* http://opensource.org/licenses/bsd-license.php\r
9*\r
10* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12*\r
13**/\r
14\r
15#include <Protocol/SimpleFileSystem.h>\r
16#include <Library/UefiLib.h>\r
17#include <Library/BaseMemoryLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
19#include <Library/DebugLib.h>\r
20\r
21#include "BootMonFsInternal.h"\r
22\r
23EFIAPI\r
24EFI_STATUS\r
25BootMonFsReadFile (\r
26 IN EFI_FILE_PROTOCOL *This,\r
27 IN OUT UINTN *BufferSize,\r
28 OUT VOID *Buffer\r
29 )\r
30{\r
31 BOOTMON_FS_INSTANCE *Instance;\r
32 BOOTMON_FS_FILE *File;\r
33 EFI_DISK_IO_PROTOCOL *DiskIo;\r
34 EFI_BLOCK_IO_MEDIA *Media;\r
35 UINT64 FileStart;\r
36 EFI_STATUS Status;\r
37 UINTN RemainingFileSize;\r
38\r
39 // Ensure the file has been written in Flash before reading it.\r
40 // This keeps the code simple and avoids having to manage a non-flushed file.\r
41 BootMonFsFlushFile (This);\r
42\r
43 File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);\r
44 if (File == NULL) {\r
45 return EFI_INVALID_PARAMETER;\r
46 }\r
47\r
48 Instance = File->Instance;\r
49 DiskIo = Instance->DiskIo;\r
50 Media = Instance->Media;\r
51 FileStart = (Media->LowestAlignedLba + File->HwDescription.BlockStart) * Media->BlockSize;\r
52\r
53 if (File->Position >= File->HwDescription.Region[0].Size) {\r
54 // The entire file has been read\r
55 *BufferSize = 0;\r
56 return EFI_DEVICE_ERROR;\r
57 }\r
58\r
59 // This driver assumes that the entire file is in region 0.\r
60 RemainingFileSize = File->HwDescription.Region[0].Size - File->Position;\r
61\r
62 // If read would go past end of file, truncate the read\r
63 if (*BufferSize > RemainingFileSize) {\r
64 *BufferSize = RemainingFileSize;\r
65 }\r
66\r
67 Status = DiskIo->ReadDisk (\r
68 DiskIo,\r
69 Media->MediaId,\r
70 FileStart + File->Position,\r
71 *BufferSize,\r
72 Buffer\r
73 );\r
74 if (EFI_ERROR (Status)) {\r
75 *BufferSize = 0;\r
76 }\r
77\r
78 File->Position += *BufferSize;\r
79\r
80 return Status;\r
81}\r
82\r
83// Inserts an entry into the write chain\r
84EFIAPI\r
85EFI_STATUS\r
86BootMonFsWriteFile (\r
87 IN EFI_FILE_PROTOCOL *This,\r
88 IN OUT UINTN *BufferSize,\r
89 IN VOID *Buffer\r
90 )\r
91{\r
92 BOOTMON_FS_FILE *File;\r
93 BOOTMON_FS_FILE_REGION *Region;\r
94\r
95 File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);\r
96 if (File == NULL) {\r
97 return EFI_INVALID_PARAMETER;\r
98 }\r
99\r
100 if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) {\r
101 return EFI_ACCESS_DENIED;\r
102 }\r
103\r
104 // Allocate and initialize the memory region\r
105 Region = (BOOTMON_FS_FILE_REGION*)AllocateZeroPool (sizeof (BOOTMON_FS_FILE_REGION));\r
106 if (Region == NULL) {\r
107 return EFI_OUT_OF_RESOURCES;\r
108 }\r
109\r
110 Region->Buffer = AllocateCopyPool (*BufferSize, Buffer);\r
111 if (Region->Buffer == NULL) {\r
112 FreePool (Region);\r
113 return EFI_OUT_OF_RESOURCES;\r
114 }\r
115\r
116 Region->Size = *BufferSize;\r
117\r
118 Region->Offset = File->Position;\r
119\r
120 InsertTailList (&File->RegionToFlushLink, &Region->Link);\r
121\r
122 File->Position += *BufferSize;\r
123\r
124 return EFI_SUCCESS;\r
125}\r
126\r
127EFIAPI\r
128EFI_STATUS\r
129BootMonFsSetPosition (\r
130 IN EFI_FILE_PROTOCOL *This,\r
131 IN UINT64 Position\r
132 )\r
133{\r
134 BOOTMON_FS_FILE *File;\r
135\r
136 File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);\r
137\r
138 // UEFI Spec section 12.5:\r
139 // "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to\r
140 // be set to the end of the file."\r
141 if (Position == 0xFFFFFFFFFFFFFFFF) {\r
142 File->Position = BootMonFsGetImageLength (File);\r
143 } else {\r
144 // NB: Seeking past the end of the file is valid.\r
145 File->Position = Position;\r
146 }\r
147\r
148 return EFI_SUCCESS;\r
149}\r
150\r
151EFIAPI\r
152EFI_STATUS\r
153BootMonFsGetPosition (\r
154 IN EFI_FILE_PROTOCOL *This,\r
155 OUT UINT64 *Position\r
156 ) {\r
157 BOOTMON_FS_FILE *File;\r
158\r
159 File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);\r
160\r
161 *Position = File->Position;\r
162 return EFI_SUCCESS;\r
163}\r