]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
Sync BaseTool trunk (version r2601) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrFormPkg.cpp
index 87da95af715c76f7eab6c218f1947a34c4b547a4..363ca82a241bfb46866f7f24d562f258b882529b 100644 (file)
@@ -2,8 +2,8 @@
   \r
   The definition of CFormPkg's member function\r
 \r
-Copyright (c) 2004 - 2009, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
 http://opensource.org/licenses/bsd-license.php                                            \r
@@ -25,7 +25,7 @@ SPendingAssign::SPendingAssign (
   IN VOID   *Addr, \r
   IN UINT32 Len, \r
   IN UINT32 LineNo,\r
-  IN CHAR8  *Msg\r
+  IN CONST CHAR8  *Msg\r
   )\r
 {\r
   mKey    = NULL;\r
@@ -152,12 +152,39 @@ CFormPkg::~CFormPkg ()
   PendingAssignList = NULL;\r
 }\r
 \r
+SBufferNode *\r
+CFormPkg::CreateNewNode (\r
+  VOID\r
+  )\r
+{\r
+  SBufferNode *Node;\r
+\r
+  Node = new SBufferNode;\r
+  if (Node == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  Node->mBufferStart = new CHAR8[mBufferSize];\r
+  if (Node->mBufferStart == NULL) {\r
+    delete Node;\r
+    return NULL;\r
+  } else {\r
+    memset (Node->mBufferStart, 0, mBufferSize);\r
+    Node->mBufferEnd  = Node->mBufferStart + mBufferSize;\r
+    Node->mBufferFree = Node->mBufferStart;\r
+    Node->mNext       = NULL;\r
+  }\r
+\r
+  return Node;\r
+}\r
+\r
 CHAR8 *\r
 CFormPkg::IfrBinBufferGet (\r
   IN UINT32 Len\r
   )\r
 {\r
-  CHAR8 *BinBuffer = NULL;\r
+  CHAR8       *BinBuffer = NULL;\r
+  SBufferNode *Node      = NULL;\r
 \r
   if ((Len == 0) || (Len > mBufferSize)) {\r
     return NULL;\r
@@ -167,24 +194,11 @@ CFormPkg::IfrBinBufferGet (
     BinBuffer = mCurrBufferNode->mBufferFree;\r
     mCurrBufferNode->mBufferFree += Len;\r
   } else {\r
-    SBufferNode *Node;\r
-\r
-    Node = new SBufferNode;\r
+    Node = CreateNewNode ();\r
     if (Node == NULL) {\r
       return NULL;\r
     }\r
 \r
-    Node->mBufferStart = new CHAR8[mBufferSize];\r
-    if (Node->mBufferStart == NULL) {\r
-      delete Node;\r
-      return NULL;\r
-    } else {\r
-      memset (Node->mBufferStart, 0, mBufferSize);\r
-      Node->mBufferEnd  = Node->mBufferStart + mBufferSize;\r
-      Node->mBufferFree = Node->mBufferStart;\r
-      Node->mNext       = NULL;\r
-    }\r
-\r
     if (mBufferNodeQueueTail == NULL) {\r
       mBufferNodeQueueHead = mBufferNodeQueueTail = Node;\r
     } else {\r
@@ -245,7 +259,7 @@ CFormPkg::Read (
   }\r
 \r
   if (mReadBufferNode == NULL) {\r
-       return 0;\r
+    return 0;\r
   }\r
 \r
   for (Index = 0; Index < Size; Index++) {\r
@@ -256,7 +270,7 @@ CFormPkg::Read (
         return Index;\r
       } else {\r
         mReadBufferOffset = 0;\r
-        Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
+        Index --;\r
       }\r
     }\r
   }\r
@@ -352,11 +366,11 @@ CFormPkg::BuildPkg (
 \r
 VOID\r
 CFormPkg::_WRITE_PKG_LINE (\r
-  IN FILE   *pFile,\r
-  IN UINT32 LineBytes,\r
-  IN CHAR8  *LineHeader,\r
-  IN CHAR8  *BlkBuf,\r
-  IN UINT32 BlkSize\r
+  IN FILE         *pFile,\r
+  IN UINT32       LineBytes,\r
+  IN CONST CHAR8  *LineHeader,\r
+  IN CHAR8        *BlkBuf,\r
+  IN UINT32       BlkSize\r
   )\r
 {\r
   UINT32    Index;\r
@@ -375,11 +389,11 @@ CFormPkg::_WRITE_PKG_LINE (
 \r
 VOID\r
 CFormPkg::_WRITE_PKG_END (\r
-  IN FILE   *pFile,\r
-  IN UINT32 LineBytes,\r
-  IN CHAR8  *LineHeader,\r
-  IN CHAR8  *BlkBuf,\r
-  IN UINT32 BlkSize\r
+  IN FILE         *pFile,\r
+  IN UINT32       LineBytes,\r
+  IN CONST CHAR8  *LineHeader,\r
+  IN CHAR8        *BlkBuf,\r
+  IN UINT32       BlkSize\r
   )\r
 {\r
   UINT32    Index;\r
@@ -402,6 +416,9 @@ CFormPkg::_WRITE_PKG_END (
 }\r
 \r
 #define BYTES_PRE_LINE 0x10\r
+UINT32   gAdjustOpcodeOffset = 0;\r
+BOOLEAN  gNeedAdjustOpcode   = FALSE;\r
+UINT32   gAdjustOpcodeLen    = 0;\r
 \r
 EFI_VFR_RETURN_CODE \r
 CFormPkg::GenCFile (\r
@@ -483,7 +500,7 @@ CFormPkg::AssignPending (
   IN VOID   *ValAddr, \r
   IN UINT32 ValLen,\r
   IN UINT32 LineNo,\r
-  IN CHAR8  *Msg\r
+  IN CONST CHAR8  *Msg\r
   )\r
 {\r
   SPendingAssign *pNew;\r
@@ -548,38 +565,266 @@ CFormPkg::PendingAssignPrintAll (
   }\r
 }\r
 \r
+SBufferNode *\r
+CFormPkg::GetBinBufferNodeForAddr (\r
+  IN CHAR8              *BinBuffAddr\r
+  )\r
+{\r
+  SBufferNode *TmpNode;\r
+\r
+  TmpNode = mBufferNodeQueueHead;\r
+\r
+  while (TmpNode != NULL) {\r
+    if (TmpNode->mBufferStart <= BinBuffAddr && TmpNode->mBufferFree >= BinBuffAddr) {\r
+      return TmpNode;\r
+    }\r
+\r
+    TmpNode = TmpNode->mNext;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+SBufferNode *\r
+CFormPkg::GetNodeBefore(\r
+  IN SBufferNode *CurrentNode\r
+  )\r
+{\r
+  SBufferNode *FirstNode   = mBufferNodeQueueHead;\r
+  SBufferNode *LastNode    = mBufferNodeQueueHead;\r
+\r
+  while (FirstNode != NULL) {\r
+    if (FirstNode == CurrentNode) {\r
+      break;\r
+    }\r
+\r
+    LastNode    = FirstNode;\r
+    FirstNode   = FirstNode->mNext;\r
+  }\r
+\r
+  if (FirstNode == NULL) {\r
+    LastNode = NULL;\r
+  }\r
+\r
+  return LastNode;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CFormPkg::InsertNodeBefore(\r
+  IN SBufferNode *CurrentNode,\r
+  IN SBufferNode *NewNode\r
+  )\r
+{\r
+  SBufferNode *LastNode = GetNodeBefore (CurrentNode);\r
+\r
+  if (LastNode == NULL) {\r
+    return VFR_RETURN_MISMATCHED;\r
+  }\r
+\r
+  NewNode->mNext = LastNode->mNext;\r
+  LastNode->mNext = NewNode;\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
+CHAR8 *\r
+CFormPkg::GetBufAddrBaseOnOffset (\r
+  IN UINT32      Offset\r
+  )\r
+{\r
+  SBufferNode *TmpNode;\r
+  UINT32      TotalBufLen;\r
+  UINT32      CurrentBufLen;\r
+\r
+  TotalBufLen = 0;\r
+\r
+  for (TmpNode = mBufferNodeQueueHead; TmpNode != NULL; TmpNode = TmpNode->mNext) {\r
+    CurrentBufLen = TmpNode->mBufferFree - TmpNode->mBufferStart;\r
+    if (Offset >= TotalBufLen && Offset < TotalBufLen + CurrentBufLen) {\r
+      return TmpNode->mBufferStart + (Offset - TotalBufLen);\r
+    }\r
+\r
+    TotalBufLen += CurrentBufLen;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+EFI_VFR_RETURN_CODE\r
+CFormPkg::AdjustDynamicInsertOpcode (\r
+  IN CHAR8              *LastFormEndAddr,\r
+  IN CHAR8              *InsertOpcodeAddr\r
+  )\r
+{\r
+  SBufferNode *LastFormEndNode;\r
+  SBufferNode *InsertOpcodeNode;\r
+  SBufferNode *NewRestoreNodeBegin;\r
+  SBufferNode *NewRestoreNodeEnd;\r
+  SBufferNode *NewLastEndNode;\r
+  SBufferNode *TmpNode;\r
+  UINT32      NeedRestoreCodeLen;\r
+\r
+  NewRestoreNodeEnd = NULL;\r
+\r
+  LastFormEndNode  = GetBinBufferNodeForAddr(LastFormEndAddr);\r
+  InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);\r
+\r
+  if (LastFormEndNode == InsertOpcodeNode) {\r
+    //\r
+    // Create New Node to save the restore opcode.\r
+    //\r
+    NeedRestoreCodeLen = InsertOpcodeAddr - LastFormEndAddr;\r
+    gAdjustOpcodeLen   = NeedRestoreCodeLen;\r
+    NewRestoreNodeBegin = CreateNewNode ();\r
+    if (NewRestoreNodeBegin == NULL) {\r
+      return VFR_RETURN_OUT_FOR_RESOURCES;\r
+    }\r
+    memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen);\r
+    NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;\r
+\r
+    //\r
+    // Override the restore buffer data.\r
+    //\r
+    memcpy (LastFormEndAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
+    InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen;\r
+    memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen);\r
+  } else {\r
+    //\r
+    // Create New Node to save the restore opcode.\r
+    //\r
+    NeedRestoreCodeLen = LastFormEndNode->mBufferFree - LastFormEndAddr;\r
+    gAdjustOpcodeLen   = NeedRestoreCodeLen;\r
+    NewRestoreNodeBegin = CreateNewNode ();\r
+    if (NewRestoreNodeBegin == NULL) {\r
+      return VFR_RETURN_OUT_FOR_RESOURCES;\r
+    }\r
+    memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen);\r
+    NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;\r
+    //\r
+    // Override the restore buffer data.\r
+    //\r
+    LastFormEndNode->mBufferFree -= NeedRestoreCodeLen;\r
+    //\r
+    // Link the restore data to new node.\r
+    //\r
+    NewRestoreNodeBegin->mNext = LastFormEndNode->mNext;\r
+\r
+    //\r
+    // Count the Adjust opcode len.\r
+    //\r
+    TmpNode = LastFormEndNode->mNext;\r
+    while (TmpNode != InsertOpcodeNode) {\r
+      gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart;\r
+      TmpNode = TmpNode->mNext;\r
+    }\r
+\r
+    //\r
+    // Create New Node to save the last node of restore opcode.\r
+    //\r
+    NeedRestoreCodeLen = InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;\r
+    gAdjustOpcodeLen  += NeedRestoreCodeLen;\r
+    if (NeedRestoreCodeLen > 0) {\r
+      NewRestoreNodeEnd = CreateNewNode ();\r
+      if (NewRestoreNodeEnd == NULL) {\r
+        return VFR_RETURN_OUT_FOR_RESOURCES;\r
+      }\r
+      memcpy (NewRestoreNodeEnd->mBufferFree, InsertOpcodeNode->mBufferStart, NeedRestoreCodeLen);\r
+      NewRestoreNodeEnd->mBufferFree += NeedRestoreCodeLen;\r
+      //\r
+      // Override the restore buffer data.\r
+      //\r
+      memcpy (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);\r
+      InsertOpcodeNode->mBufferFree -= InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;\r
+\r
+      //\r
+      // Insert the last restore data node.\r
+      //\r
+      TmpNode = GetNodeBefore (InsertOpcodeNode);\r
+      if (TmpNode == LastFormEndNode) {\r
+        NewRestoreNodeBegin->mNext = NewRestoreNodeEnd;\r
+      } else {\r
+        TmpNode->mNext = NewRestoreNodeEnd;\r
+      }\r
+      //\r
+      // Connect the dynamic opcode node to the node before last form end node.\r
+      //\r
+      LastFormEndNode->mNext = InsertOpcodeNode;\r
+    }\r
+  }\r
+\r
+  if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {\r
+    //\r
+    // End form set opcode all in the mBufferNodeQueueTail node.\r
+    //\r
+    NewLastEndNode = CreateNewNode ();\r
+    if (NewLastEndNode == NULL) {\r
+      return VFR_RETURN_OUT_FOR_RESOURCES;\r
+    }\r
+    NewLastEndNode->mBufferStart[0] = 0x29;\r
+    NewLastEndNode->mBufferStart[1] = 0x02;\r
+    NewLastEndNode->mBufferFree += 2;\r
+\r
+    mBufferNodeQueueTail->mBufferFree -= 2;\r
+\r
+    mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;\r
+    if (NewRestoreNodeEnd != NULL) {\r
+      NewRestoreNodeEnd->mNext = NewLastEndNode;\r
+    } else {\r
+      NewRestoreNodeBegin->mNext = NewLastEndNode;\r
+    }\r
+\r
+    mBufferNodeQueueTail = NewLastEndNode;\r
+  } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {\r
+    TmpNode = GetNodeBefore(mBufferNodeQueueTail);\r
+    TmpNode->mNext = NewRestoreNodeBegin;\r
+    if (NewRestoreNodeEnd != NULL) {\r
+      NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;\r
+    } else {\r
+      NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;\r
+    }\r
+  }\r
+\r
+  return VFR_RETURN_SUCCESS;\r
+}\r
+\r
 EFI_VFR_RETURN_CODE\r
 CFormPkg::DeclarePendingQuestion (\r
   IN CVfrVarDataTypeDB   &lCVfrVarDataTypeDB,\r
   IN CVfrDataStorage     &lCVfrDataStorage,\r
   IN CVfrQuestionDB      &lCVfrQuestionDB,\r
   IN EFI_GUID            *LocalFormSetGuid,\r
-  IN UINT32 LineNo\r
+  IN UINT32              LineNo,\r
+  OUT CHAR8              **InsertOpcodeAddr\r
   )\r
 {\r
   SPendingAssign *pNode;\r
   CHAR8          *VarStr;\r
   UINT32         ArrayIdx;\r
   CHAR8          FName[MAX_NAME_LEN];\r
+  CHAR8          *SName;\r
+  CHAR8          *NewStr;\r
+  UINT32         ShrinkSize;\r
   EFI_VFR_RETURN_CODE  ReturnCode;\r
   EFI_VFR_VARSTORE_TYPE VarStoreType  = EFI_VFR_VARSTORE_INVALID;\r
+  EFI_VARSTORE_ID       VarStoreId    = EFI_VARSTORE_ID_INVALID;\r
+\r
+  //\r
+  // Declare all questions as Numeric in DisableIf True\r
+  //\r
+  // DisableIf\r
+  CIfrDisableIf DIObj;\r
+  DIObj.SetLineNo (LineNo);\r
+  *InsertOpcodeAddr = DIObj.GetObjBinAddr ();\r
+  \r
+  //TrueOpcode\r
+  CIfrTrue TObj (LineNo);\r
 \r
+  // Declare Numeric qeustion for each undefined question.\r
   for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
     if (pNode->mFlag == PENDING) {\r
-      //\r
-      //  declare this question as Numeric in SuppressIf True\r
-      //\r
-      // SuppressIf\r
-      CIfrSuppressIf SIObj;\r
-      SIObj.SetLineNo (LineNo);\r
-      \r
-      //TrueOpcode\r
-      CIfrTrue TObj (LineNo);\r
-      \r
-      //Numeric qeustion\r
       CIfrNumeric CNObj;\r
       EFI_VARSTORE_INFO Info; \r
-         EFI_QUESTION_ID   QId   = EFI_QUESTION_ID_INVALID;\r
+      EFI_QUESTION_ID   QId   = EFI_QUESTION_ID_INVALID;\r
 \r
       CNObj.SetLineNo (LineNo);\r
       CNObj.SetPrompt (0x0);\r
@@ -609,7 +854,7 @@ CFormPkg::DeclarePendingQuestion (
       //\r
       // Get VarStoreType\r
       //\r
-      ReturnCode = lCVfrDataStorage.GetVarStoreType (FName, VarStoreType);\r
+      ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);\r
       if (ReturnCode == VFR_RETURN_UNDEFINED) {\r
         lCVfrDataStorage.DeclareBufferVarStore (\r
                            FName, \r
@@ -619,18 +864,13 @@ CFormPkg::DeclarePendingQuestion (
                            EFI_VARSTORE_ID_INVALID,\r
                            FALSE\r
                            );\r
-        ReturnCode = lCVfrDataStorage.GetVarStoreType (FName, VarStoreType);  \r
-      }\r
-      if (ReturnCode != VFR_RETURN_SUCCESS) {\r
-        gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
-        return ReturnCode;\r
+        ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId, LocalFormSetGuid); \r
       }\r
-      \r
-      ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);\r
       if (ReturnCode != VFR_RETURN_SUCCESS) {\r
         gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
         return ReturnCode;\r
       }\r
+      VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId); \r
 \r
       if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {\r
         ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);\r
@@ -639,7 +879,16 @@ CFormPkg::DeclarePendingQuestion (
           ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);\r
         } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {\r
           VarStr = pNode->mKey;\r
-          ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (VarStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);\r
+          //convert VarStr with store name to VarStr with structure name\r
+          ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);\r
+          if (ReturnCode == VFR_RETURN_SUCCESS) {\r
+            NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];\r
+            NewStr[0] = '\0';\r
+            strcpy (NewStr, SName);\r
+            strcat (NewStr, VarStr + strlen (FName));\r
+            ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);\r
+            delete NewStr;\r
+          }\r
         } else {\r
           ReturnCode = VFR_RETURN_UNSUPPORTED;\r
         }\r
@@ -651,29 +900,62 @@ CFormPkg::DeclarePendingQuestion (
 \r
       CNObj.SetQuestionId (QId);\r
       CNObj.SetVarStoreInfo (&Info);\r
+      //\r
+      // Numeric doesn't support BOOLEAN data type. \r
+      // BOOLEAN type has the same data size to UINT8. \r
+      //\r
+      if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {\r
+        Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
+      }\r
       CNObj.SetFlags (0, Info.mVarType);\r
+      //\r
+      // Use maximum value not to limit the vaild value for the undefined question.\r
+      //\r
+      switch (Info.mVarType) {\r
+      case EFI_IFR_TYPE_NUM_SIZE_64:\r
+        CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);\r
+        ShrinkSize = 0;\r
+        break;\r
+      case EFI_IFR_TYPE_NUM_SIZE_32:\r
+        CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
+        ShrinkSize = 12;\r
+        break;\r
+      case EFI_IFR_TYPE_NUM_SIZE_16:\r
+        CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
+        ShrinkSize = 18;\r
+        break;\r
+      case EFI_IFR_TYPE_NUM_SIZE_8:\r
+        CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
+        ShrinkSize = 21;\r
+        break;\r
+      default:\r
+        break;\r
+      }\r
+      CNObj.ShrinkBinSize (ShrinkSize);\r
 \r
       //\r
       // For undefined Efi VarStore type question\r
       // Append the extended guided opcode to contain VarName\r
       //\r
-      if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
+      if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {\r
         CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);\r
         CVNObj.SetLineNo (LineNo);\r
       }\r
-      \r
+\r
       //\r
       // End for Numeric\r
       //\r
       CIfrEnd CEObj; \r
       CEObj.SetLineNo (LineNo);\r
-      //\r
-      // End for SuppressIf\r
-      //\r
-      CIfrEnd SEObj;\r
-      SEObj.SetLineNo (LineNo);\r
     }\r
   }\r
+\r
+  //\r
+  // End for DisableIf\r
+  //\r
+  CIfrEnd SEObj;\r
+  SEObj.SetLineNo (LineNo);\r
+\r
   return VFR_RETURN_SUCCESS;\r
 }\r
 \r
@@ -924,7 +1206,7 @@ CIfrRecordInfoDB::CheckIdOpCode (
   switch (OpCode) {\r
   case EFI_IFR_EQ_ID_VAL_OP:\r
   case EFI_IFR_EQ_ID_ID_OP:\r
-  case EFI_IFR_EQ_ID_LIST_OP:\r
+  case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
   case EFI_IFR_QUESTION_REF1_OP:\r
     return TRUE;\r
   default:\r
@@ -944,6 +1226,94 @@ CIfrRecordInfoDB::GetOpcodeQuestionId (
   return QuestionHead->QuestionId;\r
 }\r
 \r
+SIfrRecord *\r
+CIfrRecordInfoDB::GetRecordInfoFromOffset (\r
+  IN UINT32 Offset\r
+  )\r
+{\r
+  SIfrRecord *pNode = NULL;\r
+\r
+  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
+    if (pNode->mOffset == Offset) {\r
+      return pNode;\r
+    }\r
+  }\r
+\r
+  return pNode;\r
+}\r
+\r
+/*\r
+  Add just the op code position.\r
+\r
+  From\r
+  \r
+  | form end opcode + end of if opcode for form ... + Dynamic opcode + form set end opcode |\r
+  \r
+  To\r
+  \r
+  | Dynamic opcode + form end opcode + end of if opcode for form ... + form set end opcode |\r
+\r
+*/\r
+BOOLEAN\r
+CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (\r
+  VOID\r
+  )\r
+{\r
+  UINT32             OpcodeOffset;\r
+  SIfrRecord         *pNode, *pPreNode;\r
+  SIfrRecord         *pStartNode, *pNodeBeforeStart;\r
+  SIfrRecord         *pEndNode;\r
+  \r
+  pStartNode = NULL;\r
+  pEndNode   = NULL;\r
+  OpcodeOffset = 0;\r
+\r
+  //\r
+  // Base on the offset info to get the node.\r
+  //\r
+  for (pNode = mIfrRecordListHead; pNode->mNext != NULL; pPreNode = pNode,pNode = pNode->mNext) {\r
+    if (OpcodeOffset == gAdjustOpcodeOffset) {\r
+      pStartNode       = pNode;\r
+      pNodeBeforeStart = pPreNode;\r
+    } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {\r
+      pEndNode = pPreNode;\r
+    }\r
+\r
+    OpcodeOffset += pNode->mBinBufLen;\r
+  }\r
+\r
+  //\r
+  // Check the value.\r
+  //\r
+  if (pEndNode == NULL || pStartNode == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Adjust the node. pPreNode save the Node before mIfrRecordListTail\r
+  //\r
+  pNodeBeforeStart->mNext = pEndNode->mNext;\r
+  pPreNode->mNext = pStartNode;\r
+  pEndNode->mNext = mIfrRecordListTail;\r
+\r
+  return TRUE;\r
+}\r
+\r
+VOID\r
+CIfrRecordInfoDB::IfrAdjustOffsetForRecord (\r
+  VOID\r
+  )\r
+{\r
+  UINT32             OpcodeOffset;\r
+  SIfrRecord         *pNode;\r
+\r
+  OpcodeOffset = 0;\r
+  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
+    pNode->mOffset = OpcodeOffset;\r
+    OpcodeOffset += pNode->mBinBufLen;\r
+  }\r
+}\r
+\r
 EFI_VFR_RETURN_CODE\r
 CIfrRecordInfoDB::IfrRecordAdjust (\r
   VOID\r
@@ -1156,11 +1526,7 @@ CIfrRecordInfoDB::IfrRecordAdjust (
   // Update Ifr Opcode Offset\r
   //\r
   if (Status == VFR_RETURN_SUCCESS) {\r
-    OpcodeOffset = 0;\r
-    for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
-      pNode->mOffset = OpcodeOffset;\r
-      OpcodeOffset += pNode->mBinBufLen;\r
-    }\r
+    IfrAdjustOffsetForRecord ();\r
   }\r
   return Status;\r
 }\r
@@ -1242,7 +1608,7 @@ static struct {
   { 0, 0 },                                    // 0x1F\r
   { sizeof (EFI_IFR_TO_LOWER), 0 },            // EFI_IFR_TO_LOWER_OP - 0x20\r
   { sizeof (EFI_IFR_TO_UPPER), 0 },            // EFI_IFR_TO_UPPER_OP - 0x21\r
-  { 0, 0 },                                    // 0x22\r
+  { sizeof (EFI_IFR_MAP), 1 },                 // EFI_IFR_MAP - 0x22\r
   { sizeof (EFI_IFR_ORDERED_LIST), 1 },        // EFI_IFR_ORDERED_LIST_OP - 0x23\r
   { sizeof (EFI_IFR_VARSTORE), 0 },            // EFI_IFR_VARSTORE_OP\r
   { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
@@ -1250,8 +1616,11 @@ static struct {
   { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 },     // EFI_IFR_VARSTORE_DEVICE_OP\r
   { sizeof (EFI_IFR_VERSION), 0 },             // EFI_IFR_VERSION_OP - 0x28\r
   { sizeof (EFI_IFR_END), 0 },                 // EFI_IFR_END_OP\r
-  { sizeof (EFI_IFR_MATCH), 1 },               // EFI_IFR_MATCH_OP - 0x2A\r
-  { 0, 0 }, { 0, 0} , { 0, 0} , { 0, 0} ,      // 0x2B ~ 0x2E\r
+  { sizeof (EFI_IFR_MATCH), 0 },               // EFI_IFR_MATCH_OP - 0x2A\r
+  { sizeof (EFI_IFR_GET), 0 },                 // EFI_IFR_GET - 0x2B\r
+  { sizeof (EFI_IFR_SET), 0 },                 // EFI_IFR_SET - 0x2C\r
+  { sizeof (EFI_IFR_READ), 0 },                // EFI_IFR_READ - 0x2D\r
+  { sizeof (EFI_IFR_WRITE), 0 },               // EFI_IFR_WRITE - 0x2E\r
   { sizeof (EFI_IFR_EQUAL), 0 },               // EFI_IFR_EQUAL_OP - 0x2F\r
   { sizeof (EFI_IFR_NOT_EQUAL), 0 },           // EFI_IFR_NOT_EQUAL_OP\r
   { sizeof (EFI_IFR_GREATER_THAN), 0 },        // EFI_IFR_GREATER_THAN_OP\r
@@ -1298,9 +1667,13 @@ static struct {
   { sizeof (EFI_IFR_VALUE), 1 },               // EFI_IFR_VALUE_OP\r
   { sizeof (EFI_IFR_DEFAULT), 0 },             // EFI_IFR_DEFAULT_OP\r
   { sizeof (EFI_IFR_DEFAULTSTORE), 0 },        // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
-  { 0, 0},                                     // 0x5D\r
+  { sizeof (EFI_IFR_FORM_MAP), 1},             // EFI_IFR_FORM_MAP_OP - 0x5D\r
   { sizeof (EFI_IFR_CATENATE), 0 },            // EFI_IFR_CATENATE_OP\r
   { sizeof (EFI_IFR_GUID), 0 },                // EFI_IFR_GUID_OP\r
+  { sizeof (EFI_IFR_SECURITY), 0 },            // EFI_IFR_SECURITY_OP - 0x60\r
+  { sizeof (EFI_IFR_MODAL_TAG), 0},            // EFI_IFR_MODAL_TAG_OP - 0x61\r
+  { sizeof (EFI_IFR_REFRESH_ID), 0},           // EFI_IFR_REFRESH_ID_OP - 0x62\r
+  { sizeof (EFI_IFR_WARNING_IF), 1},           // EFI_IFR_WARNING_IF_OP - 0x63\r
 };\r
 \r
 #ifdef CIFROBJ_DEUBG\r
@@ -1312,9 +1685,9 @@ static struct {
   "EFI_IFR_ACTION",     "EFI_IFR_RESET_BUTTON",         "EFI_IFR_FORM_SET",      "EFI_IFR_REF",             "EFI_IFR_NO_SUBMIT_IF",  "EFI_IFR_INCONSISTENT_IF",\r
   "EFI_IFR_EQ_ID_VAL",  "EFI_IFR_EQ_ID_ID",             "EFI_IFR_EQ_ID_LIST",    "EFI_IFR_AND",             "EFI_IFR_OR",            "EFI_IFR_NOT",\r
   "EFI_IFR_RULE",       "EFI_IFR_GRAY_OUT_IF",          "EFI_IFR_DATE",          "EFI_IFR_TIME",            "EFI_IFR_STRING",        "EFI_IFR_REFRESH",\r
-  "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID",              "EFI_IFR_TO_LOWER",      "EFI_IFR_TO_UPPER",        "EFI_IFR_INVALID",       "EFI_IFR_ORDERED_LIST",\r
+  "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID",              "EFI_IFR_TO_LOWER",      "EFI_IFR_TO_UPPER",        "EFI_IFR_MAP",           "EFI_IFR_ORDERED_LIST",\r
   "EFI_IFR_VARSTORE",   "EFI_IFR_VARSTORE_NAME_VALUE",  "EFI_IFR_VARSTORE_EFI",  "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION",       "EFI_IFR_END",\r
-  "EFI_IFR_MATCH",      "EFI_IFR_INVALID",              "EFI_IFR_INVALID",       "EFI_IFR_INVALID",         "EFI_IFR_INVALID",       "EFI_IFR_EQUAL",\r
+  "EFI_IFR_MATCH",      "EFI_IFR_GET",                  "EFI_IFR_SET",           "EFI_IFR_READ",            "EFI_IFR_WRITE",         "EFI_IFR_EQUAL",\r
   "EFI_IFR_NOT_EQUAL",  "EFI_IFR_GREATER_THAN",         "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN",       "EFI_IFR_LESS_EQUAL",    "EFI_IFR_BITWISE_AND",\r
   "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT",          "EFI_IFR_SHIFT_LEFT",    "EFI_IFR_SHIFT_RIGHT",     "EFI_IFR_ADD",           "EFI_IFR_SUBTRACT",\r
   "EFI_IFR_MULTIPLY",   "EFI_IFR_DIVIDE",               "EFI_IFR_MODULO",        "EFI_IFR_RULE_REF",        "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
@@ -1322,7 +1695,8 @@ static struct {
   "EFI_IFR_TO_UINT",    "EFI_IFR_TO_STRING",            "EFI_IFR_TO_BOOLEAN",    "EFI_IFR_MID",             "EFI_IFR_FIND",          "EFI_IFR_TOKEN",\r
   "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2",          "EFI_IFR_CONDITIONAL",   "EFI_IFR_QUESTION_REF3",   "EFI_IFR_ZERO",          "EFI_IFR_ONE",\r
   "EFI_IFR_ONES",       "EFI_IFR_UNDEFINED",            "EFI_IFR_LENGTH",        "EFI_IFR_DUP",             "EFI_IFR_THIS",          "EFI_IFR_SPAN",\r
-  "EFI_IFR_VALUE",      "EFI_IFR_DEFAULT",              "EFI_IFR_DEFAULTSTORE",  "EFI_IFR_INVALID",         "EFI_IFR_CATENATE",      "EFI_IFR_GUID",\r
+  "EFI_IFR_VALUE",      "EFI_IFR_DEFAULT",              "EFI_IFR_DEFAULTSTORE",  "EFI_IFR_FORM_MAP",        "EFI_IFR_CATENATE",      "EFI_IFR_GUID",\r
+  "EFI_IFR_SECURITY",   "EFI_IFR_MODAL_TAG",            "EFI_IFR_REFRESH_ID",    "EFI_IFR_WARNING_IF",\r
 };\r
 \r
 VOID\r
@@ -1338,7 +1712,7 @@ CIFROBJ_DEBUG_PRINT (
 \r
 #endif\r
 \r
-bool gCreateOp = TRUE;\r
+BOOLEAN gCreateOp = TRUE;\r
 \r
 CIfrObj::CIfrObj (\r
   IN  UINT8   OpCode,\r
@@ -1394,4 +1768,4 @@ CIfrOpHeader::CIfrOpHeader (
   mHeader = OpHdr.mHeader;\r
 }\r
 \r
-UINT32 CIfrForm::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r
+UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r