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