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
;
354 UOpcode
.Question
.VarStoreId
= VarStoreId
;
355 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
358 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
360 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
361 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
362 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
364 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
365 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
366 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
368 if (UOpcode
.Question
.QuestionId
== 0) {
369 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
370 if (EFI_ERROR (Status
)) {
371 UOpcode
.Question
.QuestionId
= FwOneOfOp
->Key
;
374 OneOfOptionMap
= AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP
));
375 ASSERT (OneOfOptionMap
!= NULL
);
376 OneOfOptionMap
->Signature
= ONE_OF_OPTION_MAP_SIGNATURE
;
377 OneOfOptionMap
->QuestionId
= UOpcode
.Question
.QuestionId
;
378 InitializeListHead (&OneOfOptionMap
->OneOfOptionMapEntryListHead
);
379 switch (FwOpcode
->Width
) {
381 OneOfOptionMap
->ValueType
= EFI_IFR_TYPE_NUM_SIZE_8
;
384 OneOfOptionMap
->ValueType
= EFI_IFR_TYPE_NUM_SIZE_16
;
390 InsertTailList (&ThunkContext
->OneOfOptionMapListHead
, &OneOfOptionMap
->Link
);
393 OneOfOptionMapEntry
= AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY
));
394 ASSERT (OneOfOptionMapEntry
!= NULL
);
396 OneOfOptionMapEntry
->FwKey
= FwOneOfOp
->Key
;
397 OneOfOptionMapEntry
->Signature
= ONE_OF_OPTION_MAP_ENTRY_SIGNATURE
;
399 CopyMem (&OneOfOptionMapEntry
->Value
, &FwOneOfOp
->Value
, FwOpcode
->Width
);
401 ASSERT (OneOfOptionMap
!= NULL
);
402 InsertTailList (&OneOfOptionMap
->OneOfOptionMapEntryListHead
, &OneOfOptionMapEntry
->Link
);
405 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
406 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
409 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
413 if (UOpcode
.Question
.QuestionId
== 0) {
415 // Assign QuestionId if still not assigned.
417 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
418 if (EFI_ERROR (Status
)) {
419 UOpcode
.Question
.QuestionId
= FwOpcode
->QuestionId
;
423 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof (UOpcode
), UefiData
);
424 if (EFI_ERROR (Status
)) {
430 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.
432 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
433 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
434 Status
= F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, FwOpcode
->Width
, UefiData
);
435 if (EFI_ERROR (Status
)) {
438 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
442 Status
= UCreateEndOfOpcode (UefiData
);
443 if (!EFI_ERROR (Status
)) {
444 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
452 typedef struct _EFI_IFR_QUESTION_HEADER {
453 EFI_IFR_STATEMENT_HEADER Header;
454 EFI_QUESTION_ID QuestionId;
455 EFI_VARSTORE_ID VarStoreId;
457 EFI_STRING_ID VarName;
461 } EFI_IFR_QUESTION_HEADER;
463 typedef struct _EFI_IFR_ORDERED_LIST {
464 EFI_IFR_OP_HEADER Header;
465 EFI_IFR_QUESTION_HEADER Question;
468 } EFI_IFR_ORDERED_LIST;
471 FRAMEWORK_EFI_IFR_OP_HEADER Header;
472 UINT16 QuestionId; // The offset in NV for storage of the data
473 UINT8 MaxEntries; // The maximum number of options in the ordered list (=size of NVStore)
474 STRING_REF Prompt; // The string token for the prompt
475 STRING_REF Help; // The string token for the context-help
476 } FRAMEWORK_EFI_IFR_ORDERED_LIST;
480 F2UCreateOrderedListOpCode (
481 IN HII_THUNK_CONTEXT
*ThunkContext
,
482 IN UINT16 VarStoreId
,
483 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST
*FwOpcode
,
484 OUT EFI_HII_UPDATE_DATA
*UefiData
,
485 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
489 EFI_IFR_ORDERED_LIST UOpcode
;
491 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
492 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
494 ZeroMem (&UOpcode
, sizeof(UOpcode
));
497 UOpcode
.Header
.Length
= sizeof(UOpcode
);
498 UOpcode
.Header
.OpCode
= EFI_IFR_ORDERED_LIST_OP
;
499 UOpcode
.Header
.Scope
= 1;
501 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
502 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
503 UOpcode
.Question
.VarStoreId
= VarStoreId
;
504 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
506 UOpcode
.MaxContainers
= FwOpcode
->MaxEntries
;
509 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
511 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
512 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
513 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
515 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
516 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
517 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
519 if (UOpcode
.Question
.QuestionId
== 0) {
520 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
521 if (EFI_ERROR (Status
)) {
522 UOpcode
.Question
.QuestionId
= FwOneOfOp
->Key
;
528 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
529 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
532 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
535 if (UOpcode
.Question
.QuestionId
== 0) {
536 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
537 if (EFI_ERROR (Status
)) {
538 UOpcode
.Question
.QuestionId
= FwOpcode
->QuestionId
;
542 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
543 if (EFI_ERROR (Status
)) {
548 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
549 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
551 // Each entry of Order List in Framework HII is always 1 byte in size
553 Status
= F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, 1, UefiData
);
554 if (EFI_ERROR (Status
)) {
557 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
561 Status
= UCreateEndOfOpcode (UefiData
);
562 if (!EFI_ERROR (Status
)) {
563 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
571 typedef struct _EFI_IFR_QUESTION_HEADER {
572 EFI_IFR_STATEMENT_HEADER Header;
573 EFI_QUESTION_ID QuestionId;
574 EFI_VARSTORE_ID VarStoreId;
576 EFI_STRING_ID VarName;
580 } EFI_IFR_QUESTION_HEADER;
584 typedef struct _EFI_IFR_CHECKBOX {
585 EFI_IFR_OP_HEADER Header;
586 EFI_IFR_QUESTION_HEADER Question;
593 FRAMEWORK_EFI_IFR_OP_HEADER Header;
594 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
595 UINT8 Width; // The Size of the Data being saved
596 STRING_REF Prompt; // The String Token for the Prompt
597 STRING_REF Help; // The string Token for the context-help
598 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely
599 UINT16 Key; // Value to be passed to caller to identify this particular op-code
600 } FRAMEWORK_EFI_IFR_CHECKBOX, FRAMEWORK_EFI_IFR_CHECK_BOX;
605 F2UCreateCheckBoxOpCode (
606 IN HII_THUNK_CONTEXT
*ThunkContext
,
607 IN UINT16 VarStoreId
,
608 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX
*FwOpcode
,
609 OUT EFI_HII_UPDATE_DATA
*UefiData
613 EFI_IFR_CHECKBOX UOpcode
;
615 ZeroMem (&UOpcode
, sizeof(UOpcode
));
617 UOpcode
.Header
.Length
= sizeof(UOpcode
);
618 UOpcode
.Header
.OpCode
= EFI_IFR_CHECKBOX_OP
;
620 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
621 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
623 if (FwOpcode
->Key
== 0) {
624 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
625 if (EFI_ERROR (Status
)) {
627 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
629 UOpcode
.Question
.QuestionId
= FwOpcode
->QuestionId
;
632 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
635 UOpcode
.Question
.VarStoreId
= RESERVED_VARSTORE_ID
;
636 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
639 // We only map 2 flags:
640 // FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE,
641 // FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,
642 // to UEFI IFR Opcode Question flags. The rest flags are obsolete.
644 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
647 // We also map 2 flags:
648 // FRAMEWORK_EFI_IFR_FLAG_DEFAULT,
649 // FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,
650 // to UEFI IFR CheckBox Opcode default flags.
652 UOpcode
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
));
654 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
659 typedef struct _EFI_IFR_QUESTION_HEADER {
660 EFI_IFR_STATEMENT_HEADER Header;
661 EFI_QUESTION_ID QuestionId;
662 EFI_VARSTORE_ID VarStoreId;
664 EFI_STRING_ID VarName;
668 } EFI_IFR_QUESTION_HEADER;
693 typedef struct _EFI_IFR_NUMERIC {
694 EFI_IFR_OP_HEADER Header;
695 EFI_IFR_QUESTION_HEADER Question;
697 MINMAXSTEP_DATA data;
702 FRAMEWORK_EFI_IFR_OP_HEADER Header;
703 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
704 UINT8 Width; // The Size of the Data being saved
705 STRING_REF Prompt; // The String Token for the Prompt
706 STRING_REF Help; // The string Token for the context-help
707 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
708 UINT16 Key; // Value to be passed to caller to identify this particular op-code
711 UINT16 Step; // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for
713 } FRAMEWORK_EFI_IFR_NUMERIC;
719 F2UCreateNumericOpCode (
720 IN HII_THUNK_CONTEXT
*ThunkContext
,
721 IN UINT16 VarStoreId
,
722 IN CONST FRAMEWORK_EFI_IFR_NUMERIC
*FwOpcode
,
723 OUT EFI_HII_UPDATE_DATA
*UefiData
727 EFI_IFR_NUMERIC UOpcode
;
728 EFI_IFR_DEFAULT UOpcodeDefault
;
730 ZeroMem (&UOpcode
, sizeof(UOpcode
));
732 if (FwOpcode
->Key
== 0) {
733 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
734 if (EFI_ERROR (Status
)) {
736 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
738 UOpcode
.Question
.QuestionId
= FwOpcode
->QuestionId
;
741 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
744 UOpcode
.Header
.Length
= sizeof(UOpcode
);
745 UOpcode
.Header
.OpCode
= EFI_IFR_NUMERIC_OP
;
747 // We need to create a nested default value for the UEFI Numeric Opcode.
748 // So turn on the scope.
750 if (FwOpcode
->Default
!= 0) {
751 UOpcode
.Header
.Scope
= 1;
754 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
755 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
757 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
759 // BUGBUG RESERVED_VARSTORE_ID should be passed in.
761 UOpcode
.Question
.VarStoreId
= RESERVED_VARSTORE_ID
;
762 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
764 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
767 // Framework Numeric values are all in UINT16 and displayed as decimal.
769 UOpcode
.data
.u16
.MinValue
= FwOpcode
->Minimum
;
770 UOpcode
.data
.u16
.MaxValue
= FwOpcode
->Maximum
;
771 UOpcode
.data
.u16
.Step
= FwOpcode
->Step
;
773 switch (FwOpcode
->Width
) {
776 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_2
| EFI_IFR_DISPLAY_UINT_DEC
;
781 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_1
| EFI_IFR_DISPLAY_UINT_DEC
;
787 return EFI_INVALID_PARAMETER
;
791 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
792 if (EFI_ERROR (Status
)) {
797 // We need to create a default value.
799 if (FwOpcode
->Default
!= 0) {
800 ZeroMem (&UOpcodeDefault
, sizeof (UOpcodeDefault
));
801 UOpcodeDefault
.Header
.Length
= sizeof (UOpcodeDefault
);
802 UOpcodeDefault
.Header
.OpCode
= EFI_IFR_DEFAULT_OP
;
804 UOpcodeDefault
.DefaultId
= 0;
806 switch (FwOpcode
->Width
) {
809 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
814 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
819 CopyMem (&UOpcodeDefault
.Value
.u8
, &FwOpcode
->Default
, FwOpcode
->Width
);
821 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcodeDefault
, sizeof(UOpcodeDefault
), UefiData
);
822 if (EFI_ERROR (Status
)) {
825 Status
= UCreateEndOfOpcode (UefiData
);
834 typedef struct _EFI_IFR_QUESTION_HEADER {
835 EFI_IFR_STATEMENT_HEADER Header;
836 EFI_QUESTION_ID QuestionId;
837 EFI_VARSTORE_ID VarStoreId;
839 EFI_STRING_ID VarName;
843 } EFI_IFR_QUESTION_HEADER;
845 typedef struct _EFI_IFR_STRING {
846 EFI_IFR_OP_HEADER Header;
847 EFI_IFR_QUESTION_HEADER Question;
855 FRAMEWORK_EFI_IFR_OP_HEADER Header;
856 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
857 UINT8 Width; // The Size of the Data being saved -- BUGBUG -- remove someday
858 STRING_REF Prompt; // The String Token for the Prompt
859 STRING_REF Help; // The string Token for the context-help
860 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
861 UINT16 Key; // Value to be passed to caller to identify this particular op-code
862 UINT8 MinSize; // Minimum allowable sized password
863 UINT8 MaxSize; // Maximum allowable sized password
864 } FRAMEWORK_EFI_IFR_STRING;
870 F2UCreateStringOpCode (
871 IN HII_THUNK_CONTEXT
*ThunkContext
,
872 IN UINT16 VarStoreId
,
873 IN CONST FRAMEWORK_EFI_IFR_STRING
*FwOpcode
,
874 OUT EFI_HII_UPDATE_DATA
*UefiData
877 EFI_IFR_STRING UOpcode
;
879 ZeroMem (&UOpcode
, sizeof(UOpcode
));
881 if (FwOpcode
->Key
== 0) {
882 FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
884 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
887 UOpcode
.Header
.Length
= sizeof(UOpcode
);
888 UOpcode
.Header
.OpCode
= EFI_IFR_STRING_OP
;
890 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
891 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
893 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
894 UOpcode
.Question
.VarStoreId
= RESERVED_VARSTORE_ID
;
895 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
897 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
899 UOpcode
.MinSize
= FwOpcode
->MinSize
;
900 UOpcode
.MaxSize
= FwOpcode
->MaxSize
;
901 UOpcode
.Flags
= EFI_IFR_STRING_MULTI_LINE
;
903 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
907 typedef struct _EFI_IFR_GUID_BANNER {
908 EFI_IFR_OP_HEADER Header;
910 UINT8 ExtendOpCode; // Extended opcode is EFI_IFR_EXTEND_OP_BANNER
911 EFI_STRING_ID Title; // The string token for the banner title
912 UINT16 LineNumber; // 1-based line number
913 UINT8 Alignment; // left, center, or right-aligned
914 } EFI_IFR_GUID_BANNER;
917 FRAMEWORK_EFI_IFR_OP_HEADER Header;
918 STRING_REF Title; // The string token for the banner title
919 UINT16 LineNumber; // 1-based line number
920 UINT8 Alignment; // left, center, or right-aligned
921 } FRAMEWORK_EFI_IFR_BANNER;
926 F2UCreateBannerOpCode (
927 IN CONST FRAMEWORK_EFI_IFR_BANNER
*FwOpcode
,
928 OUT EFI_HII_UPDATE_DATA
*UefiData
931 EFI_IFR_GUID_BANNER UOpcode
;
933 ZeroMem (&UOpcode
, sizeof(UOpcode
));
935 UOpcode
.Header
.Length
= sizeof(UOpcode
);
936 UOpcode
.Header
.OpCode
= EFI_IFR_GUID_OP
;
938 CopyMem (&UOpcode
.Guid
, &mTianoExtendedOpcodeGuid
, sizeof (EFI_GUID
));
939 UOpcode
.ExtendOpCode
= EFI_IFR_EXTEND_OP_BANNER
;
940 UOpcode
.Title
= FwOpcode
->Title
;
941 UOpcode
.LineNumber
= FwOpcode
->LineNumber
;
942 UOpcode
.Alignment
= FwOpcode
->Alignment
;
944 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
949 FwUpdateDataToUefiUpdateData (
950 IN HII_THUNK_CONTEXT
*ThunkContext
,
951 IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA
*Data
,
953 OUT EFI_HII_UPDATE_DATA
**UefiData
956 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpCode
;
957 FRAMEWORK_EFI_IFR_OP_HEADER
*NextFwOpCode
;
958 EFI_HII_UPDATE_DATA
*UefiOpCode
;
965 // Assume all dynamic opcode created is using active variable with VarStoreId of 1.
969 UefiOpCode
= AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA
));
970 if (UefiOpCode
== NULL
) {
971 return EFI_OUT_OF_RESOURCES
;
974 UefiOpCode
->Data
= AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
);
975 if (UefiOpCode
->Data
== NULL
) {
976 return EFI_OUT_OF_RESOURCES
;
979 UefiOpCode
->BufferSize
= LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
;
980 UefiOpCode
->Offset
= 0;
982 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) &Data
->Data
;
984 for (Index
= 0; Index
< Data
->DataCount
; Index
+= DataCount
) {
985 switch (FwOpCode
->OpCode
) {
986 case FRAMEWORK_EFI_IFR_SUBTITLE_OP
:
987 Status
= F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE
*) FwOpCode
, UefiOpCode
);
991 case FRAMEWORK_EFI_IFR_TEXT_OP
:
992 Status
= F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT
*) FwOpCode
, UefiOpCode
);
996 case FRAMEWORK_EFI_IFR_REF_OP
:
997 Status
= F2UCreateGotoOpCode ((FRAMEWORK_EFI_IFR_REF
*) FwOpCode
, UefiOpCode
);
1001 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
1002 Status
= F2UCreateOneOfOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_ONE_OF
*) 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_ORDERED_LIST_OP
:
1013 Status
= F2UCreateOrderedListOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_ORDERED_LIST
*) FwOpCode
, UefiOpCode
, &NextFwOpCode
, &DataCount
);
1014 if (!EFI_ERROR (Status
)) {
1015 FwOpCode
= NextFwOpCode
;
1017 // FwOpCode is already updated to point to the next opcode.
1023 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
1024 Status
= F2UCreateCheckBoxOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_CHECKBOX
*) FwOpCode
, UefiOpCode
);
1028 case FRAMEWORK_EFI_IFR_STRING_OP
:
1029 Status
= F2UCreateStringOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_STRING
*) FwOpCode
, UefiOpCode
);
1033 case FRAMEWORK_EFI_IFR_BANNER_OP
:
1034 Status
= F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER
*) FwOpCode
, UefiOpCode
);
1038 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP
:
1039 Status
= UCreateEndOfOpcode (UefiOpCode
);
1045 return EFI_UNSUPPORTED
;
1048 if (EFI_ERROR (Status
)) {
1049 FreePool (UefiOpCode
->Data
);
1050 FreePool (UefiOpCode
);
1054 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpCode
+ FwOpCode
->Length
);
1057 *UefiData
= UefiOpCode
;