]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/CCode/Source/Common/EfiDecompress.c
Add X64 support for DebugSupport driver.
[mirror_edk2.git] / Tools / CCode / Source / Common / EfiDecompress.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2004, 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 EfiDecompress.c\r
15\r
16Abstract:\r
17\r
18 Decompressor. Algorithm Ported from OPSD code (Decomp.asm)\r
19 \r
20--*/\r
21\r
22#include "EfiDecompress.h"\r
23\r
24//\r
25// Decompression algorithm begins here\r
26//\r
27#define BITBUFSIZ 32\r
28#define MAXMATCH 256\r
29#define THRESHOLD 3\r
30#define CODE_BIT 16\r
31#define BAD_TABLE - 1\r
32\r
33//\r
34// C: Char&Len Set; P: Position Set; T: exTra Set\r
35//\r
36#define NC (0xff + MAXMATCH + 2 - THRESHOLD)\r
37#define CBIT 9\r
38#define PBIT 5\r
39#define TBIT 5\r
40#define MAXNP ((1U << PBIT) - 1)\r
41#define NT (CODE_BIT + 3)\r
42#if NT > MAXNP\r
43#define NPT NT\r
44#else\r
45#define NPT MAXNP\r
46#endif\r
47\r
48typedef struct {\r
49 UINT8 *mSrcBase; // Starting address of compressed data\r
50 UINT8 *mDstBase; // Starting address of decompressed data\r
51 UINT32 mOutBuf;\r
52 UINT32 mInBuf;\r
53\r
54 UINT16 mBitCount;\r
55 UINT32 mBitBuf;\r
56 UINT32 mSubBitBuf;\r
57 UINT16 mBlockSize;\r
58 UINT32 mCompSize;\r
59 UINT32 mOrigSize;\r
60\r
61 UINT16 mBadTableFlag;\r
62\r
63 UINT16 mLeft[2 * NC - 1];\r
64 UINT16 mRight[2 * NC - 1];\r
65 UINT8 mCLen[NC];\r
66 UINT8 mPTLen[NPT];\r
67 UINT16 mCTable[4096];\r
68 UINT16 mPTTable[256];\r
69} SCRATCH_DATA;\r
70\r
71STATIC\r
72VOID\r
73FillBuf (\r
74 IN SCRATCH_DATA *Sd,\r
75 IN UINT16 NumOfBits\r
76 )\r
77/*++\r
78\r
79Routine Description:\r
80\r
81 Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.\r
82\r
83Arguments:\r
84\r
85 Sd - The global scratch data\r
86 NumOfBit - The number of bits to shift and read.\r
87\r
88Returns: (VOID)\r
89\r
90--*/\r
91{\r
92 Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);\r
93\r
94 while (NumOfBits > Sd->mBitCount) {\r
95\r
96 Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
97\r
98 if (Sd->mCompSize > 0) {\r
99 //\r
100 // Get 1 byte into SubBitBuf\r
101 //\r
102 Sd->mCompSize--;\r
103 Sd->mSubBitBuf = 0;\r
104 Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf++];\r
105 Sd->mBitCount = 8;\r
106\r
107 } else {\r
108 //\r
109 // No more bits from the source, just pad zero bit.\r
110 //\r
111 Sd->mSubBitBuf = 0;\r
112 Sd->mBitCount = 8;\r
113\r
114 }\r
115 }\r
116\r
117 Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);\r
118 Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;\r
119}\r
120\r
121STATIC\r
122UINT32\r
123GetBits (\r
124 IN SCRATCH_DATA *Sd,\r
125 IN UINT16 NumOfBits\r
126 )\r
127/*++\r
128\r
129Routine Description:\r
130\r
131 Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent \r
132 NumOfBits of bits from source. Returns NumOfBits of bits that are \r
133 popped out.\r
134\r
135Arguments:\r
136\r
137 Sd - The global scratch data.\r
138 NumOfBits - The number of bits to pop and read.\r
139\r
140Returns:\r
141\r
142 The bits that are popped out.\r
143\r
144--*/\r
145{\r
146 UINT32 OutBits;\r
147\r
148 OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));\r
149\r
150 FillBuf (Sd, NumOfBits);\r
151\r
152 return OutBits;\r
153}\r
154\r
155STATIC\r
156UINT16\r
157MakeTable (\r
158 IN SCRATCH_DATA *Sd,\r
159 IN UINT16 NumOfChar,\r
160 IN UINT8 *BitLen,\r
161 IN UINT16 TableBits,\r
162 OUT UINT16 *Table\r
163 )\r
164/*++\r
165\r
166Routine Description:\r
167\r
168 Creates Huffman Code mapping table according to code length array.\r
169\r
170Arguments:\r
171\r
172 Sd - The global scratch data\r
173 NumOfChar - Number of symbols in the symbol set\r
174 BitLen - Code length array\r
175 TableBits - The width of the mapping table\r
176 Table - The table\r
177 \r
178Returns:\r
179 \r
180 0 - OK.\r
181 BAD_TABLE - The table is corrupted.\r
182\r
183--*/\r
184{\r
185 UINT16 Count[17];\r
186 UINT16 Weight[17];\r
187 UINT16 Start[18];\r
188 UINT16 *Pointer;\r
189 UINT16 Index3;\r
190 UINT16 Index;\r
191 UINT16 Len;\r
192 UINT16 Char;\r
193 UINT16 JuBits;\r
194 UINT16 Avail;\r
195 UINT16 NextCode;\r
196 UINT16 Mask;\r
197\r
198 for (Index = 1; Index <= 16; Index++) {\r
199 Count[Index] = 0;\r
200 }\r
201\r
202 for (Index = 0; Index < NumOfChar; Index++) {\r
203 Count[BitLen[Index]]++;\r
204 }\r
205\r
206 Start[1] = 0;\r
207\r
208 for (Index = 1; Index <= 16; Index++) {\r
209 Start[Index + 1] = (UINT16) (Start[Index] + (Count[Index] << (16 - Index)));\r
210 }\r
211\r
212 if (Start[17] != 0) {\r
213 /*(1U << 16)*/\r
214 return (UINT16) BAD_TABLE;\r
215 }\r
216\r
217 JuBits = (UINT16) (16 - TableBits);\r
218\r
219 for (Index = 1; Index <= TableBits; Index++) {\r
220 Start[Index] >>= JuBits;\r
221 Weight[Index] = (UINT16) (1U << (TableBits - Index));\r
222 }\r
223\r
224 while (Index <= 16) {\r
225 Weight[Index++] = (UINT16) (1U << (16 - Index));\r
226 }\r
227\r
228 Index = (UINT16) (Start[TableBits + 1] >> JuBits);\r
229\r
230 if (Index != 0) {\r
231 Index3 = (UINT16) (1U << TableBits);\r
232 while (Index != Index3) {\r
233 Table[Index++] = 0;\r
234 }\r
235 }\r
236\r
237 Avail = NumOfChar;\r
238 Mask = (UINT16) (1U << (15 - TableBits));\r
239\r
240 for (Char = 0; Char < NumOfChar; Char++) {\r
241\r
242 Len = BitLen[Char];\r
243 if (Len == 0) {\r
244 continue;\r
245 }\r
246\r
247 NextCode = (UINT16) (Start[Len] + Weight[Len]);\r
248\r
249 if (Len <= TableBits) {\r
250\r
251 for (Index = Start[Len]; Index < NextCode; Index++) {\r
252 Table[Index] = Char;\r
253 }\r
254\r
255 } else {\r
256\r
257 Index3 = Start[Len];\r
258 Pointer = &Table[Index3 >> JuBits];\r
259 Index = (UINT16) (Len - TableBits);\r
260\r
261 while (Index != 0) {\r
262 if (*Pointer == 0) {\r
263 Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;\r
264 *Pointer = Avail++;\r
265 }\r
266\r
267 if (Index3 & Mask) {\r
268 Pointer = &Sd->mRight[*Pointer];\r
269 } else {\r
270 Pointer = &Sd->mLeft[*Pointer];\r
271 }\r
272\r
273 Index3 <<= 1;\r
274 Index--;\r
275 }\r
276\r
277 *Pointer = Char;\r
278\r
279 }\r
280\r
281 Start[Len] = NextCode;\r
282 }\r
283 //\r
284 // Succeeds\r
285 //\r
286 return 0;\r
287}\r
288\r
289STATIC\r
290UINT32\r
291DecodeP (\r
292 IN SCRATCH_DATA *Sd\r
293 )\r
294/*++\r
295\r
296Routine Description:\r
297\r
298 Decodes a position value.\r
299\r
300Arguments:\r
301\r
302 Sd - the global scratch data\r
303\r
304Returns:\r
305\r
306 The position value decoded.\r
307\r
308--*/\r
309{\r
310 UINT16 Val;\r
311 UINT32 Mask;\r
312 UINT32 Pos;\r
313\r
314 Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
315\r
316 if (Val >= MAXNP) {\r
317 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
318\r
319 do {\r
320\r
321 if (Sd->mBitBuf & Mask) {\r
322 Val = Sd->mRight[Val];\r
323 } else {\r
324 Val = Sd->mLeft[Val];\r
325 }\r
326\r
327 Mask >>= 1;\r
328 } while (Val >= MAXNP);\r
329 }\r
330 //\r
331 // Advance what we have read\r
332 //\r
333 FillBuf (Sd, Sd->mPTLen[Val]);\r
334\r
335 Pos = Val;\r
336 if (Val > 1) {\r
337 Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));\r
338 }\r
339\r
340 return Pos;\r
341}\r
342\r
343STATIC\r
344UINT16\r
345ReadPTLen (\r
346 IN SCRATCH_DATA *Sd,\r
347 IN UINT16 nn,\r
348 IN UINT16 nbit,\r
349 IN UINT16 Special\r
350 )\r
351/*++\r
352\r
353Routine Description:\r
354\r
355 Reads code lengths for the Extra Set or the Position Set\r
356\r
357Arguments:\r
358\r
359 Sd - The global scratch data\r
360 nn - Number of symbols\r
361 nbit - Number of bits needed to represent nn\r
362 Special - The special symbol that needs to be taken care of \r
363\r
364Returns:\r
365\r
366 0 - OK.\r
367 BAD_TABLE - Table is corrupted.\r
368\r
369--*/\r
370{\r
371 UINT16 Number;\r
372 UINT16 CharC;\r
373 UINT16 Index;\r
374 UINT32 Mask;\r
375\r
376 Number = (UINT16) GetBits (Sd, nbit);\r
377\r
378 if (Number == 0) {\r
379 CharC = (UINT16) GetBits (Sd, nbit);\r
380\r
381 for (Index = 0; Index < 256; Index++) {\r
382 Sd->mPTTable[Index] = CharC;\r
383 }\r
384\r
385 for (Index = 0; Index < nn; Index++) {\r
386 Sd->mPTLen[Index] = 0;\r
387 }\r
388\r
389 return 0;\r
390 }\r
391\r
392 Index = 0;\r
393\r
394 while (Index < Number) {\r
395\r
396 CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r
397\r
398 if (CharC == 7) {\r
399 Mask = 1U << (BITBUFSIZ - 1 - 3);\r
400 while (Mask & Sd->mBitBuf) {\r
401 Mask >>= 1;\r
402 CharC += 1;\r
403 }\r
404 }\r
405\r
406 FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));\r
407\r
408 Sd->mPTLen[Index++] = (UINT8) CharC;\r
409\r
410 if (Index == Special) {\r
411 CharC = (UINT16) GetBits (Sd, 2);\r
412 CharC--;\r
413 while ((INT16) (CharC) >= 0) {\r
414 Sd->mPTLen[Index++] = 0;\r
415 CharC--;\r
416 }\r
417 }\r
418 }\r
419\r
420 while (Index < nn) {\r
421 Sd->mPTLen[Index++] = 0;\r
422 }\r
423\r
424 return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);\r
425}\r
426\r
427STATIC\r
428VOID\r
429ReadCLen (\r
430 SCRATCH_DATA *Sd\r
431 )\r
432/*++\r
433\r
434Routine Description:\r
435\r
436 Reads code lengths for Char&Len Set.\r
437\r
438Arguments:\r
439\r
440 Sd - the global scratch data\r
441\r
442Returns: (VOID)\r
443\r
444--*/\r
445{\r
446 UINT16 Number;\r
447 UINT16 CharC;\r
448 UINT16 Index;\r
449 UINT32 Mask;\r
450\r
451 Number = (UINT16) GetBits (Sd, CBIT);\r
452\r
453 if (Number == 0) {\r
454 CharC = (UINT16) GetBits (Sd, CBIT);\r
455\r
456 for (Index = 0; Index < NC; Index++) {\r
457 Sd->mCLen[Index] = 0;\r
458 }\r
459\r
460 for (Index = 0; Index < 4096; Index++) {\r
461 Sd->mCTable[Index] = CharC;\r
462 }\r
463\r
464 return ;\r
465 }\r
466\r
467 Index = 0;\r
468 while (Index < Number) {\r
469\r
470 CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];\r
471 if (CharC >= NT) {\r
472 Mask = 1U << (BITBUFSIZ - 1 - 8);\r
473\r
474 do {\r
475\r
476 if (Mask & Sd->mBitBuf) {\r
477 CharC = Sd->mRight[CharC];\r
478 } else {\r
479 CharC = Sd->mLeft[CharC];\r
480 }\r
481\r
482 Mask >>= 1;\r
483\r
484 } while (CharC >= NT);\r
485 }\r
486 //\r
487 // Advance what we have read\r
488 //\r
489 FillBuf (Sd, Sd->mPTLen[CharC]);\r
490\r
491 if (CharC <= 2) {\r
492\r
493 if (CharC == 0) {\r
494 CharC = 1;\r
495 } else if (CharC == 1) {\r
496 CharC = (UINT16) (GetBits (Sd, 4) + 3);\r
497 } else if (CharC == 2) {\r
498 CharC = (UINT16) (GetBits (Sd, CBIT) + 20);\r
499 }\r
500\r
501 CharC--;\r
502 while ((INT16) (CharC) >= 0) {\r
503 Sd->mCLen[Index++] = 0;\r
504 CharC--;\r
505 }\r
506\r
507 } else {\r
508\r
509 Sd->mCLen[Index++] = (UINT8) (CharC - 2);\r
510\r
511 }\r
512 }\r
513\r
514 while (Index < NC) {\r
515 Sd->mCLen[Index++] = 0;\r
516 }\r
517\r
518 MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);\r
519\r
520 return ;\r
521}\r
522\r
523STATIC\r
524UINT16\r
525DecodeC (\r
526 SCRATCH_DATA *Sd\r
527 )\r
528/*++\r
529\r
530Routine Description:\r
531\r
532 Decode a character/length value.\r
533\r
534Arguments:\r
535\r
536 Sd - The global scratch data.\r
537\r
538Returns:\r
539\r
540 The value decoded.\r
541\r
542--*/\r
543{\r
544 UINT16 Index2;\r
545 UINT32 Mask;\r
546\r
547 if (Sd->mBlockSize == 0) {\r
548 //\r
549 // Starting a new block\r
550 //\r
551 Sd->mBlockSize = (UINT16) GetBits (Sd, 16);\r
552 Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);\r
553 if (Sd->mBadTableFlag != 0) {\r
554 return 0;\r
555 }\r
556\r
557 ReadCLen (Sd);\r
558\r
559 Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, PBIT, (UINT16) (-1));\r
560 if (Sd->mBadTableFlag != 0) {\r
561 return 0;\r
562 }\r
563 }\r
564\r
565 Sd->mBlockSize--;\r
566 Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];\r
567\r
568 if (Index2 >= NC) {\r
569 Mask = 1U << (BITBUFSIZ - 1 - 12);\r
570\r
571 do {\r
572 if (Sd->mBitBuf & Mask) {\r
573 Index2 = Sd->mRight[Index2];\r
574 } else {\r
575 Index2 = Sd->mLeft[Index2];\r
576 }\r
577\r
578 Mask >>= 1;\r
579 } while (Index2 >= NC);\r
580 }\r
581 //\r
582 // Advance what we have read\r
583 //\r
584 FillBuf (Sd, Sd->mCLen[Index2]);\r
585\r
586 return Index2;\r
587}\r
588\r
589STATIC\r
590VOID\r
591Decode (\r
592 SCRATCH_DATA *Sd\r
593 )\r
594/*++\r
595\r
596Routine Description:\r
597\r
598 Decode the source data and put the resulting data into the destination buffer.\r
599\r
600Arguments:\r
601\r
602 Sd - The global scratch data\r
603\r
604Returns: (VOID)\r
605\r
606 --*/\r
607{\r
608 UINT16 BytesRemain;\r
609 UINT32 DataIdx;\r
610 UINT16 CharC;\r
611\r
612 BytesRemain = (UINT16) (-1);\r
613\r
614 DataIdx = 0;\r
615\r
616 for (;;) {\r
617 CharC = DecodeC (Sd);\r
618 if (Sd->mBadTableFlag != 0) {\r
619 return ;\r
620 }\r
621\r
622 if (CharC < 256) {\r
623 //\r
624 // Process an Original character\r
625 //\r
626 Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;\r
627 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
628 return ;\r
629 }\r
630\r
631 } else {\r
632 //\r
633 // Process a Pointer\r
634 //\r
635 CharC = (UINT16) (CharC - (UINT8_MAX + 1 - THRESHOLD));\r
636\r
637 BytesRemain = CharC;\r
638\r
639 DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;\r
640\r
641 BytesRemain--;\r
642 while ((INT16) (BytesRemain) >= 0) {\r
643 Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
644 if (Sd->mOutBuf >= Sd->mOrigSize) {\r
645 return ;\r
646 }\r
647\r
648 BytesRemain--;\r
649 }\r
650 }\r
651 }\r
652\r
653 return ;\r
654}\r
655\r
656EFI_STATUS\r
657GetInfo (\r
658 IN VOID *Source,\r
659 IN UINT32 SrcSize,\r
660 OUT UINT32 *DstSize,\r
661 OUT UINT32 *ScratchSize\r
662 )\r
663/*++\r
664\r
665Routine Description:\r
666\r
667 The implementation of EFI_DECOMPRESS_PROTOCOL.GetInfo().\r
668\r
669Arguments:\r
670\r
671 Source - The source buffer containing the compressed data.\r
672 SrcSize - The size of source buffer\r
673 DstSize - The size of destination buffer.\r
674 ScratchSize - The size of scratch buffer.\r
675\r
676Returns:\r
677\r
678 EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
679 EFI_INVALID_PARAMETER - The source data is corrupted\r
680\r
681--*/\r
682{\r
683 UINT8 *Src;\r
684\r
685 *ScratchSize = sizeof (SCRATCH_DATA);\r
686\r
687 Src = Source;\r
688 if (SrcSize < 8) {\r
689 return EFI_INVALID_PARAMETER;\r
690 }\r
691\r
692 *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
693 return EFI_SUCCESS;\r
694}\r
695\r
696EFI_STATUS\r
697Decompress (\r
698 IN VOID *Source,\r
699 IN UINT32 SrcSize,\r
700 IN OUT VOID *Destination,\r
701 IN UINT32 DstSize,\r
702 IN OUT VOID *Scratch,\r
703 IN UINT32 ScratchSize\r
704 )\r
705/*++\r
706\r
707Routine Description:\r
708\r
709 The implementation of EFI_DECOMPRESS_PROTOCOL.Decompress().\r
710\r
711Arguments:\r
712\r
713 This - The protocol instance pointer\r
714 Source - The source buffer containing the compressed data.\r
715 SrcSize - The size of source buffer\r
716 Destination - The destination buffer to store the decompressed data\r
717 DstSize - The size of destination buffer.\r
718 Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.\r
719 ScratchSize - The size of scratch buffer.\r
720\r
721Returns:\r
722\r
723 EFI_SUCCESS - Decompression is successfull\r
724 EFI_INVALID_PARAMETER - The source data is corrupted\r
725\r
726--*/\r
727{\r
728 UINT32 Index;\r
729 UINT32 CompSize;\r
730 UINT32 OrigSize;\r
731 EFI_STATUS Status;\r
732 SCRATCH_DATA *Sd;\r
733 UINT8 *Src;\r
734 UINT8 *Dst;\r
735\r
736 Status = EFI_SUCCESS;\r
737 Src = Source;\r
738 Dst = Destination;\r
739\r
740 if (ScratchSize < sizeof (SCRATCH_DATA)) {\r
741 return EFI_INVALID_PARAMETER;\r
742 }\r
743\r
744 Sd = (SCRATCH_DATA *) Scratch;\r
745\r
746 if (SrcSize < 8) {\r
747 return EFI_INVALID_PARAMETER;\r
748 }\r
749\r
750 CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
751 OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
752\r
753 if (SrcSize < CompSize + 8) {\r
754 return EFI_INVALID_PARAMETER;\r
755 }\r
756\r
757 if (DstSize != OrigSize) {\r
758 return EFI_INVALID_PARAMETER;\r
759 }\r
760\r
761 Src = Src + 8;\r
762\r
763 for (Index = 0; Index < sizeof (SCRATCH_DATA); Index++) {\r
764 ((UINT8 *) Sd)[Index] = 0;\r
765 }\r
766\r
767 Sd->mSrcBase = Src;\r
768 Sd->mDstBase = Dst;\r
769 Sd->mCompSize = CompSize;\r
770 Sd->mOrigSize = OrigSize;\r
771\r
772 //\r
773 // Fill the first BITBUFSIZ bits\r
774 //\r
775 FillBuf (Sd, BITBUFSIZ);\r
776\r
777 //\r
778 // Decompress it\r
779 //\r
780 Decode (Sd);\r
781\r
782 if (Sd->mBadTableFlag != 0) {\r
783 //\r
784 // Something wrong with the source\r
785 //\r
786 Status = EFI_INVALID_PARAMETER;\r
787 }\r
788\r
789 return Status;\r
790}\r