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