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"
20 The dynamic creation of these opcodes is supported in Framework HII modules.
21 Therefore, Framework HII Thunk module only map these opcode between Framework
22 HII's definitions to UEFI HII's.
29 IFR_OPCODE_MAP mQuestionOpcodeMap
[] = {
30 { FRAMEWORK_EFI_IFR_ONE_OF_OP
, EFI_IFR_ONE_OF_OP
},
31 { FRAMEWORK_EFI_IFR_CHECKBOX_OP
, EFI_IFR_CHECKBOX_OP
},
32 { FRAMEWORK_EFI_IFR_NUMERIC_OP
, EFI_IFR_NUMERIC_OP
},
33 { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
, EFI_IFR_ONE_OF_OPTION_OP
},
34 { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
, EFI_IFR_ORDERED_LIST_OP
}
38 Translate a Framework Question Opcode to UEFI Question Opcode.
40 @param FwOp Framework Opcode.
41 @param UefiOp UEFI Opcode.
43 @retval EFI_SUCCESS The UEFI opcode is found and returned.
44 @retval EFI_NOT_FOUND The UEFI opcode is not found.
54 for (Index
= 0; Index
< sizeof (mQuestionOpcodeMap
) / sizeof (mQuestionOpcodeMap
[0]); Index
++) {
55 if (FwOp
== mQuestionOpcodeMap
[Index
].FrameworkIfrOp
) {
56 *UefiOp
= mQuestionOpcodeMap
[Index
].UefiIfrOp
;
61 *UefiOp
= (UINT8
) (FRAMEWORK_EFI_IFR_LAST_OPCODE
+ 1);
66 Translate a Framework Question Opcode to UEFI Question Opcode.
68 @param FwOp Framework Opcode.
69 @param UefiOp UEFI Opcode.
71 @retval EFI_SUCCESS The UEFI opcode is found and returned.
72 @retval EFI_NOT_FOUND The UEFI opcode is not found.
76 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
83 LIST_ENTRY
*StatementList
;
84 FORM_BROWSER_FORM
*Form
;
85 FORM_BROWSER_STATEMENT
*Statement
;
86 FORM_BROWSER_STATEMENT
*StatementFound
;
92 StatementFound
= NULL
;
94 FormList
= GetFirstNode (&FormSet
->FormListHead
);
96 while (!IsNull (&FormSet
->FormListHead
, FormList
)) {
97 Form
= FORM_BROWSER_FORM_FROM_LINK (FormList
);
99 StatementList
= GetFirstNode (&Form
->StatementListHead
);
101 while (!IsNull (&Form
->StatementListHead
, StatementList
)) {
102 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (StatementList
);
103 if (Statement
->VarStoreId
!= 0 && Statement
->Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
104 if (FwQId
== Statement
->VarStoreInfo
.VarOffset
) {
105 Status
= QuestionOpFwToUefi (FwOpCode
, &UefiOp
);
106 ASSERT_EFI_ERROR (Status
);
108 if ((UefiOp
== Statement
->Operand
) && (FormSet
->DefaultVarStoreId
== Statement
->VarStoreId
)) {
110 // If ASSERT here, the Framework VFR file has two Questions with all three attibutes the same:
111 // 1) Same Question Type,
112 // 2) Same Variable Storage
113 // 3) Refering to the Same offset in Variable Map (NvMap).
114 // This is ambigurity as FwQIdToUefiQId () can't find which UEFI Question
117 // One possible solution is to remove the one of the duplicated questions in this Form Set.
119 ASSERT (StatementFound
== NULL
);
120 StatementFound
= Statement
;
123 // Continue the search to check if the Form Set contains more than one questins that has the 3 attributes
130 StatementList
= GetNextNode (&Form
->StatementListHead
, StatementList
);
133 FormList
= GetNextNode (&FormSet
->FormListHead
, FormList
);
136 if (StatementFound
!= NULL
) {
137 *UefiQId
= StatementFound
->QuestionId
;
141 return EFI_NOT_FOUND
;
145 Assign a Question ID.
147 If FwQuestionId is 0, then assign a new question ID. The new question ID
148 is MaxQuestionId incremented by 1. The MaxQuestionId of FormSet is also
151 If FwQuestionId is not 0, then it is used as the Framework Question ID.
153 @return The Framework Question ID.
157 IN UINT16 FwQuestionId
,
158 IN FORM_BROWSER_FORMSET
*FormSet
161 if (FwQuestionId
== 0) {
162 FormSet
->MaxQuestionId
++;
163 return FormSet
->MaxQuestionId
;
170 Create UEFI HII Text Opcode from a Framework HII Text Opcode.
172 @param FwOpcode The input Framework Opcode.
173 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
175 @retval NULL There is not enough space left in Buffer to add the opcode.
176 @retval Other A pointer to the created opcode.
180 F2UCreateTextOpCode (
181 IN OUT VOID
*UefiUpdateDataHandle
,
182 IN CONST FRAMEWORK_EFI_IFR_TEXT
*FwOpcode
185 EFI_IFR_TEXT UTextOpCode
;
187 if ((FwOpcode
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) == 0) {
188 ZeroMem (&UTextOpCode
, sizeof(UTextOpCode
));
190 UTextOpCode
.Header
.OpCode
= EFI_IFR_TEXT_OP
;
191 UTextOpCode
.Header
.Length
= sizeof (EFI_IFR_TEXT
);
193 UTextOpCode
.Statement
.Help
= FwOpcode
->Help
;
195 UTextOpCode
.Statement
.Prompt
= FwOpcode
->Text
;
196 UTextOpCode
.TextTwo
= FwOpcode
->TextTwo
;
198 return HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UTextOpCode
, sizeof(UTextOpCode
));
201 // Iteractive Text Opcode is EFI_IFR_ACTION
203 return HiiCreateActionOpCode (UefiUpdateDataHandle
, FwOpcode
->Key
, FwOpcode
->Text
, FwOpcode
->Help
, EFI_IFR_FLAG_CALLBACK
, 0);
208 Create UEFI HII Reference Opcode from a Framework HII Reference Opcode.
210 @param FwOpcode The input Framework Opcode.
211 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
213 @retval NULL There is not enough space left in Buffer to add the opcode.
214 @retval Other A pointer to the created opcode.
218 F2UCreateReferenceOpCode (
219 IN OUT VOID
*UefiUpdateDataHandle
,
220 IN CONST FRAMEWORK_EFI_IFR_REF
*FwOpcode
225 ZeroMem (&UOpcode
, sizeof(UOpcode
));
227 UOpcode
.Header
.Length
= sizeof(UOpcode
);
228 UOpcode
.Header
.OpCode
= EFI_IFR_REF_OP
;
230 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
231 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
232 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
234 UOpcode
.FormId
= FwOpcode
->FormId
;
237 // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to
238 // UEFI IFR Opcode flags. The rest flags are obsolete.
240 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
242 return HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
246 Create UEFI HII "One Of Option" Opcode from a Framework HII "One Of Option" Opcode.
248 @param FwOpcode The input Framework Opcode.
249 @param Width The size of the One Of Option. 1 bytes or 2 bytes.
250 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
252 @retval NULL There is not enough space left in Buffer to add the opcode.
253 @retval Other A pointer to the created opcode.
257 F2UCreateOneOfOptionOpCode (
258 IN OUT VOID
*UefiUpdateDataHandle
,
259 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOpcode
,
263 EFI_IFR_ONE_OF_OPTION UOpcode
;
265 ZeroMem (&UOpcode
, sizeof(UOpcode
));
267 UOpcode
.Header
.Length
= sizeof(UOpcode
);
268 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OPTION_OP
;
270 UOpcode
.Option
= FwOpcode
->Option
;
271 CopyMem (&UOpcode
.Value
.u8
, &FwOpcode
->Value
, Width
);
274 // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT 0x01
275 // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING 0x02
276 // #define EFI_IFR_OPTION_DEFAULT 0x10
277 // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20
279 UOpcode
.Flags
= (UINT8
) (UOpcode
.Flags
| (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
)) << 4);
283 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
287 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
295 return HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
299 Create a GUID Opcode EFI_IFR_GUID_OPTIONKEY to map the Framework One Of Option callback key
300 to a UEFI Question ID. This information is used to invoke the Framework HII Browser Callback
301 function. The opcode is appened to UefiUpdateDataHandle.
303 @param QuestionId The UEFI Question ID.
304 @param OptionValue The value of the "One Of Option".
305 @param KeyValue The Framework "One Of Option" callback key.
306 @param UefiUpdateDataHandle The UEFI Update Data buffer.
308 @retval NULL There is not enough space left in Buffer to add the opcode.
309 @retval Other A pointer to the created opcode.
312 CreateGuidOptionKeyOpCode (
313 IN OUT VOID
*UefiUpdateDataHandle
,
314 IN EFI_QUESTION_ID QuestionId
,
315 IN UINT16 OptionValue
,
316 IN EFI_QUESTION_ID KeyValue
319 EFI_IFR_GUID_OPTIONKEY
*UOpcode
;
321 UOpcode
= (EFI_IFR_GUID_OPTIONKEY
*) HiiCreateGuidOpCode (
322 UefiUpdateDataHandle
,
323 &gEfiIfrFrameworkGuid
,
325 sizeof (EFI_IFR_GUID_OPTIONKEY
)
328 UOpcode
->ExtendOpCode
= EFI_IFR_EXTEND_OP_OPTIONKEY
;
329 UOpcode
->QuestionId
= QuestionId
;
330 CopyMem (&UOpcode
->OptionValue
, &OptionValue
, sizeof (OptionValue
));
331 UOpcode
->KeyValue
= KeyValue
;
333 return (UINT8
*) UOpcode
;
337 Create UEFI HII "One Of" Opcode from a Framework HII "One Of" Opcode.
339 @param ThunkContext The HII Thunk Context.
340 @param FwOpcode The input Framework Opcode.
341 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
342 @param NextFwOpcode Returns the position of the next Framework Opcode after FRAMEWORK_EFI_IFR_END_ONE_OF_OP of
344 @param OpcodeCount The number of Opcode for the complete Framework "One Of" Opcode.
346 @retval NULL There is not enough space left in Buffer to add the opcode.
347 @retval Other A pointer to the created opcode.
351 F2UCreateOneOfOpCode (
352 IN OUT VOID
*UefiUpdateDataHandle
,
353 IN HII_THUNK_CONTEXT
*ThunkContext
,
354 IN CONST FRAMEWORK_EFI_IFR_ONE_OF
*FwOpcode
,
355 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
356 OUT UINTN
*OpcodeCount
360 EFI_IFR_ONE_OF UOpcode
;
361 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
362 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
364 UINT8
*OneOfOpCodeBuffer
;
366 ASSERT (NextFwOpcode
!= NULL
);
367 ASSERT (OpcodeCount
!= NULL
);
369 ZeroMem (&UOpcode
, sizeof(UOpcode
));
372 UOpcode
.Header
.Length
= sizeof(UOpcode
);
373 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OP
;
374 UOpcode
.Header
.Scope
= 1;
376 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
377 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
378 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
379 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
382 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
384 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
385 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
386 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
388 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
389 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
390 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
392 if (UOpcode
.Question
.QuestionId
== 0) {
393 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
394 if (EFI_ERROR (Status
)) {
395 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
, ThunkContext
->FormSet
);
401 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
402 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
405 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
409 if (UOpcode
.Question
.QuestionId
== 0) {
411 // Assign QuestionId if still not assigned.
413 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
414 if (EFI_ERROR (Status
)) {
415 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
419 OneOfOpCodeBuffer
= HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof (UOpcode
));
420 if (OneOfOpCodeBuffer
== NULL
) {
426 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.
428 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
429 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
431 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
433 OpCodeBuffer
= F2UCreateOneOfOptionOpCode (UefiUpdateDataHandle
, (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, FwOpcode
->Width
);
434 if (OpCodeBuffer
== NULL
) {
438 OpCodeBuffer
= CreateGuidOptionKeyOpCode (UefiUpdateDataHandle
, UOpcode
.Question
.QuestionId
, FwOneOfOp
->Value
, FwOneOfOp
->Key
);
439 if (OpCodeBuffer
== NULL
) {
443 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
447 OpCodeBuffer
= HiiCreateEndOpCode (UefiUpdateDataHandle
);
448 if (OpCodeBuffer
!= NULL
) {
449 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
453 return OneOfOpCodeBuffer
;
457 Create UEFI HII "Ordered List" Opcode from a Framework HII "Ordered List" Opcode.
459 @param ThunkContext The HII Thunk Context.
460 @param FwOpcode The input Framework Opcode.
461 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
462 @param NextFwOpcode Returns the position of the next Framework Opcode after FRAMEWORK_EFI_IFR_END_ONE_OF_OP of
464 @param OpcodeCount The number of Opcode for the complete Framework "Ordered List" Opcode.
466 @retval NULL There is not enough space left in Buffer to add the opcode.
467 @retval Other A pointer to the created opcode.
471 F2UCreateOrderedListOpCode (
472 IN OUT VOID
*UefiUpdateDataHandle
,
473 IN HII_THUNK_CONTEXT
*ThunkContext
,
474 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST
*FwOpcode
,
475 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
476 OUT UINTN
*OpcodeCount
479 EFI_IFR_ORDERED_LIST UOpcode
;
481 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
482 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
484 UINT8
*OrderListOpCode
;
486 ZeroMem (&UOpcode
, sizeof(UOpcode
));
489 UOpcode
.Header
.Length
= sizeof(UOpcode
);
490 UOpcode
.Header
.OpCode
= EFI_IFR_ORDERED_LIST_OP
;
491 UOpcode
.Header
.Scope
= 1;
493 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
494 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
495 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
496 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
498 UOpcode
.MaxContainers
= FwOpcode
->MaxEntries
;
501 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
503 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
504 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
505 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
507 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
508 if ((FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) != 0) {
509 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
511 if (UOpcode
.Question
.QuestionId
== 0) {
512 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
513 if (EFI_ERROR (Status
)) {
514 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
, ThunkContext
->FormSet
);
520 if (FwOneOfOp
->Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
) {
521 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
524 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
527 if (UOpcode
.Question
.QuestionId
== 0) {
528 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
529 if (EFI_ERROR (Status
)) {
530 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
534 OrderListOpCode
= HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
535 if (OrderListOpCode
== NULL
) {
540 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
541 while (FwOpHeader
->OpCode
!= FRAMEWORK_EFI_IFR_END_ONE_OF_OP
) {
543 // Each entry of Order List in Framework HII is always 1 byte in size
545 OpcodeBuffer
= F2UCreateOneOfOptionOpCode (UefiUpdateDataHandle
, (CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, 1);
546 if (OpcodeBuffer
== NULL
) {
549 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
553 OpcodeBuffer
= HiiCreateEndOpCode (UefiUpdateDataHandle
);
554 if (OpcodeBuffer
!= NULL
) {
555 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
559 return OrderListOpCode
;
563 Create UEFI HII CheckBox Opcode from a Framework HII Checkbox Opcode.
565 @param ThunkContext The HII Thunk Context.
566 @param FwOpcode The input Framework Opcode.
567 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
569 @retval NULL There is not enough space left in Buffer to add the opcode.
570 @retval Other A pointer to the created opcode.
574 F2UCreateCheckBoxOpCode (
575 IN OUT VOID
*UefiUpdateDataHandle
,
576 IN HII_THUNK_CONTEXT
*ThunkContext
,
577 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX
*FwOpcode
581 EFI_IFR_CHECKBOX UOpcode
;
583 ZeroMem (&UOpcode
, sizeof(UOpcode
));
585 UOpcode
.Header
.Length
= sizeof(UOpcode
);
586 UOpcode
.Header
.OpCode
= EFI_IFR_CHECKBOX_OP
;
588 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
589 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
591 if (FwOpcode
->Key
== 0) {
592 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
593 if (EFI_ERROR (Status
)) {
595 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
597 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
600 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
605 // FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE,
606 // FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,
607 // to UEFI IFR Opcode Question flags. The rest flags are obsolete.
609 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
612 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
613 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
616 // We also map these 2 flags:
617 // FRAMEWORK_EFI_IFR_FLAG_DEFAULT,
618 // FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,
619 // to UEFI IFR CheckBox Opcode default flags.
621 UOpcode
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_DEFAULT
| FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING
));
623 return HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
628 Create UEFI HII Numeric Opcode from a Framework HII Numeric Opcode.
630 @param ThunkContext The HII Thunk Context.
631 @param FwOpcode The input Framework Opcode.
632 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
634 @retval NULL There is not enough space left in Buffer to add the opcode.
635 @retval Other A pointer to the created opcode.
639 F2UCreateNumericOpCode (
640 IN OUT VOID
*UefiUpdateDataHandle
,
641 IN HII_THUNK_CONTEXT
*ThunkContext
,
642 IN CONST FRAMEWORK_EFI_IFR_NUMERIC
*FwOpcode
646 EFI_IFR_NUMERIC UOpcode
;
647 EFI_IFR_DEFAULT UOpcodeDefault
;
648 UINT8
*NumbericOpCode
;
651 ZeroMem (&UOpcode
, sizeof(UOpcode
));
653 if (FwOpcode
->Key
== 0) {
654 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
655 if (EFI_ERROR (Status
)) {
657 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
659 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
662 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
665 UOpcode
.Header
.Length
= sizeof(UOpcode
);
666 UOpcode
.Header
.OpCode
= EFI_IFR_NUMERIC_OP
;
668 // We need to create a nested default value for the UEFI Numeric Opcode.
669 // So turn on the scope.
671 UOpcode
.Header
.Scope
= 1;
673 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
674 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
676 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
677 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
679 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
682 // Framework Numeric values are all in UINT16 and displayed as decimal.
684 UOpcode
.data
.u16
.MinValue
= FwOpcode
->Minimum
;
685 UOpcode
.data
.u16
.MaxValue
= FwOpcode
->Maximum
;
686 UOpcode
.data
.u16
.Step
= FwOpcode
->Step
;
688 switch (FwOpcode
->Width
) {
691 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_1
| EFI_IFR_DISPLAY_UINT_DEC
;
696 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_2
| EFI_IFR_DISPLAY_UINT_DEC
;
706 NumbericOpCode
= HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
707 if (NumbericOpCode
== NULL
) {
712 // We need to create a default value.
714 ZeroMem (&UOpcodeDefault
, sizeof (UOpcodeDefault
));
715 UOpcodeDefault
.Header
.Length
= sizeof (UOpcodeDefault
);
716 UOpcodeDefault
.Header
.OpCode
= EFI_IFR_DEFAULT_OP
;
718 UOpcodeDefault
.DefaultId
= 0;
720 switch (FwOpcode
->Width
) {
723 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
728 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
733 CopyMem (&UOpcodeDefault
.Value
.u8
, &FwOpcode
->Default
, FwOpcode
->Width
);
735 OpcodeBuffer
= HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcodeDefault
, sizeof(UOpcodeDefault
));
736 if (OpcodeBuffer
== NULL
) {
740 OpcodeBuffer
= HiiCreateEndOpCode (UefiUpdateDataHandle
);
741 if (OpcodeBuffer
== NULL
) {
745 return NumbericOpCode
;
750 Create UEFI HII String Opcode from a Framework HII String Opcode.
752 @param ThunkContext The HII Thunk Context.
753 @param FwOpcode The input Framework Opcode.
754 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
756 @retval NULL There is not enough space left in Buffer to add the opcode.
757 @retval Other A pointer to the created opcode.
761 F2UCreateStringOpCode (
762 IN OUT VOID
*UefiUpdateDataHandle
,
763 IN HII_THUNK_CONTEXT
*ThunkContext
,
764 IN CONST FRAMEWORK_EFI_IFR_STRING
*FwOpcode
767 EFI_IFR_STRING UOpcode
;
770 ZeroMem (&UOpcode
, sizeof(UOpcode
));
772 if (FwOpcode
->Key
== 0) {
773 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
774 if (EFI_ERROR (Status
)) {
776 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
778 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
781 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
784 UOpcode
.Header
.Length
= sizeof(UOpcode
);
785 UOpcode
.Header
.OpCode
= EFI_IFR_STRING_OP
;
787 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
788 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
790 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
));
792 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
793 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
795 UOpcode
.MinSize
= FwOpcode
->MinSize
;
796 UOpcode
.MaxSize
= FwOpcode
->MaxSize
;
797 UOpcode
.Flags
= EFI_IFR_STRING_MULTI_LINE
;
799 return HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
803 Create UEFI HII Banner Opcode from a Framework HII Banner Opcode.
805 @param FwOpcode The input Framework Opcode.
806 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
808 @retval NULL There is not enough space left in Buffer to add the opcode.
809 @retval Other A pointer to the created opcode.
813 F2UCreateBannerOpCode (
814 IN OUT VOID
*UefiUpdateDataHandle
,
815 IN CONST FRAMEWORK_EFI_IFR_BANNER
*FwOpcode
818 EFI_IFR_GUID_BANNER
*UOpcode
;
820 UOpcode
= (EFI_IFR_GUID_BANNER
*) HiiCreateGuidOpCode (
821 UefiUpdateDataHandle
,
824 sizeof (EFI_IFR_GUID_BANNER
)
827 UOpcode
->ExtendOpCode
= EFI_IFR_EXTEND_OP_BANNER
;
828 UOpcode
->Title
= FwOpcode
->Title
;
829 UOpcode
->LineNumber
= FwOpcode
->LineNumber
;
830 UOpcode
->Alignment
= FwOpcode
->Alignment
;
832 return (UINT8
*) UOpcode
;
836 Create a Hii Update data Handle used to call IfrLibUpdateForm.
838 @param ThunkContext The HII Thunk Context.
839 @param FwUpdateData The Framework Update Data.
840 @param UefiUpdateData The UEFI Update Data.
842 @retval EFI_SUCCESS The UEFI Update Data is created successfully.
843 @retval EFI_UNSUPPORTED There is unsupported opcode in FwUpdateData.
844 @retval EFI_OUT_OF_RESOURCES There is not enough resource.
847 FwUpdateDataToUefiUpdateData (
848 IN HII_THUNK_CONTEXT
*ThunkContext
,
849 IN CONST EFI_HII_UPDATE_DATA
*FwUpdateData
,
850 IN VOID
*UefiOpCodeHandle
853 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpCode
;
854 FRAMEWORK_EFI_IFR_OP_HEADER
*NextFwOpCode
;
859 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) &FwUpdateData
->Data
;
861 for (Index
= 0; Index
< FwUpdateData
->DataCount
; Index
+= DataCount
) {
862 switch (FwOpCode
->OpCode
) {
863 case FRAMEWORK_EFI_IFR_SUBTITLE_OP
:
864 OpCodeBuffer
= HiiCreateSubTitleOpCode (UefiOpCodeHandle
, ((FRAMEWORK_EFI_IFR_SUBTITLE
*) FwOpCode
)->SubTitle
, 0, 0, 0);
868 case FRAMEWORK_EFI_IFR_TEXT_OP
:
869 OpCodeBuffer
= F2UCreateTextOpCode (UefiOpCodeHandle
, (FRAMEWORK_EFI_IFR_TEXT
*) FwOpCode
);
873 case FRAMEWORK_EFI_IFR_REF_OP
:
874 OpCodeBuffer
= F2UCreateReferenceOpCode (UefiOpCodeHandle
, (FRAMEWORK_EFI_IFR_REF
*) FwOpCode
);
878 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
879 OpCodeBuffer
= F2UCreateOneOfOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_ONE_OF
*) FwOpCode
, &NextFwOpCode
, &DataCount
);
880 if (OpCodeBuffer
!= NULL
) {
881 FwOpCode
= NextFwOpCode
;
883 // FwOpCode is already updated to point to the next opcode.
889 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
:
890 OpCodeBuffer
= F2UCreateOrderedListOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_ORDERED_LIST
*) FwOpCode
, &NextFwOpCode
, &DataCount
);
891 if (OpCodeBuffer
!= NULL
) {
892 FwOpCode
= NextFwOpCode
;
894 // FwOpCode is already updated to point to the next opcode.
900 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
901 OpCodeBuffer
= F2UCreateCheckBoxOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_CHECKBOX
*) FwOpCode
);
905 case FRAMEWORK_EFI_IFR_STRING_OP
:
906 OpCodeBuffer
= F2UCreateStringOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_STRING
*) FwOpCode
);
910 case FRAMEWORK_EFI_IFR_BANNER_OP
:
911 OpCodeBuffer
= F2UCreateBannerOpCode (UefiOpCodeHandle
, (FRAMEWORK_EFI_IFR_BANNER
*) FwOpCode
);
915 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP
:
916 OpCodeBuffer
= HiiCreateEndOpCode (UefiOpCodeHandle
);
920 case FRAMEWORK_EFI_IFR_NUMERIC_OP
:
921 OpCodeBuffer
= F2UCreateNumericOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_NUMERIC
*) FwOpCode
);
927 return EFI_UNSUPPORTED
;
930 if (OpCodeBuffer
== NULL
) {
931 return EFI_OUT_OF_RESOURCES
;
934 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpCode
+ FwOpCode
->Length
);