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