]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.c
1) Add a stringent check to make sure the package list for UpdateForm call must have...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / 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
15#include "HiiDatabase.h"\r
16#include "OpcodeCreation.h"\r
17#include "UefiIfrDefault.h"\r
18\r
19EFI_GUID mTianoExtendedOpcodeGuid = EFI_IFR_TIANO_GUID;\r
20\r
21#define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL 0x1000\r
22EFI_STATUS\r
23AppendToUpdateBuffer (\r
24 IN CONST UINT8 *OpCodeBuf,\r
25 IN UINTN BufSize,\r
26 OUT EFI_HII_UPDATE_DATA *UefiData\r
27 )\r
28{\r
29 UINT8 * NewBuff;\r
30 \r
31 if (UefiData->Offset + BufSize > UefiData->BufferSize) {\r
32 NewBuff = AllocateCopyPool (UefiData->BufferSize + LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL, UefiData->Data);\r
33 if (NewBuff == NULL) {\r
34 return EFI_OUT_OF_RESOURCES;\r
35 }\r
36 UefiData->BufferSize += LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
37 FreePool (UefiData->Data);\r
38 UefiData->Data = NewBuff;\r
39 }\r
40 \r
41 CopyMem (UefiData->Data + UefiData->Offset, OpCodeBuf, BufSize);\r
42 UefiData->Offset += (UINT32) BufSize;\r
43\r
44 return EFI_SUCCESS;\r
45}\r
46\r
8ea58c07 47EFI_QUESTION_ID\r
48AssignQuestionId (\r
49 IN UINT16 FwQuestionId\r
50 )\r
51{\r
52 if (FwQuestionId == 0) {\r
53 //\r
54 // In UEFI IFR, the Question ID can't be zero. Zero means no storage.\r
55 // So use 0xABBA as a Question ID.\r
56 //\r
57 return 0xABBA;\r
58 } else {\r
59 return FwQuestionId;\r
60 }\r
61}\r
0368663f 62\r
63\r
64EFI_STATUS\r
65FwQuestionIdToUefiQuestionId (\r
66 IN HII_THUNK_CONTEXT *ThunkContext,\r
67 IN UINT16 VarStoreId,\r
68 IN UINT16 FwId,\r
69 OUT EFI_QUESTION_ID *UefiQId\r
70 )\r
71{\r
72 LIST_ENTRY *MapEntryListHead;\r
73 LIST_ENTRY *Link;\r
74 QUESTION_ID_MAP_ENTRY *MapEntry;\r
75\r
76 MapEntryListHead = GetMapEntryListHead (ThunkContext, VarStoreId);\r
77 ASSERT (MapEntryListHead != NULL);\r
78\r
79 Link = GetFirstNode (MapEntryListHead);\r
80\r
81 while (!IsNull (MapEntryListHead, Link)) {\r
82 MapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link);\r
83\r
84 if (MapEntry->FwQId == FwId) {\r
85 *UefiQId = MapEntry->UefiQid;\r
86 return EFI_SUCCESS;\r
87 }\r
88\r
89 Link = GetNextNode (MapEntryListHead, Link);\r
90 }\r
91\r
92 return EFI_NOT_FOUND;\r
93}\r
94\r
95\r
96\r
5391c4f1 97EFI_STATUS\r
98UCreateEndOfOpcode (\r
99 OUT EFI_HII_UPDATE_DATA *UefiData\r
100 )\r
101{\r
102 EFI_IFR_END UOpcode;\r
103\r
104 ZeroMem (&UOpcode, sizeof (UOpcode));\r
105\r
106 UOpcode.Header.OpCode = EFI_IFR_END_OP;\r
107 UOpcode.Header.Length = sizeof (UOpcode);\r
108\r
109 return AppendToUpdateBuffer ((UINT8 *)&UOpcode, sizeof(UOpcode), UefiData);\r
110}\r
111\r
112EFI_STATUS\r
113F2UCreateSubtitleOpCode (\r
114 IN CONST FRAMEWORK_EFI_IFR_SUBTITLE *FwSubTitle,\r
115 OUT EFI_HII_UPDATE_DATA *UefiData\r
116 )\r
117{\r
118 EFI_IFR_SUBTITLE UOpcode;\r
119\r
120 ZeroMem (&UOpcode, sizeof(UOpcode));\r
121\r
122 UOpcode.Header.OpCode = EFI_IFR_SUBTITLE_OP;\r
123 UOpcode.Header.Length = sizeof (EFI_IFR_SUBTITLE);\r
124\r
125 UOpcode.Statement.Prompt = FwSubTitle->SubTitle;\r
126\r
127 return AppendToUpdateBuffer ((UINT8 *)&UOpcode, sizeof(UOpcode), UefiData);\r
128}\r
129\r
130EFI_STATUS\r
131F2UCreateTextOpCode (\r
132 IN CONST FRAMEWORK_EFI_IFR_TEXT *FwText,\r
133 OUT EFI_HII_UPDATE_DATA *UefiData\r
134 )\r
135{\r
0368663f 136 EFI_IFR_TEXT UTextOpCode;\r
137 EFI_IFR_ACTION UActionOpCode;\r
5391c4f1 138\r
0368663f 139 if ((FwText->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) == 0) {\r
140 ZeroMem (&UTextOpCode, sizeof(UTextOpCode));\r
141 \r
142 UTextOpCode.Header.OpCode = EFI_IFR_TEXT_OP;\r
143 UTextOpCode.Header.Length = sizeof (EFI_IFR_TEXT);\r
5391c4f1 144\r
0368663f 145 UTextOpCode.Statement.Help = FwText->Help;\r
5391c4f1 146\r
0368663f 147 UTextOpCode.Statement.Prompt = FwText->Text;\r
148 UTextOpCode.TextTwo = FwText->TextTwo;\r
149 \r
150 return AppendToUpdateBuffer ((UINT8 *) &UTextOpCode, sizeof(UTextOpCode), UefiData);\r
151 } else {\r
152 //\r
153 // Iteractive Text Opcode is EFI_IFR_ACTION\r
154 //\r
155\r
156 ZeroMem (&UActionOpCode, sizeof (UActionOpCode));\r
157\r
158 UActionOpCode.Header.OpCode = EFI_IFR_ACTION_OP;\r
159 UActionOpCode.Header.Length = sizeof (EFI_IFR_ACTION);\r
160\r
161 UActionOpCode.Question.Header.Prompt = FwText->Text;\r
162 UActionOpCode.Question.Header.Help = FwText->Help;\r
163 UActionOpCode.Question.Flags = EFI_IFR_FLAG_CALLBACK;\r
164 UActionOpCode.Question.QuestionId = FwText->Key;\r
165\r
166 return AppendToUpdateBuffer ((UINT8 *) &UActionOpCode, sizeof(UActionOpCode), UefiData);\r
167 \r
168 }\r
5391c4f1 169}\r
170\r
171/*\r
172typedef struct {\r
173 FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
174 UINT16 FormId;\r
175 STRING_REF Prompt;\r
176 STRING_REF Help; // The string Token for the context-help\r
177 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.\r
178 UINT16 Key; // Value to be passed to caller to identify this particular op-code\r
179} FRAMEWORK_EFI_IFR_REF;\r
180\r
181*/\r
182EFI_STATUS\r
183F2UCreateGotoOpCode (\r
184 IN CONST FRAMEWORK_EFI_IFR_REF *FwOpcode,\r
185 OUT EFI_HII_UPDATE_DATA *UefiData\r
186 )\r
187{\r
188 EFI_IFR_REF UOpcode;\r
189\r
190 ZeroMem (&UOpcode, sizeof(UOpcode));\r
191\r
192 UOpcode.Header.Length = sizeof(UOpcode);\r
193 UOpcode.Header.OpCode = EFI_IFR_REF_OP;\r
194\r
195 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
196 UOpcode.Question.Header.Help = FwOpcode->Help;\r
197 UOpcode.Question.QuestionId = FwOpcode->Key;\r
198\r
199 UOpcode.FormId = FwOpcode->FormId;\r
200\r
201 //\r
202 // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to \r
203 // UEFI IFR Opcode flags. The rest flags are obsolete.\r
204 //\r
205 UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
206 \r
207\r
208 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
209}\r
210\r
211\r
212/*\r
213typedef struct {\r
214 FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
215 STRING_REF Option; // The string token describing the option\r
216 UINT16 Value; // The value associated with this option that is stored in the NVRAM if chosen\r
217 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely above\r
218 UINT16 Key; // Value to be passed to caller to identify this particular op-code\r
219} FRAMEWORK_EFI_IFR_ONE_OF_OPTION;\r
220\r
221typedef union {\r
222 UINT8 u8;\r
223 UINT16 u16;\r
224 UINT32 u32;\r
225 UINT64 u64;\r
226 BOOLEAN b;\r
227 EFI_HII_TIME time;\r
228 EFI_HII_DATE date;\r
229 EFI_STRING_ID string;\r
230} EFI_IFR_TYPE_VALUE;\r
231\r
232typedef struct _EFI_IFR_ONE_OF_OPTION {\r
233 EFI_IFR_OP_HEADER Header;\r
234 EFI_STRING_ID Option;\r
235 UINT8 Flags;\r
236 UINT8 Type;\r
237 EFI_IFR_TYPE_VALUE Value;\r
238} EFI_IFR_ONE_OF_OPTION;\r
239\r
240*/\r
241EFI_STATUS\r
242F2UCreateOneOfOptionOpCode (\r
243 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOpcode,\r
244 IN UINTN Width,\r
245 OUT EFI_HII_UPDATE_DATA *UefiData\r
246 )\r
247{\r
248 EFI_IFR_ONE_OF_OPTION UOpcode;\r
249\r
250 ZeroMem (&UOpcode, sizeof(UOpcode));\r
251\r
252 UOpcode.Header.Length = sizeof(UOpcode);\r
253 UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;\r
254\r
255 UOpcode.Option = FwOpcode->Option;\r
256 CopyMem (&UOpcode.Value.u8, &FwOpcode->Value, Width);\r
257\r
258 //\r
259 \r
260 // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT 0x01\r
261 // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING 0x02\r
262 // #define EFI_IFR_OPTION_DEFAULT 0x10\r
263 // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20\r
264 //\r
265 UOpcode.Flags |= (UINT8) ((FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING)) << 4);\r
266\r
267 switch (Width) {\r
268 case 1:\r
269 UOpcode.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
270 break;\r
271 \r
272 case 2:\r
273 UOpcode.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
274 break;\r
275 \r
276 default:\r
277 ASSERT (FALSE);\r
278 return EFI_UNSUPPORTED;\r
279 }\r
280\r
281 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
282}\r
283\r
284\r
285/*\r
286typedef struct _EFI_IFR_QUESTION_HEADER {\r
287 EFI_IFR_STATEMENT_HEADER Header;\r
288 EFI_QUESTION_ID QuestionId;\r
289 EFI_VARSTORE_ID VarStoreId;\r
290 union {\r
291 EFI_STRING_ID VarName;\r
292 UINT16 VarOffset;\r
293 } VarStoreInfo;\r
294 UINT8 Flags;\r
295} EFI_IFR_QUESTION_HEADER;\r
296\r
297typedef union {\r
298 struct {\r
299 UINT8 MinValue;\r
300 UINT8 MaxValue;\r
301 UINT8 Step;\r
302 } u8;\r
303 struct {\r
304 UINT16 MinValue;\r
305 UINT16 MaxValue;\r
306 UINT16 Step;\r
307 } u16;\r
308 struct {\r
309 UINT32 MinValue;\r
310 UINT32 MaxValue;\r
311 UINT32 Step;\r
312 } u32;\r
313 struct {\r
314 UINT64 MinValue;\r
315 UINT64 MaxValue;\r
316 UINT64 Step;\r
317 } u64;\r
318} MINMAXSTEP_DATA;\r
319\r
320typedef struct _EFI_IFR_ONE_OF {\r
321 EFI_IFR_OP_HEADER Header;\r
322 EFI_IFR_QUESTION_HEADER Question;\r
323 UINT8 Flags;\r
324 MINMAXSTEP_DATA data;\r
325} EFI_IFR_ONE_OF;\r
326\r
327typedef struct {\r
328 FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
329 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name\r
330 UINT8 Width; // The Size of the Data being saved\r
331 STRING_REF Prompt; // The String Token for the Prompt\r
332 STRING_REF Help; // The string Token for the context-help\r
333} FRAMEWORK_EFI_IFR_ONE_OF;\r
334\r
335\r
336*/\r
337\r
338EFI_STATUS\r
339F2UCreateOneOfOpCode (\r
0368663f 340 IN HII_THUNK_CONTEXT *ThunkContext,\r
341 IN UINT16 VarStoreId,\r
5391c4f1 342 IN CONST FRAMEWORK_EFI_IFR_ONE_OF *FwOpcode,\r
343 OUT EFI_HII_UPDATE_DATA *UefiData,\r
c64feb92 344 OUT FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
345 OUT UINTN *DataCount\r
5391c4f1 346 )\r
347{\r
0368663f 348 EFI_STATUS Status;\r
349 EFI_IFR_ONE_OF UOpcode;\r
350 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
351 FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
352 ONE_OF_OPTION_MAP *OneOfOptionMap;\r
353 ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
5391c4f1 354\r
c64feb92 355 ASSERT (NextFwOpcode != NULL);\r
356 ASSERT (DataCount != NULL);\r
357\r
0368663f 358 OneOfOptionMap = NULL;\r
359\r
5391c4f1 360 ZeroMem (&UOpcode, sizeof(UOpcode));\r
c64feb92 361 *DataCount = 0;\r
5391c4f1 362\r
363 UOpcode.Header.Length = sizeof(UOpcode);\r
364 UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OP;\r
365 UOpcode.Header.Scope = 1;\r
366\r
367 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
368 UOpcode.Question.Header.Help = FwOpcode->Help;\r
133a9dfb 369 UOpcode.Question.VarStoreId = VarStoreId;\r
370 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
371 \r
5391c4f1 372 //\r
373 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
374 //\r
5391c4f1 375 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
376 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
377 ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
378 \r
379 FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
0368663f 380 if ((FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
381 UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
382 \r
383 if (UOpcode.Question.QuestionId == 0) {\r
384 Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
385 if (EFI_ERROR (Status)) {\r
8ea58c07 386 UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key);\r
0368663f 387 }\r
388\r
389 OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));\r
390 ASSERT (OneOfOptionMap != NULL);\r
391 OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;\r
392 OneOfOptionMap->QuestionId = UOpcode.Question.QuestionId;\r
393 InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);\r
394 switch (FwOpcode->Width) {\r
395 case 1:\r
396 OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_8;\r
397 break;\r
398 case 2:\r
399 OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_16;\r
8ea58c07 400 break;\r
0368663f 401 default:\r
402 ASSERT (FALSE);\r
403 break;\r
404 }\r
405\r
406 InsertTailList (&ThunkContext->OneOfOptionMapListHead, &OneOfOptionMap->Link);\r
133a9dfb 407 }\r
408 \r
409 OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));\r
410 ASSERT (OneOfOptionMapEntry != NULL);\r
0368663f 411\r
133a9dfb 412 OneOfOptionMapEntry->FwKey = FwOneOfOp->Key;\r
413 OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;\r
414 \r
415 CopyMem (&OneOfOptionMapEntry->Value, &FwOneOfOp->Value, FwOpcode->Width);\r
0368663f 416\r
133a9dfb 417 ASSERT (OneOfOptionMap != NULL);\r
418 InsertTailList (&OneOfOptionMap->OneOfOptionMapEntryListHead, &OneOfOptionMapEntry->Link);\r
0368663f 419 }\r
420\r
421 if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
422 UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
5391c4f1 423 }\r
424\r
425 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
426 }\r
427\r
0368663f 428\r
429 if (UOpcode.Question.QuestionId == 0) {\r
430 //\r
431 // Assign QuestionId if still not assigned.\r
432 //\r
433 Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
434 if (EFI_ERROR (Status)) {\r
8ea58c07 435 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);\r
0368663f 436 }\r
437 }\r
438 \r
439 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof (UOpcode), UefiData);\r
440 if (EFI_ERROR (Status)) {\r
441 return Status;\r
442 }\r
443 *DataCount += 1;\r
444\r
5391c4f1 445 //\r
446 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.\r
447 //\r
448 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
449 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
450 Status = F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->Width, UefiData);\r
451 if (EFI_ERROR (Status)) {\r
452 return Status;\r
453 }\r
c64feb92 454 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
455 *DataCount += 1;\r
5391c4f1 456 }\r
457\r
458 Status = UCreateEndOfOpcode (UefiData);\r
459 if (!EFI_ERROR (Status)) {\r
460 *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
c64feb92 461 *DataCount += 1;\r
5391c4f1 462 }\r
463\r
464 return Status;\r
465}\r
466\r
467/*\r
468typedef struct _EFI_IFR_QUESTION_HEADER {\r
469 EFI_IFR_STATEMENT_HEADER Header;\r
470 EFI_QUESTION_ID QuestionId;\r
471 EFI_VARSTORE_ID VarStoreId;\r
472 union {\r
473 EFI_STRING_ID VarName;\r
474 UINT16 VarOffset;\r
475 } VarStoreInfo;\r
476 UINT8 Flags;\r
477} EFI_IFR_QUESTION_HEADER;\r
478\r
479typedef struct _EFI_IFR_ORDERED_LIST {\r
480 EFI_IFR_OP_HEADER Header;\r
481 EFI_IFR_QUESTION_HEADER Question;\r
482 UINT8 MaxContainers;\r
483 UINT8 Flags;\r
484} EFI_IFR_ORDERED_LIST;\r
485\r
486typedef struct {\r
487 FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
488 UINT16 QuestionId; // The offset in NV for storage of the data\r
489 UINT8 MaxEntries; // The maximum number of options in the ordered list (=size of NVStore)\r
490 STRING_REF Prompt; // The string token for the prompt\r
491 STRING_REF Help; // The string token for the context-help\r
492} FRAMEWORK_EFI_IFR_ORDERED_LIST;\r
493\r
494*/\r
495EFI_STATUS\r
496F2UCreateOrderedListOpCode (\r
0368663f 497 IN HII_THUNK_CONTEXT *ThunkContext,\r
498 IN UINT16 VarStoreId,\r
5391c4f1 499 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST *FwOpcode,\r
500 OUT EFI_HII_UPDATE_DATA *UefiData,\r
c64feb92 501 OUT FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
502 OUT UINTN *DataCount\r
5391c4f1 503 )\r
504{\r
505 EFI_IFR_ORDERED_LIST UOpcode;\r
506 EFI_STATUS Status;\r
507 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
0368663f 508 FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
5391c4f1 509\r
510 ZeroMem (&UOpcode, sizeof(UOpcode));\r
c64feb92 511 *DataCount = 0;\r
5391c4f1 512\r
513 UOpcode.Header.Length = sizeof(UOpcode);\r
514 UOpcode.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;\r
515 UOpcode.Header.Scope = 1;\r
516\r
517 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
518 UOpcode.Question.Header.Help = FwOpcode->Help;\r
0368663f 519 UOpcode.Question.VarStoreId = VarStoreId;\r
133a9dfb 520 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
5391c4f1 521\r
522 UOpcode.MaxContainers = FwOpcode->MaxEntries;\r
0368663f 523\r
524 //\r
525 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
526 //\r
527 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
528 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
529 ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
530 \r
531 FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
532 if ((FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
533 UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
534 \r
535 if (UOpcode.Question.QuestionId == 0) {\r
536 Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
537 if (EFI_ERROR (Status)) {\r
8ea58c07 538 UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key);\r
0368663f 539 }\r
540\r
541 }\r
542 }\r
543\r
544 if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
545 UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
546 }\r
547\r
548 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
549 }\r
550\r
551 if (UOpcode.Question.QuestionId == 0) {\r
552 Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
553 if (EFI_ERROR (Status)) {\r
8ea58c07 554 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);\r
0368663f 555 }\r
556 }\r
5391c4f1 557 \r
558 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
559 if (EFI_ERROR (Status)) {\r
560 return Status;\r
561 }\r
c64feb92 562 *DataCount += 1;\r
5391c4f1 563\r
564 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
565 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
0368663f 566 //\r
567 // Each entry of Order List in Framework HII is always 1 byte in size\r
568 //\r
569 Status = F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, 1, UefiData);\r
5391c4f1 570 if (EFI_ERROR (Status)) {\r
571 return Status;\r
572 }\r
c64feb92 573 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
574 *DataCount += 1;\r
5391c4f1 575 }\r
576\r
577 Status = UCreateEndOfOpcode (UefiData);\r
578 if (!EFI_ERROR (Status)) {\r
579 *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
c64feb92 580 *DataCount += 1;\r
5391c4f1 581 }\r
582\r
c64feb92 583 return Status;\r
5391c4f1 584}\r
585\r
586/*\r
587typedef struct _EFI_IFR_QUESTION_HEADER {\r
588 EFI_IFR_STATEMENT_HEADER Header;\r
589 EFI_QUESTION_ID QuestionId;\r
590 EFI_VARSTORE_ID VarStoreId;\r
591 union {\r
592 EFI_STRING_ID VarName;\r
593 UINT16 VarOffset;\r
594 } VarStoreInfo;\r
595 UINT8 Flags;\r
596} EFI_IFR_QUESTION_HEADER;\r
597*/\r
598\r
599/*\r
600typedef struct _EFI_IFR_CHECKBOX {\r
601 EFI_IFR_OP_HEADER Header;\r
602 EFI_IFR_QUESTION_HEADER Question;\r
603 UINT8 Flags;\r
604} EFI_IFR_CHECKBOX;\r
605*/\r
606\r
607/*\r
608typedef struct {\r
609 FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
610 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name\r
611 UINT8 Width; // The Size of the Data being saved\r
612 STRING_REF Prompt; // The String Token for the Prompt\r
613 STRING_REF Help; // The string Token for the context-help\r
614 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely\r
615 UINT16 Key; // Value to be passed to caller to identify this particular op-code\r
616} FRAMEWORK_EFI_IFR_CHECKBOX, FRAMEWORK_EFI_IFR_CHECK_BOX;\r
617*/\r
618\r
619\r
620EFI_STATUS\r
621F2UCreateCheckBoxOpCode (\r
0368663f 622 IN HII_THUNK_CONTEXT *ThunkContext,\r
623 IN UINT16 VarStoreId,\r
5391c4f1 624 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX *FwOpcode,\r
625 OUT EFI_HII_UPDATE_DATA *UefiData\r
626 )\r
627{\r
0368663f 628 EFI_STATUS Status;\r
5391c4f1 629 EFI_IFR_CHECKBOX UOpcode;\r
630\r
631 ZeroMem (&UOpcode, sizeof(UOpcode));\r
632\r
633 UOpcode.Header.Length = sizeof(UOpcode);\r
634 UOpcode.Header.OpCode = EFI_IFR_CHECKBOX_OP;\r
635\r
636 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
637 UOpcode.Question.Header.Help = FwOpcode->Help;\r
638\r
0368663f 639 if (FwOpcode->Key == 0) {\r
640 Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
641 if (EFI_ERROR (Status)) {\r
642 //\r
643 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
644 //\r
8ea58c07 645 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);\r
0368663f 646 }\r
647 } else {\r
648 UOpcode.Question.QuestionId = FwOpcode->Key;\r
649 }\r
650\r
5391c4f1 651 UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID;\r
652 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
653\r
654 //\r
655 // We only map 2 flags:\r
656 // FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE, \r
657 // FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,\r
658 // to UEFI IFR Opcode Question flags. The rest flags are obsolete.\r
659 //\r
660 UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
661\r
662 //\r
663 // We also map 2 flags:\r
0368663f 664 // FRAMEWORK_EFI_IFR_FLAG_DEFAULT, \r
665 // FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,\r
5391c4f1 666 // to UEFI IFR CheckBox Opcode default flags.\r
667 //\r
668 UOpcode.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING));\r
669\r
670 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
671}\r
672\r
673\r
674/*\r
675typedef struct _EFI_IFR_QUESTION_HEADER {\r
676 EFI_IFR_STATEMENT_HEADER Header;\r
677 EFI_QUESTION_ID QuestionId;\r
678 EFI_VARSTORE_ID VarStoreId;\r
679 union {\r
680 EFI_STRING_ID VarName;\r
681 UINT16 VarOffset;\r
682 } VarStoreInfo;\r
683 UINT8 Flags;\r
684} EFI_IFR_QUESTION_HEADER;\r
685\r
686typedef union {\r
687 struct {\r
688 UINT8 MinValue;\r
689 UINT8 MaxValue;\r
690 UINT8 Step;\r
691 } u8;\r
692 struct {\r
693 UINT16 MinValue;\r
694 UINT16 MaxValue;\r
695 UINT16 Step;\r
696 } u16;\r
697 struct {\r
698 UINT32 MinValue;\r
699 UINT32 MaxValue;\r
700 UINT32 Step;\r
701 } u32;\r
702 struct {\r
703 UINT64 MinValue;\r
704 UINT64 MaxValue;\r
705 UINT64 Step;\r
706 } u64;\r
707} MINMAXSTEP_DATA;\r
708\r
709typedef struct _EFI_IFR_NUMERIC {\r
710 EFI_IFR_OP_HEADER Header;\r
711 EFI_IFR_QUESTION_HEADER Question;\r
712 UINT8 Flags;\r
713 MINMAXSTEP_DATA data;\r
714} EFI_IFR_NUMERIC;\r
715\r
716\r
717typedef struct {\r
718 FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
719 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name\r
720 UINT8 Width; // The Size of the Data being saved\r
721 STRING_REF Prompt; // The String Token for the Prompt\r
722 STRING_REF Help; // The string Token for the context-help\r
723 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.\r
724 UINT16 Key; // Value to be passed to caller to identify this particular op-code\r
725 UINT16 Minimum;\r
726 UINT16 Maximum;\r
727 UINT16 Step; // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for\r
728 UINT16 Default;\r
729} FRAMEWORK_EFI_IFR_NUMERIC;\r
730\r
731*/\r
732\r
733\r
734EFI_STATUS\r
735F2UCreateNumericOpCode (\r
a3318eaf 736 IN HII_THUNK_CONTEXT *ThunkContext,\r
0368663f 737 IN UINT16 VarStoreId,\r
5391c4f1 738 IN CONST FRAMEWORK_EFI_IFR_NUMERIC *FwOpcode,\r
739 OUT EFI_HII_UPDATE_DATA *UefiData\r
740 )\r
741{\r
742 EFI_STATUS Status;\r
743 EFI_IFR_NUMERIC UOpcode;\r
744 EFI_IFR_DEFAULT UOpcodeDefault;\r
745\r
746 ZeroMem (&UOpcode, sizeof(UOpcode));\r
747\r
0368663f 748 if (FwOpcode->Key == 0) {\r
749 Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
750 if (EFI_ERROR (Status)) {\r
751 //\r
752 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
753 //\r
8ea58c07 754 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId);\r
0368663f 755 }\r
756 } else {\r
757 UOpcode.Question.QuestionId = FwOpcode->Key;\r
758 }\r
759\r
5391c4f1 760 UOpcode.Header.Length = sizeof(UOpcode);\r
761 UOpcode.Header.OpCode = EFI_IFR_NUMERIC_OP;\r
762 //\r
763 // We need to create a nested default value for the UEFI Numeric Opcode.\r
764 // So turn on the scope.\r
765 //\r
8ea58c07 766 UOpcode.Header.Scope = 1;\r
5391c4f1 767\r
768 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
769 UOpcode.Question.Header.Help = FwOpcode->Help;\r
770\r
a3318eaf 771 UOpcode.Question.VarStoreId = VarStoreId;\r
5391c4f1 772 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
773\r
774 UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
775\r
776 //\r
777 // Framework Numeric values are all in UINT16 and displayed as decimal.\r
778 //\r
779 UOpcode.data.u16.MinValue = FwOpcode->Minimum;\r
780 UOpcode.data.u16.MaxValue = FwOpcode->Maximum;\r
781 UOpcode.data.u16.Step = FwOpcode->Step;\r
782\r
783 switch (FwOpcode->Width) {\r
784 case 1: \r
785 {\r
8ea58c07 786 UOpcode.Flags = EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC; \r
5391c4f1 787 break;\r
788 } \r
789 case 2: \r
790 {\r
8ea58c07 791 UOpcode.Flags = EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC; \r
5391c4f1 792 break;\r
793 }\r
794 default: \r
795 {\r
796 ASSERT (FALSE);\r
797 return EFI_INVALID_PARAMETER;\r
798 }\r
799 }\r
800 \r
801 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
802 if (EFI_ERROR (Status)) {\r
803 return Status;\r
804 }\r
805\r
806 //\r
f274810c 807 // We need to create a default value.\r
5391c4f1 808 //\r
8ea58c07 809 ZeroMem (&UOpcodeDefault, sizeof (UOpcodeDefault));\r
810 UOpcodeDefault.Header.Length = sizeof (UOpcodeDefault);\r
811 UOpcodeDefault.Header.OpCode = EFI_IFR_DEFAULT_OP;\r
5391c4f1 812\r
8ea58c07 813 UOpcodeDefault.DefaultId = 0;\r
5391c4f1 814\r
8ea58c07 815 switch (FwOpcode->Width) {\r
816 case 1: \r
817 {\r
818 UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
819 break;\r
820 } \r
821 case 2: \r
822 {\r
823 UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
824 break;\r
5391c4f1 825 }\r
8ea58c07 826 }\r
5391c4f1 827\r
8ea58c07 828 CopyMem (&UOpcodeDefault.Value.u8, &FwOpcode->Default, FwOpcode->Width);\r
5391c4f1 829\r
8ea58c07 830 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcodeDefault, sizeof(UOpcodeDefault), UefiData);\r
831 if (EFI_ERROR (Status)) {\r
832 return Status;\r
5391c4f1 833 }\r
8ea58c07 834 Status = UCreateEndOfOpcode (UefiData);\r
5391c4f1 835\r
836 return Status;\r
837}\r
838\r
839\r
840/*\r
841\r
842typedef struct _EFI_IFR_QUESTION_HEADER {\r
843 EFI_IFR_STATEMENT_HEADER Header;\r
844 EFI_QUESTION_ID QuestionId;\r
845 EFI_VARSTORE_ID VarStoreId;\r
846 union {\r
847 EFI_STRING_ID VarName;\r
848 UINT16 VarOffset;\r
849 } VarStoreInfo;\r
850 UINT8 Flags;\r
851} EFI_IFR_QUESTION_HEADER;\r
852\r
853typedef struct _EFI_IFR_STRING {\r
854 EFI_IFR_OP_HEADER Header;\r
855 EFI_IFR_QUESTION_HEADER Question;\r
856 UINT8 MinSize;\r
857 UINT8 MaxSize;\r
858 UINT8 Flags;\r
859} EFI_IFR_STRING;\r
860\r
861\r
862typedef struct {\r
863 FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
864 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name\r
865 UINT8 Width; // The Size of the Data being saved -- BUGBUG -- remove someday\r
866 STRING_REF Prompt; // The String Token for the Prompt\r
867 STRING_REF Help; // The string Token for the context-help\r
868 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.\r
869 UINT16 Key; // Value to be passed to caller to identify this particular op-code\r
870 UINT8 MinSize; // Minimum allowable sized password\r
871 UINT8 MaxSize; // Maximum allowable sized password\r
872} FRAMEWORK_EFI_IFR_STRING;\r
873\r
874\r
875*/\r
876\r
877EFI_STATUS\r
878F2UCreateStringOpCode (\r
0368663f 879 IN HII_THUNK_CONTEXT *ThunkContext,\r
880 IN UINT16 VarStoreId,\r
5391c4f1 881 IN CONST FRAMEWORK_EFI_IFR_STRING *FwOpcode,\r
882 OUT EFI_HII_UPDATE_DATA *UefiData\r
883 )\r
884{\r
885 EFI_IFR_STRING UOpcode;\r
886\r
887 ZeroMem (&UOpcode, sizeof(UOpcode));\r
888\r
0368663f 889 if (FwOpcode->Key == 0) {\r
890 FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
891 } else {\r
892 UOpcode.Question.QuestionId = FwOpcode->Key;\r
893 }\r
894\r
5391c4f1 895 UOpcode.Header.Length = sizeof(UOpcode);\r
896 UOpcode.Header.OpCode = EFI_IFR_STRING_OP;\r
897\r
898 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
899 UOpcode.Question.Header.Help = FwOpcode->Help;\r
900\r
901 UOpcode.Question.QuestionId = FwOpcode->Key;\r
902 UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID;\r
903 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
904\r
905 UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
906\r
907 UOpcode.MinSize = FwOpcode->MinSize;\r
908 UOpcode.MaxSize = FwOpcode->MaxSize;\r
909 UOpcode.Flags = EFI_IFR_STRING_MULTI_LINE;\r
910\r
911 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
912}\r
913\r
914/*\r
915typedef struct _EFI_IFR_GUID_BANNER {\r
916 EFI_IFR_OP_HEADER Header;\r
917 EFI_GUID Guid;\r
918 UINT8 ExtendOpCode; // Extended opcode is EFI_IFR_EXTEND_OP_BANNER\r
919 EFI_STRING_ID Title; // The string token for the banner title\r
920 UINT16 LineNumber; // 1-based line number\r
921 UINT8 Alignment; // left, center, or right-aligned\r
922} EFI_IFR_GUID_BANNER;\r
923\r
924typedef struct {\r
925 FRAMEWORK_EFI_IFR_OP_HEADER Header;\r
926 STRING_REF Title; // The string token for the banner title\r
927 UINT16 LineNumber; // 1-based line number\r
928 UINT8 Alignment; // left, center, or right-aligned\r
929} FRAMEWORK_EFI_IFR_BANNER;\r
930\r
931*/\r
932\r
933EFI_STATUS\r
934F2UCreateBannerOpCode (\r
935 IN CONST FRAMEWORK_EFI_IFR_BANNER *FwOpcode,\r
936 OUT EFI_HII_UPDATE_DATA *UefiData\r
937 )\r
938{\r
939 EFI_IFR_GUID_BANNER UOpcode;\r
940\r
941 ZeroMem (&UOpcode, sizeof(UOpcode));\r
942\r
943 UOpcode.Header.Length = sizeof(UOpcode);\r
944 UOpcode.Header.OpCode = EFI_IFR_GUID_OP;\r
945\r
946 CopyMem (&UOpcode.Guid, &mTianoExtendedOpcodeGuid, sizeof (EFI_GUID));\r
947 UOpcode.ExtendOpCode = EFI_IFR_EXTEND_OP_BANNER;\r
948 UOpcode.Title = FwOpcode->Title;\r
949 UOpcode.LineNumber = FwOpcode->LineNumber;\r
950 UOpcode.Alignment = FwOpcode->Alignment;\r
951\r
952 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);\r
953}\r
954\r
955\r
5391c4f1 956EFI_STATUS\r
0368663f 957FwUpdateDataToUefiUpdateData (\r
958 IN HII_THUNK_CONTEXT *ThunkContext,\r
5391c4f1 959 IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA *Data,\r
960 IN BOOLEAN AddData,\r
961 OUT EFI_HII_UPDATE_DATA **UefiData\r
962 )\r
963{\r
0368663f 964 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpCode;\r
965 FRAMEWORK_EFI_IFR_OP_HEADER *NextFwOpCode;\r
966 EFI_HII_UPDATE_DATA *UefiOpCode;\r
5391c4f1 967 UINTN Index;\r
968 EFI_STATUS Status;\r
c64feb92 969 UINTN DataCount;\r
0368663f 970 UINT16 VarStoreId;\r
5391c4f1 971\r
0368663f 972 //\r
973 // Assume all dynamic opcode created is using active variable with VarStoreId of 1.\r
974 //\r
975 VarStoreId = 1;\r
5391c4f1 976\r
0368663f 977 UefiOpCode = AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA));\r
978 if (UefiOpCode == NULL) {\r
5391c4f1 979 return EFI_OUT_OF_RESOURCES;\r
980 }\r
981 \r
0368663f 982 UefiOpCode->Data = AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL);\r
983 if (UefiOpCode->Data == NULL) {\r
5391c4f1 984 return EFI_OUT_OF_RESOURCES;\r
985 }\r
986\r
0368663f 987 UefiOpCode->BufferSize = LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
988 UefiOpCode->Offset = 0;\r
5391c4f1 989\r
0368663f 990 FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *) &Data->Data;\r
5391c4f1 991\r
c64feb92 992 for (Index = 0; Index < Data->DataCount; Index += DataCount) {\r
0368663f 993 switch (FwOpCode->OpCode) {\r
5391c4f1 994 case FRAMEWORK_EFI_IFR_SUBTITLE_OP:\r
0368663f 995 Status = F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE *) FwOpCode, UefiOpCode);\r
996 DataCount = 1;\r
5391c4f1 997 break;\r
998 \r
999 case FRAMEWORK_EFI_IFR_TEXT_OP:\r
0368663f 1000 Status = F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT *) FwOpCode, UefiOpCode); \r
1001 DataCount = 1;\r
5391c4f1 1002 break;\r
1003\r
1004 case FRAMEWORK_EFI_IFR_REF_OP:\r
0368663f 1005 Status = F2UCreateGotoOpCode ((FRAMEWORK_EFI_IFR_REF *) FwOpCode, UefiOpCode); \r
1006 DataCount = 1;\r
5391c4f1 1007 break;\r
1008 \r
1009 case FRAMEWORK_EFI_IFR_ONE_OF_OP:\r
0368663f 1010 Status = F2UCreateOneOfOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_ONE_OF *) FwOpCode, UefiOpCode, &NextFwOpCode, &DataCount);\r
5391c4f1 1011 if (!EFI_ERROR (Status)) {\r
0368663f 1012 FwOpCode = NextFwOpCode;\r
5391c4f1 1013 //\r
0368663f 1014 // FwOpCode is already updated to point to the next opcode.\r
5391c4f1 1015 //\r
1016 continue;\r
1017 }\r
1018 break;\r
1019\r
1020 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP:\r
0368663f 1021 Status = F2UCreateOrderedListOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_ORDERED_LIST *) FwOpCode, UefiOpCode, &NextFwOpCode, &DataCount);\r
5391c4f1 1022 if (!EFI_ERROR (Status)) {\r
0368663f 1023 FwOpCode = NextFwOpCode;\r
5391c4f1 1024 //\r
0368663f 1025 // FwOpCode is already updated to point to the next opcode.\r
5391c4f1 1026 //\r
1027 continue;\r
1028 }\r
1029 break;\r
1030 \r
1031 case FRAMEWORK_EFI_IFR_CHECKBOX_OP:\r
0368663f 1032 Status = F2UCreateCheckBoxOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_CHECKBOX *) FwOpCode, UefiOpCode); \r
1033 DataCount = 1;\r
5391c4f1 1034 break;\r
1035\r
1036 case FRAMEWORK_EFI_IFR_STRING_OP:\r
0368663f 1037 Status = F2UCreateStringOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_STRING *) FwOpCode, UefiOpCode); \r
1038 DataCount = 1;\r
5391c4f1 1039 break;\r
1040\r
1041 case FRAMEWORK_EFI_IFR_BANNER_OP:\r
0368663f 1042 Status = F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER *) FwOpCode, UefiOpCode); \r
1043 DataCount = 1;\r
5391c4f1 1044 break;\r
1045\r
1046 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP:\r
0368663f 1047 Status = UCreateEndOfOpcode (UefiOpCode);\r
1048 DataCount = 1;\r
5391c4f1 1049 break;\r
0368663f 1050\r
8ea58c07 1051 case FRAMEWORK_EFI_IFR_NUMERIC_OP:\r
1052 Status = F2UCreateNumericOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_NUMERIC *) FwOpCode, UefiOpCode);\r
1053 DataCount = 1;\r
1054 break;\r
1055\r
5391c4f1 1056 default:\r
1057 ASSERT (FALSE);\r
1058 return EFI_UNSUPPORTED;\r
1059 }\r
1060\r
1061 if (EFI_ERROR (Status)) {\r
0368663f 1062 FreePool (UefiOpCode->Data);\r
1063 FreePool (UefiOpCode);\r
5391c4f1 1064 return Status;\r
1065 }\r
1066\r
0368663f 1067 FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpCode + FwOpCode->Length);\r
5391c4f1 1068 }\r
1069\r
0368663f 1070 *UefiData = UefiOpCode;\r
5391c4f1 1071 \r
1072 return EFI_SUCCESS;\r
1073}\r
1074\r