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
);
91 GetLbaAndOffsetByAddress (
92 IN EFI_PHYSICAL_ADDRESS Address
,
99 EFI_PHYSICAL_ADDRESS FvbBaseAddress
;
100 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
101 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
102 EFI_FV_BLOCK_MAP_ENTRY
*FvbMapEntry
;
105 *Lba
= (EFI_LBA
) (-1);
109 // Get the proper FVB
111 Status
= GetFvbHandleByAddress (Address
, &FvbHandle
);
112 if (EFI_ERROR (Status
)) {
116 Status
= gBS
->HandleProtocol (
118 &gEfiFirmwareVolumeBlockProtocolGuid
,
121 if (EFI_ERROR (Status
)) {
125 // Get the Base Address of FV
127 Status
= Fvb
->GetPhysicalAddress (Fvb
, &FvbBaseAddress
);
128 if (EFI_ERROR (Status
)) {
132 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINTN
) FvbBaseAddress
);
135 // Get the (LBA, Offset) of Address
137 if ((Address
>= FvbBaseAddress
) && (Address
<= (FvbBaseAddress
+ FwVolHeader
->FvLength
))) {
138 if ((FwVolHeader
->FvLength
) > (FwVolHeader
->HeaderLength
)) {
140 // BUGBUG: Assume one FV has one type of BlockLength
142 FvbMapEntry
= &FwVolHeader
->FvBlockMap
[0];
143 for (LbaIndex
= 1; LbaIndex
<= FvbMapEntry
->NumBlocks
; LbaIndex
+= 1) {
144 if (Address
< (FvbBaseAddress
+ FvbMapEntry
->BlockLength
* LbaIndex
)) {
146 // Found the (Lba, Offset)
149 *Offset
= (UINTN
) (Address
- (FvbBaseAddress
+ FvbMapEntry
->BlockLength
* (LbaIndex
- 1)));
161 IN EFI_PHYSICAL_ADDRESS VariableBase
,
168 Write a buffer to Variable space, in the working block.
171 FvbHandle - Indicates a handle to FVB to access variable store
172 Buffer - Point to the input buffer
173 BufferSize - The number of bytes of the input Buffer
176 EFI_SUCCESS - The function completed successfully
177 EFI_ABORTED - The function could not complete successfully
178 EFI_NOT_FOUND - Locate FVB protocol by handle fails
183 EFI_HANDLE FvbHandle
;
184 EFI_FTW_LITE_PROTOCOL
*FtwLiteProtocol
;
191 // Locate fault tolerant write protocol
193 Status
= gBS
->LocateProtocol (
194 &gEfiFaultTolerantWriteLiteProtocolGuid
,
196 (VOID
**) &FtwLiteProtocol
198 if (EFI_ERROR (Status
)) {
199 return EFI_NOT_FOUND
;
202 // Locate Fvb handle by address
204 Status
= GetFvbHandleByAddress (VariableBase
, &FvbHandle
);
205 if (EFI_ERROR (Status
)) {
209 // Get LBA and Offset by address
211 Status
= GetLbaAndOffsetByAddress (VariableBase
, &VarLba
, &VarOffset
);
212 if (EFI_ERROR (Status
)) {
216 // Prepare for the variable data
218 FtwBufferSize
= ((VARIABLE_STORE_HEADER
*) ((UINTN
) VariableBase
))->Size
;
219 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, FtwBufferSize
, (VOID
**) &FtwBuffer
);
220 if (EFI_ERROR (Status
)) {
221 return EFI_OUT_OF_RESOURCES
;
224 SetMem (FtwBuffer
, FtwBufferSize
, (UINT8
) 0xff);
225 CopyMem (FtwBuffer
, Buffer
, BufferSize
);
230 Status
= FtwLiteProtocol
->Write (
235 &FtwBufferSize
, // NumBytes,
239 gBS
->FreePool (FtwBuffer
);