677472aa |
1 | /**@file\r |
677472aa |
2 | Firmware Volume Block Protocol Runtime Interface Abstraction\r |
3 | And FVB Extension protocol Runtime Interface Abstraction\r |
4 | \r |
5 | mFvbEntry is an array of Handle Fvb pairs. The Fvb Lib Instance matches the\r |
6 | index in the mFvbEntry array. This should be the same sequence as the FVB's\r |
7 | were described in the HOB. We have to remember the handle so we can tell if\r |
48557c65 |
8 | the protocol has been reinstalled and it needs updating.\r |
677472aa |
9 | \r |
677472aa |
10 | \r |
11 | Copyright (c) 2006 - 2008, Intel Corporation\r |
12 | All rights reserved. This program and the accompanying materials\r |
13 | are licensed and made available under the terms and conditions of the BSD License\r |
14 | which accompanies this distribution. The full text of the license may be found at\r |
15 | http://opensource.org/licenses/bsd-license.php\r |
16 | \r |
17 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r |
18 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r |
19 | \r |
20 | **/\r |
21 | \r |
22 | \r |
23 | #include "Fvb.h"\r |
24 | \r |
bac86c0d |
25 | \r |
677472aa |
26 | //\r |
27 | // Event for Set Virtual Map Changed Event\r |
28 | //\r |
30ae98da |
29 | EFI_EVENT mSetVirtualMapChangedEvent = NULL;\r |
677472aa |
30 | \r |
31 | //\r |
32 | // Lib will ASSERT if more FVB devices than this are added to the system.\r |
33 | //\r |
bac86c0d |
34 | FVB_ENTRY *mFvbEntry = NULL;\r |
35 | EFI_EVENT mFvbRegistration = NULL;\r |
36 | UINTN mFvbCount = 0;\r |
677472aa |
37 | \r |
38 | /**\r |
39 | Check whether an address is runtime memory or not.\r |
40 | \r |
41 | @param Address The Address being checked.\r |
42 | \r |
43 | @retval TRUE The address is runtime memory.\r |
44 | @retval FALSE The address is not runtime memory.\r |
45 | **/\r |
46 | BOOLEAN\r |
47 | IsRuntimeMemory (\r |
48 | IN VOID *Address\r |
49 | )\r |
50 | {\r |
51 | EFI_STATUS Status;\r |
52 | UINT8 TmpMemoryMap[1];\r |
53 | UINTN MapKey;\r |
54 | UINTN DescriptorSize;\r |
55 | UINT32 DescriptorVersion;\r |
56 | UINTN MemoryMapSize;\r |
57 | EFI_MEMORY_DESCRIPTOR *MemoryMap;\r |
58 | EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;\r |
59 | BOOLEAN IsRuntime;\r |
60 | UINTN Index;\r |
61 | \r |
62 | IsRuntime = FALSE;\r |
63 | \r |
64 | //\r |
65 | // Get System MemoryMapSize\r |
66 | //\r |
67 | MemoryMapSize = 1;\r |
68 | Status = gBS->GetMemoryMap (\r |
69 | &MemoryMapSize,\r |
70 | (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap,\r |
71 | &MapKey,\r |
72 | &DescriptorSize,\r |
73 | &DescriptorVersion\r |
74 | );\r |
75 | ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r |
76 | //\r |
77 | // Enlarge space here, because we will allocate pool now.\r |
78 | //\r |
79 | MemoryMapSize += EFI_PAGE_SIZE;\r |
bac86c0d |
80 | MemoryMap = AllocatePool (MemoryMapSize);\r |
81 | ASSERT (MemoryMap != NULL);\r |
677472aa |
82 | \r |
83 | //\r |
84 | // Get System MemoryMap\r |
85 | //\r |
86 | Status = gBS->GetMemoryMap (\r |
87 | &MemoryMapSize,\r |
88 | MemoryMap,\r |
89 | &MapKey,\r |
90 | &DescriptorSize,\r |
91 | &DescriptorVersion\r |
92 | );\r |
93 | ASSERT_EFI_ERROR (Status);\r |
94 | \r |
95 | MemoryMapPtr = MemoryMap;\r |
96 | //\r |
97 | // Search the request Address\r |
98 | //\r |
99 | for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {\r |
100 | if (((EFI_PHYSICAL_ADDRESS)(UINTN)Address >= MemoryMap->PhysicalStart) &&\r |
101 | ((EFI_PHYSICAL_ADDRESS)(UINTN)Address < MemoryMap->PhysicalStart\r |
102 | + LShiftU64 (MemoryMap->NumberOfPages, EFI_PAGE_SHIFT))) {\r |
103 | //\r |
104 | // Found it\r |
105 | //\r |
bac86c0d |
106 | if ((MemoryMap->Attribute & EFI_MEMORY_RUNTIME) != 0) {\r |
677472aa |
107 | IsRuntime = TRUE;\r |
108 | }\r |
109 | break;\r |
110 | }\r |
111 | //\r |
112 | // Get next item\r |
113 | //\r |
bac86c0d |
114 | MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN) MemoryMap + DescriptorSize);\r |
677472aa |
115 | }\r |
116 | \r |
117 | //\r |
118 | // Done\r |
119 | //\r |
bac86c0d |
120 | FreePool (MemoryMapPtr);\r |
677472aa |
121 | \r |
122 | return IsRuntime;\r |
123 | }\r |
124 | \r |
bac86c0d |
125 | \r |
677472aa |
126 | /**\r |
127 | Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is\r |
128 | reinstalled.\r |
129 | \r |
130 | @param Event The Event that is being processed\r |
131 | @param Context Event Context\r |
132 | \r |
133 | **/\r |
677472aa |
134 | VOID\r |
135 | EFIAPI\r |
136 | FvbNotificationEvent (\r |
137 | IN EFI_EVENT Event,\r |
138 | IN VOID *Context\r |
139 | )\r |
140 | {\r |
141 | EFI_STATUS Status;\r |
142 | UINTN BufferSize;\r |
143 | EFI_HANDLE Handle;\r |
144 | UINTN Index;\r |
145 | UINTN UpdateIndex;\r |
146 | \r |
147 | while (TRUE) {\r |
148 | BufferSize = sizeof (Handle);\r |
149 | Status = gBS->LocateHandle (\r |
150 | ByRegisterNotify,\r |
151 | &gEfiFirmwareVolumeBlockProtocolGuid,\r |
152 | mFvbRegistration,\r |
153 | &BufferSize,\r |
154 | &Handle\r |
155 | );\r |
156 | if (EFI_ERROR (Status)) {\r |
157 | //\r |
158 | // Exit Path of While Loop....\r |
159 | //\r |
160 | break;\r |
161 | }\r |
162 | \r |
163 | UpdateIndex = MAX_FVB_COUNT;\r |
164 | for (Index = 0; Index < mFvbCount; Index++) {\r |
165 | if (mFvbEntry[Index].Handle == Handle) {\r |
166 | //\r |
167 | // If the handle is already in the table just update the protocol\r |
168 | //\r |
169 | UpdateIndex = Index;\r |
170 | break;\r |
171 | }\r |
172 | }\r |
173 | \r |
174 | if (UpdateIndex == MAX_FVB_COUNT) {\r |
175 | //\r |
176 | // Use the next free slot for a new entry\r |
177 | //\r |
178 | UpdateIndex = mFvbCount++;\r |
179 | //\r |
180 | // Check the UpdateIndex whether exceed the maximum value.\r |
181 | //\r |
182 | ASSERT (UpdateIndex < MAX_FVB_COUNT);\r |
183 | mFvbEntry[UpdateIndex].Handle = Handle;\r |
184 | }\r |
185 | //\r |
186 | // The array does not have enough entries\r |
187 | //\r |
188 | ASSERT (UpdateIndex < MAX_FVB_COUNT);\r |
189 | \r |
190 | //\r |
191 | // Get the interface pointer and if it's ours, skip it\r |
192 | //\r |
193 | Status = gBS->HandleProtocol (\r |
194 | Handle,\r |
195 | &gEfiFirmwareVolumeBlockProtocolGuid,\r |
196 | (VOID **) &mFvbEntry[UpdateIndex].Fvb\r |
197 | );\r |
198 | ASSERT_EFI_ERROR (Status);\r |
199 | \r |
200 | Status = gBS->HandleProtocol (\r |
201 | Handle,\r |
202 | &gEfiFvbExtensionProtocolGuid,\r |
203 | (VOID **) &mFvbEntry[UpdateIndex].FvbExtension\r |
204 | );\r |
205 | if (Status != EFI_SUCCESS) {\r |
206 | mFvbEntry[UpdateIndex].FvbExtension = NULL;\r |
207 | }\r |
208 | \r |
209 | //\r |
bac86c0d |
210 | // Check the FVB can be accessed in RUNTIME, The FVBs in FVB handle list come from two ways:\r |
211 | // 1) Dxe Core. (FVB information is transferred from FV HOB). 2) FVB driver. The FVB produced\r |
212 | // Dxe core is used to discovery DXE driver and dispatch. These FVBs can only be accessed in\r |
213 | // boot time. FVB driver will discovery all FV in FLASH and these FVBs can be accessed in\r |
214 | // runtime. The FVB itself produced by FVB driver is allocated in runtime memory. So we can\r |
677472aa |
215 | // determine the what FVB can be accessed in RUNTIME by judging whether FVB itself is allocated\r |
216 | // in RUNTIME memory.\r |
217 | //\r |
218 | mFvbEntry[UpdateIndex].IsRuntimeAccess = IsRuntimeMemory (mFvbEntry[UpdateIndex].Fvb);\r |
219 | }\r |
220 | }\r |
221 | \r |
222 | /**\r |
223 | Convert all pointers in mFvbEntry after ExitBootServices.\r |
224 | \r |
225 | @param Event The Event that is being processed\r |
226 | @param Context Event Context\r |
227 | \r |
228 | **/\r |
229 | VOID\r |
230 | EFIAPI\r |
231 | FvbVirtualAddressChangeNotifyEvent (\r |
232 | IN EFI_EVENT Event,\r |
233 | IN VOID *Context\r |
234 | )\r |
235 | {\r |
236 | UINTN Index;\r |
bac86c0d |
237 | \r |
677472aa |
238 | if (mFvbEntry != NULL) {\r |
239 | for (Index = 0; Index < MAX_FVB_COUNT; Index++) {\r |
240 | if (!mFvbEntry[Index].IsRuntimeAccess) {\r |
241 | continue;\r |
242 | }\r |
243 | \r |
bac86c0d |
244 | if (mFvbEntry[Index].Fvb != NULL) {\r |
677472aa |
245 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetBlockSize);\r |
246 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress);\r |
247 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetAttributes);\r |
248 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->SetAttributes);\r |
249 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Read);\r |
250 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Write);\r |
251 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->EraseBlocks);\r |
252 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb);\r |
253 | }\r |
254 | \r |
bac86c0d |
255 | if (mFvbEntry[Index].FvbExtension != NULL) {\r |
677472aa |
256 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension->EraseFvbCustomBlock);\r |
257 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension);\r |
258 | }\r |
259 | }\r |
260 | \r |
261 | EfiConvertPointer (0x0, (VOID **) &mFvbEntry);\r |
262 | }\r |
263 | }\r |
264 | \r |
bac86c0d |
265 | \r |
677472aa |
266 | /**\r |
267 | Library constructor function entry.\r |
268 | \r |
48557c65 |
269 | @param ImageHandle The handle of image who call this library.\r |
677472aa |
270 | @param SystemTable The point of System Table.\r |
271 | \r |
48557c65 |
272 | @retval EFI_SUCESS Success construct this library.\r |
273 | @retval Others Fail to construct this library.\r |
677472aa |
274 | **/\r |
275 | EFI_STATUS\r |
276 | EFIAPI\r |
277 | FvbLibInitialize (\r |
278 | IN EFI_HANDLE ImageHandle,\r |
279 | IN EFI_SYSTEM_TABLE *SystemTable\r |
280 | )\r |
281 | {\r |
bac86c0d |
282 | EFI_STATUS Status;\r |
283 | \r |
284 | mFvbEntry = AllocateRuntimeZeroPool (sizeof (FVB_ENTRY) * MAX_FVB_COUNT);\r |
285 | ASSERT (mFvbEntry != NULL);\r |
677472aa |
286 | \r |
bac86c0d |
287 | //\r |
288 | // Register FvbNotificationEvent () notify function.\r |
289 | // \r |
677472aa |
290 | EfiCreateProtocolNotifyEvent (\r |
291 | &gEfiFirmwareVolumeBlockProtocolGuid,\r |
292 | TPL_CALLBACK,\r |
293 | FvbNotificationEvent,\r |
294 | NULL,\r |
295 | &mFvbRegistration\r |
296 | );\r |
297 | \r |
298 | //\r |
299 | // Register SetVirtualAddressMap () notify function\r |
300 | //\r |
01a5c994 |
301 | Status = gBS->CreateEventEx (\r |
302 | EVT_NOTIFY_SIGNAL,\r |
677472aa |
303 | TPL_NOTIFY,\r |
304 | FvbVirtualAddressChangeNotifyEvent,\r |
305 | NULL,\r |
01a5c994 |
306 | &gEfiEventVirtualAddressChangeGuid,\r |
677472aa |
307 | &mSetVirtualMapChangedEvent\r |
308 | );\r |
309 | ASSERT_EFI_ERROR (Status);\r |
310 | \r |
bac86c0d |
311 | return Status;\r |
677472aa |
312 | }\r |
313 | \r |
314 | //\r |
315 | // =============================================================================\r |
316 | // The following functions wrap Fvb protocol in the Runtime Lib functions.\r |
317 | // The Instance translates into Fvb instance. The Fvb order defined by HOBs and\r |
318 | // thus the sequence of FVB protocol addition define Instance.\r |
319 | //\r |
677472aa |
320 | \r |
321 | /**\r |
322 | Reads specified number of bytes into a buffer from the specified block.\r |
323 | \r |
324 | The EfiFvbReadBlock() function reads the requested number of bytes from\r |
325 | the requested block in the specified firmware volume and stores them in\r |
326 | the provided buffer. Implementations should be mindful that the firmware\r |
327 | volume might be in the ReadDisabled state. If it is in this state, the \r |
328 | EfiFvbReadBlock() function must return the status code EFI_ACCESS_DENIED\r |
329 | without modifying the contents of the buffer.\r |
330 | \r |
331 | The EfiFvbReadBlock() function must also prevent spanning block boundaries.\r |
332 | If a read is requested that would span a block boundary, the read must read\r |
333 | up to the boundary but not beyond. The output parameter NumBytes must be\r |
334 | set to correctly indicate the number of bytes actually read. \r |
335 | The caller must be aware that a read may be partially completed.\r |
336 | \r |
337 | If NumBytes is NULL, then ASSERT().\r |
338 | \r |
339 | If Buffer is NULL, then ASSERT().\r |
340 | \r |
341 | @param[in] Instance The FV instance to be read from.\r |
342 | @param[in] Lba The logical block address to be read from\r |
343 | @param[in] Offset The offset relative to the block, at which to begin reading.\r |
344 | @param[in, out] NumBytes Pointer to a UINTN. On input, *NumBytes contains the total\r |
345 | size of the buffer. On output, it contains the actual number\r |
346 | of bytes read.\r |
347 | @param[out] Buffer Pointer to a caller allocated buffer that will be\r |
348 | used to hold the data read.\r |
349 | \r |
bac86c0d |
350 | @retval EFI_SUCCESS The firmware volume was read successfully and contents are in Buffer.\r |
351 | @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. On output, NumBytes contains\r |
352 | the total number of bytes returned in Buffer.\r |
677472aa |
353 | @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state.\r |
354 | @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read.\r |
bac86c0d |
355 | @retval EFI_INVALID_PARAMETER Invalid parameter, Instance is larger than the max FVB number. Lba index\r |
356 | is larger than the last block of the firmware volume. Offset is larger\r |
357 | than the block size.\r |
677472aa |
358 | \r |
359 | **/\r |
360 | EFI_STATUS\r |
bac86c0d |
361 | EFIAPI\r |
677472aa |
362 | EfiFvbReadBlock (\r |
363 | IN UINTN Instance,\r |
364 | IN EFI_LBA Lba,\r |
365 | IN UINTN Offset,\r |
366 | IN OUT UINTN *NumBytes,\r |
367 | OUT UINT8 *Buffer\r |
368 | )\r |
369 | {\r |
370 | ASSERT (NumBytes != NULL);\r |
371 | ASSERT (Buffer != NULL);\r |
372 | \r |
373 | if (Instance >= mFvbCount) {\r |
374 | return EFI_INVALID_PARAMETER;\r |
375 | }\r |
376 | \r |
377 | if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r |
378 | return EFI_INVALID_PARAMETER;\r |
379 | }\r |
380 | \r |
381 | return mFvbEntry[Instance].Fvb->Read (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);\r |
382 | }\r |
383 | \r |
384 | /**\r |
385 | Writes specified number of bytes from the input buffer to the block\r |
386 | \r |
387 | The EfiFvbWriteBlock() function writes the specified number of bytes\r |
388 | from the provided buffer to the specified block and offset in the \r |
389 | requested firmware volume. \r |
390 | \r |
391 | If the firmware volume is sticky write, the caller must ensure that\r |
392 | all the bits of the specified range to write are in the EFI_FVB_ERASE_POLARITY\r |
393 | state before calling the EfiFvbWriteBlock() function, or else the \r |
394 | result will be unpredictable. This unpredictability arises because,\r |
395 | for a sticky-write firmware volume, a write may negate a bit in the \r |
396 | EFI_FVB_ERASE_POLARITY state but it cannot flip it back again. In \r |
397 | general, before calling the EfiFvbWriteBlock() function, the caller\r |
398 | should call the EfiFvbEraseBlock() function first to erase the specified\r |
399 | block to write. A block erase cycle will transition bits from the\r |
400 | (NOT)EFI_FVB_ERASE_POLARITY state back to the EFI_FVB_ERASE_POLARITY state.\r |
401 | Implementations should be mindful that the firmware volume might be \r |
402 | in the WriteDisabled state. If it is in this state, the EfiFvbWriteBlock()\r |
403 | function must return the status code EFI_ACCESS_DENIED without modifying\r |
404 | the contents of the firmware volume.\r |
405 | \r |
406 | The EfiFvbWriteBlock() function must also prevent spanning block boundaries.\r |
407 | If a write is requested that spans a block boundary, the write must store\r |
408 | up to the boundary but not beyond. The output parameter NumBytes must be \r |
409 | set to correctly indicate the number of bytes actually written. The caller\r |
410 | must be aware that a write may be partially completed.\r |
411 | All writes, partial or otherwise, must be fully flushed to the hardware \r |
412 | before the EfiFvbWriteBlock() function returns. \r |
413 | \r |
414 | If NumBytes is NULL, then ASSERT().\r |
415 | \r |
48557c65 |
416 | @param Instance The FV instance to be written to.\r |
417 | @param Lba The starting logical block index to write.\r |
418 | @param Offset The offset relative to the block to write.\r |
677472aa |
419 | @param NumBytes Pointer to a UINTN. On input, *NumBytes contains\r |
420 | the total size of the buffer. On output, it contains\r |
421 | the actual number of bytes written.\r |
422 | @param Buffer Pointer to a caller allocated buffer that contains\r |
423 | the source for the write\r |
424 | \r |
425 | @retval EFI_SUCCESS The firmware volume was written successfully.\r |
426 | @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. \r |
427 | On output, NumBytes contains the total number of bytes actually written.\r |
bac86c0d |
428 | @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.\r |
677472aa |
429 | @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written.\r |
430 | @retval EFI_INVALID_PARAMETER Invalid parameter, Instance is larger than the max FVB number. \r |
431 | Lba index is larger than the last block of the firmware volume.\r |
432 | Offset is larger than the block size.\r |
433 | **/\r |
434 | EFI_STATUS\r |
bac86c0d |
435 | EFIAPI\r |
677472aa |
436 | EfiFvbWriteBlock (\r |
437 | IN UINTN Instance,\r |
438 | IN EFI_LBA Lba,\r |
439 | IN UINTN Offset,\r |
440 | IN OUT UINTN *NumBytes,\r |
441 | IN UINT8 *Buffer\r |
442 | )\r |
443 | {\r |
444 | ASSERT (NumBytes != NULL);\r |
445 | \r |
446 | if (Instance >= mFvbCount) {\r |
447 | return EFI_INVALID_PARAMETER;\r |
448 | }\r |
449 | \r |
450 | if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r |
451 | return EFI_INVALID_PARAMETER;\r |
452 | }\r |
453 | \r |
454 | return mFvbEntry[Instance].Fvb->Write (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);\r |
455 | }\r |
456 | \r |
bac86c0d |
457 | \r |
677472aa |
458 | /**\r |
459 | Erases and initializes a firmware volume block.\r |
460 | \r |
461 | The EfiFvbEraseBlock() function erases one block specified by Lba.\r |
462 | Implementations should be mindful that the firmware volume might \r |
463 | be in the WriteDisabled state. If it is in this state, the EfiFvbEraseBlock()\r |
464 | function must return the status code EFI_ACCESS_DENIED without \r |
465 | modifying the contents of the firmware volume. If Instance is \r |
466 | larger than the max FVB number, or Lba index is larger than the\r |
467 | last block of the firmware volume, this function return the status\r |
468 | code EFI_INVALID_PARAMETER.\r |
469 | \r |
470 | All calls to EfiFvbEraseBlock() must be fully flushed to the \r |
471 | hardware before this function returns. \r |
472 | \r |
473 | @param[in] Instance The FV instance to be erased.\r |
474 | @param[in] Lba The logical block index to be erased from.\r |
475 | \r |
476 | @retval EFI_SUCCESS The erase request was successfully completed.\r |
477 | @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.\r |
478 | @retval EFI_DEVICE_ERROR The block device is not functioning correctly and\r |
479 | could not be written. The firmware device may \r |
480 | have been partially erased.\r |
481 | @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max\r |
482 | FVB number. Lba index is larger than the last block\r |
483 | of the firmware volume. \r |
484 | \r |
485 | **/\r |
486 | EFI_STATUS\r |
bac86c0d |
487 | EFIAPI\r |
677472aa |
488 | EfiFvbEraseBlock (\r |
489 | IN UINTN Instance,\r |
490 | IN EFI_LBA Lba\r |
491 | )\r |
492 | {\r |
493 | if (Instance >= mFvbCount) {\r |
494 | return EFI_INVALID_PARAMETER;\r |
495 | }\r |
496 | \r |
497 | if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r |
498 | return EFI_INVALID_PARAMETER;\r |
499 | }\r |
500 | \r |
501 | return mFvbEntry[Instance].Fvb->EraseBlocks (mFvbEntry[Instance].Fvb, Lba, 1, EFI_LBA_LIST_TERMINATOR);\r |
502 | }\r |
503 | \r |
bac86c0d |
504 | \r |
677472aa |
505 | /**\r |
506 | Retrieves the attributes and current settings of the specified block, \r |
507 | returns resulting attributes in output parameter.\r |
508 | \r |
509 | The EfiFvbGetAttributes() function retrieves the attributes and current\r |
510 | settings of the block specified by Instance. If Instance is larger than\r |
511 | the max FVB number, this function returns the status code EFI_INVALID_PARAMETER.\r |
512 | \r |
513 | If Attributes is NULL, then ASSERT().\r |
514 | \r |
515 | @param[in] Instance The FV instance to be operated.\r |
516 | @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the\r |
517 | attributes and current settings are returned.\r |
518 | \r |
519 | @retval EFI_EFI_SUCCESS The firmware volume attributes were returned.\r |
520 | @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. \r |
521 | **/\r |
522 | EFI_STATUS\r |
bac86c0d |
523 | EFIAPI\r |
677472aa |
524 | EfiFvbGetVolumeAttributes (\r |
525 | IN UINTN Instance,\r |
526 | OUT EFI_FVB_ATTRIBUTES_2 *Attributes\r |
527 | )\r |
528 | {\r |
529 | ASSERT (Attributes != NULL);\r |
530 | \r |
531 | if (Instance >= mFvbCount) {\r |
532 | return EFI_INVALID_PARAMETER;\r |
533 | }\r |
534 | \r |
535 | if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r |
536 | return EFI_INVALID_PARAMETER;\r |
537 | }\r |
538 | \r |
539 | return mFvbEntry[Instance].Fvb->GetAttributes (mFvbEntry[Instance].Fvb, Attributes);\r |
540 | }\r |
541 | \r |
bac86c0d |
542 | \r |
677472aa |
543 | /**\r |
544 | Modify the attributes and current settings of the specified block\r |
545 | according to the input parameter.\r |
546 | \r |
547 | The EfiFvbSetAttributes() function sets configurable firmware volume\r |
548 | attributes and returns the new settings of the firmware volume specified\r |
549 | by Instance. If Instance is larger than the max FVB number, this function\r |
550 | returns the status code EFI_INVALID_PARAMETER.\r |
551 | \r |
552 | If Attributes is NULL, then ASSERT().\r |
553 | \r |
554 | @param[in] Instance The FV instance to be operated.\r |
555 | @param[in, out]Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2\r |
556 | that contains the desired firmware volume settings. \r |
557 | On successful return, it contains the new settings of the firmware volume.\r |
558 | \r |
559 | @retval EFI_EFI_SUCCESS The firmware volume attributes were modified successfully.\r |
560 | @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number.\r |
561 | \r |
562 | **/\r |
563 | EFI_STATUS\r |
bac86c0d |
564 | EFIAPI\r |
677472aa |
565 | EfiFvbSetVolumeAttributes (\r |
566 | IN UINTN Instance,\r |
567 | IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes\r |
568 | )\r |
569 | {\r |
570 | ASSERT (Attributes != NULL);\r |
571 | \r |
572 | if (Instance >= mFvbCount) {\r |
573 | return EFI_INVALID_PARAMETER;\r |
574 | }\r |
575 | \r |
576 | if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r |
577 | return EFI_INVALID_PARAMETER;\r |
578 | }\r |
579 | \r |
580 | return mFvbEntry[Instance].Fvb->SetAttributes (mFvbEntry[Instance].Fvb, Attributes);\r |
581 | }\r |
582 | \r |
bac86c0d |
583 | \r |
677472aa |
584 | /**\r |
585 | Retrieves the physical address of the specified memory mapped FV.\r |
586 | \r |
587 | Retrieve the base address of a memory-mapped firmware volume specified by Instance.\r |
588 | If Instance is larger than the max FVB number, this function returns the status \r |
589 | code EFI_INVALID_PARAMETER.\r |
590 | \r |
591 | If BaseAddress is NULL, then ASSERT().\r |
592 | \r |
593 | @param[in] Instance The FV instance to be operated.\r |
594 | @param[out] BaseAddress Pointer to a caller allocated EFI_PHYSICAL_ADDRESS \r |
595 | that on successful return, contains the base address\r |
596 | of the firmware volume. \r |
597 | \r |
598 | @retval EFI_EFI_SUCCESS The firmware volume base address is returned.\r |
599 | @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. \r |
600 | \r |
601 | **/\r |
602 | EFI_STATUS\r |
bac86c0d |
603 | EFIAPI\r |
677472aa |
604 | EfiFvbGetPhysicalAddress (\r |
605 | IN UINTN Instance,\r |
606 | OUT EFI_PHYSICAL_ADDRESS *BaseAddress\r |
607 | )\r |
608 | {\r |
609 | ASSERT (BaseAddress != NULL);\r |
610 | \r |
611 | if (Instance >= mFvbCount) {\r |
612 | return EFI_INVALID_PARAMETER;\r |
613 | }\r |
614 | \r |
615 | if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r |
616 | return EFI_INVALID_PARAMETER;\r |
617 | }\r |
618 | \r |
619 | return mFvbEntry[Instance].Fvb->GetPhysicalAddress (mFvbEntry[Instance].Fvb, BaseAddress);\r |
620 | }\r |
621 | \r |
bac86c0d |
622 | \r |
677472aa |
623 | /**\r |
624 | Retrieve the block size of the specified fv.\r |
625 | \r |
626 | The EfiFvbGetBlockSize() function retrieves the size of the requested block. \r |
627 | It also returns the number of additional blocks with the identical size. \r |
628 | If Instance is larger than the max FVB number, or Lba index is larger than\r |
629 | the last block of the firmware volume, this function return the status code\r |
630 | EFI_INVALID_PARAMETER.\r |
631 | \r |
bac86c0d |
632 | If BlockSize is NULL, then ASSERT().\r |
677472aa |
633 | \r |
634 | If NumOfBlocks is NULL, then ASSERT().\r |
635 | \r |
636 | @param[in] Instance The FV instance to be operated.\r |
637 | @param[in] Lba Indicates which block to return the size for.\r |
638 | @param[out] BlockSize Pointer to a caller-allocated UINTN in which the\r |
639 | size of the block is returned.\r |
640 | @param[out] NumOfBlocks Pointer to a caller-allocated UINTN in which the \r |
641 | number of consecutive blocks, starting with Lba, \r |
642 | is returned. All blocks in this range have a size of BlockSize.\r |
643 | \r |
644 | @retval EFI_EFI_SUCCESS The firmware volume base address is returned.\r |
645 | @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number.\r |
646 | Lba index is larger than the last block of the firmware volume.\r |
647 | \r |
648 | **/\r |
649 | EFI_STATUS\r |
bac86c0d |
650 | EFIAPI\r |
677472aa |
651 | EfiFvbGetBlockSize (\r |
652 | IN UINTN Instance,\r |
653 | IN EFI_LBA Lba,\r |
654 | OUT UINTN *BlockSize,\r |
655 | OUT UINTN *NumOfBlocks\r |
656 | )\r |
657 | {\r |
658 | ASSERT (BlockSize != NULL);\r |
659 | ASSERT (NumOfBlocks != NULL);\r |
660 | \r |
661 | if (Instance >= mFvbCount) {\r |
662 | return EFI_INVALID_PARAMETER;\r |
663 | }\r |
664 | \r |
665 | if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r |
666 | return EFI_INVALID_PARAMETER;\r |
667 | }\r |
668 | \r |
669 | return mFvbEntry[Instance].Fvb->GetBlockSize (mFvbEntry[Instance].Fvb, Lba, BlockSize, NumOfBlocks);\r |
670 | }\r |
671 | \r |
bac86c0d |
672 | \r |
677472aa |
673 | /**\r |
674 | Erases and initializes a specified range of a firmware volume.\r |
675 | \r |
676 | The EfiFvbEraseCustomBlockRange() function erases the specified range in the firmware\r |
677 | volume index by Instance. If Instance is larger than the max FVB number, StartLba or \r |
678 | LastLba index is larger than the last block of the firmware volume, StartLba > LastLba\r |
679 | or StartLba equal to LastLba but OffsetStartLba > OffsetLastLba, this function return \r |
680 | the status code EFI_INVALID_PARAMETER.\r |
681 | \r |
682 | @param[in] Instance The FV instance to be operated.\r |
683 | @param[in] StartLba The starting logical block index to be erased.\r |
684 | @param[in] OffsetStartLba Offset into the starting block at which to \r |
685 | begin erasing. \r |
686 | @param[in] LastLba The last logical block index to be erased.\r |
687 | @param[in] OffsetLastLba Offset into the last block at which to end erasing. \r |
688 | \r |
689 | @retval EFI_EFI_SUCCESS Successfully erase custom block range\r |
690 | @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. \r |
691 | @retval EFI_UNSUPPORTED Firmware volume block device has no this capability.\r |
692 | \r |
693 | **/\r |
694 | EFI_STATUS\r |
bac86c0d |
695 | EFIAPI\r |
677472aa |
696 | EfiFvbEraseCustomBlockRange (\r |
697 | IN UINTN Instance,\r |
698 | IN EFI_LBA StartLba,\r |
699 | IN UINTN OffsetStartLba,\r |
700 | IN EFI_LBA LastLba,\r |
701 | IN UINTN OffsetLastLba\r |
702 | )\r |
703 | {\r |
704 | if (Instance >= mFvbCount) {\r |
705 | return EFI_INVALID_PARAMETER;\r |
706 | }\r |
707 | \r |
708 | if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r |
709 | return EFI_INVALID_PARAMETER;\r |
710 | }\r |
711 | \r |
712 | if (!(mFvbEntry[Instance].FvbExtension)) {\r |
713 | return EFI_UNSUPPORTED;\r |
714 | }\r |
715 | \r |
716 | if (!(mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock)) {\r |
717 | return EFI_UNSUPPORTED;\r |
718 | }\r |
719 | \r |
720 | return mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock (\r |
721 | mFvbEntry[Instance].FvbExtension,\r |
722 | StartLba,\r |
723 | OffsetStartLba,\r |
724 | LastLba,\r |
725 | OffsetLastLba\r |
726 | );\r |
727 | }\r |