]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
94ad55b1bb4ab0f6a55b95a8c703376aaf19de4c
[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 //
666 // Numeric doesn't support BOOLEAN data type.
667 // BOOLEAN type has the same data size to UINT8.
668 //
669 if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {
670 Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
671 }
672 CNObj.SetFlags (0, Info.mVarType);
673
674 //
675 // For undefined Efi VarStore type question
676 // Append the extended guided opcode to contain VarName
677 //
678 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {
679 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);
680 CVNObj.SetLineNo (LineNo);
681 }
682
683 //
684 // End for Numeric
685 //
686 CIfrEnd CEObj;
687 CEObj.SetLineNo (LineNo);
688 }
689 }
690
691 //
692 // End for DisableIf
693 //
694 CIfrEnd SEObj;
695 SEObj.SetLineNo (LineNo);
696
697 return VFR_RETURN_SUCCESS;
698 }
699
700 CFormPkg gCFormPkg;
701
702 SIfrRecord::SIfrRecord (
703 VOID
704 )
705 {
706 mIfrBinBuf = NULL;
707 mBinBufLen = 0;
708 mLineNo = 0xFFFFFFFF;
709 mOffset = 0xFFFFFFFF;
710 mNext = NULL;
711 }
712
713 SIfrRecord::~SIfrRecord (
714 VOID
715 )
716 {
717 if (mIfrBinBuf != NULL) {
718 //delete mIfrBinBuf;
719 mIfrBinBuf = NULL;
720 }
721 mLineNo = 0xFFFFFFFF;
722 mOffset = 0xFFFFFFFF;
723 mBinBufLen = 0;
724 mNext = NULL;
725 }
726
727 CIfrRecordInfoDB::CIfrRecordInfoDB (
728 VOID
729 )
730 {
731 mSwitch = TRUE;
732 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;
733 mIfrRecordListHead = NULL;
734 mIfrRecordListTail = NULL;
735 }
736
737 CIfrRecordInfoDB::~CIfrRecordInfoDB (
738 VOID
739 )
740 {
741 SIfrRecord *pNode;
742
743 while (mIfrRecordListHead != NULL) {
744 pNode = mIfrRecordListHead;
745 mIfrRecordListHead = mIfrRecordListHead->mNext;
746 delete pNode;
747 }
748 }
749
750 SIfrRecord *
751 CIfrRecordInfoDB::GetRecordInfoFromIdx (
752 IN UINT32 RecordIdx
753 )
754 {
755 UINT32 Idx;
756 SIfrRecord *pNode = NULL;
757
758 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {
759 return NULL;
760 }
761
762 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;
763 (Idx != RecordIdx) && (pNode != NULL);
764 Idx++, pNode = pNode->mNext)
765 ;
766
767 return pNode;
768 }
769
770 UINT32
771 CIfrRecordInfoDB::IfrRecordRegister (
772 IN UINT32 LineNo,
773 IN CHAR8 *IfrBinBuf,
774 IN UINT8 BinBufLen,
775 IN UINT32 Offset
776 )
777 {
778 SIfrRecord *pNew;
779
780 if (mSwitch == FALSE) {
781 return EFI_IFR_RECORDINFO_IDX_INVALUD;
782 }
783
784 if ((pNew = new SIfrRecord) == NULL) {
785 return EFI_IFR_RECORDINFO_IDX_INVALUD;
786 }
787
788 if (mIfrRecordListHead == NULL) {
789 mIfrRecordListHead = pNew;
790 mIfrRecordListTail = pNew;
791 } else {
792 mIfrRecordListTail->mNext = pNew;
793 mIfrRecordListTail = pNew;
794 }
795 mRecordCount++;
796
797 return mRecordCount;
798 }
799
800 VOID
801 CIfrRecordInfoDB::IfrRecordInfoUpdate (
802 IN UINT32 RecordIdx,
803 IN UINT32 LineNo,
804 IN CHAR8 *BinBuf,
805 IN UINT8 BinBufLen,
806 IN UINT32 Offset
807 )
808 {
809 SIfrRecord *pNode;
810 SIfrRecord *Prev;
811
812 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {
813 return;
814 }
815
816 if (LineNo == 0) {
817 //
818 // Line number is not specified explicitly, try to use line number of previous opcode
819 //
820 Prev = GetRecordInfoFromIdx (RecordIdx - 1);
821 if (Prev != NULL) {
822 LineNo = Prev->mLineNo;
823 }
824 }
825
826 pNode->mLineNo = LineNo;
827 pNode->mOffset = Offset;
828 pNode->mBinBufLen = BinBufLen;
829 pNode->mIfrBinBuf = BinBuf;
830
831 }
832
833 VOID
834 CIfrRecordInfoDB::IfrRecordOutput (
835 OUT PACKAGE_DATA &TBuffer
836 )
837 {
838 CHAR8 *Temp;
839 SIfrRecord *pNode;
840
841 if (TBuffer.Buffer != NULL) {
842 delete TBuffer.Buffer;
843 }
844
845 TBuffer.Size = 0;
846 TBuffer.Buffer = NULL;
847
848
849 if (mSwitch == FALSE) {
850 return;
851 }
852
853 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
854 TBuffer.Size += pNode->mBinBufLen;
855 }
856
857 if (TBuffer.Size != 0) {
858 TBuffer.Buffer = new CHAR8[TBuffer.Size];
859 } else {
860 return;
861 }
862
863 Temp = TBuffer.Buffer;
864
865 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
866 if (pNode->mIfrBinBuf != NULL) {
867 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);
868 Temp += pNode->mBinBufLen;
869 }
870 }
871
872 return;
873 }
874
875 VOID
876 CIfrRecordInfoDB::IfrRecordOutput (
877 IN FILE *File,
878 IN UINT32 LineNo
879 )
880 {
881 SIfrRecord *pNode;
882 UINT8 Index;
883 UINT32 TotalSize;
884
885 if (mSwitch == FALSE) {
886 return;
887 }
888
889 if (File == NULL) {
890 return;
891 }
892
893 TotalSize = 0;
894
895 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
896 if (pNode->mLineNo == LineNo || LineNo == 0) {
897 fprintf (File, ">%08X: ", pNode->mOffset);
898 TotalSize += pNode->mBinBufLen;
899 if (pNode->mIfrBinBuf != NULL) {
900 for (Index = 0; Index < pNode->mBinBufLen; Index++) {
901 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));
902 }
903 }
904 fprintf (File, "\n");
905 }
906 }
907
908 if (LineNo == 0) {
909 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);
910 }
911 }
912
913 //
914 // for framework vfr file
915 // adjust opcode sequence for uefi IFR format
916 // adjust inconsistent and varstore into the right position.
917 //
918 BOOLEAN
919 CIfrRecordInfoDB::CheckQuestionOpCode (
920 IN UINT8 OpCode
921 )
922 {
923 switch (OpCode) {
924 case EFI_IFR_CHECKBOX_OP:
925 case EFI_IFR_NUMERIC_OP:
926 case EFI_IFR_PASSWORD_OP:
927 case EFI_IFR_ONE_OF_OP:
928 case EFI_IFR_ACTION_OP:
929 case EFI_IFR_STRING_OP:
930 case EFI_IFR_DATE_OP:
931 case EFI_IFR_TIME_OP:
932 case EFI_IFR_ORDERED_LIST_OP:
933 return TRUE;
934 default:
935 return FALSE;
936 }
937 }
938
939 BOOLEAN
940 CIfrRecordInfoDB::CheckIdOpCode (
941 IN UINT8 OpCode
942 )
943 {
944 switch (OpCode) {
945 case EFI_IFR_EQ_ID_VAL_OP:
946 case EFI_IFR_EQ_ID_ID_OP:
947 case EFI_IFR_EQ_ID_LIST_OP:
948 case EFI_IFR_QUESTION_REF1_OP:
949 return TRUE;
950 default:
951 return FALSE;
952 }
953 }
954
955 EFI_QUESTION_ID
956 CIfrRecordInfoDB::GetOpcodeQuestionId (
957 IN EFI_IFR_OP_HEADER *OpHead
958 )
959 {
960 EFI_IFR_QUESTION_HEADER *QuestionHead;
961
962 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);
963
964 return QuestionHead->QuestionId;
965 }
966
967 EFI_VFR_RETURN_CODE
968 CIfrRecordInfoDB::IfrRecordAdjust (
969 VOID
970 )
971 {
972 SIfrRecord *pNode, *preNode;
973 SIfrRecord *uNode, *tNode;
974 EFI_IFR_OP_HEADER *OpHead, *tOpHead;
975 EFI_QUESTION_ID QuestionId;
976 UINT32 StackCount;
977 UINT32 QuestionScope;
978 UINT32 OpcodeOffset;
979 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };
980 EFI_VFR_RETURN_CODE Status;
981
982 //
983 // Init local variable
984 //
985 Status = VFR_RETURN_SUCCESS;
986 pNode = mIfrRecordListHead;
987 preNode = pNode;
988 QuestionScope = 0;
989 while (pNode != NULL) {
990 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
991
992 //
993 // make sure the inconsistent opcode in question scope
994 //
995 if (QuestionScope > 0) {
996 QuestionScope += OpHead->Scope;
997 if (OpHead->OpCode == EFI_IFR_END_OP) {
998 QuestionScope --;
999 }
1000 }
1001
1002 if (CheckQuestionOpCode (OpHead->OpCode)) {
1003 QuestionScope = 1;
1004 }
1005 //
1006 // for the inconsistent opcode not in question scope, adjust it
1007 //
1008 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {
1009 //
1010 // for inconsistent opcode not in question scope
1011 //
1012
1013 //
1014 // Count inconsistent opcode Scope
1015 //
1016 StackCount = OpHead->Scope;
1017 QuestionId = EFI_QUESTION_ID_INVALID;
1018 tNode = pNode;
1019 while (tNode != NULL && StackCount > 0) {
1020 tNode = tNode->mNext;
1021 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;
1022 //
1023 // Calculate Scope Number
1024 //
1025 StackCount += tOpHead->Scope;
1026 if (tOpHead->OpCode == EFI_IFR_END_OP) {
1027 StackCount --;
1028 }
1029 //
1030 // by IdEqual opcode to get QuestionId
1031 //
1032 if (QuestionId == EFI_QUESTION_ID_INVALID &&
1033 CheckIdOpCode (tOpHead->OpCode)) {
1034 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);
1035 }
1036 }
1037 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {
1038 //
1039 // report error; not found
1040 //
1041 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);
1042 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
1043 Status = VFR_RETURN_MISMATCHED;
1044 break;
1045 }
1046 //
1047 // extract inconsistent opcode list
1048 // pNode is Incosistent opcode, tNode is End Opcode
1049 //
1050
1051 //
1052 // insert inconsistent opcode list into the right question scope by questionid
1053 //
1054 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {
1055 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;
1056 if (CheckQuestionOpCode (tOpHead->OpCode) &&
1057 (QuestionId == GetOpcodeQuestionId (tOpHead))) {
1058 break;
1059 }
1060 }
1061 //
1062 // insert inconsistent opcode list and check LATE_CHECK flag
1063 //
1064 if (uNode != NULL) {
1065 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {
1066 //
1067 // if LATE_CHECK flag is set, change inconsistent to nosumbit
1068 //
1069 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;
1070 }
1071
1072 //
1073 // skip the default storage for Date and Time
1074 //
1075 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {
1076 uNode = uNode->mNext;
1077 }
1078
1079 preNode->mNext = tNode->mNext;
1080 tNode->mNext = uNode->mNext;
1081 uNode->mNext = pNode;
1082 //
1083 // reset pNode to head list, scan the whole list again.
1084 //
1085 pNode = mIfrRecordListHead;
1086 preNode = pNode;
1087 QuestionScope = 0;
1088 continue;
1089 } else {
1090 //
1091 // not found matched question id, report error
1092 //
1093 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);
1094 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
1095 Status = VFR_RETURN_MISMATCHED;
1096 break;
1097 }
1098 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP ||
1099 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {
1100 //
1101 // for new added group of varstore opcode
1102 //
1103 tNode = pNode;
1104 while (tNode->mNext != NULL) {
1105 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;
1106 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP &&
1107 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {
1108 break;
1109 }
1110 tNode = tNode->mNext;
1111 }
1112
1113 if (tNode->mNext == NULL) {
1114 //
1115 // invalid IfrCode, IfrCode end by EndOpCode
1116 //
1117 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");
1118 Status = VFR_RETURN_MISMATCHED;
1119 break;
1120 }
1121
1122 if (tOpHead->OpCode != EFI_IFR_END_OP) {
1123 //
1124 // not new added varstore, which are not needed to be adjust.
1125 //
1126 preNode = tNode;
1127 pNode = tNode->mNext;
1128 continue;
1129 } else {
1130 //
1131 // move new added varstore opcode to the position befor form opcode
1132 // varstore opcode between pNode and tNode
1133 //
1134
1135 //
1136 // search form opcode from begin
1137 //
1138 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {
1139 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;
1140 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {
1141 break;
1142 }
1143 }
1144 //
1145 // Insert varstore opcode beform form opcode if form opcode is found
1146 //
1147 if (uNode->mNext != NULL) {
1148 preNode->mNext = tNode->mNext;
1149 tNode->mNext = uNode->mNext;
1150 uNode->mNext = pNode;
1151 //
1152 // reset pNode to head list, scan the whole list again.
1153 //
1154 pNode = mIfrRecordListHead;
1155 preNode = pNode;
1156 QuestionScope = 0;
1157 continue;
1158 } else {
1159 //
1160 // not found form, continue scan IfrRecord list
1161 //
1162 preNode = tNode;
1163 pNode = tNode->mNext;
1164 continue;
1165 }
1166 }
1167 }
1168 //
1169 // next node
1170 //
1171 preNode = pNode;
1172 pNode = pNode->mNext;
1173 }
1174
1175 //
1176 // Update Ifr Opcode Offset
1177 //
1178 if (Status == VFR_RETURN_SUCCESS) {
1179 OpcodeOffset = 0;
1180 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
1181 pNode->mOffset = OpcodeOffset;
1182 OpcodeOffset += pNode->mBinBufLen;
1183 }
1184 }
1185 return Status;
1186 }
1187
1188 CIfrRecordInfoDB gCIfrRecordInfoDB;
1189
1190 VOID
1191 CIfrObj::_EMIT_PENDING_OBJ (
1192 VOID
1193 )
1194 {
1195 CHAR8 *ObjBinBuf = NULL;
1196
1197 //
1198 // do nothing
1199 //
1200 if (!mDelayEmit || !gCreateOp) {
1201 return;
1202 }
1203
1204 mPkgOffset = gCFormPkg.GetPkgLength ();
1205 //
1206 // update data buffer to package data
1207 //
1208 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);
1209 if (ObjBinBuf != NULL) {
1210 memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);
1211 }
1212
1213 //
1214 // update bin buffer to package data buffer
1215 //
1216 if (mObjBinBuf != NULL) {
1217 delete mObjBinBuf;
1218 mObjBinBuf = ObjBinBuf;
1219 }
1220
1221 mDelayEmit = FALSE;
1222 }
1223
1224 /*
1225 * The definition of CIfrObj's member function
1226 */
1227 static struct {
1228 UINT8 mSize;
1229 UINT8 mScope;
1230 } gOpcodeSizesScopeTable[] = {
1231 { 0, 0 }, // EFI_IFR_INVALID - 0x00
1232 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP
1233 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP
1234 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP
1235 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP
1236 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
1237 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP
1238 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP
1239 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP
1240 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
1241 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
1242 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP
1243 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP
1244 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP
1245 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE
1246 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP
1247 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
1248 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
1249 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP
1250 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP
1251 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
1252 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP
1253 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP
1254 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP
1255 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP
1256 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
1257 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP
1258 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP
1259 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP
1260 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP
1261 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
1262 { 0, 0 }, // 0x1F
1263 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
1264 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
1265 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22
1266 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
1267 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP
1268 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
1269 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP
1270 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
1271 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28
1272 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP
1273 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A
1274 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B
1275 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C
1276 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D
1277 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E
1278 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
1279 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP
1280 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP
1281 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP
1282 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP
1283 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
1284 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP
1285 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP
1286 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP
1287 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP
1288 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
1289 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A
1290 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP
1291 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP
1292 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP
1293 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E
1294 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP
1295 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP
1296 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
1297 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8
1298 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16
1299 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32
1300 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64
1301 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46
1302 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP
1303 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP
1304 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP
1305 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP
1306 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP
1307 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP
1308 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP
1309 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
1310 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP
1311 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP
1312 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP
1313 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP
1314 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP
1315 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP
1316 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP
1317 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP
1318 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57
1319 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP
1320 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP
1321 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP
1322 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP
1323 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
1324 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
1325 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP
1326 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP
1327 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60
1328 { sizeof (EFI_IFR_MODAL), 0}, // EFI_IFR_MODAL_OP - 0x61
1329 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
1330 };
1331
1332 #ifdef CIFROBJ_DEUBG
1333 static struct {
1334 CHAR8 *mIfrName;
1335 } gIfrObjPrintDebugTable[] = {
1336 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
1337 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
1338 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
1339 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
1340 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
1341 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
1342 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
1343 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
1344 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
1345 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
1346 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
1347 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
1348 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
1349 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
1350 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
1351 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
1352 "EFI_IFR_SECURITY", "EFI_IFR_MODAL", "EFI_IFR_REFRESH_ID",
1353 };
1354
1355 VOID
1356 CIFROBJ_DEBUG_PRINT (
1357 IN UINT8 OpCode
1358 )
1359 {
1360 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);
1361 }
1362 #else
1363
1364 #define CIFROBJ_DEBUG_PRINT(OpCode)
1365
1366 #endif
1367
1368 BOOLEAN gCreateOp = TRUE;
1369
1370 CIfrObj::CIfrObj (
1371 IN UINT8 OpCode,
1372 OUT CHAR8 **IfrObj,
1373 IN UINT8 ObjBinLen,
1374 IN BOOLEAN DelayEmit
1375 )
1376 {
1377 mDelayEmit = DelayEmit;
1378 mPkgOffset = gCFormPkg.GetPkgLength ();
1379 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;
1380 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];
1381 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;
1382
1383 if (IfrObj != NULL) {
1384 *IfrObj = mObjBinBuf;
1385 }
1386
1387 CIFROBJ_DEBUG_PRINT (OpCode);
1388 }
1389
1390 CIfrObj::~CIfrObj (
1391 VOID
1392 )
1393 {
1394 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {
1395 _EMIT_PENDING_OBJ ();
1396 }
1397
1398 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);
1399 }
1400
1401 /*
1402 * The definition of CIfrObj's member function
1403 */
1404 UINT8 gScopeCount = 0;
1405
1406 CIfrOpHeader::CIfrOpHeader (
1407 IN UINT8 OpCode,
1408 IN VOID *StartAddr,
1409 IN UINT8 Length
1410 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)
1411 {
1412 mHeader->OpCode = OpCode;
1413 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;
1414 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;
1415 }
1416
1417 CIfrOpHeader::CIfrOpHeader (
1418 IN CIfrOpHeader &OpHdr
1419 )
1420 {
1421 mHeader = OpHdr.mHeader;
1422 }
1423
1424 UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };