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
);
84 GetLbaAndOffsetByAddress (
85 IN EFI_PHYSICAL_ADDRESS Address
,
92 EFI_PHYSICAL_ADDRESS FvbBaseAddress
;
93 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
94 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
95 EFI_FV_BLOCK_MAP_ENTRY
*FvbMapEntry
;
98 *Lba
= (EFI_LBA
) (-1);
102 // Get the proper FVB
104 Status
= GetFvbHandleByAddress (Address
, &FvbHandle
);
105 if (EFI_ERROR (Status
)) {
109 Status
= gBS
->HandleProtocol (
111 &gEfiFirmwareVolumeBlockProtocolGuid
,
114 if (EFI_ERROR (Status
)) {
118 // Get the Base Address of FV
120 Status
= Fvb
->GetPhysicalAddress (Fvb
, &FvbBaseAddress
);
121 if (EFI_ERROR (Status
)) {
125 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) FvbBaseAddress
);
128 // Get the (LBA, Offset) of Address
130 if ((Address
>= FvbBaseAddress
) && (Address
<= (FvbBaseAddress
+ FwVolHeader
->FvLength
))) {
131 if ((FwVolHeader
->FvLength
) > (FwVolHeader
->HeaderLength
)) {
133 // BUGBUG: Assume one FV has one type of BlockLength
135 FvbMapEntry
= &FwVolHeader
->BlockMap
[0];
136 for (LbaIndex
= 1; LbaIndex
<= FvbMapEntry
->NumBlocks
; LbaIndex
+= 1) {
137 if (Address
< (FvbBaseAddress
+ FvbMapEntry
->Length
* LbaIndex
)) {
139 // Found the (Lba, Offset)
142 *Offset
= (UINTN
) (Address
- (FvbBaseAddress
+ FvbMapEntry
->Length
* (LbaIndex
- 1)));
154 IN EFI_PHYSICAL_ADDRESS VariableBase
,
161 Write a buffer to Variable space, in the working block.
164 FvbHandle - Indicates a handle to FVB to access variable store
165 Buffer - Point to the input buffer
166 BufferSize - The number of bytes of the input Buffer
169 EFI_SUCCESS - The function completed successfully
170 EFI_ABORTED - The function could not complete successfully
171 EFI_NOT_FOUND - Locate FVB protocol by handle fails
176 EFI_HANDLE FvbHandle
;
177 EFI_FTW_LITE_PROTOCOL
*FtwLiteProtocol
;
184 // Locate fault tolerant write protocol
186 Status
= gBS
->LocateProtocol (
187 &gEfiFaultTolerantWriteLiteProtocolGuid
,
189 (VOID
**) &FtwLiteProtocol
191 if (EFI_ERROR (Status
)) {
192 return EFI_NOT_FOUND
;
195 // Locate Fvb handle by address
197 Status
= GetFvbHandleByAddress (VariableBase
, &FvbHandle
);
198 if (EFI_ERROR (Status
)) {
202 // Get LBA and Offset by address
204 Status
= GetLbaAndOffsetByAddress (VariableBase
, &VarLba
, &VarOffset
);
205 if (EFI_ERROR (Status
)) {
209 // Prepare for the variable data
211 FtwBufferSize
= ((VARIABLE_STORE_HEADER
*) ((UINTN
) VariableBase
))->Size
;
212 FtwBuffer
= AllocateRuntimePool (FtwBufferSize
);
213 if (FtwBuffer
== NULL
) {
214 return EFI_OUT_OF_RESOURCES
;
217 SetMem (FtwBuffer
, FtwBufferSize
, (UINT8
) 0xff);
218 CopyMem (FtwBuffer
, Buffer
, BufferSize
);
223 Status
= FtwLiteProtocol
->Write (
228 &FtwBufferSize
, // NumBytes,
232 FreePool (FtwBuffer
);