BaseTools/VfrCompile: Add two new option for VfrCompile

1.--autodefault option
   VfrCompile will generate default opcodes for questions if some
   default are missing.
2 --checkdefault option
   VfrCompile will check whether every question has no default or
   has all default. If not, will generate an error to let user know
   the question misses default.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
diff --git a/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp b/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
index 695ce6c..59f4bf3 100644
--- a/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
@@ -83,6 +83,8 @@
   mOptions.CompatibleMode                = FALSE;

   mOptions.HasOverrideClassGuid          = FALSE;

   mOptions.WarningAsError                = FALSE;

+  mOptions.AutoDefault                   = FALSE;

+  mOptions.CheckDefault                  = FALSE;

   memset (&mOptions.OverrideClassGuid, 0, sizeof (EFI_GUID));

   

   if (Argc == 1) {

@@ -160,6 +162,10 @@
       mOptions.HasOverrideClassGuid = TRUE;

     } else if (stricmp(Argv[Index], "-w") == 0 || stricmp(Argv[Index], "--warning-as-error") == 0) {

       mOptions.WarningAsError = TRUE;

+    } else if (stricmp(Argv[Index], "-a") == 0 ||stricmp(Argv[Index], "--autodefault") == 0) {

+      mOptions.AutoDefault = TRUE;

+    } else if (stricmp(Argv[Index], "-d") == 0 ||stricmp(Argv[Index], "--checkdefault") == 0) {

+      mOptions.CheckDefault = TRUE;

     } else {

       DebugError (NULL, 0, 1000, "Unknown option", "unrecognized option %s", Argv[Index]);

       goto Fail;

@@ -437,6 +443,8 @@
     "                 format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",

     "  -w  --warning-as-error",

     "                 treat warning as an error",

+    "  -a  --autodefaut    generate default value for question opcode if some default is missing",

+    "  -d  --checkdefault  check the default information in a question opcode",

     NULL

     };

   for (Index = 0; Help[Index] != NULL; Index++) {

@@ -582,42 +590,6 @@
 }

 

 VOID

-CVfrCompiler::UpdateInfoForDynamicOpcode (

-  VOID

-  )

-{

-  SIfrRecord          *pRecord;

-

-  if (!gNeedAdjustOpcode) {

-    return;

-  }

-  

-  //

-  // Base on the original offset info to update the record list.

-  //

-  if (!gCIfrRecordInfoDB.IfrAdjustDynamicOpcodeInRecords()) {

-    DebugError (NULL, 0, 1001, "Error parsing vfr file", "Can find the offset in the record.");

-  }

-

-  //

-  // Base on the opcode binary length to recalculate the offset for each opcode.

-  //

-  gCIfrRecordInfoDB.IfrAdjustOffsetForRecord();

-

-  //

-  // Base on the offset to find the binary address.

-  //

-  pRecord = gCIfrRecordInfoDB.GetRecordInfoFromOffset(gAdjustOpcodeOffset);

-  while (pRecord != NULL) {

-    pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);

-    if (pRecord->mIfrBinBuf == NULL) {

-      DebugError (NULL, 0, 0001, "Error parsing vfr file", " 0x%X. offset not allocated.", pRecord->mOffset);

-    }

-    pRecord = pRecord->mNext;

-  }

-}

-

-VOID

 CVfrCompiler::AdjustBin (

   VOID

   )

@@ -628,7 +600,19 @@
     return;

   }

 

-  UpdateInfoForDynamicOpcode ();

+  if (gNeedAdjustOpcode) {

+    //

+    // When parsing the Vfr, has created some opcodes, now need to update the record info.

+    //

+    gCIfrRecordInfoDB.IfrUpdateRecordInfoForDynamicOpcode (FALSE);

+  }

+

+  //

+  // Check whether need to check default info for question or auto add default for question.

+  //

+  if (mOptions.AutoDefault || mOptions.CheckDefault) {

+    gCIfrRecordInfoDB.IfrCheckAddDefaultRecord (mOptions.AutoDefault, mOptions.CheckDefault);

+  }

 

   //

   // Check Binary Code consistent between Form and IfrRecord

diff --git a/BaseTools/Source/C/VfrCompile/VfrCompiler.h b/BaseTools/Source/C/VfrCompile/VfrCompiler.h
index f2d9814..7dd9dd0 100644
--- a/BaseTools/Source/C/VfrCompile/VfrCompiler.h
+++ b/BaseTools/Source/C/VfrCompile/VfrCompiler.h
@@ -57,6 +57,8 @@
   BOOLEAN HasOverrideClassGuid;

   EFI_GUID OverrideClassGuid;

   BOOLEAN WarningAsError;

+  BOOLEAN AutoDefault;

+  BOOLEAN CheckDefault;

 } OPTIONS;

 

 typedef enum {

@@ -88,7 +90,6 @@
 

   VOID    SET_RUN_STATUS (IN COMPILER_RUN_STATUS);

   BOOLEAN IS_RUN_STATUS (IN COMPILER_RUN_STATUS);

-  VOID    UpdateInfoForDynamicOpcode (VOID);

 

 public:

   COMPILER_RUN_STATUS RunStatus (VOID) {

diff --git a/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp b/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
index 892b7b8..db1e4bd 100644
--- a/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
@@ -652,11 +652,12 @@
 

 EFI_VFR_RETURN_CODE

 CFormPkg::AdjustDynamicInsertOpcode (

-  IN CHAR8              *LastFormEndAddr,

-  IN CHAR8              *InsertOpcodeAddr

+  IN CHAR8              *InserPositionAddr,

+  IN CHAR8              *InsertOpcodeAddr,

+  IN BOOLEAN            CreateOpcodeAfterParsingVfr

   )

 {

-  SBufferNode *LastFormEndNode;

+  SBufferNode *InserPositionNode;

   SBufferNode *InsertOpcodeNode;

   SBufferNode *NewRestoreNodeBegin;

   SBufferNode *NewRestoreNodeEnd;

@@ -666,53 +667,53 @@
 

   NewRestoreNodeEnd = NULL;

 

-  LastFormEndNode  = GetBinBufferNodeForAddr(LastFormEndAddr);

+  InserPositionNode  = GetBinBufferNodeForAddr(InserPositionAddr);

   InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);

 

-  if (LastFormEndNode == InsertOpcodeNode) {

+  if (InserPositionNode == InsertOpcodeNode) {

     //

     // Create New Node to save the restore opcode.

     //

-    NeedRestoreCodeLen = InsertOpcodeAddr - LastFormEndAddr;

+    NeedRestoreCodeLen = InsertOpcodeAddr - InserPositionAddr;

     gAdjustOpcodeLen   = NeedRestoreCodeLen;

     NewRestoreNodeBegin = CreateNewNode ();

     if (NewRestoreNodeBegin == NULL) {

       return VFR_RETURN_OUT_FOR_RESOURCES;

     }

-    memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen);

+    memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);

     NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;

 

     //

     // Override the restore buffer data.

     //

-    memmove (LastFormEndAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);

+    memmove (InserPositionAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);

     InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen;

     memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen);

   } else {

     //

     // Create New Node to save the restore opcode.

     //

-    NeedRestoreCodeLen = LastFormEndNode->mBufferFree - LastFormEndAddr;

+    NeedRestoreCodeLen = InserPositionNode->mBufferFree - InserPositionAddr;

     gAdjustOpcodeLen   = NeedRestoreCodeLen;

     NewRestoreNodeBegin = CreateNewNode ();

     if (NewRestoreNodeBegin == NULL) {

       return VFR_RETURN_OUT_FOR_RESOURCES;

     }

-    memcpy (NewRestoreNodeBegin->mBufferFree, LastFormEndAddr, NeedRestoreCodeLen);

+    memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);

     NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;

     //

     // Override the restore buffer data.

     //

-    LastFormEndNode->mBufferFree -= NeedRestoreCodeLen;

+    InserPositionNode->mBufferFree -= NeedRestoreCodeLen;

     //

     // Link the restore data to new node.

     //

-    NewRestoreNodeBegin->mNext = LastFormEndNode->mNext;

+    NewRestoreNodeBegin->mNext = InserPositionNode->mNext;

 

     //

     // Count the Adjust opcode len.

     //

-    TmpNode = LastFormEndNode->mNext;

+    TmpNode = InserPositionNode->mNext;

     while (TmpNode != InsertOpcodeNode) {

       gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart;

       TmpNode = TmpNode->mNext;

@@ -740,50 +741,64 @@
       // Insert the last restore data node.

       //

       TmpNode = GetNodeBefore (InsertOpcodeNode);

-      if (TmpNode == LastFormEndNode) {

+      if (TmpNode == InserPositionNode) {

         NewRestoreNodeBegin->mNext = NewRestoreNodeEnd;

       } else {

         TmpNode->mNext = NewRestoreNodeEnd;

       }

       //

-      // Connect the dynamic opcode node to the node before last form end node.

+      // Connect the dynamic opcode node to the node after InserPositionNode.

       //

-      LastFormEndNode->mNext = InsertOpcodeNode;

+      InserPositionNode->mNext = InsertOpcodeNode;

     }

   }

 

-  if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {

+  if (CreateOpcodeAfterParsingVfr) {

     //

-    // End form set opcode all in the mBufferNodeQueueTail node.

+    // Th new opcodes were created after Parsing Vfr file,

+    // so the content in mBufferNodeQueueTail must be the new created opcodes.

+    // So connet the  NewRestoreNodeBegin to the tail and update the tail node.

     //

-    NewLastEndNode = CreateNewNode ();

-    if (NewLastEndNode == NULL) {

-      return VFR_RETURN_OUT_FOR_RESOURCES;

-    }

-    NewLastEndNode->mBufferStart[0] = 0x29;

-    NewLastEndNode->mBufferStart[1] = 0x02;

-    NewLastEndNode->mBufferFree += 2;

-

-    mBufferNodeQueueTail->mBufferFree -= 2;

-

     mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;

     if (NewRestoreNodeEnd != NULL) {

-      NewRestoreNodeEnd->mNext = NewLastEndNode;

+      mBufferNodeQueueTail = NewRestoreNodeEnd;

     } else {

-      NewRestoreNodeBegin->mNext = NewLastEndNode;

+      mBufferNodeQueueTail = NewRestoreNodeBegin;

     }

+  } else {

+    if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {

+      //

+      // End form set opcode all in the mBufferNodeQueueTail node.

+      //

+      NewLastEndNode = CreateNewNode ();

+      if (NewLastEndNode == NULL) {

+        return VFR_RETURN_OUT_FOR_RESOURCES;

+      }

+      NewLastEndNode->mBufferStart[0] = 0x29;

+      NewLastEndNode->mBufferStart[1] = 0x02;

+      NewLastEndNode->mBufferFree += 2;

 

-    mBufferNodeQueueTail = NewLastEndNode;

-  } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {

-    TmpNode = GetNodeBefore(mBufferNodeQueueTail);

-    TmpNode->mNext = NewRestoreNodeBegin;

-    if (NewRestoreNodeEnd != NULL) {

-      NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;

-    } else {

-      NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;

+      mBufferNodeQueueTail->mBufferFree -= 2;

+

+      mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;

+      if (NewRestoreNodeEnd != NULL) {

+        NewRestoreNodeEnd->mNext = NewLastEndNode;

+      } else {

+        NewRestoreNodeBegin->mNext = NewLastEndNode;

+      }

+

+      mBufferNodeQueueTail = NewLastEndNode;

+    } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {

+      TmpNode = GetNodeBefore(mBufferNodeQueueTail);

+      TmpNode->mNext = NewRestoreNodeBegin;

+      if (NewRestoreNodeEnd != NULL) {

+        NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;

+      } else {

+        NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;

+      }

     }

   }

-

+  mCurrBufferNode = mBufferNodeQueueTail;

   return VFR_RETURN_SUCCESS;

 }

 

@@ -983,6 +998,10 @@
   mRecordCount       = EFI_IFR_RECORDINFO_IDX_START;

   mIfrRecordListHead = NULL;

   mIfrRecordListTail = NULL;

+  mAllDefaultTypeCount = 0;

+  for (UINT8 i = 0; i < EFI_HII_MAX_SUPPORT_DEFAULT_TYPE; i++) {

+    mAllDefaultIdArray[i] = 0xffff;

+  }

 }

 

 CIfrRecordInfoDB::~CIfrRecordInfoDB (

@@ -1233,63 +1252,131 @@
   return pNode;

 }

 

-/*

+/**

   Add just the op code position.

 

-  From

-  

-  | form end opcode + end of if opcode for form ... + Dynamic opcode + form set end opcode |

-  

-  To

-  

-  | Dynamic opcode + form end opcode + end of if opcode for form ... + form set end opcode |

+  Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,

+  so pDynamicOpcodeNodes is before mIfrRecordListTail.

 

-*/

+  From

+

+  |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|

+

+  To

+

+  |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|

+

+  Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,

+  so new records are appennded to the end of OriginalIfrRecordListTail.

+

+  From

+

+  |mIfrRecordListHead + ...+ pAdjustNode +  ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|

+

+  To

+

+  |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode +  ... + OriginalIfrRecordListTail|

+

+

+  @param CreateOpcodeAfterParsingVfr     Whether create the dynamic opcode after parsing the VFR file.

+

+**/

 BOOLEAN

 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (

-  VOID

+  IN BOOLEAN  CreateOpcodeAfterParsingVfr

   )

 {

   UINT32             OpcodeOffset;

   SIfrRecord         *pNode, *pPreNode;

-  SIfrRecord         *pStartNode, *pNodeBeforeStart;

-  SIfrRecord         *pEndNode;

-  

-  pStartNode = NULL;

-  pEndNode   = NULL;

-  OpcodeOffset = 0;

+  SIfrRecord         *pAdjustNode, *pNodeBeforeAdjust;

+  SIfrRecord         *pNodeBeforeDynamic;

+

+  pAdjustNode         = NULL;

+  pNodeBeforeDynamic  = NULL;

+  OpcodeOffset        = 0;

 

   //

-  // Base on the offset info to get the node.

+  // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,

+  // and the node before pDynamicOpcodeNode.

   //

-  for (pNode = mIfrRecordListHead; pNode->mNext != NULL; pPreNode = pNode,pNode = pNode->mNext) {

+  for (pNode = mIfrRecordListHead; pNode!= NULL; pNode = pNode->mNext) {

     if (OpcodeOffset == gAdjustOpcodeOffset) {

-      pStartNode       = pNode;

-      pNodeBeforeStart = pPreNode;

+      pAdjustNode       = pNode;

+      pNodeBeforeAdjust = pPreNode;

     } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {

-      pEndNode = pPreNode;

+      pNodeBeforeDynamic = pPreNode;

     }

-

+    if (pNode->mNext != NULL) {

+      pPreNode = pNode;

+    }

     OpcodeOffset += pNode->mBinBufLen;

   }

 

   //

-  // Check the value.

+  // Check the nodes whether exist.

   //

-  if (pEndNode == NULL || pStartNode == NULL) {

+  if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL) {

     return FALSE;

   }

 

   //

   // Adjust the node. pPreNode save the Node before mIfrRecordListTail

   //

-  pNodeBeforeStart->mNext = pEndNode->mNext;

-  pPreNode->mNext = pStartNode;

-  pEndNode->mNext = mIfrRecordListTail;

+  pNodeBeforeAdjust->mNext = pNodeBeforeDynamic->mNext;

+  if (CreateOpcodeAfterParsingVfr) {

+    //

+    // mIfrRecordListTail is the end of pDynamicNode (Case2).

+    //

+    mIfrRecordListTail->mNext = pAdjustNode;

+    mIfrRecordListTail = pNodeBeforeDynamic;

+    mIfrRecordListTail->mNext = NULL;

+  } else {

+    //

+    //pPreNode is the end of pDynamicNode(Case1).

+    //

+    pPreNode->mNext = pAdjustNode;

+    pNodeBeforeDynamic->mNext = mIfrRecordListTail;

+  }

 

   return TRUE;

 }

 

+/**

+  Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.

+

+  @param CreateOpcodeAfterParsingVfr     Whether create the dynamic opcode after parsing the VFR file.

+

+**/

+VOID

+CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (

+  IN BOOLEAN  CreateOpcodeAfterParsingVfr

+  )

+{

+  SIfrRecord          *pRecord;

+

+  //

+  // Base on the original offset info to update the record list.

+  //

+  if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr)) {

+    gCVfrErrorHandle.PrintMsg (0, "Error", "Can not find the adjust offset in the record.");

+  }

+

+  //

+  // Base on the opcode binary length to recalculate the offset for each opcode.

+  //

+  IfrAdjustOffsetForRecord();

+

+  //

+  // Base on the offset to find the binary address.

+  //

+  pRecord = GetRecordInfoFromOffset(gAdjustOpcodeOffset);

+  while (pRecord != NULL) {

+    pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);

+    pRecord = pRecord->mNext;

+  }

+}

+

+

 VOID

 CIfrRecordInfoDB::IfrAdjustOffsetForRecord (

   VOID

@@ -1522,6 +1609,579 @@
   return Status;

 }

 

+/**

+  When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not

+  given by expression, should save the default info for the Buffer VarStore.

+

+  @param  DefaultId           The default id.

+  @param  pQuestionNode       Point to the question opcode node.

+  @param  Value               The default value.

+**/

+VOID

+CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (

+  IN  UINT16                  DefaultId,

+  IN  SIfrRecord              *pQuestionNode,

+  IN  EFI_IFR_TYPE_VALUE      Value

+  )

+{

+  CHAR8                   *VarStoreName = NULL;

+  EFI_VFR_VARSTORE_TYPE    VarStoreType  = EFI_VFR_VARSTORE_INVALID;

+  EFI_GUID                 *VarGuid      = NULL;

+  EFI_VARSTORE_INFO        VarInfo;

+  EFI_IFR_QUESTION_HEADER  *QuestionHead;

+  EFI_IFR_OP_HEADER        *pQuestionOpHead;

+

+  pQuestionOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;

+  QuestionHead    = (EFI_IFR_QUESTION_HEADER *) (pQuestionOpHead + 1);

+

+  //

+  // Get the Var Store name and type.

+  //

+  gCVfrDataStorage.GetVarStoreName (QuestionHead->VarStoreId, &VarStoreName);

+  VarGuid= gCVfrDataStorage.GetVarStoreGuid (QuestionHead->VarStoreId);

+  VarStoreType = gCVfrDataStorage.GetVarStoreType (QuestionHead->VarStoreId);

+

+  //

+  // Only for Buffer storage need to save the default info in the storage.

+  // Other type storage, just return.

+  //

+  if (VarStoreType != EFI_VFR_VARSTORE_BUFFER) {

+    return;

+  } else {

+    VarInfo.mInfo.mVarOffset = QuestionHead->VarStoreInfo.VarOffset;

+    VarInfo.mVarStoreId = QuestionHead->VarStoreId;

+  }

+

+  //

+  // Get the buffer storage info about this question.

+  //

+  gCVfrDataStorage.GetBufferVarStoreFieldInfo (&VarInfo);

+

+  //

+  // Add action.

+  //

+  gCVfrDefaultStore.BufferVarStoreAltConfigAdd (

+    DefaultId,

+    VarInfo,

+    VarStoreName,

+    VarGuid,

+    VarInfo.mVarType,

+    Value

+    );

+}

+

+/**

+  Record the number and default id of all defaultstore opcode.

+

+**/

+VOID

+CIfrRecordInfoDB::IfrGetDefaultStoreInfo (

+  VOID

+  )

+{

+  SIfrRecord             *pNode;

+  EFI_IFR_OP_HEADER      *pOpHead;

+  EFI_IFR_DEFAULTSTORE   *DefaultStore;

+

+  pNode                = mIfrRecordListHead;

+  mAllDefaultTypeCount = 0;

+

+  while (pNode != NULL) {

+    pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;

+

+    if (pOpHead->OpCode == EFI_IFR_DEFAULTSTORE_OP){

+      DefaultStore = (EFI_IFR_DEFAULTSTORE *) pNode->mIfrBinBuf;

+      mAllDefaultIdArray[mAllDefaultTypeCount++] = DefaultStore->DefaultId;

+    }

+    pNode = pNode->mNext;

+  }

+}

+

+/**

+  Create new default opcode record.

+

+  @param    Size            The new default opcode size.

+  @param    DefaultId       The new default id.

+  @param    Type            The new default type.

+  @param    LineNo          The line number of the new record.

+  @param    Value           The new default value.

+

+**/

+VOID

+CIfrRecordInfoDB::IfrCreateDefaultRecord(

+  IN UINT8               Size,

+  IN UINT16              DefaultId,

+  IN UINT8               Type,

+  IN UINT32              LineNo,

+  IN EFI_IFR_TYPE_VALUE  Value

+  )

+{

+  CIfrDefault   *DObj;

+  CIfrDefault2  *DObj2;

+

+  DObj  = NULL;

+  DObj2 = NULL;

+

+  if (Type == EFI_IFR_TYPE_OTHER) {

+    DObj2 = new CIfrDefault2 (Size);

+    DObj2->SetDefaultId(DefaultId);

+    DObj2->SetType(Type);

+    DObj2->SetLineNo(LineNo);

+    DObj2->SetScope (1);

+    delete DObj2;

+  } else {

+    DObj = new CIfrDefault (Size);

+    DObj->SetDefaultId(DefaultId);

+    DObj->SetType(Type);

+    DObj->SetLineNo(LineNo);

+    DObj->SetValue (Value);

+    delete DObj;

+  }

+}

+

+/**

+  Create new default opcode for question base on the QuestionDefaultInfo.

+

+  @param  pQuestionNode              Point to the question opcode Node.

+  @param  QuestionDefaultInfo        Point to the QuestionDefaultInfo for current question.

+

+**/

+VOID

+CIfrRecordInfoDB::IfrCreateDefaultForQuestion (

+  IN  SIfrRecord              *pQuestionNode,

+  IN  QuestionDefaultRecord   *QuestionDefaultInfo

+  )

+{

+  EFI_IFR_OP_HEADER      *pOpHead;

+  EFI_IFR_DEFAULT        *Default;

+  SIfrRecord             *pSNode;

+  SIfrRecord             *pENode;

+  SIfrRecord             *pDefaultNode;

+  CIfrObj                *Obj;

+  CHAR8                  *ObjBinBuf;

+  UINT8                  ScopeCount;

+  UINT8                  OpcodeNumber;

+  UINT8                  OpcodeCount;

+  UINT8                  DefaultSize;

+  EFI_IFR_ONE_OF_OPTION  *DefaultOptionOpcode;

+  EFI_IFR_TYPE_VALUE     CheckBoxDefaultValue;

+

+  CheckBoxDefaultValue.b = 1;

+  pOpHead                = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;

+  ScopeCount             = 0;

+  OpcodeCount            = 0;

+  Obj                    = NULL;

+

+  //

+  // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.

+  //

+  gAdjustOpcodeOffset = pQuestionNode->mNext->mOffset;

+  //

+  // Case 1:

+  // For oneof, the default with smallest default id is given by the option flag.

+  // So create the missing defaults base on the oneof option value(mDefaultValueRecord).

+  //

+  if (pOpHead->OpCode == EFI_IFR_ONE_OF_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {

+    DefaultOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)QuestionDefaultInfo->mDefaultValueRecord->mIfrBinBuf;

+    DefaultSize = QuestionDefaultInfo->mDefaultValueRecord->mBinBufLen - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);

+    DefaultSize += OFFSET_OF (EFI_IFR_DEFAULT, Value);

+    for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {

+      if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {

+        IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], DefaultOptionOpcode->Type, pQuestionNode->mLineNo, DefaultOptionOpcode->Value);

+        //

+        // Save the new created default in the buffer storage.

+        //

+        IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, DefaultOptionOpcode->Value);

+      }

+    }

+    return;

+  }

+

+  //

+  // Case2:

+  // For checkbox, the default with smallest default id is given by the question flag.

+  // And create the missing defaults with true value.

+  //

+  if (pOpHead-> OpCode == EFI_IFR_CHECKBOX_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {

+    DefaultSize = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (BOOLEAN);

+    for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {

+      if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {

+        IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], EFI_IFR_TYPE_BOOLEAN, pQuestionNode->mLineNo, CheckBoxDefaultValue);

+        //

+        // Save the new created default.

+        //

+        IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, CheckBoxDefaultValue);

+      }

+    }

+    return;

+  }

+

+  //

+  // Case3:

+  // The default with smallest default id is given by the default opcode.

+  // So create the missing defaults base on the value in the default opcode.

+  //

+

+  //

+  // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.

+  //

+  pDefaultNode = QuestionDefaultInfo->mDefaultValueRecord;

+  Default = (EFI_IFR_DEFAULT *)pDefaultNode->mIfrBinBuf;

+  //

+  // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.

+  //

+  gAdjustOpcodeOffset = pDefaultNode->mNext->mOffset;

+

+  if (Default->Type == EFI_IFR_TYPE_OTHER) {

+    //

+    // EFI_IFR_DEFAULT_2 opcode.

+    //

+    // Point to the first expression opcode.

+    //

+    pSNode = pDefaultNode->mNext;

+    ScopeCount++;

+    //

+    // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)

+    //

+    while (pSNode != NULL && pSNode->mNext != NULL && ScopeCount != 0) {

+      pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;

+      if (pOpHead->Scope == 1) {

+        ScopeCount++;

+      }

+      if (pOpHead->OpCode == EFI_IFR_END_OP) {

+        ScopeCount--;

+      }

+      pENode = pSNode;

+      pSNode = pSNode->mNext;

+      OpcodeCount++;

+    }

+    //

+    // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.

+    //

+    gAdjustOpcodeOffset = pSNode->mOffset;

+    //

+    // Create new default opcode node for missing default.

+    //

+    for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {

+      OpcodeNumber = OpcodeCount;

+      if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {

+        IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pENode->mLineNo, Default->Value);

+        //

+        // Point to the first expression opcode node.

+        //

+        pSNode = pDefaultNode->mNext;

+        //

+        // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.

+        //

+        while (pSNode != NULL && pSNode->mNext != NULL && OpcodeNumber-- != 0) {

+          pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;

+          Obj = new CIfrObj (pOpHead->OpCode, NULL, pSNode->mBinBufLen, FALSE);

+          Obj->SetLineNo (pSNode->mLineNo);

+          ObjBinBuf = Obj->GetObjBinAddr();

+          memcpy (ObjBinBuf, pSNode->mIfrBinBuf, (UINTN)pSNode->mBinBufLen);

+          delete Obj;

+          pSNode = pSNode->mNext;

+        }

+      }

+    }

+  } else {

+    //

+    // EFI_IFR_DEFAULT opcode.

+    //

+    // Create new default opcode node for missing default.

+    //

+    for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {

+      if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {

+        IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pDefaultNode->mLineNo, Default->Value);

+        //

+        // Save the new created default in the buffer storage..

+        //

+        IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, Default->Value);

+      }

+    }

+  }

+}

+

+/**

+  Parse the default information in a question, get the QuestionDefaultInfo.

+

+  @param  pQuestionNode          Point to the question record Node.

+  @param  QuestionDefaultInfo    On return, point to the QuestionDefaultInfo.

+**/

+VOID

+CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(

+  IN  SIfrRecord              *pQuestionNode,

+  OUT QuestionDefaultRecord   *QuestionDefaultInfo

+  )

+{

+  SIfrRecord              *pSNode;

+  EFI_IFR_ONE_OF_OPTION   *OneofOptionOpcode;

+  EFI_IFR_OP_HEADER       *pSOpHead;

+  EFI_IFR_CHECKBOX        *CheckBoxOpcode;

+  EFI_IFR_DEFAULT         *DefaultOpcode;

+  BOOLEAN                 IsOneOfOpcode;

+  UINT16                  SmallestDefaultId;

+  UINT8                   ScopeCount;

+

+  SmallestDefaultId  = 0xffff;

+  IsOneOfOpcode      = FALSE;

+  ScopeCount         = 0;

+  pSNode             = pQuestionNode;

+

+  //

+  // Parse all the opcodes in the Question.

+  //

+  while (pSNode != NULL) {

+    pSOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;

+    //

+    // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.

+    // Scopes may be nested within other scopes.

+    // When finishing parsing a question, the scope count must be zero.

+    //

+    if (pSOpHead->Scope == 1) {

+      ScopeCount++;

+    }

+    if (pSOpHead->OpCode == EFI_IFR_END_OP) {

+      ScopeCount--;

+    }

+    //

+    // Check whether finishing parsing a question.

+    //

+    if (ScopeCount == 0) {

+      break;

+    }

+

+    //

+    // Record the default information in the question.

+    //

+    switch (pSOpHead->OpCode) {

+    case EFI_IFR_ONE_OF_OP:

+      IsOneOfOpcode = TRUE;

+      break;

+    case EFI_IFR_CHECKBOX_OP:

+      //

+      // The default info of check box may be given by flag.

+      // So need to check the flag of check box.

+      //

+      CheckBoxOpcode = (EFI_IFR_CHECKBOX *)pSNode->mIfrBinBuf;

+      if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0) {

+        //

+        // Check whether need to update the smallest default id.

+        //

+        if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {

+          SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;

+        }

+        //

+        // Update the QuestionDefaultInfo.

+        //

+        for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {

+          if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {

+            if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {

+              QuestionDefaultInfo->mDefaultNumber ++;

+              QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;

+            }

+            break;

+          }

+        }

+      }

+      if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0) {

+        //

+        // Check whether need to update the smallest default id.

+        //

+        if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {

+          SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;

+        }

+        //

+        // Update the QuestionDefaultInfo.

+        //

+        for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {

+          if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {

+            if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {

+              QuestionDefaultInfo->mDefaultNumber ++;

+              QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;

+            }

+            break;

+          }

+        }

+      }

+      break;

+    case EFI_IFR_ONE_OF_OPTION_OP:

+      if (!IsOneOfOpcode) {

+        //

+        // Only check the option in oneof.

+        //

+        break;

+      }

+      OneofOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)pSNode->mIfrBinBuf;

+      if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {

+        //

+        // The option is used as the standard default.

+        // Check whether need to update the smallest default id and QuestionDefaultInfo.

+        //

+        if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {

+          SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;

+          QuestionDefaultInfo->mDefaultValueRecord = pSNode;

+        }

+        //

+        // Update the IsDefaultIdExist array in QuestionDefaultInfo.

+        //

+        for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {

+          if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {

+            if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {

+              QuestionDefaultInfo->mDefaultNumber ++;

+              QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;

+            }

+            break;

+          }

+        }

+      }

+      if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0) {

+        //

+        // This option is used as the manufacture default.

+        // Check whether need to update the smallest default id and QuestionDefaultInfo.

+        //

+        if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {

+          SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;

+          QuestionDefaultInfo->mDefaultValueRecord = pSNode;

+        }

+        //

+        // Update the QuestionDefaultInfo.

+        //

+        for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {

+          if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {

+            if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {

+              QuestionDefaultInfo->mDefaultNumber ++;

+              QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;

+            }

+            break;

+          }

+        }

+      }

+      break;

+    case EFI_IFR_DEFAULT_OP:

+      DefaultOpcode = (EFI_IFR_DEFAULT *) pSNode->mIfrBinBuf;

+      //

+      // Check whether need to update the smallest default id and QuestionDefaultInfo.

+      //

+      if (SmallestDefaultId >= DefaultOpcode->DefaultId ) {

+        SmallestDefaultId = DefaultOpcode->DefaultId;

+        QuestionDefaultInfo->mDefaultValueRecord= pSNode;

+        QuestionDefaultInfo->mIsDefaultOpcode= TRUE;

+      }

+      //

+      // Update the QuestionDefaultInfo.

+      //

+      for (UINT8 i = 0; i < mAllDefaultTypeCount; i++){

+        if (mAllDefaultIdArray[i] == ((EFI_IFR_DEFAULT *)pSNode->mIfrBinBuf)->DefaultId) {

+          if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {

+            QuestionDefaultInfo->mDefaultNumber ++;

+            QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;

+          }

+          break;

+        }

+      }

+      break;

+    default:

+      break;

+    }

+    //

+    // Parse next opcode in this question.

+    //

+    pSNode = pSNode->mNext;

+  }

+}

+

+/**

+  Check or add default for question if need.

+

+  This function will check the default info for question.

+  If the question has default, but the default number < defaultstore opcode number.

+  will do following two action :

+

+  1. if (AutoDefault) will add default for question to support all kinds of defaults.

+  2. if (CheckDefault) will generate an error to tell user the question misses some default value.

+

+  We assume that the two options can not be TRUE at same time.

+  If they are TRUE at same time, only do the action corresponding to AutoDefault option.

+

+  @param  AutoDefault          Add default for question if needed

+  @param  CheckDefault         Check the default info, if missing default, generates an error.

+

+**/

+VOID

+CIfrRecordInfoDB::IfrCheckAddDefaultRecord (

+  BOOLEAN  AutoDefault,

+  BOOLEAN  CheckDefault

+  )

+{

+  SIfrRecord            *pNode;

+  SIfrRecord            *pTailNode;

+  SIfrRecord            *pStartAdjustNode;

+  EFI_IFR_OP_HEADER     *pOpHead;

+  QuestionDefaultRecord  QuestionDefaultInfo;

+  UINT8                  MissingDefaultCount;

+  CHAR8                  Msg[MAX_STRING_LEN] = {0, };

+

+  pNode               = mIfrRecordListHead;

+

+  //

+  // Record the number and default id of all defaultstore opcode.

+  //

+  IfrGetDefaultStoreInfo ();

+

+  while (pNode != NULL) {

+    pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;

+    //

+    // Check whether is question opcode.

+    //

+    if (CheckQuestionOpCode (pOpHead->OpCode)) {

+      //

+      // Initialize some local variables here, because they vary with question.

+      // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.

+      //

+      memset (&QuestionDefaultInfo, 0, sizeof (QuestionDefaultRecord));

+      pTailNode = mIfrRecordListTail;

+      //

+      // Get the QuestionDefaultInfo for current question.

+      //

+      IfrParseDefaulInfoInQuestion (pNode, &QuestionDefaultInfo);

+

+      if (QuestionDefaultInfo.mDefaultNumber != mAllDefaultTypeCount && QuestionDefaultInfo.mDefaultNumber != 0) {

+        if (AutoDefault) {

+          //

+          // Create default for question which misses default.

+          //

+          IfrCreateDefaultForQuestion (pNode, &QuestionDefaultInfo);

+

+          //

+          // Adjust the buffer content.

+          // pStartAdjustNode->mIfrBinBuf points to the insert position.

+          // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.

+          //

+          pStartAdjustNode =GetRecordInfoFromOffset (gAdjustOpcodeOffset);

+          gCFormPkg.AdjustDynamicInsertOpcode (pStartAdjustNode->mIfrBinBuf, pTailNode->mNext->mIfrBinBuf, TRUE);

+

+          //

+          // Update the record info.

+          //

+          IfrUpdateRecordInfoForDynamicOpcode (TRUE);

+        } else if (CheckDefault) {

+          //

+          // Generate an error for question which misses default.

+          //

+          MissingDefaultCount = mAllDefaultTypeCount - QuestionDefaultInfo.mDefaultNumber;

+          sprintf (Msg, "The question misses %d default, the question's opcode is %d", MissingDefaultCount, pOpHead->OpCode);

+          gCVfrErrorHandle.PrintMsg (pNode->mLineNo, NULL, "Error", Msg);

+        }

+      }

+    }

+    //

+    // parse next opcode.

+    //

+    pNode = pNode->mNext;

+  }

+}

+

 CIfrRecordInfoDB gCIfrRecordInfoDB;

 

 VOID

diff --git a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
index 644dfdd..051df28 100644
--- a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
+++ b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
@@ -2,7 +2,7 @@
   

   The definition of CFormPkg's member function

 

-Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>

+Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>

 This program and the accompanying materials                          

 are licensed and made available under the terms and conditions of the BSD License         

 which accompanies this distribution.  The full text of the license may be found at        

@@ -154,7 +154,8 @@
     );

   EFI_VFR_RETURN_CODE AdjustDynamicInsertOpcode (

     IN CHAR8              *LastFormEndAddr,

-    IN CHAR8              *InsertOpcodeAddr

+    IN CHAR8              *InsertOpcodeAddr,

+    IN BOOLEAN            CreateOpcodeAfterParsingVfr

     );

   CHAR8 *             GetBufAddrBaseOnOffset (

     IN UINT32             Offset

@@ -177,8 +178,23 @@
   ~SIfrRecord (VOID);

 };

 

+

 #define EFI_IFR_RECORDINFO_IDX_INVALUD 0xFFFFFF

 #define EFI_IFR_RECORDINFO_IDX_START   0x0

+#define EFI_HII_MAX_SUPPORT_DEFAULT_TYPE  0x08

+

+struct QuestionDefaultRecord {

+  BOOLEAN     mIsDefaultIdExist[EFI_HII_MAX_SUPPORT_DEFAULT_TYPE]; // Record the default id in mAllDefaultIdArray[EFI_HII_MAX_SUPPORT_DEFAULT_TYPE]

+                                                                   // whether exists in current question.

+

+  SIfrRecord  *mDefaultValueRecord;   // Point to the default value record in RecordList which has smallest default Id.

+                                      // (for checkbox it may be NULL, because the dedault value is always true when the flag is set.)

+

+  BOOLEAN     mIsDefaultOpcode;       // whether the default value with smallest default id is given by default opcode.

+                                      // (for oneof and checkbox default info may be given by flag.)

+

+  UINT16      mDefaultNumber;         // The default number of this question.

+};

 

 class CIfrRecordInfoDB {

 private:

@@ -186,6 +202,8 @@
   UINT32     mRecordCount;

   SIfrRecord *mIfrRecordListHead;

   SIfrRecord *mIfrRecordListTail;

+  UINT8      mAllDefaultTypeCount;

+  UINT16     mAllDefaultIdArray[EFI_HII_MAX_SUPPORT_DEFAULT_TYPE];

 

   SIfrRecord * GetRecordInfoFromIdx (IN UINT32);

   BOOLEAN          CheckQuestionOpCode (IN UINT8);

@@ -205,13 +223,20 @@
 

   SIfrRecord * GetRecordInfoFromOffset (IN UINT32);

   VOID        IfrAdjustOffsetForRecord (VOID);

-  BOOLEAN     IfrAdjustDynamicOpcodeInRecords (VOID);

+  BOOLEAN     IfrAdjustDynamicOpcodeInRecords (IN BOOLEAN);

 

   UINT32      IfrRecordRegister (IN UINT32, IN CHAR8 *, IN UINT8, IN UINT32);

   VOID        IfrRecordInfoUpdate (IN UINT32, IN UINT32, IN CHAR8*, IN UINT8, IN UINT32);

   VOID        IfrRecordOutput (IN FILE *, IN UINT32 LineNo);

   VOID        IfrRecordOutput (OUT PACKAGE_DATA &);

-  EFI_VFR_RETURN_CODE  IfrRecordAdjust (VOID);   

+  EFI_VFR_RETURN_CODE  IfrRecordAdjust (VOID);

+  VOID        IfrUpdateRecordInfoForDynamicOpcode (IN BOOLEAN);

+  VOID        IfrCheckAddDefaultRecord (IN BOOLEAN, IN BOOLEAN);

+  VOID        IfrGetDefaultStoreInfo ();

+  VOID        IfrCreateDefaultRecord (IN UINT8 Size,IN UINT16 DefaultId,IN UINT8 Type,IN UINT32 LineNo,IN EFI_IFR_TYPE_VALUE Value);

+  VOID        IfrCreateDefaultForQuestion (IN  SIfrRecord *, IN  QuestionDefaultRecord *);

+  VOID        IfrParseDefaulInfoInQuestion (IN  SIfrRecord *, OUT QuestionDefaultRecord *);

+  VOID        IfrAddDefaultToBufferConfig (IN  UINT16, IN  SIfrRecord *,IN  EFI_IFR_TYPE_VALUE);

 };

 

 extern CIfrRecordInfoDB gCIfrRecordInfoDB;

diff --git a/BaseTools/Source/C/VfrCompile/VfrSyntax.g b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
index 55a9a23..4b42d3c 100644
--- a/BaseTools/Source/C/VfrCompile/VfrSyntax.g
+++ b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
@@ -596,7 +596,7 @@
                                                       if (gCFormPkg.HavePendingUnassigned()) {

                                                         mParserStatus += gCFormPkg.DeclarePendingQuestion (

                                                                     gCVfrVarDataTypeDB,

-                                                                    mCVfrDataStorage,

+                                                                    gCVfrDataStorage,

                                                                     mCVfrQuestionDB,

                                                                     &mFormsetGuid,

                                                                     E->getLine(),

@@ -614,7 +614,8 @@
                                                       if (gNeedAdjustOpcode) {

                                                         gCFormPkg.AdjustDynamicInsertOpcode (

                                                           mLastFormEndAddr,

-                                                          InsertOpcodeAddr

+                                                          InsertOpcodeAddr,

+                                                          FALSE

                                                         );

                                                       }

 

@@ -834,14 +835,14 @@
     "," Attribute "=" A:Number                      << DefaultId = _STOU16(A->getText(), A->getLine()); >>

   }

                                                     <<

-                                                       if (mCVfrDefaultStore.DefaultIdRegistered (DefaultId) == FALSE) {

+                                                       if (gCVfrDefaultStore.DefaultIdRegistered (DefaultId) == FALSE) {

                                                          CIfrDefaultStore DSObj;

-                                                         _PCATCH(mCVfrDefaultStore.RegisterDefaultStore (DSObj.GetObjBinAddr(), N->getText(), _STOSID(S->getText(), S->getLine()), DefaultId)), D->getLine();

+                                                         _PCATCH(gCVfrDefaultStore.RegisterDefaultStore (DSObj.GetObjBinAddr(), N->getText(), _STOSID(S->getText(), S->getLine()), DefaultId)), D->getLine();

                                                          DSObj.SetLineNo(D->getLine());

                                                          DSObj.SetDefaultName (_STOSID(S->getText(), S->getLine()));

                                                          DSObj.SetDefaultId (DefaultId);

                                                        } else {

-                                                         _PCATCH(mCVfrDefaultStore.ReRegisterDefaultStoreById (DefaultId, N->getText(), _STOSID(S->getText(), S->getLine()))), D->getLine();

+                                                         _PCATCH(gCVfrDefaultStore.ReRegisterDefaultStoreById (DefaultId, N->getText(), _STOSID(S->getText(), S->getLine()))), D->getLine();

                                                        }

                                                     >>

   ";"

@@ -893,7 +894,7 @@
                                                        } else {

                                                          StoreName = SN->getText();

                                                        }

-                                                       _PCATCH(mCVfrDataStorage.DeclareBufferVarStore (

+                                                       _PCATCH(gCVfrDataStorage.DeclareBufferVarStore (

                                                                                   StoreName,

                                                                                   &Guid,

                                                                                   &gCVfrVarDataTypeDB,

@@ -901,7 +902,7 @@
                                                                                   VarStoreId

                                                                                   ), LineNum);

                                                        VSObj.SetGuid (&Guid);

-                                                       _PCATCH(mCVfrDataStorage.GetVarStoreId(StoreName, &VarStoreId, &Guid), SN);

+                                                       _PCATCH(gCVfrDataStorage.GetVarStoreId(StoreName, &VarStoreId, &Guid), SN);

                                                        VSObj.SetVarStoreId (VarStoreId);

                                                        _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), LineNum);

                                                        VSObj.SetSize ((UINT16) Size);

@@ -985,24 +986,24 @@
 

   Uuid "=" guidDefinition[Guid]                     << 

                                                        if (IsUEFI23EfiVarstore) {

-                                                       _PCATCH(mCVfrDataStorage.DeclareBufferVarStore (

+                                                       _PCATCH(gCVfrDataStorage.DeclareBufferVarStore (

                                                                                   StoreName,

                                                                                   &Guid,

                                                                                   &gCVfrVarDataTypeDB,

                                                                                   TypeName,

                                                                                   VarStoreId

                                                                                   ), LineNum);                                                        

-                                                         _PCATCH(mCVfrDataStorage.GetVarStoreId(StoreName, &VarStoreId, &Guid), SN);

+                                                         _PCATCH(gCVfrDataStorage.GetVarStoreId(StoreName, &VarStoreId, &Guid), SN);

                                                          _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), LineNum);

                                                        } else {

-                                                        _PCATCH(mCVfrDataStorage.DeclareBufferVarStore (

+                                                        _PCATCH(gCVfrDataStorage.DeclareBufferVarStore (

                                                                                   TN->getText(),

                                                                                   &Guid,

                                                                                   &gCVfrVarDataTypeDB,

                                                                                   TypeName,

                                                                                   VarStoreId

                                                                                   ), LineNum);                                                      

-                                                         _PCATCH(mCVfrDataStorage.GetVarStoreId(TN->getText(), &VarStoreId, &Guid), VN);

+                                                         _PCATCH(gCVfrDataStorage.GetVarStoreId(TN->getText(), &VarStoreId, &Guid), VN);

                                                          _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), N->getLine());

                                                        }

                                                        VSEObj.SetGuid (&Guid);                                                       

@@ -1043,16 +1044,16 @@
   (

     Name "=" "STRING_TOKEN" "\(" N:Number "\)" ","  << 

                                                        if (!Created) {

-                                                         _PCATCH(mCVfrDataStorage.DeclareNameVarStoreBegin (SN->getText(), VarStoreId), SN);

+                                                         _PCATCH(gCVfrDataStorage.DeclareNameVarStoreBegin (SN->getText(), VarStoreId), SN);

                                                          Created = TRUE;

                                                        }

-                                                       _PCATCH(mCVfrDataStorage.NameTableAddItem (_STOSID(N->getText(), N->getLine())), SN); 

+                                                       _PCATCH(gCVfrDataStorage.NameTableAddItem (_STOSID(N->getText(), N->getLine())), SN);

                                                     >>

   )+

-  Uuid "=" guidDefinition[Guid]                     << _PCATCH(mCVfrDataStorage.DeclareNameVarStoreEnd (&Guid), SN); >>

+  Uuid "=" guidDefinition[Guid]                     << _PCATCH(gCVfrDataStorage.DeclareNameVarStoreEnd (&Guid), SN); >>

                                                     <<

                                                        VSNVObj.SetGuid (&Guid);

-                                                       _PCATCH(mCVfrDataStorage.GetVarStoreId(SN->getText(), &VarStoreId, &Guid), SN);

+                                                       _PCATCH(gCVfrDataStorage.GetVarStoreId(SN->getText(), &VarStoreId, &Guid), SN);

                                                        VSNVObj.SetVarStoreId (VarStoreId);

                                                     >>

   ";"

@@ -1244,9 +1245,9 @@
                                                        _STRCAT(&VarIdStr, "]");

                                                     >>

                                                     <<

-                                                       VfrReturnCode = mCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId);

+                                                       VfrReturnCode = gCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId);

                                                        if (mCompatibleMode && VfrReturnCode == VFR_RETURN_UNDEFINED) {

-                                                          mCVfrDataStorage.DeclareBufferVarStore (

+                                                          gCVfrDataStorage.DeclareBufferVarStore (

                                                                              SName,

                                                                              &mFormsetGuid,

                                                                              &gCVfrVarDataTypeDB,

@@ -1254,11 +1255,11 @@
                                                                              EFI_VARSTORE_ID_INVALID,

                                                                              FALSE

                                                                              );

-                                                          VfrReturnCode = mCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId, &mFormsetGuid);

+                                                          VfrReturnCode = gCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId, &mFormsetGuid);

                                                        }

                                                        if (CheckFlag || VfrReturnCode == VFR_RETURN_SUCCESS) {

                                                          _PCATCH(VfrReturnCode, SN1);

-                                                         _PCATCH(mCVfrDataStorage.GetNameVarStoreInfo (&$Info, Idx), SN1);

+                                                         _PCATCH(gCVfrDataStorage.GetNameVarStoreInfo (&$Info, Idx), SN1);

                                                        }

 

                                                        QuestVarIdStr = VarIdStr;

@@ -1268,9 +1269,9 @@
   (

     SN2:StringIdentifier                            << SName = SN2->getText(); _STRCAT(&VarIdStr, SName); >>

                                                     <<

-                                                       VfrReturnCode = mCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId);

+                                                       VfrReturnCode = gCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId);

                                                        if (mCompatibleMode && VfrReturnCode == VFR_RETURN_UNDEFINED) {

-                                                          mCVfrDataStorage.DeclareBufferVarStore (

+                                                          gCVfrDataStorage.DeclareBufferVarStore (

                                                                              SName,

                                                                              &mFormsetGuid,

                                                                              &gCVfrVarDataTypeDB,

@@ -1278,13 +1279,13 @@
                                                                              EFI_VARSTORE_ID_INVALID,

                                                                              FALSE

                                                                              );

-                                                          VfrReturnCode = mCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId, &mFormsetGuid);

+                                                          VfrReturnCode = gCVfrDataStorage.GetVarStoreId(SName, &$Info.mVarStoreId, &mFormsetGuid);

                                                        }

                                                        if (CheckFlag || VfrReturnCode == VFR_RETURN_SUCCESS) {

                                                          _PCATCH(VfrReturnCode, SN2);

-                                                         VarStoreType = mCVfrDataStorage.GetVarStoreType ($Info.mVarStoreId);

+                                                         VarStoreType = gCVfrDataStorage.GetVarStoreType ($Info.mVarStoreId);

                                                          if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {

-                                                           _PCATCH(mCVfrDataStorage.GetBufferVarStoreDataTypeName(Info.mVarStoreId, &TName), SN2);

+                                                           _PCATCH(gCVfrDataStorage.GetBufferVarStoreDataTypeName(Info.mVarStoreId, &TName), SN2);

                                                            _STRCAT(&VarStr, TName);

                                                          }

                                                        }

@@ -1319,11 +1320,11 @@
     )*                                              <<

                                                        switch (VarStoreType) {

                                                        case EFI_VFR_VARSTORE_EFI:

-                                                         _PCATCH(mCVfrDataStorage.GetEfiVarStoreInfo (&$Info), SN2);

+                                                         _PCATCH(gCVfrDataStorage.GetEfiVarStoreInfo (&$Info), SN2);

                                                          break;

                                                        case EFI_VFR_VARSTORE_BUFFER:

                                                          _PCATCH(gCVfrVarDataTypeDB.GetDataFieldInfo (VarStr, $Info.mInfo.mVarOffset, $Info.mVarType, $Info.mVarTotalSize), SN2->getLine(), VarStr);

-                                                         VarGuid = mCVfrDataStorage.GetVarStoreGuid($Info.mVarStoreId);

+                                                         VarGuid = gCVfrDataStorage.GetVarStoreGuid($Info.mVarStoreId);

                                                          _PCATCH((EFI_VFR_RETURN_CODE)gCVfrBufferConfig.Register (

                                                                     SName,

                                                                     VarGuid,

@@ -1339,6 +1340,7 @@
                                                                     $Info.mVarTotalSize,

                                                                     Dummy),

                                                                  SN2->getLine());

+                                                         _PCATCH(gCVfrDataStorage.AddBufferVarStoreFieldInfo(&$Info ),SN2->getLine());

                                                          break;

                                                        case EFI_VFR_VARSTORE_NAME:

                                                        default: break;

@@ -1761,7 +1763,7 @@
     )

     {

       DefaultStore "=" SN:StringIdentifier ","      << 

-                                                        _PCATCH(mCVfrDefaultStore.GetDefaultId (SN->getText(), &DefaultId), SN); 

+                                                        _PCATCH(gCVfrDefaultStore.GetDefaultId (SN->getText(), &DefaultId), SN);

                                                         if (DObj != NULL) {

                                                           DObj->SetDefaultId (DefaultId); 

                                                         } 

@@ -1774,11 +1776,11 @@
                                                     <<

                                                       CheckDuplicateDefaultValue (DefaultId, D);

                                                       if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {

-                                                       _PCATCH(mCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), D->getLine());

-                                                       VarGuid = mCVfrDataStorage.GetVarStoreGuid(_GET_CURRQEST_VARTINFO().mVarStoreId);

-                                                       VarStoreType = mCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);

+                                                       _PCATCH(gCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), D->getLine());

+                                                       VarGuid = gCVfrDataStorage.GetVarStoreGuid(_GET_CURRQEST_VARTINFO().mVarStoreId);

+                                                       VarStoreType = gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);

                                                        if ((IsExp == FALSE) && (VarStoreType == EFI_VFR_VARSTORE_BUFFER)) {

-                                                         _PCATCH(mCVfrDefaultStore.BufferVarStoreAltConfigAdd (

+                                                         _PCATCH(gCVfrDefaultStore.BufferVarStoreAltConfigAdd (

                                                                    DefaultId,

                                                                    _GET_CURRQEST_VARTINFO(),

                                                                    VarStoreName,

@@ -2131,7 +2133,7 @@
   L:ResetButton                                        << RBObj.SetLineNo(L->getLine()); >>

   DefaultStore

   "=" N:StringIdentifier ","                           <<

-                                                          _PCATCH(mCVfrDefaultStore.GetDefaultId (N->getText(), &DefaultId), N->getLine());

+                                                          _PCATCH(gCVfrDefaultStore.GetDefaultId (N->getText(), &DefaultId), N->getLine());

                                                           RBObj.SetDefaultId (DefaultId);

                                                        >>

   vfrStatementHeader[&RBObj] ","

@@ -2174,7 +2176,7 @@
                                                             _PCATCH (gCVfrVarDataTypeDB.GetDataTypeSize (_GET_CURRQEST_DATATYPE(), &DataTypeSize), L->getLine(), "CheckBox varid is not the valid data type");

                                                             if (DataTypeSize != 0 && DataTypeSize != _GET_CURRQEST_VARSIZE()) {

                                                               _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "CheckBox varid doesn't support array");

-                                                            } else if ((mCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId) == EFI_VFR_VARSTORE_BUFFER) &&

+                                                            } else if ((gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId) == EFI_VFR_VARSTORE_BUFFER) &&

                                                                       (_GET_CURRQEST_VARSIZE() != sizeof (BOOLEAN))) {

                                                               _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "CheckBox varid only support BOOLEAN data type");

                                                             }

@@ -2184,13 +2186,13 @@
     F:FLAGS "=" vfrCheckBoxFlags[CBObj, F->getLine()] ","

                                                        <<

                                                          if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {

-                                                            _PCATCH(mCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), VFR_RETURN_SUCCESS, L, "Failed to retrieve varstore name");

-                                                            VarStoreGuid = mCVfrDataStorage.GetVarStoreGuid(_GET_CURRQEST_VARTINFO().mVarStoreId);

+                                                            _PCATCH(gCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), VFR_RETURN_SUCCESS, L, "Failed to retrieve varstore name");

+                                                            VarStoreGuid = gCVfrDataStorage.GetVarStoreGuid(_GET_CURRQEST_VARTINFO().mVarStoreId);

                                                             Val.b = TRUE;

                                                             if (CBObj.GetFlags () & 0x01) {

                                                               CheckDuplicateDefaultValue (EFI_HII_DEFAULT_CLASS_STANDARD, F);

                                                               _PCATCH(

-                                                                mCVfrDefaultStore.BufferVarStoreAltConfigAdd (

+                                                                gCVfrDefaultStore.BufferVarStoreAltConfigAdd (

                                                                                     EFI_HII_DEFAULT_CLASS_STANDARD,

                                                                                     _GET_CURRQEST_VARTINFO(),

                                                                                     VarStoreName,

@@ -2206,7 +2208,7 @@
                                                             if (CBObj.GetFlags () & 0x02) {

                                                               CheckDuplicateDefaultValue (EFI_HII_DEFAULT_CLASS_MANUFACTURING, F);

                                                               _PCATCH(

-                                                                mCVfrDefaultStore.BufferVarStoreAltConfigAdd (

+                                                                gCVfrDefaultStore.BufferVarStoreAltConfigAdd (

                                                                                     EFI_HII_DEFAULT_CLASS_MANUFACTURING,

                                                                                     _GET_CURRQEST_VARTINFO(),

                                                                                     VarStoreName,

@@ -2703,7 +2705,7 @@
                                                        <<

                                                           //check data type flag

                                                           if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {

-                                                            VarStoreType = mCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);

+                                                            VarStoreType = gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);

                                                             if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_EFI) {

                                                               if (_GET_CURRQEST_DATATYPE() != (LFlags & EFI_IFR_NUMERIC_SIZE)) {

                                                                 _PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Numeric Flag is not same to Numeric VarData type");

@@ -2793,7 +2795,7 @@
                                                        <<

                                                           //check data type flag

                                                           if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {

-                                                            VarStoreType = mCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);

+                                                            VarStoreType = gCVfrDataStorage.GetVarStoreType (_GET_CURRQEST_VARTINFO().mVarStoreId);

                                                             if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_EFI) {

                                                               if (_GET_CURRQEST_DATATYPE() != (LFlags & EFI_IFR_NUMERIC_SIZE)) {

                                                                 _PCATCH(VFR_RETURN_INVALID_PARAMETER, LineNum, "Numeric Flag is not same to Numeric VarData type");

@@ -3445,11 +3447,11 @@
                                                           }

 

                                                           if (_GET_CURRQEST_VARTINFO().mVarStoreId != EFI_VARSTORE_ID_INVALID) {

-                                                            _PCATCH(mCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), L->getLine());

-                                                            VarStoreGuid = mCVfrDataStorage.GetVarStoreGuid(_GET_CURRQEST_VARTINFO().mVarStoreId);

+                                                            _PCATCH(gCVfrDataStorage.GetVarStoreName (_GET_CURRQEST_VARTINFO().mVarStoreId, &VarStoreName), L->getLine());

+                                                            VarStoreGuid = gCVfrDataStorage.GetVarStoreGuid(_GET_CURRQEST_VARTINFO().mVarStoreId);

                                                             if (OOOObj->GetFlags () & EFI_IFR_OPTION_DEFAULT) {

                                                               CheckDuplicateDefaultValue (EFI_HII_DEFAULT_CLASS_STANDARD, F);

-                                                              _PCATCH(mCVfrDefaultStore.BufferVarStoreAltConfigAdd (

+                                                              _PCATCH(gCVfrDefaultStore.BufferVarStoreAltConfigAdd (

                                                                         EFI_HII_DEFAULT_CLASS_STANDARD,

                                                                          _GET_CURRQEST_VARTINFO(),

                                                                         VarStoreName,

@@ -3460,7 +3462,7 @@
                                                             }

                                                             if (OOOObj->GetFlags () & EFI_IFR_OPTION_DEFAULT_MFG) {

                                                               CheckDuplicateDefaultValue (EFI_HII_DEFAULT_CLASS_MANUFACTURING, F);

-                                                              _PCATCH(mCVfrDefaultStore.BufferVarStoreAltConfigAdd (

+                                                              _PCATCH(gCVfrDefaultStore.BufferVarStoreAltConfigAdd (

                                                                         EFI_HII_DEFAULT_CLASS_MANUFACTURING,

                                                                          _GET_CURRQEST_VARTINFO(),

                                                                         VarStoreName,

@@ -3930,9 +3932,9 @@
   OpenParen

   VN:Number                                           <<

                                                           VarIdStr = NULL; _STRCAT(&VarIdStr, VK->getText()); _STRCAT(&VarIdStr, VN->getText());

-                                                          VfrReturnCode = mCVfrDataStorage.GetVarStoreId (VarIdStr, &VarStoreId);

+                                                          VfrReturnCode = gCVfrDataStorage.GetVarStoreId (VarIdStr, &VarStoreId);

                                                           if (VfrReturnCode == VFR_RETURN_UNDEFINED) {

-                                                            _PCATCH (mCVfrDataStorage.DeclareEfiVarStore (

+                                                            _PCATCH (gCVfrDataStorage.DeclareEfiVarStore (

                                                                                         VarIdStr,

                                                                                         &mFormsetGuid,

                                                                                         _STOSID(VN->getText(), VN->getLine()),

@@ -4249,7 +4251,7 @@
                                                                 break;

                                                               }

                                                             } else {

-                                                              if ((mCVfrDataStorage.GetVarStoreType(Info.mVarStoreId) == EFI_VFR_VARSTORE_NAME) && (VarType == EFI_IFR_TYPE_UNDEFINED)) {

+                                                              if ((gCVfrDataStorage.GetVarStoreType(Info.mVarStoreId) == EFI_VFR_VARSTORE_NAME) && (VarType == EFI_IFR_TYPE_UNDEFINED)) {

                                                                 _PCATCH(VFR_RETURN_UNSUPPORTED, L->getLine(), "Get/Set opcode don't support name string");

                                                               }

                                                               if (VarType != EFI_IFR_TYPE_UNDEFINED) {

@@ -4424,7 +4426,7 @@
                                                                 break;

                                                               }

                                                             } else {

-                                                              if ((mCVfrDataStorage.GetVarStoreType(Info.mVarStoreId) == EFI_VFR_VARSTORE_NAME) && (VarType == EFI_IFR_TYPE_UNDEFINED)) {

+                                                              if ((gCVfrDataStorage.GetVarStoreType(Info.mVarStoreId) == EFI_VFR_VARSTORE_NAME) && (VarType == EFI_IFR_TYPE_UNDEFINED)) {

                                                                 _PCATCH(VFR_RETURN_UNSUPPORTED, L->getLine(), "Get/Set opcode don't support name string");

                                                               }

                                                               if (VarType != EFI_IFR_TYPE_UNDEFINED) {

@@ -4553,8 +4555,6 @@
   UINT8               mParserStatus;

   BOOLEAN             mConstantOnlyInExpression;

 

-  CVfrDefaultStore    mCVfrDefaultStore;

-  CVfrDataStorage     mCVfrDataStorage;

   CVfrQuestionDB      mCVfrQuestionDB;

   CVfrRulesDB         mCVfrRulesDB;

 

@@ -5115,7 +5115,7 @@
   CONST CHAR8           VarName[] = "Setup";

 

   FirstNode = TRUE;

-  pNode = mCVfrDataStorage.GetBufferVarStoreList();

+  pNode = gCVfrDataStorage.GetBufferVarStoreList();

   if (pNode == NULL && gCVfrVarDataTypeDB.mFirstNewDataTypeName != NULL) {

     //

     // Create the default Buffer Var Store when no VarStore is defined.

@@ -5157,7 +5157,7 @@
     }

   }

 

-  pNode = mCVfrDataStorage.GetEfiVarStoreList();

+  pNode = gCVfrDataStorage.GetEfiVarStoreList();

   for (; pNode != NULL; pNode = pNode->mNext) {

     //

     // create the default efi varstore opcode for not exist varstore

@@ -5200,14 +5200,14 @@
     CIfrVarStore      VSObj;

 

     VSObj.SetLineNo (LineNo);

-    mCVfrDataStorage.DeclareBufferVarStore (

+    gCVfrDataStorage.DeclareBufferVarStore (

                        TypeNameList[Index],

                        &mFormsetGuid,

                        &gCVfrVarDataTypeDB,

                        TypeNameList[Index],

                        EFI_VARSTORE_ID_INVALID

                        );

-    mCVfrDataStorage.GetVarStoreId(TypeNameList[Index], &VarStoreId, &mFormsetGuid);

+    gCVfrDataStorage.GetVarStoreId(TypeNameList[Index], &VarStoreId, &mFormsetGuid);

     VSObj.SetVarStoreId (VarStoreId);

     gCVfrVarDataTypeDB.GetDataTypeSize(TypeNameList[Index], &Size);

     VSObj.SetSize ((UINT16) Size);

@@ -5225,14 +5225,14 @@
     CIfrVarStore      VSObj;

 

     VSObj.SetLineNo (LineNo);

-    mCVfrDataStorage.DeclareBufferVarStore (

+    gCVfrDataStorage.DeclareBufferVarStore (

                        (CHAR8 *) DateName,

                        &mFormsetGuid,

                        &gCVfrVarDataTypeDB,

                        (CHAR8 *) DateType,

                        EFI_VARSTORE_ID_INVALID

                        );

-    mCVfrDataStorage.GetVarStoreId((CHAR8 *) DateName, &VarStoreId, &mFormsetGuid);

+    gCVfrDataStorage.GetVarStoreId((CHAR8 *) DateName, &VarStoreId, &mFormsetGuid);

     VSObj.SetVarStoreId (VarStoreId);

     gCVfrVarDataTypeDB.GetDataTypeSize((CHAR8 *) DateType, &Size);

     VSObj.SetSize ((UINT16) Size);

@@ -5246,14 +5246,14 @@
     CIfrVarStore      VSObj;

 

     VSObj.SetLineNo (LineNo);

-    mCVfrDataStorage.DeclareBufferVarStore (

+    gCVfrDataStorage.DeclareBufferVarStore (

                        (CHAR8 *) TimeName,

                        &mFormsetGuid,

                        &gCVfrVarDataTypeDB,

                        (CHAR8 *) TimeType,

                        EFI_VARSTORE_ID_INVALID

                        );

-    mCVfrDataStorage.GetVarStoreId((CHAR8 *) TimeName, &VarStoreId, &mFormsetGuid);

+    gCVfrDataStorage.GetVarStoreId((CHAR8 *) TimeName, &VarStoreId, &mFormsetGuid);

     VSObj.SetVarStoreId (VarStoreId);

     gCVfrVarDataTypeDB.GetDataTypeSize((CHAR8 *) TimeType, &Size);

     VSObj.SetSize ((UINT16) Size);

@@ -5272,7 +5272,7 @@
   //

   CIfrDefaultStore DSObj;

 

-  mCVfrDefaultStore.RegisterDefaultStore (DSObj.GetObjBinAddr(), (CHAR8 *) "Standard Defaults", EFI_STRING_ID_INVALID, EFI_HII_DEFAULT_CLASS_STANDARD);

+  gCVfrDefaultStore.RegisterDefaultStore (DSObj.GetObjBinAddr(), (CHAR8 *) "Standard Defaults", EFI_STRING_ID_INVALID, EFI_HII_DEFAULT_CLASS_STANDARD);

   DSObj.SetLineNo (LineNo);

   DSObj.SetDefaultName (EFI_STRING_ID_INVALID);

   DSObj.SetDefaultId (EFI_HII_DEFAULT_CLASS_STANDARD);

@@ -5282,7 +5282,7 @@
   //

   CIfrDefaultStore DSObjMF;

 

-  mCVfrDefaultStore.RegisterDefaultStore (DSObjMF.GetObjBinAddr(), (CHAR8 *) "Standard ManuFacturing", EFI_STRING_ID_INVALID, EFI_HII_DEFAULT_CLASS_MANUFACTURING);

+  gCVfrDefaultStore.RegisterDefaultStore (DSObjMF.GetObjBinAddr(), (CHAR8 *) "Standard ManuFacturing", EFI_STRING_ID_INVALID, EFI_HII_DEFAULT_CLASS_MANUFACTURING);

   DSObjMF.SetLineNo (LineNo);

   DSObjMF.SetDefaultName (EFI_STRING_ID_INVALID);

   DSObjMF.SetDefaultId (EFI_HII_DEFAULT_CLASS_MANUFACTURING);

diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
index f73b70d..b3d1ac5 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
@@ -2,7 +2,7 @@
   

   Vfr common library functions.

 

-Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>

+Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>

 This program and the accompanying materials                          

 are licensed and made available under the terms and conditions of the BSD License         

 which accompanies this distribution.  The full text of the license may be found at        

@@ -1419,6 +1419,8 @@
   mNameVarStoreList        = NULL;

   mCurrVarStorageNode      = NULL;

   mNewVarStorageNode       = NULL;

+  mBufferFieldInfoListHead = NULL;

+  mBufferFieldInfoListTail = NULL;

 }

 

 CVfrDataStorage::~CVfrDataStorage (

@@ -2000,6 +2002,48 @@
 }

 

 EFI_VFR_RETURN_CODE

+CVfrDataStorage::AddBufferVarStoreFieldInfo (

+  IN EFI_VARSTORE_INFO  *Info

+  )

+{

+  BufferVarStoreFieldInfoNode *pNew;

+

+  if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {

+    return VFR_RETURN_FATAL_ERROR;

+  }

+

+  if (mBufferFieldInfoListHead == NULL) {

+    mBufferFieldInfoListHead = pNew;

+    mBufferFieldInfoListTail= pNew;

+  } else {

+    mBufferFieldInfoListTail->mNext = pNew;

+    mBufferFieldInfoListTail = pNew;

+  }

+

+  return VFR_RETURN_SUCCESS;

+}

+

+EFI_VFR_RETURN_CODE

+CVfrDataStorage::GetBufferVarStoreFieldInfo (

+  IN OUT EFI_VARSTORE_INFO  *Info

+  )

+{

+  BufferVarStoreFieldInfoNode *pNode;

+

+  pNode = mBufferFieldInfoListHead;

+  while (pNode != NULL) {

+    if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&

+      Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {

+      Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;

+      Info->mVarType      = pNode->mVarStoreInfo.mVarType;

+      return VFR_RETURN_SUCCESS;

+    }

+    pNode = pNode->mNext;

+  }

+  return VFR_RETURN_FATAL_ERROR;

+}

+

+EFI_VFR_RETURN_CODE

 CVfrDataStorage::GetNameVarStoreInfo (

   OUT EFI_VARSTORE_INFO  *Info,

   IN  UINT32             Index

@@ -2358,6 +2402,26 @@
   return FALSE;

 }

 

+BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(

+  IN EFI_VARSTORE_INFO  *Info

+  )

+{

+  mVarStoreInfo.mVarType               = Info->mVarType;

+  mVarStoreInfo.mVarTotalSize          = Info->mVarTotalSize;

+  mVarStoreInfo.mInfo.mVarOffset       = Info->mInfo.mVarOffset;

+  mVarStoreInfo.mVarStoreId            = Info->mVarStoreId;

+  mNext = NULL;

+}

+

+BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()

+{

+  mVarStoreInfo.mVarType               = EFI_IFR_TYPE_OTHER;

+  mVarStoreInfo.mVarTotalSize          = 0;

+  mVarStoreInfo.mInfo.mVarOffset       = EFI_VAROFFSET_INVALID;

+  mVarStoreInfo.mVarStoreId            = EFI_VARSTORE_ID_INVALID;

+  mNext = NULL;

+}

+

 static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;

 

 EFI_QUESTION_ID

@@ -3632,5 +3696,7 @@
 BOOLEAN  VfrCompatibleMode = FALSE;

 

 CVfrVarDataTypeDB gCVfrVarDataTypeDB;

+CVfrDefaultStore  gCVfrDefaultStore;

+CVfrDataStorage  gCVfrDataStorage;

 

 

diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
index c8f5333..5faa1f4 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
@@ -2,7 +2,7 @@
   

   Vfr common library functions.

 

-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>

+Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>

 This program and the accompanying materials                          

 are licensed and made available under the terms and conditions of the BSD License         

 which accompanies this distribution.  The full text of the license may be found at        

@@ -265,6 +265,14 @@
   BOOLEAN operator == (IN EFI_VARSTORE_INFO *);

 };

 

+struct BufferVarStoreFieldInfoNode {

+  EFI_VARSTORE_INFO  mVarStoreInfo;

+  struct BufferVarStoreFieldInfoNode *mNext;

+

+  BufferVarStoreFieldInfoNode( IN EFI_VARSTORE_INFO  *Info );

+  ~BufferVarStoreFieldInfoNode ();

+};

+

 #define EFI_VARSTORE_ID_MAX              0xFFFF

 #define EFI_FREE_VARSTORE_ID_BITMAP_SIZE ((EFI_VARSTORE_ID_MAX + 1) / EFI_BITS_PER_UINT32)

 

@@ -278,6 +286,8 @@
 

   struct SVfrVarStorageNode *mCurrVarStorageNode;

   struct SVfrVarStorageNode *mNewVarStorageNode;

+  BufferVarStoreFieldInfoNode    *mBufferFieldInfoListHead;

+  BufferVarStoreFieldInfoNode    *mBufferFieldInfoListTail;

 

 private:

 

@@ -317,8 +327,12 @@
   EFI_VFR_RETURN_CODE GetBufferVarStoreDataTypeName (IN EFI_VARSTORE_ID, OUT CHAR8 **);

   EFI_VFR_RETURN_CODE GetEfiVarStoreInfo (IN EFI_VARSTORE_INFO *);

   EFI_VFR_RETURN_CODE GetNameVarStoreInfo (IN EFI_VARSTORE_INFO *, IN UINT32);

+  EFI_VFR_RETURN_CODE AddBufferVarStoreFieldInfo (IN EFI_VARSTORE_INFO *);

+  EFI_VFR_RETURN_CODE GetBufferVarStoreFieldInfo (IN OUT EFI_VARSTORE_INFO *);

 };

 

+extern CVfrDataStorage gCVfrDataStorage;

+

 #define EFI_QUESTION_ID_MAX              0xFFFF

 #define EFI_FREE_QUESTION_ID_BITMAP_SIZE ((EFI_QUESTION_ID_MAX + 1) / EFI_BITS_PER_UINT32)

 #define EFI_QUESTION_ID_INVALID          0x0

@@ -402,6 +416,8 @@
   EFI_VFR_RETURN_CODE BufferVarStoreAltConfigAdd (IN EFI_VARSTORE_ID, IN EFI_VARSTORE_INFO &, IN CHAR8 *, IN EFI_GUID *, IN UINT8, IN EFI_IFR_TYPE_VALUE);

 };

 

+extern CVfrDefaultStore gCVfrDefaultStore;

+

 #define EFI_RULE_ID_START    0x01

 #define EFI_RULE_ID_INVALID  0x00