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
;
59 *UefiOp
= (UINT8
) (FRAMEWORK_EFI_IFR_LAST_OPCODE
+ 1);
66 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
74 LIST_ENTRY
*StatementList
;
75 FORM_BROWSER_FORM
*Form
;
76 FORM_BROWSER_STATEMENT
*Statement
;
82 FormList
= GetFirstNode (&FormSet
->FormListHead
);
84 while (!IsNull (&FormSet
->FormListHead
, FormList
)) {
85 Form
= FORM_BROWSER_FORM_FROM_LINK (FormList
);
87 StatementList
= GetFirstNode (&Form
->StatementListHead
);
89 while (!IsNull (&Form
->StatementListHead
, StatementList
)) {
90 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (StatementList
);
91 if (Statement
->VarStoreId
!= 0 && Statement
->Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
92 if (FwQId
== Statement
->VarStoreInfo
.VarOffset
) {
93 Status
= QuestionOpFwToUefi (FwOpCode
, &UefiOp
);
94 ASSERT_EFI_ERROR (Status
);
96 if (UefiOp
== Statement
->Operand
) {
98 // If ASSERT here, the Framework VFR file has two IFR Question with the Same Type refering to the
99 // same field in NvMap. This is ambigurity, we don't handle it for now.
102 // UEFI Question ID is unique in a FormSet.
104 ASSERT (VarStoreId
== Statement
->VarStoreId
);
105 *UefiQId
= Statement
->QuestionId
;
113 StatementList
= GetNextNode (&Form
->StatementListHead
, StatementList
);
116 FormList
= GetNextNode (&FormSet
->FormListHead
, FormList
);
119 return EFI_NOT_FOUND
;
124 #define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL 0x1000
126 AppendToUpdateBuffer (
127 IN CONST UINT8
*OpCodeBuf
,
129 OUT EFI_HII_UPDATE_DATA
*UefiData
134 if (UefiData
->Offset
+ BufSize
> UefiData
->BufferSize
) {
135 NewBuff
= AllocateCopyPool (UefiData
->BufferSize
+ LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
, UefiData
->Data
);
136 if (NewBuff
== NULL
) {
137 return EFI_OUT_OF_RESOURCES
;
139 UefiData
->BufferSize
+= LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
;
140 FreePool (UefiData
->Data
);
141 UefiData
->Data
= NewBuff
;
144 CopyMem (UefiData
->Data
+ UefiData
->Offset
, OpCodeBuf
, BufSize
);
145 UefiData
->Offset
+= (UINT32
) BufSize
;
152 IN UINT16 FwQuestionId
,
153 IN FORM_BROWSER_FORMSET
*FormSet
156 if (FwQuestionId
== 0) {
157 FormSet
->MaxQuestionId
++;
158 return FormSet
->MaxQuestionId
;
166 OUT EFI_HII_UPDATE_DATA
*UefiData
171 ZeroMem (&UOpcode
, sizeof (UOpcode
));
173 UOpcode
.Header
.OpCode
= EFI_IFR_END_OP
;
174 UOpcode
.Header
.Length
= sizeof (UOpcode
);
176 return AppendToUpdateBuffer ((UINT8
*)&UOpcode
, sizeof(UOpcode
), UefiData
);
180 F2UCreateSubtitleOpCode (
181 IN CONST FRAMEWORK_EFI_IFR_SUBTITLE
*FwSubTitle
,
182 OUT EFI_HII_UPDATE_DATA
*UefiData
185 EFI_IFR_SUBTITLE UOpcode
;
187 ZeroMem (&UOpcode
, sizeof(UOpcode
));
189 UOpcode
.Header
.OpCode
= EFI_IFR_SUBTITLE_OP
;
190 UOpcode
.Header
.Length
= sizeof (EFI_IFR_SUBTITLE
);
192 UOpcode
.Statement
.Prompt
= FwSubTitle
->SubTitle
;
194 return AppendToUpdateBuffer ((UINT8
*)&UOpcode
, sizeof(UOpcode
), UefiData
);
198 F2UCreateTextOpCode (
199 IN CONST FRAMEWORK_EFI_IFR_TEXT
*FwText
,
200 OUT EFI_HII_UPDATE_DATA
*UefiData
203 EFI_IFR_TEXT UTextOpCode
;
204 EFI_IFR_ACTION UActionOpCode
;
206 if ((FwText
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) == 0) {
207 ZeroMem (&UTextOpCode
, sizeof(UTextOpCode
));
209 UTextOpCode
.Header
.OpCode
= EFI_IFR_TEXT_OP
;
210 UTextOpCode
.Header
.Length
= sizeof (EFI_IFR_TEXT
);
212 UTextOpCode
.Statement
.Help
= FwText
->Help
;
214 UTextOpCode
.Statement
.Prompt
= FwText
->Text
;
215 UTextOpCode
.TextTwo
= FwText
->TextTwo
;
217 return AppendToUpdateBuffer ((UINT8
*) &UTextOpCode
, sizeof(UTextOpCode
), UefiData
);
220 // Iteractive Text Opcode is EFI_IFR_ACTION
223 ZeroMem (&UActionOpCode
, sizeof (UActionOpCode
));
225 UActionOpCode
.Header
.OpCode
= EFI_IFR_ACTION_OP
;
226 UActionOpCode
.Header
.Length
= sizeof (EFI_IFR_ACTION
);
228 UActionOpCode
.Question
.Header
.Prompt
= FwText
->Text
;
229 UActionOpCode
.Question
.Header
.Help
= FwText
->Help
;
230 UActionOpCode
.Question
.Flags
= EFI_IFR_FLAG_CALLBACK
;
231 UActionOpCode
.Question
.QuestionId
= FwText
->Key
;
233 return AppendToUpdateBuffer ((UINT8
*) &UActionOpCode
, sizeof(UActionOpCode
), UefiData
);
240 FRAMEWORK_EFI_IFR_OP_HEADER Header;
243 STRING_REF Help; // The string Token for the context-help
244 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
245 UINT16 Key; // Value to be passed to caller to identify this particular op-code
246 } FRAMEWORK_EFI_IFR_REF;
250 F2UCreateGotoOpCode (
251 IN CONST FRAMEWORK_EFI_IFR_REF
*FwOpcode
,
252 OUT EFI_HII_UPDATE_DATA
*UefiData
257 ZeroMem (&UOpcode
, sizeof(UOpcode
));
259 UOpcode
.Header
.Length
= sizeof(UOpcode
);
260 UOpcode
.Header
.OpCode
= EFI_IFR_REF_OP
;
262 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
263 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
264 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
266 UOpcode
.FormId
= FwOpcode
->FormId
;
269 // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to
270 // UEFI IFR Opcode flags. The rest flags are obsolete.
272 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
275 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
281 FRAMEWORK_EFI_IFR_OP_HEADER Header;
282 STRING_REF Option; // The string token describing the option
283 UINT16 Value; // The value associated with this option that is stored in the NVRAM if chosen
284 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely above
285 UINT16 Key; // Value to be passed to caller to identify this particular op-code
286 } FRAMEWORK_EFI_IFR_ONE_OF_OPTION;
296 EFI_STRING_ID string;
297 } EFI_IFR_TYPE_VALUE;
299 typedef struct _EFI_IFR_ONE_OF_OPTION {
300 EFI_IFR_OP_HEADER Header;
301 EFI_STRING_ID Option;
304 EFI_IFR_TYPE_VALUE Value;
305 } EFI_IFR_ONE_OF_OPTION;
309 F2UCreateOneOfOptionOpCode (
310 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOpcode
,
312 OUT EFI_HII_UPDATE_DATA
*UefiData
315 EFI_IFR_ONE_OF_OPTION UOpcode
;
317 ZeroMem (&UOpcode
, sizeof(UOpcode
));
319 UOpcode
.Header
.Length
= sizeof(UOpcode
);
320 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OPTION_OP
;
322 UOpcode
.Option
= FwOpcode
->Option
;
323 CopyMem (&UOpcode
.Value
.u8
, &FwOpcode
->Value
, Width
);
327 // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT 0x01
328 // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING 0x02
329 // #define EFI_IFR_OPTION_DEFAULT 0x10
330 // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20
332 UOpcode
.Flags
= (UINT8
) (UOpcode
.Flags
| (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
)) << 4);
336 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
340 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
345 return EFI_UNSUPPORTED
;
348 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
352 CreateGuidOptionKeyOpCode (
353 IN EFI_QUESTION_ID QuestionId
,
354 IN UINT16 OptionValue
,
355 IN EFI_QUESTION_ID KeyValue
,
356 OUT EFI_HII_UPDATE_DATA
*UefiData
359 EFI_IFR_GUID_OPTIONKEY UOpcode
;
361 CopyMem (&UOpcode
, &mOptionKeyTemplate
, sizeof (EFI_IFR_GUID_OPTIONKEY
));
363 UOpcode
.QuestionId
= QuestionId
;
364 CopyMem (&UOpcode
.OptionValue
, &OptionValue
, sizeof (OptionValue
));
365 UOpcode
.KeyValue
= KeyValue
;
367 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
371 typedef struct _EFI_IFR_QUESTION_HEADER {
372 EFI_IFR_STATEMENT_HEADER Header;
373 EFI_QUESTION_ID QuestionId;
374 EFI_VARSTORE_ID VarStoreId;
376 EFI_STRING_ID VarName;
380 } EFI_IFR_QUESTION_HEADER;
405 typedef struct _EFI_IFR_ONE_OF {
406 EFI_IFR_OP_HEADER Header;
407 EFI_IFR_QUESTION_HEADER Question;
409 MINMAXSTEP_DATA data;
413 FRAMEWORK_EFI_IFR_OP_HEADER Header;
414 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
415 UINT8 Width; // The Size of the Data being saved
416 STRING_REF Prompt; // The String Token for the Prompt
417 STRING_REF Help; // The string Token for the context-help
418 } FRAMEWORK_EFI_IFR_ONE_OF;
424 F2UCreateOneOfOpCode (
425 IN HII_THUNK_CONTEXT
*ThunkContext
,
426 IN UINT16 VarStoreId
,
427 IN CONST FRAMEWORK_EFI_IFR_ONE_OF
*FwOpcode
,
428 OUT EFI_HII_UPDATE_DATA
*UefiData
,
429 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
434 EFI_IFR_ONE_OF UOpcode
;
435 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
436 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
438 ASSERT (NextFwOpcode
!= NULL
);
439 ASSERT (DataCount
!= NULL
);
441 ZeroMem (&UOpcode
, sizeof(UOpcode
));
444 UOpcode
.Header
.Length
= sizeof(UOpcode
);
445 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OP
;
446 UOpcode
.Header
.Scope
= 1;
448 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
449 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
450 UOpcode
.Question
.VarStoreId
= VarStoreId
;
451 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
454 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
456 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
457 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
458 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
460 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
461 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
462 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
464 if (UOpcode
.Question
.QuestionId
== 0) {
465 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
466 if (EFI_ERROR (Status
)) {
467 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
, ThunkContext
->FormSet
);
473 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
474 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
477 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
481 if (UOpcode
.Question
.QuestionId
== 0) {
483 // Assign QuestionId if still not assigned.
485 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
486 if (EFI_ERROR (Status
)) {
487 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
491 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof (UOpcode
), UefiData
);
492 if (EFI_ERROR (Status
)) {
498 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.
500 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
501 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
503 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
505 Status
= F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, FwOpcode
->Width
, UefiData
);
506 if (EFI_ERROR (Status
)) {
510 Status
= CreateGuidOptionKeyOpCode (UOpcode
.Question
.QuestionId
, FwOneOfOp
->Value
, FwOneOfOp
->Key
, UefiData
);
511 if (EFI_ERROR (Status
)) {
514 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
518 Status
= UCreateEndOfOpcode (UefiData
);
519 if (!EFI_ERROR (Status
)) {
520 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
528 typedef struct _EFI_IFR_QUESTION_HEADER {
529 EFI_IFR_STATEMENT_HEADER Header;
530 EFI_QUESTION_ID QuestionId;
531 EFI_VARSTORE_ID VarStoreId;
533 EFI_STRING_ID VarName;
537 } EFI_IFR_QUESTION_HEADER;
539 typedef struct _EFI_IFR_ORDERED_LIST {
540 EFI_IFR_OP_HEADER Header;
541 EFI_IFR_QUESTION_HEADER Question;
544 } EFI_IFR_ORDERED_LIST;
547 FRAMEWORK_EFI_IFR_OP_HEADER Header;
548 UINT16 QuestionId; // The offset in NV for storage of the data
549 UINT8 MaxEntries; // The maximum number of options in the ordered list (=size of NVStore)
550 STRING_REF Prompt; // The string token for the prompt
551 STRING_REF Help; // The string token for the context-help
552 } FRAMEWORK_EFI_IFR_ORDERED_LIST;
556 F2UCreateOrderedListOpCode (
557 IN HII_THUNK_CONTEXT
*ThunkContext
,
558 IN UINT16 VarStoreId
,
559 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST
*FwOpcode
,
560 OUT EFI_HII_UPDATE_DATA
*UefiData
,
561 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
565 EFI_IFR_ORDERED_LIST UOpcode
;
567 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
568 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
570 ZeroMem (&UOpcode
, sizeof(UOpcode
));
573 UOpcode
.Header
.Length
= sizeof(UOpcode
);
574 UOpcode
.Header
.OpCode
= EFI_IFR_ORDERED_LIST_OP
;
575 UOpcode
.Header
.Scope
= 1;
577 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
578 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
579 UOpcode
.Question
.VarStoreId
= VarStoreId
;
580 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
582 UOpcode
.MaxContainers
= FwOpcode
->MaxEntries
;
585 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
587 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
588 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
589 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
591 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
592 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
593 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
595 if (UOpcode
.Question
.QuestionId
== 0) {
596 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
597 if (EFI_ERROR (Status
)) {
598 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
, ThunkContext
->FormSet
);
604 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
605 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
608 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
611 if (UOpcode
.Question
.QuestionId
== 0) {
612 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
613 if (EFI_ERROR (Status
)) {
614 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
618 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
619 if (EFI_ERROR (Status
)) {
624 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
625 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
627 // Each entry of Order List in Framework HII is always 1 byte in size
629 Status
= F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, 1, UefiData
);
630 if (EFI_ERROR (Status
)) {
633 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
637 Status
= UCreateEndOfOpcode (UefiData
);
638 if (!EFI_ERROR (Status
)) {
639 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
647 typedef struct _EFI_IFR_QUESTION_HEADER {
648 EFI_IFR_STATEMENT_HEADER Header;
649 EFI_QUESTION_ID QuestionId;
650 EFI_VARSTORE_ID VarStoreId;
652 EFI_STRING_ID VarName;
656 } EFI_IFR_QUESTION_HEADER;
660 typedef struct _EFI_IFR_CHECKBOX {
661 EFI_IFR_OP_HEADER Header;
662 EFI_IFR_QUESTION_HEADER Question;
669 FRAMEWORK_EFI_IFR_OP_HEADER Header;
670 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
671 UINT8 Width; // The Size of the Data being saved
672 STRING_REF Prompt; // The String Token for the Prompt
673 STRING_REF Help; // The string Token for the context-help
674 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely
675 UINT16 Key; // Value to be passed to caller to identify this particular op-code
676 } FRAMEWORK_EFI_IFR_CHECKBOX, FRAMEWORK_EFI_IFR_CHECK_BOX;
681 F2UCreateCheckBoxOpCode (
682 IN HII_THUNK_CONTEXT
*ThunkContext
,
683 IN UINT16 VarStoreId
,
684 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX
*FwOpcode
,
685 OUT EFI_HII_UPDATE_DATA
*UefiData
689 EFI_IFR_CHECKBOX UOpcode
;
691 ZeroMem (&UOpcode
, sizeof(UOpcode
));
693 UOpcode
.Header
.Length
= sizeof(UOpcode
);
694 UOpcode
.Header
.OpCode
= EFI_IFR_CHECKBOX_OP
;
696 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
697 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
699 if (FwOpcode
->Key
== 0) {
700 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
701 if (EFI_ERROR (Status
)) {
703 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
705 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
708 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
711 UOpcode
.Question
.VarStoreId
= FRAMEWORK_RESERVED_VARSTORE_ID
;
712 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
715 // We only 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.
720 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
723 // We also map 2 flags:
724 // FRAMEWORK_EFI_IFR_FLAG_DEFAULT,
725 // FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,
726 // to UEFI IFR CheckBox Opcode default flags.
728 UOpcode
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
));
730 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
735 typedef struct _EFI_IFR_QUESTION_HEADER {
736 EFI_IFR_STATEMENT_HEADER Header;
737 EFI_QUESTION_ID QuestionId;
738 EFI_VARSTORE_ID VarStoreId;
740 EFI_STRING_ID VarName;
744 } EFI_IFR_QUESTION_HEADER;
769 typedef struct _EFI_IFR_NUMERIC {
770 EFI_IFR_OP_HEADER Header;
771 EFI_IFR_QUESTION_HEADER Question;
773 MINMAXSTEP_DATA data;
778 FRAMEWORK_EFI_IFR_OP_HEADER Header;
779 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
780 UINT8 Width; // The Size of the Data being saved
781 STRING_REF Prompt; // The String Token for the Prompt
782 STRING_REF Help; // The string Token for the context-help
783 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
784 UINT16 Key; // Value to be passed to caller to identify this particular op-code
787 UINT16 Step; // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for
789 } FRAMEWORK_EFI_IFR_NUMERIC;
795 F2UCreateNumericOpCode (
796 IN HII_THUNK_CONTEXT
*ThunkContext
,
797 IN UINT16 VarStoreId
,
798 IN CONST FRAMEWORK_EFI_IFR_NUMERIC
*FwOpcode
,
799 OUT EFI_HII_UPDATE_DATA
*UefiData
803 EFI_IFR_NUMERIC UOpcode
;
804 EFI_IFR_DEFAULT UOpcodeDefault
;
806 ZeroMem (&UOpcode
, sizeof(UOpcode
));
808 if (FwOpcode
->Key
== 0) {
809 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
810 if (EFI_ERROR (Status
)) {
812 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
814 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
817 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
820 UOpcode
.Header
.Length
= sizeof(UOpcode
);
821 UOpcode
.Header
.OpCode
= EFI_IFR_NUMERIC_OP
;
823 // We need to create a nested default value for the UEFI Numeric Opcode.
824 // So turn on the scope.
826 UOpcode
.Header
.Scope
= 1;
828 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
829 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
831 UOpcode
.Question
.VarStoreId
= VarStoreId
;
832 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
834 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
837 // Framework Numeric values are all in UINT16 and displayed as decimal.
839 UOpcode
.data
.u16
.MinValue
= FwOpcode
->Minimum
;
840 UOpcode
.data
.u16
.MaxValue
= FwOpcode
->Maximum
;
841 UOpcode
.data
.u16
.Step
= FwOpcode
->Step
;
843 switch (FwOpcode
->Width
) {
846 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_1
| EFI_IFR_DISPLAY_UINT_DEC
;
851 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_2
| EFI_IFR_DISPLAY_UINT_DEC
;
857 return EFI_INVALID_PARAMETER
;
861 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
862 if (EFI_ERROR (Status
)) {
867 // We need to create a default value.
869 ZeroMem (&UOpcodeDefault
, sizeof (UOpcodeDefault
));
870 UOpcodeDefault
.Header
.Length
= sizeof (UOpcodeDefault
);
871 UOpcodeDefault
.Header
.OpCode
= EFI_IFR_DEFAULT_OP
;
873 UOpcodeDefault
.DefaultId
= 0;
875 switch (FwOpcode
->Width
) {
878 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
883 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
888 CopyMem (&UOpcodeDefault
.Value
.u8
, &FwOpcode
->Default
, FwOpcode
->Width
);
890 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcodeDefault
, sizeof(UOpcodeDefault
), UefiData
);
891 if (EFI_ERROR (Status
)) {
894 Status
= UCreateEndOfOpcode (UefiData
);
902 typedef struct _EFI_IFR_QUESTION_HEADER {
903 EFI_IFR_STATEMENT_HEADER Header;
904 EFI_QUESTION_ID QuestionId;
905 EFI_VARSTORE_ID VarStoreId;
907 EFI_STRING_ID VarName;
911 } EFI_IFR_QUESTION_HEADER;
913 typedef struct _EFI_IFR_STRING {
914 EFI_IFR_OP_HEADER Header;
915 EFI_IFR_QUESTION_HEADER Question;
923 FRAMEWORK_EFI_IFR_OP_HEADER Header;
924 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
925 UINT8 Width; // The Size of the Data being saved -- BUGBUG -- remove someday
926 STRING_REF Prompt; // The String Token for the Prompt
927 STRING_REF Help; // The string Token for the context-help
928 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
929 UINT16 Key; // Value to be passed to caller to identify this particular op-code
930 UINT8 MinSize; // Minimum allowable sized password
931 UINT8 MaxSize; // Maximum allowable sized password
932 } FRAMEWORK_EFI_IFR_STRING;
938 F2UCreateStringOpCode (
939 IN HII_THUNK_CONTEXT
*ThunkContext
,
940 IN UINT16 VarStoreId
,
941 IN CONST FRAMEWORK_EFI_IFR_STRING
*FwOpcode
,
942 OUT EFI_HII_UPDATE_DATA
*UefiData
945 EFI_IFR_STRING UOpcode
;
947 ZeroMem (&UOpcode
, sizeof(UOpcode
));
949 if (FwOpcode
->Key
== 0) {
950 FwQIdToUefiQId (ThunkContext
->FormSet
, VarStoreId
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
952 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
955 UOpcode
.Header
.Length
= sizeof(UOpcode
);
956 UOpcode
.Header
.OpCode
= EFI_IFR_STRING_OP
;
958 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
959 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
961 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
962 UOpcode
.Question
.VarStoreId
= FRAMEWORK_RESERVED_VARSTORE_ID
;
963 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
965 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
967 UOpcode
.MinSize
= FwOpcode
->MinSize
;
968 UOpcode
.MaxSize
= FwOpcode
->MaxSize
;
969 UOpcode
.Flags
= EFI_IFR_STRING_MULTI_LINE
;
971 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
975 typedef struct _EFI_IFR_GUID_BANNER {
976 EFI_IFR_OP_HEADER Header;
978 UINT8 ExtendOpCode; // Extended opcode is EFI_IFR_EXTEND_OP_BANNER
979 EFI_STRING_ID Title; // The string token for the banner title
980 UINT16 LineNumber; // 1-based line number
981 UINT8 Alignment; // left, center, or right-aligned
982 } EFI_IFR_GUID_BANNER;
985 FRAMEWORK_EFI_IFR_OP_HEADER Header;
986 STRING_REF Title; // The string token for the banner title
987 UINT16 LineNumber; // 1-based line number
988 UINT8 Alignment; // left, center, or right-aligned
989 } FRAMEWORK_EFI_IFR_BANNER;
994 F2UCreateBannerOpCode (
995 IN CONST FRAMEWORK_EFI_IFR_BANNER
*FwOpcode
,
996 OUT EFI_HII_UPDATE_DATA
*UefiData
999 EFI_IFR_GUID_BANNER UOpcode
;
1001 ZeroMem (&UOpcode
, sizeof(UOpcode
));
1003 UOpcode
.Header
.Length
= sizeof(UOpcode
);
1004 UOpcode
.Header
.OpCode
= EFI_IFR_GUID_OP
;
1006 CopyMem (&UOpcode
.Guid
, &mTianoExtendedOpcodeGuid
, sizeof (EFI_GUID
));
1007 UOpcode
.ExtendOpCode
= EFI_IFR_EXTEND_OP_BANNER
;
1008 UOpcode
.Title
= FwOpcode
->Title
;
1009 UOpcode
.LineNumber
= FwOpcode
->LineNumber
;
1010 UOpcode
.Alignment
= FwOpcode
->Alignment
;
1012 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
1017 FwUpdateDataToUefiUpdateData (
1018 IN HII_THUNK_CONTEXT
*ThunkContext
,
1019 IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA
*Data
,
1020 OUT EFI_HII_UPDATE_DATA
**UefiData
1023 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpCode
;
1024 FRAMEWORK_EFI_IFR_OP_HEADER
*NextFwOpCode
;
1025 EFI_HII_UPDATE_DATA
*UefiOpCode
;
1032 // Assume all dynamic opcode created is using active variable with VarStoreId of 1.
1036 UefiOpCode
= AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA
));
1037 if (UefiOpCode
== NULL
) {
1038 return EFI_OUT_OF_RESOURCES
;
1041 UefiOpCode
->Data
= AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
);
1042 if (UefiOpCode
->Data
== NULL
) {
1043 return EFI_OUT_OF_RESOURCES
;
1046 UefiOpCode
->BufferSize
= LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
;
1047 UefiOpCode
->Offset
= 0;
1049 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) &Data
->Data
;
1051 for (Index
= 0; Index
< Data
->DataCount
; Index
+= DataCount
) {
1052 switch (FwOpCode
->OpCode
) {
1053 case FRAMEWORK_EFI_IFR_SUBTITLE_OP
:
1054 Status
= F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE
*) FwOpCode
, UefiOpCode
);
1058 case FRAMEWORK_EFI_IFR_TEXT_OP
:
1059 Status
= F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT
*) FwOpCode
, UefiOpCode
);
1063 case FRAMEWORK_EFI_IFR_REF_OP
:
1064 Status
= F2UCreateGotoOpCode ((FRAMEWORK_EFI_IFR_REF
*) FwOpCode
, UefiOpCode
);
1068 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
1069 Status
= F2UCreateOneOfOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_ONE_OF
*) FwOpCode
, UefiOpCode
, &NextFwOpCode
, &DataCount
);
1070 if (!EFI_ERROR (Status
)) {
1071 FwOpCode
= NextFwOpCode
;
1073 // FwOpCode is already updated to point to the next opcode.
1079 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
:
1080 Status
= F2UCreateOrderedListOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_ORDERED_LIST
*) FwOpCode
, UefiOpCode
, &NextFwOpCode
, &DataCount
);
1081 if (!EFI_ERROR (Status
)) {
1082 FwOpCode
= NextFwOpCode
;
1084 // FwOpCode is already updated to point to the next opcode.
1090 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
1091 Status
= F2UCreateCheckBoxOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_CHECKBOX
*) FwOpCode
, UefiOpCode
);
1095 case FRAMEWORK_EFI_IFR_STRING_OP
:
1096 Status
= F2UCreateStringOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_STRING
*) FwOpCode
, UefiOpCode
);
1100 case FRAMEWORK_EFI_IFR_BANNER_OP
:
1101 Status
= F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER
*) FwOpCode
, UefiOpCode
);
1105 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP
:
1106 Status
= UCreateEndOfOpcode (UefiOpCode
);
1110 case FRAMEWORK_EFI_IFR_NUMERIC_OP
:
1111 Status
= F2UCreateNumericOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_NUMERIC
*) FwOpCode
, UefiOpCode
);
1117 return EFI_UNSUPPORTED
;
1120 if (EFI_ERROR (Status
)) {
1121 FreePool (UefiOpCode
->Data
);
1122 FreePool (UefiOpCode
);
1126 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpCode
+ FwOpCode
->Length
);
1129 *UefiData
= UefiOpCode
;