]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/VariableRuntimeDxe/reclaim.c
add ia32 and x64 direcotry for EdkFvbServiceLib
[mirror_edk2.git] / MdeModulePkg / Universal / VariableRuntimeDxe / reclaim.c
CommitLineData
94774441 1/*++\r
2\r
3Copyright (c) 2006 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 reclaim.c\r
15\r
16Abstract:\r
17\r
18 Handles non-volatile variable store garbage collection, using FTW\r
19 (Fault Tolerant Write) protocol.\r
20\r
21Revision History\r
22\r
23--*/\r
24\r
25\r
26#include "reclaim.h"\r
27#include "Common/Variable.h"\r
28\r
29EFI_STATUS\r
30GetFvbHandleByAddress (\r
31 IN EFI_PHYSICAL_ADDRESS Address,\r
32 OUT EFI_HANDLE *FvbHandle\r
33 )\r
34{\r
35 EFI_STATUS Status;\r
36 EFI_HANDLE *HandleBuffer;\r
37 UINTN HandleCount;\r
38 UINTN Index;\r
39 EFI_PHYSICAL_ADDRESS FvbBaseAddress;\r
40 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
41 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
42\r
43 *FvbHandle = NULL;\r
44 //\r
45 // Locate all handles of Fvb protocol\r
46 //\r
47 Status = gBS->LocateHandleBuffer (\r
48 ByProtocol,\r
49 &gEfiFirmwareVolumeBlockProtocolGuid,\r
50 NULL,\r
51 &HandleCount,\r
52 &HandleBuffer\r
53 );\r
54 if (EFI_ERROR (Status)) {\r
55 return EFI_NOT_FOUND;\r
56 }\r
57 //\r
58 // Get the FVB to access variable store\r
59 //\r
60 for (Index = 0; Index < HandleCount; Index += 1) {\r
61 Status = gBS->HandleProtocol (\r
62 HandleBuffer[Index],\r
63 &gEfiFirmwareVolumeBlockProtocolGuid,\r
64 (VOID **) &Fvb\r
65 );\r
66 if (EFI_ERROR (Status)) {\r
67 Status = EFI_NOT_FOUND;\r
68 break;\r
69 }\r
70 //\r
71 // Compare the address and select the right one\r
72 //\r
73 Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);\r
74 if (EFI_ERROR (Status)) {\r
75 continue;\r
76 }\r
77\r
78 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);\r
79 if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + FwVolHeader->FvLength))) {\r
80 *FvbHandle = HandleBuffer[Index];\r
81 Status = EFI_SUCCESS;\r
82 break;\r
83 }\r
84 }\r
85\r
86 FreePool (HandleBuffer);\r
87 return Status;\r
88}\r
89\r
90STATIC\r
91EFI_STATUS\r
92GetLbaAndOffsetByAddress (\r
93 IN EFI_PHYSICAL_ADDRESS Address,\r
94 OUT EFI_LBA *Lba,\r
95 OUT UINTN *Offset\r
96 )\r
97{\r
a190687a 98 EFI_STATUS Status;\r
99 EFI_HANDLE FvbHandle;\r
100 EFI_PHYSICAL_ADDRESS FvbBaseAddress;\r
101 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
102 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
103 EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry;\r
104 UINT32 LbaIndex;\r
94774441 105\r
106 *Lba = (EFI_LBA) (-1);\r
107 *Offset = 0;\r
108\r
109 //\r
110 // Get the proper FVB\r
111 //\r
112 Status = GetFvbHandleByAddress (Address, &FvbHandle);\r
113 if (EFI_ERROR (Status)) {\r
114 return Status;\r
115 }\r
116\r
117 Status = gBS->HandleProtocol (\r
118 FvbHandle,\r
119 &gEfiFirmwareVolumeBlockProtocolGuid,\r
120 (VOID **) &Fvb\r
121 );\r
122 if (EFI_ERROR (Status)) {\r
123 return Status;\r
124 }\r
125 //\r
126 // Get the Base Address of FV\r
127 //\r
128 Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);\r
129 if (EFI_ERROR (Status)) {\r
130 return Status;\r
131 }\r
132\r
a190687a 133 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);\r
94774441 134\r
135 //\r
136 // Get the (LBA, Offset) of Address\r
137 //\r
138 if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + FwVolHeader->FvLength))) {\r
139 if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {\r
140 //\r
141 // BUGBUG: Assume one FV has one type of BlockLength\r
142 //\r
a190687a 143 FvbMapEntry = &FwVolHeader->BlockMap[0];\r
94774441 144 for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {\r
145 if (Address < (FvbBaseAddress + FvbMapEntry->Length * LbaIndex)) {\r
146 //\r
147 // Found the (Lba, Offset)\r
148 //\r
149 *Lba = LbaIndex - 1;\r
150 *Offset = (UINTN) (Address - (FvbBaseAddress + FvbMapEntry->Length * (LbaIndex - 1)));\r
151 return EFI_SUCCESS;\r
a190687a 152 }\r
94774441 153 }\r
154 }\r
155 }\r
156\r
157 return EFI_ABORTED;\r
158}\r
159\r
160EFI_STATUS\r
161FtwVariableSpace (\r
162 IN EFI_PHYSICAL_ADDRESS VariableBase,\r
163 IN UINT8 *Buffer,\r
164 IN UINTN BufferSize\r
165 )\r
166/*++\r
167\r
168Routine Description:\r
169 Write a buffer to Variable space, in the working block.\r
170\r
171Arguments:\r
172 FvbHandle - Indicates a handle to FVB to access variable store\r
173 Buffer - Point to the input buffer\r
174 BufferSize - The number of bytes of the input Buffer\r
175\r
176Returns:\r
177 EFI_SUCCESS - The function completed successfully\r
178 EFI_ABORTED - The function could not complete successfully\r
179 EFI_NOT_FOUND - Locate FVB protocol by handle fails\r
180\r
181--*/\r
182{\r
183 EFI_STATUS Status;\r
184 EFI_HANDLE FvbHandle;\r
185 EFI_FTW_LITE_PROTOCOL *FtwLiteProtocol;\r
186 EFI_LBA VarLba;\r
187 UINTN VarOffset;\r
188 UINT8 *FtwBuffer;\r
189 UINTN FtwBufferSize;\r
190\r
191 //\r
192 // Locate fault tolerant write protocol\r
193 //\r
194 Status = gBS->LocateProtocol (\r
195 &gEfiFaultTolerantWriteLiteProtocolGuid,\r
196 NULL,\r
197 (VOID **) &FtwLiteProtocol\r
198 );\r
199 if (EFI_ERROR (Status)) {\r
200 return EFI_NOT_FOUND;\r
201 }\r
202 //\r
203 // Locate Fvb handle by address\r
204 //\r
205 Status = GetFvbHandleByAddress (VariableBase, &FvbHandle);\r
206 if (EFI_ERROR (Status)) {\r
207 return Status;\r
208 }\r
209 //\r
210 // Get LBA and Offset by address\r
211 //\r
212 Status = GetLbaAndOffsetByAddress (VariableBase, &VarLba, &VarOffset);\r
213 if (EFI_ERROR (Status)) {\r
214 return EFI_ABORTED;\r
215 }\r
216 //\r
217 // Prepare for the variable data\r
218 //\r
219 FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;\r
220 FtwBuffer = AllocateRuntimePool (FtwBufferSize);\r
221 if (FtwBuffer == NULL) {\r
222 return EFI_OUT_OF_RESOURCES;\r
223 }\r
224\r
225 SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff);\r
226 CopyMem (FtwBuffer, Buffer, BufferSize);\r
227\r
228 //\r
229 // FTW write record\r
230 //\r
231 Status = FtwLiteProtocol->Write (\r
232 FtwLiteProtocol,\r
233 FvbHandle,\r
234 VarLba, // LBA\r
235 VarOffset, // Offset\r
236 &FtwBufferSize, // NumBytes,\r
237 FtwBuffer\r
238 );\r
239\r
240 FreePool (FtwBuffer);\r
241 return Status;\r
242}\r