3 Handles non-volatile variable store garbage collection, using FTW
4 (Fault Tolerant Write) protocol.
6 Copyright (c) 2006 - 2008, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <VariableFormat.h>
22 GetFvbHandleByAddress (
23 IN EFI_PHYSICAL_ADDRESS Address
,
24 OUT EFI_HANDLE
*FvbHandle
28 EFI_HANDLE
*HandleBuffer
;
31 EFI_PHYSICAL_ADDRESS FvbBaseAddress
;
32 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
33 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
37 // Locate all handles of Fvb protocol
39 Status
= gBS
->LocateHandleBuffer (
41 &gEfiFirmwareVolumeBlockProtocolGuid
,
46 if (EFI_ERROR (Status
)) {
50 // Get the FVB to access variable store
52 for (Index
= 0; Index
< HandleCount
; Index
+= 1) {
53 Status
= gBS
->HandleProtocol (
55 &gEfiFirmwareVolumeBlockProtocolGuid
,
58 if (EFI_ERROR (Status
)) {
59 Status
= EFI_NOT_FOUND
;
63 // Compare the address and select the right one
65 Status
= Fvb
->GetPhysicalAddress (Fvb
, &FvbBaseAddress
);
66 if (EFI_ERROR (Status
)) {
70 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) FvbBaseAddress
);
71 if ((Address
>= FvbBaseAddress
) && (Address
<= (FvbBaseAddress
+ FwVolHeader
->FvLength
))) {
72 *FvbHandle
= HandleBuffer
[Index
];
78 FreePool (HandleBuffer
);
83 GetLbaAndOffsetByAddress (
84 IN EFI_PHYSICAL_ADDRESS Address
,
91 EFI_PHYSICAL_ADDRESS FvbBaseAddress
;
92 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
93 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
94 EFI_FV_BLOCK_MAP_ENTRY
*FvbMapEntry
;
97 *Lba
= (EFI_LBA
) (-1);
101 // Get the proper FVB
103 Status
= GetFvbHandleByAddress (Address
, &FvbHandle
);
104 if (EFI_ERROR (Status
)) {
108 Status
= gBS
->HandleProtocol (
110 &gEfiFirmwareVolumeBlockProtocolGuid
,
113 if (EFI_ERROR (Status
)) {
117 // Get the Base Address of FV
119 Status
= Fvb
->GetPhysicalAddress (Fvb
, &FvbBaseAddress
);
120 if (EFI_ERROR (Status
)) {
124 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) FvbBaseAddress
);
127 // Get the (LBA, Offset) of Address
129 if ((Address
>= FvbBaseAddress
) && (Address
<= (FvbBaseAddress
+ FwVolHeader
->FvLength
))) {
130 if ((FwVolHeader
->FvLength
) > (FwVolHeader
->HeaderLength
)) {
132 // BUGBUG: Assume one FV has one type of BlockLength
134 FvbMapEntry
= &FwVolHeader
->BlockMap
[0];
135 for (LbaIndex
= 1; LbaIndex
<= FvbMapEntry
->NumBlocks
; LbaIndex
+= 1) {
136 if (Address
< (FvbBaseAddress
+ FvbMapEntry
->Length
* LbaIndex
)) {
138 // Found the (Lba, Offset)
141 *Offset
= (UINTN
) (Address
- (FvbBaseAddress
+ FvbMapEntry
->Length
* (LbaIndex
- 1)));
153 IN EFI_PHYSICAL_ADDRESS VariableBase
,
160 Write a buffer to Variable space, in the working block.
163 FvbHandle - Indicates a handle to FVB to access variable store
164 Buffer - Point to the input buffer
165 BufferSize - The number of bytes of the input Buffer
168 EFI_SUCCESS - The function completed successfully
169 EFI_ABORTED - The function could not complete successfully
170 EFI_NOT_FOUND - Locate FVB protocol by handle fails
175 EFI_HANDLE FvbHandle
;
176 EFI_FTW_LITE_PROTOCOL
*FtwLiteProtocol
;
183 // Locate fault tolerant write protocol
185 Status
= gBS
->LocateProtocol (
186 &gEfiFaultTolerantWriteLiteProtocolGuid
,
188 (VOID
**) &FtwLiteProtocol
190 if (EFI_ERROR (Status
)) {
191 return EFI_NOT_FOUND
;
194 // Locate Fvb handle by address
196 Status
= GetFvbHandleByAddress (VariableBase
, &FvbHandle
);
197 if (EFI_ERROR (Status
)) {
201 // Get LBA and Offset by address
203 Status
= GetLbaAndOffsetByAddress (VariableBase
, &VarLba
, &VarOffset
);
204 if (EFI_ERROR (Status
)) {
208 // Prepare for the variable data
210 FtwBufferSize
= ((VARIABLE_STORE_HEADER
*) ((UINTN
) VariableBase
))->Size
;
211 FtwBuffer
= AllocateRuntimePool (FtwBufferSize
);
212 if (FtwBuffer
== NULL
) {
213 return EFI_OUT_OF_RESOURCES
;
216 SetMem (FtwBuffer
, FtwBufferSize
, (UINT8
) 0xff);
217 CopyMem (FtwBuffer
, Buffer
, BufferSize
);
222 Status
= FtwLiteProtocol
->Write (
227 &FtwBufferSize
, // NumBytes,
231 FreePool (FtwBuffer
);