]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/FSVariable/FileStorage.c
SecurityPkg: Add TPM PTP support in TPM2 device lib.
[mirror_edk2.git] / DuetPkg / FSVariable / FileStorage.c
CommitLineData
9071550e 1/*++\r
2\r
741a1e58
ED
3Caution: This file is used for Duet platform only, do not use them in real platform.\r
4All variable code, variable metadata, and variable data used by Duet platform are on \r
5disk. They can be changed by user. BIOS is not able to protoect those.\r
6Duet trusts all meta data from disk. If variable code, variable metadata and variable\r
7data is modified in inproper way, the behavior is undefined.\r
8\r
9Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
b1f700a8 10This program and the accompanying materials\r
9071550e 11are licensed and made available under the terms and conditions of the BSD License\r
12which accompanies this distribution. The full text of the license may be found at\r
13http://opensource.org/licenses/bsd-license.php\r
14\r
15THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
16WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
17\r
18Module Name:\r
19\r
20 FileStorage.c\r
21\r
22Abstract:\r
23\r
24 handles variable store/reads on file\r
25\r
26Revision History\r
27\r
28--*/\r
29#include "FSVariable.h"\r
30\r
31VOID *mSFSRegistration;\r
32\r
33//\r
34// Prototypes\r
35//\r
36\r
9071550e 37VOID\r
38EFIAPI\r
e56dd2ce 39OnVirtualAddressChangeFs (\r
9071550e 40 IN EFI_EVENT Event,\r
41 IN VOID *Context\r
42 );\r
43\r
9071550e 44EFI_STATUS\r
45EFIAPI\r
46FileEraseStore(\r
47 IN VARIABLE_STORAGE *This\r
48 );\r
49\r
9071550e 50EFI_STATUS\r
51EFIAPI\r
52FileWriteStore (\r
53 IN VARIABLE_STORAGE *This,\r
54 IN UINTN Offset,\r
55 IN UINTN BufferSize,\r
56 IN VOID *Buffer\r
57 );\r
58\r
9071550e 59EFI_STATUS\r
60OpenStore (\r
61 IN EFI_DEVICE_PATH_PROTOCOL *Device,\r
62 IN CHAR16 *FilePathName,\r
63 IN UINT64 OpenMode,\r
b0b961c8 64 OUT EFI_FILE_PROTOCOL **File\r
9071550e 65 );\r
66\r
67//\r
68// Implementation below:\r
69//\r
9071550e 70VOID\r
71FileClose (\r
b0b961c8 72 IN EFI_FILE_PROTOCOL *File\r
9071550e 73 )\r
74{\r
75 EFI_STATUS Status;\r
76\r
77 Status = File->Flush (File);\r
78 ASSERT_EFI_ERROR (Status);\r
79\r
80 Status = File->Close (File);\r
81 ASSERT_EFI_ERROR (Status);\r
82}\r
83\r
84EFI_STATUS\r
85CheckStore (\r
86 IN EFI_HANDLE SimpleFileSystemHandle,\r
87 IN UINT32 VolumeId,\r
88 OUT EFI_DEVICE_PATH_PROTOCOL **Device\r
89 )\r
90{\r
91#define BLOCK_SIZE 0x200\r
92#define FAT16_VOLUME_ID_OFFSET 39\r
93#define FAT32_VOLUME_ID_OFFSET 67\r
94 EFI_STATUS Status;\r
95 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
96 UINT8 BootSector[BLOCK_SIZE];\r
97\r
98 *Device = NULL;\r
99 Status = gBS->HandleProtocol (\r
100 SimpleFileSystemHandle,\r
101 &gEfiBlockIoProtocolGuid, // BlockIo should be supported if it supports SimpleFileSystem\r
102 (VOID*)&BlkIo\r
103 );\r
104\r
105 if (EFI_ERROR (Status)) {\r
106 goto ErrHandle;\r
107 }\r
108 if (!BlkIo->Media->MediaPresent) {\r
109 DEBUG ((EFI_D_ERROR, "FileStorage: Media not present!\n"));\r
110 Status = EFI_NO_MEDIA;\r
111 goto ErrHandle;\r
112 }\r
113 if (BlkIo->Media->ReadOnly) {\r
114 DEBUG ((EFI_D_ERROR, "FileStorage: Media is read-only!\n"));\r
115 Status = EFI_ACCESS_DENIED;\r
116 goto ErrHandle;\r
117 }\r
118\r
119 Status = BlkIo->ReadBlocks(\r
120 BlkIo,\r
121 BlkIo->Media->MediaId,\r
122 0,\r
123 BLOCK_SIZE,\r
124 BootSector\r
125 );\r
126 ASSERT_EFI_ERROR (Status);\r
127 if ((*(UINT32 *) &BootSector[FAT16_VOLUME_ID_OFFSET] != VolumeId) &&\r
128 (*(UINT32 *) &BootSector[FAT32_VOLUME_ID_OFFSET] != VolumeId)\r
129 ) {\r
130 Status = EFI_NOT_FOUND;\r
131 goto ErrHandle;\r
132 }\r
133\r
134 *Device = DuplicateDevicePath (DevicePathFromHandle (SimpleFileSystemHandle));\r
135 ASSERT (*Device != NULL);\r
136\r
137ErrHandle:\r
138 return Status;\r
139}\r
140\r
141EFI_STATUS\r
142CheckStoreExists (\r
143 IN EFI_DEVICE_PATH_PROTOCOL *Device\r
144 )\r
145{\r
146 EFI_HANDLE Handle;\r
147 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;\r
148 EFI_STATUS Status;\r
149\r
150 Status = gBS->LocateDevicePath (\r
151 &gEfiSimpleFileSystemProtocolGuid,\r
152 &Device, \r
153 &Handle\r
154 );\r
155\r
156 if (EFI_ERROR (Status)) {\r
157 return Status;\r
158 }\r
159\r
160 Status = gBS->HandleProtocol (\r
161 Handle,\r
162 &gEfiSimpleFileSystemProtocolGuid,\r
7c04a679 163 (VOID **) &Volume\r
9071550e 164 );\r
165 if (EFI_ERROR (Status)) {\r
166 return Status;\r
167 }\r
168\r
169 return EFI_SUCCESS;\r
170}\r
171\r
172// this routine is still running in BS period, no limitation\r
173// call FileInitStorage(), which load variable content file to memory\r
174// read the store_header, init store_header if it has not been inited (read sth. about format/heathy)\r
175// reclaim space using scratch memory\r
176\r
9071550e 177VOID\r
178EFIAPI\r
179OnSimpleFileSystemInstall (\r
180 IN EFI_EVENT Event,\r
181 IN VOID *Context\r
182 )\r
183{\r
184 EFI_STATUS Status;\r
185 UINTN HandleSize;\r
186 EFI_HANDLE Handle;\r
187 EFI_DEVICE_PATH_PROTOCOL *Device;\r
188 VS_DEV *Dev;\r
b0b961c8 189 EFI_FILE_PROTOCOL *File;\r
9071550e 190 UINTN NumBytes;\r
191\r
192 Dev = (VS_DEV *) Context;\r
193 \r
194 if (VAR_FILE_DEVICEPATH (Dev) != NULL &&\r
195 !EFI_ERROR (CheckStoreExists (VAR_FILE_DEVICEPATH (Dev)))\r
196 ) {\r
197 DEBUG ((EFI_D_ERROR, "FileStorage: Already mapped!\n"));\r
198 return ;\r
199 }\r
200\r
201 while (TRUE) {\r
202 HandleSize = sizeof (EFI_HANDLE);\r
203 Status = gBS->LocateHandle (\r
204 ByRegisterNotify,\r
205 NULL,\r
206 mSFSRegistration,\r
207 &HandleSize,\r
208 &Handle\r
209 );\r
210 if (EFI_ERROR (Status)) {\r
211 return ;\r
212 }\r
213 \r
214 Status = CheckStore (Handle, VAR_FILE_VOLUMEID (Dev), &Device);\r
215 if (!EFI_ERROR (Status)) {\r
216 break;\r
217 }\r
218 }\r
219\r
220 VAR_FILE_DEVICEPATH (Dev) = Device;\r
221 Status = OpenStore (\r
222 VAR_FILE_DEVICEPATH (Dev), \r
223 VAR_FILE_FILEPATH (Dev), \r
224 EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ | EFI_FILE_MODE_CREATE,\r
225 &File\r
226 );\r
227 ASSERT_EFI_ERROR (Status);\r
228 \r
229 NumBytes = Dev->Size;\r
230 Status = File->Write (File, &NumBytes, VAR_DATA_PTR (Dev));\r
231 ASSERT_EFI_ERROR (Status);\r
571f4f52 232 FileClose (File);\r
9071550e 233 DEBUG ((EFI_D_ERROR, "FileStorage: Mapped to file!\n"));\r
234}\r
235\r
236EFI_STATUS\r
237FileStorageConstructor (\r
238 OUT VARIABLE_STORAGE **VarStore,\r
239 OUT EFI_EVENT_NOTIFY *GoVirtualEvent,\r
240 IN EFI_PHYSICAL_ADDRESS NvStorageBase,\r
241 IN UINTN Size,\r
242 IN UINT32 VolumeId,\r
243 IN CHAR16 *FilePath\r
244 )\r
245{\r
246 VS_DEV *Dev;\r
247 EFI_STATUS Status;\r
248 EFI_EVENT Event;\r
249\r
7c04a679 250 Status = gBS->AllocatePool (EfiRuntimeServicesData, sizeof(VS_DEV), (VOID **) &Dev);\r
9071550e 251 ASSERT_EFI_ERROR (Status);\r
252 ZeroMem (Dev, sizeof(VS_DEV));\r
253\r
439c34f3 254 Dev->Signature = VS_DEV_SIGNATURE;\r
9071550e 255 Dev->Size = Size;\r
256 VAR_DATA_PTR (Dev) = (UINT8 *) (UINTN) NvStorageBase;\r
257 VAR_FILE_VOLUMEID (Dev) = VolumeId;\r
258 StrCpy (VAR_FILE_FILEPATH (Dev), FilePath);\r
259 Dev->VarStore.Erase = FileEraseStore;\r
260 Dev->VarStore.Write = FileWriteStore;\r
261\r
262 DEBUG ((EFI_D_ERROR, "FileStorageConstructor(0x%0x:0x%0x): added!\n", NvStorageBase, Size));\r
263\r
264 // add notify on SFS's installation.\r
265\r
266 Status = gBS->CreateEvent (\r
e53a6ea9 267 EVT_NOTIFY_SIGNAL,\r
9071550e 268 TPL_CALLBACK,\r
269 OnSimpleFileSystemInstall,\r
270 Dev,\r
271 &Event\r
272 );\r
273 ASSERT_EFI_ERROR (Status);\r
274\r
275 Status = gBS->RegisterProtocolNotify (\r
276 &gEfiSimpleFileSystemProtocolGuid,\r
277 Event,\r
278 &mSFSRegistration\r
279 );\r
280 ASSERT_EFI_ERROR (Status);\r
281\r
282 *VarStore = &Dev->VarStore;\r
e56dd2ce 283 *GoVirtualEvent = OnVirtualAddressChangeFs;\r
9071550e 284 return EFI_SUCCESS;\r
285}\r
286\r
9071550e 287EFI_STATUS\r
288EFIAPI\r
289FileEraseStore(\r
290 IN VARIABLE_STORAGE *This\r
291 )\r
292{\r
293 EFI_STATUS Status;\r
294 VS_DEV *Dev;\r
b0b961c8 295 EFI_FILE_PROTOCOL *File;\r
9071550e 296 UINTN NumBytes;\r
297\r
298 Status = EFI_SUCCESS;\r
299 Dev = DEV_FROM_THIS(This);\r
300\r
301 SetMem (VAR_DATA_PTR (Dev), Dev->Size, VAR_DEFAULT_VALUE);\r
302\r
303 if (!EfiAtRuntime () && VAR_FILE_DEVICEPATH (Dev) != NULL) {\r
304 Status = OpenStore (\r
305 VAR_FILE_DEVICEPATH (Dev), \r
306 VAR_FILE_FILEPATH (Dev), \r
307 EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ,\r
308 &File\r
309 );\r
310 ASSERT_EFI_ERROR (Status);\r
311 NumBytes = Dev->Size;\r
312 Status = File->Write (File, &NumBytes, VAR_DATA_PTR (Dev));\r
313 ASSERT_EFI_ERROR (Status);\r
314 FileClose (File);\r
315 }\r
316 \r
317 return Status;\r
318}\r
319\r
9071550e 320EFI_STATUS\r
321EFIAPI\r
322FileWriteStore (\r
323 IN VARIABLE_STORAGE *This,\r
324 IN UINTN Offset,\r
325 IN UINTN BufferSize,\r
326 IN VOID *Buffer\r
327 )\r
328{\r
329 EFI_STATUS Status;\r
330 VS_DEV *Dev;\r
b0b961c8 331 EFI_FILE_PROTOCOL *File;\r
9071550e 332\r
333 Status = EFI_SUCCESS;\r
334 Dev = DEV_FROM_THIS(This);\r
335\r
336 ASSERT (Buffer != NULL);\r
337 ASSERT (Offset + BufferSize <= Dev->Size);\r
338\r
339 CopyMem (VAR_DATA_PTR (Dev) + Offset, Buffer, BufferSize);\r
340 \r
341 if (!EfiAtRuntime () && VAR_FILE_DEVICEPATH (Dev) != NULL) {\r
342 Status = OpenStore (\r
343 VAR_FILE_DEVICEPATH (Dev), \r
344 VAR_FILE_FILEPATH (Dev), \r
345 EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ,\r
346 &File\r
347 );\r
348 Status = File->SetPosition (File, Offset);\r
349 ASSERT_EFI_ERROR (Status);\r
350 Status = File->Write (File, &BufferSize, Buffer);\r
351 ASSERT_EFI_ERROR (Status);\r
352 FileClose (File);\r
353 }\r
354 return Status;\r
355}\r
356\r
9071550e 357VOID\r
358EFIAPI\r
e56dd2ce 359OnVirtualAddressChangeFs (\r
9071550e 360 IN EFI_EVENT Event,\r
361 IN VOID *Context\r
362 )\r
363{\r
364 VS_DEV *Dev;\r
365\r
366 Dev = DEV_FROM_THIS (Context);\r
367\r
7c04a679 368 EfiConvertPointer (0, (VOID **) &VAR_DATA_PTR (Dev));\r
9071550e 369 EfiConvertPointer (0, (VOID **) &Dev->VarStore.Erase);\r
370 EfiConvertPointer (0, (VOID **) &Dev->VarStore.Write);\r
371}\r
372\r
9071550e 373EFI_STATUS\r
374OpenStore (\r
375 IN EFI_DEVICE_PATH_PROTOCOL *Device,\r
376 IN CHAR16 *FilePathName,\r
377 IN UINT64 OpenMode,\r
b0b961c8 378 OUT EFI_FILE_PROTOCOL **File\r
9071550e 379 )\r
380{\r
381 EFI_HANDLE Handle;\r
382 EFI_FILE_HANDLE Root;\r
383 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;\r
384 EFI_STATUS Status;\r
385\r
386 *File = NULL;\r
387\r
388 Status = gBS->LocateDevicePath (\r
389 &gEfiSimpleFileSystemProtocolGuid,\r
390 &Device, \r
391 &Handle\r
392 );\r
393\r
394 if (EFI_ERROR (Status)) {\r
395 return Status;\r
396 }\r
397\r
398 Status = gBS->HandleProtocol (\r
399 Handle,\r
400 &gEfiSimpleFileSystemProtocolGuid,\r
7c04a679 401 (VOID **) &Volume\r
9071550e 402 );\r
403 if (EFI_ERROR (Status)) {\r
404 return Status;\r
405 }\r
be768885 406\r
9071550e 407 //\r
408 // Open the root directory of the volume\r
409 //\r
410 Root = NULL;\r
411 Status = Volume->OpenVolume (\r
412 Volume,\r
413 &Root\r
414 );\r
415 ASSERT_EFI_ERROR (Status);\r
416 ASSERT (Root != NULL);\r
417\r
418 //\r
419 // Open file\r
420 //\r
421 Status = Root->Open (\r
422 Root,\r
423 File,\r
424 FilePathName,\r
425 OpenMode,\r
426 0\r
427 );\r
428 if (EFI_ERROR (Status)) {\r
429 *File = NULL;\r
430 }\r
431\r
432 //\r
433 // Close the Root directory\r
434 //\r
435 Root->Close (Root);\r
436 return Status;\r
437}\r