]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/EdkFvbServiceLib/Fvb.c
Patch to remove STATIC modifier. This is on longer recommended by EFI Framework codin...
[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
30ae98da 30EFI_EVENT mSetVirtualMapChangedEvent = NULL;\r
677472aa 31\r
32//\r
33// Lib will ASSERT if more FVB devices than this are added to the system.\r
34//\r
30ae98da 35FVB_ENTRY *mFvbEntry;\r
36EFI_EVENT mFvbRegistration;\r
37UINTN mFvbCount;\r
677472aa 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
677472aa 138VOID\r
139EFIAPI\r
140FvbNotificationEvent (\r
141 IN EFI_EVENT Event,\r
142 IN VOID *Context\r
143 )\r
144{\r
145 EFI_STATUS Status;\r
146 UINTN BufferSize;\r
147 EFI_HANDLE Handle;\r
148 UINTN Index;\r
149 UINTN UpdateIndex;\r
150\r
151 while (TRUE) {\r
152 BufferSize = sizeof (Handle);\r
153 Status = gBS->LocateHandle (\r
154 ByRegisterNotify,\r
155 &gEfiFirmwareVolumeBlockProtocolGuid,\r
156 mFvbRegistration,\r
157 &BufferSize,\r
158 &Handle\r
159 );\r
160 if (EFI_ERROR (Status)) {\r
161 //\r
162 // Exit Path of While Loop....\r
163 //\r
164 break;\r
165 }\r
166\r
167 UpdateIndex = MAX_FVB_COUNT;\r
168 for (Index = 0; Index < mFvbCount; Index++) {\r
169 if (mFvbEntry[Index].Handle == Handle) {\r
170 //\r
171 // If the handle is already in the table just update the protocol\r
172 //\r
173 UpdateIndex = Index;\r
174 break;\r
175 }\r
176 }\r
177\r
178 if (UpdateIndex == MAX_FVB_COUNT) {\r
179 //\r
180 // Use the next free slot for a new entry\r
181 //\r
182 UpdateIndex = mFvbCount++;\r
183 //\r
184 // Check the UpdateIndex whether exceed the maximum value.\r
185 //\r
186 ASSERT (UpdateIndex < MAX_FVB_COUNT);\r
187 mFvbEntry[UpdateIndex].Handle = Handle;\r
188 }\r
189 //\r
190 // The array does not have enough entries\r
191 //\r
192 ASSERT (UpdateIndex < MAX_FVB_COUNT);\r
193\r
194 //\r
195 // Get the interface pointer and if it's ours, skip it\r
196 //\r
197 Status = gBS->HandleProtocol (\r
198 Handle,\r
199 &gEfiFirmwareVolumeBlockProtocolGuid,\r
200 (VOID **) &mFvbEntry[UpdateIndex].Fvb\r
201 );\r
202 ASSERT_EFI_ERROR (Status);\r
203\r
204 Status = gBS->HandleProtocol (\r
205 Handle,\r
206 &gEfiFvbExtensionProtocolGuid,\r
207 (VOID **) &mFvbEntry[UpdateIndex].FvbExtension\r
208 );\r
209 if (Status != EFI_SUCCESS) {\r
210 mFvbEntry[UpdateIndex].FvbExtension = NULL;\r
211 }\r
212\r
213 //\r
214 // Check the FVB can be accessed in RUNTIME, The FVBs in FVB handle list comes\r
215 // from two way:\r
216 // 1) Dxe Core. (FVB information is transferred from FV HOB).\r
217 // 2) FVB driver.\r
218 // The FVB produced Dxe core is used for discoverying DXE driver and dispatch. These\r
219 // FVBs can only be accessed in boot time.\r
220 // FVB driver will discovery all FV in FLASH and these FVBs can be accessed in runtime.\r
221 // The FVB itself produced by FVB driver is allocated in runtime memory. So we can\r
222 // determine the what FVB can be accessed in RUNTIME by judging whether FVB itself is allocated\r
223 // in RUNTIME memory.\r
224 //\r
225 mFvbEntry[UpdateIndex].IsRuntimeAccess = IsRuntimeMemory (mFvbEntry[UpdateIndex].Fvb);\r
226 }\r
227}\r
228\r
229/**\r
230 Convert all pointers in mFvbEntry after ExitBootServices.\r
231\r
232 @param Event The Event that is being processed\r
233 @param Context Event Context\r
234\r
235**/\r
236VOID\r
237EFIAPI\r
238FvbVirtualAddressChangeNotifyEvent (\r
239 IN EFI_EVENT Event,\r
240 IN VOID *Context\r
241 )\r
242{\r
243 UINTN Index;\r
244 if (mFvbEntry != NULL) {\r
245 for (Index = 0; Index < MAX_FVB_COUNT; Index++) {\r
246 if (!mFvbEntry[Index].IsRuntimeAccess) {\r
247 continue;\r
248 }\r
249\r
250 if (NULL != mFvbEntry[Index].Fvb) {\r
251 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetBlockSize);\r
252 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress);\r
253 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetAttributes);\r
254 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->SetAttributes);\r
255 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Read);\r
256 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Write);\r
257 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->EraseBlocks);\r
258 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb);\r
259 }\r
260\r
261 if (NULL != mFvbEntry[Index].FvbExtension) {\r
262 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension->EraseFvbCustomBlock);\r
263 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension);\r
264 }\r
265 }\r
266\r
267 EfiConvertPointer (0x0, (VOID **) &mFvbEntry);\r
268 }\r
269}\r
270\r
271/**\r
272 Library constructor function entry.\r
273\r
274 @param ImageHandle The handle of image who call this libary.\r
275 @param SystemTable The point of System Table.\r
276\r
277 @retval EFI_SUCESS Sucess construct this library.\r
278 @retval Others Fail to contruct this libary.\r
279**/\r
280EFI_STATUS\r
281EFIAPI\r
282FvbLibInitialize (\r
283 IN EFI_HANDLE ImageHandle,\r
284 IN EFI_SYSTEM_TABLE *SystemTable\r
285 )\r
286{\r
287 UINTN Status;\r
288 mFvbCount = 0;\r
289\r
290 Status = gBS->AllocatePool (\r
291 EfiRuntimeServicesData,\r
292 (UINTN) sizeof (FVB_ENTRY) * MAX_FVB_COUNT,\r
293 (VOID *) &mFvbEntry\r
294 );\r
295\r
296 if (EFI_ERROR (Status)) {\r
297 return Status;\r
298 }\r
299\r
300 ZeroMem (mFvbEntry, sizeof (FVB_ENTRY) * MAX_FVB_COUNT);\r
301\r
302 EfiCreateProtocolNotifyEvent (\r
303 &gEfiFirmwareVolumeBlockProtocolGuid,\r
304 TPL_CALLBACK,\r
305 FvbNotificationEvent,\r
306 NULL,\r
307 &mFvbRegistration\r
308 );\r
309\r
310 //\r
311 // Register SetVirtualAddressMap () notify function\r
312 //\r
313 Status = gBS->CreateEvent (\r
314 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
315 TPL_NOTIFY,\r
316 FvbVirtualAddressChangeNotifyEvent,\r
317 NULL,\r
318 &mSetVirtualMapChangedEvent\r
319 );\r
320 ASSERT_EFI_ERROR (Status);\r
321\r
322 return EFI_SUCCESS;\r
323}\r
324\r
325//\r
326// =============================================================================\r
327// The following functions wrap Fvb protocol in the Runtime Lib functions.\r
328// The Instance translates into Fvb instance. The Fvb order defined by HOBs and\r
329// thus the sequence of FVB protocol addition define Instance.\r
330//\r
331// EfiFvbInitialize () must be called before any of the following functions\r
332// must be called.\r
333// =============================================================================\r
334//\r
335\r
336/**\r
337 Reads specified number of bytes into a buffer from the specified block.\r
338\r
339 The EfiFvbReadBlock() function reads the requested number of bytes from\r
340 the requested block in the specified firmware volume and stores them in\r
341 the provided buffer. Implementations should be mindful that the firmware\r
342 volume might be in the ReadDisabled state. If it is in this state, the \r
343 EfiFvbReadBlock() function must return the status code EFI_ACCESS_DENIED\r
344 without modifying the contents of the buffer.\r
345 \r
346 The EfiFvbReadBlock() function must also prevent spanning block boundaries.\r
347 If a read is requested that would span a block boundary, the read must read\r
348 up to the boundary but not beyond. The output parameter NumBytes must be\r
349 set to correctly indicate the number of bytes actually read. \r
350 The caller must be aware that a read may be partially completed.\r
351\r
352 If NumBytes is NULL, then ASSERT().\r
353\r
354 If Buffer is NULL, then ASSERT().\r
355\r
356 @param[in] Instance The FV instance to be read from.\r
357 @param[in] Lba The logical block address to be read from\r
358 @param[in] Offset The offset relative to the block, at which to begin reading.\r
359 @param[in, out] NumBytes Pointer to a UINTN. On input, *NumBytes contains the total\r
360 size of the buffer. On output, it contains the actual number\r
361 of bytes read.\r
362 @param[out] Buffer Pointer to a caller allocated buffer that will be\r
363 used to hold the data read.\r
364\r
365 @retval EFI_SUCCESS The firmware volume was read successfully and contents are in Buffer.\r
366 @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. On output, NumBytes contains the total number of bytes returned in Buffer.\r
367 @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state.\r
368 @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read.\r
369 @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
370\r
371**/\r
372EFI_STATUS\r
373EfiFvbReadBlock (\r
374 IN UINTN Instance,\r
375 IN EFI_LBA Lba,\r
376 IN UINTN Offset,\r
377 IN OUT UINTN *NumBytes,\r
378 OUT UINT8 *Buffer\r
379 )\r
380{\r
381 ASSERT (NumBytes != NULL);\r
382 ASSERT (Buffer != NULL);\r
383 \r
384 if (Instance >= mFvbCount) {\r
385 return EFI_INVALID_PARAMETER;\r
386 }\r
387\r
388 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
389 return EFI_INVALID_PARAMETER;\r
390 }\r
391\r
392 return mFvbEntry[Instance].Fvb->Read (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);\r
393}\r
394\r
395/**\r
396 Writes specified number of bytes from the input buffer to the block\r
397\r
398 The EfiFvbWriteBlock() function writes the specified number of bytes\r
399 from the provided buffer to the specified block and offset in the \r
400 requested firmware volume. \r
401\r
402 If the firmware volume is sticky write, the caller must ensure that\r
403 all the bits of the specified range to write are in the EFI_FVB_ERASE_POLARITY\r
404 state before calling the EfiFvbWriteBlock() function, or else the \r
405 result will be unpredictable. This unpredictability arises because,\r
406 for a sticky-write firmware volume, a write may negate a bit in the \r
407 EFI_FVB_ERASE_POLARITY state but it cannot flip it back again. In \r
408 general, before calling the EfiFvbWriteBlock() function, the caller\r
409 should call the EfiFvbEraseBlock() function first to erase the specified\r
410 block to write. A block erase cycle will transition bits from the\r
411 (NOT)EFI_FVB_ERASE_POLARITY state back to the EFI_FVB_ERASE_POLARITY state.\r
412 Implementations should be mindful that the firmware volume might be \r
413 in the WriteDisabled state. If it is in this state, the EfiFvbWriteBlock()\r
414 function must return the status code EFI_ACCESS_DENIED without modifying\r
415 the contents of the firmware volume.\r
416 \r
417 The EfiFvbWriteBlock() function must also prevent spanning block boundaries.\r
418 If a write is requested that spans a block boundary, the write must store\r
419 up to the boundary but not beyond. The output parameter NumBytes must be \r
420 set to correctly indicate the number of bytes actually written. The caller\r
421 must be aware that a write may be partially completed.\r
422 All writes, partial or otherwise, must be fully flushed to the hardware \r
423 before the EfiFvbWriteBlock() function returns. \r
424 \r
425 If NumBytes is NULL, then ASSERT().\r
426\r
427 @param Instance The FV instance to be written to\r
428 @param Lba The starting logical block index to write to\r
429 @param Offset The offset relative to the block, at which to begin writting.\r
430 @param NumBytes Pointer to a UINTN. On input, *NumBytes contains\r
431 the total size of the buffer. On output, it contains\r
432 the actual number of bytes written.\r
433 @param Buffer Pointer to a caller allocated buffer that contains\r
434 the source for the write\r
435\r
436 @retval EFI_SUCCESS The firmware volume was written successfully.\r
437 @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. \r
438 On output, NumBytes contains the total number of bytes actually written.\r
439 @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.\r
440 @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written.\r
441 @retval EFI_INVALID_PARAMETER Invalid parameter, Instance is larger than the max FVB number. \r
442 Lba index is larger than the last block of the firmware volume.\r
443 Offset is larger than the block size.\r
444**/\r
445EFI_STATUS\r
446EfiFvbWriteBlock (\r
447 IN UINTN Instance,\r
448 IN EFI_LBA Lba,\r
449 IN UINTN Offset,\r
450 IN OUT UINTN *NumBytes,\r
451 IN UINT8 *Buffer\r
452 )\r
453{\r
454 ASSERT (NumBytes != NULL);\r
455 \r
456 if (Instance >= mFvbCount) {\r
457 return EFI_INVALID_PARAMETER;\r
458 }\r
459\r
460 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
461 return EFI_INVALID_PARAMETER;\r
462 }\r
463\r
464 return mFvbEntry[Instance].Fvb->Write (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);\r
465}\r
466\r
467/**\r
468 Erases and initializes a firmware volume block.\r
469\r
470 The EfiFvbEraseBlock() function erases one block specified by Lba.\r
471 Implementations should be mindful that the firmware volume might \r
472 be in the WriteDisabled state. If it is in this state, the EfiFvbEraseBlock()\r
473 function must return the status code EFI_ACCESS_DENIED without \r
474 modifying the contents of the firmware volume. If Instance is \r
475 larger than the max FVB number, or Lba index is larger than the\r
476 last block of the firmware volume, this function return the status\r
477 code EFI_INVALID_PARAMETER.\r
478 \r
479 All calls to EfiFvbEraseBlock() must be fully flushed to the \r
480 hardware before this function returns. \r
481\r
482 @param[in] Instance The FV instance to be erased.\r
483 @param[in] Lba The logical block index to be erased from.\r
484 \r
485 @retval EFI_SUCCESS The erase request was successfully completed.\r
486 @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.\r
487 @retval EFI_DEVICE_ERROR The block device is not functioning correctly and\r
488 could not be written. The firmware device may \r
489 have been partially erased.\r
490 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max\r
491 FVB number. Lba index is larger than the last block\r
492 of the firmware volume. \r
493\r
494**/\r
495EFI_STATUS\r
496EfiFvbEraseBlock (\r
497 IN UINTN Instance,\r
498 IN EFI_LBA Lba\r
499 )\r
500{\r
501 if (Instance >= mFvbCount) {\r
502 return EFI_INVALID_PARAMETER;\r
503 }\r
504\r
505 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
506 return EFI_INVALID_PARAMETER;\r
507 }\r
508\r
509 return mFvbEntry[Instance].Fvb->EraseBlocks (mFvbEntry[Instance].Fvb, Lba, 1, EFI_LBA_LIST_TERMINATOR);\r
510}\r
511\r
512/**\r
513 Retrieves the attributes and current settings of the specified block, \r
514 returns resulting attributes in output parameter.\r
515\r
516 The EfiFvbGetAttributes() function retrieves the attributes and current\r
517 settings of the block specified by Instance. If Instance is larger than\r
518 the max FVB number, this function returns the status code EFI_INVALID_PARAMETER.\r
519\r
520 If Attributes is NULL, then ASSERT().\r
521\r
522 @param[in] Instance The FV instance to be operated.\r
523 @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the\r
524 attributes and current settings are returned.\r
525\r
526 @retval EFI_EFI_SUCCESS The firmware volume attributes were returned.\r
527 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. \r
528**/\r
529EFI_STATUS\r
530EfiFvbGetVolumeAttributes (\r
531 IN UINTN Instance,\r
532 OUT EFI_FVB_ATTRIBUTES_2 *Attributes\r
533 )\r
534{\r
535 ASSERT (Attributes != NULL);\r
536 \r
537 if (Instance >= mFvbCount) {\r
538 return EFI_INVALID_PARAMETER;\r
539 }\r
540\r
541 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
542 return EFI_INVALID_PARAMETER;\r
543 }\r
544\r
545 return mFvbEntry[Instance].Fvb->GetAttributes (mFvbEntry[Instance].Fvb, Attributes);\r
546}\r
547\r
548/**\r
549 Modify the attributes and current settings of the specified block\r
550 according to the input parameter.\r
551\r
552 The EfiFvbSetAttributes() function sets configurable firmware volume\r
553 attributes and returns the new settings of the firmware volume specified\r
554 by Instance. If Instance is larger than the max FVB number, this function\r
555 returns the status code EFI_INVALID_PARAMETER.\r
556\r
557 If Attributes is NULL, then ASSERT().\r
558\r
559 @param[in] Instance The FV instance to be operated.\r
560 @param[in, out]Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2\r
561 that contains the desired firmware volume settings. \r
562 On successful return, it contains the new settings of the firmware volume.\r
563\r
564 @retval EFI_EFI_SUCCESS The firmware volume attributes were modified successfully.\r
565 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number.\r
566\r
567**/\r
568EFI_STATUS\r
569EfiFvbSetVolumeAttributes (\r
570 IN UINTN Instance,\r
571 IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes\r
572 )\r
573{\r
574 ASSERT (Attributes != NULL);\r
575 \r
576 if (Instance >= mFvbCount) {\r
577 return EFI_INVALID_PARAMETER;\r
578 }\r
579\r
580 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
581 return EFI_INVALID_PARAMETER;\r
582 }\r
583\r
584 return mFvbEntry[Instance].Fvb->SetAttributes (mFvbEntry[Instance].Fvb, Attributes);\r
585}\r
586\r
587/**\r
588 Retrieves the physical address of the specified memory mapped FV.\r
589\r
590 Retrieve the base address of a memory-mapped firmware volume specified by Instance.\r
591 If Instance is larger than the max FVB number, this function returns the status \r
592 code EFI_INVALID_PARAMETER.\r
593 \r
594 If BaseAddress is NULL, then ASSERT().\r
595\r
596 @param[in] Instance The FV instance to be operated.\r
597 @param[out] BaseAddress Pointer to a caller allocated EFI_PHYSICAL_ADDRESS \r
598 that on successful return, contains the base address\r
599 of the firmware volume. \r
600\r
601 @retval EFI_EFI_SUCCESS The firmware volume base address is returned.\r
602 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. \r
603\r
604**/\r
605EFI_STATUS\r
606EfiFvbGetPhysicalAddress (\r
607 IN UINTN Instance,\r
608 OUT EFI_PHYSICAL_ADDRESS *BaseAddress\r
609 )\r
610{\r
611 ASSERT (BaseAddress != NULL);\r
612 \r
613 if (Instance >= mFvbCount) {\r
614 return EFI_INVALID_PARAMETER;\r
615 }\r
616\r
617 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
618 return EFI_INVALID_PARAMETER;\r
619 }\r
620\r
621 return mFvbEntry[Instance].Fvb->GetPhysicalAddress (mFvbEntry[Instance].Fvb, BaseAddress);\r
622}\r
623\r
624/**\r
625 Retrieve the block size of the specified fv.\r
626 \r
627 The EfiFvbGetBlockSize() function retrieves the size of the requested block. \r
628 It also returns the number of additional blocks with the identical size. \r
629 If Instance is larger than the max FVB number, or Lba index is larger than\r
630 the last block of the firmware volume, this function return the status code\r
631 EFI_INVALID_PARAMETER.\r
632\r
633 If BlockSize is NULL, then ASSERT().\r
634 \r
635 If NumOfBlocks is NULL, then ASSERT().\r
636\r
637 @param[in] Instance The FV instance to be operated.\r
638 @param[in] Lba Indicates which block to return the size for.\r
639 @param[out] BlockSize Pointer to a caller-allocated UINTN in which the\r
640 size of the block is returned.\r
641 @param[out] NumOfBlocks Pointer to a caller-allocated UINTN in which the \r
642 number of consecutive blocks, starting with Lba, \r
643 is returned. All blocks in this range have a size of BlockSize.\r
644\r
645 @retval EFI_EFI_SUCCESS The firmware volume base address is returned.\r
646 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number.\r
647 Lba index is larger than the last block of the firmware volume.\r
648\r
649**/\r
650EFI_STATUS\r
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
672/**\r
673 Erases and initializes a specified range of a firmware volume.\r
674\r
675 The EfiFvbEraseCustomBlockRange() function erases the specified range in the firmware\r
676 volume index by Instance. If Instance is larger than the max FVB number, StartLba or \r
677 LastLba index is larger than the last block of the firmware volume, StartLba > LastLba\r
678 or StartLba equal to LastLba but OffsetStartLba > OffsetLastLba, this function return \r
679 the status code EFI_INVALID_PARAMETER.\r
680\r
681 @param[in] Instance The FV instance to be operated.\r
682 @param[in] StartLba The starting logical block index to be erased.\r
683 @param[in] OffsetStartLba Offset into the starting block at which to \r
684 begin erasing. \r
685 @param[in] LastLba The last logical block index to be erased.\r
686 @param[in] OffsetLastLba Offset into the last block at which to end erasing. \r
687\r
688 @retval EFI_EFI_SUCCESS Successfully erase custom block range\r
689 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. \r
690 @retval EFI_UNSUPPORTED Firmware volume block device has no this capability.\r
691\r
692**/\r
693EFI_STATUS\r
694EfiFvbEraseCustomBlockRange (\r
695 IN UINTN Instance,\r
696 IN EFI_LBA StartLba,\r
697 IN UINTN OffsetStartLba,\r
698 IN EFI_LBA LastLba,\r
699 IN UINTN OffsetLastLba\r
700 )\r
701{\r
702 if (Instance >= mFvbCount) {\r
703 return EFI_INVALID_PARAMETER;\r
704 }\r
705\r
706 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
707 return EFI_INVALID_PARAMETER;\r
708 }\r
709\r
710 if (!(mFvbEntry[Instance].FvbExtension)) {\r
711 return EFI_UNSUPPORTED;\r
712 }\r
713\r
714 if (!(mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock)) {\r
715 return EFI_UNSUPPORTED;\r
716 }\r
717\r
718 return mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock (\r
719 mFvbEntry[Instance].FvbExtension,\r
720 StartLba,\r
721 OffsetStartLba,\r
722 LastLba,\r
723 OffsetLastLba\r
724 );\r
725}\r