]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Library/EdkFvbServiceLib/x64/Fvb.c
Add more check for index whether exceed maximum value of fv count.
[mirror_edk2.git] / EdkModulePkg / Library / EdkFvbServiceLib / x64 / Fvb.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 Fvb.c \r
15\r
16Abstract:\r
17\r
18 Firmware Volume Block Protocol Runtime Abstraction\r
19\r
20 mFvbEntry is an array of Handle Fvb pairs. The Fvb Lib Instance matches the \r
21 index in the mFvbEntry array. This should be the same sequence as the FVB's\r
22 were described in the HOB. We have to remember the handle so we can tell if \r
23 the protocol has been reinstalled and it needs updateing.\r
24\r
25 If you are using any of these lib functions.you must first call FvbInitialize ().\r
26\r
27Key:\r
28 FVB - Firmware Volume Block\r
29\r
30--*/\r
31\r
32#include "Fvb.h"\r
33\r
34//\r
35// Lib will ASSERT if more FVB devices than this are added to the system.\r
36//\r
37STATIC FVB_ENTRY *mFvbEntry;\r
0cc82df1 38// STATIC EFI_EVENT mFvbVirtualNotifyEvent;\r
878ddf1f 39STATIC EFI_EVENT mFvbRegistration;\r
0cc82df1 40// STATIC EFI_EVENT mEfiFvbVirtualNotifyEvent;\r
878ddf1f 41STATIC BOOLEAN mEfiFvbInitialized = FALSE;\r
42STATIC UINTN mFvbCount;\r
43\r
44STATIC\r
45VOID\r
46EFIAPI\r
47FvbNotificationEvent (\r
48 IN EFI_EVENT Event,\r
49 IN VOID *Context\r
50 )\r
51/*++\r
52\r
53Routine Description:\r
54 Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is\r
55 reinstalled.\r
56\r
57Arguments:\r
58\r
59 Event - The Event that is being processed\r
60 \r
61 Context - Event Context\r
62\r
63Returns: \r
64 None\r
65\r
66--*/\r
67{\r
68 EFI_STATUS Status;\r
69 UINTN BufferSize;\r
70 EFI_HANDLE Handle;\r
71 UINTN Index;\r
72 UINTN UpdateIndex;\r
73\r
74 while (TRUE) {\r
75 BufferSize = sizeof (Handle);\r
76 Status = gBS->LocateHandle (\r
77 ByRegisterNotify,\r
78 &gEfiFirmwareVolumeBlockProtocolGuid,\r
79 mFvbRegistration,\r
80 &BufferSize,\r
81 &Handle\r
82 );\r
83 if (EFI_ERROR (Status)) {\r
84 //\r
85 // Exit Path of While Loop....\r
86 //\r
87 break;\r
88 }\r
89\r
90 UpdateIndex = MAX_FVB_COUNT;\r
91 for (Index = 0; Index < mFvbCount; Index++) {\r
92 if (mFvbEntry[Index].Handle == Handle) {\r
93 //\r
94 // If the handle is already in the table just update the protocol\r
95 //\r
96 UpdateIndex = Index;\r
97 break;\r
98 }\r
99 }\r
100\r
101 if (UpdateIndex == MAX_FVB_COUNT) {\r
102 //\r
103 // Use the next free slot for a new entry\r
104 //\r
105 UpdateIndex = mFvbCount++;;\r
106 mFvbEntry[UpdateIndex].Handle = Handle;\r
107 }\r
108 //\r
109 // The array does not have enough entries\r
110 //\r
111 ASSERT (UpdateIndex < MAX_FVB_COUNT);\r
112\r
113 //\r
114 // Get the interface pointer and if it's ours, skip it\r
115 //\r
0cc82df1 116 Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&mFvbEntry[UpdateIndex].Fvb);\r
878ddf1f 117 ASSERT_EFI_ERROR (Status);\r
118\r
0cc82df1 119 Status = gBS->HandleProtocol (Handle, &gEfiFvbExtensionProtocolGuid, (VOID **)&mFvbEntry[UpdateIndex].FvbExtension);\r
878ddf1f 120 if (Status != EFI_SUCCESS) {\r
121 mFvbEntry[UpdateIndex].FvbExtension = NULL;\r
122 }\r
123 }\r
124}\r
125\r
126VOID\r
127EFIAPI\r
128FvbVirtualAddressChangeNotifyEvent (\r
129 IN EFI_EVENT Event,\r
130 IN VOID *Context\r
131 )\r
132/*++\r
133\r
134Routine Description:\r
135\r
136 Convert all pointers in mFvbEntry after ExitBootServices.\r
137\r
138Arguments:\r
139\r
140 Event - The Event that is being processed\r
141 \r
142 Context - Event Context\r
143\r
144Returns:\r
145\r
146 None\r
147\r
148--*/\r
149{\r
150 UINTN Index;\r
151 if (mFvbEntry != NULL) {\r
152 for (Index = 0; Index < MAX_FVB_COUNT; Index++) {\r
153 if (NULL != mFvbEntry[Index].Fvb) {\r
154 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetBlockSize);\r
155 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress);\r
156 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetVolumeAttributes);\r
157 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->SetVolumeAttributes);\r
158 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Read);\r
159 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Write);\r
160 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->EraseBlocks);\r
161 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb);\r
162 }\r
163\r
164 if (NULL != mFvbEntry[Index].FvbExtension) {\r
165 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension->EraseFvbCustomBlock);\r
166 EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension);\r
167 }\r
168 }\r
169\r
170 EfiConvertPointer (0x0, (VOID **) &mFvbEntry);\r
171 }\r
172}\r
173\r
174EFI_STATUS\r
175EFIAPI\r
176FvbLibInitialize (\r
177 IN EFI_HANDLE ImageHandle,\r
178 IN EFI_SYSTEM_TABLE *SystemTable\r
179 )\r
180/*++\r
181\r
182Routine Description:\r
183 Initialize globals and register Fvb Protocol notification function.\r
184\r
185Arguments:\r
186 None \r
187\r
188Returns: \r
189 EFI_SUCCESS\r
190\r
191--*/\r
192{\r
193 UINTN Status;\r
194 mFvbCount = 0;\r
195\r
196 Status = gBS->AllocatePool (\r
197 EfiRuntimeServicesData,\r
198 (UINTN) sizeof (FVB_ENTRY) * MAX_FVB_COUNT,\r
199 (VOID *) &mFvbEntry\r
200 );\r
201\r
202 if (EFI_ERROR (Status)) {\r
203 return Status;\r
204 }\r
205\r
206 ZeroMem (mFvbEntry, sizeof (FVB_ENTRY) * MAX_FVB_COUNT);\r
207\r
208 EfiCreateProtocolNotifyEvent (\r
209 &gEfiFirmwareVolumeBlockProtocolGuid,\r
210 EFI_TPL_CALLBACK,\r
211 FvbNotificationEvent,\r
212 NULL,\r
213 &mFvbRegistration\r
214 );\r
215\r
216 //\r
217 // Register SetVirtualAddressMap () notify function\r
218 //\r
219 // Status = gBS->CreateEvent (\r
220 // EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
221 // EFI_TPL_NOTIFY,\r
222 // EfiRuntimeLibFvbVirtualNotifyEvent,\r
223 // NULL,\r
224 // &mEfiFvbVirtualNotifyEvent\r
225 // );\r
226 // ASSERT_EFI_ERROR (Status);\r
227 //\r
228\r
229 //\r
230 // Register SetVirtualAddressMap () notify function\r
231 //\r
232\r
233 ASSERT_EFI_ERROR (Status);\r
234\r
235 mEfiFvbInitialized = TRUE;\r
236\r
237 return EFI_SUCCESS;\r
238}\r
239//\r
240// The following functions wrap Fvb protocol in the Runtime Lib functions.\r
241// The Instance translates into Fvb instance. The Fvb order defined by HOBs and\r
242// thus the sequence of FVB protocol addition define Instance.\r
243//\r
244// EfiFvbInitialize () must be called before any of the following functions\r
245// must be called.\r
246//\r
247\r
248EFI_STATUS\r
249EfiFvbReadBlock (\r
250 IN UINTN Instance,\r
251 IN EFI_LBA Lba,\r
252 IN UINTN Offset,\r
253 IN OUT UINTN *NumBytes,\r
254 IN UINT8 *Buffer\r
255 )\r
256/*++\r
257\r
258Routine Description:\r
259 Reads specified number of bytes into a buffer from the specified block\r
260\r
261Arguments:\r
262 Instance - The FV instance to be read from\r
263 Lba - The logical block address to be read from\r
264 Offset - Offset into the block at which to begin reading\r
265 NumBytes - Pointer that on input contains the total size of\r
266 the buffer. On output, it contains the total number\r
267 of bytes read\r
268 Buffer - Pointer to a caller allocated buffer that will be\r
269 used to hold the data read\r
270\r
271Returns: \r
272\r
273 Status code\r
274 \r
275 EFI_INVALID_PARAMETER - invalid parameter\r
276\r
277--*/\r
278{\r
279 if (Instance >= mFvbCount) {\r
280 return EFI_INVALID_PARAMETER;\r
281 }\r
282\r
283 return mFvbEntry[Instance].Fvb->Read (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);\r
284}\r
285\r
286EFI_STATUS\r
287EfiFvbWriteBlock (\r
288 IN UINTN Instance,\r
289 IN EFI_LBA Lba,\r
290 IN UINTN Offset,\r
291 IN OUT UINTN *NumBytes,\r
292 IN UINT8 *Buffer\r
293 )\r
294/*++\r
295\r
296Routine Description:\r
297 Writes specified number of bytes from the input buffer to the block\r
298\r
299Arguments:\r
300 Instance - The FV instance to be written to\r
301 Lba - The starting logical block index to write to\r
302 Offset - Offset into the block at which to begin writing\r
303 NumBytes - Pointer that on input contains the total size of\r
304 the buffer. On output, it contains the total number\r
305 of bytes actually written\r
306 Buffer - Pointer to a caller allocated buffer that contains\r
307 the source for the write\r
308\r
309Returns: \r
310\r
311 Status code\r
312 \r
313 EFI_INVALID_PARAMETER - invalid parameter\r
314\r
315--*/\r
316{\r
317 if (Instance >= mFvbCount) {\r
318 return EFI_INVALID_PARAMETER;\r
319 }\r
320\r
321 return mFvbEntry[Instance].Fvb->Write (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);\r
322}\r
323\r
324EFI_STATUS\r
325EfiFvbEraseBlock (\r
326 IN UINTN Instance,\r
327 IN EFI_LBA Lba\r
328 )\r
329/*++\r
330\r
331Routine Description:\r
332 Erases and initializes a firmware volume block\r
333\r
334Arguments:\r
335 Instance - The FV instance to be erased\r
336 Lba - The logical block index to be erased\r
337 \r
338Returns: \r
339\r
340 Status code\r
341 \r
342 EFI_INVALID_PARAMETER - invalid parameter\r
343\r
344--*/\r
345{\r
346 if (Instance >= mFvbCount) {\r
347 return EFI_INVALID_PARAMETER;\r
348 }\r
349\r
350 return mFvbEntry[Instance].Fvb->EraseBlocks (mFvbEntry[Instance].Fvb, Lba, -1);\r
351}\r
352\r
353EFI_STATUS\r
354EfiFvbGetVolumeAttributes (\r
355 IN UINTN Instance,\r
356 OUT EFI_FVB_ATTRIBUTES *Attributes\r
357 )\r
358/*++\r
359\r
360Routine Description:\r
361 Retrieves attributes, insures positive polarity of attribute bits, returns\r
362 resulting attributes in output parameter\r
363\r
364Arguments:\r
365 Instance - The FV instance whose attributes is going to be \r
366 returned\r
367 Attributes - Output buffer which contains attributes\r
368\r
369Returns: \r
370 Status code\r
371 \r
372 EFI_INVALID_PARAMETER - invalid parameter\r
373\r
374--*/\r
375{\r
376 if (Instance >= mFvbCount) {\r
377 return EFI_INVALID_PARAMETER;\r
378 }\r
379\r
380 return mFvbEntry[Instance].Fvb->GetVolumeAttributes (mFvbEntry[Instance].Fvb, Attributes);\r
381}\r
382\r
383EFI_STATUS\r
384EfiFvbSetVolumeAttributes (\r
385 IN UINTN Instance,\r
386 IN EFI_FVB_ATTRIBUTES Attributes\r
387 )\r
388/*++\r
389\r
390Routine Description:\r
391 Modifies the current settings of the firmware volume according to the \r
392 input parameter, and returns the new setting of the volume\r
393\r
394Arguments:\r
395 Instance - The FV instance whose attributes is going to be \r
396 modified\r
397 Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES \r
398 containing the desired firmware volume settings.\r
399 On successful return, it contains the new settings\r
400 of the firmware volume\r
401\r
402Returns: \r
403 Status code\r
404 \r
405 EFI_INVALID_PARAMETER - invalid parameter\r
406\r
407--*/\r
408{\r
409 if (Instance >= mFvbCount) {\r
410 return EFI_INVALID_PARAMETER;\r
411 }\r
412\r
413 return mFvbEntry[Instance].Fvb->SetVolumeAttributes (mFvbEntry[Instance].Fvb, &Attributes);\r
414}\r
415\r
416EFI_STATUS\r
417EfiFvbGetPhysicalAddress (\r
418 IN UINTN Instance,\r
419 OUT EFI_PHYSICAL_ADDRESS *BaseAddress\r
420 )\r
421/*++\r
422\r
423Routine Description:\r
424 Retrieves the physical address of a memory mapped FV\r
425\r
426Arguments:\r
427 Instance - The FV instance whose base address is going to be\r
428 returned\r
429 BaseAddress - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS \r
430 that on successful return, contains the base address\r
431 of the firmware volume. \r
432\r
433Returns: \r
434\r
435 Status code\r
436 \r
437 EFI_INVALID_PARAMETER - invalid parameter\r
438\r
439--*/\r
440{\r
441 if (Instance >= mFvbCount) {\r
442 return EFI_INVALID_PARAMETER;\r
443 }\r
444\r
445 return mFvbEntry[Instance].Fvb->GetPhysicalAddress (mFvbEntry[Instance].Fvb, BaseAddress);\r
446}\r
447\r
448EFI_STATUS\r
449EfiFvbGetBlockSize (\r
450 IN UINTN Instance,\r
451 IN EFI_LBA Lba,\r
452 OUT UINTN *BlockSize,\r
453 OUT UINTN *NumOfBlocks\r
454 )\r
455/*++\r
456\r
457Routine Description:\r
458 Retrieve the size of a logical block\r
459\r
460Arguments:\r
461 Instance - The FV instance whose block size is going to be\r
462 returned\r
463 Lba - Indicates which block to return the size for.\r
464 BlockSize - A pointer to a caller allocated UINTN in which\r
465 the size of the block is returned\r
466 NumOfBlocks - a pointer to a caller allocated UINTN in which the\r
467 number of consecutive blocks starting with Lba is\r
468 returned. All blocks in this range have a size of\r
469 BlockSize\r
470\r
471Returns: \r
472 EFI_SUCCESS - The firmware volume was read successfully and \r
473 contents are in Buffer\r
474 \r
475 EFI_INVALID_PARAMETER - invalid parameter\r
476\r
477--*/\r
478{\r
479 if (Instance >= mFvbCount) {\r
480 return EFI_INVALID_PARAMETER;\r
481 }\r
482\r
483 return mFvbEntry[Instance].Fvb->GetBlockSize (mFvbEntry[Instance].Fvb, Lba, BlockSize, NumOfBlocks);\r
484}\r
485\r
486EFI_STATUS\r
487EfiFvbEraseCustomBlockRange (\r
488 IN UINTN Instance,\r
489 IN EFI_LBA StartLba,\r
490 IN UINTN OffsetStartLba,\r
491 IN EFI_LBA LastLba,\r
492 IN UINTN OffsetLastLba\r
493 )\r
494/*++\r
495\r
496Routine Description:\r
497 Erases and initializes a specified range of a firmware volume\r
498\r
499Arguments:\r
500 Instance - The FV instance to be erased\r
501 StartLba - The starting logical block index to be erased\r
502 OffsetStartLba - Offset into the starting block at which to \r
503 begin erasing\r
504 LastLba - The last logical block index to be erased\r
505 OffsetLastLba - Offset into the last block at which to end erasing\r
506\r
507Returns: \r
508\r
509 Status code\r
510 \r
511 EFI_INVALID_PARAMETER - invalid parameter\r
512 \r
513 EFI_UNSUPPORTED - not support\r
514 \r
515--*/\r
516{\r
517 if (Instance >= mFvbCount) {\r
518 return EFI_INVALID_PARAMETER;\r
519 }\r
520\r
521 if (!(mFvbEntry[Instance].FvbExtension)) {\r
522 return EFI_UNSUPPORTED;\r
523 }\r
524\r
525 if (!(mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock)) {\r
526 return EFI_UNSUPPORTED;\r
527 }\r
528\r
529 return mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock (\r
530 mFvbEntry[Instance].FvbExtension,\r
531 StartLba,\r
532 OffsetStartLba,\r
533 LastLba,\r
534 OffsetLastLba\r
535 );\r
536}\r