3 Caution: This file is used for Duet platform only, do not use them in real platform.
4 All variable code, variable metadata, and variable data used by Duet platform are on
5 disk. They can be changed by user. BIOS is not able to protoect those.
6 Duet trusts all meta data from disk. If variable code, variable metadata and variable
7 data is modified in inproper way, the behavior is undefined.
9 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
10 This program and the accompanying materials
11 are licensed and made available under the terms and conditions of the BSD License
12 which accompanies this distribution. The full text of the license may be found at
13 http://opensource.org/licenses/bsd-license.php
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
24 handles variable store/reads on file
29 #include "FSVariable.h"
31 VOID
*mSFSRegistration
;
39 OnVirtualAddressChangeFs (
47 IN VARIABLE_STORAGE
*This
53 IN VARIABLE_STORAGE
*This
,
61 IN EFI_DEVICE_PATH_PROTOCOL
*Device
,
62 IN CHAR16
*FilePathName
,
64 OUT EFI_FILE_PROTOCOL
**File
68 // Implementation below:
72 IN EFI_FILE_PROTOCOL
*File
77 Status
= File
->Flush (File
);
78 ASSERT_EFI_ERROR (Status
);
80 Status
= File
->Close (File
);
81 ASSERT_EFI_ERROR (Status
);
86 IN EFI_HANDLE SimpleFileSystemHandle
,
88 OUT EFI_DEVICE_PATH_PROTOCOL
**Device
91 #define BLOCK_SIZE 0x200
92 #define FAT16_VOLUME_ID_OFFSET 39
93 #define FAT32_VOLUME_ID_OFFSET 67
95 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
96 UINT8 BootSector
[BLOCK_SIZE
];
99 Status
= gBS
->HandleProtocol (
100 SimpleFileSystemHandle
,
101 &gEfiBlockIoProtocolGuid
, // BlockIo should be supported if it supports SimpleFileSystem
105 if (EFI_ERROR (Status
)) {
108 if (!BlkIo
->Media
->MediaPresent
) {
109 DEBUG ((EFI_D_ERROR
, "FileStorage: Media not present!\n"));
110 Status
= EFI_NO_MEDIA
;
113 if (BlkIo
->Media
->ReadOnly
) {
114 DEBUG ((EFI_D_ERROR
, "FileStorage: Media is read-only!\n"));
115 Status
= EFI_ACCESS_DENIED
;
119 Status
= BlkIo
->ReadBlocks(
121 BlkIo
->Media
->MediaId
,
126 ASSERT_EFI_ERROR (Status
);
127 if ((*(UINT32
*) &BootSector
[FAT16_VOLUME_ID_OFFSET
] != VolumeId
) &&
128 (*(UINT32
*) &BootSector
[FAT32_VOLUME_ID_OFFSET
] != VolumeId
)
130 Status
= EFI_NOT_FOUND
;
134 *Device
= DuplicateDevicePath (DevicePathFromHandle (SimpleFileSystemHandle
));
135 ASSERT (*Device
!= NULL
);
143 IN EFI_DEVICE_PATH_PROTOCOL
*Device
147 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
150 Status
= gBS
->LocateDevicePath (
151 &gEfiSimpleFileSystemProtocolGuid
,
156 if (EFI_ERROR (Status
)) {
160 Status
= gBS
->HandleProtocol (
162 &gEfiSimpleFileSystemProtocolGuid
,
165 if (EFI_ERROR (Status
)) {
172 // this routine is still running in BS period, no limitation
173 // call FileInitStorage(), which load variable content file to memory
174 // read the store_header, init store_header if it has not been inited (read sth. about format/heathy)
175 // reclaim space using scratch memory
179 OnSimpleFileSystemInstall (
187 EFI_DEVICE_PATH_PROTOCOL
*Device
;
189 EFI_FILE_PROTOCOL
*File
;
192 Dev
= (VS_DEV
*) Context
;
194 if (VAR_FILE_DEVICEPATH (Dev
) != NULL
&&
195 !EFI_ERROR (CheckStoreExists (VAR_FILE_DEVICEPATH (Dev
)))
197 DEBUG ((EFI_D_ERROR
, "FileStorage: Already mapped!\n"));
202 HandleSize
= sizeof (EFI_HANDLE
);
203 Status
= gBS
->LocateHandle (
210 if (EFI_ERROR (Status
)) {
214 Status
= CheckStore (Handle
, VAR_FILE_VOLUMEID (Dev
), &Device
);
215 if (!EFI_ERROR (Status
)) {
220 VAR_FILE_DEVICEPATH (Dev
) = Device
;
222 VAR_FILE_DEVICEPATH (Dev
),
223 VAR_FILE_FILEPATH (Dev
),
224 EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
| EFI_FILE_MODE_CREATE
,
227 ASSERT_EFI_ERROR (Status
);
229 NumBytes
= Dev
->Size
;
230 Status
= File
->Write (File
, &NumBytes
, VAR_DATA_PTR (Dev
));
231 ASSERT_EFI_ERROR (Status
);
233 DEBUG ((EFI_D_ERROR
, "FileStorage: Mapped to file!\n"));
237 FileStorageConstructor (
238 OUT VARIABLE_STORAGE
**VarStore
,
239 OUT EFI_EVENT_NOTIFY
*GoVirtualEvent
,
240 IN EFI_PHYSICAL_ADDRESS NvStorageBase
,
250 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, sizeof(VS_DEV
), (VOID
**) &Dev
);
251 ASSERT_EFI_ERROR (Status
);
252 ZeroMem (Dev
, sizeof(VS_DEV
));
254 Dev
->Signature
= VS_DEV_SIGNATURE
;
256 VAR_DATA_PTR (Dev
) = (UINT8
*) (UINTN
) NvStorageBase
;
257 VAR_FILE_VOLUMEID (Dev
) = VolumeId
;
258 StrCpy (VAR_FILE_FILEPATH (Dev
), FilePath
);
259 Dev
->VarStore
.Erase
= FileEraseStore
;
260 Dev
->VarStore
.Write
= FileWriteStore
;
262 DEBUG ((EFI_D_ERROR
, "FileStorageConstructor(0x%0x:0x%0x): added!\n", NvStorageBase
, Size
));
264 // add notify on SFS's installation.
266 Status
= gBS
->CreateEvent (
269 OnSimpleFileSystemInstall
,
273 ASSERT_EFI_ERROR (Status
);
275 Status
= gBS
->RegisterProtocolNotify (
276 &gEfiSimpleFileSystemProtocolGuid
,
280 ASSERT_EFI_ERROR (Status
);
282 *VarStore
= &Dev
->VarStore
;
283 *GoVirtualEvent
= OnVirtualAddressChangeFs
;
290 IN VARIABLE_STORAGE
*This
295 EFI_FILE_PROTOCOL
*File
;
298 Status
= EFI_SUCCESS
;
299 Dev
= DEV_FROM_THIS(This
);
301 SetMem (VAR_DATA_PTR (Dev
), Dev
->Size
, VAR_DEFAULT_VALUE
);
303 if (!EfiAtRuntime () && VAR_FILE_DEVICEPATH (Dev
) != NULL
) {
305 VAR_FILE_DEVICEPATH (Dev
),
306 VAR_FILE_FILEPATH (Dev
),
307 EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
,
310 ASSERT_EFI_ERROR (Status
);
311 NumBytes
= Dev
->Size
;
312 Status
= File
->Write (File
, &NumBytes
, VAR_DATA_PTR (Dev
));
313 ASSERT_EFI_ERROR (Status
);
323 IN VARIABLE_STORAGE
*This
,
331 EFI_FILE_PROTOCOL
*File
;
333 Status
= EFI_SUCCESS
;
334 Dev
= DEV_FROM_THIS(This
);
336 ASSERT (Buffer
!= NULL
);
337 ASSERT (Offset
+ BufferSize
<= Dev
->Size
);
339 CopyMem (VAR_DATA_PTR (Dev
) + Offset
, Buffer
, BufferSize
);
341 if (!EfiAtRuntime () && VAR_FILE_DEVICEPATH (Dev
) != NULL
) {
343 VAR_FILE_DEVICEPATH (Dev
),
344 VAR_FILE_FILEPATH (Dev
),
345 EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
,
348 Status
= File
->SetPosition (File
, Offset
);
349 ASSERT_EFI_ERROR (Status
);
350 Status
= File
->Write (File
, &BufferSize
, Buffer
);
351 ASSERT_EFI_ERROR (Status
);
359 OnVirtualAddressChangeFs (
366 Dev
= DEV_FROM_THIS (Context
);
368 EfiConvertPointer (0, (VOID
**) &VAR_DATA_PTR (Dev
));
369 EfiConvertPointer (0, (VOID
**) &Dev
->VarStore
.Erase
);
370 EfiConvertPointer (0, (VOID
**) &Dev
->VarStore
.Write
);
375 IN EFI_DEVICE_PATH_PROTOCOL
*Device
,
376 IN CHAR16
*FilePathName
,
378 OUT EFI_FILE_PROTOCOL
**File
382 EFI_FILE_HANDLE Root
;
383 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Volume
;
388 Status
= gBS
->LocateDevicePath (
389 &gEfiSimpleFileSystemProtocolGuid
,
394 if (EFI_ERROR (Status
)) {
398 Status
= gBS
->HandleProtocol (
400 &gEfiSimpleFileSystemProtocolGuid
,
403 if (EFI_ERROR (Status
)) {
408 // Open the root directory of the volume
411 Status
= Volume
->OpenVolume (
415 ASSERT_EFI_ERROR (Status
);
416 ASSERT (Root
!= NULL
);
421 Status
= Root
->Open (
428 if (EFI_ERROR (Status
)) {
433 // Close the Root directory