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