]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/EdkFvbServiceLib/Fvb.c
Coding style checked
[mirror_edk2.git] / MdeModulePkg / Library / EdkFvbServiceLib / Fvb.c
CommitLineData
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
11Copyright (c) 2006 - 2008, Intel Corporation\r
12All rights reserved. This program and the accompanying materials\r
13are licensed and made available under the terms and conditions of the BSD License\r
14which accompanies this distribution. The full text of the license may be found at\r
15http://opensource.org/licenses/bsd-license.php\r
16\r
17THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
18WITHOUT 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 29EFI_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 34FVB_ENTRY *mFvbEntry = NULL;\r
35EFI_EVENT mFvbRegistration = NULL;\r
36UINTN 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
46BOOLEAN\r
47IsRuntimeMemory (\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 134VOID\r
135EFIAPI\r
136FvbNotificationEvent (\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
229VOID\r
230EFIAPI\r
231FvbVirtualAddressChangeNotifyEvent (\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
275EFI_STATUS\r
276EFIAPI\r
277FvbLibInitialize (\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
360EFI_STATUS\r
bac86c0d 361EFIAPI\r
677472aa 362EfiFvbReadBlock (\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
434EFI_STATUS\r
bac86c0d 435EFIAPI\r
677472aa 436EfiFvbWriteBlock (\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
486EFI_STATUS\r
bac86c0d 487EFIAPI\r
677472aa 488EfiFvbEraseBlock (\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
522EFI_STATUS\r
bac86c0d 523EFIAPI\r
677472aa 524EfiFvbGetVolumeAttributes (\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
563EFI_STATUS\r
bac86c0d 564EFIAPI\r
677472aa 565EfiFvbSetVolumeAttributes (\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
602EFI_STATUS\r
bac86c0d 603EFIAPI\r
677472aa 604EfiFvbGetPhysicalAddress (\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
649EFI_STATUS\r
bac86c0d 650EFIAPI\r
677472aa 651EfiFvbGetBlockSize (\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
694EFI_STATUS\r
bac86c0d 695EFIAPI\r
677472aa 696EfiFvbEraseCustomBlockRange (\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
7b2207f0 712 if (mFvbEntry[Instance].FvbExtension == NULL) {\r
677472aa 713 return EFI_UNSUPPORTED;\r
714 }\r
715\r
7b2207f0 716 if (mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock == NULL) {\r
677472aa 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