]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.c
1) Add in code to sync Browser Data with the NvMapOverride that may be updated by...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / OpcodeCreation.c
1 /** @file
2 Implement Functions to convert IFR Opcode in format defined in Framework HII specification to
3 format defined in UEFI HII Specification.
4
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
10
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.
13
14 **/
15 #include "HiiDatabase.h"
16 #include "OpcodeCreation.h"
17 #include "UefiIfrDefault.h"
18
19 EFI_GUID mTianoExtendedOpcodeGuid = EFI_IFR_TIANO_GUID;
20
21 #define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL 0x1000
22 EFI_STATUS
23 AppendToUpdateBuffer (
24 IN CONST UINT8 *OpCodeBuf,
25 IN UINTN BufSize,
26 OUT EFI_HII_UPDATE_DATA *UefiData
27 )
28 {
29 UINT8 * NewBuff;
30
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;
35 }
36 UefiData->BufferSize += LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;
37 FreePool (UefiData->Data);
38 UefiData->Data = NewBuff;
39 }
40
41 CopyMem (UefiData->Data + UefiData->Offset, OpCodeBuf, BufSize);
42 UefiData->Offset += (UINT32) BufSize;
43
44 return EFI_SUCCESS;
45 }
46
47
48
49 EFI_STATUS
50 FwQuestionIdToUefiQuestionId (
51 IN HII_THUNK_CONTEXT *ThunkContext,
52 IN UINT16 VarStoreId,
53 IN UINT16 FwId,
54 OUT EFI_QUESTION_ID *UefiQId
55 )
56 {
57 LIST_ENTRY *MapEntryListHead;
58 LIST_ENTRY *Link;
59 QUESTION_ID_MAP_ENTRY *MapEntry;
60
61 MapEntryListHead = GetMapEntryListHead (ThunkContext, VarStoreId);
62 ASSERT (MapEntryListHead != NULL);
63
64 Link = GetFirstNode (MapEntryListHead);
65
66 while (!IsNull (MapEntryListHead, Link)) {
67 MapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link);
68
69 if (MapEntry->FwQId == FwId) {
70 *UefiQId = MapEntry->UefiQid;
71 return EFI_SUCCESS;
72 }
73
74 Link = GetNextNode (MapEntryListHead, Link);
75 }
76
77 return EFI_NOT_FOUND;
78 }
79
80
81
82 EFI_STATUS
83 UCreateEndOfOpcode (
84 OUT EFI_HII_UPDATE_DATA *UefiData
85 )
86 {
87 EFI_IFR_END UOpcode;
88
89 ZeroMem (&UOpcode, sizeof (UOpcode));
90
91 UOpcode.Header.OpCode = EFI_IFR_END_OP;
92 UOpcode.Header.Length = sizeof (UOpcode);
93
94 return AppendToUpdateBuffer ((UINT8 *)&UOpcode, sizeof(UOpcode), UefiData);
95 }
96
97 EFI_STATUS
98 F2UCreateSubtitleOpCode (
99 IN CONST FRAMEWORK_EFI_IFR_SUBTITLE *FwSubTitle,
100 OUT EFI_HII_UPDATE_DATA *UefiData
101 )
102 {
103 EFI_IFR_SUBTITLE UOpcode;
104
105 ZeroMem (&UOpcode, sizeof(UOpcode));
106
107 UOpcode.Header.OpCode = EFI_IFR_SUBTITLE_OP;
108 UOpcode.Header.Length = sizeof (EFI_IFR_SUBTITLE);
109
110 UOpcode.Statement.Prompt = FwSubTitle->SubTitle;
111
112 return AppendToUpdateBuffer ((UINT8 *)&UOpcode, sizeof(UOpcode), UefiData);
113 }
114
115 EFI_STATUS
116 F2UCreateTextOpCode (
117 IN CONST FRAMEWORK_EFI_IFR_TEXT *FwText,
118 OUT EFI_HII_UPDATE_DATA *UefiData
119 )
120 {
121 EFI_IFR_TEXT UTextOpCode;
122 EFI_IFR_ACTION UActionOpCode;
123
124 if ((FwText->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) == 0) {
125 ZeroMem (&UTextOpCode, sizeof(UTextOpCode));
126
127 UTextOpCode.Header.OpCode = EFI_IFR_TEXT_OP;
128 UTextOpCode.Header.Length = sizeof (EFI_IFR_TEXT);
129
130 UTextOpCode.Statement.Help = FwText->Help;
131
132 UTextOpCode.Statement.Prompt = FwText->Text;
133 UTextOpCode.TextTwo = FwText->TextTwo;
134
135 return AppendToUpdateBuffer ((UINT8 *) &UTextOpCode, sizeof(UTextOpCode), UefiData);
136 } else {
137 //
138 // Iteractive Text Opcode is EFI_IFR_ACTION
139 //
140
141 ZeroMem (&UActionOpCode, sizeof (UActionOpCode));
142
143 UActionOpCode.Header.OpCode = EFI_IFR_ACTION_OP;
144 UActionOpCode.Header.Length = sizeof (EFI_IFR_ACTION);
145
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;
150
151 return AppendToUpdateBuffer ((UINT8 *) &UActionOpCode, sizeof(UActionOpCode), UefiData);
152
153 }
154 }
155
156 /*
157 typedef struct {
158 FRAMEWORK_EFI_IFR_OP_HEADER Header;
159 UINT16 FormId;
160 STRING_REF Prompt;
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;
165
166 */
167 EFI_STATUS
168 F2UCreateGotoOpCode (
169 IN CONST FRAMEWORK_EFI_IFR_REF *FwOpcode,
170 OUT EFI_HII_UPDATE_DATA *UefiData
171 )
172 {
173 EFI_IFR_REF UOpcode;
174
175 ZeroMem (&UOpcode, sizeof(UOpcode));
176
177 UOpcode.Header.Length = sizeof(UOpcode);
178 UOpcode.Header.OpCode = EFI_IFR_REF_OP;
179
180 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;
181 UOpcode.Question.Header.Help = FwOpcode->Help;
182 UOpcode.Question.QuestionId = FwOpcode->Key;
183
184 UOpcode.FormId = FwOpcode->FormId;
185
186 //
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.
189 //
190 UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));
191
192
193 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);
194 }
195
196
197 /*
198 typedef struct {
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;
205
206 typedef union {
207 UINT8 u8;
208 UINT16 u16;
209 UINT32 u32;
210 UINT64 u64;
211 BOOLEAN b;
212 EFI_HII_TIME time;
213 EFI_HII_DATE date;
214 EFI_STRING_ID string;
215 } EFI_IFR_TYPE_VALUE;
216
217 typedef struct _EFI_IFR_ONE_OF_OPTION {
218 EFI_IFR_OP_HEADER Header;
219 EFI_STRING_ID Option;
220 UINT8 Flags;
221 UINT8 Type;
222 EFI_IFR_TYPE_VALUE Value;
223 } EFI_IFR_ONE_OF_OPTION;
224
225 */
226 EFI_STATUS
227 F2UCreateOneOfOptionOpCode (
228 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOpcode,
229 IN UINTN Width,
230 OUT EFI_HII_UPDATE_DATA *UefiData
231 )
232 {
233 EFI_IFR_ONE_OF_OPTION UOpcode;
234
235 ZeroMem (&UOpcode, sizeof(UOpcode));
236
237 UOpcode.Header.Length = sizeof(UOpcode);
238 UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;
239
240 UOpcode.Option = FwOpcode->Option;
241 CopyMem (&UOpcode.Value.u8, &FwOpcode->Value, Width);
242
243 //
244
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
249 //
250 UOpcode.Flags |= (UINT8) ((FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING)) << 4);
251
252 switch (Width) {
253 case 1:
254 UOpcode.Type = EFI_IFR_TYPE_NUM_SIZE_8;
255 break;
256
257 case 2:
258 UOpcode.Type = EFI_IFR_TYPE_NUM_SIZE_16;
259 break;
260
261 default:
262 ASSERT (FALSE);
263 return EFI_UNSUPPORTED;
264 }
265
266 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);
267 }
268
269
270 /*
271 typedef struct _EFI_IFR_QUESTION_HEADER {
272 EFI_IFR_STATEMENT_HEADER Header;
273 EFI_QUESTION_ID QuestionId;
274 EFI_VARSTORE_ID VarStoreId;
275 union {
276 EFI_STRING_ID VarName;
277 UINT16 VarOffset;
278 } VarStoreInfo;
279 UINT8 Flags;
280 } EFI_IFR_QUESTION_HEADER;
281
282 typedef union {
283 struct {
284 UINT8 MinValue;
285 UINT8 MaxValue;
286 UINT8 Step;
287 } u8;
288 struct {
289 UINT16 MinValue;
290 UINT16 MaxValue;
291 UINT16 Step;
292 } u16;
293 struct {
294 UINT32 MinValue;
295 UINT32 MaxValue;
296 UINT32 Step;
297 } u32;
298 struct {
299 UINT64 MinValue;
300 UINT64 MaxValue;
301 UINT64 Step;
302 } u64;
303 } MINMAXSTEP_DATA;
304
305 typedef struct _EFI_IFR_ONE_OF {
306 EFI_IFR_OP_HEADER Header;
307 EFI_IFR_QUESTION_HEADER Question;
308 UINT8 Flags;
309 MINMAXSTEP_DATA data;
310 } EFI_IFR_ONE_OF;
311
312 typedef struct {
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;
319
320
321 */
322
323 EFI_STATUS
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,
330 OUT UINTN *DataCount
331 )
332 {
333 EFI_STATUS Status;
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;
339
340 ASSERT (NextFwOpcode != NULL);
341 ASSERT (DataCount != NULL);
342
343 OneOfOptionMap = NULL;
344
345 ZeroMem (&UOpcode, sizeof(UOpcode));
346 *DataCount = 0;
347
348 UOpcode.Header.Length = sizeof(UOpcode);
349 UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OP;
350 UOpcode.Header.Scope = 1;
351
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;
356
357 //
358 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
359 //
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);
363
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;
367
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;
372 }
373
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) {
380 case 1:
381 OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_8;
382 break;
383 case 2:
384 OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_16;
385 default:
386 ASSERT (FALSE);
387 break;
388 }
389
390 InsertTailList (&ThunkContext->OneOfOptionMapListHead, &OneOfOptionMap->Link);
391 }
392
393 OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));
394 ASSERT (OneOfOptionMapEntry != NULL);
395
396 OneOfOptionMapEntry->FwKey = FwOneOfOp->Key;
397 OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;
398
399 CopyMem (&OneOfOptionMapEntry->Value, &FwOneOfOp->Value, FwOpcode->Width);
400
401 ASSERT (OneOfOptionMap != NULL);
402 InsertTailList (&OneOfOptionMap->OneOfOptionMapEntryListHead, &OneOfOptionMapEntry->Link);
403 }
404
405 if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {
406 UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;
407 }
408
409 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);
410 }
411
412
413 if (UOpcode.Question.QuestionId == 0) {
414 //
415 // Assign QuestionId if still not assigned.
416 //
417 Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
418 if (EFI_ERROR (Status)) {
419 UOpcode.Question.QuestionId = FwOpcode->QuestionId;
420 }
421 }
422
423 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof (UOpcode), UefiData);
424 if (EFI_ERROR (Status)) {
425 return Status;
426 }
427 *DataCount += 1;
428
429 //
430 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.
431 //
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)) {
436 return Status;
437 }
438 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);
439 *DataCount += 1;
440 }
441
442 Status = UCreateEndOfOpcode (UefiData);
443 if (!EFI_ERROR (Status)) {
444 *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);
445 *DataCount += 1;
446 }
447
448 return Status;
449 }
450
451 /*
452 typedef struct _EFI_IFR_QUESTION_HEADER {
453 EFI_IFR_STATEMENT_HEADER Header;
454 EFI_QUESTION_ID QuestionId;
455 EFI_VARSTORE_ID VarStoreId;
456 union {
457 EFI_STRING_ID VarName;
458 UINT16 VarOffset;
459 } VarStoreInfo;
460 UINT8 Flags;
461 } EFI_IFR_QUESTION_HEADER;
462
463 typedef struct _EFI_IFR_ORDERED_LIST {
464 EFI_IFR_OP_HEADER Header;
465 EFI_IFR_QUESTION_HEADER Question;
466 UINT8 MaxContainers;
467 UINT8 Flags;
468 } EFI_IFR_ORDERED_LIST;
469
470 typedef struct {
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;
477
478 */
479 EFI_STATUS
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,
486 OUT UINTN *DataCount
487 )
488 {
489 EFI_IFR_ORDERED_LIST UOpcode;
490 EFI_STATUS Status;
491 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;
492 FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;
493
494 ZeroMem (&UOpcode, sizeof(UOpcode));
495 *DataCount = 0;
496
497 UOpcode.Header.Length = sizeof(UOpcode);
498 UOpcode.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;
499 UOpcode.Header.Scope = 1;
500
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;
505
506 UOpcode.MaxContainers = FwOpcode->MaxEntries;
507
508 //
509 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
510 //
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);
514
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;
518
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;
523 }
524
525 }
526 }
527
528 if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {
529 UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;
530 }
531
532 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);
533 }
534
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;
539 }
540 }
541
542 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);
543 if (EFI_ERROR (Status)) {
544 return Status;
545 }
546 *DataCount += 1;
547
548 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);
549 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {
550 //
551 // Each entry of Order List in Framework HII is always 1 byte in size
552 //
553 Status = F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, 1, UefiData);
554 if (EFI_ERROR (Status)) {
555 return Status;
556 }
557 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);
558 *DataCount += 1;
559 }
560
561 Status = UCreateEndOfOpcode (UefiData);
562 if (!EFI_ERROR (Status)) {
563 *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);
564 *DataCount += 1;
565 }
566
567 return Status;
568 }
569
570 /*
571 typedef struct _EFI_IFR_QUESTION_HEADER {
572 EFI_IFR_STATEMENT_HEADER Header;
573 EFI_QUESTION_ID QuestionId;
574 EFI_VARSTORE_ID VarStoreId;
575 union {
576 EFI_STRING_ID VarName;
577 UINT16 VarOffset;
578 } VarStoreInfo;
579 UINT8 Flags;
580 } EFI_IFR_QUESTION_HEADER;
581 */
582
583 /*
584 typedef struct _EFI_IFR_CHECKBOX {
585 EFI_IFR_OP_HEADER Header;
586 EFI_IFR_QUESTION_HEADER Question;
587 UINT8 Flags;
588 } EFI_IFR_CHECKBOX;
589 */
590
591 /*
592 typedef struct {
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;
601 */
602
603
604 EFI_STATUS
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
610 )
611 {
612 EFI_STATUS Status;
613 EFI_IFR_CHECKBOX UOpcode;
614
615 ZeroMem (&UOpcode, sizeof(UOpcode));
616
617 UOpcode.Header.Length = sizeof(UOpcode);
618 UOpcode.Header.OpCode = EFI_IFR_CHECKBOX_OP;
619
620 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;
621 UOpcode.Question.Header.Help = FwOpcode->Help;
622
623 if (FwOpcode->Key == 0) {
624 Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
625 if (EFI_ERROR (Status)) {
626 //
627 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
628 //
629 UOpcode.Question.QuestionId = FwOpcode->QuestionId;
630 }
631 } else {
632 UOpcode.Question.QuestionId = FwOpcode->Key;
633 }
634
635 UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID;
636 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;
637
638 //
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.
643 //
644 UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));
645
646 //
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.
651 //
652 UOpcode.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING));
653
654 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);
655 }
656
657
658 /*
659 typedef struct _EFI_IFR_QUESTION_HEADER {
660 EFI_IFR_STATEMENT_HEADER Header;
661 EFI_QUESTION_ID QuestionId;
662 EFI_VARSTORE_ID VarStoreId;
663 union {
664 EFI_STRING_ID VarName;
665 UINT16 VarOffset;
666 } VarStoreInfo;
667 UINT8 Flags;
668 } EFI_IFR_QUESTION_HEADER;
669
670 typedef union {
671 struct {
672 UINT8 MinValue;
673 UINT8 MaxValue;
674 UINT8 Step;
675 } u8;
676 struct {
677 UINT16 MinValue;
678 UINT16 MaxValue;
679 UINT16 Step;
680 } u16;
681 struct {
682 UINT32 MinValue;
683 UINT32 MaxValue;
684 UINT32 Step;
685 } u32;
686 struct {
687 UINT64 MinValue;
688 UINT64 MaxValue;
689 UINT64 Step;
690 } u64;
691 } MINMAXSTEP_DATA;
692
693 typedef struct _EFI_IFR_NUMERIC {
694 EFI_IFR_OP_HEADER Header;
695 EFI_IFR_QUESTION_HEADER Question;
696 UINT8 Flags;
697 MINMAXSTEP_DATA data;
698 } EFI_IFR_NUMERIC;
699
700
701 typedef struct {
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
709 UINT16 Minimum;
710 UINT16 Maximum;
711 UINT16 Step; // If step is 0, then manual input is specified, otherwise, left/right arrow selection is called for
712 UINT16 Default;
713 } FRAMEWORK_EFI_IFR_NUMERIC;
714
715 */
716
717
718 EFI_STATUS
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
724 )
725 {
726 EFI_STATUS Status;
727 EFI_IFR_NUMERIC UOpcode;
728 EFI_IFR_DEFAULT UOpcodeDefault;
729
730 ZeroMem (&UOpcode, sizeof(UOpcode));
731
732 if (FwOpcode->Key == 0) {
733 Status = FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
734 if (EFI_ERROR (Status)) {
735 //
736 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
737 //
738 UOpcode.Question.QuestionId = FwOpcode->QuestionId;
739 }
740 } else {
741 UOpcode.Question.QuestionId = FwOpcode->Key;
742 }
743
744 UOpcode.Header.Length = sizeof(UOpcode);
745 UOpcode.Header.OpCode = EFI_IFR_NUMERIC_OP;
746 //
747 // We need to create a nested default value for the UEFI Numeric Opcode.
748 // So turn on the scope.
749 //
750 if (FwOpcode->Default != 0) {
751 UOpcode.Header.Scope = 1;
752 }
753
754 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;
755 UOpcode.Question.Header.Help = FwOpcode->Help;
756
757 UOpcode.Question.QuestionId = FwOpcode->Key;
758 //
759 // BUGBUG RESERVED_VARSTORE_ID should be passed in.
760 //
761 UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID;
762 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;
763
764 UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));
765
766 //
767 // Framework Numeric values are all in UINT16 and displayed as decimal.
768 //
769 UOpcode.data.u16.MinValue = FwOpcode->Minimum;
770 UOpcode.data.u16.MaxValue = FwOpcode->Maximum;
771 UOpcode.data.u16.Step = FwOpcode->Step;
772
773 switch (FwOpcode->Width) {
774 case 1:
775 {
776 UOpcode.Flags = EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC;
777 break;
778 }
779 case 2:
780 {
781 UOpcode.Flags = EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC;
782 break;
783 }
784 default:
785 {
786 ASSERT (FALSE);
787 return EFI_INVALID_PARAMETER;
788 }
789 }
790
791 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);
792 if (EFI_ERROR (Status)) {
793 return Status;
794 }
795
796 //
797 // We need to create a default value.
798 //
799 if (FwOpcode->Default != 0) {
800 ZeroMem (&UOpcodeDefault, sizeof (UOpcodeDefault));
801 UOpcodeDefault.Header.Length = sizeof (UOpcodeDefault);
802 UOpcodeDefault.Header.OpCode = EFI_IFR_DEFAULT_OP;
803
804 UOpcodeDefault.DefaultId = 0;
805
806 switch (FwOpcode->Width) {
807 case 1:
808 {
809 UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_8;
810 break;
811 }
812 case 2:
813 {
814 UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_16;
815 break;
816 }
817 }
818
819 CopyMem (&UOpcodeDefault.Value.u8, &FwOpcode->Default, FwOpcode->Width);
820
821 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcodeDefault, sizeof(UOpcodeDefault), UefiData);
822 if (EFI_ERROR (Status)) {
823 return Status;
824 }
825 Status = UCreateEndOfOpcode (UefiData);
826 }
827
828 return Status;
829 }
830
831
832 /*
833
834 typedef struct _EFI_IFR_QUESTION_HEADER {
835 EFI_IFR_STATEMENT_HEADER Header;
836 EFI_QUESTION_ID QuestionId;
837 EFI_VARSTORE_ID VarStoreId;
838 union {
839 EFI_STRING_ID VarName;
840 UINT16 VarOffset;
841 } VarStoreInfo;
842 UINT8 Flags;
843 } EFI_IFR_QUESTION_HEADER;
844
845 typedef struct _EFI_IFR_STRING {
846 EFI_IFR_OP_HEADER Header;
847 EFI_IFR_QUESTION_HEADER Question;
848 UINT8 MinSize;
849 UINT8 MaxSize;
850 UINT8 Flags;
851 } EFI_IFR_STRING;
852
853
854 typedef struct {
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;
865
866
867 */
868
869 EFI_STATUS
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
875 )
876 {
877 EFI_IFR_STRING UOpcode;
878
879 ZeroMem (&UOpcode, sizeof(UOpcode));
880
881 if (FwOpcode->Key == 0) {
882 FwQuestionIdToUefiQuestionId (ThunkContext, VarStoreId, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);
883 } else {
884 UOpcode.Question.QuestionId = FwOpcode->Key;
885 }
886
887 UOpcode.Header.Length = sizeof(UOpcode);
888 UOpcode.Header.OpCode = EFI_IFR_STRING_OP;
889
890 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;
891 UOpcode.Question.Header.Help = FwOpcode->Help;
892
893 UOpcode.Question.QuestionId = FwOpcode->Key;
894 UOpcode.Question.VarStoreId = RESERVED_VARSTORE_ID;
895 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;
896
897 UOpcode.Question.Flags = (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));
898
899 UOpcode.MinSize = FwOpcode->MinSize;
900 UOpcode.MaxSize = FwOpcode->MaxSize;
901 UOpcode.Flags = EFI_IFR_STRING_MULTI_LINE;
902
903 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);
904 }
905
906 /*
907 typedef struct _EFI_IFR_GUID_BANNER {
908 EFI_IFR_OP_HEADER Header;
909 EFI_GUID Guid;
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;
915
916 typedef struct {
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;
922
923 */
924
925 EFI_STATUS
926 F2UCreateBannerOpCode (
927 IN CONST FRAMEWORK_EFI_IFR_BANNER *FwOpcode,
928 OUT EFI_HII_UPDATE_DATA *UefiData
929 )
930 {
931 EFI_IFR_GUID_BANNER UOpcode;
932
933 ZeroMem (&UOpcode, sizeof(UOpcode));
934
935 UOpcode.Header.Length = sizeof(UOpcode);
936 UOpcode.Header.OpCode = EFI_IFR_GUID_OP;
937
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;
943
944 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiData);
945 }
946
947
948 EFI_STATUS
949 FwUpdateDataToUefiUpdateData (
950 IN HII_THUNK_CONTEXT *ThunkContext,
951 IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA *Data,
952 IN BOOLEAN AddData,
953 OUT EFI_HII_UPDATE_DATA **UefiData
954 )
955 {
956 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpCode;
957 FRAMEWORK_EFI_IFR_OP_HEADER *NextFwOpCode;
958 EFI_HII_UPDATE_DATA *UefiOpCode;
959 UINTN Index;
960 EFI_STATUS Status;
961 UINTN DataCount;
962 UINT16 VarStoreId;
963
964 //
965 // Assume all dynamic opcode created is using active variable with VarStoreId of 1.
966 //
967 VarStoreId = 1;
968
969 UefiOpCode = AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA));
970 if (UefiOpCode == NULL) {
971 return EFI_OUT_OF_RESOURCES;
972 }
973
974 UefiOpCode->Data = AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL);
975 if (UefiOpCode->Data == NULL) {
976 return EFI_OUT_OF_RESOURCES;
977 }
978
979 UefiOpCode->BufferSize = LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;
980 UefiOpCode->Offset = 0;
981
982 FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *) &Data->Data;
983
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);
988 DataCount = 1;
989 break;
990
991 case FRAMEWORK_EFI_IFR_TEXT_OP:
992 Status = F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT *) FwOpCode, UefiOpCode);
993 DataCount = 1;
994 break;
995
996 case FRAMEWORK_EFI_IFR_REF_OP:
997 Status = F2UCreateGotoOpCode ((FRAMEWORK_EFI_IFR_REF *) FwOpCode, UefiOpCode);
998 DataCount = 1;
999 break;
1000
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;
1005 //
1006 // FwOpCode is already updated to point to the next opcode.
1007 //
1008 continue;
1009 }
1010 break;
1011
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;
1016 //
1017 // FwOpCode is already updated to point to the next opcode.
1018 //
1019 continue;
1020 }
1021 break;
1022
1023 case FRAMEWORK_EFI_IFR_CHECKBOX_OP:
1024 Status = F2UCreateCheckBoxOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_CHECKBOX *) FwOpCode, UefiOpCode);
1025 DataCount = 1;
1026 break;
1027
1028 case FRAMEWORK_EFI_IFR_STRING_OP:
1029 Status = F2UCreateStringOpCode (ThunkContext, VarStoreId, (FRAMEWORK_EFI_IFR_STRING *) FwOpCode, UefiOpCode);
1030 DataCount = 1;
1031 break;
1032
1033 case FRAMEWORK_EFI_IFR_BANNER_OP:
1034 Status = F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER *) FwOpCode, UefiOpCode);
1035 DataCount = 1;
1036 break;
1037
1038 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP:
1039 Status = UCreateEndOfOpcode (UefiOpCode);
1040 DataCount = 1;
1041 break;
1042
1043 default:
1044 ASSERT (FALSE);
1045 return EFI_UNSUPPORTED;
1046 }
1047
1048 if (EFI_ERROR (Status)) {
1049 FreePool (UefiOpCode->Data);
1050 FreePool (UefiOpCode);
1051 return Status;
1052 }
1053
1054 FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpCode + FwOpCode->Length);
1055 }
1056
1057 *UefiData = UefiOpCode;
1058
1059 return EFI_SUCCESS;
1060 }
1061