]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.c
clean up for IPF ICC tool chain.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / OpcodeCreation.c
index fb6169b29c13351ec27d5510ce75732370fe2a58..c79ad26e988570bd7f03b66492dcb607d541b281 100644 (file)
@@ -18,6 +18,108 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 EFI_GUID  mTianoExtendedOpcodeGuid = EFI_IFR_TIANO_GUID;\r
 \r
+\r
+EFI_IFR_GUID_OPTIONKEY mOptionKeyTemplate = {\r
+   {EFI_IFR_GUID_OP, sizeof (EFI_IFR_GUID_OPTIONKEY), 0},\r
+   EFI_IFR_FRAMEWORK_GUID,\r
+   EFI_IFR_EXTEND_OP_OPTIONKEY,\r
+   0,\r
+   0,\r
+   0\r
+};\r
+\r
+typedef struct { \r
+  UINT8 FrameworkIfrOp;\r
+  UINT8 UefiIfrOp;\r
+} IFR_OPCODE_MAP;\r
+\r
+IFR_OPCODE_MAP mQuestionOpcodeMap [] = {\r
+  { FRAMEWORK_EFI_IFR_ONE_OF_OP,        EFI_IFR_ONE_OF_OP},\r
+  { FRAMEWORK_EFI_IFR_CHECKBOX_OP,      EFI_IFR_CHECKBOX_OP},\r
+  { FRAMEWORK_EFI_IFR_NUMERIC_OP,       EFI_IFR_NUMERIC_OP},\r
+  { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP, EFI_IFR_ONE_OF_OPTION_OP},\r
+  { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP,  EFI_IFR_ORDERED_LIST_OP}\r
+};\r
+\r
+EFI_STATUS\r
+QuestionOpFwToUefi (\r
+  IN            UINT8   FwOp,\r
+  OUT           UINT8   *UefiOp\r
+  )\r
+{\r
+  UINTN       Index;\r
+\r
+  for (Index = 0; Index < sizeof (mQuestionOpcodeMap) / sizeof (mQuestionOpcodeMap[0]); Index++) {\r
+    if (FwOp == mQuestionOpcodeMap[Index].FrameworkIfrOp) {\r
+      *UefiOp = mQuestionOpcodeMap[Index].UefiIfrOp;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+FwQIdToUefiQId (\r
+  IN  CONST FORM_BROWSER_FORMSET *FormSet,\r
+  IN  UINT16                     VarStoreId,\r
+  IN  UINT8                      FwOpCode,\r
+  IN  UINT16                     FwQId,\r
+  OUT UINT16                     *UefiQId\r
+  )\r
+{\r
+  LIST_ENTRY             *FormList;\r
+  LIST_ENTRY             *StatementList;\r
+  FORM_BROWSER_FORM      *Form;\r
+  FORM_BROWSER_STATEMENT *Statement;\r
+  EFI_STATUS             Status;\r
+  UINT8                  UefiOp;\r
+\r
+  *UefiQId = 0;\r
+\r
+  FormList = GetFirstNode (&FormSet->FormListHead);\r
+\r
+  while (!IsNull (&FormSet->FormListHead, FormList)) {\r
+    Form = FORM_BROWSER_FORM_FROM_LINK (FormList);\r
+\r
+    StatementList = GetFirstNode (&Form->StatementListHead);\r
+\r
+    while (!IsNull (&Form->StatementListHead, StatementList)) {\r
+      Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);\r
+      if (Statement->VarStoreId != 0 && Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+        if (FwQId == Statement->VarStoreInfo.VarOffset) {\r
+          Status = QuestionOpFwToUefi (FwOpCode, &UefiOp);\r
+          ASSERT_EFI_ERROR (Status);\r
+\r
+          if (UefiOp == Statement->Operand) {\r
+            //\r
+            // If ASSERT here, the Framework VFR file has two IFR Question with the Same Type refering to the \r
+            // same field in NvMap. This is ambigurity, we don't handle it for now.\r
+            //\r
+            //\r
+            // UEFI Question ID is unique in a FormSet.\r
+            //\r
+            ASSERT (VarStoreId == Statement->VarStoreId);\r
+            *UefiQId = Statement->QuestionId;\r
+\r
+            return EFI_SUCCESS;\r
+            \r
+          }\r
+        }\r
+      }\r
+\r
+      StatementList = GetNextNode (&Form->StatementListHead, StatementList);\r
+    }\r
+\r
+    FormList = GetNextNode (&FormSet->FormListHead, FormList);\r
+  }\r
+  \r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+\r
 #define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL   0x1000\r
 EFI_STATUS\r
 AppendToUpdateBuffer (\r
@@ -44,6 +146,20 @@ AppendToUpdateBuffer (
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_QUESTION_ID\r
+AssignQuestionId (\r
+  IN  UINT16                      FwQuestionId,\r
+  IN        FORM_BROWSER_FORMSET  *FormSet\r
+  )\r
+{\r
+  if (FwQuestionId == 0) {\r
+    FormSet->MaxQuestionId++;\r
+    return FormSet->MaxQuestionId;\r
+  } else {\r
+    return FwQuestionId;\r
+  }\r
+}\r
+\r
 EFI_STATUS\r
 UCreateEndOfOpcode (\r
   OUT      EFI_HII_UPDATE_DATA         *UefiData\r
@@ -83,19 +199,39 @@ F2UCreateTextOpCode (
   OUT      EFI_HII_UPDATE_DATA         *UefiData\r
   )\r
 {\r
-  EFI_IFR_TEXT UOpcode;\r
+  EFI_IFR_TEXT      UTextOpCode;\r
+  EFI_IFR_ACTION    UActionOpCode;\r
 \r
-  ZeroMem (&UOpcode, sizeof(UOpcode));\r
-  \r
-  UOpcode.Header.OpCode = EFI_IFR_TEXT_OP;\r
-  UOpcode.Header.Length = sizeof (EFI_IFR_TEXT);\r
+  if ((FwText->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) == 0) {\r
+    ZeroMem (&UTextOpCode, sizeof(UTextOpCode));\r
+    \r
+    UTextOpCode.Header.OpCode = EFI_IFR_TEXT_OP;\r
+    UTextOpCode.Header.Length = sizeof (EFI_IFR_TEXT);\r
 \r
-  UOpcode.Statement.Help   = FwText->Help;\r
+    UTextOpCode.Statement.Help   = FwText->Help;\r
 \r
-  UOpcode.Statement.Prompt = FwText->Text;\r
-  UOpcode.TextTwo          = FwText->TextTwo;\r
-  \r
-  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+    UTextOpCode.Statement.Prompt = FwText->Text;\r
+    UTextOpCode.TextTwo          = FwText->TextTwo;\r
+    \r
+    return AppendToUpdateBuffer ((UINT8 *) &UTextOpCode, sizeof(UTextOpCode), UefiData);\r
+  } else {\r
+    //\r
+    // Iteractive Text Opcode is EFI_IFR_ACTION\r
+    //\r
+\r
+    ZeroMem (&UActionOpCode, sizeof (UActionOpCode));\r
+\r
+    UActionOpCode.Header.OpCode = EFI_IFR_ACTION_OP;\r
+    UActionOpCode.Header.Length = sizeof (EFI_IFR_ACTION);\r
+\r
+    UActionOpCode.Question.Header.Prompt = FwText->Text;\r
+    UActionOpCode.Question.Header.Help  = FwText->Help;\r
+    UActionOpCode.Question.Flags      = EFI_IFR_FLAG_CALLBACK;\r
+    UActionOpCode.Question.QuestionId = FwText->Key;\r
+\r
+    return AppendToUpdateBuffer ((UINT8 *) &UActionOpCode, sizeof(UActionOpCode), UefiData);\r
+    \r
+  }\r
 }\r
 \r
 /*\r
@@ -132,7 +268,7 @@ F2UCreateGotoOpCode (
   // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to \r
   // UEFI IFR Opcode flags. The rest flags are obsolete.\r
   //\r
-  UOpcode.Question.Flags  = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
+  UOpcode.Question.Flags  = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
   \r
 \r
   return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
@@ -192,7 +328,7 @@ F2UCreateOneOfOptionOpCode (
   // #define EFI_IFR_OPTION_DEFAULT 0x10\r
   // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20\r
   //\r
-  UOpcode.Flags |= (UINT8) ((FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING)) << 4);\r
+  UOpcode.Flags = (UINT8) (UOpcode.Flags  | (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING)) << 4);\r
 \r
   switch (Width) {\r
     case 1:\r
@@ -211,6 +347,24 @@ F2UCreateOneOfOptionOpCode (
   return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
 }\r
 \r
+EFI_STATUS\r
+CreateGuidOptionKeyOpCode (\r
+  IN EFI_QUESTION_ID                   QuestionId,\r
+  IN UINT16                            OptionValue,\r
+  IN EFI_QUESTION_ID                   KeyValue,\r
+  OUT      EFI_HII_UPDATE_DATA         *UefiData\r
+  )\r
+{\r
+  EFI_IFR_GUID_OPTIONKEY              UOpcode;\r
+\r
+  CopyMem (&UOpcode, &mOptionKeyTemplate, sizeof (EFI_IFR_GUID_OPTIONKEY));\r
+\r
+  UOpcode.QuestionId  = QuestionId;\r
+  CopyMem (&UOpcode.OptionValue, &OptionValue, sizeof (OptionValue)); \r
+  UOpcode.KeyValue = KeyValue;\r
+  \r
+  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+}\r
 \r
 /*\r
 typedef struct _EFI_IFR_QUESTION_HEADER {\r
@@ -267,18 +421,24 @@ typedef struct {
 \r
 EFI_STATUS\r
 F2UCreateOneOfOpCode (\r
+  IN       HII_THUNK_CONTEXT           *ThunkContext,\r
+  IN       UINT16                      VarStoreId,\r
   IN CONST FRAMEWORK_EFI_IFR_ONE_OF    *FwOpcode,\r
   OUT      EFI_HII_UPDATE_DATA         *UefiData,\r
-  OUT      FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode\r
+  OUT      FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
+  OUT      UINTN                       *DataCount\r
   )\r
 {\r
-  EFI_STATUS     Status;\r
-  EFI_IFR_ONE_OF UOpcode;\r
-  FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
-  FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
-  BOOLEAN        HasQuestionId;\r
+  EFI_STATUS                          Status;\r
+  EFI_IFR_ONE_OF                      UOpcode;\r
+  FRAMEWORK_EFI_IFR_OP_HEADER         *FwOpHeader;\r
+  FRAMEWORK_EFI_IFR_ONE_OF_OPTION     *FwOneOfOp;\r
+\r
+  ASSERT (NextFwOpcode != NULL);\r
+  ASSERT (DataCount != NULL);\r
 \r
   ZeroMem (&UOpcode, sizeof(UOpcode));\r
+  *DataCount = 0;\r
 \r
   UOpcode.Header.Length = sizeof(UOpcode);\r
   UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OP;\r
@@ -286,43 +446,78 @@ F2UCreateOneOfOpCode (
 \r
   UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
   UOpcode.Question.Header.Help = FwOpcode->Help;\r
\r
-  Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
+  UOpcode.Question.VarStoreId  = VarStoreId;\r
+  UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
+  \r
   //\r
   // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
   //\r
-  HasQuestionId = FALSE;\r
   FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
   while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
     ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
     \r
     FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
-    if (((FwOneOfOp->Key & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) == 0) & !HasQuestionId) {\r
-      HasQuestionId = TRUE;\r
-      UOpcode.Question.QuestionId = FwOneOfOp->Key;\r
+    if ((FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
+      UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
+      \r
+      if (UOpcode.Question.QuestionId == 0) {\r
+        Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+        if (EFI_ERROR (Status)) {\r
+          UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
+        }\r
+      }\r
+\r
+    }\r
+\r
+    if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
+      UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
     }\r
 \r
     FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
   }\r
 \r
+\r
+  if (UOpcode.Question.QuestionId == 0) {\r
+    //\r
+    // Assign QuestionId if still not assigned.\r
+    //\r
+    Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+    if (EFI_ERROR (Status)) {\r
+      UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
+    }\r
+  }\r
+  \r
+  Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof (UOpcode), UefiData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  *DataCount += 1;\r
+\r
   //\r
   // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.\r
   //\r
   FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
   while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
+\r
+    FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
+      \r
     Status = F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->Width, UefiData);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+\r
+    Status = CreateGuidOptionKeyOpCode (UOpcode.Question.QuestionId, FwOneOfOp->Value, FwOneOfOp->Key, UefiData);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
+    *DataCount += 1;\r
   }\r
 \r
   Status = UCreateEndOfOpcode (UefiData);\r
   if (!EFI_ERROR (Status)) {\r
     *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
+    *DataCount += 1;\r
   }\r
 \r
   return Status;\r
@@ -358,16 +553,21 @@ typedef struct {
 */\r
 EFI_STATUS\r
 F2UCreateOrderedListOpCode (\r
+  IN       HII_THUNK_CONTEXT               *ThunkContext,\r
+  IN       UINT16                      VarStoreId,\r
   IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST *FwOpcode,\r
   OUT      EFI_HII_UPDATE_DATA         *UefiData,\r
-  OUT      FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode\r
+  OUT      FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
+  OUT      UINTN                       *DataCount\r
   )\r
 {\r
   EFI_IFR_ORDERED_LIST              UOpcode;\r
   EFI_STATUS                        Status;\r
   FRAMEWORK_EFI_IFR_OP_HEADER       *FwOpHeader;\r
+  FRAMEWORK_EFI_IFR_ONE_OF_OPTION     *FwOneOfOp;\r
 \r
   ZeroMem (&UOpcode, sizeof(UOpcode));\r
+  *DataCount = 0;\r
 \r
   UOpcode.Header.Length = sizeof(UOpcode);\r
   UOpcode.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;\r
@@ -375,28 +575,71 @@ F2UCreateOrderedListOpCode (
 \r
   UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
   UOpcode.Question.Header.Help = FwOpcode->Help;\r
+  UOpcode.Question.VarStoreId  = VarStoreId;\r
+  UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
 \r
   UOpcode.MaxContainers = FwOpcode->MaxEntries;\r
+\r
+  //\r
+  // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
+  //\r
+  FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
+  while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
+    ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
+    \r
+    FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
+    if ((FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
+      UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
+      \r
+      if (UOpcode.Question.QuestionId == 0) {\r
+        Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+        if (EFI_ERROR (Status)) {\r
+          UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
+        }\r
+\r
+      }\r
+    }\r
+\r
+    if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
+      UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
+    }\r
+\r
+    FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
+  }\r
+\r
+  if (UOpcode.Question.QuestionId == 0) {\r
+    Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+    if (EFI_ERROR (Status)) {\r
+      UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
+    }\r
+  }\r
  \r
   Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+  *DataCount += 1;\r
 \r
   FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
   while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
-    Status = F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->MaxEntries, UefiData);\r
+    //\r
+    // Each entry of Order List in Framework HII is always 1 byte in size\r
+    //\r
+    Status = F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, 1, UefiData);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+    FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
+    *DataCount += 1;\r
   }\r
 \r
   Status = UCreateEndOfOpcode (UefiData);\r
   if (!EFI_ERROR (Status)) {\r
     *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
+    *DataCount += 1;\r
   }\r
 \r
-  return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
+  return Status;\r
 }\r
 \r
 /*\r
@@ -435,10 +678,13 @@ typedef struct {
 \r
 EFI_STATUS\r
 F2UCreateCheckBoxOpCode (\r
+  IN       HII_THUNK_CONTEXT           *ThunkContext,\r
+  IN       UINT16                      VarStoreId,\r
   IN CONST FRAMEWORK_EFI_IFR_CHECKBOX  *FwOpcode,\r
   OUT      EFI_HII_UPDATE_DATA         *UefiData\r
   )\r
 {\r
+  EFI_STATUS       Status;\r
   EFI_IFR_CHECKBOX UOpcode;\r
 \r
   ZeroMem (&UOpcode, sizeof(UOpcode));\r
@@ -449,8 +695,19 @@ F2UCreateCheckBoxOpCode (
   UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
   UOpcode.Question.Header.Help = FwOpcode->Help;\r
 \r
-  UOpcode.Question.QuestionId    = FwOpcode->Key;\r
-  UOpcode.Question.VarStoreId    = RESERVED_VARSTORE_ID;\r
+  if (FwOpcode->Key == 0) {\r
+    Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
+      //\r
+      UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
+    }\r
+  } else {\r
+    UOpcode.Question.QuestionId    = FwOpcode->Key;\r
+  }\r
+\r
+  UOpcode.Question.VarStoreId    = FRAMEWORK_RESERVED_VARSTORE_ID;\r
   UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
 \r
   //\r
@@ -459,15 +716,15 @@ F2UCreateCheckBoxOpCode (
   //      FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,\r
   // to UEFI IFR Opcode Question flags. The rest flags are obsolete.\r
   //\r
-  UOpcode.Question.Flags  = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
+  UOpcode.Question.Flags  = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
 \r
   //\r
   // We also map 2 flags:\r
-  //      FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE\r
-  //      FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,\r
+  //      FRAMEWORK_EFI_IFR_FLAG_DEFAULT\r
+  //      FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,\r
   // to UEFI IFR CheckBox Opcode default flags.\r
   //\r
-  UOpcode.Flags           = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING));\r
+  UOpcode.Flags           = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING));\r
 \r
   return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
 }\r
@@ -535,6 +792,8 @@ typedef struct {
 \r
 EFI_STATUS\r
 F2UCreateNumericOpCode (\r
+  IN       HII_THUNK_CONTEXT           *ThunkContext,\r
+  IN       UINT16                      VarStoreId,\r
   IN CONST FRAMEWORK_EFI_IFR_NUMERIC   *FwOpcode,\r
   OUT      EFI_HII_UPDATE_DATA         *UefiData\r
   )\r
@@ -545,24 +804,33 @@ F2UCreateNumericOpCode (
 \r
   ZeroMem (&UOpcode, sizeof(UOpcode));\r
 \r
+  if (FwOpcode->Key == 0) {\r
+    Status = FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
+      //\r
+      UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
+    }\r
+  } else {\r
+    UOpcode.Question.QuestionId    = FwOpcode->Key;\r
+  }\r
+\r
   UOpcode.Header.Length = sizeof(UOpcode);\r
   UOpcode.Header.OpCode = EFI_IFR_NUMERIC_OP;\r
   //\r
   // We need to create a nested default value for the UEFI Numeric Opcode.\r
   // So turn on the scope.\r
   //\r
-  if (FwOpcode->Default != 0) {\r
-    UOpcode.Header.Scope = 1;\r
-  }\r
+  UOpcode.Header.Scope = 1;\r
 \r
   UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
   UOpcode.Question.Header.Help = FwOpcode->Help;\r
 \r
-  UOpcode.Question.QuestionId    = FwOpcode->Key;\r
-  UOpcode.Question.VarStoreId    = RESERVED_VARSTORE_ID;\r
+  UOpcode.Question.VarStoreId    = VarStoreId;\r
   UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
 \r
-  UOpcode.Question.Flags  = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
+  UOpcode.Question.Flags  = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
 \r
   //\r
   // Framework Numeric values are all in UINT16 and displayed as decimal.\r
@@ -574,12 +842,12 @@ F2UCreateNumericOpCode (
   switch (FwOpcode->Width) {\r
     case 1: \r
     {\r
-      UOpcode.Flags           =  EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC; \r
+      UOpcode.Flags           =  EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC; \r
       break;\r
     } \r
     case 2: \r
     {\r
-      UOpcode.Flags           =  EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC; \r
+      UOpcode.Flags           =  EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC; \r
       break;\r
     }\r
     default: \r
@@ -595,36 +863,34 @@ F2UCreateNumericOpCode (
   }\r
 \r
   //\r
-  // We need to create a default \r
+  // We need to create a default value.\r
   //\r
-  if (FwOpcode->Default != 0) {\r
-    ZeroMem (&UOpcodeDefault, sizeof (UOpcodeDefault));\r
-    UOpcodeDefault.Header.Length = sizeof (UOpcodeDefault);\r
-    UOpcodeDefault.Header.OpCode = EFI_IFR_DEFAULT_OP;\r
+  ZeroMem (&UOpcodeDefault, sizeof (UOpcodeDefault));\r
+  UOpcodeDefault.Header.Length = sizeof (UOpcodeDefault);\r
+  UOpcodeDefault.Header.OpCode = EFI_IFR_DEFAULT_OP;\r
 \r
-    UOpcodeDefault.DefaultId = 0;\r
+  UOpcodeDefault.DefaultId = 0;\r
 \r
-    switch (FwOpcode->Width) {\r
-      case 1: \r
-      {\r
-        UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
-        break;\r
-      } \r
-      case 2: \r
-      {\r
-        UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
-        break;\r
-      }\r
+  switch (FwOpcode->Width) {\r
+    case 1: \r
+    {\r
+      UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
+      break;\r
+    } \r
+    case 2: \r
+    {\r
+      UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
+      break;\r
     }\r
+  }\r
 \r
-    CopyMem (&UOpcodeDefault.Value.u8, &FwOpcode->Default, FwOpcode->Width);\r
+  CopyMem (&UOpcodeDefault.Value.u8, &FwOpcode->Default, FwOpcode->Width);\r
 \r
-    Status = AppendToUpdateBuffer ((UINT8 *) &UOpcodeDefault, sizeof(UOpcodeDefault), UefiData);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-    Status = UCreateEndOfOpcode (UefiData);\r
+  Status = AppendToUpdateBuffer ((UINT8 *) &UOpcodeDefault, sizeof(UOpcodeDefault), UefiData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
   }\r
+  Status = UCreateEndOfOpcode (UefiData);\r
 \r
   return Status;\r
 }\r
@@ -669,6 +935,8 @@ typedef struct {
 \r
 EFI_STATUS\r
 F2UCreateStringOpCode (\r
+  IN       HII_THUNK_CONTEXT               *ThunkContext,\r
+  IN       UINT16                      VarStoreId,\r
   IN CONST FRAMEWORK_EFI_IFR_STRING    *FwOpcode,\r
   OUT      EFI_HII_UPDATE_DATA         *UefiData\r
   )\r
@@ -677,6 +945,12 @@ F2UCreateStringOpCode (
 \r
   ZeroMem (&UOpcode, sizeof(UOpcode));\r
 \r
+  if (FwOpcode->Key == 0) {\r
+    FwQIdToUefiQId (ThunkContext->FormSet, VarStoreId, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
+  } else {\r
+    UOpcode.Question.QuestionId    = FwOpcode->Key;\r
+  }\r
+\r
   UOpcode.Header.Length = sizeof(UOpcode);\r
   UOpcode.Header.OpCode = EFI_IFR_STRING_OP;\r
 \r
@@ -684,10 +958,10 @@ F2UCreateStringOpCode (
   UOpcode.Question.Header.Help = FwOpcode->Help;\r
 \r
   UOpcode.Question.QuestionId    = FwOpcode->Key;\r
-  UOpcode.Question.VarStoreId    = RESERVED_VARSTORE_ID;\r
+  UOpcode.Question.VarStoreId    = FRAMEWORK_RESERVED_VARSTORE_ID;\r
   UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
 \r
-  UOpcode.Question.Flags  = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
+  UOpcode.Question.Flags  = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
 \r
   UOpcode.MinSize = FwOpcode->MinSize;\r
   UOpcode.MaxSize = FwOpcode->MaxSize;\r
@@ -738,107 +1012,120 @@ F2UCreateBannerOpCode (
 }\r
 \r
 \r
-\r
 EFI_STATUS\r
-ThunkFrameworkUpdateDataToUefiUpdateData (\r
+FwUpdateDataToUefiUpdateData (\r
+  IN       HII_THUNK_CONTEXT                 *ThunkContext,\r
   IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA    *Data,\r
-  IN       BOOLEAN                          AddData,\r
   OUT      EFI_HII_UPDATE_DATA              **UefiData\r
   )\r
 {\r
-  FRAMEWORK_EFI_IFR_OP_HEADER          *FrameworkOpcodeBuffer;\r
-  FRAMEWORK_EFI_IFR_OP_HEADER          *NextFrameworkOpcodeBuffer;\r
-  EFI_HII_UPDATE_DATA                  *UefiUpdateDataBuffer;\r
+  FRAMEWORK_EFI_IFR_OP_HEADER          *FwOpCode;\r
+  FRAMEWORK_EFI_IFR_OP_HEADER          *NextFwOpCode;\r
+  EFI_HII_UPDATE_DATA                  *UefiOpCode;\r
   UINTN                                Index;\r
   EFI_STATUS                           Status;\r
-  static UINTN                         mOneOfOptionWidth;\r
+  UINTN                                DataCount;\r
+  UINT16                               VarStoreId;\r
 \r
-  mOneOfOptionWidth = 0;\r
-  \r
+  //\r
+  // Assume all dynamic opcode created is using active variable with VarStoreId of 1.\r
+  //\r
+  VarStoreId = 1;\r
 \r
-  UefiUpdateDataBuffer = AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA));\r
-  if (UefiUpdateDataBuffer == NULL) {\r
+  UefiOpCode = AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA));\r
+  if (UefiOpCode == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
   \r
-  UefiUpdateDataBuffer->Data = AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL);\r
-  if (UefiUpdateDataBuffer->Data == NULL) {\r
+  UefiOpCode->Data = AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL);\r
+  if (UefiOpCode->Data == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  UefiUpdateDataBuffer->BufferSize = LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
-  UefiUpdateDataBuffer->Offset = 0;\r
+  UefiOpCode->BufferSize = LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
+  UefiOpCode->Offset = 0;\r
 \r
-  FrameworkOpcodeBuffer = (FRAMEWORK_EFI_IFR_OP_HEADER *) &Data->Data;\r
+  FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *) &Data->Data;\r
 \r
-  for (Index = 0; Index < Data->DataCount; Index++) {\r
-    switch (FrameworkOpcodeBuffer->OpCode) {\r
+  for (Index = 0; Index < Data->DataCount; Index += DataCount) {\r
+    switch (FwOpCode->OpCode) {\r
       case FRAMEWORK_EFI_IFR_SUBTITLE_OP:\r
-        Status = F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE  *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);\r
+        Status = F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE  *) FwOpCode, UefiOpCode);\r
+        DataCount = 1;\r
         break;\r
         \r
       case FRAMEWORK_EFI_IFR_TEXT_OP:\r
-        Status = F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT  *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
+        Status = F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT  *) FwOpCode, UefiOpCode);  \r
+        DataCount = 1;\r
         break;\r
 \r
       case FRAMEWORK_EFI_IFR_REF_OP:\r
-        Status = F2UCreateGotoOpCode ((FRAMEWORK_EFI_IFR_REF *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
+        Status = F2UCreateGotoOpCode ((FRAMEWORK_EFI_IFR_REF *) FwOpCode, UefiOpCode);  \r
+        DataCount = 1;\r
         break;\r
         \r
       case FRAMEWORK_EFI_IFR_ONE_OF_OP:\r
-        Status = F2UCreateOneOfOpCode ((FRAMEWORK_EFI_IFR_ONE_OF *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer, &NextFrameworkOpcodeBuffer);\r
+        Status = F2UCreateOneOfOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_ONE_OF *) FwOpCode, UefiOpCode, &NextFwOpCode, &DataCount);\r
         if (!EFI_ERROR (Status)) {\r
-          FrameworkOpcodeBuffer = NextFrameworkOpcodeBuffer;\r
+          FwOpCode = NextFwOpCode;\r
           //\r
-          // F2UCreateOneOfOpCode has updated FrameworkOpcodeBuffer to point to the next opcode.\r
+          // FwOpCode is already updated to point to the next opcode.\r
           //\r
           continue;\r
         }\r
         break;\r
 \r
       case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP:\r
-        Status = F2UCreateOrderedListOpCode ((FRAMEWORK_EFI_IFR_ORDERED_LIST *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer, &NextFrameworkOpcodeBuffer);\r
+        Status = F2UCreateOrderedListOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_ORDERED_LIST *) FwOpCode, UefiOpCode, &NextFwOpCode, &DataCount);\r
         if (!EFI_ERROR (Status)) {\r
-          FrameworkOpcodeBuffer = NextFrameworkOpcodeBuffer;\r
+          FwOpCode = NextFwOpCode;\r
           //\r
-          // F2UCreateOrderedListOpCode has updated FrameworkOpcodeBuffer to point to the next opcode.\r
+          // FwOpCode is already updated to point to the next opcode.\r
           //\r
           continue;\r
         }\r
         break;\r
         \r
       case FRAMEWORK_EFI_IFR_CHECKBOX_OP:\r
-        Status = F2UCreateCheckBoxOpCode ((FRAMEWORK_EFI_IFR_CHECKBOX *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
+        Status = F2UCreateCheckBoxOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_CHECKBOX *) FwOpCode, UefiOpCode);  \r
+        DataCount = 1;\r
         break;\r
 \r
       case FRAMEWORK_EFI_IFR_STRING_OP:\r
-        Status = F2UCreateStringOpCode ((FRAMEWORK_EFI_IFR_STRING *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
+        Status = F2UCreateStringOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_STRING *) FwOpCode, UefiOpCode);  \r
+        DataCount = 1;\r
         break;\r
 \r
       case FRAMEWORK_EFI_IFR_BANNER_OP:\r
-        Status = F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER *) FrameworkOpcodeBuffer, UefiUpdateDataBuffer);  \r
+        Status = F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER *) FwOpCode, UefiOpCode);  \r
+        DataCount = 1;\r
         break;\r
 \r
       case FRAMEWORK_EFI_IFR_END_ONE_OF_OP:\r
-        Status = UCreateEndOfOpcode (UefiUpdateDataBuffer);\r
-        mOneOfOptionWidth = 0;\r
+        Status = UCreateEndOfOpcode (UefiOpCode);\r
+        DataCount = 1;\r
         break;\r
-        \r
+\r
+      case FRAMEWORK_EFI_IFR_NUMERIC_OP:\r
+        Status = F2UCreateNumericOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_NUMERIC *) FwOpCode, UefiOpCode);\r
+        DataCount = 1;\r
+        break;\r
+\r
       default:\r
         ASSERT (FALSE);\r
         return EFI_UNSUPPORTED;\r
     }\r
 \r
     if (EFI_ERROR (Status)) {\r
-      FreePool (UefiUpdateDataBuffer->Data);\r
-      FreePool (UefiUpdateDataBuffer);\r
+      FreePool (UefiOpCode->Data);\r
+      FreePool (UefiOpCode);\r
       return Status;\r
     }\r
 \r
-    FrameworkOpcodeBuffer = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FrameworkOpcodeBuffer + FrameworkOpcodeBuffer->Length);\r
+    FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpCode + FwOpCode->Length);\r
   }\r
 \r
-  *UefiData = UefiUpdateDataBuffer;\r
+  *UefiData = UefiOpCode;\r
   \r
   return EFI_SUCCESS;\r
 }\r