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
;
49 IN UINT16 FwQuestionId
52 if (FwQuestionId
== 0) {
54 // In UEFI IFR, the Question ID can't be zero. Zero means no storage.
55 // So use 0xABBA as a Question ID.
65 FwQuestionIdToUefiQuestionId (
66 IN HII_THUNK_CONTEXT
*ThunkContext
,
69 OUT EFI_QUESTION_ID
*UefiQId
72 LIST_ENTRY
*MapEntryListHead
;
74 QUESTION_ID_MAP_ENTRY
*MapEntry
;
76 MapEntryListHead
= GetMapEntryListHead (ThunkContext
, VarStoreId
);
77 ASSERT (MapEntryListHead
!= NULL
);
79 Link
= GetFirstNode (MapEntryListHead
);
81 while (!IsNull (MapEntryListHead
, Link
)) {
82 MapEntry
= QUESTION_ID_MAP_ENTRY_FROM_LINK (Link
);
84 if (MapEntry
->FwQId
== FwId
) {
85 *UefiQId
= MapEntry
->UefiQid
;
89 Link
= GetNextNode (MapEntryListHead
, Link
);
99 OUT EFI_HII_UPDATE_DATA
*UefiData
104 ZeroMem (&UOpcode
, sizeof (UOpcode
));
106 UOpcode
.Header
.OpCode
= EFI_IFR_END_OP
;
107 UOpcode
.Header
.Length
= sizeof (UOpcode
);
109 return AppendToUpdateBuffer ((UINT8
*)&UOpcode
, sizeof(UOpcode
), UefiData
);
113 F2UCreateSubtitleOpCode (
114 IN CONST FRAMEWORK_EFI_IFR_SUBTITLE
*FwSubTitle
,
115 OUT EFI_HII_UPDATE_DATA
*UefiData
118 EFI_IFR_SUBTITLE UOpcode
;
120 ZeroMem (&UOpcode
, sizeof(UOpcode
));
122 UOpcode
.Header
.OpCode
= EFI_IFR_SUBTITLE_OP
;
123 UOpcode
.Header
.Length
= sizeof (EFI_IFR_SUBTITLE
);
125 UOpcode
.Statement
.Prompt
= FwSubTitle
->SubTitle
;
127 return AppendToUpdateBuffer ((UINT8
*)&UOpcode
, sizeof(UOpcode
), UefiData
);
131 F2UCreateTextOpCode (
132 IN CONST FRAMEWORK_EFI_IFR_TEXT
*FwText
,
133 OUT EFI_HII_UPDATE_DATA
*UefiData
136 EFI_IFR_TEXT UTextOpCode
;
137 EFI_IFR_ACTION UActionOpCode
;
139 if ((FwText
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) == 0) {
140 ZeroMem (&UTextOpCode
, sizeof(UTextOpCode
));
142 UTextOpCode
.Header
.OpCode
= EFI_IFR_TEXT_OP
;
143 UTextOpCode
.Header
.Length
= sizeof (EFI_IFR_TEXT
);
145 UTextOpCode
.Statement
.Help
= FwText
->Help
;
147 UTextOpCode
.Statement
.Prompt
= FwText
->Text
;
148 UTextOpCode
.TextTwo
= FwText
->TextTwo
;
150 return AppendToUpdateBuffer ((UINT8
*) &UTextOpCode
, sizeof(UTextOpCode
), UefiData
);
153 // Iteractive Text Opcode is EFI_IFR_ACTION
156 ZeroMem (&UActionOpCode
, sizeof (UActionOpCode
));
158 UActionOpCode
.Header
.OpCode
= EFI_IFR_ACTION_OP
;
159 UActionOpCode
.Header
.Length
= sizeof (EFI_IFR_ACTION
);
161 UActionOpCode
.Question
.Header
.Prompt
= FwText
->Text
;
162 UActionOpCode
.Question
.Header
.Help
= FwText
->Help
;
163 UActionOpCode
.Question
.Flags
= EFI_IFR_FLAG_CALLBACK
;
164 UActionOpCode
.Question
.QuestionId
= FwText
->Key
;
166 return AppendToUpdateBuffer ((UINT8
*) &UActionOpCode
, sizeof(UActionOpCode
), UefiData
);
173 FRAMEWORK_EFI_IFR_OP_HEADER Header;
176 STRING_REF Help; // The string Token for the context-help
177 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
178 UINT16 Key; // Value to be passed to caller to identify this particular op-code
179 } FRAMEWORK_EFI_IFR_REF;
183 F2UCreateGotoOpCode (
184 IN CONST FRAMEWORK_EFI_IFR_REF
*FwOpcode
,
185 OUT EFI_HII_UPDATE_DATA
*UefiData
190 ZeroMem (&UOpcode
, sizeof(UOpcode
));
192 UOpcode
.Header
.Length
= sizeof(UOpcode
);
193 UOpcode
.Header
.OpCode
= EFI_IFR_REF_OP
;
195 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
196 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
197 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
199 UOpcode
.FormId
= FwOpcode
->FormId
;
202 // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to
203 // UEFI IFR Opcode flags. The rest flags are obsolete.
205 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
208 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
214 FRAMEWORK_EFI_IFR_OP_HEADER Header;
215 STRING_REF Option; // The string token describing the option
216 UINT16 Value; // The value associated with this option that is stored in the NVRAM if chosen
217 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely above
218 UINT16 Key; // Value to be passed to caller to identify this particular op-code
219 } FRAMEWORK_EFI_IFR_ONE_OF_OPTION;
229 EFI_STRING_ID string;
230 } EFI_IFR_TYPE_VALUE;
232 typedef struct _EFI_IFR_ONE_OF_OPTION {
233 EFI_IFR_OP_HEADER Header;
234 EFI_STRING_ID Option;
237 EFI_IFR_TYPE_VALUE Value;
238 } EFI_IFR_ONE_OF_OPTION;
242 F2UCreateOneOfOptionOpCode (
243 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOpcode
,
245 OUT EFI_HII_UPDATE_DATA
*UefiData
248 EFI_IFR_ONE_OF_OPTION UOpcode
;
250 ZeroMem (&UOpcode
, sizeof(UOpcode
));
252 UOpcode
.Header
.Length
= sizeof(UOpcode
);
253 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OPTION_OP
;
255 UOpcode
.Option
= FwOpcode
->Option
;
256 CopyMem (&UOpcode
.Value
.u8
, &FwOpcode
->Value
, Width
);
260 // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT 0x01
261 // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING 0x02
262 // #define EFI_IFR_OPTION_DEFAULT 0x10
263 // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20
265 UOpcode
.Flags
|= (UINT8
) ((FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
)) << 4);
269 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
273 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
278 return EFI_UNSUPPORTED
;
281 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
286 typedef struct _EFI_IFR_QUESTION_HEADER {
287 EFI_IFR_STATEMENT_HEADER Header;
288 EFI_QUESTION_ID QuestionId;
289 EFI_VARSTORE_ID VarStoreId;
291 EFI_STRING_ID VarName;
295 } EFI_IFR_QUESTION_HEADER;
320 typedef struct _EFI_IFR_ONE_OF {
321 EFI_IFR_OP_HEADER Header;
322 EFI_IFR_QUESTION_HEADER Question;
324 MINMAXSTEP_DATA data;
328 FRAMEWORK_EFI_IFR_OP_HEADER Header;
329 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
330 UINT8 Width; // The Size of the Data being saved
331 STRING_REF Prompt; // The String Token for the Prompt
332 STRING_REF Help; // The string Token for the context-help
333 } FRAMEWORK_EFI_IFR_ONE_OF;
339 F2UCreateOneOfOpCode (
340 IN HII_THUNK_CONTEXT
*ThunkContext
,
341 IN UINT16 VarStoreId
,
342 IN CONST FRAMEWORK_EFI_IFR_ONE_OF
*FwOpcode
,
343 OUT EFI_HII_UPDATE_DATA
*UefiData
,
344 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
349 EFI_IFR_ONE_OF UOpcode
;
350 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
351 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
352 ONE_OF_OPTION_MAP
*OneOfOptionMap
;
353 ONE_OF_OPTION_MAP_ENTRY
*OneOfOptionMapEntry
;
355 ASSERT (NextFwOpcode
!= NULL
);
356 ASSERT (DataCount
!= NULL
);
358 OneOfOptionMap
= NULL
;
360 ZeroMem (&UOpcode
, sizeof(UOpcode
));
363 UOpcode
.Header
.Length
= sizeof(UOpcode
);
364 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OP
;
365 UOpcode
.Header
.Scope
= 1;
367 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
368 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
369 UOpcode
.Question
.VarStoreId
= VarStoreId
;
370 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
373 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
375 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
376 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
377 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
379 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
380 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
381 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
383 if (UOpcode
.Question
.QuestionId
== 0) {
384 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
385 if (EFI_ERROR (Status
)) {
386 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
);
389 OneOfOptionMap
= AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP
));
390 ASSERT (OneOfOptionMap
!= NULL
);
391 OneOfOptionMap
->Signature
= ONE_OF_OPTION_MAP_SIGNATURE
;
392 OneOfOptionMap
->QuestionId
= UOpcode
.Question
.QuestionId
;
393 InitializeListHead (&OneOfOptionMap
->OneOfOptionMapEntryListHead
);
394 switch (FwOpcode
->Width
) {
396 OneOfOptionMap
->ValueType
= EFI_IFR_TYPE_NUM_SIZE_8
;
399 OneOfOptionMap
->ValueType
= EFI_IFR_TYPE_NUM_SIZE_16
;
406 InsertTailList (&ThunkContext
->OneOfOptionMapListHead
, &OneOfOptionMap
->Link
);
409 OneOfOptionMapEntry
= AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY
));
410 ASSERT (OneOfOptionMapEntry
!= NULL
);
412 OneOfOptionMapEntry
->FwKey
= FwOneOfOp
->Key
;
413 OneOfOptionMapEntry
->Signature
= ONE_OF_OPTION_MAP_ENTRY_SIGNATURE
;
415 CopyMem (&OneOfOptionMapEntry
->Value
, &FwOneOfOp
->Value
, FwOpcode
->Width
);
417 ASSERT (OneOfOptionMap
!= NULL
);
418 InsertTailList (&OneOfOptionMap
->OneOfOptionMapEntryListHead
, &OneOfOptionMapEntry
->Link
);
421 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
422 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
425 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
429 if (UOpcode
.Question
.QuestionId
== 0) {
431 // Assign QuestionId if still not assigned.
433 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
434 if (EFI_ERROR (Status
)) {
435 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
);
439 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof (UOpcode
), UefiData
);
440 if (EFI_ERROR (Status
)) {
446 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.
448 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
449 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
450 Status
= F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, FwOpcode
->Width
, UefiData
);
451 if (EFI_ERROR (Status
)) {
454 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
458 Status
= UCreateEndOfOpcode (UefiData
);
459 if (!EFI_ERROR (Status
)) {
460 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
468 typedef struct _EFI_IFR_QUESTION_HEADER {
469 EFI_IFR_STATEMENT_HEADER Header;
470 EFI_QUESTION_ID QuestionId;
471 EFI_VARSTORE_ID VarStoreId;
473 EFI_STRING_ID VarName;
477 } EFI_IFR_QUESTION_HEADER;
479 typedef struct _EFI_IFR_ORDERED_LIST {
480 EFI_IFR_OP_HEADER Header;
481 EFI_IFR_QUESTION_HEADER Question;
484 } EFI_IFR_ORDERED_LIST;
487 FRAMEWORK_EFI_IFR_OP_HEADER Header;
488 UINT16 QuestionId; // The offset in NV for storage of the data
489 UINT8 MaxEntries; // The maximum number of options in the ordered list (=size of NVStore)
490 STRING_REF Prompt; // The string token for the prompt
491 STRING_REF Help; // The string token for the context-help
492 } FRAMEWORK_EFI_IFR_ORDERED_LIST;
496 F2UCreateOrderedListOpCode (
497 IN HII_THUNK_CONTEXT
*ThunkContext
,
498 IN UINT16 VarStoreId
,
499 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST
*FwOpcode
,
500 OUT EFI_HII_UPDATE_DATA
*UefiData
,
501 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
505 EFI_IFR_ORDERED_LIST UOpcode
;
507 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
508 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
510 ZeroMem (&UOpcode
, sizeof(UOpcode
));
513 UOpcode
.Header
.Length
= sizeof(UOpcode
);
514 UOpcode
.Header
.OpCode
= EFI_IFR_ORDERED_LIST_OP
;
515 UOpcode
.Header
.Scope
= 1;
517 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
518 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
519 UOpcode
.Question
.VarStoreId
= VarStoreId
;
520 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
522 UOpcode
.MaxContainers
= FwOpcode
->MaxEntries
;
525 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
527 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
528 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
529 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
531 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
532 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
533 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
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
= AssignQuestionId (FwOneOfOp
->Key
);
544 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
545 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
548 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
551 if (UOpcode
.Question
.QuestionId
== 0) {
552 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
553 if (EFI_ERROR (Status
)) {
554 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
);
558 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
559 if (EFI_ERROR (Status
)) {
564 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
565 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
567 // Each entry of Order List in Framework HII is always 1 byte in size
569 Status
= F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, 1, UefiData
);
570 if (EFI_ERROR (Status
)) {
573 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
577 Status
= UCreateEndOfOpcode (UefiData
);
578 if (!EFI_ERROR (Status
)) {
579 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
587 typedef struct _EFI_IFR_QUESTION_HEADER {
588 EFI_IFR_STATEMENT_HEADER Header;
589 EFI_QUESTION_ID QuestionId;
590 EFI_VARSTORE_ID VarStoreId;
592 EFI_STRING_ID VarName;
596 } EFI_IFR_QUESTION_HEADER;
600 typedef struct _EFI_IFR_CHECKBOX {
601 EFI_IFR_OP_HEADER Header;
602 EFI_IFR_QUESTION_HEADER Question;
609 FRAMEWORK_EFI_IFR_OP_HEADER Header;
610 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
611 UINT8 Width; // The Size of the Data being saved
612 STRING_REF Prompt; // The String Token for the Prompt
613 STRING_REF Help; // The string Token for the context-help
614 UINT8 Flags; // For now, if non-zero, means that it is the default option, - further definition likely
615 UINT16 Key; // Value to be passed to caller to identify this particular op-code
616 } FRAMEWORK_EFI_IFR_CHECKBOX, FRAMEWORK_EFI_IFR_CHECK_BOX;
621 F2UCreateCheckBoxOpCode (
622 IN HII_THUNK_CONTEXT
*ThunkContext
,
623 IN UINT16 VarStoreId
,
624 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX
*FwOpcode
,
625 OUT EFI_HII_UPDATE_DATA
*UefiData
629 EFI_IFR_CHECKBOX UOpcode
;
631 ZeroMem (&UOpcode
, sizeof(UOpcode
));
633 UOpcode
.Header
.Length
= sizeof(UOpcode
);
634 UOpcode
.Header
.OpCode
= EFI_IFR_CHECKBOX_OP
;
636 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
637 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
639 if (FwOpcode
->Key
== 0) {
640 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
641 if (EFI_ERROR (Status
)) {
643 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
645 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
);
648 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
651 UOpcode
.Question
.VarStoreId
= RESERVED_VARSTORE_ID
;
652 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
655 // We only map 2 flags:
656 // FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE,
657 // FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,
658 // to UEFI IFR Opcode Question flags. The rest flags are obsolete.
660 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
663 // We also map 2 flags:
664 // FRAMEWORK_EFI_IFR_FLAG_DEFAULT,
665 // FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,
666 // to UEFI IFR CheckBox Opcode default flags.
668 UOpcode
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
));
670 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
675 typedef struct _EFI_IFR_QUESTION_HEADER {
676 EFI_IFR_STATEMENT_HEADER Header;
677 EFI_QUESTION_ID QuestionId;
678 EFI_VARSTORE_ID VarStoreId;
680 EFI_STRING_ID VarName;
684 } EFI_IFR_QUESTION_HEADER;
709 typedef struct _EFI_IFR_NUMERIC {
710 EFI_IFR_OP_HEADER Header;
711 EFI_IFR_QUESTION_HEADER Question;
713 MINMAXSTEP_DATA data;
718 FRAMEWORK_EFI_IFR_OP_HEADER Header;
719 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
720 UINT8 Width; // The Size of the Data being saved
721 STRING_REF Prompt; // The String Token for the Prompt
722 STRING_REF Help; // The string Token for the context-help
723 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
724 UINT16 Key; // Value to be passed to caller to identify this particular op-code
727 UINT16 Step; // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for
729 } FRAMEWORK_EFI_IFR_NUMERIC;
735 F2UCreateNumericOpCode (
736 IN HII_THUNK_CONTEXT
*ThunkContext
,
737 IN UINT16 VarStoreId
,
738 IN CONST FRAMEWORK_EFI_IFR_NUMERIC
*FwOpcode
,
739 OUT EFI_HII_UPDATE_DATA
*UefiData
743 EFI_IFR_NUMERIC UOpcode
;
744 EFI_IFR_DEFAULT UOpcodeDefault
;
746 ZeroMem (&UOpcode
, sizeof(UOpcode
));
748 if (FwOpcode
->Key
== 0) {
749 Status
= FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
750 if (EFI_ERROR (Status
)) {
752 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
754 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
);
757 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
760 UOpcode
.Header
.Length
= sizeof(UOpcode
);
761 UOpcode
.Header
.OpCode
= EFI_IFR_NUMERIC_OP
;
763 // We need to create a nested default value for the UEFI Numeric Opcode.
764 // So turn on the scope.
766 UOpcode
.Header
.Scope
= 1;
768 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
769 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
771 UOpcode
.Question
.VarStoreId
= VarStoreId
;
772 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
774 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
777 // Framework Numeric values are all in UINT16 and displayed as decimal.
779 UOpcode
.data
.u16
.MinValue
= FwOpcode
->Minimum
;
780 UOpcode
.data
.u16
.MaxValue
= FwOpcode
->Maximum
;
781 UOpcode
.data
.u16
.Step
= FwOpcode
->Step
;
783 switch (FwOpcode
->Width
) {
786 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_1
| EFI_IFR_DISPLAY_UINT_DEC
;
791 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_2
| EFI_IFR_DISPLAY_UINT_DEC
;
797 return EFI_INVALID_PARAMETER
;
801 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
802 if (EFI_ERROR (Status
)) {
807 // We need to create a default value.
809 ZeroMem (&UOpcodeDefault
, sizeof (UOpcodeDefault
));
810 UOpcodeDefault
.Header
.Length
= sizeof (UOpcodeDefault
);
811 UOpcodeDefault
.Header
.OpCode
= EFI_IFR_DEFAULT_OP
;
813 UOpcodeDefault
.DefaultId
= 0;
815 switch (FwOpcode
->Width
) {
818 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
823 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
828 CopyMem (&UOpcodeDefault
.Value
.u8
, &FwOpcode
->Default
, FwOpcode
->Width
);
830 Status
= AppendToUpdateBuffer ((UINT8
*) &UOpcodeDefault
, sizeof(UOpcodeDefault
), UefiData
);
831 if (EFI_ERROR (Status
)) {
834 Status
= UCreateEndOfOpcode (UefiData
);
842 typedef struct _EFI_IFR_QUESTION_HEADER {
843 EFI_IFR_STATEMENT_HEADER Header;
844 EFI_QUESTION_ID QuestionId;
845 EFI_VARSTORE_ID VarStoreId;
847 EFI_STRING_ID VarName;
851 } EFI_IFR_QUESTION_HEADER;
853 typedef struct _EFI_IFR_STRING {
854 EFI_IFR_OP_HEADER Header;
855 EFI_IFR_QUESTION_HEADER Question;
863 FRAMEWORK_EFI_IFR_OP_HEADER Header;
864 UINT16 QuestionId; // The ID designating what the question is about...sucked in from a #define, likely in the form of a variable name
865 UINT8 Width; // The Size of the Data being saved -- BUGBUG -- remove someday
866 STRING_REF Prompt; // The String Token for the Prompt
867 STRING_REF Help; // The string Token for the context-help
868 UINT8 Flags; // This is included solely for purposes of interactive/dynamic support.
869 UINT16 Key; // Value to be passed to caller to identify this particular op-code
870 UINT8 MinSize; // Minimum allowable sized password
871 UINT8 MaxSize; // Maximum allowable sized password
872 } FRAMEWORK_EFI_IFR_STRING;
878 F2UCreateStringOpCode (
879 IN HII_THUNK_CONTEXT
*ThunkContext
,
880 IN UINT16 VarStoreId
,
881 IN CONST FRAMEWORK_EFI_IFR_STRING
*FwOpcode
,
882 OUT EFI_HII_UPDATE_DATA
*UefiData
885 EFI_IFR_STRING UOpcode
;
887 ZeroMem (&UOpcode
, sizeof(UOpcode
));
889 if (FwOpcode
->Key
== 0) {
890 FwQuestionIdToUefiQuestionId (ThunkContext
, VarStoreId
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
892 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
895 UOpcode
.Header
.Length
= sizeof(UOpcode
);
896 UOpcode
.Header
.OpCode
= EFI_IFR_STRING_OP
;
898 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
899 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
901 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
902 UOpcode
.Question
.VarStoreId
= RESERVED_VARSTORE_ID
;
903 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
905 UOpcode
.Question
.Flags
= (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
907 UOpcode
.MinSize
= FwOpcode
->MinSize
;
908 UOpcode
.MaxSize
= FwOpcode
->MaxSize
;
909 UOpcode
.Flags
= EFI_IFR_STRING_MULTI_LINE
;
911 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
915 typedef struct _EFI_IFR_GUID_BANNER {
916 EFI_IFR_OP_HEADER Header;
918 UINT8 ExtendOpCode; // Extended opcode is EFI_IFR_EXTEND_OP_BANNER
919 EFI_STRING_ID Title; // The string token for the banner title
920 UINT16 LineNumber; // 1-based line number
921 UINT8 Alignment; // left, center, or right-aligned
922 } EFI_IFR_GUID_BANNER;
925 FRAMEWORK_EFI_IFR_OP_HEADER Header;
926 STRING_REF Title; // The string token for the banner title
927 UINT16 LineNumber; // 1-based line number
928 UINT8 Alignment; // left, center, or right-aligned
929 } FRAMEWORK_EFI_IFR_BANNER;
934 F2UCreateBannerOpCode (
935 IN CONST FRAMEWORK_EFI_IFR_BANNER
*FwOpcode
,
936 OUT EFI_HII_UPDATE_DATA
*UefiData
939 EFI_IFR_GUID_BANNER UOpcode
;
941 ZeroMem (&UOpcode
, sizeof(UOpcode
));
943 UOpcode
.Header
.Length
= sizeof(UOpcode
);
944 UOpcode
.Header
.OpCode
= EFI_IFR_GUID_OP
;
946 CopyMem (&UOpcode
.Guid
, &mTianoExtendedOpcodeGuid
, sizeof (EFI_GUID
));
947 UOpcode
.ExtendOpCode
= EFI_IFR_EXTEND_OP_BANNER
;
948 UOpcode
.Title
= FwOpcode
->Title
;
949 UOpcode
.LineNumber
= FwOpcode
->LineNumber
;
950 UOpcode
.Alignment
= FwOpcode
->Alignment
;
952 return AppendToUpdateBuffer ((UINT8
*) &UOpcode
, sizeof(UOpcode
), UefiData
);
957 FwUpdateDataToUefiUpdateData (
958 IN HII_THUNK_CONTEXT
*ThunkContext
,
959 IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA
*Data
,
961 OUT EFI_HII_UPDATE_DATA
**UefiData
964 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpCode
;
965 FRAMEWORK_EFI_IFR_OP_HEADER
*NextFwOpCode
;
966 EFI_HII_UPDATE_DATA
*UefiOpCode
;
973 // Assume all dynamic opcode created is using active variable with VarStoreId of 1.
977 UefiOpCode
= AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA
));
978 if (UefiOpCode
== NULL
) {
979 return EFI_OUT_OF_RESOURCES
;
982 UefiOpCode
->Data
= AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
);
983 if (UefiOpCode
->Data
== NULL
) {
984 return EFI_OUT_OF_RESOURCES
;
987 UefiOpCode
->BufferSize
= LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL
;
988 UefiOpCode
->Offset
= 0;
990 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) &Data
->Data
;
992 for (Index
= 0; Index
< Data
->DataCount
; Index
+= DataCount
) {
993 switch (FwOpCode
->OpCode
) {
994 case FRAMEWORK_EFI_IFR_SUBTITLE_OP
:
995 Status
= F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE
*) FwOpCode
, UefiOpCode
);
999 case FRAMEWORK_EFI_IFR_TEXT_OP
:
1000 Status
= F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT
*) FwOpCode
, UefiOpCode
);
1004 case FRAMEWORK_EFI_IFR_REF_OP
:
1005 Status
= F2UCreateGotoOpCode ((FRAMEWORK_EFI_IFR_REF
*) FwOpCode
, UefiOpCode
);
1009 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
1010 Status
= F2UCreateOneOfOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_ONE_OF
*) 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_ORDERED_LIST_OP
:
1021 Status
= F2UCreateOrderedListOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_ORDERED_LIST
*) FwOpCode
, UefiOpCode
, &NextFwOpCode
, &DataCount
);
1022 if (!EFI_ERROR (Status
)) {
1023 FwOpCode
= NextFwOpCode
;
1025 // FwOpCode is already updated to point to the next opcode.
1031 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
1032 Status
= F2UCreateCheckBoxOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_CHECKBOX
*) FwOpCode
, UefiOpCode
);
1036 case FRAMEWORK_EFI_IFR_STRING_OP
:
1037 Status
= F2UCreateStringOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_STRING
*) FwOpCode
, UefiOpCode
);
1041 case FRAMEWORK_EFI_IFR_BANNER_OP
:
1042 Status
= F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER
*) FwOpCode
, UefiOpCode
);
1046 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP
:
1047 Status
= UCreateEndOfOpcode (UefiOpCode
);
1051 case FRAMEWORK_EFI_IFR_NUMERIC_OP
:
1052 Status
= F2UCreateNumericOpCode (ThunkContext
, VarStoreId
, (FRAMEWORK_EFI_IFR_NUMERIC
*) FwOpCode
, UefiOpCode
);
1058 return EFI_UNSUPPORTED
;
1061 if (EFI_ERROR (Status
)) {
1062 FreePool (UefiOpCode
->Data
);
1063 FreePool (UefiOpCode
);
1067 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpCode
+ FwOpCode
->Length
);
1070 *UefiData
= UefiOpCode
;