]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/RuntimeDxe/EfiRuntimeLib/Ia32/Fvb.c
Update the copyright notice format
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / RuntimeDxe / EfiRuntimeLib / Ia32 / Fvb.c
1 /*++
2
3 Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
4 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 "Tiano.h"
33 #include "EfiRuntimeLib.h"
34 #include EFI_PROTOCOL_DEFINITION (FirmwareVolumeBlock)
35 #include EFI_PROTOCOL_DEFINITION (FvbExtension)
36
37 //
38 // Lib will ASSERT if more FVB devices than this are added to the system.
39 //
40 UINTN mFvbCount;
41 VOID *mFvbRegistration;
42 VOID *mFvbExtRegistration;
43 //static EFI_EVENT mEfiFvbVirtualNotifyEvent;
44 BOOLEAN gEfiFvbInitialized = FALSE;
45 EFI_EVENT mFvbEvent;
46
47 BOOLEAN
48 IsMemoryRuntime (
49 IN VOID *Address
50 )
51 /*++
52
53 Routine Description:
54 Check whether an address is runtime memory or not.
55
56 Arguments:
57
58 Address - The Address being checked.
59
60 Returns:
61 TRUE - The address is runtime memory.
62 FALSE - The address is not runtime memory.
63
64 --*/
65 {
66 EFI_STATUS Status;
67 UINT8 TmpMemoryMap[1];
68 UINTN MapKey;
69 UINTN DescriptorSize;
70 UINT32 DescriptorVersion;
71 UINTN MemoryMapSize;
72 EFI_MEMORY_DESCRIPTOR *MemoryMap;
73 EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
74 BOOLEAN IsRuntime;
75 UINTN Index;
76
77 IsRuntime = FALSE;
78
79 //
80 // Get System MemoryMapSize
81 //
82 MemoryMapSize = 1;
83 Status = gBS->GetMemoryMap (
84 &MemoryMapSize,
85 (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap,
86 &MapKey,
87 &DescriptorSize,
88 &DescriptorVersion
89 );
90 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
91 //
92 // Enlarge space here, because we will allocate pool now.
93 //
94 MemoryMapSize += EFI_PAGE_SIZE;
95 Status = gBS->AllocatePool (
96 EfiBootServicesData,
97 MemoryMapSize,
98 (VOID**)&MemoryMap
99 );
100 ASSERT_EFI_ERROR (Status);
101
102 //
103 // Get System MemoryMap
104 //
105 Status = gBS->GetMemoryMap (
106 &MemoryMapSize,
107 MemoryMap,
108 &MapKey,
109 &DescriptorSize,
110 &DescriptorVersion
111 );
112 ASSERT_EFI_ERROR (Status);
113
114 MemoryMapPtr = MemoryMap;
115 //
116 // Search the request Address
117 //
118 for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {
119 if (((EFI_PHYSICAL_ADDRESS)(UINTN)Address >= MemoryMap->PhysicalStart) &&
120 ((EFI_PHYSICAL_ADDRESS)(UINTN)Address < MemoryMap->PhysicalStart
121 + LShiftU64 (MemoryMap->NumberOfPages, EFI_PAGE_SHIFT))) {
122 //
123 // Found it
124 //
125 if (MemoryMap->Attribute & EFI_MEMORY_RUNTIME) {
126 IsRuntime = TRUE;
127 }
128 break;
129 }
130 //
131 // Get next item
132 //
133 MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + DescriptorSize);
134 }
135
136 //
137 // Done
138 //
139 gBS->FreePool (MemoryMapPtr);
140
141 return IsRuntime;
142 }
143
144 VOID
145 EFIAPI
146 FvbNotificationFunction (
147 IN EFI_EVENT Event,
148 IN VOID *Context
149 )
150 /*++
151
152 Routine Description:
153 Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is
154 reinstalled.
155
156 Arguments:
157
158 Event - The Event that is being processed
159
160 Context - Event Context
161
162 Returns:
163 None
164
165 --*/
166 {
167 EFI_STATUS Status;
168 UINTN BufferSize;
169 EFI_HANDLE Handle;
170 UINTN Index;
171 UINTN UpdateIndex;
172 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
173 EFI_FVB_EXTENSION_PROTOCOL *FvbExtension;
174
175 while (TRUE) {
176 BufferSize = sizeof (Handle);
177 Status = gBS->LocateHandle (
178 ByRegisterNotify,
179 &gEfiFirmwareVolumeBlockProtocolGuid,
180 mFvbRegistration,
181 &BufferSize,
182 &Handle
183 );
184 if (EFI_ERROR (Status)) {
185 //
186 // Exit Path of While Loop....
187 //
188 break;
189 }
190
191 UpdateIndex = MAX_FVB_COUNT;
192 for (Index = 0; Index < mFvbCount; Index++) {
193 if (mFvbEntry[Index].Handle == Handle) {
194 //
195 // If the handle is already in the table just update the protocol
196 //
197 UpdateIndex = Index;
198 break;
199 }
200 }
201
202 if (UpdateIndex == MAX_FVB_COUNT) {
203 //
204 // Use the next free slot for a new entry
205 //
206 UpdateIndex = mFvbCount;
207 }
208 //
209 // The array does not have enough entries
210 //
211 ASSERT (UpdateIndex < MAX_FVB_COUNT);
212
213 //
214 // Get the interface pointer and if it's ours, skip it.
215 // We check Runtime here, because it has no reason to register
216 // a boot time FVB protocol.
217 //
218 Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **) &Fvb);
219 ASSERT_EFI_ERROR (Status);
220 if (IsMemoryRuntime (Fvb)) {
221 //
222 // Increase mFvbCount if we need to add a new entry
223 //
224 if (UpdateIndex == mFvbCount) {
225 mFvbCount++;
226 }
227 mFvbEntry[UpdateIndex].Handle = Handle;
228 mFvbEntry[UpdateIndex].Fvb = Fvb;
229 mFvbEntry[UpdateIndex].FvbExtension = NULL;
230
231 Status = gBS->HandleProtocol (Handle, &gEfiFvbExtensionProtocolGuid, (VOID **) &FvbExtension);
232 if ((Status == EFI_SUCCESS) && IsMemoryRuntime (FvbExtension)) {
233 mFvbEntry[UpdateIndex].FvbExtension = FvbExtension;
234 }
235 }
236 }
237 }
238
239 EFI_STATUS
240 EfiFvbInitialize (
241 VOID
242 )
243 /*++
244
245 Routine Description:
246 Initialize globals and register Fvb Protocol notification function.
247
248 Arguments:
249 None
250
251 Returns:
252 EFI_SUCCESS - Fvb is successfully initialized
253 others - Fail to initialize
254
255 --*/
256 {
257 UINTN Status;
258 mFvbCount = 0;
259
260 Status = gBS->AllocatePool (
261 EfiRuntimeServicesData,
262 (UINTN) sizeof (FVB_ENTRY) * MAX_FVB_COUNT,
263 (VOID *) &mFvbEntry
264 );
265
266 if (EFI_ERROR (Status)) {
267 return Status;
268 }
269
270 EfiZeroMem (mFvbEntry, sizeof (FVB_ENTRY) * MAX_FVB_COUNT);
271
272 mFvbEvent = RtEfiLibCreateProtocolNotifyEvent (
273 &gEfiFirmwareVolumeBlockProtocolGuid,
274 EFI_TPL_CALLBACK,
275 FvbNotificationFunction,
276 NULL,
277 &mFvbRegistration
278 );
279
280 //
281 // Register SetVirtualAddressMap () notify function
282 //
283 // Status = gBS->CreateEvent (
284 // EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
285 // EFI_TPL_NOTIFY,
286 // EfiRuntimeLibFvbVirtualNotifyEvent,
287 // NULL,
288 // &mEfiFvbVirtualNotifyEvent
289 // );
290 // ASSERT_EFI_ERROR (Status);
291 //
292 gEfiFvbInitialized = TRUE;
293
294 return EFI_SUCCESS;
295 }
296
297 EFI_STATUS
298 EfiFvbShutdown (
299 VOID
300 )
301 /*++
302
303 Routine Description:
304 Release resources allocated in EfiFvbInitialize.
305
306 Arguments:
307 None
308
309 Returns:
310 EFI_SUCCESS
311
312 --*/
313 {
314 gBS->FreePool ((VOID *) mFvbEntry);
315 gBS->CloseEvent (mFvbEvent);
316 gEfiFvbInitialized = FALSE;
317 return EFI_SUCCESS;
318 }
319
320 //
321 // The following functions wrap Fvb protocol in the Runtime Lib functions.
322 // The Instance translates into Fvb instance. The Fvb order defined by HOBs and
323 // thus the sequence of FVB protocol addition define Instance.
324 //
325 // EfiFvbInitialize () must be called before any of the following functions
326 // must be called.
327 //
328
329 EFI_STATUS
330 EfiFvbReadBlock (
331 IN UINTN Instance,
332 IN EFI_LBA Lba,
333 IN UINTN Offset,
334 IN OUT UINTN *NumBytes,
335 IN UINT8 *Buffer
336 )
337 /*++
338
339 Routine Description:
340 Reads specified number of bytes into a buffer from the specified block
341
342 Arguments:
343 Instance - The FV instance to be read from
344 Lba - The logical block address to be read from
345 Offset - Offset into the block at which to begin reading
346 NumBytes - Pointer that on input contains the total size of
347 the buffer. On output, it contains the total number
348 of bytes read
349 Buffer - Pointer to a caller allocated buffer that will be
350 used to hold the data read
351
352 Returns:
353
354 Status code
355
356 EFI_INVALID_PARAMETER - invalid parameter
357
358 --*/
359 {
360 if (Instance >= mFvbCount) {
361 return EFI_INVALID_PARAMETER;
362 }
363
364 return mFvbEntry[Instance].Fvb->Read (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);
365 }
366
367 EFI_STATUS
368 EfiFvbWriteBlock (
369 IN UINTN Instance,
370 IN EFI_LBA Lba,
371 IN UINTN Offset,
372 IN OUT UINTN *NumBytes,
373 IN UINT8 *Buffer
374 )
375 /*++
376
377 Routine Description:
378 Writes specified number of bytes from the input buffer to the block
379
380 Arguments:
381 Instance - The FV instance to be written to
382 Lba - The starting logical block index to write to
383 Offset - Offset into the block at which to begin writing
384 NumBytes - Pointer that on input contains the total size of
385 the buffer. On output, it contains the total number
386 of bytes actually written
387 Buffer - Pointer to a caller allocated buffer that contains
388 the source for the write
389
390 Returns:
391
392 Status code
393
394 EFI_INVALID_PARAMETER - invalid parameter
395
396 --*/
397 {
398 if (Instance >= mFvbCount) {
399 return EFI_INVALID_PARAMETER;
400 }
401
402 return mFvbEntry[Instance].Fvb->Write (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);
403 }
404
405 EFI_STATUS
406 EfiFvbEraseBlock (
407 IN UINTN Instance,
408 IN EFI_LBA Lba
409 )
410 /*++
411
412 Routine Description:
413 Erases and initializes a firmware volume block
414
415 Arguments:
416 Instance - The FV instance to be erased
417 Lba - The logical block index to be erased
418
419 Returns:
420
421 Status code
422
423 EFI_INVALID_PARAMETER - invalid parameter
424
425 --*/
426 {
427 if (Instance >= mFvbCount) {
428 return EFI_INVALID_PARAMETER;
429 }
430
431 return mFvbEntry[Instance].Fvb->EraseBlocks (mFvbEntry[Instance].Fvb, Lba, -1);
432 }
433
434 EFI_STATUS
435 EfiFvbGetVolumeAttributes (
436 IN UINTN Instance,
437 OUT EFI_FVB_ATTRIBUTES *Attributes
438 )
439 /*++
440
441 Routine Description:
442 Retrieves attributes, insures positive polarity of attribute bits, returns
443 resulting attributes in output parameter
444
445 Arguments:
446 Instance - The FV instance whose attributes is going to be
447 returned
448 Attributes - Output buffer which contains attributes
449
450 Returns:
451 Status code
452
453 EFI_INVALID_PARAMETER - invalid parameter
454
455 --*/
456 {
457 if (Instance >= mFvbCount) {
458 return EFI_INVALID_PARAMETER;
459 }
460
461 return mFvbEntry[Instance].Fvb->GetVolumeAttributes (mFvbEntry[Instance].Fvb, Attributes);
462 }
463
464 EFI_STATUS
465 EfiFvbSetVolumeAttributes (
466 IN UINTN Instance,
467 IN EFI_FVB_ATTRIBUTES Attributes
468 )
469 /*++
470
471 Routine Description:
472 Modifies the current settings of the firmware volume according to the
473 input parameter.
474
475 Arguments:
476 Instance - The FV instance whose attributes is going to be
477 modified
478 Attributes - It is a pointer to EFI_FVB_ATTRIBUTES
479 containing the desired firmware volume settings.
480
481 Returns:
482 Status code
483
484 EFI_INVALID_PARAMETER - invalid parameter
485
486 --*/
487 {
488 if (Instance >= mFvbCount) {
489 return EFI_INVALID_PARAMETER;
490 }
491
492 return mFvbEntry[Instance].Fvb->SetVolumeAttributes (mFvbEntry[Instance].Fvb, &Attributes);
493 }
494
495 EFI_STATUS
496 EfiFvbGetPhysicalAddress (
497 IN UINTN Instance,
498 OUT EFI_PHYSICAL_ADDRESS *BaseAddress
499 )
500 /*++
501
502 Routine Description:
503 Retrieves the physical address of a memory mapped FV
504
505 Arguments:
506 Instance - The FV instance whose base address is going to be
507 returned
508 BaseAddress - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
509 that on successful return, contains the base address
510 of the firmware volume.
511
512 Returns:
513
514 Status code
515
516 EFI_INVALID_PARAMETER - invalid parameter
517
518 --*/
519 {
520 if (Instance >= mFvbCount) {
521 return EFI_INVALID_PARAMETER;
522 }
523
524 return mFvbEntry[Instance].Fvb->GetPhysicalAddress (mFvbEntry[Instance].Fvb, BaseAddress);
525 }
526
527 EFI_STATUS
528 EfiFvbGetBlockSize (
529 IN UINTN Instance,
530 IN EFI_LBA Lba,
531 OUT UINTN *BlockSize,
532 OUT UINTN *NumOfBlocks
533 )
534 /*++
535
536 Routine Description:
537 Retrieve the size of a logical block
538
539 Arguments:
540 Instance - The FV instance whose block size is going to be
541 returned
542 Lba - Indicates which block to return the size for.
543 BlockSize - A pointer to a caller allocated UINTN in which
544 the size of the block is returned
545 NumOfBlocks - a pointer to a caller allocated UINTN in which the
546 number of consecutive blocks starting with Lba is
547 returned. All blocks in this range have a size of
548 BlockSize
549
550 Returns:
551 EFI_SUCCESS - The firmware volume was read successfully and
552 contents are in Buffer
553
554 EFI_INVALID_PARAMETER - invalid parameter
555
556 --*/
557 {
558 if (Instance >= mFvbCount) {
559 return EFI_INVALID_PARAMETER;
560 }
561
562 return mFvbEntry[Instance].Fvb->GetBlockSize (mFvbEntry[Instance].Fvb, Lba, BlockSize, NumOfBlocks);
563 }
564
565 EFI_STATUS
566 EfiFvbEraseCustomBlockRange (
567 IN UINTN Instance,
568 IN EFI_LBA StartLba,
569 IN UINTN OffsetStartLba,
570 IN EFI_LBA LastLba,
571 IN UINTN OffsetLastLba
572 )
573 /*++
574
575 Routine Description:
576 Erases and initializes a specified range of a firmware volume
577
578 Arguments:
579 Instance - The FV instance to be erased
580 StartLba - The starting logical block index to be erased
581 OffsetStartLba - Offset into the starting block at which to
582 begin erasing
583 LastLba - The last logical block index to be erased
584 OffsetLastLba - Offset into the last block at which to end erasing
585
586 Returns:
587
588 Status code
589
590 EFI_INVALID_PARAMETER - invalid parameter
591
592 EFI_UNSUPPORTED - not support
593
594 --*/
595 {
596 if (Instance >= mFvbCount) {
597 return EFI_INVALID_PARAMETER;
598 }
599
600 if (!(mFvbEntry[Instance].FvbExtension)) {
601 return EFI_UNSUPPORTED;
602 }
603
604 if (!(mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock)) {
605 return EFI_UNSUPPORTED;
606 }
607
608 return mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock (
609 mFvbEntry[Instance].FvbExtension,
610 StartLba,
611 OffsetStartLba,
612 LastLba,
613 OffsetLastLba
614 );
615 }