]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/EdkFvbServiceLib/Fvb.c
Move Crc32GuidedSectionExtraction from Protocol to Guid directory
[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
677472aa 200 //\r
bac86c0d 201 // Check the FVB can be accessed in RUNTIME, The FVBs in FVB handle list come from two ways:\r
202 // 1) Dxe Core. (FVB information is transferred from FV HOB). 2) FVB driver. The FVB produced\r
203 // Dxe core is used to discovery DXE driver and dispatch. These FVBs can only be accessed in\r
204 // boot time. FVB driver will discovery all FV in FLASH and these FVBs can be accessed in\r
205 // runtime. The FVB itself produced by FVB driver is allocated in runtime memory. So we can\r
677472aa 206 // determine the what FVB can be accessed in RUNTIME by judging whether FVB itself is allocated\r
207 // in RUNTIME memory.\r
208 //\r
209 mFvbEntry[UpdateIndex].IsRuntimeAccess = IsRuntimeMemory (mFvbEntry[UpdateIndex].Fvb);\r
210 }\r
211}\r
212\r
213/**\r
214 Convert all pointers in mFvbEntry after ExitBootServices.\r
215\r
216 @param Event The Event that is being processed\r
217 @param Context Event Context\r
218\r
219**/\r
220VOID\r
221EFIAPI\r
222FvbVirtualAddressChangeNotifyEvent (\r
223 IN EFI_EVENT Event,\r
224 IN VOID *Context\r
225 )\r
226{\r
227 UINTN Index;\r
bac86c0d 228\r
677472aa 229 if (mFvbEntry != NULL) {\r
230 for (Index = 0; Index < MAX_FVB_COUNT; Index++) {\r
231 if (!mFvbEntry[Index].IsRuntimeAccess) {\r
232 continue;\r
233 }\r
234\r
bac86c0d 235 if (mFvbEntry[Index].Fvb != NULL) {\r
677472aa 236 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetBlockSize);\r
237 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress);\r
238 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetAttributes);\r
239 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->SetAttributes);\r
240 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Read);\r
241 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Write);\r
242 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->EraseBlocks);\r
243 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb);\r
244 }\r
677472aa 245 }\r
246\r
247 EfiConvertPointer (0x0, (VOID **) &mFvbEntry);\r
248 }\r
249}\r
250\r
bac86c0d 251\r
677472aa 252/**\r
253 Library constructor function entry.\r
254\r
48557c65 255 @param ImageHandle The handle of image who call this library.\r
677472aa 256 @param SystemTable The point of System Table.\r
257\r
48557c65 258 @retval EFI_SUCESS Success construct this library.\r
259 @retval Others Fail to construct this library.\r
677472aa 260**/\r
261EFI_STATUS\r
262EFIAPI\r
263FvbLibInitialize (\r
264 IN EFI_HANDLE ImageHandle,\r
265 IN EFI_SYSTEM_TABLE *SystemTable\r
266 )\r
267{\r
bac86c0d 268 EFI_STATUS Status;\r
269 \r
270 mFvbEntry = AllocateRuntimeZeroPool (sizeof (FVB_ENTRY) * MAX_FVB_COUNT);\r
271 ASSERT (mFvbEntry != NULL);\r
677472aa 272\r
bac86c0d 273 //\r
274 // Register FvbNotificationEvent () notify function.\r
275 // \r
677472aa 276 EfiCreateProtocolNotifyEvent (\r
277 &gEfiFirmwareVolumeBlockProtocolGuid,\r
278 TPL_CALLBACK,\r
279 FvbNotificationEvent,\r
280 NULL,\r
281 &mFvbRegistration\r
282 );\r
283\r
284 //\r
285 // Register SetVirtualAddressMap () notify function\r
286 //\r
01a5c994 287 Status = gBS->CreateEventEx (\r
288 EVT_NOTIFY_SIGNAL,\r
677472aa 289 TPL_NOTIFY,\r
290 FvbVirtualAddressChangeNotifyEvent,\r
291 NULL,\r
01a5c994 292 &gEfiEventVirtualAddressChangeGuid,\r
677472aa 293 &mSetVirtualMapChangedEvent\r
294 );\r
295 ASSERT_EFI_ERROR (Status);\r
296\r
bac86c0d 297 return Status;\r
677472aa 298}\r
299\r
300//\r
301// =============================================================================\r
302// The following functions wrap Fvb protocol in the Runtime Lib functions.\r
303// The Instance translates into Fvb instance. The Fvb order defined by HOBs and\r
304// thus the sequence of FVB protocol addition define Instance.\r
305//\r
677472aa 306\r
307/**\r
308 Reads specified number of bytes into a buffer from the specified block.\r
309\r
310 The EfiFvbReadBlock() function reads the requested number of bytes from\r
311 the requested block in the specified firmware volume and stores them in\r
312 the provided buffer. Implementations should be mindful that the firmware\r
313 volume might be in the ReadDisabled state. If it is in this state, the \r
314 EfiFvbReadBlock() function must return the status code EFI_ACCESS_DENIED\r
315 without modifying the contents of the buffer.\r
316 \r
317 The EfiFvbReadBlock() function must also prevent spanning block boundaries.\r
318 If a read is requested that would span a block boundary, the read must read\r
319 up to the boundary but not beyond. The output parameter NumBytes must be\r
320 set to correctly indicate the number of bytes actually read. \r
321 The caller must be aware that a read may be partially completed.\r
322\r
323 If NumBytes is NULL, then ASSERT().\r
324\r
325 If Buffer is NULL, then ASSERT().\r
326\r
327 @param[in] Instance The FV instance to be read from.\r
328 @param[in] Lba The logical block address to be read from\r
329 @param[in] Offset The offset relative to the block, at which to begin reading.\r
330 @param[in, out] NumBytes Pointer to a UINTN. On input, *NumBytes contains the total\r
331 size of the buffer. On output, it contains the actual number\r
332 of bytes read.\r
333 @param[out] Buffer Pointer to a caller allocated buffer that will be\r
334 used to hold the data read.\r
335\r
bac86c0d 336 @retval EFI_SUCCESS The firmware volume was read successfully and contents are in Buffer.\r
337 @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. On output, NumBytes contains\r
338 the total number of bytes returned in Buffer.\r
677472aa 339 @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state.\r
340 @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read.\r
bac86c0d 341 @retval EFI_INVALID_PARAMETER Invalid parameter, Instance is larger than the max FVB number. Lba index\r
342 is larger than the last block of the firmware volume. Offset is larger\r
343 than the block size.\r
677472aa 344\r
345**/\r
346EFI_STATUS\r
bac86c0d 347EFIAPI\r
677472aa 348EfiFvbReadBlock (\r
349 IN UINTN Instance,\r
350 IN EFI_LBA Lba,\r
351 IN UINTN Offset,\r
352 IN OUT UINTN *NumBytes,\r
353 OUT UINT8 *Buffer\r
354 )\r
355{\r
356 ASSERT (NumBytes != NULL);\r
357 ASSERT (Buffer != NULL);\r
358 \r
359 if (Instance >= mFvbCount) {\r
360 return EFI_INVALID_PARAMETER;\r
361 }\r
362\r
363 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
364 return EFI_INVALID_PARAMETER;\r
365 }\r
366\r
367 return mFvbEntry[Instance].Fvb->Read (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);\r
368}\r
369\r
370/**\r
371 Writes specified number of bytes from the input buffer to the block\r
372\r
373 The EfiFvbWriteBlock() function writes the specified number of bytes\r
374 from the provided buffer to the specified block and offset in the \r
375 requested firmware volume. \r
376\r
377 If the firmware volume is sticky write, the caller must ensure that\r
378 all the bits of the specified range to write are in the EFI_FVB_ERASE_POLARITY\r
379 state before calling the EfiFvbWriteBlock() function, or else the \r
380 result will be unpredictable. This unpredictability arises because,\r
381 for a sticky-write firmware volume, a write may negate a bit in the \r
382 EFI_FVB_ERASE_POLARITY state but it cannot flip it back again. In \r
383 general, before calling the EfiFvbWriteBlock() function, the caller\r
384 should call the EfiFvbEraseBlock() function first to erase the specified\r
385 block to write. A block erase cycle will transition bits from the\r
386 (NOT)EFI_FVB_ERASE_POLARITY state back to the EFI_FVB_ERASE_POLARITY state.\r
387 Implementations should be mindful that the firmware volume might be \r
388 in the WriteDisabled state. If it is in this state, the EfiFvbWriteBlock()\r
389 function must return the status code EFI_ACCESS_DENIED without modifying\r
390 the contents of the firmware volume.\r
391 \r
392 The EfiFvbWriteBlock() function must also prevent spanning block boundaries.\r
393 If a write is requested that spans a block boundary, the write must store\r
394 up to the boundary but not beyond. The output parameter NumBytes must be \r
395 set to correctly indicate the number of bytes actually written. The caller\r
396 must be aware that a write may be partially completed.\r
397 All writes, partial or otherwise, must be fully flushed to the hardware \r
398 before the EfiFvbWriteBlock() function returns. \r
399 \r
400 If NumBytes is NULL, then ASSERT().\r
401\r
48557c65 402 @param Instance The FV instance to be written to.\r
403 @param Lba The starting logical block index to write.\r
404 @param Offset The offset relative to the block to write.\r
677472aa 405 @param NumBytes Pointer to a UINTN. On input, *NumBytes contains\r
406 the total size of the buffer. On output, it contains\r
407 the actual number of bytes written.\r
408 @param Buffer Pointer to a caller allocated buffer that contains\r
409 the source for the write\r
410\r
411 @retval EFI_SUCCESS The firmware volume was written successfully.\r
412 @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. \r
413 On output, NumBytes contains the total number of bytes actually written.\r
bac86c0d 414 @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.\r
677472aa 415 @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written.\r
416 @retval EFI_INVALID_PARAMETER Invalid parameter, Instance is larger than the max FVB number. \r
417 Lba index is larger than the last block of the firmware volume.\r
418 Offset is larger than the block size.\r
419**/\r
420EFI_STATUS\r
bac86c0d 421EFIAPI\r
677472aa 422EfiFvbWriteBlock (\r
423 IN UINTN Instance,\r
424 IN EFI_LBA Lba,\r
425 IN UINTN Offset,\r
426 IN OUT UINTN *NumBytes,\r
427 IN UINT8 *Buffer\r
428 )\r
429{\r
430 ASSERT (NumBytes != NULL);\r
431 \r
432 if (Instance >= mFvbCount) {\r
433 return EFI_INVALID_PARAMETER;\r
434 }\r
435\r
436 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
437 return EFI_INVALID_PARAMETER;\r
438 }\r
439\r
440 return mFvbEntry[Instance].Fvb->Write (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);\r
441}\r
442\r
bac86c0d 443\r
677472aa 444/**\r
445 Erases and initializes a firmware volume block.\r
446\r
447 The EfiFvbEraseBlock() function erases one block specified by Lba.\r
448 Implementations should be mindful that the firmware volume might \r
449 be in the WriteDisabled state. If it is in this state, the EfiFvbEraseBlock()\r
450 function must return the status code EFI_ACCESS_DENIED without \r
451 modifying the contents of the firmware volume. If Instance is \r
452 larger than the max FVB number, or Lba index is larger than the\r
453 last block of the firmware volume, this function return the status\r
454 code EFI_INVALID_PARAMETER.\r
455 \r
456 All calls to EfiFvbEraseBlock() must be fully flushed to the \r
457 hardware before this function returns. \r
458\r
459 @param[in] Instance The FV instance to be erased.\r
460 @param[in] Lba The logical block index to be erased from.\r
461 \r
462 @retval EFI_SUCCESS The erase request was successfully completed.\r
463 @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state.\r
464 @retval EFI_DEVICE_ERROR The block device is not functioning correctly and\r
465 could not be written. The firmware device may \r
466 have been partially erased.\r
467 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max\r
468 FVB number. Lba index is larger than the last block\r
469 of the firmware volume. \r
470\r
471**/\r
472EFI_STATUS\r
bac86c0d 473EFIAPI\r
677472aa 474EfiFvbEraseBlock (\r
475 IN UINTN Instance,\r
476 IN EFI_LBA Lba\r
477 )\r
478{\r
479 if (Instance >= mFvbCount) {\r
480 return EFI_INVALID_PARAMETER;\r
481 }\r
482\r
483 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
484 return EFI_INVALID_PARAMETER;\r
485 }\r
486\r
487 return mFvbEntry[Instance].Fvb->EraseBlocks (mFvbEntry[Instance].Fvb, Lba, 1, EFI_LBA_LIST_TERMINATOR);\r
488}\r
489\r
bac86c0d 490\r
677472aa 491/**\r
492 Retrieves the attributes and current settings of the specified block, \r
493 returns resulting attributes in output parameter.\r
494\r
495 The EfiFvbGetAttributes() function retrieves the attributes and current\r
496 settings of the block specified by Instance. If Instance is larger than\r
497 the max FVB number, this function returns the status code EFI_INVALID_PARAMETER.\r
498\r
499 If Attributes is NULL, then ASSERT().\r
500\r
501 @param[in] Instance The FV instance to be operated.\r
502 @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the\r
503 attributes and current settings are returned.\r
504\r
505 @retval EFI_EFI_SUCCESS The firmware volume attributes were returned.\r
506 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. \r
507**/\r
508EFI_STATUS\r
bac86c0d 509EFIAPI\r
677472aa 510EfiFvbGetVolumeAttributes (\r
511 IN UINTN Instance,\r
512 OUT EFI_FVB_ATTRIBUTES_2 *Attributes\r
513 )\r
514{\r
515 ASSERT (Attributes != NULL);\r
516 \r
517 if (Instance >= mFvbCount) {\r
518 return EFI_INVALID_PARAMETER;\r
519 }\r
520\r
521 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
522 return EFI_INVALID_PARAMETER;\r
523 }\r
524\r
525 return mFvbEntry[Instance].Fvb->GetAttributes (mFvbEntry[Instance].Fvb, Attributes);\r
526}\r
527\r
bac86c0d 528\r
677472aa 529/**\r
530 Modify the attributes and current settings of the specified block\r
531 according to the input parameter.\r
532\r
533 The EfiFvbSetAttributes() function sets configurable firmware volume\r
534 attributes and returns the new settings of the firmware volume specified\r
535 by Instance. If Instance is larger than the max FVB number, this function\r
536 returns the status code EFI_INVALID_PARAMETER.\r
537\r
538 If Attributes is NULL, then ASSERT().\r
539\r
540 @param[in] Instance The FV instance to be operated.\r
541 @param[in, out]Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2\r
542 that contains the desired firmware volume settings. \r
543 On successful return, it contains the new settings of the firmware volume.\r
544\r
545 @retval EFI_EFI_SUCCESS The firmware volume attributes were modified successfully.\r
546 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number.\r
547\r
548**/\r
549EFI_STATUS\r
bac86c0d 550EFIAPI\r
677472aa 551EfiFvbSetVolumeAttributes (\r
552 IN UINTN Instance,\r
553 IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes\r
554 )\r
555{\r
556 ASSERT (Attributes != NULL);\r
557 \r
558 if (Instance >= mFvbCount) {\r
559 return EFI_INVALID_PARAMETER;\r
560 }\r
561\r
562 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
563 return EFI_INVALID_PARAMETER;\r
564 }\r
565\r
566 return mFvbEntry[Instance].Fvb->SetAttributes (mFvbEntry[Instance].Fvb, Attributes);\r
567}\r
568\r
bac86c0d 569\r
677472aa 570/**\r
571 Retrieves the physical address of the specified memory mapped FV.\r
572\r
573 Retrieve the base address of a memory-mapped firmware volume specified by Instance.\r
574 If Instance is larger than the max FVB number, this function returns the status \r
575 code EFI_INVALID_PARAMETER.\r
576 \r
577 If BaseAddress is NULL, then ASSERT().\r
578\r
579 @param[in] Instance The FV instance to be operated.\r
580 @param[out] BaseAddress Pointer to a caller allocated EFI_PHYSICAL_ADDRESS \r
581 that on successful return, contains the base address\r
582 of the firmware volume. \r
583\r
584 @retval EFI_EFI_SUCCESS The firmware volume base address is returned.\r
585 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. \r
586\r
587**/\r
588EFI_STATUS\r
bac86c0d 589EFIAPI\r
677472aa 590EfiFvbGetPhysicalAddress (\r
591 IN UINTN Instance,\r
592 OUT EFI_PHYSICAL_ADDRESS *BaseAddress\r
593 )\r
594{\r
595 ASSERT (BaseAddress != NULL);\r
596 \r
597 if (Instance >= mFvbCount) {\r
598 return EFI_INVALID_PARAMETER;\r
599 }\r
600\r
601 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
602 return EFI_INVALID_PARAMETER;\r
603 }\r
604\r
605 return mFvbEntry[Instance].Fvb->GetPhysicalAddress (mFvbEntry[Instance].Fvb, BaseAddress);\r
606}\r
607\r
bac86c0d 608\r
677472aa 609/**\r
610 Retrieve the block size of the specified fv.\r
611 \r
612 The EfiFvbGetBlockSize() function retrieves the size of the requested block. \r
613 It also returns the number of additional blocks with the identical size. \r
614 If Instance is larger than the max FVB number, or Lba index is larger than\r
615 the last block of the firmware volume, this function return the status code\r
616 EFI_INVALID_PARAMETER.\r
617\r
bac86c0d 618 If BlockSize is NULL, then ASSERT().\r
677472aa 619 \r
620 If NumOfBlocks is NULL, then ASSERT().\r
621\r
622 @param[in] Instance The FV instance to be operated.\r
623 @param[in] Lba Indicates which block to return the size for.\r
624 @param[out] BlockSize Pointer to a caller-allocated UINTN in which the\r
625 size of the block is returned.\r
626 @param[out] NumOfBlocks Pointer to a caller-allocated UINTN in which the \r
627 number of consecutive blocks, starting with Lba, \r
628 is returned. All blocks in this range have a size of BlockSize.\r
629\r
630 @retval EFI_EFI_SUCCESS The firmware volume base address is returned.\r
631 @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number.\r
632 Lba index is larger than the last block of the firmware volume.\r
633\r
634**/\r
635EFI_STATUS\r
bac86c0d 636EFIAPI\r
677472aa 637EfiFvbGetBlockSize (\r
638 IN UINTN Instance,\r
639 IN EFI_LBA Lba,\r
640 OUT UINTN *BlockSize,\r
641 OUT UINTN *NumOfBlocks\r
642 )\r
643{\r
644 ASSERT (BlockSize != NULL);\r
645 ASSERT (NumOfBlocks != NULL);\r
646 \r
647 if (Instance >= mFvbCount) {\r
648 return EFI_INVALID_PARAMETER;\r
649 }\r
650\r
651 if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) {\r
652 return EFI_INVALID_PARAMETER;\r
653 }\r
654\r
655 return mFvbEntry[Instance].Fvb->GetBlockSize (mFvbEntry[Instance].Fvb, Lba, BlockSize, NumOfBlocks);\r
656}\r