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