TianoCore EDK2 master
Loading...
Searching...
No Matches
Reclaim.c
Go to the documentation of this file.
1
10#include "Variable.h"
11
32 OUT EFI_LBA *Lba,
33 OUT UINTN *Offset
34 )
35{
36 EFI_STATUS Status;
37 EFI_PHYSICAL_ADDRESS FvbBaseAddress;
39 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
40 EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry;
41 UINT32 LbaIndex;
42
43 Fvb = NULL;
44 *Lba = (EFI_LBA)(-1);
45 *Offset = 0;
46
47 //
48 // Get the proper FVB protocol.
49 //
50 Status = GetFvbInfoByAddress (Address, NULL, &Fvb);
51 if (EFI_ERROR (Status)) {
52 return Status;
53 }
54
55 //
56 // Get the Base Address of FV.
57 //
58 Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);
59 if (EFI_ERROR (Status)) {
60 return Status;
61 }
62
63 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbBaseAddress);
64
65 //
66 // Get the (LBA, Offset) of Address.
67 //
68 if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {
69 //
70 // BUGBUG: Assume one FV has one type of BlockLength.
71 //
72 FvbMapEntry = &FwVolHeader->BlockMap[0];
73 for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {
74 if (Address < (FvbBaseAddress + FvbMapEntry->Length * LbaIndex)) {
75 //
76 // Found the (Lba, Offset).
77 //
78 *Lba = LbaIndex - 1;
79 *Offset = (UINTN)(Address - (FvbBaseAddress + FvbMapEntry->Length * (LbaIndex - 1)));
80 return EFI_SUCCESS;
81 }
82 }
83 }
84
85 return EFI_ABORTED;
86}
87
105 IN EFI_PHYSICAL_ADDRESS VariableBase,
106 IN VARIABLE_STORE_HEADER *VariableBuffer
107 )
108{
109 EFI_STATUS Status;
110 EFI_HANDLE FvbHandle;
111 EFI_LBA VarLba;
112 UINTN VarOffset;
113 UINTN FtwBufferSize;
115
116 //
117 // Locate fault tolerant write protocol.
118 //
119 Status = GetFtwProtocol ((VOID **)&FtwProtocol);
120 if (EFI_ERROR (Status)) {
121 return EFI_NOT_FOUND;
122 }
123
124 //
125 // Locate Fvb handle by address.
126 //
127 Status = GetFvbInfoByAddress (VariableBase, &FvbHandle, NULL);
128 if (EFI_ERROR (Status)) {
129 return Status;
130 }
131
132 //
133 // Get LBA and Offset by address.
134 //
135 Status = GetLbaAndOffsetByAddress (VariableBase, &VarLba, &VarOffset);
136 if (EFI_ERROR (Status)) {
137 return EFI_ABORTED;
138 }
139
140 FtwBufferSize = ((VARIABLE_STORE_HEADER *)((UINTN)VariableBase))->Size;
141 ASSERT (FtwBufferSize == VariableBuffer->Size);
142
143 //
144 // FTW write record.
145 //
146 Status = FtwProtocol->Write (
147 FtwProtocol,
148 VarLba, // LBA
149 VarOffset, // Offset
150 FtwBufferSize, // NumBytes
151 NULL, // PrivateData NULL
152 FvbHandle, // Fvb Handle
153 (VOID *)VariableBuffer // write buffer
154 );
155
156 return Status;
157}
UINT64 UINTN
EFI_STATUS GetFtwProtocol(OUT VOID **FtwProtocol)
Definition: VariableDxe.c:150
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
EFI_STATUS GetLbaAndOffsetByAddress(IN EFI_PHYSICAL_ADDRESS Address, OUT EFI_LBA *Lba, OUT UINTN *Offset)
Definition: Reclaim.c:30
EFI_STATUS FtwVariableSpace(IN EFI_PHYSICAL_ADDRESS VariableBase, IN VARIABLE_STORE_HEADER *VariableBuffer)
Definition: Reclaim.c:104
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
UINT64 EFI_LBA
Definition: UefiBaseType.h:45
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS GetFvbInfoByAddress(IN EFI_PHYSICAL_ADDRESS Address, OUT EFI_HANDLE *FvbHandle OPTIONAL, OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvbProtocol OPTIONAL)
Definition: Variable.c:3811
EFI_FV_BLOCK_MAP_ENTRY BlockMap[1]