3 Copyright (c) 2006 - 2007, 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.
27 #include "Common/Variable.h"
30 GetFvbHandleByAddress (
31 IN EFI_PHYSICAL_ADDRESS Address
,
32 OUT EFI_HANDLE
*FvbHandle
36 EFI_HANDLE
*HandleBuffer
;
39 EFI_PHYSICAL_ADDRESS FvbBaseAddress
;
40 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
41 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
45 // Locate all handles of Fvb protocol
47 Status
= gBS
->LocateHandleBuffer (
49 &gEfiFirmwareVolumeBlockProtocolGuid
,
54 if (EFI_ERROR (Status
)) {
58 // Get the FVB to access variable store
60 for (Index
= 0; Index
< HandleCount
; Index
+= 1) {
61 Status
= gBS
->HandleProtocol (
63 &gEfiFirmwareVolumeBlockProtocolGuid
,
66 if (EFI_ERROR (Status
)) {
67 Status
= EFI_NOT_FOUND
;
71 // Compare the address and select the right one
73 Status
= Fvb
->GetPhysicalAddress (Fvb
, &FvbBaseAddress
);
74 if (EFI_ERROR (Status
)) {
78 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) FvbBaseAddress
);
79 if ((Address
>= FvbBaseAddress
) && (Address
<= (FvbBaseAddress
+ FwVolHeader
->FvLength
))) {
80 *FvbHandle
= HandleBuffer
[Index
];
86 FreePool (HandleBuffer
);
92 GetLbaAndOffsetByAddress (
93 IN EFI_PHYSICAL_ADDRESS Address
,
100 EFI_PHYSICAL_ADDRESS FvbBaseAddress
;
101 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
102 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
103 EFI_FV_BLOCK_MAP_ENTRY
*FvbMapEntry
;
106 *Lba
= (EFI_LBA
) (-1);
110 // Get the proper FVB
112 Status
= GetFvbHandleByAddress (Address
, &FvbHandle
);
113 if (EFI_ERROR (Status
)) {
117 Status
= gBS
->HandleProtocol (
119 &gEfiFirmwareVolumeBlockProtocolGuid
,
122 if (EFI_ERROR (Status
)) {
126 // Get the Base Address of FV
128 Status
= Fvb
->GetPhysicalAddress (Fvb
, &FvbBaseAddress
);
129 if (EFI_ERROR (Status
)) {
133 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) FvbBaseAddress
);
136 // Get the (LBA, Offset) of Address
138 if ((Address
>= FvbBaseAddress
) && (Address
<= (FvbBaseAddress
+ FwVolHeader
->FvLength
))) {
139 if ((FwVolHeader
->FvLength
) > (FwVolHeader
->HeaderLength
)) {
141 // BUGBUG: Assume one FV has one type of BlockLength
143 FvbMapEntry
= &FwVolHeader
->BlockMap
[0];
144 for (LbaIndex
= 1; LbaIndex
<= FvbMapEntry
->NumBlocks
; LbaIndex
+= 1) {
145 if (Address
< (FvbBaseAddress
+ FvbMapEntry
->Length
* LbaIndex
)) {
147 // Found the (Lba, Offset)
150 *Offset
= (UINTN
) (Address
- (FvbBaseAddress
+ FvbMapEntry
->Length
* (LbaIndex
- 1)));
162 IN EFI_PHYSICAL_ADDRESS VariableBase
,
169 Write a buffer to Variable space, in the working block.
172 FvbHandle - Indicates a handle to FVB to access variable store
173 Buffer - Point to the input buffer
174 BufferSize - The number of bytes of the input Buffer
177 EFI_SUCCESS - The function completed successfully
178 EFI_ABORTED - The function could not complete successfully
179 EFI_NOT_FOUND - Locate FVB protocol by handle fails
184 EFI_HANDLE FvbHandle
;
185 EFI_FTW_LITE_PROTOCOL
*FtwLiteProtocol
;
192 // Locate fault tolerant write protocol
194 Status
= gBS
->LocateProtocol (
195 &gEfiFaultTolerantWriteLiteProtocolGuid
,
197 (VOID
**) &FtwLiteProtocol
199 if (EFI_ERROR (Status
)) {
200 return EFI_NOT_FOUND
;
203 // Locate Fvb handle by address
205 Status
= GetFvbHandleByAddress (VariableBase
, &FvbHandle
);
206 if (EFI_ERROR (Status
)) {
210 // Get LBA and Offset by address
212 Status
= GetLbaAndOffsetByAddress (VariableBase
, &VarLba
, &VarOffset
);
213 if (EFI_ERROR (Status
)) {
217 // Prepare for the variable data
219 FtwBufferSize
= ((VARIABLE_STORE_HEADER
*) ((UINTN
) VariableBase
))->Size
;
220 FtwBuffer
= AllocateRuntimePool (FtwBufferSize
);
221 if (FtwBuffer
== NULL
) {
222 return EFI_OUT_OF_RESOURCES
;
225 SetMem (FtwBuffer
, FtwBufferSize
, (UINT8
) 0xff);
226 CopyMem (FtwBuffer
, Buffer
, BufferSize
);
231 Status
= FtwLiteProtocol
->Write (
236 &FtwBufferSize
, // NumBytes,
240 FreePool (FtwBuffer
);