Home | History | Annotate | Download | only in UefiVfrCompile
      1 /*++
      2 
      3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   VfrFormPkg.cpp
     15 
     16 Abstract:
     17 
     18 --*/
     19 
     20 #include "stdio.h"
     21 #include "VfrFormPkg.h"
     22 
     23 /*
     24  * The definition of CFormPkg's member function
     25  */
     26 
     27 SPendingAssign::SPendingAssign (
     28   IN INT8   *Key,
     29   IN VOID   *Addr,
     30   IN UINT32 Len,
     31   IN UINT32 LineNo,
     32   IN INT8   *Msg
     33   )
     34 {
     35   mKey    = NULL;
     36   mAddr   = Addr;
     37   mLen    = Len;
     38   mFlag   = PENDING;
     39   mLineNo = LineNo;
     40   mMsg    = NULL;
     41   mNext   = NULL;
     42 
     43   if (Key != NULL) {
     44     mKey = new INT8[strlen (Key) + 1];
     45     if (mKey != NULL) {
     46       strcpy (mKey, Key);
     47     }
     48   }
     49 
     50   if (Msg != NULL) {
     51     mMsg = new INT8[strlen (Msg) + 1];
     52     if (mMsg != NULL) {
     53       strcpy (mMsg, Msg);
     54     }
     55   }
     56 }
     57 
     58 SPendingAssign::~SPendingAssign (
     59   VOID
     60   )
     61 {
     62   if (mKey != NULL) {
     63     delete mKey;
     64   }
     65   mAddr   = NULL;
     66   mLen    = 0;
     67   mLineNo = 0;
     68   if (mMsg != NULL) {
     69     delete mMsg;
     70   }
     71   mNext   = NULL;
     72 }
     73 
     74 VOID
     75 SPendingAssign::SetAddrAndLen (
     76   IN VOID   *Addr,
     77   IN UINT32 LineNo
     78   )
     79 {
     80   mAddr   = Addr;
     81   mLineNo = LineNo;
     82 }
     83 
     84 VOID
     85 SPendingAssign::AssignValue (
     86   IN VOID   *Addr,
     87   IN UINT32 Len
     88   )
     89 {
     90   memcpy (mAddr, Addr, (mLen < Len ? mLen : Len));
     91   mFlag = ASSIGNED;
     92 }
     93 
     94 INT8 *
     95 SPendingAssign::GetKey (
     96   VOID
     97   )
     98 {
     99   return mKey;
    100 }
    101 
    102 CFormPkg::CFormPkg (
    103   IN UINT32 BufferSize = 4096
    104   )
    105 {
    106   CHAR8       *BufferStart;
    107   CHAR8       *BufferEnd;
    108   SBufferNode *Node;
    109 
    110   mPkgLength           = 0;
    111   mBufferNodeQueueHead = NULL;
    112   mCurrBufferNode      = NULL;
    113 
    114   Node = new SBufferNode;
    115   if (Node == NULL) {
    116     return ;
    117   }
    118   BufferStart = new CHAR8[BufferSize];
    119   if (BufferStart == NULL) {
    120     return;
    121   }
    122   BufferEnd   = BufferStart + BufferSize;
    123 
    124   memset (BufferStart, 0, BufferSize);
    125   Node->mBufferStart   = BufferStart;
    126   Node->mBufferEnd     = BufferEnd;
    127   Node->mBufferFree    = BufferStart;
    128   Node->mNext          = NULL;
    129 
    130   mBufferSize          = BufferSize;
    131   mBufferNodeQueueHead = Node;
    132   mBufferNodeQueueTail = Node;
    133   mCurrBufferNode      = Node;
    134 }
    135 
    136 CFormPkg::~CFormPkg ()
    137 {
    138   SBufferNode    *pBNode;
    139   SPendingAssign *pPNode;
    140 
    141   while (mBufferNodeQueueHead != NULL) {
    142     pBNode = mBufferNodeQueueHead;
    143     mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;
    144     if (pBNode->mBufferStart != NULL) {
    145       delete pBNode->mBufferStart;
    146       delete pBNode;
    147     }
    148   }
    149   mBufferNodeQueueTail = NULL;
    150   mCurrBufferNode      = NULL;
    151 
    152   while (PendingAssignList != NULL) {
    153     pPNode = PendingAssignList;
    154     PendingAssignList = PendingAssignList->mNext;
    155     delete pPNode;
    156   }
    157   PendingAssignList = NULL;
    158 }
    159 
    160 CHAR8 *
    161 CFormPkg::IfrBinBufferGet (
    162   IN UINT32 Len
    163   )
    164 {
    165   CHAR8 *BinBuffer = NULL;
    166 
    167   if ((Len == 0) || (Len > mBufferSize)) {
    168     return NULL;
    169   }
    170 
    171   if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {
    172     BinBuffer = mCurrBufferNode->mBufferFree;
    173     mCurrBufferNode->mBufferFree += Len;
    174   } else {
    175     SBufferNode *Node;
    176 
    177     Node = new SBufferNode;
    178     if (Node == NULL) {
    179       return NULL;
    180     }
    181 
    182     Node->mBufferStart = new CHAR8[mBufferSize];
    183     if (Node->mBufferStart == NULL) {
    184       delete Node;
    185       return NULL;
    186     } else {
    187       memset (Node->mBufferStart, 0, mBufferSize);
    188       Node->mBufferEnd  = Node->mBufferStart + mBufferSize;
    189       Node->mBufferFree = Node->mBufferStart;
    190       Node->mNext       = NULL;
    191     }
    192 
    193     if (mBufferNodeQueueTail == NULL) {
    194       mBufferNodeQueueHead = mBufferNodeQueueTail = Node;
    195     } else {
    196       mBufferNodeQueueTail->mNext = Node;
    197       mBufferNodeQueueTail = Node;
    198     }
    199     mCurrBufferNode = Node;
    200 
    201     //
    202     // Now try again.
    203     //
    204     BinBuffer = mCurrBufferNode->mBufferFree;
    205     mCurrBufferNode->mBufferFree += Len;
    206   }
    207 
    208   mPkgLength += Len;
    209 
    210   return BinBuffer;
    211 }
    212 
    213 inline
    214 UINT32
    215 CFormPkg::GetPkgLength (
    216   VOID
    217   )
    218 {
    219   return mPkgLength;
    220 }
    221 
    222 VOID
    223 CFormPkg::Open (
    224   VOID
    225   )
    226 {
    227   mReadBufferNode   = mBufferNodeQueueHead;
    228   mReadBufferOffset = 0;
    229 }
    230 
    231 VOID
    232 CFormPkg::Close (
    233   VOID
    234   )
    235 {
    236   mReadBufferNode   = NULL;
    237   mReadBufferOffset = 0;
    238 }
    239 
    240 UINT32
    241 CFormPkg::Read (
    242   IN CHAR8     *Buffer,
    243   IN UINT32    Size
    244   )
    245 {
    246   UINT32       Index;
    247 
    248   if ((Size == 0) || (Buffer == NULL)) {
    249     return 0;
    250   }
    251 
    252   if (mReadBufferNode == NULL) {
    253   	return 0;
    254   }
    255 
    256   for (Index = 0; Index < Size; Index++) {
    257     if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {
    258       Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];
    259     } else {
    260       if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {
    261         return Index;
    262       } else {
    263         mReadBufferOffset = 0;
    264         Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];
    265       }
    266     }
    267   }
    268 
    269   return Size;
    270 }
    271 
    272 EFI_VFR_RETURN_CODE
    273 CFormPkg::BuildPkgHdr (
    274   OUT EFI_HII_PACKAGE_HEADER **PkgHdr
    275   )
    276 {
    277   if (PkgHdr == NULL) {
    278     return VFR_RETURN_FATAL_ERROR;
    279   }
    280 
    281   if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {
    282     return VFR_RETURN_OUT_FOR_RESOURCES;
    283   }
    284 
    285   (*PkgHdr)->Type = EFI_HII_PACKAGE_FORMS;
    286   (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);
    287   return VFR_RETURN_SUCCESS;
    288 }
    289 
    290 EFI_VFR_RETURN_CODE
    291 CFormPkg::BuildPkg (
    292   IN FILE  *Output
    293   )
    294 {
    295   EFI_VFR_RETURN_CODE     Ret;
    296   CHAR8                   Buffer[1024];
    297   UINT32                  Size;
    298   EFI_HII_PACKAGE_HEADER  *PkgHdr;
    299 
    300   if (Output == NULL) {
    301     return VFR_RETURN_FATAL_ERROR;
    302   }
    303 
    304   if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
    305     return Ret;
    306   }
    307   fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);
    308   delete PkgHdr;
    309 
    310   Open ();
    311   while ((Size = Read (Buffer, 1024)) != 0) {
    312     fwrite (Buffer, Size, 1, Output);
    313   }
    314   Close ();
    315 
    316   return VFR_RETURN_SUCCESS;
    317 }
    318 
    319 VOID
    320 CFormPkg::_WRITE_PKG_LINE (
    321   IN FILE   *pFile,
    322   IN UINT32 LineBytes,
    323   IN INT8   *LineHeader,
    324   IN INT8   *BlkBuf,
    325   IN UINT32 BlkSize
    326   )
    327 {
    328   UINT32    Index;
    329 
    330   if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
    331     return;
    332   }
    333 
    334   for (Index = 0; Index < BlkSize; Index++) {
    335     if ((Index % LineBytes) == 0) {
    336       fprintf (pFile, "\n%s", LineHeader);
    337     }
    338     fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);
    339   }
    340 }
    341 
    342 VOID
    343 CFormPkg::_WRITE_PKG_END (
    344   IN FILE   *pFile,
    345   IN UINT32 LineBytes,
    346   IN INT8   *LineHeader,
    347   IN INT8   *BlkBuf,
    348   IN UINT32 BlkSize
    349   )
    350 {
    351   UINT32    Index;
    352 
    353   if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
    354     return;
    355   }
    356 
    357   for (Index = 0; Index < BlkSize - 1; Index++) {
    358     if ((Index % LineBytes) == 0) {
    359       fprintf (pFile, "\n%s", LineHeader);
    360     }
    361     fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);
    362   }
    363 
    364   if ((Index % LineBytes) == 0) {
    365     fprintf (pFile, "\n%s", LineHeader);
    366   }
    367   fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
    368 }
    369 
    370 #define BYTES_PRE_LINE 0x10
    371 
    372 EFI_VFR_RETURN_CODE
    373 CFormPkg::GenCFile (
    374   IN INT8 *BaseName,
    375   IN FILE *pFile
    376   )
    377 {
    378   EFI_VFR_RETURN_CODE          Ret;
    379   INT8                         Buffer[BYTES_PRE_LINE * 8];
    380   EFI_HII_PACKAGE_HEADER       *PkgHdr;
    381   UINT32                       PkgLength  = 0;
    382   UINT32                       ReadSize   = 0;
    383 
    384   if ((BaseName == NULL) || (pFile == NULL)) {
    385     return VFR_RETURN_FATAL_ERROR;
    386   }
    387 
    388   fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);
    389 
    390   if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
    391     return Ret;
    392   }
    393 
    394   fprintf (pFile, "  // ARRAY LENGTH\n");
    395   PkgLength = PkgHdr->Length + sizeof (UINT32);
    396   _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (INT8 *)&PkgLength, sizeof (UINT32));
    397 
    398   fprintf (pFile, "\n\n  // PACKAGE HEADER\n");
    399   _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (INT8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));
    400   PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);
    401 
    402   fprintf (pFile, "\n\n  // PACKAGE DATA\n");
    403   Open ();
    404   while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {
    405     PkgLength += ReadSize;
    406     if (PkgLength < PkgHdr->Length) {
    407       _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, "  ", Buffer, ReadSize);
    408     } else {
    409       _WRITE_PKG_END (pFile, BYTES_PRE_LINE, "  ", Buffer, ReadSize);
    410     }
    411   }
    412   Close ();
    413 
    414   delete PkgHdr;
    415   fprintf (pFile, "\n};\n");
    416 
    417   return VFR_RETURN_SUCCESS;
    418 }
    419 
    420 EFI_VFR_RETURN_CODE
    421 CFormPkg::AssignPending (
    422   IN INT8   *Key,
    423   IN VOID   *ValAddr,
    424   IN UINT32 ValLen,
    425   IN UINT32 LineNo,
    426   IN INT8   *Msg
    427   )
    428 {
    429   SPendingAssign *pNew;
    430 
    431   pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);
    432   if (pNew == NULL) {
    433     return VFR_RETURN_OUT_FOR_RESOURCES;
    434   }
    435 
    436   pNew->mNext       = PendingAssignList;
    437   PendingAssignList = pNew;
    438   return VFR_RETURN_SUCCESS;
    439 }
    440 
    441 VOID
    442 CFormPkg::DoPendingAssign (
    443   IN INT8   *Key,
    444   IN VOID   *ValAddr,
    445   IN UINT32 ValLen
    446   )
    447 {
    448   SPendingAssign *pNode;
    449 
    450   if ((Key == NULL) || (ValAddr == NULL)) {
    451     return;
    452   }
    453 
    454   for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    455     if (strcmp (pNode->mKey, Key) == 0) {
    456       pNode->AssignValue (ValAddr, ValLen);
    457     }
    458   }
    459 }
    460 
    461 bool
    462 CFormPkg::HavePendingUnassigned (
    463   VOID
    464   )
    465 {
    466   SPendingAssign *pNode;
    467 
    468   for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    469     if (pNode->mFlag == PENDING) {
    470       return TRUE;
    471     }
    472   }
    473 
    474   return FALSE;
    475 }
    476 
    477 VOID
    478 CFormPkg::PendingAssignPrintAll (
    479   VOID
    480   )
    481 {
    482   SPendingAssign *pNode;
    483 
    484   for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    485     if (pNode->mFlag == PENDING) {
    486       gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);
    487     }
    488   }
    489 }
    490 
    491 CFormPkg gCFormPkg;
    492 
    493 SIfrRecord::SIfrRecord (
    494   VOID
    495   )
    496 {
    497   mIfrBinBuf = NULL;
    498   mBinBufLen = 0;
    499   mLineNo    = 0xFFFFFFFF;
    500   mOffset    = 0xFFFFFFFF;
    501   mNext      = NULL;
    502 }
    503 
    504 SIfrRecord::~SIfrRecord (
    505   VOID
    506   )
    507 {
    508   mIfrBinBuf   = NULL;
    509   mLineNo      = 0xFFFFFFFF;
    510   mOffset      = 0xFFFFFFFF;
    511   mBinBufLen   = 0;
    512   mNext        = NULL;
    513 }
    514 
    515 CIfrRecordInfoDB::CIfrRecordInfoDB (
    516   VOID
    517   )
    518 {
    519   mSwitch            = FALSE;
    520   mRecordCount       = EFI_IFR_RECORDINFO_IDX_START;
    521   mIfrRecordListHead = NULL;
    522   mIfrRecordListTail = NULL;
    523 }
    524 
    525 CIfrRecordInfoDB::~CIfrRecordInfoDB (
    526   VOID
    527   )
    528 {
    529   SIfrRecord *pNode;
    530 
    531   while (mIfrRecordListHead != NULL) {
    532     pNode = mIfrRecordListHead;
    533     mIfrRecordListHead = mIfrRecordListHead->mNext;
    534     delete pNode;
    535   }
    536 }
    537 
    538 SIfrRecord *
    539 CIfrRecordInfoDB::GetRecordInfoFromIdx (
    540   IN UINT32 RecordIdx
    541   )
    542 {
    543   UINT32     Idx;
    544   SIfrRecord *pNode = NULL;
    545 
    546   if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {
    547     return NULL;
    548   }
    549 
    550   for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;
    551        (Idx != RecordIdx) && (pNode != NULL);
    552        Idx++, pNode = pNode->mNext)
    553   ;
    554 
    555   return pNode;
    556 }
    557 
    558 UINT32
    559 CIfrRecordInfoDB::IfrRecordRegister (
    560   IN UINT32 LineNo,
    561   IN CHAR8  *IfrBinBuf,
    562   IN UINT8  BinBufLen,
    563   IN UINT32 Offset
    564   )
    565 {
    566   SIfrRecord *pNew;
    567 
    568   if (mSwitch == FALSE) {
    569     return EFI_IFR_RECORDINFO_IDX_INVALUD;
    570   }
    571 
    572   if ((pNew = new SIfrRecord) == NULL) {
    573     return EFI_IFR_RECORDINFO_IDX_INVALUD;
    574   }
    575 
    576   if (mIfrRecordListHead == NULL) {
    577     mIfrRecordListHead = pNew;
    578     mIfrRecordListTail = pNew;
    579   } else {
    580     mIfrRecordListTail->mNext = pNew;
    581     mIfrRecordListTail = pNew;
    582   }
    583   mRecordCount++;
    584 
    585   return mRecordCount;
    586 }
    587 
    588 VOID
    589 CIfrRecordInfoDB::IfrRecordInfoUpdate (
    590   IN UINT32 RecordIdx,
    591   IN UINT32 LineNo,
    592   IN CHAR8  *BinBuf,
    593   IN UINT8  BinBufLen,
    594   IN UINT32 Offset
    595   )
    596 {
    597   SIfrRecord *pNode;
    598   SIfrRecord *Prev;
    599 
    600   if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {
    601     return;
    602   }
    603 
    604   if (LineNo == 0) {
    605     //
    606     // Line number is not specified explicitly, try to use line number of previous opcode
    607     //
    608     Prev = GetRecordInfoFromIdx (RecordIdx - 1);
    609     if (Prev != NULL) {
    610       LineNo = Prev->mLineNo;
    611     }
    612   }
    613   pNode->mLineNo    = LineNo;
    614   pNode->mOffset    = Offset;
    615   pNode->mBinBufLen = BinBufLen;
    616   pNode->mIfrBinBuf = BinBuf;
    617 }
    618 
    619 VOID
    620 CIfrRecordInfoDB::IfrRecordOutput (
    621   IN FILE   *File,
    622   IN UINT32 LineNo
    623   )
    624 {
    625   SIfrRecord *pNode;
    626   UINT8      Index;
    627 
    628   if (mSwitch == FALSE) {
    629     return;
    630   }
    631 
    632   if (File == NULL) {
    633     return;
    634   }
    635 
    636   for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
    637     if (pNode->mLineNo == LineNo) {
    638       fprintf (File, ">%08X: ", pNode->mOffset);
    639       if (pNode->mIfrBinBuf != NULL) {
    640         for (Index = 0; Index < pNode->mBinBufLen; Index++) {
    641           fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));
    642         }
    643       }
    644       fprintf (File, "\n");
    645     }
    646   }
    647 }
    648 
    649 CIfrRecordInfoDB gCIfrRecordInfoDB;
    650 
    651 VOID
    652 CIfrObj::_EMIT_PENDING_OBJ (
    653   VOID
    654   )
    655 {
    656   CHAR8  *ObjBinBuf = NULL;
    657 
    658   ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);
    659   if (ObjBinBuf != NULL) {
    660     memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);
    661   }
    662 
    663   if (mObjBinBuf != NULL) {
    664     delete mObjBinBuf;
    665     mObjBinBuf = ObjBinBuf;
    666   }
    667 }
    668 
    669 /*
    670  * The definition of CIfrObj's member function
    671  */
    672 static struct {
    673   UINT8  mSize;
    674   UINT8  mScope;
    675 } gOpcodeSizesScopeTable[] = {
    676   { 0, 0 },                                    // EFI_IFR_INVALID - 0x00
    677   { sizeof (EFI_IFR_FORM), 1 },                // EFI_IFR_FORM_OP
    678   { sizeof (EFI_IFR_SUBTITLE), 1 },            // EFI_IFR_SUBTITLE_OP
    679   { sizeof (EFI_IFR_TEXT), 0 },                // EFI_IFR_TEXT_OP
    680   { sizeof (EFI_IFR_IMAGE), 0 },               // EFI_IFR_IMAGE_OP
    681   { sizeof (EFI_IFR_ONE_OF), 1 },              // EFI_IFR_ONE_OF_OP - 0x05
    682   { sizeof (EFI_IFR_CHECKBOX), 1},             // EFI_IFR_CHECKBOX_OP
    683   { sizeof (EFI_IFR_NUMERIC), 1 },             // EFI_IFR_NUMERIC_OP
    684   { sizeof (EFI_IFR_PASSWORD), 1 },            // EFI_IFR_PASSWORD_OP
    685   { sizeof (EFI_IFR_ONE_OF_OPTION), 0 },       // EFI_IFR_ONE_OF_OPTION_OP
    686   { sizeof (EFI_IFR_SUPPRESS_IF), 1 },         // EFI_IFR_SUPPRESS_IF - 0x0A
    687   { sizeof (EFI_IFR_LOCKED), 0 },              // EFI_IFR_LOCKED_OP
    688   { sizeof (EFI_IFR_ACTION), 1 },              // EFI_IFR_ACTION_OP
    689   { sizeof (EFI_IFR_RESET_BUTTON), 1 },        // EFI_IFR_RESET_BUTTON_OP
    690   { sizeof (EFI_IFR_FORM_SET), 1 },            // EFI_IFR_FORM_SET_OP -0xE
    691   { sizeof (EFI_IFR_REF), 0 },                 // EFI_IFR_REF_OP
    692   { sizeof (EFI_IFR_NO_SUBMIT_IF), 1},         // EFI_IFR_NO_SUBMIT_IF_OP -0x10
    693   { sizeof (EFI_IFR_INCONSISTENT_IF), 1 },     // EFI_IFR_INCONSISTENT_IF_OP
    694   { sizeof (EFI_IFR_EQ_ID_VAL), 0 },           // EFI_IFR_EQ_ID_VAL_OP
    695   { sizeof (EFI_IFR_EQ_ID_ID), 0 },            // EFI_IFR_EQ_ID_ID_OP
    696   { sizeof (EFI_IFR_EQ_ID_LIST), 0 },          // EFI_IFR_EQ_ID_LIST_OP - 0x14
    697   { sizeof (EFI_IFR_AND), 0 },                 // EFI_IFR_AND_OP
    698   { sizeof (EFI_IFR_OR), 0 },                  // EFI_IFR_OR_OP
    699   { sizeof (EFI_IFR_NOT), 0 },                 // EFI_IFR_NOT_OP
    700   { sizeof (EFI_IFR_RULE), 1 },                // EFI_IFR_RULE_OP
    701   { sizeof (EFI_IFR_GRAY_OUT_IF), 1 },         // EFI_IFR_GRAYOUT_IF_OP - 0x19
    702   { sizeof (EFI_IFR_DATE), 1 },                // EFI_IFR_DATE_OP
    703   { sizeof (EFI_IFR_TIME), 1 },                // EFI_IFR_TIME_OP
    704   { sizeof (EFI_IFR_STRING), 1 },              // EFI_IFR_STRING_OP
    705   { sizeof (EFI_IFR_REFRESH), 0 },             // EFI_IFR_REFRESH_OP
    706   { sizeof (EFI_IFR_DISABLE_IF), 1 },          // EFI_IFR_DISABLE_IF_OP - 0x1E
    707   { 0, 0 },                                    // 0x1F
    708   { sizeof (EFI_IFR_TO_LOWER), 0 },            // EFI_IFR_TO_LOWER_OP - 0x20
    709   { sizeof (EFI_IFR_TO_UPPER), 0 },            // EFI_IFR_TO_UPPER_OP - 0x21
    710   { 0, 0 },                                    // 0x22
    711   { sizeof (EFI_IFR_ORDERED_LIST), 1 },        // EFI_IFR_ORDERED_LIST_OP - 0x23
    712   { sizeof (EFI_IFR_VARSTORE), 0 },            // EFI_IFR_VARSTORE_OP
    713   { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
    714   { sizeof (EFI_IFR_VARSTORE_EFI), 0 },        // EFI_IFR_VARSTORE_EFI_OP
    715   { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 },     // EFI_IFR_VARSTORE_DEVICE_OP
    716   { sizeof (EFI_IFR_VERSION), 0 },             // EFI_IFR_VERSION_OP - 0x28
    717   { sizeof (EFI_IFR_END), 0 },                 // EFI_IFR_END_OP
    718   { sizeof (EFI_IFR_MATCH), 1 },               // EFI_IFR_MATCH_OP - 0x2A
    719   { 0, 0 }, { 0, 0} , { 0, 0} , { 0, 0} ,      // 0x2B ~ 0x2E
    720   { sizeof (EFI_IFR_EQUAL), 0 },               // EFI_IFR_EQUAL_OP - 0x2F
    721   { sizeof (EFI_IFR_NOT_EQUAL), 0 },           // EFI_IFR_NOT_EQUAL_OP
    722   { sizeof (EFI_IFR_GREATER_THAN), 0 },        // EFI_IFR_GREATER_THAN_OP
    723   { sizeof (EFI_IFR_GREATER_EQUAL), 0 },       // EFI_IFR_GREATER_EQUAL_OP
    724   { sizeof (EFI_IFR_LESS_THAN), 0 },           // EFI_IFR_LESS_THAN_OP
    725   { sizeof (EFI_IFR_LESS_EQUAL), 0 },          // EFI_IFR_LESS_EQUAL_OP - 0x34
    726   { sizeof (EFI_IFR_BITWISE_AND), 0 },         // EFI_IFR_BITWISE_AND_OP
    727   { sizeof (EFI_IFR_BITWISE_OR), 0 },          // EFI_IFR_BITWISE_OR_OP
    728   { sizeof (EFI_IFR_BITWISE_NOT), 0 },         // EFI_IFR_BITWISE_NOT_OP
    729   { sizeof (EFI_IFR_SHIFT_LEFT), 0 },          // EFI_IFR_SHIFT_LEFT_OP
    730   { sizeof (EFI_IFR_SHIFT_RIGHT), 0 },         // EFI_IFR_SHIFT_RIGHT_OP
    731   { sizeof (EFI_IFR_ADD), 0 },                 // EFI_IFR_ADD_OP - 0x3A
    732   { sizeof (EFI_IFR_SUBTRACT), 0 },            // EFI_IFR_SUBTRACT_OP
    733   { sizeof (EFI_IFR_MULTIPLY), 0 },            // EFI_IFR_MULTIPLY_OP
    734   { sizeof (EFI_IFR_DIVIDE), 0 },              // EFI_IFR_DIVIDE_OP
    735   { sizeof (EFI_IFR_MODULO), 0 },              // EFI_IFR_MODULO_OP - 0x3E
    736   { sizeof (EFI_IFR_RULE_REF), 0 },            // EFI_IFR_RULE_REF_OP
    737   { sizeof (EFI_IFR_QUESTION_REF1), 0 },       // EFI_IFR_QUESTION_REF1_OP
    738   { sizeof (EFI_IFR_QUESTION_REF2), 0 },       // EFI_IFR_QUESTION_REF2_OP - 0x41
    739   { sizeof (EFI_IFR_UINT8), 0},                // EFI_IFR_UINT8
    740   { sizeof (EFI_IFR_UINT16), 0},               // EFI_IFR_UINT16
    741   { sizeof (EFI_IFR_UINT32), 0},               // EFI_IFR_UINT32
    742   { sizeof (EFI_IFR_UINT64), 0},               // EFI_IFR_UTNT64
    743   { sizeof (EFI_IFR_TRUE), 0 },                // EFI_IFR_TRUE_OP - 0x46
    744   { sizeof (EFI_IFR_FALSE), 0 },               // EFI_IFR_FALSE_OP
    745   { sizeof (EFI_IFR_TO_UINT), 0 },             // EFI_IFR_TO_UINT_OP
    746   { sizeof (EFI_IFR_TO_STRING), 0 },           // EFI_IFR_TO_STRING_OP
    747   { sizeof (EFI_IFR_TO_BOOLEAN), 0 },          // EFI_IFR_TO_BOOLEAN_OP
    748   { sizeof (EFI_IFR_MID), 0 },                 // EFI_IFR_MID_OP
    749   { sizeof (EFI_IFR_FIND), 0 },                // EFI_IFR_FIND_OP
    750   { sizeof (EFI_IFR_TOKEN), 0 },               // EFI_IFR_TOKEN_OP
    751   { sizeof (EFI_IFR_STRING_REF1), 0 },         // EFI_IFR_STRING_REF1_OP - 0x4E
    752   { sizeof (EFI_IFR_STRING_REF2), 0 },         // EFI_IFR_STRING_REF2_OP
    753   { sizeof (EFI_IFR_CONDITIONAL), 0 },         // EFI_IFR_CONDITIONAL_OP
    754   { sizeof (EFI_IFR_QUESTION_REF3), 0 },       // EFI_IFR_QUESTION_REF3_OP
    755   { sizeof (EFI_IFR_ZERO), 0 },                // EFI_IFR_ZERO_OP
    756   { sizeof (EFI_IFR_ONE), 0 },                 // EFI_IFR_ONE_OP
    757   { sizeof (EFI_IFR_ONES), 0 },                // EFI_IFR_ONES_OP
    758   { sizeof (EFI_IFR_UNDEFINED), 0 },           // EFI_IFR_UNDEFINED_OP
    759   { sizeof (EFI_IFR_LENGTH), 0 },              // EFI_IFR_LENGTH_OP
    760   { sizeof (EFI_IFR_DUP), 0 },                 // EFI_IFR_DUP_OP - 0x57
    761   { sizeof (EFI_IFR_THIS), 0 },                // EFI_IFR_THIS_OP
    762   { sizeof (EFI_IFR_SPAN), 0 },                // EFI_IFR_SPAN_OP
    763   { sizeof (EFI_IFR_VALUE), 1 },               // EFI_IFR_VALUE_OP
    764   { sizeof (EFI_IFR_DEFAULT), 0 },             // EFI_IFR_DEFAULT_OP
    765   { sizeof (EFI_IFR_DEFAULTSTORE), 0 },        // EFI_IFR_DEFAULTSTORE_OP - 0x5C
    766   { 0, 0},                                     // 0x5D
    767   { sizeof (EFI_IFR_CATENATE), 0 },            // EFI_IFR_CATENATE_OP
    768   { sizeof (EFI_IFR_GUID), 0 },                // EFI_IFR_GUID_OP
    769 };
    770 
    771 #ifdef CIFROBJ_DEUBG
    772 static struct {
    773   INT8 *mIfrName;
    774 } gIfrObjPrintDebugTable[] = {
    775   "EFI_IFR_INVALID",    "EFI_IFR_FORM",                 "EFI_IFR_SUBTITLE",      "EFI_IFR_TEXT",            "EFI_IFR_IMAGE",         "EFI_IFR_ONE_OF",
    776   "EFI_IFR_CHECKBOX",   "EFI_IFR_NUMERIC",              "EFI_IFR_PASSWORD",      "EFI_IFR_ONE_OF_OPTION",   "EFI_IFR_SUPPRESS_IF",   "EFI_IFR_LOCKED",
    777   "EFI_IFR_ACTION",     "EFI_IFR_RESET_BUTTON",         "EFI_IFR_FORM_SET",      "EFI_IFR_REF",             "EFI_IFR_NO_SUBMIT_IF",  "EFI_IFR_INCONSISTENT_IF",
    778   "EFI_IFR_EQ_ID_VAL",  "EFI_IFR_EQ_ID_ID",             "EFI_IFR_EQ_ID_LIST",    "EFI_IFR_AND",             "EFI_IFR_OR",            "EFI_IFR_NOT",
    779   "EFI_IFR_RULE",       "EFI_IFR_GRAY_OUT_IF",          "EFI_IFR_DATE",          "EFI_IFR_TIME",            "EFI_IFR_STRING",        "EFI_IFR_REFRESH",
    780   "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID",              "EFI_IFR_TO_LOWER",      "EFI_IFR_TO_UPPER",        "EFI_IFR_INVALID",       "EFI_IFR_ORDERED_LIST",
    781   "EFI_IFR_VARSTORE",   "EFI_IFR_VARSTORE_NAME_VALUE",  "EFI_IFR_VARSTORE_EFI",  "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION",       "EFI_IFR_END",
    782   "EFI_IFR_MATCH",      "EFI_IFR_INVALID",              "EFI_IFR_INVALID",       "EFI_IFR_INVALID",         "EFI_IFR_INVALID",       "EFI_IFR_EQUAL",
    783   "EFI_IFR_NOT_EQUAL",  "EFI_IFR_GREATER_THAN",         "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN",       "EFI_IFR_LESS_EQUAL",    "EFI_IFR_BITWISE_AND",
    784   "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT",          "EFI_IFR_SHIFT_LEFT",    "EFI_IFR_SHIFT_RIGHT",     "EFI_IFR_ADD",           "EFI_IFR_SUBTRACT",
    785   "EFI_IFR_MULTIPLY",   "EFI_IFR_DIVIDE",               "EFI_IFR_MODULO",        "EFI_IFR_RULE_REF",        "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
    786   "EFI_IFR_UINT8",      "EFI_IFR_UINT16",               "EFI_IFR_UINT32",        "EFI_IFR_UINT64",          "EFI_IFR_TRUE",          "EFI_IFR_FALSE",
    787   "EFI_IFR_TO_UINT",    "EFI_IFR_TO_STRING",            "EFI_IFR_TO_BOOLEAN",    "EFI_IFR_MID",             "EFI_IFR_FIND",          "EFI_IFR_TOKEN",
    788   "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2",          "EFI_IFR_CONDITIONAL",   "EFI_IFR_QUESTION_REF3",   "EFI_IFR_ZERO",          "EFI_IFR_ONE",
    789   "EFI_IFR_ONES",       "EFI_IFR_UNDEFINED",            "EFI_IFR_LENGTH",        "EFI_IFR_DUP",             "EFI_IFR_THIS",          "EFI_IFR_SPAN",
    790   "EFI_IFR_VALUE",      "EFI_IFR_DEFAULT",              "EFI_IFR_DEFAULTSTORE",  "EFI_IFR_INVALID",         "EFI_IFR_CATENATE",      "EFI_IFR_GUID",
    791 };
    792 
    793 VOID
    794 CIFROBJ_DEBUG_PRINT (
    795   IN UINT8 OpCode
    796   )
    797 {
    798   printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);
    799 }
    800 #else
    801 
    802 #define CIFROBJ_DEBUG_PRINT(OpCode)
    803 
    804 #endif
    805 
    806 bool gCreateOp = TRUE;
    807 
    808 CIfrObj::CIfrObj (
    809   IN  UINT8   OpCode,
    810   OUT CHAR8   **IfrObj,
    811   IN  UINT8   ObjBinLen,
    812   IN  BOOLEAN DelayEmit
    813   )
    814 {
    815   mDelayEmit   = DelayEmit;
    816   mPkgOffset   = gCFormPkg.GetPkgLength ();
    817   mObjBinLen   = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;
    818   mObjBinBuf   = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];
    819   mRecordIdx   = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;
    820 
    821   if (IfrObj != NULL) {
    822     *IfrObj    = mObjBinBuf;
    823   }
    824 
    825   CIFROBJ_DEBUG_PRINT (OpCode);
    826 }
    827 
    828 CIfrObj::~CIfrObj (
    829   VOID
    830   )
    831 {
    832   if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {
    833     _EMIT_PENDING_OBJ ();
    834   }
    835 
    836   gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);
    837 }
    838 
    839 /*
    840  * The definition of CIfrObj's member function
    841  */
    842 UINT8 gScopeCount = 0;
    843 
    844 CIfrOpHeader::CIfrOpHeader (
    845   IN UINT8 OpCode,
    846   IN VOID *StartAddr,
    847   IN UINT8 Length
    848   ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)
    849 {
    850   mHeader->OpCode = OpCode;
    851   mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;
    852   mHeader->Scope  = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;
    853 }
    854 
    855 CIfrOpHeader::CIfrOpHeader (
    856   IN CIfrOpHeader &OpHdr
    857   )
    858 {
    859   mHeader = OpHdr.mHeader;
    860 }
    861 
    862 UINT32 CIfrForm::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };
    863