]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
BaseTools: Enable Match2 Opcode.
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrFormPkg.cpp
1 /** @file
2
3 The definition of CFormPkg's member function
4
5 Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "stdio.h"
17 #include "VfrFormPkg.h"
18
19 /*
20 * The definition of CFormPkg's member function
21 */
22
23 SPendingAssign::SPendingAssign (
24 IN CHAR8 *Key,
25 IN VOID *Addr,
26 IN UINT32 Len,
27 IN UINT32 LineNo,
28 IN CONST CHAR8 *Msg
29 )
30 {
31 mKey = NULL;
32 mAddr = Addr;
33 mLen = Len;
34 mFlag = PENDING;
35 mLineNo = LineNo;
36 mMsg = NULL;
37 mNext = NULL;
38 if (Key != NULL) {
39 mKey = new CHAR8[strlen (Key) + 1];
40 if (mKey != NULL) {
41 strcpy (mKey, Key);
42 }
43 }
44
45 if (Msg != NULL) {
46 mMsg = new CHAR8[strlen (Msg) + 1];
47 if (mMsg != NULL) {
48 strcpy (mMsg, Msg);
49 }
50 }
51 }
52
53 SPendingAssign::~SPendingAssign (
54 VOID
55 )
56 {
57 if (mKey != NULL) {
58 delete mKey;
59 }
60 mAddr = NULL;
61 mLen = 0;
62 mLineNo = 0;
63 if (mMsg != NULL) {
64 delete mMsg;
65 }
66 mNext = NULL;
67 }
68
69 VOID
70 SPendingAssign::SetAddrAndLen (
71 IN VOID *Addr,
72 IN UINT32 LineNo
73 )
74 {
75 mAddr = Addr;
76 mLineNo = LineNo;
77 }
78
79 VOID
80 SPendingAssign::AssignValue (
81 IN VOID *Addr,
82 IN UINT32 Len
83 )
84 {
85 memmove (mAddr, Addr, (mLen < Len ? mLen : Len));
86 mFlag = ASSIGNED;
87 }
88
89 CHAR8 *
90 SPendingAssign::GetKey (
91 VOID
92 )
93 {
94 return mKey;
95 }
96
97 CFormPkg::CFormPkg (
98 IN UINT32 BufferSize
99 )
100 {
101 CHAR8 *BufferStart;
102 CHAR8 *BufferEnd;
103 SBufferNode *Node;
104
105 mPkgLength = 0;
106 mBufferNodeQueueHead = NULL;
107 mCurrBufferNode = NULL;
108
109 Node = new SBufferNode;
110 if (Node == NULL) {
111 return ;
112 }
113 BufferStart = new CHAR8[BufferSize];
114 if (BufferStart == NULL) {
115 return;
116 }
117 BufferEnd = BufferStart + BufferSize;
118
119 memset (BufferStart, 0, BufferSize);
120 Node->mBufferStart = BufferStart;
121 Node->mBufferEnd = BufferEnd;
122 Node->mBufferFree = BufferStart;
123 Node->mNext = NULL;
124
125 mBufferSize = BufferSize;
126 mBufferNodeQueueHead = Node;
127 mBufferNodeQueueTail = Node;
128 mCurrBufferNode = Node;
129 }
130
131 CFormPkg::~CFormPkg ()
132 {
133 SBufferNode *pBNode;
134 SPendingAssign *pPNode;
135
136 while (mBufferNodeQueueHead != NULL) {
137 pBNode = mBufferNodeQueueHead;
138 mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;
139 if (pBNode->mBufferStart != NULL) {
140 delete pBNode->mBufferStart;
141 delete pBNode;
142 }
143 }
144 mBufferNodeQueueTail = NULL;
145 mCurrBufferNode = NULL;
146
147 while (PendingAssignList != NULL) {
148 pPNode = PendingAssignList;
149 PendingAssignList = PendingAssignList->mNext;
150 delete pPNode;
151 }
152 PendingAssignList = NULL;
153 }
154
155 SBufferNode *
156 CFormPkg::CreateNewNode (
157 VOID
158 )
159 {
160 SBufferNode *Node;
161
162 Node = new SBufferNode;
163 if (Node == NULL) {
164 return NULL;
165 }
166
167 Node->mBufferStart = new CHAR8[mBufferSize];
168 if (Node->mBufferStart == NULL) {
169 delete Node;
170 return NULL;
171 } else {
172 memset (Node->mBufferStart, 0, mBufferSize);
173 Node->mBufferEnd = Node->mBufferStart + mBufferSize;
174 Node->mBufferFree = Node->mBufferStart;
175 Node->mNext = NULL;
176 }
177
178 return Node;
179 }
180
181 CHAR8 *
182 CFormPkg::IfrBinBufferGet (
183 IN UINT32 Len
184 )
185 {
186 CHAR8 *BinBuffer = NULL;
187 SBufferNode *Node = NULL;
188
189 if ((Len == 0) || (Len > mBufferSize)) {
190 return NULL;
191 }
192
193 if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {
194 BinBuffer = mCurrBufferNode->mBufferFree;
195 mCurrBufferNode->mBufferFree += Len;
196 } else {
197 Node = CreateNewNode ();
198 if (Node == NULL) {
199 return NULL;
200 }
201
202 if (mBufferNodeQueueTail == NULL) {
203 mBufferNodeQueueHead = mBufferNodeQueueTail = Node;
204 } else {
205 mBufferNodeQueueTail->mNext = Node;
206 mBufferNodeQueueTail = Node;
207 }
208 mCurrBufferNode = Node;
209
210 //
211 // Now try again.
212 //
213 BinBuffer = mCurrBufferNode->mBufferFree;
214 mCurrBufferNode->mBufferFree += Len;
215 }
216
217 mPkgLength += Len;
218
219 return BinBuffer;
220 }
221
222 inline
223 UINT32
224 CFormPkg::GetPkgLength (
225 VOID
226 )
227 {
228 return mPkgLength;
229 }
230
231 VOID
232 CFormPkg::Open (
233 VOID
234 )
235 {
236 mReadBufferNode = mBufferNodeQueueHead;
237 mReadBufferOffset = 0;
238 }
239
240 VOID
241 CFormPkg::Close (
242 VOID
243 )
244 {
245 mReadBufferNode = NULL;
246 mReadBufferOffset = 0;
247 }
248
249 UINT32
250 CFormPkg::Read (
251 IN CHAR8 *Buffer,
252 IN UINT32 Size
253 )
254 {
255 UINT32 Index;
256
257 if ((Size == 0) || (Buffer == NULL)) {
258 return 0;
259 }
260
261 if (mReadBufferNode == NULL) {
262 return 0;
263 }
264
265 for (Index = 0; Index < Size; Index++) {
266 if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {
267 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];
268 } else {
269 if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {
270 return Index;
271 } else {
272 mReadBufferOffset = 0;
273 Index --;
274 }
275 }
276 }
277
278 return Size;
279 }
280
281 EFI_VFR_RETURN_CODE
282 CFormPkg::BuildPkgHdr (
283 OUT EFI_HII_PACKAGE_HEADER **PkgHdr
284 )
285 {
286 if (PkgHdr == NULL) {
287 return VFR_RETURN_FATAL_ERROR;
288 }
289
290 if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {
291 return VFR_RETURN_OUT_FOR_RESOURCES;
292 }
293
294 (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;
295 (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);
296
297 return VFR_RETURN_SUCCESS;
298 }
299
300 EFI_VFR_RETURN_CODE
301 CFormPkg::BuildPkg (
302 OUT PACKAGE_DATA &TBuffer
303 )
304 {
305
306 CHAR8 *Temp;
307 UINT32 Size;
308 CHAR8 Buffer[1024];
309
310 if (TBuffer.Buffer != NULL) {
311 delete TBuffer.Buffer;
312 }
313
314 TBuffer.Size = mPkgLength;
315 TBuffer.Buffer = NULL;
316 if (TBuffer.Size != 0) {
317 TBuffer.Buffer = new CHAR8[TBuffer.Size];
318 } else {
319 return VFR_RETURN_SUCCESS;
320 }
321
322 Temp = TBuffer.Buffer;
323 Open ();
324 while ((Size = Read (Buffer, 1024)) != 0) {
325 memcpy (Temp, Buffer, Size);
326 Temp += Size;
327 }
328 Close ();
329 return VFR_RETURN_SUCCESS;
330 }
331
332
333 EFI_VFR_RETURN_CODE
334 CFormPkg::BuildPkg (
335 IN FILE *Output,
336 IN PACKAGE_DATA *PkgData
337 )
338 {
339 EFI_VFR_RETURN_CODE Ret;
340 CHAR8 Buffer[1024];
341 UINT32 Size;
342 EFI_HII_PACKAGE_HEADER *PkgHdr;
343
344 if (Output == NULL) {
345 return VFR_RETURN_FATAL_ERROR;
346 }
347
348 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
349 return Ret;
350 }
351 fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);
352 delete PkgHdr;
353
354 if (PkgData == NULL) {
355 Open ();
356 while ((Size = Read (Buffer, 1024)) != 0) {
357 fwrite (Buffer, Size, 1, Output);
358 }
359 Close ();
360 } else {
361 fwrite (PkgData->Buffer, PkgData->Size, 1, Output);
362 }
363
364 return VFR_RETURN_SUCCESS;
365 }
366
367 VOID
368 CFormPkg::_WRITE_PKG_LINE (
369 IN FILE *pFile,
370 IN UINT32 LineBytes,
371 IN CONST CHAR8 *LineHeader,
372 IN CHAR8 *BlkBuf,
373 IN UINT32 BlkSize
374 )
375 {
376 UINT32 Index;
377
378 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
379 return;
380 }
381
382 for (Index = 0; Index < BlkSize; Index++) {
383 if ((Index % LineBytes) == 0) {
384 fprintf (pFile, "\n%s", LineHeader);
385 }
386 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
387 }
388 }
389
390 VOID
391 CFormPkg::_WRITE_PKG_END (
392 IN FILE *pFile,
393 IN UINT32 LineBytes,
394 IN CONST CHAR8 *LineHeader,
395 IN CHAR8 *BlkBuf,
396 IN UINT32 BlkSize
397 )
398 {
399 UINT32 Index;
400
401 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
402 return;
403 }
404
405 for (Index = 0; Index < BlkSize - 1; Index++) {
406 if ((Index % LineBytes) == 0) {
407 fprintf (pFile, "\n%s", LineHeader);
408 }
409 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
410 }
411
412 if ((Index % LineBytes) == 0) {
413 fprintf (pFile, "\n%s", LineHeader);
414 }
415 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
416 }
417
418 #define BYTES_PRE_LINE 0x10
419 UINT32 gAdjustOpcodeOffset = 0;
420 BOOLEAN gNeedAdjustOpcode = FALSE;
421 UINT32 gAdjustOpcodeLen = 0;
422
423 EFI_VFR_RETURN_CODE
424 CFormPkg::GenCFile (
425 IN CHAR8 *BaseName,
426 IN FILE *pFile,
427 IN PACKAGE_DATA *PkgData
428 )
429 {
430 EFI_VFR_RETURN_CODE Ret;
431 CHAR8 Buffer[BYTES_PRE_LINE * 8];
432 EFI_HII_PACKAGE_HEADER *PkgHdr;
433 UINT32 PkgLength = 0;
434 UINT32 ReadSize = 0;
435
436 if ((BaseName == NULL) || (pFile == NULL)) {
437 return VFR_RETURN_FATAL_ERROR;
438 }
439
440 fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);
441
442 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
443 return Ret;
444 }
445
446 //
447 // For framework vfr file, the extension framework header will be added.
448 //
449 if (VfrCompatibleMode) {
450 fprintf (pFile, " // FRAMEWORK PACKAGE HEADER Length\n");
451 PkgLength = PkgHdr->Length + sizeof (UINT32) + 2;
452 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32));
453 fprintf (pFile, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");
454 PkgLength = 3;
455 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT16));
456 } else {
457 fprintf (pFile, " // ARRAY LENGTH\n");
458 PkgLength = PkgHdr->Length + sizeof (UINT32);
459 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32));
460 }
461
462 fprintf (pFile, "\n\n // PACKAGE HEADER\n");
463 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));
464 PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);
465
466 fprintf (pFile, "\n\n // PACKAGE DATA\n");
467
468 if (PkgData == NULL) {
469 Open ();
470 while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {
471 PkgLength += ReadSize;
472 if (PkgLength < PkgHdr->Length) {
473 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);
474 } else {
475 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);
476 }
477 }
478 Close ();
479 } else {
480 if (PkgData->Size % BYTES_PRE_LINE != 0) {
481 PkgLength = PkgData->Size - (PkgData->Size % BYTES_PRE_LINE);
482 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);
483 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, PkgData->Size % BYTES_PRE_LINE);
484 } else {
485 PkgLength = PkgData->Size - BYTES_PRE_LINE;
486 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);
487 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, BYTES_PRE_LINE);
488 }
489 }
490
491 delete PkgHdr;
492 fprintf (pFile, "\n};\n");
493
494 return VFR_RETURN_SUCCESS;
495 }
496
497 EFI_VFR_RETURN_CODE
498 CFormPkg::AssignPending (
499 IN CHAR8 *Key,
500 IN VOID *ValAddr,
501 IN UINT32 ValLen,
502 IN UINT32 LineNo,
503 IN CONST CHAR8 *Msg
504 )
505 {
506 SPendingAssign *pNew;
507
508 pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);
509 if (pNew == NULL) {
510 return VFR_RETURN_OUT_FOR_RESOURCES;
511 }
512
513 pNew->mNext = PendingAssignList;
514 PendingAssignList = pNew;
515 return VFR_RETURN_SUCCESS;
516 }
517
518 VOID
519 CFormPkg::DoPendingAssign (
520 IN CHAR8 *Key,
521 IN VOID *ValAddr,
522 IN UINT32 ValLen
523 )
524 {
525 SPendingAssign *pNode;
526
527 if ((Key == NULL) || (ValAddr == NULL)) {
528 return;
529 }
530
531 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
532 if (strcmp (pNode->mKey, Key) == 0) {
533 pNode->AssignValue (ValAddr, ValLen);
534 }
535 }
536 }
537
538 bool
539 CFormPkg::HavePendingUnassigned (
540 VOID
541 )
542 {
543 SPendingAssign *pNode;
544
545 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
546 if (pNode->mFlag == PENDING) {
547 return TRUE;
548 }
549 }
550
551 return FALSE;
552 }
553
554 VOID
555 CFormPkg::PendingAssignPrintAll (
556 VOID
557 )
558 {
559 SPendingAssign *pNode;
560
561 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
562 if (pNode->mFlag == PENDING) {
563 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);
564 }
565 }
566 }
567
568 SBufferNode *
569 CFormPkg::GetBinBufferNodeForAddr (
570 IN CHAR8 *BinBuffAddr
571 )
572 {
573 SBufferNode *TmpNode;
574
575 TmpNode = mBufferNodeQueueHead;
576
577 while (TmpNode != NULL) {
578 if (TmpNode->mBufferStart <= BinBuffAddr && TmpNode->mBufferFree >= BinBuffAddr) {
579 return TmpNode;
580 }
581
582 TmpNode = TmpNode->mNext;
583 }
584
585 return NULL;
586 }
587
588 SBufferNode *
589 CFormPkg::GetNodeBefore(
590 IN SBufferNode *CurrentNode
591 )
592 {
593 SBufferNode *FirstNode = mBufferNodeQueueHead;
594 SBufferNode *LastNode = mBufferNodeQueueHead;
595
596 while (FirstNode != NULL) {
597 if (FirstNode == CurrentNode) {
598 break;
599 }
600
601 LastNode = FirstNode;
602 FirstNode = FirstNode->mNext;
603 }
604
605 if (FirstNode == NULL) {
606 LastNode = NULL;
607 }
608
609 return LastNode;
610 }
611
612 EFI_VFR_RETURN_CODE
613 CFormPkg::InsertNodeBefore(
614 IN SBufferNode *CurrentNode,
615 IN SBufferNode *NewNode
616 )
617 {
618 SBufferNode *LastNode = GetNodeBefore (CurrentNode);
619
620 if (LastNode == NULL) {
621 return VFR_RETURN_MISMATCHED;
622 }
623
624 NewNode->mNext = LastNode->mNext;
625 LastNode->mNext = NewNode;
626
627 return VFR_RETURN_SUCCESS;
628 }
629
630 CHAR8 *
631 CFormPkg::GetBufAddrBaseOnOffset (
632 IN UINT32 Offset
633 )
634 {
635 SBufferNode *TmpNode;
636 UINT32 TotalBufLen;
637 UINT32 CurrentBufLen;
638
639 TotalBufLen = 0;
640
641 for (TmpNode = mBufferNodeQueueHead; TmpNode != NULL; TmpNode = TmpNode->mNext) {
642 CurrentBufLen = TmpNode->mBufferFree - TmpNode->mBufferStart;
643 if (Offset >= TotalBufLen && Offset < TotalBufLen + CurrentBufLen) {
644 return TmpNode->mBufferStart + (Offset - TotalBufLen);
645 }
646
647 TotalBufLen += CurrentBufLen;
648 }
649
650 return NULL;
651 }
652
653 EFI_VFR_RETURN_CODE
654 CFormPkg::AdjustDynamicInsertOpcode (
655 IN CHAR8 *LastFormEndAddr,
656 IN CHAR8 *InsertOpcodeAddr
657 )
658 {
659 SBufferNode *LastFormEndNode;
660 SBufferNode *InsertOpcodeNode;
661 SBufferNode *NewRestoreNodeBegin;
662 SBufferNode *NewRestoreNodeEnd;
663 SBufferNode *NewLastEndNode;
664 SBufferNode *TmpNode;
665 UINT32 NeedRestoreCodeLen;
666
667 NewRestoreNodeEnd = NULL;
668
669 LastFormEndNode = GetBinBufferNodeForAddr(LastFormEndAddr);
670 InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);
671
672 if (LastFormEndNode == InsertOpcodeNode) {
673 //
674 // Create New Node to save the restore opcode.
675 //
676 NeedRestoreCodeLen = InsertOpcodeAddr - LastFormEndAddr;
677 gAdjustOpcodeLen = NeedRestoreCodeLen;
678 NewRestoreNodeBegin = CreateNewNode ();
679 if (NewRestoreNodeBegin == NULL) {
680 return VFR_RETURN_OUT_FOR_RESOURCES;
681 }
682 memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen);
683 NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;
684
685 //
686 // Override the restore buffer data.
687 //
688 memmove (LastFormEndAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);
689 InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen;
690 memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen);
691 } else {
692 //
693 // Create New Node to save the restore opcode.
694 //
695 NeedRestoreCodeLen = LastFormEndNode->mBufferFree - LastFormEndAddr;
696 gAdjustOpcodeLen = NeedRestoreCodeLen;
697 NewRestoreNodeBegin = CreateNewNode ();
698 if (NewRestoreNodeBegin == NULL) {
699 return VFR_RETURN_OUT_FOR_RESOURCES;
700 }
701 memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen);
702 NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;
703 //
704 // Override the restore buffer data.
705 //
706 LastFormEndNode->mBufferFree -= NeedRestoreCodeLen;
707 //
708 // Link the restore data to new node.
709 //
710 NewRestoreNodeBegin->mNext = LastFormEndNode->mNext;
711
712 //
713 // Count the Adjust opcode len.
714 //
715 TmpNode = LastFormEndNode->mNext;
716 while (TmpNode != InsertOpcodeNode) {
717 gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart;
718 TmpNode = TmpNode->mNext;
719 }
720
721 //
722 // Create New Node to save the last node of restore opcode.
723 //
724 NeedRestoreCodeLen = InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;
725 gAdjustOpcodeLen += NeedRestoreCodeLen;
726 if (NeedRestoreCodeLen > 0) {
727 NewRestoreNodeEnd = CreateNewNode ();
728 if (NewRestoreNodeEnd == NULL) {
729 return VFR_RETURN_OUT_FOR_RESOURCES;
730 }
731 memcpy (NewRestoreNodeEnd->mBufferFree, InsertOpcodeNode->mBufferStart, NeedRestoreCodeLen);
732 NewRestoreNodeEnd->mBufferFree += NeedRestoreCodeLen;
733 //
734 // Override the restore buffer data.
735 //
736 memmove (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);
737 InsertOpcodeNode->mBufferFree -= InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;
738
739 //
740 // Insert the last restore data node.
741 //
742 TmpNode = GetNodeBefore (InsertOpcodeNode);
743 if (TmpNode == LastFormEndNode) {
744 NewRestoreNodeBegin->mNext = NewRestoreNodeEnd;
745 } else {
746 TmpNode->mNext = NewRestoreNodeEnd;
747 }
748 //
749 // Connect the dynamic opcode node to the node before last form end node.
750 //
751 LastFormEndNode->mNext = InsertOpcodeNode;
752 }
753 }
754
755 if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {
756 //
757 // End form set opcode all in the mBufferNodeQueueTail node.
758 //
759 NewLastEndNode = CreateNewNode ();
760 if (NewLastEndNode == NULL) {
761 return VFR_RETURN_OUT_FOR_RESOURCES;
762 }
763 NewLastEndNode->mBufferStart[0] = 0x29;
764 NewLastEndNode->mBufferStart[1] = 0x02;
765 NewLastEndNode->mBufferFree += 2;
766
767 mBufferNodeQueueTail->mBufferFree -= 2;
768
769 mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;
770 if (NewRestoreNodeEnd != NULL) {
771 NewRestoreNodeEnd->mNext = NewLastEndNode;
772 } else {
773 NewRestoreNodeBegin->mNext = NewLastEndNode;
774 }
775
776 mBufferNodeQueueTail = NewLastEndNode;
777 } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {
778 TmpNode = GetNodeBefore(mBufferNodeQueueTail);
779 TmpNode->mNext = NewRestoreNodeBegin;
780 if (NewRestoreNodeEnd != NULL) {
781 NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;
782 } else {
783 NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;
784 }
785 }
786
787 return VFR_RETURN_SUCCESS;
788 }
789
790 EFI_VFR_RETURN_CODE
791 CFormPkg::DeclarePendingQuestion (
792 IN CVfrVarDataTypeDB &lCVfrVarDataTypeDB,
793 IN CVfrDataStorage &lCVfrDataStorage,
794 IN CVfrQuestionDB &lCVfrQuestionDB,
795 IN EFI_GUID *LocalFormSetGuid,
796 IN UINT32 LineNo,
797 OUT CHAR8 **InsertOpcodeAddr
798 )
799 {
800 SPendingAssign *pNode;
801 CHAR8 *VarStr;
802 UINT32 ArrayIdx;
803 CHAR8 FName[MAX_NAME_LEN];
804 CHAR8 *SName;
805 CHAR8 *NewStr;
806 UINT32 ShrinkSize;
807 EFI_VFR_RETURN_CODE ReturnCode;
808 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
809 EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;
810
811 //
812 // Declare all questions as Numeric in DisableIf True
813 //
814 // DisableIf
815 CIfrDisableIf DIObj;
816 DIObj.SetLineNo (LineNo);
817 *InsertOpcodeAddr = DIObj.GetObjBinAddr ();
818
819 //TrueOpcode
820 CIfrTrue TObj (LineNo);
821
822 // Declare Numeric qeustion for each undefined question.
823 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
824 if (pNode->mFlag == PENDING) {
825 CIfrNumeric CNObj;
826 EFI_VARSTORE_INFO Info;
827 EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
828
829 CNObj.SetLineNo (LineNo);
830 CNObj.SetPrompt (0x0);
831 CNObj.SetHelp (0x0);
832
833 //
834 // Register this question, assume it is normal question, not date or time question
835 //
836 VarStr = pNode->mKey;
837 ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);
838 if (ReturnCode != VFR_RETURN_SUCCESS) {
839 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
840 return ReturnCode;
841 }
842
843 #ifdef VFREXP_DEBUG
844 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);
845 #endif
846 //
847 // Get Question Info, framework vfr VarName == StructName
848 //
849 ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx);
850 if (ReturnCode != VFR_RETURN_SUCCESS) {
851 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");
852 return ReturnCode;
853 }
854 //
855 // Get VarStoreType
856 //
857 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);
858 if (ReturnCode != VFR_RETURN_SUCCESS) {
859 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");
860 return ReturnCode;
861 }
862 VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId);
863
864 if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {
865 ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);
866 } else {
867 if (VarStoreType == EFI_VFR_VARSTORE_EFI) {
868 ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);
869 } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {
870 VarStr = pNode->mKey;
871 //convert VarStr with store name to VarStr with structure name
872 ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);
873 if (ReturnCode == VFR_RETURN_SUCCESS) {
874 NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];
875 NewStr[0] = '\0';
876 strcpy (NewStr, SName);
877 strcat (NewStr, VarStr + strlen (FName));
878 ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);
879 delete NewStr;
880 }
881 } else {
882 ReturnCode = VFR_RETURN_UNSUPPORTED;
883 }
884 }
885 if (ReturnCode != VFR_RETURN_SUCCESS) {
886 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
887 return ReturnCode;
888 }
889
890 CNObj.SetQuestionId (QId);
891 CNObj.SetVarStoreInfo (&Info);
892 //
893 // Numeric doesn't support BOOLEAN data type.
894 // BOOLEAN type has the same data size to UINT8.
895 //
896 if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {
897 Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
898 }
899 CNObj.SetFlags (0, Info.mVarType);
900 //
901 // Use maximum value not to limit the vaild value for the undefined question.
902 //
903 switch (Info.mVarType) {
904 case EFI_IFR_TYPE_NUM_SIZE_64:
905 CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);
906 ShrinkSize = 0;
907 break;
908 case EFI_IFR_TYPE_NUM_SIZE_32:
909 CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);
910 ShrinkSize = 12;
911 break;
912 case EFI_IFR_TYPE_NUM_SIZE_16:
913 CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);
914 ShrinkSize = 18;
915 break;
916 case EFI_IFR_TYPE_NUM_SIZE_8:
917 CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);
918 ShrinkSize = 21;
919 break;
920 default:
921 break;
922 }
923 CNObj.ShrinkBinSize (ShrinkSize);
924
925 //
926 // For undefined Efi VarStore type question
927 // Append the extended guided opcode to contain VarName
928 //
929 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {
930 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);
931 CVNObj.SetLineNo (LineNo);
932 }
933
934 //
935 // End for Numeric
936 //
937 CIfrEnd CEObj;
938 CEObj.SetLineNo (LineNo);
939 }
940 }
941
942 //
943 // End for DisableIf
944 //
945 CIfrEnd SEObj;
946 SEObj.SetLineNo (LineNo);
947
948 return VFR_RETURN_SUCCESS;
949 }
950
951 CFormPkg gCFormPkg;
952
953 SIfrRecord::SIfrRecord (
954 VOID
955 )
956 {
957 mIfrBinBuf = NULL;
958 mBinBufLen = 0;
959 mLineNo = 0xFFFFFFFF;
960 mOffset = 0xFFFFFFFF;
961 mNext = NULL;
962 }
963
964 SIfrRecord::~SIfrRecord (
965 VOID
966 )
967 {
968 if (mIfrBinBuf != NULL) {
969 //delete mIfrBinBuf;
970 mIfrBinBuf = NULL;
971 }
972 mLineNo = 0xFFFFFFFF;
973 mOffset = 0xFFFFFFFF;
974 mBinBufLen = 0;
975 mNext = NULL;
976 }
977
978 CIfrRecordInfoDB::CIfrRecordInfoDB (
979 VOID
980 )
981 {
982 mSwitch = TRUE;
983 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;
984 mIfrRecordListHead = NULL;
985 mIfrRecordListTail = NULL;
986 }
987
988 CIfrRecordInfoDB::~CIfrRecordInfoDB (
989 VOID
990 )
991 {
992 SIfrRecord *pNode;
993
994 while (mIfrRecordListHead != NULL) {
995 pNode = mIfrRecordListHead;
996 mIfrRecordListHead = mIfrRecordListHead->mNext;
997 delete pNode;
998 }
999 }
1000
1001 SIfrRecord *
1002 CIfrRecordInfoDB::GetRecordInfoFromIdx (
1003 IN UINT32 RecordIdx
1004 )
1005 {
1006 UINT32 Idx;
1007 SIfrRecord *pNode = NULL;
1008
1009 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {
1010 return NULL;
1011 }
1012
1013 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;
1014 (Idx != RecordIdx) && (pNode != NULL);
1015 Idx++, pNode = pNode->mNext)
1016 ;
1017
1018 return pNode;
1019 }
1020
1021 UINT32
1022 CIfrRecordInfoDB::IfrRecordRegister (
1023 IN UINT32 LineNo,
1024 IN CHAR8 *IfrBinBuf,
1025 IN UINT8 BinBufLen,
1026 IN UINT32 Offset
1027 )
1028 {
1029 SIfrRecord *pNew;
1030
1031 if (mSwitch == FALSE) {
1032 return EFI_IFR_RECORDINFO_IDX_INVALUD;
1033 }
1034
1035 if ((pNew = new SIfrRecord) == NULL) {
1036 return EFI_IFR_RECORDINFO_IDX_INVALUD;
1037 }
1038
1039 if (mIfrRecordListHead == NULL) {
1040 mIfrRecordListHead = pNew;
1041 mIfrRecordListTail = pNew;
1042 } else {
1043 mIfrRecordListTail->mNext = pNew;
1044 mIfrRecordListTail = pNew;
1045 }
1046 mRecordCount++;
1047
1048 return mRecordCount;
1049 }
1050
1051 VOID
1052 CIfrRecordInfoDB::IfrRecordInfoUpdate (
1053 IN UINT32 RecordIdx,
1054 IN UINT32 LineNo,
1055 IN CHAR8 *BinBuf,
1056 IN UINT8 BinBufLen,
1057 IN UINT32 Offset
1058 )
1059 {
1060 SIfrRecord *pNode;
1061 SIfrRecord *Prev;
1062
1063 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {
1064 return;
1065 }
1066
1067 if (LineNo == 0) {
1068 //
1069 // Line number is not specified explicitly, try to use line number of previous opcode
1070 //
1071 Prev = GetRecordInfoFromIdx (RecordIdx - 1);
1072 if (Prev != NULL) {
1073 LineNo = Prev->mLineNo;
1074 }
1075 }
1076
1077 pNode->mLineNo = LineNo;
1078 pNode->mOffset = Offset;
1079 pNode->mBinBufLen = BinBufLen;
1080 pNode->mIfrBinBuf = BinBuf;
1081
1082 }
1083
1084 VOID
1085 CIfrRecordInfoDB::IfrRecordOutput (
1086 OUT PACKAGE_DATA &TBuffer
1087 )
1088 {
1089 CHAR8 *Temp;
1090 SIfrRecord *pNode;
1091
1092 if (TBuffer.Buffer != NULL) {
1093 delete TBuffer.Buffer;
1094 }
1095
1096 TBuffer.Size = 0;
1097 TBuffer.Buffer = NULL;
1098
1099
1100 if (mSwitch == FALSE) {
1101 return;
1102 }
1103
1104 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1105 TBuffer.Size += pNode->mBinBufLen;
1106 }
1107
1108 if (TBuffer.Size != 0) {
1109 TBuffer.Buffer = new CHAR8[TBuffer.Size];
1110 } else {
1111 return;
1112 }
1113
1114 Temp = TBuffer.Buffer;
1115
1116 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1117 if (pNode->mIfrBinBuf != NULL) {
1118 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);
1119 Temp += pNode->mBinBufLen;
1120 }
1121 }
1122
1123 return;
1124 }
1125
1126 VOID
1127 CIfrRecordInfoDB::IfrRecordOutput (
1128 IN FILE *File,
1129 IN UINT32 LineNo
1130 )
1131 {
1132 SIfrRecord *pNode;
1133 UINT8 Index;
1134 UINT32 TotalSize;
1135
1136 if (mSwitch == FALSE) {
1137 return;
1138 }
1139
1140 if (File == NULL) {
1141 return;
1142 }
1143
1144 TotalSize = 0;
1145
1146 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1147 if (pNode->mLineNo == LineNo || LineNo == 0) {
1148 fprintf (File, ">%08X: ", pNode->mOffset);
1149 TotalSize += pNode->mBinBufLen;
1150 if (pNode->mIfrBinBuf != NULL) {
1151 for (Index = 0; Index < pNode->mBinBufLen; Index++) {
1152 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));
1153 }
1154 }
1155 fprintf (File, "\n");
1156 }
1157 }
1158
1159 if (LineNo == 0) {
1160 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);
1161 }
1162 }
1163
1164 //
1165 // for framework vfr file
1166 // adjust opcode sequence for uefi IFR format
1167 // adjust inconsistent and varstore into the right position.
1168 //
1169 BOOLEAN
1170 CIfrRecordInfoDB::CheckQuestionOpCode (
1171 IN UINT8 OpCode
1172 )
1173 {
1174 switch (OpCode) {
1175 case EFI_IFR_CHECKBOX_OP:
1176 case EFI_IFR_NUMERIC_OP:
1177 case EFI_IFR_PASSWORD_OP:
1178 case EFI_IFR_ONE_OF_OP:
1179 case EFI_IFR_ACTION_OP:
1180 case EFI_IFR_STRING_OP:
1181 case EFI_IFR_DATE_OP:
1182 case EFI_IFR_TIME_OP:
1183 case EFI_IFR_ORDERED_LIST_OP:
1184 return TRUE;
1185 default:
1186 return FALSE;
1187 }
1188 }
1189
1190 BOOLEAN
1191 CIfrRecordInfoDB::CheckIdOpCode (
1192 IN UINT8 OpCode
1193 )
1194 {
1195 switch (OpCode) {
1196 case EFI_IFR_EQ_ID_VAL_OP:
1197 case EFI_IFR_EQ_ID_ID_OP:
1198 case EFI_IFR_EQ_ID_VAL_LIST_OP:
1199 case EFI_IFR_QUESTION_REF1_OP:
1200 return TRUE;
1201 default:
1202 return FALSE;
1203 }
1204 }
1205
1206 EFI_QUESTION_ID
1207 CIfrRecordInfoDB::GetOpcodeQuestionId (
1208 IN EFI_IFR_OP_HEADER *OpHead
1209 )
1210 {
1211 EFI_IFR_QUESTION_HEADER *QuestionHead;
1212
1213 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);
1214
1215 return QuestionHead->QuestionId;
1216 }
1217
1218 SIfrRecord *
1219 CIfrRecordInfoDB::GetRecordInfoFromOffset (
1220 IN UINT32 Offset
1221 )
1222 {
1223 SIfrRecord *pNode = NULL;
1224
1225 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1226 if (pNode->mOffset == Offset) {
1227 return pNode;
1228 }
1229 }
1230
1231 return pNode;
1232 }
1233
1234 /*
1235 Add just the op code position.
1236
1237 From
1238
1239 | form end opcode + end of if opcode for form ... + Dynamic opcode + form set end opcode |
1240
1241 To
1242
1243 | Dynamic opcode + form end opcode + end of if opcode for form ... + form set end opcode |
1244
1245 */
1246 BOOLEAN
1247 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
1248 VOID
1249 )
1250 {
1251 UINT32 OpcodeOffset;
1252 SIfrRecord *pNode, *pPreNode;
1253 SIfrRecord *pStartNode, *pNodeBeforeStart;
1254 SIfrRecord *pEndNode;
1255
1256 pStartNode = NULL;
1257 pEndNode = NULL;
1258 OpcodeOffset = 0;
1259
1260 //
1261 // Base on the offset info to get the node.
1262 //
1263 for (pNode = mIfrRecordListHead; pNode->mNext != NULL; pPreNode = pNode,pNode = pNode->mNext) {
1264 if (OpcodeOffset == gAdjustOpcodeOffset) {
1265 pStartNode = pNode;
1266 pNodeBeforeStart = pPreNode;
1267 } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {
1268 pEndNode = pPreNode;
1269 }
1270
1271 OpcodeOffset += pNode->mBinBufLen;
1272 }
1273
1274 //
1275 // Check the value.
1276 //
1277 if (pEndNode == NULL || pStartNode == NULL) {
1278 return FALSE;
1279 }
1280
1281 //
1282 // Adjust the node. pPreNode save the Node before mIfrRecordListTail
1283 //
1284 pNodeBeforeStart->mNext = pEndNode->mNext;
1285 pPreNode->mNext = pStartNode;
1286 pEndNode->mNext = mIfrRecordListTail;
1287
1288 return TRUE;
1289 }
1290
1291 VOID
1292 CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
1293 VOID
1294 )
1295 {
1296 UINT32 OpcodeOffset;
1297 SIfrRecord *pNode;
1298
1299 OpcodeOffset = 0;
1300 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1301 pNode->mOffset = OpcodeOffset;
1302 OpcodeOffset += pNode->mBinBufLen;
1303 }
1304 }
1305
1306 EFI_VFR_RETURN_CODE
1307 CIfrRecordInfoDB::IfrRecordAdjust (
1308 VOID
1309 )
1310 {
1311 SIfrRecord *pNode, *preNode;
1312 SIfrRecord *uNode, *tNode;
1313 EFI_IFR_OP_HEADER *OpHead, *tOpHead;
1314 EFI_QUESTION_ID QuestionId;
1315 UINT32 StackCount;
1316 UINT32 QuestionScope;
1317 UINT32 OpcodeOffset;
1318 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };
1319 EFI_VFR_RETURN_CODE Status;
1320
1321 //
1322 // Init local variable
1323 //
1324 Status = VFR_RETURN_SUCCESS;
1325 pNode = mIfrRecordListHead;
1326 preNode = pNode;
1327 QuestionScope = 0;
1328 while (pNode != NULL) {
1329 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
1330
1331 //
1332 // make sure the inconsistent opcode in question scope
1333 //
1334 if (QuestionScope > 0) {
1335 QuestionScope += OpHead->Scope;
1336 if (OpHead->OpCode == EFI_IFR_END_OP) {
1337 QuestionScope --;
1338 }
1339 }
1340
1341 if (CheckQuestionOpCode (OpHead->OpCode)) {
1342 QuestionScope = 1;
1343 }
1344 //
1345 // for the inconsistent opcode not in question scope, adjust it
1346 //
1347 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {
1348 //
1349 // for inconsistent opcode not in question scope
1350 //
1351
1352 //
1353 // Count inconsistent opcode Scope
1354 //
1355 StackCount = OpHead->Scope;
1356 QuestionId = EFI_QUESTION_ID_INVALID;
1357 tNode = pNode;
1358 while (tNode != NULL && StackCount > 0) {
1359 tNode = tNode->mNext;
1360 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;
1361 //
1362 // Calculate Scope Number
1363 //
1364 StackCount += tOpHead->Scope;
1365 if (tOpHead->OpCode == EFI_IFR_END_OP) {
1366 StackCount --;
1367 }
1368 //
1369 // by IdEqual opcode to get QuestionId
1370 //
1371 if (QuestionId == EFI_QUESTION_ID_INVALID &&
1372 CheckIdOpCode (tOpHead->OpCode)) {
1373 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);
1374 }
1375 }
1376 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {
1377 //
1378 // report error; not found
1379 //
1380 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);
1381 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
1382 Status = VFR_RETURN_MISMATCHED;
1383 break;
1384 }
1385 //
1386 // extract inconsistent opcode list
1387 // pNode is Incosistent opcode, tNode is End Opcode
1388 //
1389
1390 //
1391 // insert inconsistent opcode list into the right question scope by questionid
1392 //
1393 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {
1394 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;
1395 if (CheckQuestionOpCode (tOpHead->OpCode) &&
1396 (QuestionId == GetOpcodeQuestionId (tOpHead))) {
1397 break;
1398 }
1399 }
1400 //
1401 // insert inconsistent opcode list and check LATE_CHECK flag
1402 //
1403 if (uNode != NULL) {
1404 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {
1405 //
1406 // if LATE_CHECK flag is set, change inconsistent to nosumbit
1407 //
1408 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;
1409 }
1410
1411 //
1412 // skip the default storage for Date and Time
1413 //
1414 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {
1415 uNode = uNode->mNext;
1416 }
1417
1418 preNode->mNext = tNode->mNext;
1419 tNode->mNext = uNode->mNext;
1420 uNode->mNext = pNode;
1421 //
1422 // reset pNode to head list, scan the whole list again.
1423 //
1424 pNode = mIfrRecordListHead;
1425 preNode = pNode;
1426 QuestionScope = 0;
1427 continue;
1428 } else {
1429 //
1430 // not found matched question id, report error
1431 //
1432 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);
1433 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
1434 Status = VFR_RETURN_MISMATCHED;
1435 break;
1436 }
1437 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP ||
1438 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {
1439 //
1440 // for new added group of varstore opcode
1441 //
1442 tNode = pNode;
1443 while (tNode->mNext != NULL) {
1444 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;
1445 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP &&
1446 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {
1447 break;
1448 }
1449 tNode = tNode->mNext;
1450 }
1451
1452 if (tNode->mNext == NULL) {
1453 //
1454 // invalid IfrCode, IfrCode end by EndOpCode
1455 //
1456 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");
1457 Status = VFR_RETURN_MISMATCHED;
1458 break;
1459 }
1460
1461 if (tOpHead->OpCode != EFI_IFR_END_OP) {
1462 //
1463 // not new added varstore, which are not needed to be adjust.
1464 //
1465 preNode = tNode;
1466 pNode = tNode->mNext;
1467 continue;
1468 } else {
1469 //
1470 // move new added varstore opcode to the position befor form opcode
1471 // varstore opcode between pNode and tNode
1472 //
1473
1474 //
1475 // search form opcode from begin
1476 //
1477 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {
1478 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;
1479 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {
1480 break;
1481 }
1482 }
1483 //
1484 // Insert varstore opcode beform form opcode if form opcode is found
1485 //
1486 if (uNode->mNext != NULL) {
1487 preNode->mNext = tNode->mNext;
1488 tNode->mNext = uNode->mNext;
1489 uNode->mNext = pNode;
1490 //
1491 // reset pNode to head list, scan the whole list again.
1492 //
1493 pNode = mIfrRecordListHead;
1494 preNode = pNode;
1495 QuestionScope = 0;
1496 continue;
1497 } else {
1498 //
1499 // not found form, continue scan IfrRecord list
1500 //
1501 preNode = tNode;
1502 pNode = tNode->mNext;
1503 continue;
1504 }
1505 }
1506 }
1507 //
1508 // next node
1509 //
1510 preNode = pNode;
1511 pNode = pNode->mNext;
1512 }
1513
1514 //
1515 // Update Ifr Opcode Offset
1516 //
1517 if (Status == VFR_RETURN_SUCCESS) {
1518 IfrAdjustOffsetForRecord ();
1519 }
1520 return Status;
1521 }
1522
1523 CIfrRecordInfoDB gCIfrRecordInfoDB;
1524
1525 VOID
1526 CIfrObj::_EMIT_PENDING_OBJ (
1527 VOID
1528 )
1529 {
1530 CHAR8 *ObjBinBuf = NULL;
1531
1532 //
1533 // do nothing
1534 //
1535 if (!mDelayEmit || !gCreateOp) {
1536 return;
1537 }
1538
1539 mPkgOffset = gCFormPkg.GetPkgLength ();
1540 //
1541 // update data buffer to package data
1542 //
1543 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);
1544 if (ObjBinBuf != NULL) {
1545 memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);
1546 }
1547
1548 //
1549 // update bin buffer to package data buffer
1550 //
1551 if (mObjBinBuf != NULL) {
1552 delete mObjBinBuf;
1553 mObjBinBuf = ObjBinBuf;
1554 }
1555
1556 mDelayEmit = FALSE;
1557 }
1558
1559 /*
1560 * The definition of CIfrObj's member function
1561 */
1562 static struct {
1563 UINT8 mSize;
1564 UINT8 mScope;
1565 } gOpcodeSizesScopeTable[] = {
1566 { 0, 0 }, // EFI_IFR_INVALID - 0x00
1567 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP
1568 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP
1569 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP
1570 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP
1571 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
1572 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP
1573 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP
1574 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP
1575 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
1576 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
1577 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP
1578 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP
1579 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP
1580 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE
1581 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP
1582 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
1583 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
1584 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP
1585 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP
1586 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
1587 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP
1588 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP
1589 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP
1590 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP
1591 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
1592 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP
1593 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP
1594 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP
1595 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP
1596 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
1597 { 0, 0 }, // 0x1F
1598 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
1599 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
1600 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22
1601 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
1602 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP
1603 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
1604 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP
1605 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
1606 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28
1607 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP
1608 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A
1609 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B
1610 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C
1611 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D
1612 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E
1613 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
1614 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP
1615 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP
1616 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP
1617 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP
1618 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
1619 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP
1620 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP
1621 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP
1622 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP
1623 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
1624 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A
1625 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP
1626 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP
1627 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP
1628 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E
1629 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP
1630 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP
1631 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
1632 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8
1633 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16
1634 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32
1635 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64
1636 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46
1637 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP
1638 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP
1639 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP
1640 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP
1641 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP
1642 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP
1643 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP
1644 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
1645 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP
1646 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP
1647 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP
1648 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP
1649 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP
1650 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP
1651 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP
1652 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP
1653 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57
1654 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP
1655 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP
1656 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP
1657 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP
1658 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
1659 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
1660 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP
1661 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP
1662 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60
1663 { sizeof (EFI_IFR_MODAL_TAG), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61
1664 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
1665 { sizeof (EFI_IFR_WARNING_IF), 1}, // EFI_IFR_WARNING_IF_OP - 0x63
1666 { sizeof (EFI_IFR_MATCH2), 0 }, // EFI_IFR_MATCH2_OP - 0x64
1667 };
1668
1669 #ifdef CIFROBJ_DEUBG
1670 static struct {
1671 CHAR8 *mIfrName;
1672 } gIfrObjPrintDebugTable[] = {
1673 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
1674 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
1675 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
1676 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
1677 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
1678 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
1679 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
1680 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
1681 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
1682 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
1683 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
1684 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
1685 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
1686 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
1687 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
1688 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
1689 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",
1690 };
1691
1692 VOID
1693 CIFROBJ_DEBUG_PRINT (
1694 IN UINT8 OpCode
1695 )
1696 {
1697 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);
1698 }
1699 #else
1700
1701 #define CIFROBJ_DEBUG_PRINT(OpCode)
1702
1703 #endif
1704
1705 BOOLEAN gCreateOp = TRUE;
1706
1707 CIfrObj::CIfrObj (
1708 IN UINT8 OpCode,
1709 OUT CHAR8 **IfrObj,
1710 IN UINT8 ObjBinLen,
1711 IN BOOLEAN DelayEmit
1712 )
1713 {
1714 mDelayEmit = DelayEmit;
1715 mPkgOffset = gCFormPkg.GetPkgLength ();
1716 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;
1717 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];
1718 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;
1719
1720 if (IfrObj != NULL) {
1721 *IfrObj = mObjBinBuf;
1722 }
1723
1724 CIFROBJ_DEBUG_PRINT (OpCode);
1725 }
1726
1727 CIfrObj::~CIfrObj (
1728 VOID
1729 )
1730 {
1731 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {
1732 _EMIT_PENDING_OBJ ();
1733 }
1734
1735 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);
1736 }
1737
1738 /*
1739 * The definition of CIfrObj's member function
1740 */
1741 UINT8 gScopeCount = 0;
1742
1743 CIfrOpHeader::CIfrOpHeader (
1744 IN UINT8 OpCode,
1745 IN VOID *StartAddr,
1746 IN UINT8 Length
1747 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)
1748 {
1749 mHeader->OpCode = OpCode;
1750 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;
1751 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;
1752 }
1753
1754 CIfrOpHeader::CIfrOpHeader (
1755 IN CIfrOpHeader &OpHdr
1756 )
1757 {
1758 mHeader = OpHdr.mHeader;
1759 }
1760
1761 UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };