]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciMem.c
1. Add NULL QH to set as QH header;
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / Ehci / Dxe / EhciMem.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 EhciMem.c
15
16 Abstract:
17
18
19 Revision History
20 --*/
21
22 #include "Ehci.h"
23
24
25 EFI_STATUS
26 CreateMemoryBlock (
27 IN USB2_HC_DEV *HcDev,
28 OUT MEMORY_MANAGE_HEADER **MemoryHeader,
29 IN UINTN MemoryBlockSizeInPages
30 )
31 /*++
32
33 Routine Description:
34
35 Use PciIo->AllocateBuffer to allocate common buffer for the memory block,
36 and use PciIo->Map to map the common buffer for Bus Master Read/Write.
37
38 Arguments:
39
40 HcDev - USB2_HC_DEV
41 MemoryHeader - MEMORY_MANAGE_HEADER to output
42 MemoryBlockSizeInPages - MemoryBlockSizeInPages
43
44 Returns:
45
46 EFI_SUCCESS Success
47 EFI_OUT_OF_RESOURCES Fail for no resources
48 EFI_UNSUPPORTED Unsupported currently
49
50 --*/
51 {
52 EFI_STATUS Status;
53 VOID *CommonBuffer;
54 EFI_PHYSICAL_ADDRESS MappedAddress;
55 UINTN MemoryBlockSizeInBytes;
56 VOID *Mapping;
57
58 //
59 // Allocate memory for MemoryHeader
60 //
61 *MemoryHeader = AllocateZeroPool (sizeof (MEMORY_MANAGE_HEADER));
62 if (*MemoryHeader == NULL) {
63 return EFI_OUT_OF_RESOURCES;
64 }
65
66 (*MemoryHeader)->Next = NULL;
67
68 //
69 // set Memory block size
70 //
71 (*MemoryHeader)->MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);
72
73 //
74 // each bit in Bit Array will manage 32 bytes memory in memory block
75 //
76 (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / MEM_UNIT_SIZE) / 8;
77
78 //
79 // Allocate memory for BitArray
80 //
81 (*MemoryHeader)->BitArrayPtr = AllocateZeroPool ((*MemoryHeader)->BitArraySizeInBytes);
82 if ((*MemoryHeader)->BitArrayPtr == NULL) {
83 gBS->FreePool (*MemoryHeader);
84 return EFI_OUT_OF_RESOURCES;
85 }
86
87 //
88 // Memory Block uses MemoryBlockSizeInPages pages,
89 // and it is allocated as common buffer use.
90 //
91 Status = HcDev->PciIo->AllocateBuffer (
92 HcDev->PciIo,
93 AllocateAnyPages,
94 EfiBootServicesData,
95 MemoryBlockSizeInPages,
96 &CommonBuffer,
97 0
98 );
99 if (EFI_ERROR (Status)) {
100 gBS->FreePool ((*MemoryHeader)->BitArrayPtr);
101 gBS->FreePool (*MemoryHeader);
102 return EFI_OUT_OF_RESOURCES;
103 }
104
105 MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);
106 Status = HcDev->PciIo->Map (
107 HcDev->PciIo,
108 EfiPciIoOperationBusMasterCommonBuffer,
109 CommonBuffer,
110 &MemoryBlockSizeInBytes,
111 &MappedAddress,
112 &Mapping
113 );
114 //
115 // If returned Mapped size is less than the size
116 // we request,do not support.
117 //
118 if (EFI_ERROR (Status) || (MemoryBlockSizeInBytes != EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages))) {
119 HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);
120 gBS->FreePool ((*MemoryHeader)->BitArrayPtr);
121 gBS->FreePool (*MemoryHeader);
122 return EFI_UNSUPPORTED;
123 }
124
125 //
126 // Data structure involved by host controller
127 // should be restricted into the same 4G
128 //
129 if (HcDev->Is64BitCapable != 0) {
130 if (HcDev->High32BitAddr != GET_32B_TO_63B (MappedAddress)) {
131 HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);
132 HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);
133 gBS->FreePool ((*MemoryHeader)->BitArrayPtr);
134 gBS->FreePool (*MemoryHeader);
135 return EFI_UNSUPPORTED;
136 }
137 }
138
139 //
140 // Set Memory block initial address
141 //
142 (*MemoryHeader)->MemoryBlockPtr = (UINT8 *) ((UINTN) MappedAddress);
143 (*MemoryHeader)->Mapping = Mapping;
144
145 ZeroMem (
146 (*MemoryHeader)->MemoryBlockPtr,
147 EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages)
148 );
149
150 return EFI_SUCCESS;
151 }
152
153 EFI_STATUS
154 FreeMemoryHeader (
155 IN USB2_HC_DEV *HcDev,
156 IN MEMORY_MANAGE_HEADER *MemoryHeader
157 )
158 /*++
159
160 Routine Description:
161
162 Free Memory Header
163
164 Arguments:
165
166 HcDev - USB2_HC_DEV
167 MemoryHeader - MemoryHeader to be freed
168
169 Returns:
170
171 EFI_SUCCESS Success
172 EFI_INVALID_PARAMETER Parameter is error
173
174 --*/
175 {
176 if ((MemoryHeader == NULL) || (HcDev == NULL)) {
177 return EFI_INVALID_PARAMETER;
178 }
179 //
180 // unmap the common buffer used by the memory block
181 //
182 HcDev->PciIo->Unmap (HcDev->PciIo, MemoryHeader->Mapping);
183
184 //
185 // free common buffer
186 //
187 HcDev->PciIo->FreeBuffer (
188 HcDev->PciIo,
189 EFI_SIZE_TO_PAGES (MemoryHeader->MemoryBlockSizeInBytes),
190 MemoryHeader->MemoryBlockPtr
191 );
192 //
193 // free bit array
194 //
195 gBS->FreePool (MemoryHeader->BitArrayPtr);
196 //
197 // free memory header
198 //
199 gBS->FreePool (MemoryHeader);
200
201 return EFI_SUCCESS;
202 }
203
204 EFI_STATUS
205 EhciAllocatePool (
206 IN USB2_HC_DEV *HcDev,
207 OUT UINT8 **Pool,
208 IN UINTN AllocSize
209 )
210 /*++
211
212 Routine Description:
213
214 Ehci Allocate Pool
215
216 Arguments:
217
218 HcDev - USB2_HC_DEV
219 Pool - Place to store pointer to the memory buffer
220 AllocSize - Alloc Size
221
222 Returns:
223
224 EFI_SUCCESS Success
225 EFI_DEVICE_ERROR Fail
226
227 --*/
228 {
229 MEMORY_MANAGE_HEADER *MemoryHeader;
230 MEMORY_MANAGE_HEADER *TempHeaderPtr;
231 MEMORY_MANAGE_HEADER *NewMemoryHeader;
232 UINTN RealAllocSize;
233 UINTN MemoryBlockSizeInPages;
234 EFI_STATUS Status;
235 EFI_TPL OldTpl;
236
237 *Pool = NULL;
238
239 MemoryHeader = HcDev->MemoryHeader;
240 ASSERT (MemoryHeader != NULL);
241
242 OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);
243
244 //
245 // allocate unit is 32 bytes (align on 32 byte)
246 //
247 if (AllocSize & (MEM_UNIT_SIZE - 1)) {
248 RealAllocSize = (AllocSize / MEM_UNIT_SIZE + 1) * MEM_UNIT_SIZE;
249 } else {
250 RealAllocSize = AllocSize;
251 }
252
253 //
254 // There may be linked MemoryHeaders.
255 // To allocate a free pool in Memory blocks,
256 // must search in the MemoryHeader link list
257 // until enough free pool is found.
258 //
259 Status = EFI_NOT_FOUND;
260 for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
261
262 Status = AllocMemInMemoryBlock (
263 TempHeaderPtr,
264 (VOID **) Pool,
265 RealAllocSize / MEM_UNIT_SIZE
266 );
267 if (!EFI_ERROR (Status)) {
268 break;
269 }
270 }
271
272 gBS->RestoreTPL (OldTpl);
273
274 if (!EFI_ERROR (Status)) {
275 ZeroMem (*Pool, AllocSize);
276 return EFI_SUCCESS;
277 }
278
279
280 //
281 // There is no enough memory,
282 // Create a new Memory Block
283 //
284
285 //
286 // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,
287 // just allocate a large enough memory block.
288 //
289 if (RealAllocSize > EFI_PAGES_TO_SIZE (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES)) {
290 MemoryBlockSizeInPages = EFI_SIZE_TO_PAGES (RealAllocSize) + 1;
291 } else {
292 MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
293 }
294
295 Status = CreateMemoryBlock (HcDev, &NewMemoryHeader, MemoryBlockSizeInPages);
296 if (EFI_ERROR (Status)) {
297 return Status;
298 }
299
300 OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);
301
302 //
303 // Link the new Memory Block to the Memory Header list
304 //
305 InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);
306
307 Status = AllocMemInMemoryBlock (
308 NewMemoryHeader,
309 (VOID **) Pool,
310 RealAllocSize / MEM_UNIT_SIZE
311 );
312
313 gBS->RestoreTPL (OldTpl);
314
315 if (!EFI_ERROR (Status)) {
316 ZeroMem (*Pool, AllocSize);
317 }
318
319 return Status;
320 }
321
322 VOID
323 EhciFreePool (
324 IN USB2_HC_DEV *HcDev,
325 IN UINT8 *Pool,
326 IN UINTN AllocSize
327 )
328 /*++
329
330 Routine Description:
331
332 Uhci Free Pool
333
334 Arguments:
335
336 HcDev - USB_HC_DEV
337 Pool - Pool to free
338 AllocSize - Pool size
339
340 Returns:
341
342 VOID
343
344 --*/
345 {
346 MEMORY_MANAGE_HEADER *MemoryHeader;
347 MEMORY_MANAGE_HEADER *TempHeaderPtr;
348 UINTN StartBytePos;
349 UINTN Index;
350 UINT8 StartBitPos;
351 UINT8 Index2;
352 UINTN Count;
353 UINTN RealAllocSize;
354 EFI_TPL OldTpl;
355
356 OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);
357
358 MemoryHeader = HcDev->MemoryHeader;
359
360 //
361 // allocate unit is 32 byte (align on 32 byte)
362 //
363 if (AllocSize & (MEM_UNIT_SIZE - 1)) {
364 RealAllocSize = (AllocSize / MEM_UNIT_SIZE + 1) * MEM_UNIT_SIZE;
365 } else {
366 RealAllocSize = AllocSize;
367 }
368
369 //
370 // scan the memory header linked list for
371 // the asigned memory to free.
372 //
373 for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
374
375 if ((Pool >= TempHeaderPtr->MemoryBlockPtr) &&
376 ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr + TempHeaderPtr->MemoryBlockSizeInBytes))
377 ) {
378 //
379 // Pool is in the Memory Block area,
380 // find the start byte and bit in the bit array
381 //
382 StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / MEM_UNIT_SIZE) / 8;
383 StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / MEM_UNIT_SIZE) & 0x7);
384
385 //
386 // reset associated bits in bit arry
387 //
388 for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / MEM_UNIT_SIZE); Count++) {
389 ASSERT ((TempHeaderPtr->BitArrayPtr[Index] & bit (Index2) )== bit (Index2));
390
391 TempHeaderPtr->BitArrayPtr[Index] ^= (UINT8) (bit (Index2));
392 Index2++;
393 if (Index2 == 8) {
394 Index += 1;
395 Index2 = 0;
396 }
397 }
398 //
399 // break the loop
400 //
401 break;
402 }
403 }
404
405 //
406 // Release emptied memory blocks (only if the memory block is not
407 // the first one in the memory header list
408 //
409 for (TempHeaderPtr = MemoryHeader->Next; TempHeaderPtr != NULL;) {
410
411 ASSERT (MemoryHeader->Next != NULL);
412
413 if (IsMemoryBlockEmptied (TempHeaderPtr)) {
414
415 DelinkMemoryBlock (MemoryHeader, TempHeaderPtr);
416 //
417 // when the TempHeaderPtr is freed in FreeMemoryHeader(),
418 // the TempHeaderPtr is pointing to nonsense content.
419 //
420 gBS->RestoreTPL (OldTpl);
421 FreeMemoryHeader (HcDev, TempHeaderPtr);
422 OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);
423 //
424 // reset the TempHeaderPtr, continue search for
425 // another empty memory block.
426 //
427 TempHeaderPtr = MemoryHeader->Next;
428 continue;
429 }
430
431 TempHeaderPtr = TempHeaderPtr->Next;
432 }
433
434 gBS->RestoreTPL (OldTpl);
435 }
436
437 VOID
438 InsertMemoryHeaderToList (
439 IN MEMORY_MANAGE_HEADER *MemoryHeader,
440 IN MEMORY_MANAGE_HEADER *NewMemoryHeader
441 )
442 /*++
443
444 Routine Description:
445
446 Insert Memory Header To List
447
448 Arguments:
449
450 MemoryHeader - MEMORY_MANAGE_HEADER
451 NewMemoryHeader - MEMORY_MANAGE_HEADER
452
453 Returns:
454
455 VOID
456
457 --*/
458 {
459 MEMORY_MANAGE_HEADER *TempHeaderPtr;
460
461 for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
462 if (TempHeaderPtr->Next == NULL) {
463 TempHeaderPtr->Next = NewMemoryHeader;
464 break;
465 }
466 }
467 }
468
469 EFI_STATUS
470 AllocMemInMemoryBlock (
471 IN MEMORY_MANAGE_HEADER *MemoryHeader,
472 OUT VOID **Pool,
473 IN UINTN NumberOfMemoryUnit
474 )
475 /*++
476
477 Routine Description:
478
479 Alloc Memory In MemoryBlock
480
481 Arguments:
482
483 MemoryHeader - MEMORY_MANAGE_HEADER
484 Pool - Place to store pointer to memory
485 NumberOfMemoryUnit - Number Of Memory Unit
486
487 Returns:
488
489 EFI_SUCCESS Success
490 EFI_NOT_FOUND Can't find the free memory
491
492 --*/
493 {
494 UINTN TempBytePos;
495 UINTN FoundBytePos;
496 UINT8 Index;
497 UINT8 FoundBitPos;
498 UINT8 ByteValue;
499 UINT8 BitValue;
500 UINTN NumberOfZeros;
501 UINTN Count;
502
503 FoundBytePos = 0;
504 FoundBitPos = 0;
505 ByteValue = MemoryHeader->BitArrayPtr[0];
506 NumberOfZeros = 0;
507 Index = 0;
508
509 for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {
510
511 //
512 // Pop out BitValue from a byte in TempBytePos.
513 //
514 BitValue = (UINT8) (ByteValue & 0x1);
515
516 //
517 // right shift the byte
518 //
519 ByteValue = ByteValue >> 1;
520
521 if (BitValue == 0) {
522 //
523 // Found a free bit, the NumberOfZeros only record the number
524 // of those consecutive zeros
525 //
526 NumberOfZeros++;
527 //
528 // Found enough consecutive free space, break the loop
529 //
530 if (NumberOfZeros >= NumberOfMemoryUnit) {
531 break;
532 }
533 } else {
534 //
535 // Encountering a '1', meant the bit is ocupied.
536 //
537 if (NumberOfZeros >= NumberOfMemoryUnit) {
538 //
539 // Found enough consecutive free space,break the loop
540 //
541 break;
542 } else {
543 //
544 // the NumberOfZeros only record the number of those consecutive zeros,
545 // so reset the NumberOfZeros to 0 when encountering '1' before finding
546 // enough consecutive '0's
547 //
548 NumberOfZeros = 0;
549 //
550 // reset the (FoundBytePos,FoundBitPos) to the position of '1'
551 //
552 FoundBytePos = TempBytePos;
553 FoundBitPos = Index;
554 }
555 }
556
557 //
558 // step forward a bit
559 //
560 Index++;
561 if (Index == 8) {
562 //
563 // step forward a byte, getting the byte value,
564 // and reset the bit pos.
565 //
566 TempBytePos += 1;
567 ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];
568 Index = 0;
569 }
570 }
571
572 if (NumberOfZeros < NumberOfMemoryUnit) {
573 return EFI_NOT_FOUND;
574 }
575
576 //
577 // Found enough free space.
578 //
579
580 //
581 // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:
582 // 1)(FoundBytePos,FoundBitPos) record the position
583 // of the last '1' before the consecutive '0's, it must
584 // be adjusted to the start position of the consecutive '0's.
585 // 2)the start address of the consecutive '0's is just the start of
586 // the bitarray. so no need to adjust the values of
587 // (FoundBytePos,FoundBitPos).
588 //
589 if ((MemoryHeader->BitArrayPtr[FoundBytePos] & bit (FoundBitPos)) != 0) {
590 FoundBitPos += 1;
591 }
592
593 //
594 // Have the (FoundBytePos,FoundBitPos) make sense.
595 //
596 if (FoundBitPos > 7) {
597 FoundBytePos += 1;
598 FoundBitPos -= 8;
599 }
600
601 //
602 // Set the memory as allocated
603 //
604 for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) {
605
606 ASSERT ((MemoryHeader->BitArrayPtr[TempBytePos] & bit (Index) )== 0);
607 MemoryHeader->BitArrayPtr[TempBytePos] |= bit (Index);
608 Index++;
609 if (Index == 8) {
610 TempBytePos += 1;
611 Index = 0;
612 }
613 }
614
615 *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * MEM_UNIT_SIZE;
616
617 return EFI_SUCCESS;
618 }
619
620 BOOLEAN
621 IsMemoryBlockEmptied (
622 IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr
623 )
624 /*++
625
626 Routine Description:
627
628 Is Memory Block Emptied
629
630 Arguments:
631
632 MemoryHeaderPtr - MEMORY_MANAGE_HEADER
633
634 Returns:
635
636 TRUE Empty
637 FALSE Not Empty
638
639 --*/
640 {
641 UINTN Index;
642
643 for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {
644 if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {
645 return FALSE;
646 }
647 }
648
649 return TRUE;
650 }
651
652 VOID
653 DelinkMemoryBlock (
654 IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,
655 IN MEMORY_MANAGE_HEADER *NeedFreeMemoryHeader
656 )
657 /*++
658
659 Routine Description:
660
661 Delink Memory Block
662
663 Arguments:
664
665 FirstMemoryHeader - MEMORY_MANAGE_HEADER
666 NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER
667
668 Returns:
669
670 VOID
671
672 --*/
673 {
674 MEMORY_MANAGE_HEADER *TempHeaderPtr;
675
676 if ((FirstMemoryHeader == NULL) || (NeedFreeMemoryHeader == NULL)) {
677 return ;
678 }
679
680 for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
681
682 if (TempHeaderPtr->Next == NeedFreeMemoryHeader) {
683 //
684 // Link the before and after
685 //
686 TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;
687 NeedFreeMemoryHeader->Next = NULL;
688 break;
689 }
690 }
691 }
692
693 EFI_STATUS
694 InitialMemoryManagement (
695 IN USB2_HC_DEV *HcDev
696 )
697 /*++
698
699 Routine Description:
700
701 Initialize Memory Management
702
703 Arguments:
704
705 HcDev - USB2_HC_DEV
706
707 Returns:
708
709 EFI_SUCCESS Success
710 EFI_DEVICE_ERROR Fail
711
712 --*/
713 {
714 EFI_STATUS Status;
715 MEMORY_MANAGE_HEADER *MemoryHeader;
716 UINTN MemPages;
717
718 MemPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
719 Status = CreateMemoryBlock (HcDev, &MemoryHeader, MemPages);
720 if (EFI_ERROR (Status)) {
721 Status = EFI_OUT_OF_RESOURCES;
722 goto exit;
723 }
724
725 HcDev->MemoryHeader = MemoryHeader;
726
727 exit:
728 return Status;
729 }
730
731 EFI_STATUS
732 DeinitialMemoryManagement (
733 IN USB2_HC_DEV *HcDev
734 )
735 /*++
736
737 Routine Description:
738
739 Deinitialize Memory Management
740
741 Arguments:
742
743 HcDev - USB2_HC_DEV
744
745 Returns:
746
747 EFI_SUCCESS Success
748 EFI_DEVICE_ERROR Fail
749
750 --*/
751 {
752 MEMORY_MANAGE_HEADER *TempHeaderPtr;
753
754 for (TempHeaderPtr = HcDev->MemoryHeader->Next; TempHeaderPtr != NULL;) {
755
756 DelinkMemoryBlock (HcDev->MemoryHeader, TempHeaderPtr);
757 //
758 // when the TempHeaderPtr is freed in FreeMemoryHeader(),
759 // the TempHeaderPtr is pointing to nonsense content.
760 //
761 FreeMemoryHeader (HcDev, TempHeaderPtr);
762 //
763 // reset the TempHeaderPtr,continue free another memory block.
764 //
765 TempHeaderPtr = HcDev->MemoryHeader->Next;
766 }
767
768 FreeMemoryHeader (HcDev, HcDev->MemoryHeader);
769
770 return EFI_SUCCESS;
771 }