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