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
;
21 #define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL 0x1000
23 AppendToUpdateBuffer (
24 IN CONST UINT8
*OpCodeBuf
,
26 OUT EFI_HII_UPDATE_DATA
*UefiData
31 if (UefiData
->Offset
+ BufSize
> UefiData
->BufferSize
) {
32 NewBuff
= AllocateCopyPool (UefiData
->BufferSize
+ LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
, UefiData
->Data
);
33 if (NewBuff
== NULL
) {
34 return EFI_OUT_OF_RESOURCES
;
36 UefiData
->BufferSize
+= LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
;
37 FreePool (UefiData
->Data
);
38 UefiData
->Data
= NewBuff
;
41 CopyMem (UefiData
->Data
+ UefiData
->Offset
, OpCodeBuf
, BufSize
);
42 UefiData
->Offset
+= (UINT32
) BufSize
;
50 FwQuestionIdToUefiQuestionId (
51 IN HII_THUNK_CONTEXT
*ThunkContext
,
54 OUT EFI_QUESTION_ID
*UefiQId
57 LIST_ENTRY
*MapEntryListHead
;
59 QUESTION_ID_MAP_ENTRY
*MapEntry
;
61 MapEntryListHead
= GetMapEntryListHead (ThunkContext
, VarStoreId
);
62 ASSERT (MapEntryListHead
!= NULL
);
64 Link
= GetFirstNode (MapEntryListHead
);
66 while (!IsNull (MapEntryListHead
, Link
)) {
67 MapEntry
= QUESTION_ID_MAP_ENTRY_FROM_LINK (Link
);
69 if (MapEntry
->FwQId
== FwId
) {
70 *UefiQId
= MapEntry
->UefiQid
;
74 Link
= GetNextNode (MapEntryListHead
, Link
);
84 OUT EFI_HII_UPDATE_DATA
*UefiData
89 ZeroMem (&UOpcode
, sizeof (UOpcode
));
91 UOpcode
.Header
.OpCode
= EFI_IFR_END_OP
;
92 UOpcode
.Header
.Length
= sizeof (UOpcode
);
94 return AppendToUpdateBuffer ((UINT8
*)&UOpcode
, sizeof(UOpcode
), UefiData
);
98 F2UCreateSubtitleOpCode (
99 IN CONST FRAMEWORK_EFI_IFR_SUBTITLE
*FwSubTitle
,
100 OUT EFI_HII_UPDATE_DATA
*UefiData
103 EFI_IFR_SUBTITLE UOpcode
;
105 ZeroMem (&UOpcode
, sizeof(UOpcode
));
107 UOpcode
.Header
.OpCode
= EFI_IFR_SUBTITLE_OP
;
108 UOpcode
.Header
.Length
= sizeof (EFI_IFR_SUBTITLE
);
110 UOpcode
.Statement
.Prompt
= FwSubTitle
->SubTitle
;
112 return AppendToUpdateBuffer ((UINT8
*)&UOpcode
, sizeof(UOpcode
), UefiData
);
116 F2UCreateTextOpCode (
117 IN CONST FRAMEWORK_EFI_IFR_TEXT
*FwText
,
118 OUT EFI_HII_UPDATE_DATA
*UefiData
121 EFI_IFR_TEXT UTextOpCode
;
122 EFI_IFR_ACTION UActionOpCode
;
124 if ((FwText
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) == 0) {
125 ZeroMem (&UTextOpCode
, sizeof(UTextOpCode
));
127 UTextOpCode
.Header
.OpCode
= EFI_IFR_TEXT_OP
;
128 UTextOpCode
.Header
.Length
= sizeof (EFI_IFR_TEXT
);
130 UTextOpCode
.Statement
.Help
= FwText
->Help
;
132 UTextOpCode
.Statement
.Prompt
= FwText
->Text
;
133 UTextOpCode
.TextTwo
= FwText
->TextTwo
;
135 return AppendToUpdateBuffer ((UINT8
*) &UTextOpCode
, sizeof(UTextOpCode
), UefiData
);
138 // Iteractive Text Opcode is EFI_IFR_ACTION
141 ZeroMem (&UActionOpCode
, sizeof (UActionOpCode
));
143 UActionOpCode
.Header
.OpCode
= EFI_IFR_ACTION_OP
;
144 UActionOpCode
.Header
.Length
= sizeof (EFI_IFR_ACTION
);
146 UActionOpCode
.Question
.Header
.Prompt
= FwText
->Text
;
147 UActionOpCode
.Question
.Header
.Help
= FwText
->Help
;
148 UActionOpCode
.Question
.Flags
= EFI_IFR_FLAG_CALLBACK
;
149 UActionOpCode
.Question
.QuestionId
= FwText
->Key
;
151 return AppendToUpdateBuffer ((UINT8
*) &UActionOpCode
, sizeof(UActionOpCode
), UefiData
);
158 FRAMEWORK_EFI_IFR_OP_HEADER Header;
161 STRING_REF Help; // The string Token for the context-help
162 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
163 UINT16 Key; // Value to be passed to caller to identify this particular op-code
164 } FRAMEWORK_EFI_IFR_REF;
168 F2UCreateGotoOpCode (
169 IN CONST FRAMEWORK_EFI_IFR_REF
*FwOpcode
,
170 OUT EFI_HII_UPDATE_DATA
*UefiData
175 ZeroMem (&UOpcode
, sizeof(UOpcode
));
177 UOpcode
.Header
.Length
= sizeof(UOpcode
);
178 UOpcode
.Header
.OpCode
= EFI_IFR_REF_OP
;
180 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
181 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
182 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
184 UOpcode
.FormId
= FwOpcode
->FormId
;
187 // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to
188 // UEFI IFR Opcode flags. The rest flags are obsolete.
190 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
193 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
199 FRAMEWORK_EFI_IFR_OP_HEADER Header;
200 STRING_REF Option; // The string token describing the option
201 UINT16 Value; // The value associated with this option that is stored in the NVRAM if chosen
202 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely above
203 UINT16 Key; // Value to be passed to caller to identify this particular op-code
204 } FRAMEWORK_EFI_IFR_ONE_OF_OPTION;
214 EFI_STRING_ID string;
215 } EFI_IFR_TYPE_VALUE;
217 typedef struct _EFI_IFR_ONE_OF_OPTION {
218 EFI_IFR_OP_HEADER Header;
219 EFI_STRING_ID Option;
222 EFI_IFR_TYPE_VALUE Value;
223 } EFI_IFR_ONE_OF_OPTION;
227 F2UCreateOneOfOptionOpCode (
228 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOpcode
,
230 OUT EFI_HII_UPDATE_DATA
*UefiData
233 EFI_IFR_ONE_OF_OPTION UOpcode
;
235 ZeroMem (&UOpcode
, sizeof(UOpcode
));
237 UOpcode
.Header
.Length
= sizeof(UOpcode
);
238 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OPTION_OP
;
240 UOpcode
.Option
= FwOpcode
->Option
;
241 CopyMem (&UOpcode
.Value
.u8
, &FwOpcode
->Value
, Width
);
245 // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT 0x01
246 // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING 0x02
247 // #define EFI_IFR_OPTION_DEFAULT 0x10
248 // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20
250 UOpcode
.Flags
|= (UINT8
) ((FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
)) << 4);
254 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
258 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
263 return EFI_UNSUPPORTED
;
266 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
271 typedef struct _EFI_IFR_QUESTION_HEADER {
272 EFI_IFR_STATEMENT_HEADER Header;
273 EFI_QUESTION_ID QuestionId;
274 EFI_VARSTORE_ID VarStoreId;
276 EFI_STRING_ID VarName;
280 } EFI_IFR_QUESTION_HEADER;
305 typedef struct _EFI_IFR_ONE_OF {
306 EFI_IFR_OP_HEADER Header;
307 EFI_IFR_QUESTION_HEADER Question;
309 MINMAXSTEP_DATA data;
313 FRAMEWORK_EFI_IFR_OP_HEADER Header;
314 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
315 UINT8 Width; // The Size of the Data being saved
316 STRING_REF Prompt; // The String Token for the Prompt
317 STRING_REF Help; // The string Token for the context-help
318 } FRAMEWORK_EFI_IFR_ONE_OF;
324 F2UCreateOneOfOpCode (
325 IN HII_THUNK_CONTEXT
*ThunkContext
,
326 IN UINT16 VarStoreId
,
327 IN CONST FRAMEWORK_EFI_IFR_ONE_OF
*FwOpcode
,
328 OUT EFI_HII_UPDATE_DATA
*UefiData
,
329 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
334 EFI_IFR_ONE_OF UOpcode
;
335 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
336 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
337 ONE_OF_OPTION_MAP
*OneOfOptionMap
;
338 ONE_OF_OPTION_MAP_ENTRY
*OneOfOptionMapEntry
;
340 ASSERT (NextFwOpcode
!= NULL
);
341 ASSERT (DataCount
!= NULL
);
343 OneOfOptionMap
= NULL
;
345 ZeroMem (&UOpcode
, sizeof(UOpcode
));
348 UOpcode
.Header
.Length
= sizeof(UOpcode
);
349 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OP
;
350 UOpcode
.Header
.Scope
= 1;
352 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
353 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
356 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
358 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
359 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
360 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
362 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
363 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
364 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
366 if (UOpcode
.Question
.QuestionId
== 0) {
367 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
368 if (EFI_ERROR (Status
)) {
369 UOpcode
.Question
.QuestionId
= FwOneOfOp
->Key
;
372 OneOfOptionMap
= AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP
));
373 ASSERT (OneOfOptionMap
!= NULL
);
374 OneOfOptionMap
->Signature
= ONE_OF_OPTION_MAP_SIGNATURE
;
375 OneOfOptionMap
->QuestionId
= UOpcode
.Question
.QuestionId
;
376 InitializeListHead (&OneOfOptionMap
->OneOfOptionMapEntryListHead
);
377 switch (FwOpcode
->Width
) {
379 OneOfOptionMap
->ValueType
= EFI_IFR_TYPE_NUM_SIZE_8
;
382 OneOfOptionMap
->ValueType
= EFI_IFR_TYPE_NUM_SIZE_16
;
388 InsertTailList (&ThunkContext
->OneOfOptionMapListHead
, &OneOfOptionMap
->Link
);
390 OneOfOptionMapEntry
= AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY
));
391 ASSERT (OneOfOptionMapEntry
!= NULL
);
393 OneOfOptionMapEntry
->FwKey
= FwOneOfOp
->Key
;
394 OneOfOptionMapEntry
->Signature
= ONE_OF_OPTION_MAP_ENTRY_SIGNATURE
;
396 CopyMem (&OneOfOptionMapEntry
->Value
, &FwOneOfOp
->Value
, FwOpcode
->Width
);
398 ASSERT (OneOfOptionMap
!= NULL
);
399 InsertTailList (&OneOfOptionMap
->OneOfOptionMapEntryListHead
, &OneOfOptionMapEntry
->Link
);
403 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
404 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
407 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
411 if (UOpcode
.Question
.QuestionId
== 0) {
413 // Assign QuestionId if still not assigned.
415 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
416 if (EFI_ERROR (Status
)) {
417 UOpcode
.Question
.QuestionId
= FwOpcode
->QuestionId
;
421 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof (UOpcode
), UefiData
);
422 if (EFI_ERROR (Status
)) {
428 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.
430 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
431 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
432 Status
= F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, FwOpcode
->Width
, UefiData
);
433 if (EFI_ERROR (Status
)) {
436 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
440 Status
= UCreateEndOfOpcode (UefiData
);
441 if (!EFI_ERROR (Status
)) {
442 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
450 typedef struct _EFI_IFR_QUESTION_HEADER {
451 EFI_IFR_STATEMENT_HEADER Header;
452 EFI_QUESTION_ID QuestionId;
453 EFI_VARSTORE_ID VarStoreId;
455 EFI_STRING_ID VarName;
459 } EFI_IFR_QUESTION_HEADER;
461 typedef struct _EFI_IFR_ORDERED_LIST {
462 EFI_IFR_OP_HEADER Header;
463 EFI_IFR_QUESTION_HEADER Question;
466 } EFI_IFR_ORDERED_LIST;
469 FRAMEWORK_EFI_IFR_OP_HEADER Header;
470 UINT16 QuestionId; // The offset in NV for storage of the data
471 UINT8 MaxEntries; // The maximum number of options in the ordered list (=size of NVStore)
472 STRING_REF Prompt; // The string token for the prompt
473 STRING_REF Help; // The string token for the context-help
474 } FRAMEWORK_EFI_IFR_ORDERED_LIST;
478 F2UCreateOrderedListOpCode (
479 IN HII_THUNK_CONTEXT
*ThunkContext
,
480 IN UINT16 VarStoreId
,
481 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST
*FwOpcode
,
482 OUT EFI_HII_UPDATE_DATA
*UefiData
,
483 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
487 EFI_IFR_ORDERED_LIST UOpcode
;
489 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
490 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
492 ZeroMem (&UOpcode
, sizeof(UOpcode
));
495 UOpcode
.Header
.Length
= sizeof(UOpcode
);
496 UOpcode
.Header
.OpCode
= EFI_IFR_ORDERED_LIST_OP
;
497 UOpcode
.Header
.Scope
= 1;
499 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
500 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
501 UOpcode
.Question
.VarStoreId
= VarStoreId
;
503 UOpcode
.MaxContainers
= FwOpcode
->MaxEntries
;
506 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
508 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
509 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
510 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
512 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
513 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
514 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
516 if (UOpcode
.Question
.QuestionId
== 0) {
517 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
518 if (EFI_ERROR (Status
)) {
519 UOpcode
.Question
.QuestionId
= FwOneOfOp
->Key
;
525 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
526 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
529 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
532 if (UOpcode
.Question
.QuestionId
== 0) {
533 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
534 if (EFI_ERROR (Status
)) {
535 UOpcode
.Question
.QuestionId
= FwOpcode
->QuestionId
;
539 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
540 if (EFI_ERROR (Status
)) {
545 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
546 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
548 // Each entry of Order List in Framework HII is always 1 byte in size
550 Status
= F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, 1, UefiData
);
551 if (EFI_ERROR (Status
)) {
554 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
558 Status
= UCreateEndOfOpcode (UefiData
);
559 if (!EFI_ERROR (Status
)) {
560 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
568 typedef struct _EFI_IFR_QUESTION_HEADER {
569 EFI_IFR_STATEMENT_HEADER Header;
570 EFI_QUESTION_ID QuestionId;
571 EFI_VARSTORE_ID VarStoreId;
573 EFI_STRING_ID VarName;
577 } EFI_IFR_QUESTION_HEADER;
581 typedef struct _EFI_IFR_CHECKBOX {
582 EFI_IFR_OP_HEADER Header;
583 EFI_IFR_QUESTION_HEADER Question;
590 FRAMEWORK_EFI_IFR_OP_HEADER Header;
591 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
592 UINT8 Width; // The Size of the Data being saved
593 STRING_REF Prompt; // The String Token for the Prompt
594 STRING_REF Help; // The string Token for the context-help
595 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely
596 UINT16 Key; // Value to be passed to caller to identify this particular op-code
597 } FRAMEWORK_EFI_IFR_CHECKBOX, FRAMEWORK_EFI_IFR_CHECK_BOX;
602 F2UCreateCheckBoxOpCode (
603 IN HII_THUNK_CONTEXT
*ThunkContext
,
604 IN UINT16 VarStoreId
,
605 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX
*FwOpcode
,
606 OUT EFI_HII_UPDATE_DATA
*UefiData
610 EFI_IFR_CHECKBOX UOpcode
;
612 ZeroMem (&UOpcode
, sizeof(UOpcode
));
614 UOpcode
.Header
.Length
= sizeof(UOpcode
);
615 UOpcode
.Header
.OpCode
= EFI_IFR_CHECKBOX_OP
;
617 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
618 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
620 if (FwOpcode
->Key
== 0) {
621 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
622 if (EFI_ERROR (Status
)) {
624 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
626 UOpcode
.Question
.QuestionId
= FwOpcode
->QuestionId
;
629 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
632 UOpcode
.Question
.VarStoreId
= RESERVED_VARSTORE_ID
;
633 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
636 // We only map 2 flags:
637 // FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE,
638 // FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,
639 // to UEFI IFR Opcode Question flags. The rest flags are obsolete.
641 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
644 // We also map 2 flags:
645 // FRAMEWORK_EFI_IFR_FLAG_DEFAULT,
646 // FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,
647 // to UEFI IFR CheckBox Opcode default flags.
649 UOpcode
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
));
651 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
656 typedef struct _EFI_IFR_QUESTION_HEADER {
657 EFI_IFR_STATEMENT_HEADER Header;
658 EFI_QUESTION_ID QuestionId;
659 EFI_VARSTORE_ID VarStoreId;
661 EFI_STRING_ID VarName;
665 } EFI_IFR_QUESTION_HEADER;
690 typedef struct _EFI_IFR_NUMERIC {
691 EFI_IFR_OP_HEADER Header;
692 EFI_IFR_QUESTION_HEADER Question;
694 MINMAXSTEP_DATA data;
699 FRAMEWORK_EFI_IFR_OP_HEADER Header;
700 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
701 UINT8 Width; // The Size of the Data being saved
702 STRING_REF Prompt; // The String Token for the Prompt
703 STRING_REF Help; // The string Token for the context-help
704 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
705 UINT16 Key; // Value to be passed to caller to identify this particular op-code
708 UINT16 Step; // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for
710 } FRAMEWORK_EFI_IFR_NUMERIC;
716 F2UCreateNumericOpCode (
717 IN HII_THUNK_CONTEXT
*ThunkContext
,
718 IN UINT16 VarStoreId
,
719 IN CONST FRAMEWORK_EFI_IFR_NUMERIC
*FwOpcode
,
720 OUT EFI_HII_UPDATE_DATA
*UefiData
724 EFI_IFR_NUMERIC UOpcode
;
725 EFI_IFR_DEFAULT UOpcodeDefault
;
727 ZeroMem (&UOpcode
, sizeof(UOpcode
));
729 if (FwOpcode
->Key
== 0) {
730 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
731 if (EFI_ERROR (Status
)) {
733 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
735 UOpcode
.Question
.QuestionId
= FwOpcode
->QuestionId
;
738 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
741 UOpcode
.Header
.Length
= sizeof(UOpcode
);
742 UOpcode
.Header
.OpCode
= EFI_IFR_NUMERIC_OP
;
744 // We need to create a nested default value for the UEFI Numeric Opcode.
745 // So turn on the scope.
747 if (FwOpcode
->Default
!= 0) {
748 UOpcode
.Header
.Scope
= 1;
751 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
752 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
754 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
756 // BUGBUG RESERVED_VARSTORE_ID should be passed in.
758 UOpcode
.Question
.VarStoreId
= RESERVED_VARSTORE_ID
;
759 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
761 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
764 // Framework Numeric values are all in UINT16 and displayed as decimal.
766 UOpcode
.data
.u16
.MinValue
= FwOpcode
->Minimum
;
767 UOpcode
.data
.u16
.MaxValue
= FwOpcode
->Maximum
;
768 UOpcode
.data
.u16
.Step
= FwOpcode
->Step
;
770 switch (FwOpcode
->Width
) {
773 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_2
| EFI_IFR_DISPLAY_UINT_DEC
;
778 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_1
| EFI_IFR_DISPLAY_UINT_DEC
;
784 return EFI_INVALID_PARAMETER
;
788 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
789 if (EFI_ERROR (Status
)) {
794 // We need to create a default value.
796 if (FwOpcode
->Default
!= 0) {
797 ZeroMem (&UOpcodeDefault
, sizeof (UOpcodeDefault
));
798 UOpcodeDefault
.Header
.Length
= sizeof (UOpcodeDefault
);
799 UOpcodeDefault
.Header
.OpCode
= EFI_IFR_DEFAULT_OP
;
801 UOpcodeDefault
.DefaultId
= 0;
803 switch (FwOpcode
->Width
) {
806 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
811 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
816 CopyMem (&UOpcodeDefault
.Value
.u8
, &FwOpcode
->Default
, FwOpcode
->Width
);
818 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcodeDefault
, sizeof(UOpcodeDefault
), UefiData
);
819 if (EFI_ERROR (Status
)) {
822 Status
= UCreateEndOfOpcode (UefiData
);
831 typedef struct _EFI_IFR_QUESTION_HEADER {
832 EFI_IFR_STATEMENT_HEADER Header;
833 EFI_QUESTION_ID QuestionId;
834 EFI_VARSTORE_ID VarStoreId;
836 EFI_STRING_ID VarName;
840 } EFI_IFR_QUESTION_HEADER;
842 typedef struct _EFI_IFR_STRING {
843 EFI_IFR_OP_HEADER Header;
844 EFI_IFR_QUESTION_HEADER Question;
852 FRAMEWORK_EFI_IFR_OP_HEADER Header;
853 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
854 UINT8 Width; // The Size of the Data being saved -- BUGBUG -- remove someday
855 STRING_REF Prompt; // The String Token for the Prompt
856 STRING_REF Help; // The string Token for the context-help
857 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
858 UINT16 Key; // Value to be passed to caller to identify this particular op-code
859 UINT8 MinSize; // Minimum allowable sized password
860 UINT8 MaxSize; // Maximum allowable sized password
861 } FRAMEWORK_EFI_IFR_STRING;
867 F2UCreateStringOpCode (
868 IN HII_THUNK_CONTEXT
*ThunkContext
,
869 IN UINT16 VarStoreId
,
870 IN CONST FRAMEWORK_EFI_IFR_STRING
*FwOpcode
,
871 OUT EFI_HII_UPDATE_DATA
*UefiData
874 EFI_IFR_STRING UOpcode
;
876 ZeroMem (&UOpcode
, sizeof(UOpcode
));
878 if (FwOpcode
->Key
== 0) {
879 FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
881 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
884 UOpcode
.Header
.Length
= sizeof(UOpcode
);
885 UOpcode
.Header
.OpCode
= EFI_IFR_STRING_OP
;
887 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
888 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
890 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
891 UOpcode
.Question
.VarStoreId
= RESERVED_VARSTORE_ID
;
892 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
894 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
896 UOpcode
.MinSize
= FwOpcode
->MinSize
;
897 UOpcode
.MaxSize
= FwOpcode
->MaxSize
;
898 UOpcode
.Flags
= EFI_IFR_STRING_MULTI_LINE
;
900 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
904 typedef struct _EFI_IFR_GUID_BANNER {
905 EFI_IFR_OP_HEADER Header;
907 UINT8 ExtendOpCode; // Extended opcode is EFI_IFR_EXTEND_OP_BANNER
908 EFI_STRING_ID Title; // The string token for the banner title
909 UINT16 LineNumber; // 1-based line number
910 UINT8 Alignment; // left, center, or right-aligned
911 } EFI_IFR_GUID_BANNER;
914 FRAMEWORK_EFI_IFR_OP_HEADER Header;
915 STRING_REF Title; // The string token for the banner title
916 UINT16 LineNumber; // 1-based line number
917 UINT8 Alignment; // left, center, or right-aligned
918 } FRAMEWORK_EFI_IFR_BANNER;
923 F2UCreateBannerOpCode (
924 IN CONST FRAMEWORK_EFI_IFR_BANNER
*FwOpcode
,
925 OUT EFI_HII_UPDATE_DATA
*UefiData
928 EFI_IFR_GUID_BANNER UOpcode
;
930 ZeroMem (&UOpcode
, sizeof(UOpcode
));
932 UOpcode
.Header
.Length
= sizeof(UOpcode
);
933 UOpcode
.Header
.OpCode
= EFI_IFR_GUID_OP
;
935 CopyMem (&UOpcode
.Guid
, &mTianoExtendedOpcodeGuid
, sizeof (EFI_GUID
));
936 UOpcode
.ExtendOpCode
= EFI_IFR_EXTEND_OP_BANNER
;
937 UOpcode
.Title
= FwOpcode
->Title
;
938 UOpcode
.LineNumber
= FwOpcode
->LineNumber
;
939 UOpcode
.Alignment
= FwOpcode
->Alignment
;
941 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
946 FwUpdateDataToUefiUpdateData (
947 IN HII_THUNK_CONTEXT
*ThunkContext
,
948 IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA
*Data
,
950 OUT EFI_HII_UPDATE_DATA
**UefiData
953 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpCode
;
954 FRAMEWORK_EFI_IFR_OP_HEADER
*NextFwOpCode
;
955 EFI_HII_UPDATE_DATA
*UefiOpCode
;
962 // Assume all dynamic opcode created is using active variable with VarStoreId of 1.
966 UefiOpCode
= AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA
));
967 if (UefiOpCode
== NULL
) {
968 return EFI_OUT_OF_RESOURCES
;
971 UefiOpCode
->Data
= AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
);
972 if (UefiOpCode
->Data
== NULL
) {
973 return EFI_OUT_OF_RESOURCES
;
976 UefiOpCode
->BufferSize
= LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
;
977 UefiOpCode
->Offset
= 0;
979 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) &Data
->Data
;
981 for (Index
= 0; Index
< Data
->DataCount
; Index
+= DataCount
) {
982 switch (FwOpCode
->OpCode
) {
983 case FRAMEWORK_EFI_IFR_SUBTITLE_OP
:
984 Status
= F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE
*) FwOpCode
, UefiOpCode
);
988 case FRAMEWORK_EFI_IFR_TEXT_OP
:
989 Status
= F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT
*) FwOpCode
, UefiOpCode
);
993 case FRAMEWORK_EFI_IFR_REF_OP
:
994 Status
= F2UCreateGotoOpCode ((FRAMEWORK_EFI_IFR_REF
*) FwOpCode
, UefiOpCode
);
998 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
999 Status
= F2UCreateOneOfOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_ONE_OF
*) FwOpCode
, UefiOpCode
, &NextFwOpCode
, &DataCount
);
1000 if (!EFI_ERROR (Status
)) {
1001 FwOpCode
= NextFwOpCode
;
1003 // FwOpCode is already updated to point to the next opcode.
1009 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
:
1010 Status
= F2UCreateOrderedListOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_ORDERED_LIST
*) FwOpCode
, UefiOpCode
, &NextFwOpCode
, &DataCount
);
1011 if (!EFI_ERROR (Status
)) {
1012 FwOpCode
= NextFwOpCode
;
1014 // FwOpCode is already updated to point to the next opcode.
1020 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
1021 Status
= F2UCreateCheckBoxOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_CHECKBOX
*) FwOpCode
, UefiOpCode
);
1025 case FRAMEWORK_EFI_IFR_STRING_OP
:
1026 Status
= F2UCreateStringOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_STRING
*) FwOpCode
, UefiOpCode
);
1030 case FRAMEWORK_EFI_IFR_BANNER_OP
:
1031 Status
= F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER
*) FwOpCode
, UefiOpCode
);
1035 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP
:
1036 Status
= UCreateEndOfOpcode (UefiOpCode
);
1042 return EFI_UNSUPPORTED
;
1045 if (EFI_ERROR (Status
)) {
1046 FreePool (UefiOpCode
->Data
);
1047 FreePool (UefiOpCode
);
1051 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpCode
+ FwOpCode
->Length
);
1054 *UefiData
= UefiOpCode
;