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.
16 #include "HiiDatabase.h"
17 #include "UefiIfrDefault.h"
23 } HII_LIB_OPCODE_BUFFER
;
26 The dynamic creation of these opcodes is supported in Framework HII modules.
27 Therefore, Framework HII Thunk module only map these opcode between Framework
28 HII's definitions to UEFI HII's.
35 IFR_OPCODE_MAP mQuestionOpcodeMap
[] = {
36 { FRAMEWORK_EFI_IFR_ONE_OF_OP
, EFI_IFR_ONE_OF_OP
},
37 { FRAMEWORK_EFI_IFR_CHECKBOX_OP
, EFI_IFR_CHECKBOX_OP
},
38 { FRAMEWORK_EFI_IFR_NUMERIC_OP
, EFI_IFR_NUMERIC_OP
},
39 { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
, EFI_IFR_ONE_OF_OPTION_OP
},
40 { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
, EFI_IFR_ORDERED_LIST_OP
}
44 Translate a Framework Question Opcode to UEFI Question Opcode.
46 @param FwOp Framework Opcode.
47 @param UefiOp UEFI Opcode.
49 @retval EFI_SUCCESS The UEFI opcode is found and returned.
50 @retval EFI_NOT_FOUND The UEFI opcode is not found.
60 for (Index
= 0; Index
< sizeof (mQuestionOpcodeMap
) / sizeof (mQuestionOpcodeMap
[0]); Index
++) {
61 if (FwOp
== mQuestionOpcodeMap
[Index
].FrameworkIfrOp
) {
62 *UefiOp
= mQuestionOpcodeMap
[Index
].UefiIfrOp
;
67 *UefiOp
= (UINT8
) (FRAMEWORK_EFI_IFR_LAST_OPCODE
+ 1);
72 Translate a Framework Question Opcode to UEFI Question Opcode.
74 @param FwOp Framework Opcode.
75 @param UefiOp UEFI Opcode.
77 @retval EFI_SUCCESS The UEFI opcode is found and returned.
78 @retval EFI_NOT_FOUND The UEFI opcode is not found.
82 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
89 LIST_ENTRY
*StatementList
;
90 FORM_BROWSER_FORM
*Form
;
91 FORM_BROWSER_STATEMENT
*Statement
;
92 FORM_BROWSER_STATEMENT
*StatementFound
;
98 StatementFound
= NULL
;
100 FormList
= GetFirstNode (&FormSet
->FormListHead
);
102 while (!IsNull (&FormSet
->FormListHead
, FormList
)) {
103 Form
= FORM_BROWSER_FORM_FROM_LINK (FormList
);
105 StatementList
= GetFirstNode (&Form
->StatementListHead
);
107 while (!IsNull (&Form
->StatementListHead
, StatementList
)) {
108 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (StatementList
);
109 if (Statement
->VarStoreId
!= 0 && Statement
->Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
110 if (FwQId
== Statement
->VarStoreInfo
.VarOffset
) {
111 Status
= QuestionOpFwToUefi (FwOpCode
, &UefiOp
);
112 ASSERT_EFI_ERROR (Status
);
114 if ((UefiOp
== Statement
->Operand
) && (FormSet
->DefaultVarStoreId
== Statement
->VarStoreId
)) {
116 // If ASSERT here, the Framework VFR file has two Questions with all three attibutes the same:
117 // 1) Same Question Type,
118 // 2) Same Variable Storage
119 // 3) Refering to the Same offset in Variable Map (NvMap).
120 // This is ambigurity as FwQIdToUefiQId () can't find which UEFI Question
123 // One possible solution is to remove the one of the duplicated questions in this Form Set.
125 ASSERT (StatementFound
== NULL
);
126 StatementFound
= Statement
;
129 // Continue the search to check if the Form Set contains more than one questins that has the 3 attributes
136 StatementList
= GetNextNode (&Form
->StatementListHead
, StatementList
);
139 FormList
= GetNextNode (&FormSet
->FormListHead
, FormList
);
142 if (StatementFound
!= NULL
) {
143 *UefiQId
= StatementFound
->QuestionId
;
147 return EFI_NOT_FOUND
;
152 #define HII_LIB_OPCODE_ALLOCATION_SIZE 0x200
155 Append raw opcodes to an OpCodeHandle.
157 If OpCodeHandle is NULL, then ASSERT().
158 If RawBuffer is NULL, then ASSERT();
160 @param[in] OpCodeHandle Handle to the buffer of opcodes.
161 @param[in] RawBuffer Buffer of opcodes to append.
162 @param[in] RawBufferSize The size, in bytes, of Buffer.
164 @retval NULL There is not enough space left in Buffer to add the opcode.
165 @retval Other A pointer to the appended opcodes.
170 HiiThunkCreateRawOpCodes (
171 IN VOID
*OpCodeHandle
,
173 IN UINTN RawBufferSize
177 HII_LIB_OPCODE_BUFFER
*OpCodeBuffer
;
179 ASSERT (RawBuffer
!= NULL
);
180 ASSERT (OpCodeHandle
!= NULL
);
182 OpCodeBuffer
= (HII_LIB_OPCODE_BUFFER
*)OpCodeHandle
;
183 if (OpCodeBuffer
->Position
+ RawBufferSize
> OpCodeBuffer
->BufferSize
) {
184 Buffer
= ReallocatePool (
185 OpCodeBuffer
->BufferSize
,
186 OpCodeBuffer
->BufferSize
+ (RawBufferSize
+ HII_LIB_OPCODE_ALLOCATION_SIZE
),
189 if (Buffer
== NULL
) {
192 OpCodeBuffer
->Buffer
= Buffer
;
193 OpCodeBuffer
->BufferSize
+= (RawBufferSize
+ HII_LIB_OPCODE_ALLOCATION_SIZE
);
195 Buffer
= OpCodeBuffer
->Buffer
+ OpCodeBuffer
->Position
;
196 OpCodeBuffer
->Position
+= RawBufferSize
;
198 return (UINT8
*)CopyMem (Buffer
, RawBuffer
, RawBufferSize
);
202 Assign a Question ID.
204 If FwQuestionId is 0, then assign a new question ID. The new question ID
205 is MaxQuestionId incremented by 1. The MaxQuestionId of FormSet is also
208 If FwQuestionId is not 0, then it is used as the Framework Question ID.
210 @return The Framework Question ID.
214 IN UINT16 FwQuestionId
,
215 IN FORM_BROWSER_FORMSET
*FormSet
218 if (FwQuestionId
== 0) {
219 FormSet
->MaxQuestionId
++;
220 return FormSet
->MaxQuestionId
;
227 Create UEFI HII Text Opcode from a Framework HII Text Opcode.
229 @param FwOpcode The input Framework Opcode.
230 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
232 @retval NULL There is not enough space left in Buffer to add the opcode.
233 @retval Other A pointer to the created opcode.
237 F2UCreateTextOpCode (
238 IN OUT VOID
*UefiUpdateDataHandle
,
239 IN CONST FRAMEWORK_EFI_IFR_TEXT
*FwOpcode
242 EFI_IFR_TEXT UTextOpCode
;
244 if ((FwOpcode
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) == 0) {
245 ZeroMem (&UTextOpCode
, sizeof(UTextOpCode
));
247 UTextOpCode
.Header
.OpCode
= EFI_IFR_TEXT_OP
;
248 UTextOpCode
.Header
.Length
= sizeof (EFI_IFR_TEXT
);
250 UTextOpCode
.Statement
.Help
= FwOpcode
->Help
;
252 UTextOpCode
.Statement
.Prompt
= FwOpcode
->Text
;
253 UTextOpCode
.TextTwo
= FwOpcode
->TextTwo
;
255 return HiiThunkCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UTextOpCode
, sizeof(UTextOpCode
));
258 // Iteractive Text Opcode is EFI_IFR_ACTION
260 return HiiCreateActionOpCode (UefiUpdateDataHandle
, FwOpcode
->Key
, FwOpcode
->Text
, FwOpcode
->Help
, EFI_IFR_FLAG_CALLBACK
, 0);
265 Create UEFI HII Reference Opcode from a Framework HII Reference Opcode.
267 @param FwOpcode The input Framework Opcode.
268 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
270 @retval NULL There is not enough space left in Buffer to add the opcode.
271 @retval Other A pointer to the created opcode.
275 F2UCreateReferenceOpCode (
276 IN OUT VOID
*UefiUpdateDataHandle
,
277 IN CONST FRAMEWORK_EFI_IFR_REF
*FwOpcode
282 ZeroMem (&UOpcode
, sizeof(UOpcode
));
284 UOpcode
.Header
.Length
= sizeof(UOpcode
);
285 UOpcode
.Header
.OpCode
= EFI_IFR_REF_OP
;
287 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
288 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
289 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
291 UOpcode
.FormId
= FwOpcode
->FormId
;
294 // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to
295 // UEFI IFR Opcode flags. The rest flags are obsolete.
297 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
299 return HiiThunkCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
303 Create UEFI HII "One Of Option" Opcode from a Framework HII "One Of Option" Opcode.
305 @param FwOpcode The input Framework Opcode.
306 @param Width The size of the One Of Option. 1 bytes or 2 bytes.
307 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
309 @retval NULL There is not enough space left in Buffer to add the opcode.
310 @retval Other A pointer to the created opcode.
314 F2UCreateOneOfOptionOpCode (
315 IN OUT VOID
*UefiUpdateDataHandle
,
316 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOpcode
,
320 EFI_IFR_ONE_OF_OPTION UOpcode
;
322 ZeroMem (&UOpcode
, sizeof(UOpcode
));
324 UOpcode
.Header
.Length
= sizeof(UOpcode
);
325 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OPTION_OP
;
327 UOpcode
.Option
= FwOpcode
->Option
;
328 CopyMem (&UOpcode
.Value
.u8
, &FwOpcode
->Value
, Width
);
331 // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT 0x01
332 // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING 0x02
333 // #define EFI_IFR_OPTION_DEFAULT 0x10
334 // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20
336 UOpcode
.Flags
= (UINT8
) (UOpcode
.Flags
| (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
)) << 4);
340 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
344 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
352 return HiiThunkCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
356 Create a GUID Opcode EFI_IFR_GUID_OPTIONKEY to map the Framework One Of Option callback key
357 to a UEFI Question ID. This information is used to invoke the Framework HII Browser Callback
358 function. The opcode is appened to UefiUpdateDataHandle.
360 @param QuestionId The UEFI Question ID.
361 @param OptionValue The value of the "One Of Option".
362 @param KeyValue The Framework "One Of Option" callback key.
363 @param UefiUpdateDataHandle The UEFI Update Data buffer.
365 @retval NULL There is not enough space left in Buffer to add the opcode.
366 @retval Other A pointer to the created opcode.
369 CreateGuidOptionKeyOpCode (
370 IN OUT VOID
*UefiUpdateDataHandle
,
371 IN EFI_QUESTION_ID QuestionId
,
372 IN UINT16 OptionValue
,
373 IN EFI_QUESTION_ID KeyValue
376 EFI_IFR_GUID_OPTIONKEY
*UOpcode
;
378 UOpcode
= (EFI_IFR_GUID_OPTIONKEY
*) HiiCreateGuidOpCode (
379 UefiUpdateDataHandle
,
380 &gEfiIfrFrameworkGuid
,
382 sizeof (EFI_IFR_GUID_OPTIONKEY
)
385 UOpcode
->ExtendOpCode
= EFI_IFR_EXTEND_OP_OPTIONKEY
;
386 UOpcode
->QuestionId
= QuestionId
;
387 CopyMem (&UOpcode
->OptionValue
, &OptionValue
, sizeof (OptionValue
));
388 UOpcode
->KeyValue
= KeyValue
;
390 return (UINT8
*) UOpcode
;
394 Create UEFI HII "One Of" Opcode from a Framework HII "One Of" Opcode.
396 @param ThunkContext The HII Thunk Context.
397 @param FwOpcode The input Framework Opcode.
398 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
399 @param NextFwOpcode Returns the position of the next Framework Opcode after FRAMEWORK_EFI_IFR_END_ONE_OF_OP of
401 @param OpcodeCount The number of Opcode for the complete Framework "One Of" Opcode.
403 @retval NULL There is not enough space left in Buffer to add the opcode.
404 @retval Other A pointer to the created opcode.
408 F2UCreateOneOfOpCode (
409 IN OUT VOID
*UefiUpdateDataHandle
,
410 IN HII_THUNK_CONTEXT
*ThunkContext
,
411 IN CONST FRAMEWORK_EFI_IFR_ONE_OF
*FwOpcode
,
412 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
413 OUT UINTN
*OpcodeCount
417 EFI_IFR_ONE_OF UOpcode
;
418 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
419 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
421 UINT8
*OneOfOpCodeBuffer
;
423 ASSERT (NextFwOpcode
!= NULL
);
424 ASSERT (OpcodeCount
!= NULL
);
426 ZeroMem (&UOpcode
, sizeof(UOpcode
));
429 UOpcode
.Header
.Length
= sizeof(UOpcode
);
430 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OP
;
431 UOpcode
.Header
.Scope
= 1;
433 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
434 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
435 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
436 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
439 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
441 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
442 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
443 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
445 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
446 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
447 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
449 if (UOpcode
.Question
.QuestionId
== 0) {
450 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
451 if (EFI_ERROR (Status
)) {
452 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
, ThunkContext
->FormSet
);
458 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
459 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
462 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
466 if (UOpcode
.Question
.QuestionId
== 0) {
468 // Assign QuestionId if still not assigned.
470 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
471 if (EFI_ERROR (Status
)) {
472 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
476 OneOfOpCodeBuffer
= HiiThunkCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof (UOpcode
));
477 if (OneOfOpCodeBuffer
== NULL
) {
483 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.
485 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
486 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
488 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
490 OpCodeBuffer
= F2UCreateOneOfOptionOpCode (UefiUpdateDataHandle
, (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, FwOpcode
->Width
);
491 if (OpCodeBuffer
== NULL
) {
495 OpCodeBuffer
= CreateGuidOptionKeyOpCode (UefiUpdateDataHandle
, UOpcode
.Question
.QuestionId
, FwOneOfOp
->Value
, FwOneOfOp
->Key
);
496 if (OpCodeBuffer
== NULL
) {
500 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
504 OpCodeBuffer
= HiiCreateEndOpCode (UefiUpdateDataHandle
);
505 if (OpCodeBuffer
!= NULL
) {
506 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
510 return OneOfOpCodeBuffer
;
514 Create UEFI HII "Ordered List" Opcode from a Framework HII "Ordered List" Opcode.
516 @param ThunkContext The HII Thunk Context.
517 @param FwOpcode The input Framework Opcode.
518 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
519 @param NextFwOpcode Returns the position of the next Framework Opcode after FRAMEWORK_EFI_IFR_END_ONE_OF_OP of
521 @param OpcodeCount The number of Opcode for the complete Framework "Ordered List" Opcode.
523 @retval NULL There is not enough space left in Buffer to add the opcode.
524 @retval Other A pointer to the created opcode.
528 F2UCreateOrderedListOpCode (
529 IN OUT VOID
*UefiUpdateDataHandle
,
530 IN HII_THUNK_CONTEXT
*ThunkContext
,
531 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST
*FwOpcode
,
532 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
533 OUT UINTN
*OpcodeCount
536 EFI_IFR_ORDERED_LIST UOpcode
;
538 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
539 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
541 UINT8
*OrderListOpCode
;
543 ZeroMem (&UOpcode
, sizeof(UOpcode
));
546 UOpcode
.Header
.Length
= sizeof(UOpcode
);
547 UOpcode
.Header
.OpCode
= EFI_IFR_ORDERED_LIST_OP
;
548 UOpcode
.Header
.Scope
= 1;
550 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
551 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
552 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
553 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
555 UOpcode
.MaxContainers
= FwOpcode
->MaxEntries
;
558 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
560 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
561 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
562 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
564 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
565 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
566 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
568 if (UOpcode
.Question
.QuestionId
== 0) {
569 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
570 if (EFI_ERROR (Status
)) {
571 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
, ThunkContext
->FormSet
);
577 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
578 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
581 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
584 if (UOpcode
.Question
.QuestionId
== 0) {
585 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
586 if (EFI_ERROR (Status
)) {
587 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
591 OrderListOpCode
= HiiThunkCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
592 if (OrderListOpCode
== NULL
) {
597 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
598 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
600 // Each entry of Order List in Framework HII is always 1 byte in size
602 OpcodeBuffer
= F2UCreateOneOfOptionOpCode (UefiUpdateDataHandle
, (CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, 1);
603 if (OpcodeBuffer
== NULL
) {
606 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
610 OpcodeBuffer
= HiiCreateEndOpCode (UefiUpdateDataHandle
);
611 if (OpcodeBuffer
!= NULL
) {
612 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
616 return OrderListOpCode
;
620 Create UEFI HII CheckBox Opcode from a Framework HII Checkbox Opcode.
622 @param ThunkContext The HII Thunk Context.
623 @param FwOpcode The input Framework Opcode.
624 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
626 @retval NULL There is not enough space left in Buffer to add the opcode.
627 @retval Other A pointer to the created opcode.
631 F2UCreateCheckBoxOpCode (
632 IN OUT VOID
*UefiUpdateDataHandle
,
633 IN HII_THUNK_CONTEXT
*ThunkContext
,
634 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX
*FwOpcode
638 EFI_IFR_CHECKBOX UOpcode
;
640 ZeroMem (&UOpcode
, sizeof(UOpcode
));
642 UOpcode
.Header
.Length
= sizeof(UOpcode
);
643 UOpcode
.Header
.OpCode
= EFI_IFR_CHECKBOX_OP
;
645 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
646 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
648 if (FwOpcode
->Key
== 0) {
649 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
650 if (EFI_ERROR (Status
)) {
652 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
654 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
657 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
662 // FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE,
663 // FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,
664 // to UEFI IFR Opcode Question flags. The rest flags are obsolete.
666 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
669 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
670 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
673 // We also map these 2 flags:
674 // FRAMEWORK_EFI_IFR_FLAG_DEFAULT,
675 // FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,
676 // to UEFI IFR CheckBox Opcode default flags.
678 UOpcode
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
));
680 return HiiThunkCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
685 Create UEFI HII Numeric Opcode from a Framework HII Numeric Opcode.
687 @param ThunkContext The HII Thunk Context.
688 @param FwOpcode The input Framework Opcode.
689 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
691 @retval NULL There is not enough space left in Buffer to add the opcode.
692 @retval Other A pointer to the created opcode.
696 F2UCreateNumericOpCode (
697 IN OUT VOID
*UefiUpdateDataHandle
,
698 IN HII_THUNK_CONTEXT
*ThunkContext
,
699 IN CONST FRAMEWORK_EFI_IFR_NUMERIC
*FwOpcode
703 EFI_IFR_NUMERIC UOpcode
;
704 EFI_IFR_DEFAULT UOpcodeDefault
;
705 UINT8
*NumbericOpCode
;
708 ZeroMem (&UOpcode
, sizeof(UOpcode
));
710 if (FwOpcode
->Key
== 0) {
711 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
712 if (EFI_ERROR (Status
)) {
714 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
716 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
719 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
722 UOpcode
.Header
.Length
= sizeof(UOpcode
);
723 UOpcode
.Header
.OpCode
= EFI_IFR_NUMERIC_OP
;
725 // We need to create a nested default value for the UEFI Numeric Opcode.
726 // So turn on the scope.
728 UOpcode
.Header
.Scope
= 1;
730 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
731 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
733 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
734 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
736 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
739 // Framework Numeric values are all in UINT16 and displayed as decimal.
741 UOpcode
.data
.u16
.MinValue
= FwOpcode
->Minimum
;
742 UOpcode
.data
.u16
.MaxValue
= FwOpcode
->Maximum
;
743 UOpcode
.data
.u16
.Step
= FwOpcode
->Step
;
745 switch (FwOpcode
->Width
) {
748 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_1
| EFI_IFR_DISPLAY_UINT_DEC
;
753 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_2
| EFI_IFR_DISPLAY_UINT_DEC
;
763 NumbericOpCode
= HiiThunkCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
764 if (NumbericOpCode
== NULL
) {
769 // We need to create a default value.
771 ZeroMem (&UOpcodeDefault
, sizeof (UOpcodeDefault
));
772 UOpcodeDefault
.Header
.Length
= sizeof (UOpcodeDefault
);
773 UOpcodeDefault
.Header
.OpCode
= EFI_IFR_DEFAULT_OP
;
775 UOpcodeDefault
.DefaultId
= 0;
777 switch (FwOpcode
->Width
) {
780 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
785 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
790 CopyMem (&UOpcodeDefault
.Value
.u8
, &FwOpcode
->Default
, FwOpcode
->Width
);
792 OpcodeBuffer
= HiiThunkCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcodeDefault
, sizeof(UOpcodeDefault
));
793 if (OpcodeBuffer
== NULL
) {
797 OpcodeBuffer
= HiiCreateEndOpCode (UefiUpdateDataHandle
);
798 if (OpcodeBuffer
== NULL
) {
802 return NumbericOpCode
;
807 Create UEFI HII String Opcode from a Framework HII String Opcode.
809 @param ThunkContext The HII Thunk Context.
810 @param FwOpcode The input Framework Opcode.
811 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
813 @retval NULL There is not enough space left in Buffer to add the opcode.
814 @retval Other A pointer to the created opcode.
818 F2UCreateStringOpCode (
819 IN OUT VOID
*UefiUpdateDataHandle
,
820 IN HII_THUNK_CONTEXT
*ThunkContext
,
821 IN CONST FRAMEWORK_EFI_IFR_STRING
*FwOpcode
824 EFI_IFR_STRING UOpcode
;
827 ZeroMem (&UOpcode
, sizeof(UOpcode
));
829 if (FwOpcode
->Key
== 0) {
830 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
831 if (EFI_ERROR (Status
)) {
833 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
835 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
838 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
841 UOpcode
.Header
.Length
= sizeof(UOpcode
);
842 UOpcode
.Header
.OpCode
= EFI_IFR_STRING_OP
;
844 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
845 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
847 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
849 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
850 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
852 UOpcode
.MinSize
= FwOpcode
->MinSize
;
853 UOpcode
.MaxSize
= FwOpcode
->MaxSize
;
854 UOpcode
.Flags
= EFI_IFR_STRING_MULTI_LINE
;
856 return HiiThunkCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
860 Create UEFI HII Banner Opcode from a Framework HII Banner Opcode.
862 @param FwOpcode The input Framework Opcode.
863 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
865 @retval NULL There is not enough space left in Buffer to add the opcode.
866 @retval Other A pointer to the created opcode.
870 F2UCreateBannerOpCode (
871 IN OUT VOID
*UefiUpdateDataHandle
,
872 IN CONST FRAMEWORK_EFI_IFR_BANNER
*FwOpcode
875 EFI_IFR_GUID_BANNER
*UOpcode
;
877 UOpcode
= (EFI_IFR_GUID_BANNER
*) HiiCreateGuidOpCode (
878 UefiUpdateDataHandle
,
881 sizeof (EFI_IFR_GUID_BANNER
)
884 UOpcode
->ExtendOpCode
= EFI_IFR_EXTEND_OP_BANNER
;
885 UOpcode
->Title
= FwOpcode
->Title
;
886 UOpcode
->LineNumber
= FwOpcode
->LineNumber
;
887 UOpcode
->Alignment
= FwOpcode
->Alignment
;
889 return (UINT8
*) UOpcode
;
893 Create a Hii Update data Handle used to call IfrLibUpdateForm.
895 @param ThunkContext The HII Thunk Context.
896 @param FwUpdateData The Framework Update Data.
897 @param UefiUpdateData The UEFI Update Data.
899 @retval EFI_SUCCESS The UEFI Update Data is created successfully.
900 @retval EFI_UNSUPPORTED There is unsupported opcode in FwUpdateData.
901 @retval EFI_OUT_OF_RESOURCES There is not enough resource.
904 FwUpdateDataToUefiUpdateData (
905 IN HII_THUNK_CONTEXT
*ThunkContext
,
906 IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA
*FwUpdateData
,
907 IN VOID
*UefiOpCodeHandle
910 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpCode
;
911 FRAMEWORK_EFI_IFR_OP_HEADER
*NextFwOpCode
;
916 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) &FwUpdateData
->Data
;
918 for (Index
= 0; Index
< FwUpdateData
->DataCount
; Index
+= DataCount
) {
919 switch (FwOpCode
->OpCode
) {
920 case FRAMEWORK_EFI_IFR_SUBTITLE_OP
:
921 OpCodeBuffer
= HiiCreateSubTitleOpCode (UefiOpCodeHandle
, ((FRAMEWORK_EFI_IFR_SUBTITLE
*) FwOpCode
)->SubTitle
, 0, 0, 0);
925 case FRAMEWORK_EFI_IFR_TEXT_OP
:
926 OpCodeBuffer
= F2UCreateTextOpCode (UefiOpCodeHandle
, (FRAMEWORK_EFI_IFR_TEXT
*) FwOpCode
);
930 case FRAMEWORK_EFI_IFR_REF_OP
:
931 OpCodeBuffer
= F2UCreateReferenceOpCode (UefiOpCodeHandle
, (FRAMEWORK_EFI_IFR_REF
*) FwOpCode
);
935 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
936 OpCodeBuffer
= F2UCreateOneOfOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_ONE_OF
*) FwOpCode
, &NextFwOpCode
, &DataCount
);
937 if (OpCodeBuffer
!= NULL
) {
938 FwOpCode
= NextFwOpCode
;
940 // FwOpCode is already updated to point to the next opcode.
946 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
:
947 OpCodeBuffer
= F2UCreateOrderedListOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_ORDERED_LIST
*) FwOpCode
, &NextFwOpCode
, &DataCount
);
948 if (OpCodeBuffer
!= NULL
) {
949 FwOpCode
= NextFwOpCode
;
951 // FwOpCode is already updated to point to the next opcode.
957 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
958 OpCodeBuffer
= F2UCreateCheckBoxOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_CHECKBOX
*) FwOpCode
);
962 case FRAMEWORK_EFI_IFR_STRING_OP
:
963 OpCodeBuffer
= F2UCreateStringOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_STRING
*) FwOpCode
);
967 case FRAMEWORK_EFI_IFR_BANNER_OP
:
968 OpCodeBuffer
= F2UCreateBannerOpCode (UefiOpCodeHandle
, (FRAMEWORK_EFI_IFR_BANNER
*) FwOpCode
);
972 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP
:
973 OpCodeBuffer
= HiiCreateEndOpCode (UefiOpCodeHandle
);
977 case FRAMEWORK_EFI_IFR_NUMERIC_OP
:
978 OpCodeBuffer
= F2UCreateNumericOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_NUMERIC
*) FwOpCode
);
984 return EFI_UNSUPPORTED
;
987 if (OpCodeBuffer
== NULL
) {
988 return EFI_OUT_OF_RESOURCES
;
991 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpCode
+ FwOpCode
->Length
);