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