3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Handles non-volatile variable store garbage collection, using FTW
19 (Fault Tolerant Write) protocol.
26 #include "Common/Variable.h"
29 GetFvbHandleByAddress (
30 IN EFI_PHYSICAL_ADDRESS Address
,
31 OUT EFI_HANDLE
*FvbHandle
35 EFI_HANDLE
*HandleBuffer
;
38 EFI_PHYSICAL_ADDRESS FvbBaseAddress
;
39 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
40 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
44 // Locate all handles of Fvb protocol
46 Status
= gBS
->LocateHandleBuffer (
48 &gEfiFirmwareVolumeBlockProtocolGuid
,
53 if (EFI_ERROR (Status
)) {
57 // Get the FVB to access variable store
59 for (Index
= 0; Index
< HandleCount
; Index
+= 1) {
60 Status
= gBS
->HandleProtocol (
62 &gEfiFirmwareVolumeBlockProtocolGuid
,
65 if (EFI_ERROR (Status
)) {
66 Status
= EFI_NOT_FOUND
;
70 // Compare the address and select the right one
72 Status
= Fvb
->GetPhysicalAddress (Fvb
, &FvbBaseAddress
);
73 if (EFI_ERROR (Status
)) {
77 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) FvbBaseAddress
);
78 if ((Address
>= FvbBaseAddress
) && (Address
<= (FvbBaseAddress
+ FwVolHeader
->FvLength
))) {
79 *FvbHandle
= HandleBuffer
[Index
];
85 gBS
->FreePool (HandleBuffer
);
90 GetLbaAndOffsetByAddress (
91 IN EFI_PHYSICAL_ADDRESS Address
,
98 EFI_PHYSICAL_ADDRESS FvbBaseAddress
;
99 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
100 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
101 EFI_FV_BLOCK_MAP_ENTRY
*FvbMapEntry
;
104 *Lba
= (EFI_LBA
) (-1);
108 // Get the proper FVB
110 Status
= GetFvbHandleByAddress (Address
, &FvbHandle
);
111 if (EFI_ERROR (Status
)) {
115 Status
= gBS
->HandleProtocol (
117 &gEfiFirmwareVolumeBlockProtocolGuid
,
120 if (EFI_ERROR (Status
)) {
124 // Get the Base Address of FV
126 Status
= Fvb
->GetPhysicalAddress (Fvb
, &FvbBaseAddress
);
127 if (EFI_ERROR (Status
)) {
131 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) FvbBaseAddress
);
134 // Get the (LBA, Offset) of Address
136 if ((Address
>= FvbBaseAddress
) && (Address
<= (FvbBaseAddress
+ FwVolHeader
->FvLength
))) {
137 if ((FwVolHeader
->FvLength
) > (FwVolHeader
->HeaderLength
)) {
139 // BUGBUG: Assume one FV has one type of BlockLength
141 FvbMapEntry
= &FwVolHeader
->FvBlockMap
[0];
142 for (LbaIndex
= 1; LbaIndex
<= FvbMapEntry
->NumBlocks
; LbaIndex
+= 1) {
143 if (Address
< (FvbBaseAddress
+ FvbMapEntry
->BlockLength
* LbaIndex
)) {
145 // Found the (Lba, Offset)
148 *Offset
= (UINTN
) (Address
- (FvbBaseAddress
+ FvbMapEntry
->BlockLength
* (LbaIndex
- 1)));
160 IN EFI_PHYSICAL_ADDRESS VariableBase
,
167 Write a buffer to Variable space, in the working block.
170 FvbHandle - Indicates a handle to FVB to access variable store
171 Buffer - Point to the input buffer
172 BufferSize - The number of bytes of the input Buffer
175 EFI_SUCCESS - The function completed successfully
176 EFI_ABORTED - The function could not complete successfully
177 EFI_NOT_FOUND - Locate FVB protocol by handle fails
182 EFI_HANDLE FvbHandle
;
183 EFI_FTW_LITE_PROTOCOL
*FtwLiteProtocol
;
190 // Locate fault tolerant write protocol
192 Status
= gBS
->LocateProtocol (
193 &gEfiFaultTolerantWriteLiteProtocolGuid
,
195 (VOID
**) &FtwLiteProtocol
197 if (EFI_ERROR (Status
)) {
198 return EFI_NOT_FOUND
;
201 // Locate Fvb handle by address
203 Status
= GetFvbHandleByAddress (VariableBase
, &FvbHandle
);
204 if (EFI_ERROR (Status
)) {
208 // Get LBA and Offset by address
210 Status
= GetLbaAndOffsetByAddress (VariableBase
, &VarLba
, &VarOffset
);
211 if (EFI_ERROR (Status
)) {
215 // Prepare for the variable data
217 FtwBufferSize
= ((VARIABLE_STORE_HEADER
*) ((UINTN
) VariableBase
))->Size
;
218 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, FtwBufferSize
, (VOID
**) &FtwBuffer
);
219 if (EFI_ERROR (Status
)) {
220 return EFI_OUT_OF_RESOURCES
;
223 SetMem (FtwBuffer
, FtwBufferSize
, (UINT8
) 0xff);
224 CopyMem (FtwBuffer
, Buffer
, BufferSize
);
229 Status
= FtwLiteProtocol
->Write (
234 &FtwBufferSize
, // NumBytes,
238 gBS
->FreePool (FtwBuffer
);