2 Implement Functions to convert IFR Opcode in format defined in Framework HII specification to
3 format defined in UEFI HII Specification.
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
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.
16 #include "HiiDatabase.h"
17 #include "UefiIfrDefault.h"
19 EFI_GUID mTianoExtendedOpcodeGuid
= EFI_IFR_TIANO_GUID
;
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
,
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.
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
}
50 Translate a Framework Question Opcode to UEFI Question Opcode.
52 @param FwOp Framework Opcode.
53 @param UefiOp UEFI Opcode.
55 @retval EFI_SUCCESS The UEFI opcode is found and returned.
56 @retval EFI_NOT_FOUND The UEFI opcode is not found.
66 for (Index
= 0; Index
< sizeof (mQuestionOpcodeMap
) / sizeof (mQuestionOpcodeMap
[0]); Index
++) {
67 if (FwOp
== mQuestionOpcodeMap
[Index
].FrameworkIfrOp
) {
68 *UefiOp
= mQuestionOpcodeMap
[Index
].UefiIfrOp
;
73 *UefiOp
= (UINT8
) (FRAMEWORK_EFI_IFR_LAST_OPCODE
+ 1);
78 Translate a Framework Question Opcode to UEFI Question Opcode.
80 @param FwOp Framework Opcode.
81 @param UefiOp UEFI Opcode.
83 @retval EFI_SUCCESS The UEFI opcode is found and returned.
84 @retval EFI_NOT_FOUND The UEFI opcode is not found.
88 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
95 LIST_ENTRY
*StatementList
;
96 FORM_BROWSER_FORM
*Form
;
97 FORM_BROWSER_STATEMENT
*Statement
;
98 FORM_BROWSER_STATEMENT
*StatementFound
;
104 StatementFound
= NULL
;
106 FormList
= GetFirstNode (&FormSet
->FormListHead
);
108 while (!IsNull (&FormSet
->FormListHead
, FormList
)) {
109 Form
= FORM_BROWSER_FORM_FROM_LINK (FormList
);
111 StatementList
= GetFirstNode (&Form
->StatementListHead
);
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
);
120 if ((UefiOp
== Statement
->Operand
) && (FormSet
->DefaultVarStoreId
== Statement
->VarStoreId
)) {
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
129 // One possible solution is to remove the one of the duplicated questions in this Form Set.
131 ASSERT (StatementFound
== NULL
);
132 StatementFound
= Statement
;
135 // Continue the search to check if the Form Set contains more than one questins that has the 3 attributes
142 StatementList
= GetNextNode (&Form
->StatementListHead
, StatementList
);
145 FormList
= GetNextNode (&FormSet
->FormListHead
, FormList
);
148 if (StatementFound
!= NULL
) {
149 *UefiQId
= StatementFound
->QuestionId
;
153 return EFI_NOT_FOUND
;
158 #define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL 0x1000
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
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.
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.
174 AppendToUpdateBuffer (
175 IN CONST UINT8
*OpCodeBuf
,
176 IN UINTN OpCodeBufSize
,
177 IN OUT EFI_HII_UPDATE_DATA
*UefiUpdateData
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
;
187 UefiUpdateData
->BufferSize
+= LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
;
188 FreePool (UefiUpdateData
->Data
);
189 UefiUpdateData
->Data
= NewBuff
;
192 CopyMem (UefiUpdateData
->Data
+ UefiUpdateData
->Offset
, OpCodeBuf
, OpCodeBufSize
);
193 UefiUpdateData
->Offset
+= (UINT32
) OpCodeBufSize
;
199 Assign a Question ID.
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
205 If FwQuestionId is not 0, then it is used as the Framework Question ID.
207 @return The Framework Question ID.
211 IN UINT16 FwQuestionId
,
212 IN FORM_BROWSER_FORMSET
*FormSet
215 if (FwQuestionId
== 0) {
216 FormSet
->MaxQuestionId
++;
217 return FormSet
->MaxQuestionId
;
224 Create UEFI HII "End Of" Opcode and append it to UefiUpdateData buffer.
226 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.
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.
234 IN OUT EFI_HII_UPDATE_DATA
*UefiUpdateData
239 ZeroMem (&UOpcode
, sizeof (UOpcode
));
241 UOpcode
.Header
.OpCode
= EFI_IFR_END_OP
;
242 UOpcode
.Header
.Length
= sizeof (UOpcode
);
244 return AppendToUpdateBuffer ((UINT8
*)&UOpcode
, sizeof(UOpcode
), UefiUpdateData
);
248 Create UEFI HII Subtitle Opcode from a Framework HII Subtitle Opcode.
250 @param FwOpcode The input Framework Opcode.
251 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.
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.
258 F2UCreateSubtitleOpCode (
259 IN CONST FRAMEWORK_EFI_IFR_SUBTITLE
*FwOpcode
,
260 IN OUT EFI_HII_UPDATE_DATA
*UefiUpdateData
263 EFI_IFR_SUBTITLE UOpcode
;
265 ZeroMem (&UOpcode
, sizeof(UOpcode
));
267 UOpcode
.Header
.OpCode
= EFI_IFR_SUBTITLE_OP
;
268 UOpcode
.Header
.Length
= sizeof (EFI_IFR_SUBTITLE
);
270 UOpcode
.Statement
.Prompt
= FwOpcode
->SubTitle
;
272 return AppendToUpdateBuffer ((UINT8
*)&UOpcode
, sizeof(UOpcode
), UefiUpdateData
);
276 Create UEFI HII Text Opcode from a Framework HII Text Opcode.
278 @param FwOpcode The input Framework Opcode.
279 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.
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.
286 F2UCreateTextOpCode (
287 IN CONST FRAMEWORK_EFI_IFR_TEXT
*FwOpcode
,
288 IN OUT EFI_HII_UPDATE_DATA
*UefiUpdateData
291 EFI_IFR_TEXT UTextOpCode
;
292 EFI_IFR_ACTION UActionOpCode
;
294 if ((FwOpcode
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) == 0) {
295 ZeroMem (&UTextOpCode
, sizeof(UTextOpCode
));
297 UTextOpCode
.Header
.OpCode
= EFI_IFR_TEXT_OP
;
298 UTextOpCode
.Header
.Length
= sizeof (EFI_IFR_TEXT
);
300 UTextOpCode
.Statement
.Help
= FwOpcode
->Help
;
302 UTextOpCode
.Statement
.Prompt
= FwOpcode
->Text
;
303 UTextOpCode
.TextTwo
= FwOpcode
->TextTwo
;
305 return AppendToUpdateBuffer ((UINT8
*) &UTextOpCode
, sizeof(UTextOpCode
), UefiUpdateData
);
308 // Iteractive Text Opcode is EFI_IFR_ACTION
311 ZeroMem (&UActionOpCode
, sizeof (UActionOpCode
));
313 UActionOpCode
.Header
.OpCode
= EFI_IFR_ACTION_OP
;
314 UActionOpCode
.Header
.Length
= sizeof (EFI_IFR_ACTION
);
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
;
321 return AppendToUpdateBuffer ((UINT8
*) &UActionOpCode
, sizeof(UActionOpCode
), UefiUpdateData
);
327 Create UEFI HII Reference Opcode from a Framework HII Reference Opcode.
329 @param FwOpcode The input Framework Opcode.
330 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.
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.
337 F2UCreateReferenceOpCode (
338 IN CONST FRAMEWORK_EFI_IFR_REF
*FwOpcode
,
339 IN OUT EFI_HII_UPDATE_DATA
*UefiUpdateData
344 ZeroMem (&UOpcode
, sizeof(UOpcode
));
346 UOpcode
.Header
.Length
= sizeof(UOpcode
);
347 UOpcode
.Header
.OpCode
= EFI_IFR_REF_OP
;
349 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
350 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
351 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
353 UOpcode
.FormId
= FwOpcode
->FormId
;
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.
359 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
362 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiUpdateData
);
367 Create UEFI HII "One Of Option" Opcode from a Framework HII "One Of Option" Opcode.
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.
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.
378 F2UCreateOneOfOptionOpCode (
379 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOpcode
,
381 IN OUT EFI_HII_UPDATE_DATA
*UefiUpdateData
384 EFI_IFR_ONE_OF_OPTION UOpcode
;
386 ZeroMem (&UOpcode
, sizeof(UOpcode
));
388 UOpcode
.Header
.Length
= sizeof(UOpcode
);
389 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OPTION_OP
;
391 UOpcode
.Option
= FwOpcode
->Option
;
392 CopyMem (&UOpcode
.Value
.u8
, &FwOpcode
->Value
, Width
);
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
400 UOpcode
.Flags
= (UINT8
) (UOpcode
.Flags
| (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
)) << 4);
404 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
408 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
413 return EFI_UNSUPPORTED
;
416 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiUpdateData
);
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.
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.
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.
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
441 EFI_IFR_GUID_OPTIONKEY UOpcode
;
443 CopyMem (&UOpcode
, &mOptionKeyTemplate
, sizeof (EFI_IFR_GUID_OPTIONKEY
));
445 UOpcode
.QuestionId
= QuestionId
;
446 CopyMem (&UOpcode
.OptionValue
, &OptionValue
, sizeof (OptionValue
));
447 UOpcode
.KeyValue
= KeyValue
;
449 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiUpdateData
);
453 Create UEFI HII "One Of" Opcode from a Framework HII "One Of" Opcode.
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
460 @param OpcodeCount The number of Opcode for the complete Framework "One Of" Opcode.
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.
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
476 EFI_IFR_ONE_OF UOpcode
;
477 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
478 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
480 ASSERT (NextFwOpcode
!= NULL
);
481 ASSERT (OpcodeCount
!= NULL
);
483 ZeroMem (&UOpcode
, sizeof(UOpcode
));
486 UOpcode
.Header
.Length
= sizeof(UOpcode
);
487 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OP
;
488 UOpcode
.Header
.Scope
= 1;
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
;
496 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
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
);
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
;
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
);
515 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
516 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
519 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
523 if (UOpcode
.Question
.QuestionId
== 0) {
525 // Assign QuestionId if still not assigned.
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
);
533 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof (UOpcode
), UefiUpdateData
);
534 if (EFI_ERROR (Status
)) {
540 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.
542 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
543 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
545 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
547 Status
= F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, FwOpcode
->Width
, UefiUpdateData
);
548 if (EFI_ERROR (Status
)) {
552 Status
= CreateGuidOptionKeyOpCode (UOpcode
.Question
.QuestionId
, FwOneOfOp
->Value
, FwOneOfOp
->Key
, UefiUpdateData
);
553 if (EFI_ERROR (Status
)) {
556 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
560 Status
= UCreateEndOfOpcode (UefiUpdateData
);
561 if (!EFI_ERROR (Status
)) {
562 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
570 Create UEFI HII "Ordered List" Opcode from a Framework HII "Ordered List" Opcode.
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
577 @param OpcodeCount The number of Opcode for the complete Framework "Ordered List" Opcode.
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.
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
592 EFI_IFR_ORDERED_LIST UOpcode
;
594 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
595 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
597 ZeroMem (&UOpcode
, sizeof(UOpcode
));
600 UOpcode
.Header
.Length
= sizeof(UOpcode
);
601 UOpcode
.Header
.OpCode
= EFI_IFR_ORDERED_LIST_OP
;
602 UOpcode
.Header
.Scope
= 1;
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
;
609 UOpcode
.MaxContainers
= FwOpcode
->MaxEntries
;
612 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
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
);
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
;
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
);
631 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
632 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
635 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
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
);
645 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiUpdateData
);
646 if (EFI_ERROR (Status
)) {
651 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
652 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
654 // Each entry of Order List in Framework HII is always 1 byte in size
656 Status
= F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, 1, UefiUpdateData
);
657 if (EFI_ERROR (Status
)) {
660 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
664 Status
= UCreateEndOfOpcode (UefiUpdateData
);
665 if (!EFI_ERROR (Status
)) {
666 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
674 Create UEFI HII CheckBox Opcode from a Framework HII Checkbox Opcode.
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.
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.
685 F2UCreateCheckBoxOpCode (
686 IN HII_THUNK_CONTEXT
*ThunkContext
,
687 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX
*FwOpcode
,
688 IN OUT EFI_HII_UPDATE_DATA
*UefiUpdateData
692 EFI_IFR_CHECKBOX UOpcode
;
694 ZeroMem (&UOpcode
, sizeof(UOpcode
));
696 UOpcode
.Header
.Length
= sizeof(UOpcode
);
697 UOpcode
.Header
.OpCode
= EFI_IFR_CHECKBOX_OP
;
699 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
700 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
702 if (FwOpcode
->Key
== 0) {
703 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
704 if (EFI_ERROR (Status
)) {
706 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
708 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
711 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
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.
720 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
723 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
724 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
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.
732 UOpcode
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
));
734 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiUpdateData
);
739 Create UEFI HII Numeric Opcode from a Framework HII Numeric Opcode.
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.
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.
750 F2UCreateNumericOpCode (
751 IN HII_THUNK_CONTEXT
*ThunkContext
,
752 IN CONST FRAMEWORK_EFI_IFR_NUMERIC
*FwOpcode
,
753 IN OUT EFI_HII_UPDATE_DATA
*UefiUpdateData
757 EFI_IFR_NUMERIC UOpcode
;
758 EFI_IFR_DEFAULT UOpcodeDefault
;
760 ZeroMem (&UOpcode
, sizeof(UOpcode
));
762 if (FwOpcode
->Key
== 0) {
763 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
764 if (EFI_ERROR (Status
)) {
766 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
768 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
771 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
774 UOpcode
.Header
.Length
= sizeof(UOpcode
);
775 UOpcode
.Header
.OpCode
= EFI_IFR_NUMERIC_OP
;
777 // We need to create a nested default value for the UEFI Numeric Opcode.
778 // So turn on the scope.
780 UOpcode
.Header
.Scope
= 1;
782 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
783 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
785 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
786 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
788 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
791 // Framework Numeric values are all in UINT16 and displayed as decimal.
793 UOpcode
.data
.u16
.MinValue
= FwOpcode
->Minimum
;
794 UOpcode
.data
.u16
.MaxValue
= FwOpcode
->Maximum
;
795 UOpcode
.data
.u16
.Step
= FwOpcode
->Step
;
797 switch (FwOpcode
->Width
) {
800 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_1
| EFI_IFR_DISPLAY_UINT_DEC
;
805 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_2
| EFI_IFR_DISPLAY_UINT_DEC
;
811 return EFI_INVALID_PARAMETER
;
815 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiUpdateData
);
816 if (EFI_ERROR (Status
)) {
821 // We need to create a default value.
823 ZeroMem (&UOpcodeDefault
, sizeof (UOpcodeDefault
));
824 UOpcodeDefault
.Header
.Length
= sizeof (UOpcodeDefault
);
825 UOpcodeDefault
.Header
.OpCode
= EFI_IFR_DEFAULT_OP
;
827 UOpcodeDefault
.DefaultId
= 0;
829 switch (FwOpcode
->Width
) {
832 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
837 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
842 CopyMem (&UOpcodeDefault
.Value
.u8
, &FwOpcode
->Default
, FwOpcode
->Width
);
844 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcodeDefault
, sizeof(UOpcodeDefault
), UefiUpdateData
);
845 if (EFI_ERROR (Status
)) {
848 Status
= UCreateEndOfOpcode (UefiUpdateData
);
855 Create UEFI HII String Opcode from a Framework HII String Opcode.
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.
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.
866 F2UCreateStringOpCode (
867 IN HII_THUNK_CONTEXT
*ThunkContext
,
868 IN CONST FRAMEWORK_EFI_IFR_STRING
*FwOpcode
,
869 IN OUT EFI_HII_UPDATE_DATA
*UefiUpdateData
872 EFI_IFR_STRING UOpcode
;
874 ZeroMem (&UOpcode
, sizeof(UOpcode
));
876 if (FwOpcode
->Key
== 0) {
877 FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
879 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
882 UOpcode
.Header
.Length
= sizeof(UOpcode
);
883 UOpcode
.Header
.OpCode
= EFI_IFR_STRING_OP
;
885 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
886 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
888 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
889 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
891 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
892 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
894 UOpcode
.MinSize
= FwOpcode
->MinSize
;
895 UOpcode
.MaxSize
= FwOpcode
->MaxSize
;
896 UOpcode
.Flags
= EFI_IFR_STRING_MULTI_LINE
;
898 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiUpdateData
);
902 Create UEFI HII Banner Opcode from a Framework HII Banner Opcode.
904 @param FwOpcode The input Framework Opcode.
905 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.
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.
912 F2UCreateBannerOpCode (
913 IN CONST FRAMEWORK_EFI_IFR_BANNER
*FwOpcode
,
914 IN OUT EFI_HII_UPDATE_DATA
*UefiUpdateData
917 EFI_IFR_GUID_BANNER UOpcode
;
919 ZeroMem (&UOpcode
, sizeof(UOpcode
));
921 UOpcode
.Header
.Length
= sizeof(UOpcode
);
922 UOpcode
.Header
.OpCode
= EFI_IFR_GUID_OP
;
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
;
930 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiUpdateData
);
934 Create a EFI_HII_UPDATE_DATA structure used to call IfrLibUpdateForm.
936 @param ThunkContext The HII Thunk Context.
937 @param FwUpdateData The Framework Update Data.
938 @param UefiUpdateData The UEFI Update Data.
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.
945 FwUpdateDataToUefiUpdateData (
946 IN HII_THUNK_CONTEXT
*ThunkContext
,
947 IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA
*FwUpdateData
,
948 OUT EFI_HII_UPDATE_DATA
**UefiUpdateData
951 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpCode
;
952 FRAMEWORK_EFI_IFR_OP_HEADER
*NextFwOpCode
;
953 EFI_HII_UPDATE_DATA
*UefiOpCode
;
958 UefiOpCode
= AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA
));
959 if (UefiOpCode
== NULL
) {
960 return EFI_OUT_OF_RESOURCES
;
963 UefiOpCode
->Data
= AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
);
964 if (UefiOpCode
->Data
== NULL
) {
965 return EFI_OUT_OF_RESOURCES
;
968 UefiOpCode
->BufferSize
= LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
;
969 UefiOpCode
->Offset
= 0;
971 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) &FwUpdateData
->Data
;
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
);
980 case FRAMEWORK_EFI_IFR_TEXT_OP
:
981 Status
= F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT
*) FwOpCode
, UefiOpCode
);
985 case FRAMEWORK_EFI_IFR_REF_OP
:
986 Status
= F2UCreateReferenceOpCode ((FRAMEWORK_EFI_IFR_REF
*) FwOpCode
, UefiOpCode
);
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
;
995 // FwOpCode is already updated to point to the next opcode.
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
;
1006 // FwOpCode is already updated to point to the next opcode.
1012 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
1013 Status
= F2UCreateCheckBoxOpCode (ThunkContext
, (FRAMEWORK_EFI_IFR_CHECKBOX
*) FwOpCode
, UefiOpCode
);
1017 case FRAMEWORK_EFI_IFR_STRING_OP
:
1018 Status
= F2UCreateStringOpCode (ThunkContext
, (FRAMEWORK_EFI_IFR_STRING
*) FwOpCode
, UefiOpCode
);
1022 case FRAMEWORK_EFI_IFR_BANNER_OP
:
1023 Status
= F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER
*) FwOpCode
, UefiOpCode
);
1027 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP
:
1028 Status
= UCreateEndOfOpcode (UefiOpCode
);
1032 case FRAMEWORK_EFI_IFR_NUMERIC_OP
:
1033 Status
= F2UCreateNumericOpCode (ThunkContext
, (FRAMEWORK_EFI_IFR_NUMERIC
*) FwOpCode
, UefiOpCode
);
1039 return EFI_UNSUPPORTED
;
1042 if (EFI_ERROR (Status
)) {
1043 FreePool (UefiOpCode
->Data
);
1044 FreePool (UefiOpCode
);
1048 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpCode
+ FwOpCode
->Length
);
1051 *UefiUpdateData
= UefiOpCode
;