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