]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/OpcodeCreation.c
Update FrameworkHiiOnUefiHiiThunk driver due to clean up of FrameworkHii.h.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / OpcodeCreation.c
CommitLineData
5391c4f1 1/** @file\r
2Implement Functions to convert IFR Opcode in format defined in Framework HII specification to\r
3format defined in UEFI HII Specification.\r
4\r
5Copyright (c) 2007, Intel Corporation\r
6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
03254710 15\r
5391c4f1 16#include "HiiDatabase.h"\r
5391c4f1 17#include "UefiIfrDefault.h"\r
18\r
03254710 19/**\r
20 The dynamic creation of these opcodes is supported in Framework HII modules.\r
21 Therefore, Framework HII Thunk module only map these opcode between Framework\r
22 HII's definitions to UEFI HII's.\r
23**/\r
a9d85320 24typedef struct { \r
25 UINT8 FrameworkIfrOp;\r
26 UINT8 UefiIfrOp;\r
27} IFR_OPCODE_MAP;\r
03254710 28 \r
a9d85320 29IFR_OPCODE_MAP mQuestionOpcodeMap [] = {\r
30 { FRAMEWORK_EFI_IFR_ONE_OF_OP, EFI_IFR_ONE_OF_OP},\r
31 { FRAMEWORK_EFI_IFR_CHECKBOX_OP, EFI_IFR_CHECKBOX_OP},\r
32 { FRAMEWORK_EFI_IFR_NUMERIC_OP, EFI_IFR_NUMERIC_OP},\r
33 { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP, EFI_IFR_ONE_OF_OPTION_OP},\r
34 { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP, EFI_IFR_ORDERED_LIST_OP}\r
35};\r
36\r
03254710 37/**\r
38 Translate a Framework Question Opcode to UEFI Question Opcode.\r
39\r
40 @param FwOp Framework Opcode.\r
41 @param UefiOp UEFI Opcode.\r
42\r
43 @retval EFI_SUCCESS The UEFI opcode is found and returned.\r
44 @retval EFI_NOT_FOUND The UEFI opcode is not found.\r
45**/\r
a9d85320 46EFI_STATUS\r
47QuestionOpFwToUefi (\r
48 IN UINT8 FwOp,\r
49 OUT UINT8 *UefiOp\r
50 )\r
51{\r
52 UINTN Index;\r
53\r
54 for (Index = 0; Index < sizeof (mQuestionOpcodeMap) / sizeof (mQuestionOpcodeMap[0]); Index++) {\r
55 if (FwOp == mQuestionOpcodeMap[Index].FrameworkIfrOp) {\r
56 *UefiOp = mQuestionOpcodeMap[Index].UefiIfrOp;\r
57 return EFI_SUCCESS;\r
58 }\r
59 }\r
60\r
e24d48ac 61 *UefiOp = (UINT8) (FRAMEWORK_EFI_IFR_LAST_OPCODE + 1);\r
a9d85320 62 return EFI_NOT_FOUND;\r
63}\r
64\r
03254710 65/**\r
66 Translate a Framework Question Opcode to UEFI Question Opcode.\r
67\r
68 @param FwOp Framework Opcode.\r
69 @param UefiOp UEFI Opcode.\r
a9d85320 70\r
03254710 71 @retval EFI_SUCCESS The UEFI opcode is found and returned.\r
72 @retval EFI_NOT_FOUND The UEFI opcode is not found.\r
73**/\r
a9d85320 74EFI_STATUS\r
75FwQIdToUefiQId (\r
76 IN CONST FORM_BROWSER_FORMSET *FormSet,\r
a9d85320 77 IN UINT8 FwOpCode,\r
78 IN UINT16 FwQId,\r
79 OUT UINT16 *UefiQId\r
80 )\r
81{\r
82 LIST_ENTRY *FormList;\r
83 LIST_ENTRY *StatementList;\r
84 FORM_BROWSER_FORM *Form;\r
85 FORM_BROWSER_STATEMENT *Statement;\r
03254710 86 FORM_BROWSER_STATEMENT *StatementFound;\r
a9d85320 87 EFI_STATUS Status;\r
88 UINT8 UefiOp;\r
03254710 89 \r
a9d85320 90\r
91 *UefiQId = 0;\r
03254710 92 StatementFound = NULL;\r
a9d85320 93\r
94 FormList = GetFirstNode (&FormSet->FormListHead);\r
95\r
96 while (!IsNull (&FormSet->FormListHead, FormList)) {\r
97 Form = FORM_BROWSER_FORM_FROM_LINK (FormList);\r
98\r
99 StatementList = GetFirstNode (&Form->StatementListHead);\r
100\r
101 while (!IsNull (&Form->StatementListHead, StatementList)) {\r
102 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);\r
103 if (Statement->VarStoreId != 0 && Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
104 if (FwQId == Statement->VarStoreInfo.VarOffset) {\r
105 Status = QuestionOpFwToUefi (FwOpCode, &UefiOp);\r
106 ASSERT_EFI_ERROR (Status);\r
107\r
03254710 108 if ((UefiOp == Statement->Operand) && (FormSet->DefaultVarStoreId == Statement->VarStoreId)) {\r
a9d85320 109 //\r
03254710 110 // If ASSERT here, the Framework VFR file has two Questions with all three attibutes the same:\r
111 // 1) Same Question Type, \r
112 // 2) Same Variable Storage\r
113 // 3) Refering to the Same offset in Variable Map (NvMap). \r
114 // This is ambigurity as FwQIdToUefiQId () can't find which UEFI Question \r
115 // ID to return. \r
a9d85320 116 //\r
03254710 117 // One possible solution is to remove the one of the duplicated questions in this Form Set.\r
a9d85320 118 //\r
03254710 119 ASSERT (StatementFound == NULL);\r
120 StatementFound= Statement;\r
a9d85320 121\r
03254710 122 //\r
123 // Continue the search to check if the Form Set contains more than one questins that has the 3 attributes\r
124 // with same value.\r
125 //\r
a9d85320 126 }\r
127 }\r
128 }\r
129\r
130 StatementList = GetNextNode (&Form->StatementListHead, StatementList);\r
131 }\r
132\r
133 FormList = GetNextNode (&FormSet->FormListHead, FormList);\r
134 }\r
03254710 135\r
136 if (StatementFound != NULL) {\r
137 *UefiQId = StatementFound->QuestionId;\r
138 return EFI_SUCCESS;\r
139 }\r
a9d85320 140 \r
141 return EFI_NOT_FOUND;\r
142}\r
143\r
03254710 144/**\r
145 Assign a Question ID.\r
146\r
147 If FwQuestionId is 0, then assign a new question ID. The new question ID\r
148 is MaxQuestionId incremented by 1. The MaxQuestionId of FormSet is also\r
149 incremented by 1.\r
150\r
151 If FwQuestionId is not 0, then it is used as the Framework Question ID.\r
152\r
153 @return The Framework Question ID.\r
154**/\r
8ea58c07 155EFI_QUESTION_ID\r
156AssignQuestionId (\r
a9d85320 157 IN UINT16 FwQuestionId,\r
158 IN FORM_BROWSER_FORMSET *FormSet\r
8ea58c07 159 )\r
160{\r
161 if (FwQuestionId == 0) {\r
a9d85320 162 FormSet->MaxQuestionId++;\r
163 return FormSet->MaxQuestionId;\r
8ea58c07 164 } else {\r
165 return FwQuestionId;\r
166 }\r
167}\r
0368663f 168\r
03254710 169/**\r
170 Create UEFI HII Text Opcode from a Framework HII Text Opcode.\r
171\r
a5420536
LG
172 @param FwOpcode The input Framework Opcode.\r
173 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
03254710 174\r
a5420536
LG
175 @retval NULL There is not enough space left in Buffer to add the opcode.\r
176 @retval Other A pointer to the created opcode.\r
03254710 177 \r
178**/\r
a5420536 179UINT8 *\r
5391c4f1 180F2UCreateTextOpCode (\r
a5420536
LG
181 IN OUT VOID *UefiUpdateDataHandle,\r
182 IN CONST FRAMEWORK_EFI_IFR_TEXT *FwOpcode\r
5391c4f1 183 )\r
184{\r
0368663f 185 EFI_IFR_TEXT UTextOpCode;\r
5391c4f1 186\r
03254710 187 if ((FwOpcode->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) == 0) {\r
0368663f 188 ZeroMem (&UTextOpCode, sizeof(UTextOpCode));\r
189 \r
190 UTextOpCode.Header.OpCode = EFI_IFR_TEXT_OP;\r
191 UTextOpCode.Header.Length = sizeof (EFI_IFR_TEXT);\r
5391c4f1 192\r
03254710 193 UTextOpCode.Statement.Help = FwOpcode->Help;\r
5391c4f1 194\r
03254710 195 UTextOpCode.Statement.Prompt = FwOpcode->Text;\r
196 UTextOpCode.TextTwo = FwOpcode->TextTwo;\r
0368663f 197 \r
54b44c4c 198 return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UTextOpCode, sizeof(UTextOpCode));\r
0368663f 199 } else {\r
200 //\r
201 // Iteractive Text Opcode is EFI_IFR_ACTION\r
202 //\r
a5420536 203 return HiiCreateActionOpCode (UefiUpdateDataHandle, FwOpcode->Key, FwOpcode->Text, FwOpcode->Help, EFI_IFR_FLAG_CALLBACK, 0);\r
0368663f 204 }\r
5391c4f1 205}\r
206\r
03254710 207/**\r
208 Create UEFI HII Reference Opcode from a Framework HII Reference Opcode.\r
209\r
a5420536
LG
210 @param FwOpcode The input Framework Opcode.\r
211 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
03254710 212\r
a5420536
LG
213 @retval NULL There is not enough space left in Buffer to add the opcode.\r
214 @retval Other A pointer to the created opcode.\r
03254710 215 \r
216**/\r
a5420536 217UINT8 *\r
03254710 218F2UCreateReferenceOpCode (\r
a5420536
LG
219 IN OUT VOID *UefiUpdateDataHandle,\r
220 IN CONST FRAMEWORK_EFI_IFR_REF *FwOpcode\r
5391c4f1 221 )\r
222{\r
223 EFI_IFR_REF UOpcode;\r
224\r
225 ZeroMem (&UOpcode, sizeof(UOpcode));\r
226\r
227 UOpcode.Header.Length = sizeof(UOpcode);\r
228 UOpcode.Header.OpCode = EFI_IFR_REF_OP;\r
229\r
230 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
231 UOpcode.Question.Header.Help = FwOpcode->Help;\r
232 UOpcode.Question.QuestionId = FwOpcode->Key;\r
233\r
234 UOpcode.FormId = FwOpcode->FormId;\r
235\r
236 //\r
237 // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to \r
238 // UEFI IFR Opcode flags. The rest flags are obsolete.\r
239 //\r
98b16b9d 240 UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
5391c4f1 241 \r
54b44c4c 242 return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
5391c4f1 243}\r
244\r
03254710 245/**\r
246 Create UEFI HII "One Of Option" Opcode from a Framework HII "One Of Option" Opcode.\r
247\r
a5420536
LG
248 @param FwOpcode The input Framework Opcode.\r
249 @param Width The size of the One Of Option. 1 bytes or 2 bytes.\r
250 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
03254710 251\r
a5420536
LG
252 @retval NULL There is not enough space left in Buffer to add the opcode.\r
253 @retval Other A pointer to the created opcode.\r
03254710 254 \r
255**/\r
a5420536 256UINT8 *\r
5391c4f1 257F2UCreateOneOfOptionOpCode (\r
a5420536 258 IN OUT VOID *UefiUpdateDataHandle,\r
5391c4f1 259 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOpcode,\r
a5420536 260 IN UINTN Width\r
5391c4f1 261 )\r
262{\r
263 EFI_IFR_ONE_OF_OPTION UOpcode;\r
264\r
265 ZeroMem (&UOpcode, sizeof(UOpcode));\r
266\r
267 UOpcode.Header.Length = sizeof(UOpcode);\r
268 UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;\r
269\r
270 UOpcode.Option = FwOpcode->Option;\r
271 CopyMem (&UOpcode.Value.u8, &FwOpcode->Value, Width);\r
272\r
273 //\r
03254710 274 // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT 0x01\r
275 // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING 0x02\r
276 // #define EFI_IFR_OPTION_DEFAULT 0x10\r
277 // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20\r
5391c4f1 278 //\r
98b16b9d 279 UOpcode.Flags = (UINT8) (UOpcode.Flags | (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING)) << 4);\r
5391c4f1 280\r
281 switch (Width) {\r
282 case 1:\r
283 UOpcode.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
284 break;\r
285 \r
286 case 2:\r
287 UOpcode.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
288 break;\r
289 \r
290 default:\r
291 ASSERT (FALSE);\r
a5420536 292 return NULL;\r
5391c4f1 293 }\r
294\r
54b44c4c 295 return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
5391c4f1 296}\r
297\r
03254710 298/**\r
299 Create a GUID Opcode EFI_IFR_GUID_OPTIONKEY to map the Framework One Of Option callback key\r
300 to a UEFI Question ID. This information is used to invoke the Framework HII Browser Callback\r
a5420536 301 function. The opcode is appened to UefiUpdateDataHandle.\r
03254710 302\r
a5420536
LG
303 @param QuestionId The UEFI Question ID.\r
304 @param OptionValue The value of the "One Of Option".\r
305 @param KeyValue The Framework "One Of Option" callback key.\r
306 @param UefiUpdateDataHandle The UEFI Update Data buffer.\r
03254710 307\r
a5420536
LG
308 @retval NULL There is not enough space left in Buffer to add the opcode.\r
309 @retval Other A pointer to the created opcode.\r
03254710 310**/\r
a5420536 311UINT8 *\r
a9d85320 312CreateGuidOptionKeyOpCode (\r
a5420536 313 IN OUT VOID *UefiUpdateDataHandle,\r
a9d85320 314 IN EFI_QUESTION_ID QuestionId,\r
315 IN UINT16 OptionValue,\r
a5420536 316 IN EFI_QUESTION_ID KeyValue\r
a9d85320 317 )\r
318{\r
a5420536 319 EFI_IFR_GUID_OPTIONKEY *UOpcode;\r
a9d85320 320 \r
a5420536
LG
321 UOpcode = (EFI_IFR_GUID_OPTIONKEY *) HiiCreateGuidOpCode (\r
322 UefiUpdateDataHandle, \r
323 &gEfiIfrFrameworkGuid, \r
324 NULL,\r
325 sizeof (EFI_IFR_GUID_OPTIONKEY)\r
326 );\r
327\r
328 UOpcode->ExtendOpCode = EFI_IFR_EXTEND_OP_OPTIONKEY;\r
329 UOpcode->QuestionId = QuestionId;\r
330 CopyMem (&UOpcode->OptionValue, &OptionValue, sizeof (OptionValue)); \r
331 UOpcode->KeyValue = KeyValue;\r
332\r
333 return (UINT8 *) UOpcode;\r
a9d85320 334}\r
5391c4f1 335\r
03254710 336/**\r
337 Create UEFI HII "One Of" Opcode from a Framework HII "One Of" Opcode.\r
338\r
a5420536
LG
339 @param ThunkContext The HII Thunk Context.\r
340 @param FwOpcode The input Framework Opcode.\r
341 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
342 @param NextFwOpcode Returns the position of the next Framework Opcode after FRAMEWORK_EFI_IFR_END_ONE_OF_OP of\r
343 the "One Of Option".\r
344 @param OpcodeCount The number of Opcode for the complete Framework "One Of" Opcode.\r
03254710 345 \r
a5420536
LG
346 @retval NULL There is not enough space left in Buffer to add the opcode.\r
347 @retval Other A pointer to the created opcode.\r
03254710 348 \r
349**/\r
a5420536 350UINT8 *\r
5391c4f1 351F2UCreateOneOfOpCode (\r
a5420536 352 IN OUT VOID *UefiUpdateDataHandle,\r
0368663f 353 IN HII_THUNK_CONTEXT *ThunkContext,\r
5391c4f1 354 IN CONST FRAMEWORK_EFI_IFR_ONE_OF *FwOpcode,\r
c64feb92 355 OUT FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
03254710 356 OUT UINTN *OpcodeCount\r
5391c4f1 357 )\r
358{\r
0368663f 359 EFI_STATUS Status;\r
360 EFI_IFR_ONE_OF UOpcode;\r
361 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
362 FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
a5420536
LG
363 UINT8 *OpCodeBuffer;\r
364 UINT8 *OneOfOpCodeBuffer;\r
5391c4f1 365\r
c64feb92 366 ASSERT (NextFwOpcode != NULL);\r
03254710 367 ASSERT (OpcodeCount != NULL);\r
c64feb92 368\r
5391c4f1 369 ZeroMem (&UOpcode, sizeof(UOpcode));\r
03254710 370 *OpcodeCount = 0;\r
5391c4f1 371\r
372 UOpcode.Header.Length = sizeof(UOpcode);\r
373 UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OP;\r
374 UOpcode.Header.Scope = 1;\r
375\r
376 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
377 UOpcode.Question.Header.Help = FwOpcode->Help;\r
03254710 378 UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
133a9dfb 379 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
380 \r
5391c4f1 381 //\r
382 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
383 //\r
5391c4f1 384 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
385 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
386 ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
387 \r
388 FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
0368663f 389 if ((FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
390 UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
391 \r
392 if (UOpcode.Question.QuestionId == 0) {\r
03254710 393 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 394 if (EFI_ERROR (Status)) {\r
a9d85320 395 UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
0368663f 396 }\r
133a9dfb 397 }\r
0368663f 398\r
0368663f 399 }\r
400\r
401 if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
402 UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
5391c4f1 403 }\r
404\r
405 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
406 }\r
407\r
0368663f 408\r
409 if (UOpcode.Question.QuestionId == 0) {\r
410 //\r
411 // Assign QuestionId if still not assigned.\r
412 //\r
03254710 413 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 414 if (EFI_ERROR (Status)) {\r
a9d85320 415 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
0368663f 416 }\r
417 }\r
418 \r
54b44c4c 419 OneOfOpCodeBuffer = HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof (UOpcode));\r
a5420536
LG
420 if (OneOfOpCodeBuffer == NULL) {\r
421 return NULL;\r
0368663f 422 }\r
03254710 423 *OpcodeCount += 1;\r
0368663f 424\r
5391c4f1 425 //\r
426 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.\r
427 //\r
428 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
429 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
a9d85320 430\r
431 FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
432 \r
a5420536
LG
433 OpCodeBuffer = F2UCreateOneOfOptionOpCode (UefiUpdateDataHandle, (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->Width);\r
434 if (OpCodeBuffer == NULL) {\r
435 return NULL;\r
5391c4f1 436 }\r
a9d85320 437\r
a5420536
LG
438 OpCodeBuffer = CreateGuidOptionKeyOpCode (UefiUpdateDataHandle, UOpcode.Question.QuestionId, FwOneOfOp->Value, FwOneOfOp->Key);\r
439 if (OpCodeBuffer == NULL) {\r
440 return NULL;\r
a9d85320 441 }\r
a5420536 442\r
c64feb92 443 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
03254710 444 *OpcodeCount += 1;\r
5391c4f1 445 }\r
446\r
a5420536
LG
447 OpCodeBuffer = HiiCreateEndOpCode (UefiUpdateDataHandle);\r
448 if (OpCodeBuffer != NULL) {\r
5391c4f1 449 *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
03254710 450 *OpcodeCount += 1;\r
5391c4f1 451 }\r
452\r
a5420536 453 return OneOfOpCodeBuffer;\r
5391c4f1 454}\r
455\r
03254710 456/**\r
457 Create UEFI HII "Ordered List" Opcode from a Framework HII "Ordered List" Opcode.\r
458\r
a5420536
LG
459 @param ThunkContext The HII Thunk Context.\r
460 @param FwOpcode The input Framework Opcode.\r
461 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
462 @param NextFwOpcode Returns the position of the next Framework Opcode after FRAMEWORK_EFI_IFR_END_ONE_OF_OP of\r
463 the "Ordered List".\r
464 @param OpcodeCount The number of Opcode for the complete Framework "Ordered List" Opcode.\r
03254710 465 \r
a5420536
LG
466 @retval NULL There is not enough space left in Buffer to add the opcode.\r
467 @retval Other A pointer to the created opcode.\r
03254710 468 \r
469**/\r
a5420536 470UINT8 *\r
5391c4f1 471F2UCreateOrderedListOpCode (\r
a5420536 472 IN OUT VOID *UefiUpdateDataHandle,\r
03254710 473 IN HII_THUNK_CONTEXT *ThunkContext,\r
5391c4f1 474 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST *FwOpcode,\r
03254710 475 OUT FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
476 OUT UINTN *OpcodeCount\r
5391c4f1 477 )\r
478{\r
479 EFI_IFR_ORDERED_LIST UOpcode;\r
480 EFI_STATUS Status;\r
481 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
a5420536
LG
482 FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
483 UINT8 *OpcodeBuffer; \r
484 UINT8 *OrderListOpCode;\r
5391c4f1 485\r
486 ZeroMem (&UOpcode, sizeof(UOpcode));\r
03254710 487 *OpcodeCount = 0;\r
5391c4f1 488\r
489 UOpcode.Header.Length = sizeof(UOpcode);\r
490 UOpcode.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;\r
491 UOpcode.Header.Scope = 1;\r
492\r
493 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
494 UOpcode.Question.Header.Help = FwOpcode->Help;\r
03254710 495 UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
133a9dfb 496 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
5391c4f1 497\r
498 UOpcode.MaxContainers = FwOpcode->MaxEntries;\r
0368663f 499\r
500 //\r
501 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
502 //\r
503 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
504 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
505 ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
506 \r
507 FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
508 if ((FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
509 UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
510 \r
511 if (UOpcode.Question.QuestionId == 0) {\r
03254710 512 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 513 if (EFI_ERROR (Status)) {\r
a9d85320 514 UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
0368663f 515 }\r
516\r
517 }\r
518 }\r
519\r
520 if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
521 UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
522 }\r
523\r
524 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
525 }\r
526\r
527 if (UOpcode.Question.QuestionId == 0) {\r
03254710 528 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 529 if (EFI_ERROR (Status)) {\r
a9d85320 530 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
0368663f 531 }\r
532 }\r
5391c4f1 533 \r
54b44c4c 534 OrderListOpCode = HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
a5420536
LG
535 if (OrderListOpCode == NULL) {\r
536 return NULL;\r
5391c4f1 537 }\r
03254710 538 *OpcodeCount += 1;\r
5391c4f1 539\r
540 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
541 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
0368663f 542 //\r
543 // Each entry of Order List in Framework HII is always 1 byte in size\r
544 //\r
a5420536
LG
545 OpcodeBuffer = F2UCreateOneOfOptionOpCode (UefiUpdateDataHandle, (CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, 1);\r
546 if (OpcodeBuffer == NULL) {\r
547 return NULL;\r
5391c4f1 548 }\r
c64feb92 549 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
03254710 550 *OpcodeCount += 1;\r
5391c4f1 551 }\r
552\r
a5420536
LG
553 OpcodeBuffer = HiiCreateEndOpCode (UefiUpdateDataHandle);\r
554 if (OpcodeBuffer != NULL) {\r
5391c4f1 555 *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
03254710 556 *OpcodeCount += 1;\r
5391c4f1 557 }\r
558\r
a5420536 559 return OrderListOpCode;\r
5391c4f1 560}\r
561\r
03254710 562/**\r
563 Create UEFI HII CheckBox Opcode from a Framework HII Checkbox Opcode.\r
5391c4f1 564\r
a5420536
LG
565 @param ThunkContext The HII Thunk Context.\r
566 @param FwOpcode The input Framework Opcode.\r
567 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
5391c4f1 568\r
a5420536
LG
569 @retval NULL There is not enough space left in Buffer to add the opcode.\r
570 @retval Other A pointer to the created opcode.\r
03254710 571 \r
572**/\r
a5420536 573UINT8 *\r
5391c4f1 574F2UCreateCheckBoxOpCode (\r
a5420536 575 IN OUT VOID *UefiUpdateDataHandle,\r
0368663f 576 IN HII_THUNK_CONTEXT *ThunkContext,\r
a5420536 577 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX *FwOpcode\r
5391c4f1 578 )\r
579{\r
0368663f 580 EFI_STATUS Status;\r
5391c4f1 581 EFI_IFR_CHECKBOX UOpcode;\r
582\r
583 ZeroMem (&UOpcode, sizeof(UOpcode));\r
584\r
585 UOpcode.Header.Length = sizeof(UOpcode);\r
586 UOpcode.Header.OpCode = EFI_IFR_CHECKBOX_OP;\r
587\r
588 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
589 UOpcode.Question.Header.Help = FwOpcode->Help;\r
590\r
0368663f 591 if (FwOpcode->Key == 0) {\r
03254710 592 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 593 if (EFI_ERROR (Status)) {\r
594 //\r
595 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
596 //\r
a9d85320 597 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
0368663f 598 }\r
599 } else {\r
600 UOpcode.Question.QuestionId = FwOpcode->Key;\r
601 }\r
602\r
5391c4f1 603 //\r
03254710 604 // We map 2 flags:\r
5391c4f1 605 // FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE, \r
606 // FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,\r
607 // to UEFI IFR Opcode Question flags. The rest flags are obsolete.\r
608 //\r
98b16b9d 609 UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
5391c4f1 610\r
03254710 611\r
612 UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
613 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
614\r
5391c4f1 615 //\r
03254710 616 // We also map these 2 flags:\r
0368663f 617 // FRAMEWORK_EFI_IFR_FLAG_DEFAULT, \r
618 // FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,\r
5391c4f1 619 // to UEFI IFR CheckBox Opcode default flags.\r
620 //\r
98b16b9d 621 UOpcode.Flags = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING));\r
5391c4f1 622\r
54b44c4c 623 return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
5391c4f1 624}\r
625\r
626\r
03254710 627/**\r
628 Create UEFI HII Numeric Opcode from a Framework HII Numeric Opcode.\r
5391c4f1 629\r
a5420536
LG
630 @param ThunkContext The HII Thunk Context.\r
631 @param FwOpcode The input Framework Opcode.\r
632 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
5391c4f1 633\r
a5420536
LG
634 @retval NULL There is not enough space left in Buffer to add the opcode.\r
635 @retval Other A pointer to the created opcode.\r
03254710 636 \r
637**/\r
a5420536 638UINT8 *\r
5391c4f1 639F2UCreateNumericOpCode (\r
a5420536 640 IN OUT VOID *UefiUpdateDataHandle,\r
a3318eaf 641 IN HII_THUNK_CONTEXT *ThunkContext,\r
a5420536 642 IN CONST FRAMEWORK_EFI_IFR_NUMERIC *FwOpcode\r
5391c4f1 643 )\r
644{\r
645 EFI_STATUS Status;\r
646 EFI_IFR_NUMERIC UOpcode;\r
647 EFI_IFR_DEFAULT UOpcodeDefault;\r
a5420536
LG
648 UINT8 *NumbericOpCode;\r
649 UINT8 *OpcodeBuffer;\r
5391c4f1 650\r
651 ZeroMem (&UOpcode, sizeof(UOpcode));\r
652\r
0368663f 653 if (FwOpcode->Key == 0) {\r
03254710 654 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 655 if (EFI_ERROR (Status)) {\r
656 //\r
657 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
658 //\r
a9d85320 659 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
0368663f 660 }\r
661 } else {\r
662 UOpcode.Question.QuestionId = FwOpcode->Key;\r
663 }\r
664\r
5391c4f1 665 UOpcode.Header.Length = sizeof(UOpcode);\r
666 UOpcode.Header.OpCode = EFI_IFR_NUMERIC_OP;\r
667 //\r
668 // We need to create a nested default value for the UEFI Numeric Opcode.\r
669 // So turn on the scope.\r
670 //\r
8ea58c07 671 UOpcode.Header.Scope = 1;\r
5391c4f1 672\r
673 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
674 UOpcode.Question.Header.Help = FwOpcode->Help;\r
675\r
03254710 676 UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
5391c4f1 677 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
678\r
98b16b9d 679 UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
5391c4f1 680\r
681 //\r
682 // Framework Numeric values are all in UINT16 and displayed as decimal.\r
683 //\r
684 UOpcode.data.u16.MinValue = FwOpcode->Minimum;\r
685 UOpcode.data.u16.MaxValue = FwOpcode->Maximum;\r
686 UOpcode.data.u16.Step = FwOpcode->Step;\r
687\r
688 switch (FwOpcode->Width) {\r
689 case 1: \r
690 {\r
8ea58c07 691 UOpcode.Flags = EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC; \r
5391c4f1 692 break;\r
693 } \r
694 case 2: \r
695 {\r
8ea58c07 696 UOpcode.Flags = EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC; \r
5391c4f1 697 break;\r
698 }\r
699 default: \r
700 {\r
701 ASSERT (FALSE);\r
a5420536 702 return NULL;\r
5391c4f1 703 }\r
704 }\r
705 \r
54b44c4c 706 NumbericOpCode = HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
a5420536
LG
707 if (NumbericOpCode == NULL) {\r
708 return NULL;\r
5391c4f1 709 }\r
710\r
711 //\r
f274810c 712 // We need to create a default value.\r
5391c4f1 713 //\r
8ea58c07 714 ZeroMem (&UOpcodeDefault, sizeof (UOpcodeDefault));\r
715 UOpcodeDefault.Header.Length = sizeof (UOpcodeDefault);\r
716 UOpcodeDefault.Header.OpCode = EFI_IFR_DEFAULT_OP;\r
5391c4f1 717\r
8ea58c07 718 UOpcodeDefault.DefaultId = 0;\r
5391c4f1 719\r
8ea58c07 720 switch (FwOpcode->Width) {\r
721 case 1: \r
722 {\r
723 UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
724 break;\r
725 } \r
726 case 2: \r
727 {\r
728 UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
729 break;\r
5391c4f1 730 }\r
8ea58c07 731 }\r
5391c4f1 732\r
8ea58c07 733 CopyMem (&UOpcodeDefault.Value.u8, &FwOpcode->Default, FwOpcode->Width);\r
5391c4f1 734\r
54b44c4c 735 OpcodeBuffer = HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcodeDefault, sizeof(UOpcodeDefault));\r
a5420536
LG
736 if (OpcodeBuffer == NULL) {\r
737 return NULL;\r
738 }\r
739\r
740 OpcodeBuffer = HiiCreateEndOpCode (UefiUpdateDataHandle);\r
741 if (OpcodeBuffer == NULL) {\r
742 return NULL;\r
5391c4f1 743 }\r
744\r
a5420536 745 return NumbericOpCode;\r
5391c4f1 746}\r
747\r
748\r
03254710 749/**\r
750 Create UEFI HII String Opcode from a Framework HII String Opcode.\r
5391c4f1 751\r
a5420536
LG
752 @param ThunkContext The HII Thunk Context.\r
753 @param FwOpcode The input Framework Opcode.\r
754 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
5391c4f1 755\r
a5420536
LG
756 @retval NULL There is not enough space left in Buffer to add the opcode.\r
757 @retval Other A pointer to the created opcode.\r
03254710 758 \r
759**/\r
a5420536 760UINT8 *\r
5391c4f1 761F2UCreateStringOpCode (\r
a5420536 762 IN OUT VOID *UefiUpdateDataHandle,\r
03254710 763 IN HII_THUNK_CONTEXT *ThunkContext,\r
a5420536 764 IN CONST FRAMEWORK_EFI_IFR_STRING *FwOpcode\r
5391c4f1 765 )\r
766{\r
767 EFI_IFR_STRING UOpcode;\r
a5420536 768 EFI_STATUS Status;\r
5391c4f1 769\r
770 ZeroMem (&UOpcode, sizeof(UOpcode));\r
771\r
0368663f 772 if (FwOpcode->Key == 0) {\r
a5420536
LG
773 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
774 if (EFI_ERROR (Status)) {\r
775 //\r
776 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
777 //\r
778 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
779 }\r
0368663f 780 } else {\r
781 UOpcode.Question.QuestionId = FwOpcode->Key;\r
782 }\r
783\r
5391c4f1 784 UOpcode.Header.Length = sizeof(UOpcode);\r
785 UOpcode.Header.OpCode = EFI_IFR_STRING_OP;\r
786\r
787 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
788 UOpcode.Question.Header.Help = FwOpcode->Help;\r
789\r
98b16b9d 790 UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
5391c4f1 791\r
03254710 792 UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
793 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
794\r
5391c4f1 795 UOpcode.MinSize = FwOpcode->MinSize;\r
796 UOpcode.MaxSize = FwOpcode->MaxSize;\r
797 UOpcode.Flags = EFI_IFR_STRING_MULTI_LINE;\r
798\r
54b44c4c 799 return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
5391c4f1 800}\r
801\r
03254710 802/**\r
803 Create UEFI HII Banner Opcode from a Framework HII Banner Opcode.\r
804\r
a5420536
LG
805 @param FwOpcode The input Framework Opcode.\r
806 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
5391c4f1 807\r
a5420536
LG
808 @retval NULL There is not enough space left in Buffer to add the opcode.\r
809 @retval Other A pointer to the created opcode.\r
03254710 810 \r
811**/\r
a5420536 812UINT8 *\r
5391c4f1 813F2UCreateBannerOpCode (\r
a5420536
LG
814 IN OUT VOID *UefiUpdateDataHandle,\r
815 IN CONST FRAMEWORK_EFI_IFR_BANNER *FwOpcode\r
5391c4f1 816 )\r
817{\r
a5420536 818 EFI_IFR_GUID_BANNER *UOpcode;\r
5391c4f1 819\r
a5420536
LG
820 UOpcode = (EFI_IFR_GUID_BANNER *) HiiCreateGuidOpCode (\r
821 UefiUpdateDataHandle, \r
822 &gEfiIfrTianoGuid, \r
823 NULL,\r
824 sizeof (EFI_IFR_GUID_BANNER)\r
825 ); \r
5391c4f1 826\r
a5420536
LG
827 UOpcode->ExtendOpCode = EFI_IFR_EXTEND_OP_BANNER;\r
828 UOpcode->Title = FwOpcode->Title;\r
829 UOpcode->LineNumber = FwOpcode->LineNumber;\r
830 UOpcode->Alignment = FwOpcode->Alignment;\r
5391c4f1 831\r
a5420536 832 return (UINT8 *) UOpcode;\r
5391c4f1 833}\r
834\r
03254710 835/**\r
a5420536 836 Create a Hii Update data Handle used to call IfrLibUpdateForm.\r
5391c4f1 837\r
a5420536
LG
838 @param ThunkContext The HII Thunk Context.\r
839 @param FwUpdateData The Framework Update Data.\r
840 @param UefiUpdateData The UEFI Update Data.\r
03254710 841\r
842 @retval EFI_SUCCESS The UEFI Update Data is created successfully.\r
843 @retval EFI_UNSUPPORTED There is unsupported opcode in FwUpdateData.\r
844 @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
845**/\r
a5420536 846EFI_STATUS \r
0368663f 847FwUpdateDataToUefiUpdateData (\r
2d630302 848 IN HII_THUNK_CONTEXT *ThunkContext,\r
849 IN CONST EFI_HII_UPDATE_DATA *FwUpdateData,\r
850 IN VOID *UefiOpCodeHandle\r
5391c4f1 851 )\r
852{\r
0368663f 853 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpCode;\r
854 FRAMEWORK_EFI_IFR_OP_HEADER *NextFwOpCode;\r
5391c4f1 855 UINTN Index;\r
c64feb92 856 UINTN DataCount;\r
a5420536 857 UINT8 *OpCodeBuffer;\r
5391c4f1 858\r
03254710 859 FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *) &FwUpdateData->Data;\r
5391c4f1 860\r
03254710 861 for (Index = 0; Index < FwUpdateData->DataCount; Index += DataCount) {\r
0368663f 862 switch (FwOpCode->OpCode) {\r
5391c4f1 863 case FRAMEWORK_EFI_IFR_SUBTITLE_OP:\r
a5420536 864 OpCodeBuffer = HiiCreateSubTitleOpCode (UefiOpCodeHandle, ((FRAMEWORK_EFI_IFR_SUBTITLE *) FwOpCode)->SubTitle, 0, 0, 0);\r
0368663f 865 DataCount = 1;\r
5391c4f1 866 break;\r
867 \r
868 case FRAMEWORK_EFI_IFR_TEXT_OP:\r
a5420536 869 OpCodeBuffer = F2UCreateTextOpCode (UefiOpCodeHandle, (FRAMEWORK_EFI_IFR_TEXT *) FwOpCode); \r
0368663f 870 DataCount = 1;\r
5391c4f1 871 break;\r
872\r
873 case FRAMEWORK_EFI_IFR_REF_OP:\r
a5420536 874 OpCodeBuffer = F2UCreateReferenceOpCode (UefiOpCodeHandle, (FRAMEWORK_EFI_IFR_REF *) FwOpCode); \r
0368663f 875 DataCount = 1;\r
5391c4f1 876 break;\r
877 \r
878 case FRAMEWORK_EFI_IFR_ONE_OF_OP:\r
a5420536
LG
879 OpCodeBuffer = F2UCreateOneOfOpCode (UefiOpCodeHandle, ThunkContext, (FRAMEWORK_EFI_IFR_ONE_OF *) FwOpCode, &NextFwOpCode, &DataCount);\r
880 if (OpCodeBuffer != NULL) {\r
0368663f 881 FwOpCode = NextFwOpCode;\r
5391c4f1 882 //\r
0368663f 883 // FwOpCode is already updated to point to the next opcode.\r
5391c4f1 884 //\r
885 continue;\r
886 }\r
887 break;\r
888\r
889 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP:\r
a5420536
LG
890 OpCodeBuffer = F2UCreateOrderedListOpCode (UefiOpCodeHandle, ThunkContext, (FRAMEWORK_EFI_IFR_ORDERED_LIST *) FwOpCode, &NextFwOpCode, &DataCount);\r
891 if (OpCodeBuffer != NULL) {\r
0368663f 892 FwOpCode = NextFwOpCode;\r
5391c4f1 893 //\r
0368663f 894 // FwOpCode is already updated to point to the next opcode.\r
5391c4f1 895 //\r
896 continue;\r
897 }\r
898 break;\r
899 \r
900 case FRAMEWORK_EFI_IFR_CHECKBOX_OP:\r
a5420536 901 OpCodeBuffer = F2UCreateCheckBoxOpCode (UefiOpCodeHandle, ThunkContext, (FRAMEWORK_EFI_IFR_CHECKBOX *) FwOpCode); \r
0368663f 902 DataCount = 1;\r
5391c4f1 903 break;\r
904\r
905 case FRAMEWORK_EFI_IFR_STRING_OP:\r
a5420536 906 OpCodeBuffer = F2UCreateStringOpCode (UefiOpCodeHandle, ThunkContext, (FRAMEWORK_EFI_IFR_STRING *) FwOpCode); \r
0368663f 907 DataCount = 1;\r
5391c4f1 908 break;\r
909\r
910 case FRAMEWORK_EFI_IFR_BANNER_OP:\r
a5420536 911 OpCodeBuffer = F2UCreateBannerOpCode (UefiOpCodeHandle, (FRAMEWORK_EFI_IFR_BANNER *) FwOpCode); \r
0368663f 912 DataCount = 1;\r
5391c4f1 913 break;\r
914\r
915 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP:\r
a5420536 916 OpCodeBuffer = HiiCreateEndOpCode (UefiOpCodeHandle);\r
0368663f 917 DataCount = 1;\r
5391c4f1 918 break;\r
0368663f 919\r
8ea58c07 920 case FRAMEWORK_EFI_IFR_NUMERIC_OP:\r
a5420536 921 OpCodeBuffer = F2UCreateNumericOpCode (UefiOpCodeHandle, ThunkContext, (FRAMEWORK_EFI_IFR_NUMERIC *) FwOpCode);\r
8ea58c07 922 DataCount = 1;\r
923 break;\r
924\r
5391c4f1 925 default:\r
926 ASSERT (FALSE);\r
927 return EFI_UNSUPPORTED;\r
928 }\r
929\r
a5420536
LG
930 if (OpCodeBuffer == NULL) {\r
931 return EFI_OUT_OF_RESOURCES;\r
5391c4f1 932 }\r
933\r
0368663f 934 FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpCode + FwOpCode->Length);\r
5391c4f1 935 }\r
936\r
5391c4f1 937 return EFI_SUCCESS;\r
938}\r
939\r