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