]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
Sync BaseTools Branch (version r2321) to EDKII main trunk.
[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 - 2010, 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 memcpy (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 = 4096
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 CHAR8 *
156 CFormPkg::IfrBinBufferGet (
157 IN UINT32 Len
158 )
159 {
160 CHAR8 *BinBuffer = NULL;
161
162 if ((Len == 0) || (Len > mBufferSize)) {
163 return NULL;
164 }
165
166 if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {
167 BinBuffer = mCurrBufferNode->mBufferFree;
168 mCurrBufferNode->mBufferFree += Len;
169 } else {
170 SBufferNode *Node;
171
172 Node = new SBufferNode;
173 if (Node == NULL) {
174 return NULL;
175 }
176
177 Node->mBufferStart = new CHAR8[mBufferSize];
178 if (Node->mBufferStart == NULL) {
179 delete Node;
180 return NULL;
181 } else {
182 memset (Node->mBufferStart, 0, mBufferSize);
183 Node->mBufferEnd = Node->mBufferStart + mBufferSize;
184 Node->mBufferFree = Node->mBufferStart;
185 Node->mNext = NULL;
186 }
187
188 if (mBufferNodeQueueTail == NULL) {
189 mBufferNodeQueueHead = mBufferNodeQueueTail = Node;
190 } else {
191 mBufferNodeQueueTail->mNext = Node;
192 mBufferNodeQueueTail = Node;
193 }
194 mCurrBufferNode = Node;
195
196 //
197 // Now try again.
198 //
199 BinBuffer = mCurrBufferNode->mBufferFree;
200 mCurrBufferNode->mBufferFree += Len;
201 }
202
203 mPkgLength += Len;
204
205 return BinBuffer;
206 }
207
208 inline
209 UINT32
210 CFormPkg::GetPkgLength (
211 VOID
212 )
213 {
214 return mPkgLength;
215 }
216
217 VOID
218 CFormPkg::Open (
219 VOID
220 )
221 {
222 mReadBufferNode = mBufferNodeQueueHead;
223 mReadBufferOffset = 0;
224 }
225
226 VOID
227 CFormPkg::Close (
228 VOID
229 )
230 {
231 mReadBufferNode = NULL;
232 mReadBufferOffset = 0;
233 }
234
235 UINT32
236 CFormPkg::Read (
237 IN CHAR8 *Buffer,
238 IN UINT32 Size
239 )
240 {
241 UINT32 Index;
242
243 if ((Size == 0) || (Buffer == NULL)) {
244 return 0;
245 }
246
247 if (mReadBufferNode == NULL) {
248 return 0;
249 }
250
251 for (Index = 0; Index < Size; Index++) {
252 if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {
253 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];
254 } else {
255 if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {
256 return Index;
257 } else {
258 mReadBufferOffset = 0;
259 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];
260 }
261 }
262 }
263
264 return Size;
265 }
266
267 EFI_VFR_RETURN_CODE
268 CFormPkg::BuildPkgHdr (
269 OUT EFI_HII_PACKAGE_HEADER **PkgHdr
270 )
271 {
272 if (PkgHdr == NULL) {
273 return VFR_RETURN_FATAL_ERROR;
274 }
275
276 if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {
277 return VFR_RETURN_OUT_FOR_RESOURCES;
278 }
279
280 (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;
281 (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);
282
283 return VFR_RETURN_SUCCESS;
284 }
285
286 EFI_VFR_RETURN_CODE
287 CFormPkg::BuildPkg (
288 OUT PACKAGE_DATA &TBuffer
289 )
290 {
291
292 CHAR8 *Temp;
293 UINT32 Size;
294 CHAR8 Buffer[1024];
295
296 if (TBuffer.Buffer != NULL) {
297 delete TBuffer.Buffer;
298 }
299
300 TBuffer.Size = mPkgLength;
301 TBuffer.Buffer = NULL;
302 if (TBuffer.Size != 0) {
303 TBuffer.Buffer = new CHAR8[TBuffer.Size];
304 } else {
305 return VFR_RETURN_SUCCESS;
306 }
307
308 Temp = TBuffer.Buffer;
309 Open ();
310 while ((Size = Read (Buffer, 1024)) != 0) {
311 memcpy (Temp, Buffer, Size);
312 Temp += Size;
313 }
314 Close ();
315 return VFR_RETURN_SUCCESS;
316 }
317
318
319 EFI_VFR_RETURN_CODE
320 CFormPkg::BuildPkg (
321 IN FILE *Output,
322 IN PACKAGE_DATA *PkgData
323 )
324 {
325 EFI_VFR_RETURN_CODE Ret;
326 CHAR8 Buffer[1024];
327 UINT32 Size;
328 EFI_HII_PACKAGE_HEADER *PkgHdr;
329
330 if (Output == NULL) {
331 return VFR_RETURN_FATAL_ERROR;
332 }
333
334 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
335 return Ret;
336 }
337 fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);
338 delete PkgHdr;
339
340 if (PkgData == NULL) {
341 Open ();
342 while ((Size = Read (Buffer, 1024)) != 0) {
343 fwrite (Buffer, Size, 1, Output);
344 }
345 Close ();
346 } else {
347 fwrite (PkgData->Buffer, PkgData->Size, 1, Output);
348 }
349
350 return VFR_RETURN_SUCCESS;
351 }
352
353 VOID
354 CFormPkg::_WRITE_PKG_LINE (
355 IN FILE *pFile,
356 IN UINT32 LineBytes,
357 IN CONST CHAR8 *LineHeader,
358 IN CHAR8 *BlkBuf,
359 IN UINT32 BlkSize
360 )
361 {
362 UINT32 Index;
363
364 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
365 return;
366 }
367
368 for (Index = 0; Index < BlkSize; Index++) {
369 if ((Index % LineBytes) == 0) {
370 fprintf (pFile, "\n%s", LineHeader);
371 }
372 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
373 }
374 }
375
376 VOID
377 CFormPkg::_WRITE_PKG_END (
378 IN FILE *pFile,
379 IN UINT32 LineBytes,
380 IN CONST CHAR8 *LineHeader,
381 IN CHAR8 *BlkBuf,
382 IN UINT32 BlkSize
383 )
384 {
385 UINT32 Index;
386
387 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
388 return;
389 }
390
391 for (Index = 0; Index < BlkSize - 1; Index++) {
392 if ((Index % LineBytes) == 0) {
393 fprintf (pFile, "\n%s", LineHeader);
394 }
395 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
396 }
397
398 if ((Index % LineBytes) == 0) {
399 fprintf (pFile, "\n%s", LineHeader);
400 }
401 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
402 }
403
404 #define BYTES_PRE_LINE 0x10
405
406 EFI_VFR_RETURN_CODE
407 CFormPkg::GenCFile (
408 IN CHAR8 *BaseName,
409 IN FILE *pFile,
410 IN PACKAGE_DATA *PkgData
411 )
412 {
413 EFI_VFR_RETURN_CODE Ret;
414 CHAR8 Buffer[BYTES_PRE_LINE * 8];
415 EFI_HII_PACKAGE_HEADER *PkgHdr;
416 UINT32 PkgLength = 0;
417 UINT32 ReadSize = 0;
418
419 if ((BaseName == NULL) || (pFile == NULL)) {
420 return VFR_RETURN_FATAL_ERROR;
421 }
422
423 fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);
424
425 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
426 return Ret;
427 }
428
429 //
430 // For framework vfr file, the extension framework header will be added.
431 //
432 if (VfrCompatibleMode) {
433 fprintf (pFile, " // FRAMEWORK PACKAGE HEADER Length\n");
434 PkgLength = PkgHdr->Length + sizeof (UINT32) + 2;
435 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32));
436 fprintf (pFile, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");
437 PkgLength = 3;
438 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT16));
439 } else {
440 fprintf (pFile, " // ARRAY LENGTH\n");
441 PkgLength = PkgHdr->Length + sizeof (UINT32);
442 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32));
443 }
444
445 fprintf (pFile, "\n\n // PACKAGE HEADER\n");
446 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));
447 PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);
448
449 fprintf (pFile, "\n\n // PACKAGE DATA\n");
450
451 if (PkgData == NULL) {
452 Open ();
453 while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {
454 PkgLength += ReadSize;
455 if (PkgLength < PkgHdr->Length) {
456 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);
457 } else {
458 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);
459 }
460 }
461 Close ();
462 } else {
463 if (PkgData->Size % BYTES_PRE_LINE != 0) {
464 PkgLength = PkgData->Size - (PkgData->Size % BYTES_PRE_LINE);
465 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);
466 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, PkgData->Size % BYTES_PRE_LINE);
467 } else {
468 PkgLength = PkgData->Size - BYTES_PRE_LINE;
469 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);
470 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, BYTES_PRE_LINE);
471 }
472 }
473
474 delete PkgHdr;
475 fprintf (pFile, "\n};\n");
476
477 return VFR_RETURN_SUCCESS;
478 }
479
480 EFI_VFR_RETURN_CODE
481 CFormPkg::AssignPending (
482 IN CHAR8 *Key,
483 IN VOID *ValAddr,
484 IN UINT32 ValLen,
485 IN UINT32 LineNo,
486 IN CONST CHAR8 *Msg
487 )
488 {
489 SPendingAssign *pNew;
490
491 pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);
492 if (pNew == NULL) {
493 return VFR_RETURN_OUT_FOR_RESOURCES;
494 }
495
496 pNew->mNext = PendingAssignList;
497 PendingAssignList = pNew;
498 return VFR_RETURN_SUCCESS;
499 }
500
501 VOID
502 CFormPkg::DoPendingAssign (
503 IN CHAR8 *Key,
504 IN VOID *ValAddr,
505 IN UINT32 ValLen
506 )
507 {
508 SPendingAssign *pNode;
509
510 if ((Key == NULL) || (ValAddr == NULL)) {
511 return;
512 }
513
514 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
515 if (strcmp (pNode->mKey, Key) == 0) {
516 pNode->AssignValue (ValAddr, ValLen);
517 }
518 }
519 }
520
521 bool
522 CFormPkg::HavePendingUnassigned (
523 VOID
524 )
525 {
526 SPendingAssign *pNode;
527
528 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
529 if (pNode->mFlag == PENDING) {
530 return TRUE;
531 }
532 }
533
534 return FALSE;
535 }
536
537 VOID
538 CFormPkg::PendingAssignPrintAll (
539 VOID
540 )
541 {
542 SPendingAssign *pNode;
543
544 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
545 if (pNode->mFlag == PENDING) {
546 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);
547 }
548 }
549 }
550
551 EFI_VFR_RETURN_CODE
552 CFormPkg::DeclarePendingQuestion (
553 IN CVfrVarDataTypeDB &lCVfrVarDataTypeDB,
554 IN CVfrDataStorage &lCVfrDataStorage,
555 IN CVfrQuestionDB &lCVfrQuestionDB,
556 IN EFI_GUID *LocalFormSetGuid,
557 IN UINT32 LineNo
558 )
559 {
560 SPendingAssign *pNode;
561 CHAR8 *VarStr;
562 UINT32 ArrayIdx;
563 CHAR8 FName[MAX_NAME_LEN];
564 CHAR8 *SName;
565 CHAR8 *NewStr;
566 EFI_VFR_RETURN_CODE ReturnCode;
567 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
568
569 //
570 // Declare all questions as Numeric in DisableIf True
571 //
572 // DisableIf
573 CIfrDisableIf DIObj;
574 DIObj.SetLineNo (LineNo);
575
576 //TrueOpcode
577 CIfrTrue TObj (LineNo);
578
579 // Declare Numeric qeustion for each undefined question.
580 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
581 if (pNode->mFlag == PENDING) {
582 CIfrNumeric CNObj;
583 EFI_VARSTORE_INFO Info;
584 EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
585
586 CNObj.SetLineNo (LineNo);
587 CNObj.SetPrompt (0x0);
588 CNObj.SetHelp (0x0);
589
590 //
591 // Register this question, assume it is normal question, not date or time question
592 //
593 VarStr = pNode->mKey;
594 ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);
595 if (ReturnCode != VFR_RETURN_SUCCESS) {
596 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
597 return ReturnCode;
598 }
599
600 #ifdef VFREXP_DEBUG
601 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);
602 #endif
603 //
604 // Get Question Info, framework vfr VarName == StructName
605 //
606 ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx);
607 if (ReturnCode != VFR_RETURN_SUCCESS) {
608 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");
609 return ReturnCode;
610 }
611 //
612 // Get VarStoreType
613 //
614 ReturnCode = lCVfrDataStorage.GetVarStoreType (FName, VarStoreType);
615 if (ReturnCode == VFR_RETURN_UNDEFINED) {
616 lCVfrDataStorage.DeclareBufferVarStore (
617 FName,
618 LocalFormSetGuid,
619 &lCVfrVarDataTypeDB,
620 FName,
621 EFI_VARSTORE_ID_INVALID,
622 FALSE
623 );
624 ReturnCode = lCVfrDataStorage.GetVarStoreType (FName, VarStoreType);
625 }
626 if (ReturnCode != VFR_RETURN_SUCCESS) {
627 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");
628 return ReturnCode;
629 }
630
631 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);
632 if (ReturnCode != VFR_RETURN_SUCCESS) {
633 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");
634 return ReturnCode;
635 }
636
637 if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {
638 ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);
639 } else {
640 if (VarStoreType == EFI_VFR_VARSTORE_EFI) {
641 ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);
642 } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {
643 VarStr = pNode->mKey;
644 //convert VarStr with store name to VarStr with structure name
645 ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (FName, &SName);
646 if (ReturnCode == VFR_RETURN_SUCCESS) {
647 NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];
648 NewStr[0] = '\0';
649 strcpy (NewStr, SName);
650 strcat (NewStr, VarStr + strlen (FName));
651 ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);
652 delete NewStr;
653 }
654 } else {
655 ReturnCode = VFR_RETURN_UNSUPPORTED;
656 }
657 }
658 if (ReturnCode != VFR_RETURN_SUCCESS) {
659 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
660 return ReturnCode;
661 }
662
663 CNObj.SetQuestionId (QId);
664 CNObj.SetVarStoreInfo (&Info);
665 CNObj.SetFlags (0, Info.mVarType);
666
667 //
668 // For undefined Efi VarStore type question
669 // Append the extended guided opcode to contain VarName
670 //
671 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {
672 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);
673 CVNObj.SetLineNo (LineNo);
674 }
675
676 //
677 // End for Numeric
678 //
679 CIfrEnd CEObj;
680 CEObj.SetLineNo (LineNo);
681 }
682 }
683
684 //
685 // End for DisableIf
686 //
687 CIfrEnd SEObj;
688 SEObj.SetLineNo (LineNo);
689
690 return VFR_RETURN_SUCCESS;
691 }
692
693 CFormPkg gCFormPkg;
694
695 SIfrRecord::SIfrRecord (
696 VOID
697 )
698 {
699 mIfrBinBuf = NULL;
700 mBinBufLen = 0;
701 mLineNo = 0xFFFFFFFF;
702 mOffset = 0xFFFFFFFF;
703 mNext = NULL;
704 }
705
706 SIfrRecord::~SIfrRecord (
707 VOID
708 )
709 {
710 if (mIfrBinBuf != NULL) {
711 //delete mIfrBinBuf;
712 mIfrBinBuf = NULL;
713 }
714 mLineNo = 0xFFFFFFFF;
715 mOffset = 0xFFFFFFFF;
716 mBinBufLen = 0;
717 mNext = NULL;
718 }
719
720 CIfrRecordInfoDB::CIfrRecordInfoDB (
721 VOID
722 )
723 {
724 mSwitch = TRUE;
725 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;
726 mIfrRecordListHead = NULL;
727 mIfrRecordListTail = NULL;
728 }
729
730 CIfrRecordInfoDB::~CIfrRecordInfoDB (
731 VOID
732 )
733 {
734 SIfrRecord *pNode;
735
736 while (mIfrRecordListHead != NULL) {
737 pNode = mIfrRecordListHead;
738 mIfrRecordListHead = mIfrRecordListHead->mNext;
739 delete pNode;
740 }
741 }
742
743 SIfrRecord *
744 CIfrRecordInfoDB::GetRecordInfoFromIdx (
745 IN UINT32 RecordIdx
746 )
747 {
748 UINT32 Idx;
749 SIfrRecord *pNode = NULL;
750
751 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {
752 return NULL;
753 }
754
755 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;
756 (Idx != RecordIdx) && (pNode != NULL);
757 Idx++, pNode = pNode->mNext)
758 ;
759
760 return pNode;
761 }
762
763 UINT32
764 CIfrRecordInfoDB::IfrRecordRegister (
765 IN UINT32 LineNo,
766 IN CHAR8 *IfrBinBuf,
767 IN UINT8 BinBufLen,
768 IN UINT32 Offset
769 )
770 {
771 SIfrRecord *pNew;
772
773 if (mSwitch == FALSE) {
774 return EFI_IFR_RECORDINFO_IDX_INVALUD;
775 }
776
777 if ((pNew = new SIfrRecord) == NULL) {
778 return EFI_IFR_RECORDINFO_IDX_INVALUD;
779 }
780
781 if (mIfrRecordListHead == NULL) {
782 mIfrRecordListHead = pNew;
783 mIfrRecordListTail = pNew;
784 } else {
785 mIfrRecordListTail->mNext = pNew;
786 mIfrRecordListTail = pNew;
787 }
788 mRecordCount++;
789
790 return mRecordCount;
791 }
792
793 VOID
794 CIfrRecordInfoDB::IfrRecordInfoUpdate (
795 IN UINT32 RecordIdx,
796 IN UINT32 LineNo,
797 IN CHAR8 *BinBuf,
798 IN UINT8 BinBufLen,
799 IN UINT32 Offset
800 )
801 {
802 SIfrRecord *pNode;
803 SIfrRecord *Prev;
804
805 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {
806 return;
807 }
808
809 if (LineNo == 0) {
810 //
811 // Line number is not specified explicitly, try to use line number of previous opcode
812 //
813 Prev = GetRecordInfoFromIdx (RecordIdx - 1);
814 if (Prev != NULL) {
815 LineNo = Prev->mLineNo;
816 }
817 }
818
819 pNode->mLineNo = LineNo;
820 pNode->mOffset = Offset;
821 pNode->mBinBufLen = BinBufLen;
822 pNode->mIfrBinBuf = BinBuf;
823
824 }
825
826 VOID
827 CIfrRecordInfoDB::IfrRecordOutput (
828 OUT PACKAGE_DATA &TBuffer
829 )
830 {
831 CHAR8 *Temp;
832 SIfrRecord *pNode;
833
834 if (TBuffer.Buffer != NULL) {
835 delete TBuffer.Buffer;
836 }
837
838 TBuffer.Size = 0;
839 TBuffer.Buffer = NULL;
840
841
842 if (mSwitch == FALSE) {
843 return;
844 }
845
846 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
847 TBuffer.Size += pNode->mBinBufLen;
848 }
849
850 if (TBuffer.Size != 0) {
851 TBuffer.Buffer = new CHAR8[TBuffer.Size];
852 } else {
853 return;
854 }
855
856 Temp = TBuffer.Buffer;
857
858 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
859 if (pNode->mIfrBinBuf != NULL) {
860 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);
861 Temp += pNode->mBinBufLen;
862 }
863 }
864
865 return;
866 }
867
868 VOID
869 CIfrRecordInfoDB::IfrRecordOutput (
870 IN FILE *File,
871 IN UINT32 LineNo
872 )
873 {
874 SIfrRecord *pNode;
875 UINT8 Index;
876 UINT32 TotalSize;
877
878 if (mSwitch == FALSE) {
879 return;
880 }
881
882 if (File == NULL) {
883 return;
884 }
885
886 TotalSize = 0;
887
888 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
889 if (pNode->mLineNo == LineNo || LineNo == 0) {
890 fprintf (File, ">%08X: ", pNode->mOffset);
891 TotalSize += pNode->mBinBufLen;
892 if (pNode->mIfrBinBuf != NULL) {
893 for (Index = 0; Index < pNode->mBinBufLen; Index++) {
894 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));
895 }
896 }
897 fprintf (File, "\n");
898 }
899 }
900
901 if (LineNo == 0) {
902 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);
903 }
904 }
905
906 //
907 // for framework vfr file
908 // adjust opcode sequence for uefi IFR format
909 // adjust inconsistent and varstore into the right position.
910 //
911 BOOLEAN
912 CIfrRecordInfoDB::CheckQuestionOpCode (
913 IN UINT8 OpCode
914 )
915 {
916 switch (OpCode) {
917 case EFI_IFR_CHECKBOX_OP:
918 case EFI_IFR_NUMERIC_OP:
919 case EFI_IFR_PASSWORD_OP:
920 case EFI_IFR_ONE_OF_OP:
921 case EFI_IFR_ACTION_OP:
922 case EFI_IFR_STRING_OP:
923 case EFI_IFR_DATE_OP:
924 case EFI_IFR_TIME_OP:
925 case EFI_IFR_ORDERED_LIST_OP:
926 return TRUE;
927 default:
928 return FALSE;
929 }
930 }
931
932 BOOLEAN
933 CIfrRecordInfoDB::CheckIdOpCode (
934 IN UINT8 OpCode
935 )
936 {
937 switch (OpCode) {
938 case EFI_IFR_EQ_ID_VAL_OP:
939 case EFI_IFR_EQ_ID_ID_OP:
940 case EFI_IFR_EQ_ID_LIST_OP:
941 case EFI_IFR_QUESTION_REF1_OP:
942 return TRUE;
943 default:
944 return FALSE;
945 }
946 }
947
948 EFI_QUESTION_ID
949 CIfrRecordInfoDB::GetOpcodeQuestionId (
950 IN EFI_IFR_OP_HEADER *OpHead
951 )
952 {
953 EFI_IFR_QUESTION_HEADER *QuestionHead;
954
955 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);
956
957 return QuestionHead->QuestionId;
958 }
959
960 EFI_VFR_RETURN_CODE
961 CIfrRecordInfoDB::IfrRecordAdjust (
962 VOID
963 )
964 {
965 SIfrRecord *pNode, *preNode;
966 SIfrRecord *uNode, *tNode;
967 EFI_IFR_OP_HEADER *OpHead, *tOpHead;
968 EFI_QUESTION_ID QuestionId;
969 UINT32 StackCount;
970 UINT32 QuestionScope;
971 UINT32 OpcodeOffset;
972 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };
973 EFI_VFR_RETURN_CODE Status;
974
975 //
976 // Init local variable
977 //
978 Status = VFR_RETURN_SUCCESS;
979 pNode = mIfrRecordListHead;
980 preNode = pNode;
981 QuestionScope = 0;
982 while (pNode != NULL) {
983 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
984
985 //
986 // make sure the inconsistent opcode in question scope
987 //
988 if (QuestionScope > 0) {
989 QuestionScope += OpHead->Scope;
990 if (OpHead->OpCode == EFI_IFR_END_OP) {
991 QuestionScope --;
992 }
993 }
994
995 if (CheckQuestionOpCode (OpHead->OpCode)) {
996 QuestionScope = 1;
997 }
998 //
999 // for the inconsistent opcode not in question scope, adjust it
1000 //
1001 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {
1002 //
1003 // for inconsistent opcode not in question scope
1004 //
1005
1006 //
1007 // Count inconsistent opcode Scope
1008 //
1009 StackCount = OpHead->Scope;
1010 QuestionId = EFI_QUESTION_ID_INVALID;
1011 tNode = pNode;
1012 while (tNode != NULL && StackCount > 0) {
1013 tNode = tNode->mNext;
1014 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;
1015 //
1016 // Calculate Scope Number
1017 //
1018 StackCount += tOpHead->Scope;
1019 if (tOpHead->OpCode == EFI_IFR_END_OP) {
1020 StackCount --;
1021 }
1022 //
1023 // by IdEqual opcode to get QuestionId
1024 //
1025 if (QuestionId == EFI_QUESTION_ID_INVALID &&
1026 CheckIdOpCode (tOpHead->OpCode)) {
1027 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);
1028 }
1029 }
1030 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {
1031 //
1032 // report error; not found
1033 //
1034 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);
1035 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
1036 Status = VFR_RETURN_MISMATCHED;
1037 break;
1038 }
1039 //
1040 // extract inconsistent opcode list
1041 // pNode is Incosistent opcode, tNode is End Opcode
1042 //
1043
1044 //
1045 // insert inconsistent opcode list into the right question scope by questionid
1046 //
1047 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {
1048 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;
1049 if (CheckQuestionOpCode (tOpHead->OpCode) &&
1050 (QuestionId == GetOpcodeQuestionId (tOpHead))) {
1051 break;
1052 }
1053 }
1054 //
1055 // insert inconsistent opcode list and check LATE_CHECK flag
1056 //
1057 if (uNode != NULL) {
1058 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {
1059 //
1060 // if LATE_CHECK flag is set, change inconsistent to nosumbit
1061 //
1062 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;
1063 }
1064
1065 //
1066 // skip the default storage for Date and Time
1067 //
1068 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {
1069 uNode = uNode->mNext;
1070 }
1071
1072 preNode->mNext = tNode->mNext;
1073 tNode->mNext = uNode->mNext;
1074 uNode->mNext = pNode;
1075 //
1076 // reset pNode to head list, scan the whole list again.
1077 //
1078 pNode = mIfrRecordListHead;
1079 preNode = pNode;
1080 QuestionScope = 0;
1081 continue;
1082 } else {
1083 //
1084 // not found matched question id, report error
1085 //
1086 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);
1087 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
1088 Status = VFR_RETURN_MISMATCHED;
1089 break;
1090 }
1091 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP ||
1092 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {
1093 //
1094 // for new added group of varstore opcode
1095 //
1096 tNode = pNode;
1097 while (tNode->mNext != NULL) {
1098 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;
1099 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP &&
1100 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {
1101 break;
1102 }
1103 tNode = tNode->mNext;
1104 }
1105
1106 if (tNode->mNext == NULL) {
1107 //
1108 // invalid IfrCode, IfrCode end by EndOpCode
1109 //
1110 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");
1111 Status = VFR_RETURN_MISMATCHED;
1112 break;
1113 }
1114
1115 if (tOpHead->OpCode != EFI_IFR_END_OP) {
1116 //
1117 // not new added varstore, which are not needed to be adjust.
1118 //
1119 preNode = tNode;
1120 pNode = tNode->mNext;
1121 continue;
1122 } else {
1123 //
1124 // move new added varstore opcode to the position befor form opcode
1125 // varstore opcode between pNode and tNode
1126 //
1127
1128 //
1129 // search form opcode from begin
1130 //
1131 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {
1132 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;
1133 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {
1134 break;
1135 }
1136 }
1137 //
1138 // Insert varstore opcode beform form opcode if form opcode is found
1139 //
1140 if (uNode->mNext != NULL) {
1141 preNode->mNext = tNode->mNext;
1142 tNode->mNext = uNode->mNext;
1143 uNode->mNext = pNode;
1144 //
1145 // reset pNode to head list, scan the whole list again.
1146 //
1147 pNode = mIfrRecordListHead;
1148 preNode = pNode;
1149 QuestionScope = 0;
1150 continue;
1151 } else {
1152 //
1153 // not found form, continue scan IfrRecord list
1154 //
1155 preNode = tNode;
1156 pNode = tNode->mNext;
1157 continue;
1158 }
1159 }
1160 }
1161 //
1162 // next node
1163 //
1164 preNode = pNode;
1165 pNode = pNode->mNext;
1166 }
1167
1168 //
1169 // Update Ifr Opcode Offset
1170 //
1171 if (Status == VFR_RETURN_SUCCESS) {
1172 OpcodeOffset = 0;
1173 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1174 pNode->mOffset = OpcodeOffset;
1175 OpcodeOffset += pNode->mBinBufLen;
1176 }
1177 }
1178 return Status;
1179 }
1180
1181 CIfrRecordInfoDB gCIfrRecordInfoDB;
1182
1183 VOID
1184 CIfrObj::_EMIT_PENDING_OBJ (
1185 VOID
1186 )
1187 {
1188 CHAR8 *ObjBinBuf = NULL;
1189
1190 //
1191 // do nothing
1192 //
1193 if (!mDelayEmit || !gCreateOp) {
1194 return;
1195 }
1196
1197 mPkgOffset = gCFormPkg.GetPkgLength ();
1198 //
1199 // update data buffer to package data
1200 //
1201 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);
1202 if (ObjBinBuf != NULL) {
1203 memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);
1204 }
1205
1206 //
1207 // update bin buffer to package data buffer
1208 //
1209 if (mObjBinBuf != NULL) {
1210 delete mObjBinBuf;
1211 mObjBinBuf = ObjBinBuf;
1212 }
1213
1214 mDelayEmit = FALSE;
1215 }
1216
1217 /*
1218 * The definition of CIfrObj's member function
1219 */
1220 static struct {
1221 UINT8 mSize;
1222 UINT8 mScope;
1223 } gOpcodeSizesScopeTable[] = {
1224 { 0, 0 }, // EFI_IFR_INVALID - 0x00
1225 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP
1226 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP
1227 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP
1228 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP
1229 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
1230 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP
1231 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP
1232 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP
1233 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
1234 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
1235 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP
1236 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP
1237 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP
1238 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE
1239 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP
1240 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
1241 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
1242 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP
1243 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP
1244 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
1245 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP
1246 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP
1247 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP
1248 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP
1249 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
1250 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP
1251 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP
1252 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP
1253 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP
1254 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
1255 { 0, 0 }, // 0x1F
1256 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
1257 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
1258 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22
1259 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
1260 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP
1261 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
1262 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP
1263 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
1264 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28
1265 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP
1266 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A
1267 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B
1268 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C
1269 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D
1270 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E
1271 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
1272 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP
1273 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP
1274 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP
1275 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP
1276 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
1277 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP
1278 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP
1279 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP
1280 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP
1281 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
1282 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A
1283 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP
1284 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP
1285 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP
1286 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E
1287 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP
1288 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP
1289 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
1290 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8
1291 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16
1292 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32
1293 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64
1294 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46
1295 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP
1296 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP
1297 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP
1298 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP
1299 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP
1300 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP
1301 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP
1302 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
1303 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP
1304 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP
1305 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP
1306 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP
1307 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP
1308 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP
1309 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP
1310 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP
1311 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57
1312 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP
1313 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP
1314 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP
1315 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP
1316 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
1317 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
1318 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP
1319 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP
1320 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60
1321 { sizeof (EFI_IFR_MODAL), 0}, // EFI_IFR_MODAL_OP - 0x61
1322 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
1323 };
1324
1325 #ifdef CIFROBJ_DEUBG
1326 static struct {
1327 CHAR8 *mIfrName;
1328 } gIfrObjPrintDebugTable[] = {
1329 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
1330 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
1331 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
1332 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
1333 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
1334 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
1335 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
1336 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
1337 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
1338 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
1339 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
1340 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
1341 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
1342 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
1343 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
1344 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
1345 "EFI_IFR_SECURITY", "EFI_IFR_MODAL", "EFI_IFR_REFRESH_ID",
1346 };
1347
1348 VOID
1349 CIFROBJ_DEBUG_PRINT (
1350 IN UINT8 OpCode
1351 )
1352 {
1353 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);
1354 }
1355 #else
1356
1357 #define CIFROBJ_DEBUG_PRINT(OpCode)
1358
1359 #endif
1360
1361 BOOLEAN gCreateOp = TRUE;
1362
1363 CIfrObj::CIfrObj (
1364 IN UINT8 OpCode,
1365 OUT CHAR8 **IfrObj,
1366 IN UINT8 ObjBinLen,
1367 IN BOOLEAN DelayEmit
1368 )
1369 {
1370 mDelayEmit = DelayEmit;
1371 mPkgOffset = gCFormPkg.GetPkgLength ();
1372 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;
1373 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];
1374 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;
1375
1376 if (IfrObj != NULL) {
1377 *IfrObj = mObjBinBuf;
1378 }
1379
1380 CIFROBJ_DEBUG_PRINT (OpCode);
1381 }
1382
1383 CIfrObj::~CIfrObj (
1384 VOID
1385 )
1386 {
1387 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {
1388 _EMIT_PENDING_OBJ ();
1389 }
1390
1391 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);
1392 }
1393
1394 /*
1395 * The definition of CIfrObj's member function
1396 */
1397 UINT8 gScopeCount = 0;
1398
1399 CIfrOpHeader::CIfrOpHeader (
1400 IN UINT8 OpCode,
1401 IN VOID *StartAddr,
1402 IN UINT8 Length
1403 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)
1404 {
1405 mHeader->OpCode = OpCode;
1406 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;
1407 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;
1408 }
1409
1410 CIfrOpHeader::CIfrOpHeader (
1411 IN CIfrOpHeader &OpHdr
1412 )
1413 {
1414 mHeader = OpHdr.mHeader;
1415 }
1416
1417 UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };