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.
15 #include "HiiDatabase.h"
16 #include "OpcodeCreation.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
,
36 IFR_OPCODE_MAP mQuestionOpcodeMap
[] = {
37 { FRAMEWORK_EFI_IFR_ONE_OF_OP
, EFI_IFR_ONE_OF_OP
},
38 { FRAMEWORK_EFI_IFR_CHECKBOX_OP
, EFI_IFR_CHECKBOX_OP
},
39 { FRAMEWORK_EFI_IFR_NUMERIC_OP
, EFI_IFR_NUMERIC_OP
},
40 { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
, EFI_IFR_ONE_OF_OPTION_OP
},
41 { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
, EFI_IFR_ORDERED_LIST_OP
}
52 for (Index
= 0; Index
< sizeof (mQuestionOpcodeMap
) / sizeof (mQuestionOpcodeMap
[0]); Index
++) {
53 if (FwOp
== mQuestionOpcodeMap
[Index
].FrameworkIfrOp
) {
54 *UefiOp
= mQuestionOpcodeMap
[Index
].UefiIfrOp
;
65 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
73 LIST_ENTRY
*StatementList
;
74 FORM_BROWSER_FORM
*Form
;
75 FORM_BROWSER_STATEMENT
*Statement
;
81 FormList
= GetFirstNode (&FormSet
->FormListHead
);
83 while (!IsNull (&FormSet
->FormListHead
, FormList
)) {
84 Form
= FORM_BROWSER_FORM_FROM_LINK (FormList
);
86 StatementList
= GetFirstNode (&Form
->StatementListHead
);
88 while (!IsNull (&Form
->StatementListHead
, StatementList
)) {
89 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (StatementList
);
90 if (Statement
->VarStoreId
!= 0 && Statement
->Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
91 if (FwQId
== Statement
->VarStoreInfo
.VarOffset
) {
92 Status
= QuestionOpFwToUefi (FwOpCode
, &UefiOp
);
93 ASSERT_EFI_ERROR (Status
);
95 if (UefiOp
== Statement
->Operand
) {
97 // If ASSERT here, the Framework VFR file has two IFR Question with the Same Type refering to the
98 // same field in NvMap. This is ambigurity, we don't handle it for now.
101 // UEFI Question ID is unique in a FormSet.
103 ASSERT (VarStoreId
== Statement
->VarStoreId
);
104 *UefiQId
= Statement
->QuestionId
;
112 StatementList
= GetNextNode (&Form
->StatementListHead
, StatementList
);
115 FormList
= GetNextNode (&FormSet
->FormListHead
, FormList
);
118 return EFI_NOT_FOUND
;
123 #define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL 0x1000
125 AppendToUpdateBuffer (
126 IN CONST UINT8
*OpCodeBuf
,
128 OUT EFI_HII_UPDATE_DATA
*UefiData
133 if (UefiData
->Offset
+ BufSize
> UefiData
->BufferSize
) {
134 NewBuff
= AllocateCopyPool (UefiData
->BufferSize
+ LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
, UefiData
->Data
);
135 if (NewBuff
== NULL
) {
136 return EFI_OUT_OF_RESOURCES
;
138 UefiData
->BufferSize
+= LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
;
139 FreePool (UefiData
->Data
);
140 UefiData
->Data
= NewBuff
;
143 CopyMem (UefiData
->Data
+ UefiData
->Offset
, OpCodeBuf
, BufSize
);
144 UefiData
->Offset
+= (UINT32
) BufSize
;
151 IN UINT16 FwQuestionId
,
152 IN FORM_BROWSER_FORMSET
*FormSet
155 if (FwQuestionId
== 0) {
156 FormSet
->MaxQuestionId
++;
157 return FormSet
->MaxQuestionId
;
165 OUT EFI_HII_UPDATE_DATA
*UefiData
170 ZeroMem (&UOpcode
, sizeof (UOpcode
));
172 UOpcode
.Header
.OpCode
= EFI_IFR_END_OP
;
173 UOpcode
.Header
.Length
= sizeof (UOpcode
);
175 return AppendToUpdateBuffer ((UINT8
*)&UOpcode
, sizeof(UOpcode
), UefiData
);
179 F2UCreateSubtitleOpCode (
180 IN CONST FRAMEWORK_EFI_IFR_SUBTITLE
*FwSubTitle
,
181 OUT EFI_HII_UPDATE_DATA
*UefiData
184 EFI_IFR_SUBTITLE UOpcode
;
186 ZeroMem (&UOpcode
, sizeof(UOpcode
));
188 UOpcode
.Header
.OpCode
= EFI_IFR_SUBTITLE_OP
;
189 UOpcode
.Header
.Length
= sizeof (EFI_IFR_SUBTITLE
);
191 UOpcode
.Statement
.Prompt
= FwSubTitle
->SubTitle
;
193 return AppendToUpdateBuffer ((UINT8
*)&UOpcode
, sizeof(UOpcode
), UefiData
);
197 F2UCreateTextOpCode (
198 IN CONST FRAMEWORK_EFI_IFR_TEXT
*FwText
,
199 OUT EFI_HII_UPDATE_DATA
*UefiData
202 EFI_IFR_TEXT UTextOpCode
;
203 EFI_IFR_ACTION UActionOpCode
;
205 if ((FwText
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) == 0) {
206 ZeroMem (&UTextOpCode
, sizeof(UTextOpCode
));
208 UTextOpCode
.Header
.OpCode
= EFI_IFR_TEXT_OP
;
209 UTextOpCode
.Header
.Length
= sizeof (EFI_IFR_TEXT
);
211 UTextOpCode
.Statement
.Help
= FwText
->Help
;
213 UTextOpCode
.Statement
.Prompt
= FwText
->Text
;
214 UTextOpCode
.TextTwo
= FwText
->TextTwo
;
216 return AppendToUpdateBuffer ((UINT8
*) &UTextOpCode
, sizeof(UTextOpCode
), UefiData
);
219 // Iteractive Text Opcode is EFI_IFR_ACTION
222 ZeroMem (&UActionOpCode
, sizeof (UActionOpCode
));
224 UActionOpCode
.Header
.OpCode
= EFI_IFR_ACTION_OP
;
225 UActionOpCode
.Header
.Length
= sizeof (EFI_IFR_ACTION
);
227 UActionOpCode
.Question
.Header
.Prompt
= FwText
->Text
;
228 UActionOpCode
.Question
.Header
.Help
= FwText
->Help
;
229 UActionOpCode
.Question
.Flags
= EFI_IFR_FLAG_CALLBACK
;
230 UActionOpCode
.Question
.QuestionId
= FwText
->Key
;
232 return AppendToUpdateBuffer ((UINT8
*) &UActionOpCode
, sizeof(UActionOpCode
), UefiData
);
239 FRAMEWORK_EFI_IFR_OP_HEADER Header;
242 STRING_REF Help; // The string Token for the context-help
243 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
244 UINT16 Key; // Value to be passed to caller to identify this particular op-code
245 } FRAMEWORK_EFI_IFR_REF;
249 F2UCreateGotoOpCode (
250 IN CONST FRAMEWORK_EFI_IFR_REF
*FwOpcode
,
251 OUT EFI_HII_UPDATE_DATA
*UefiData
256 ZeroMem (&UOpcode
, sizeof(UOpcode
));
258 UOpcode
.Header
.Length
= sizeof(UOpcode
);
259 UOpcode
.Header
.OpCode
= EFI_IFR_REF_OP
;
261 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
262 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
263 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
265 UOpcode
.FormId
= FwOpcode
->FormId
;
268 // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to
269 // UEFI IFR Opcode flags. The rest flags are obsolete.
271 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
274 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
280 FRAMEWORK_EFI_IFR_OP_HEADER Header;
281 STRING_REF Option; // The string token describing the option
282 UINT16 Value; // The value associated with this option that is stored in the NVRAM if chosen
283 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely above
284 UINT16 Key; // Value to be passed to caller to identify this particular op-code
285 } FRAMEWORK_EFI_IFR_ONE_OF_OPTION;
295 EFI_STRING_ID string;
296 } EFI_IFR_TYPE_VALUE;
298 typedef struct _EFI_IFR_ONE_OF_OPTION {
299 EFI_IFR_OP_HEADER Header;
300 EFI_STRING_ID Option;
303 EFI_IFR_TYPE_VALUE Value;
304 } EFI_IFR_ONE_OF_OPTION;
308 F2UCreateOneOfOptionOpCode (
309 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOpcode
,
311 OUT EFI_HII_UPDATE_DATA
*UefiData
314 EFI_IFR_ONE_OF_OPTION UOpcode
;
316 ZeroMem (&UOpcode
, sizeof(UOpcode
));
318 UOpcode
.Header
.Length
= sizeof(UOpcode
);
319 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OPTION_OP
;
321 UOpcode
.Option
= FwOpcode
->Option
;
322 CopyMem (&UOpcode
.Value
.u8
, &FwOpcode
->Value
, Width
);
326 // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT 0x01
327 // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING 0x02
328 // #define EFI_IFR_OPTION_DEFAULT 0x10
329 // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20
331 UOpcode
.Flags
= (UINT8
) (UOpcode
.Flags
| (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
)) << 4);
335 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
339 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
344 return EFI_UNSUPPORTED
;
347 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
351 CreateGuidOptionKeyOpCode (
352 IN EFI_QUESTION_ID QuestionId
,
353 IN UINT16 OptionValue
,
354 IN EFI_QUESTION_ID KeyValue
,
355 OUT EFI_HII_UPDATE_DATA
*UefiData
358 EFI_IFR_GUID_OPTIONKEY UOpcode
;
360 CopyMem (&UOpcode
, &mOptionKeyTemplate
, sizeof (EFI_IFR_GUID_OPTIONKEY
));
362 UOpcode
.QuestionId
= QuestionId
;
363 CopyMem (&UOpcode
.OptionValue
, &OptionValue
, sizeof (OptionValue
));
364 UOpcode
.KeyValue
= KeyValue
;
366 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
370 typedef struct _EFI_IFR_QUESTION_HEADER {
371 EFI_IFR_STATEMENT_HEADER Header;
372 EFI_QUESTION_ID QuestionId;
373 EFI_VARSTORE_ID VarStoreId;
375 EFI_STRING_ID VarName;
379 } EFI_IFR_QUESTION_HEADER;
404 typedef struct _EFI_IFR_ONE_OF {
405 EFI_IFR_OP_HEADER Header;
406 EFI_IFR_QUESTION_HEADER Question;
408 MINMAXSTEP_DATA data;
412 FRAMEWORK_EFI_IFR_OP_HEADER Header;
413 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
414 UINT8 Width; // The Size of the Data being saved
415 STRING_REF Prompt; // The String Token for the Prompt
416 STRING_REF Help; // The string Token for the context-help
417 } FRAMEWORK_EFI_IFR_ONE_OF;
423 F2UCreateOneOfOpCode (
424 IN HII_THUNK_CONTEXT
*ThunkContext
,
425 IN UINT16 VarStoreId
,
426 IN CONST FRAMEWORK_EFI_IFR_ONE_OF
*FwOpcode
,
427 OUT EFI_HII_UPDATE_DATA
*UefiData
,
428 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
433 EFI_IFR_ONE_OF UOpcode
;
434 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
435 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
437 ASSERT (NextFwOpcode
!= NULL
);
438 ASSERT (DataCount
!= NULL
);
440 ZeroMem (&UOpcode
, sizeof(UOpcode
));
443 UOpcode
.Header
.Length
= sizeof(UOpcode
);
444 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OP
;
445 UOpcode
.Header
.Scope
= 1;
447 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
448 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
449 UOpcode
.Question
.VarStoreId
= VarStoreId
;
450 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
453 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
455 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
456 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
457 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
459 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
460 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
461 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
463 if (UOpcode
.Question
.QuestionId
== 0) {
464 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
465 if (EFI_ERROR (Status
)) {
466 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
, ThunkContext
->FormSet
);
472 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
473 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
476 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
480 if (UOpcode
.Question
.QuestionId
== 0) {
482 // Assign QuestionId if still not assigned.
484 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
485 if (EFI_ERROR (Status
)) {
486 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
490 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof (UOpcode
), UefiData
);
491 if (EFI_ERROR (Status
)) {
497 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.
499 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
500 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
502 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
504 Status
= F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, FwOpcode
->Width
, UefiData
);
505 if (EFI_ERROR (Status
)) {
509 Status
= CreateGuidOptionKeyOpCode (UOpcode
.Question
.QuestionId
, FwOneOfOp
->Value
, FwOneOfOp
->Key
, UefiData
);
510 if (EFI_ERROR (Status
)) {
513 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
517 Status
= UCreateEndOfOpcode (UefiData
);
518 if (!EFI_ERROR (Status
)) {
519 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
527 typedef struct _EFI_IFR_QUESTION_HEADER {
528 EFI_IFR_STATEMENT_HEADER Header;
529 EFI_QUESTION_ID QuestionId;
530 EFI_VARSTORE_ID VarStoreId;
532 EFI_STRING_ID VarName;
536 } EFI_IFR_QUESTION_HEADER;
538 typedef struct _EFI_IFR_ORDERED_LIST {
539 EFI_IFR_OP_HEADER Header;
540 EFI_IFR_QUESTION_HEADER Question;
543 } EFI_IFR_ORDERED_LIST;
546 FRAMEWORK_EFI_IFR_OP_HEADER Header;
547 UINT16 QuestionId; // The offset in NV for storage of the data
548 UINT8 MaxEntries; // The maximum number of options in the ordered list (=size of NVStore)
549 STRING_REF Prompt; // The string token for the prompt
550 STRING_REF Help; // The string token for the context-help
551 } FRAMEWORK_EFI_IFR_ORDERED_LIST;
555 F2UCreateOrderedListOpCode (
556 IN HII_THUNK_CONTEXT
*ThunkContext
,
557 IN UINT16 VarStoreId
,
558 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST
*FwOpcode
,
559 OUT EFI_HII_UPDATE_DATA
*UefiData
,
560 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
564 EFI_IFR_ORDERED_LIST UOpcode
;
566 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
567 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
569 ZeroMem (&UOpcode
, sizeof(UOpcode
));
572 UOpcode
.Header
.Length
= sizeof(UOpcode
);
573 UOpcode
.Header
.OpCode
= EFI_IFR_ORDERED_LIST_OP
;
574 UOpcode
.Header
.Scope
= 1;
576 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
577 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
578 UOpcode
.Question
.VarStoreId
= VarStoreId
;
579 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
581 UOpcode
.MaxContainers
= FwOpcode
->MaxEntries
;
584 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
586 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
587 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
588 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
590 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
591 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
592 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
594 if (UOpcode
.Question
.QuestionId
== 0) {
595 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
596 if (EFI_ERROR (Status
)) {
597 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
, ThunkContext
->FormSet
);
603 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
604 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
607 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
610 if (UOpcode
.Question
.QuestionId
== 0) {
611 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
612 if (EFI_ERROR (Status
)) {
613 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
617 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
618 if (EFI_ERROR (Status
)) {
623 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
624 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
626 // Each entry of Order List in Framework HII is always 1 byte in size
628 Status
= F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, 1, UefiData
);
629 if (EFI_ERROR (Status
)) {
632 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
636 Status
= UCreateEndOfOpcode (UefiData
);
637 if (!EFI_ERROR (Status
)) {
638 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
646 typedef struct _EFI_IFR_QUESTION_HEADER {
647 EFI_IFR_STATEMENT_HEADER Header;
648 EFI_QUESTION_ID QuestionId;
649 EFI_VARSTORE_ID VarStoreId;
651 EFI_STRING_ID VarName;
655 } EFI_IFR_QUESTION_HEADER;
659 typedef struct _EFI_IFR_CHECKBOX {
660 EFI_IFR_OP_HEADER Header;
661 EFI_IFR_QUESTION_HEADER Question;
668 FRAMEWORK_EFI_IFR_OP_HEADER Header;
669 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
670 UINT8 Width; // The Size of the Data being saved
671 STRING_REF Prompt; // The String Token for the Prompt
672 STRING_REF Help; // The string Token for the context-help
673 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely
674 UINT16 Key; // Value to be passed to caller to identify this particular op-code
675 } FRAMEWORK_EFI_IFR_CHECKBOX, FRAMEWORK_EFI_IFR_CHECK_BOX;
680 F2UCreateCheckBoxOpCode (
681 IN HII_THUNK_CONTEXT
*ThunkContext
,
682 IN UINT16 VarStoreId
,
683 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX
*FwOpcode
,
684 OUT EFI_HII_UPDATE_DATA
*UefiData
688 EFI_IFR_CHECKBOX UOpcode
;
690 ZeroMem (&UOpcode
, sizeof(UOpcode
));
692 UOpcode
.Header
.Length
= sizeof(UOpcode
);
693 UOpcode
.Header
.OpCode
= EFI_IFR_CHECKBOX_OP
;
695 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
696 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
698 if (FwOpcode
->Key
== 0) {
699 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
700 if (EFI_ERROR (Status
)) {
702 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
704 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
707 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
710 UOpcode
.Question
.VarStoreId
= FRAMEWORK_RESERVED_VARSTORE_ID
;
711 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
714 // We only map 2 flags:
715 // FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE,
716 // FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,
717 // to UEFI IFR Opcode Question flags. The rest flags are obsolete.
719 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
722 // We also map 2 flags:
723 // FRAMEWORK_EFI_IFR_FLAG_DEFAULT,
724 // FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,
725 // to UEFI IFR CheckBox Opcode default flags.
727 UOpcode
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
));
729 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
734 typedef struct _EFI_IFR_QUESTION_HEADER {
735 EFI_IFR_STATEMENT_HEADER Header;
736 EFI_QUESTION_ID QuestionId;
737 EFI_VARSTORE_ID VarStoreId;
739 EFI_STRING_ID VarName;
743 } EFI_IFR_QUESTION_HEADER;
768 typedef struct _EFI_IFR_NUMERIC {
769 EFI_IFR_OP_HEADER Header;
770 EFI_IFR_QUESTION_HEADER Question;
772 MINMAXSTEP_DATA data;
777 FRAMEWORK_EFI_IFR_OP_HEADER Header;
778 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
779 UINT8 Width; // The Size of the Data being saved
780 STRING_REF Prompt; // The String Token for the Prompt
781 STRING_REF Help; // The string Token for the context-help
782 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
783 UINT16 Key; // Value to be passed to caller to identify this particular op-code
786 UINT16 Step; // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for
788 } FRAMEWORK_EFI_IFR_NUMERIC;
794 F2UCreateNumericOpCode (
795 IN HII_THUNK_CONTEXT
*ThunkContext
,
796 IN UINT16 VarStoreId
,
797 IN CONST FRAMEWORK_EFI_IFR_NUMERIC
*FwOpcode
,
798 OUT EFI_HII_UPDATE_DATA
*UefiData
802 EFI_IFR_NUMERIC UOpcode
;
803 EFI_IFR_DEFAULT UOpcodeDefault
;
805 ZeroMem (&UOpcode
, sizeof(UOpcode
));
807 if (FwOpcode
->Key
== 0) {
808 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
809 if (EFI_ERROR (Status
)) {
811 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
813 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
816 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
819 UOpcode
.Header
.Length
= sizeof(UOpcode
);
820 UOpcode
.Header
.OpCode
= EFI_IFR_NUMERIC_OP
;
822 // We need to create a nested default value for the UEFI Numeric Opcode.
823 // So turn on the scope.
825 UOpcode
.Header
.Scope
= 1;
827 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
828 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
830 UOpcode
.Question
.VarStoreId
= VarStoreId
;
831 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
833 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
836 // Framework Numeric values are all in UINT16 and displayed as decimal.
838 UOpcode
.data
.u16
.MinValue
= FwOpcode
->Minimum
;
839 UOpcode
.data
.u16
.MaxValue
= FwOpcode
->Maximum
;
840 UOpcode
.data
.u16
.Step
= FwOpcode
->Step
;
842 switch (FwOpcode
->Width
) {
845 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_1
| EFI_IFR_DISPLAY_UINT_DEC
;
850 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_2
| EFI_IFR_DISPLAY_UINT_DEC
;
856 return EFI_INVALID_PARAMETER
;
860 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
861 if (EFI_ERROR (Status
)) {
866 // We need to create a default value.
868 ZeroMem (&UOpcodeDefault
, sizeof (UOpcodeDefault
));
869 UOpcodeDefault
.Header
.Length
= sizeof (UOpcodeDefault
);
870 UOpcodeDefault
.Header
.OpCode
= EFI_IFR_DEFAULT_OP
;
872 UOpcodeDefault
.DefaultId
= 0;
874 switch (FwOpcode
->Width
) {
877 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
882 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
887 CopyMem (&UOpcodeDefault
.Value
.u8
, &FwOpcode
->Default
, FwOpcode
->Width
);
889 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcodeDefault
, sizeof(UOpcodeDefault
), UefiData
);
890 if (EFI_ERROR (Status
)) {
893 Status
= UCreateEndOfOpcode (UefiData
);
901 typedef struct _EFI_IFR_QUESTION_HEADER {
902 EFI_IFR_STATEMENT_HEADER Header;
903 EFI_QUESTION_ID QuestionId;
904 EFI_VARSTORE_ID VarStoreId;
906 EFI_STRING_ID VarName;
910 } EFI_IFR_QUESTION_HEADER;
912 typedef struct _EFI_IFR_STRING {
913 EFI_IFR_OP_HEADER Header;
914 EFI_IFR_QUESTION_HEADER Question;
922 FRAMEWORK_EFI_IFR_OP_HEADER Header;
923 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
924 UINT8 Width; // The Size of the Data being saved -- BUGBUG -- remove someday
925 STRING_REF Prompt; // The String Token for the Prompt
926 STRING_REF Help; // The string Token for the context-help
927 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
928 UINT16 Key; // Value to be passed to caller to identify this particular op-code
929 UINT8 MinSize; // Minimum allowable sized password
930 UINT8 MaxSize; // Maximum allowable sized password
931 } FRAMEWORK_EFI_IFR_STRING;
937 F2UCreateStringOpCode (
938 IN HII_THUNK_CONTEXT
*ThunkContext
,
939 IN UINT16 VarStoreId
,
940 IN CONST FRAMEWORK_EFI_IFR_STRING
*FwOpcode
,
941 OUT EFI_HII_UPDATE_DATA
*UefiData
944 EFI_IFR_STRING UOpcode
;
946 ZeroMem (&UOpcode
, sizeof(UOpcode
));
948 if (FwOpcode
->Key
== 0) {
949 FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
951 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
954 UOpcode
.Header
.Length
= sizeof(UOpcode
);
955 UOpcode
.Header
.OpCode
= EFI_IFR_STRING_OP
;
957 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
958 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
960 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
961 UOpcode
.Question
.VarStoreId
= FRAMEWORK_RESERVED_VARSTORE_ID
;
962 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
964 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
966 UOpcode
.MinSize
= FwOpcode
->MinSize
;
967 UOpcode
.MaxSize
= FwOpcode
->MaxSize
;
968 UOpcode
.Flags
= EFI_IFR_STRING_MULTI_LINE
;
970 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
974 typedef struct _EFI_IFR_GUID_BANNER {
975 EFI_IFR_OP_HEADER Header;
977 UINT8 ExtendOpCode; // Extended opcode is EFI_IFR_EXTEND_OP_BANNER
978 EFI_STRING_ID Title; // The string token for the banner title
979 UINT16 LineNumber; // 1-based line number
980 UINT8 Alignment; // left, center, or right-aligned
981 } EFI_IFR_GUID_BANNER;
984 FRAMEWORK_EFI_IFR_OP_HEADER Header;
985 STRING_REF Title; // The string token for the banner title
986 UINT16 LineNumber; // 1-based line number
987 UINT8 Alignment; // left, center, or right-aligned
988 } FRAMEWORK_EFI_IFR_BANNER;
993 F2UCreateBannerOpCode (
994 IN CONST FRAMEWORK_EFI_IFR_BANNER
*FwOpcode
,
995 OUT EFI_HII_UPDATE_DATA
*UefiData
998 EFI_IFR_GUID_BANNER UOpcode
;
1000 ZeroMem (&UOpcode
, sizeof(UOpcode
));
1002 UOpcode
.Header
.Length
= sizeof(UOpcode
);
1003 UOpcode
.Header
.OpCode
= EFI_IFR_GUID_OP
;
1005 CopyMem (&UOpcode
.Guid
, &mTianoExtendedOpcodeGuid
, sizeof (EFI_GUID
));
1006 UOpcode
.ExtendOpCode
= EFI_IFR_EXTEND_OP_BANNER
;
1007 UOpcode
.Title
= FwOpcode
->Title
;
1008 UOpcode
.LineNumber
= FwOpcode
->LineNumber
;
1009 UOpcode
.Alignment
= FwOpcode
->Alignment
;
1011 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
1016 FwUpdateDataToUefiUpdateData (
1017 IN HII_THUNK_CONTEXT
*ThunkContext
,
1018 IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA
*Data
,
1019 OUT EFI_HII_UPDATE_DATA
**UefiData
1022 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpCode
;
1023 FRAMEWORK_EFI_IFR_OP_HEADER
*NextFwOpCode
;
1024 EFI_HII_UPDATE_DATA
*UefiOpCode
;
1031 // Assume all dynamic opcode created is using active variable with VarStoreId of 1.
1035 UefiOpCode
= AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA
));
1036 if (UefiOpCode
== NULL
) {
1037 return EFI_OUT_OF_RESOURCES
;
1040 UefiOpCode
->Data
= AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
);
1041 if (UefiOpCode
->Data
== NULL
) {
1042 return EFI_OUT_OF_RESOURCES
;
1045 UefiOpCode
->BufferSize
= LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
;
1046 UefiOpCode
->Offset
= 0;
1048 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) &Data
->Data
;
1050 for (Index
= 0; Index
< Data
->DataCount
; Index
+= DataCount
) {
1051 switch (FwOpCode
->OpCode
) {
1052 case FRAMEWORK_EFI_IFR_SUBTITLE_OP
:
1053 Status
= F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE
*) FwOpCode
, UefiOpCode
);
1057 case FRAMEWORK_EFI_IFR_TEXT_OP
:
1058 Status
= F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT
*) FwOpCode
, UefiOpCode
);
1062 case FRAMEWORK_EFI_IFR_REF_OP
:
1063 Status
= F2UCreateGotoOpCode ((FRAMEWORK_EFI_IFR_REF
*) FwOpCode
, UefiOpCode
);
1067 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
1068 Status
= F2UCreateOneOfOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_ONE_OF
*) FwOpCode
, UefiOpCode
, &NextFwOpCode
, &DataCount
);
1069 if (!EFI_ERROR (Status
)) {
1070 FwOpCode
= NextFwOpCode
;
1072 // FwOpCode is already updated to point to the next opcode.
1078 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
:
1079 Status
= F2UCreateOrderedListOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_ORDERED_LIST
*) FwOpCode
, UefiOpCode
, &NextFwOpCode
, &DataCount
);
1080 if (!EFI_ERROR (Status
)) {
1081 FwOpCode
= NextFwOpCode
;
1083 // FwOpCode is already updated to point to the next opcode.
1089 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
1090 Status
= F2UCreateCheckBoxOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_CHECKBOX
*) FwOpCode
, UefiOpCode
);
1094 case FRAMEWORK_EFI_IFR_STRING_OP
:
1095 Status
= F2UCreateStringOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_STRING
*) FwOpCode
, UefiOpCode
);
1099 case FRAMEWORK_EFI_IFR_BANNER_OP
:
1100 Status
= F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER
*) FwOpCode
, UefiOpCode
);
1104 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP
:
1105 Status
= UCreateEndOfOpcode (UefiOpCode
);
1109 case FRAMEWORK_EFI_IFR_NUMERIC_OP
:
1110 Status
= F2UCreateNumericOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_NUMERIC
*) FwOpCode
, UefiOpCode
);
1116 return EFI_UNSUPPORTED
;
1119 if (EFI_ERROR (Status
)) {
1120 FreePool (UefiOpCode
->Data
);
1121 FreePool (UefiOpCode
);
1125 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpCode
+ FwOpCode
->Length
);
1128 *UefiData
= UefiOpCode
;