]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/IfrSupportLib/UefiIfrOpCodeCreation.c
Cleanup Cpu library class and CpuLib instance and BaseLib instance; and add comments...
[mirror_edk2.git] / MdePkg / Library / IfrSupportLib / UefiIfrOpCodeCreation.c
CommitLineData
e52c5a9f 1/** @file
ad1b3619 2 Library Routines to create IFR independent of string data - assume tokens already exist
3 Primarily to be used for exporting op-codes at a label in pre-defined forms.
4
e52c5a9f 5
6Copyright (c) 2007, Intel Corporation
7All rights reserved. This program and the accompanying materials
8are licensed and made available under the terms and conditions of the BSD License
9which accompanies this distribution. The full text of the license may be found at
10http://opensource.org/licenses/bsd-license.php
11
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
e52c5a9f 15
ad1b3619 16**/
e52c5a9f 17
ad1b3619 18#include "UefiIfrLibraryInternal.h"
e52c5a9f 19
ad1b3619 20/**
21 Check if the input question flags is a valid value.
22 The valid combination of question flags includes
23 EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY.
e52c5a9f 24
ad1b3619 25 @param Flags The question flags to check.
e52c5a9f 26
ad1b3619 27 @retval TRUE If the question flag is a valid combination.
28 @retval FALSE If the question flag is an invalid combination.
29
e52c5a9f 30**/
e52c5a9f 31BOOLEAN
32IsValidQuestionFlags (
33 IN UINT8 Flags
34 )
35{
ad1b3619 36 return (BOOLEAN) (((Flags & (~QUESTION_FLAGS)) != 0) ? FALSE : TRUE);
e52c5a9f 37}
38
ad1b3619 39/**
40 Check if the input value type is a valid type.
41 The valid value type is smaller or equal than EFI_IFR_TYPE_OTHER.
42
43 @param Type The value type to check.
44
45 @retval TRUE If the value type is valid.
46 @retval FALSE If the value type is invalid.
47
48**/
e52c5a9f 49BOOLEAN
50IsValidValueType (
51 IN UINT8 Type
52 )
53{
54 return (BOOLEAN) ((Type <= EFI_IFR_TYPE_OTHER) ? TRUE : FALSE);
55}
56
ad1b3619 57/**
58 Check if the input numeric flags is a valid value.
59
60 @param Flags The numeric flags to check.
61
62 @retval TRUE If the numeric flags is valid.
63 @retval FALSE If the numeric flags is invalid.
64
65**/
e52c5a9f 66BOOLEAN
67IsValidNumricFlags (
68 IN UINT8 Flags
69 )
70{
ad1b3619 71 if ((Flags & ~(EFI_IFR_NUMERIC_SIZE | EFI_IFR_DISPLAY)) != 0) {
e52c5a9f 72 return FALSE;
73 }
74
75 if ((Flags & EFI_IFR_DISPLAY) > EFI_IFR_DISPLAY_UINT_HEX) {
76 return FALSE;
77 }
78
79 return TRUE;
80}
81
ad1b3619 82/**
83 Check if the checkbox flags is a valid value.
84
85 @param Flags The checkbox flags to check.
86
87 @retval TRUE If the checkbox flags is valid.
88 @retval FALSE If the checkbox flags is invalid.
89
90**/
e52c5a9f 91BOOLEAN
92IsValidCheckboxFlags (
93 IN UINT8 Flags
94 )
95{
96 return (BOOLEAN) ((Flags <= EFI_IFR_CHECKBOX_DEFAULT_MFG) ? TRUE : FALSE);
97}
98
ad1b3619 99/**
100 Create EFI_IFR_END_OP opcode.
101
102 If Data is NULL or Data->Data is NULL, then ASSERT.
103
104 @param Data Destination for the created opcode binary
105
106 @retval EFI_SUCCESS Opcode create success
107 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
108
109**/
e52c5a9f 110EFI_STATUS
111EFIAPI
112CreateEndOpCode (
113 IN OUT EFI_HII_UPDATE_DATA *Data
114 )
115{
116 EFI_IFR_END End;
117 UINT8 *LocalBuffer;
118
119 ASSERT (Data != NULL && Data->Data != NULL);
120
121 if (Data->Offset + sizeof (EFI_IFR_END) > Data->BufferSize) {
122 return EFI_BUFFER_TOO_SMALL;
123 }
124
125 End.Header.Length = sizeof (EFI_IFR_END);
126 End.Header.OpCode = EFI_IFR_END_OP;
127 End.Header.Scope = 0;
128
129 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
130 //
131 // CopyMem is used for EFI_IFR_END to cover the unaligned address access.
132 //
e52c5a9f 133 CopyMem (LocalBuffer, &End, sizeof (EFI_IFR_END));
134 Data->Offset += sizeof (EFI_IFR_END);
135
136 return EFI_SUCCESS;
137}
138
ad1b3619 139/**
140 Create EFI_IFR_DEFAULT_OP opcode.
141
142 @param Value Value for the default
143 @param Type Type for the default
144 @param Data Destination for the created opcode binary
145
146 @retval EFI_SUCCESS Opcode create success
147 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
148 @retval EFI_INVALID_PARAMETER The type is not valid.
149
150**/
e52c5a9f 151EFI_STATUS
152EFIAPI
153CreateDefaultOpCode (
154 IN EFI_IFR_TYPE_VALUE *Value,
155 IN UINT8 Type,
156 IN OUT EFI_HII_UPDATE_DATA *Data
157 )
158{
159 EFI_IFR_DEFAULT Default;
160 UINT8 *LocalBuffer;
161
162 ASSERT (Data != NULL && Data->Data != NULL);
163
164 if ((Value == NULL) || !IsValidValueType (Type)) {
165 return EFI_INVALID_PARAMETER;
166 }
167
168 if (Data->Offset + sizeof (EFI_IFR_DEFAULT) > Data->BufferSize) {
169 return EFI_BUFFER_TOO_SMALL;
170 }
171
172 Default.Header.OpCode = EFI_IFR_DEFAULT_OP;
173 Default.Header.Length = sizeof (EFI_IFR_DEFAULT);
174 Default.Header.Scope = 0;
175 Default.Type = Type;
176 Default.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
177 CopyMem (&Default.Value, Value, sizeof(EFI_IFR_TYPE_VALUE));
178
179 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
180 //
181 // CopyMem is used for EFI_IFR_DEFAULT to cover the unaligned address access.
182 //
e52c5a9f 183 CopyMem (LocalBuffer, &Default, sizeof (EFI_IFR_DEFAULT));
184 Data->Offset += sizeof (EFI_IFR_DEFAULT);
185
186 return EFI_SUCCESS;
187}
188
ad1b3619 189/**
190 Create EFI_IFR_ACTION_OP opcode.
191
192 @param QuestionId Question ID
193 @param Prompt String ID for Prompt
194 @param Help String ID for Help
195 @param QuestionFlags Flags in Question Header
196 @param QuestionConfig String ID for configuration
197 @param Data Destination for the created opcode binary
198
199 @retval EFI_SUCCESS Opcode create success
200 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
201 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
202
203**/
e52c5a9f 204EFI_STATUS
205EFIAPI
206CreateActionOpCode (
207 IN EFI_QUESTION_ID QuestionId,
208 IN EFI_STRING_ID Prompt,
209 IN EFI_STRING_ID Help,
210 IN UINT8 QuestionFlags,
211 IN EFI_STRING_ID QuestionConfig,
212 IN OUT EFI_HII_UPDATE_DATA *Data
213 )
214{
215 EFI_IFR_ACTION Action;
216 UINT8 *LocalBuffer;
217
218 ASSERT (Data != NULL && Data->Data != NULL);
219
220 if (!IsValidQuestionFlags (QuestionFlags)) {
221 return EFI_INVALID_PARAMETER;
222 }
223
224 if (Data->Offset + sizeof (EFI_IFR_ACTION) > Data->BufferSize) {
225 return EFI_BUFFER_TOO_SMALL;
226 }
227
228 Action.Header.OpCode = EFI_IFR_ACTION_OP;
229 Action.Header.Length = sizeof (EFI_IFR_ACTION);
230 Action.Header.Scope = 0;
231 Action.Question.QuestionId = QuestionId;
232 Action.Question.Header.Prompt = Prompt;
233 Action.Question.Header.Help = Help;
234 Action.Question.VarStoreId = INVALID_VARSTORE_ID;
235 Action.Question.Flags = QuestionFlags;
236 Action.QuestionConfig = QuestionConfig;
237
238 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
239 //
240 // CopyMem is used for EFI_IFR_ACTION to cover the unaligned address access.
241 //
e52c5a9f 242 CopyMem (LocalBuffer, &Action, sizeof (EFI_IFR_ACTION));
243 Data->Offset += sizeof (EFI_IFR_ACTION);
244
245 return EFI_SUCCESS;
246}
247
ad1b3619 248/**
249 Create EFI_IFR_SUBTITLE_OP opcode.
250
251 @param Prompt String ID for Prompt
252 @param Help String ID for Help
253 @param Flags Subtitle opcode flags
254 @param Scope Subtitle Scope bit
255 @param Data Destination for the created opcode binary
256
257 @retval EFI_SUCCESS Opcode create success
258 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
259
260**/
e52c5a9f 261EFI_STATUS
262EFIAPI
263CreateSubTitleOpCode (
264 IN EFI_STRING_ID Prompt,
265 IN EFI_STRING_ID Help,
266 IN UINT8 Flags,
267 IN UINT8 Scope,
268 IN OUT EFI_HII_UPDATE_DATA *Data
269 )
270{
271 EFI_IFR_SUBTITLE Subtitle;
272 UINT8 *LocalBuffer;
273
274 ASSERT (Data != NULL && Data->Data != NULL);
275
276 if (Data->Offset + sizeof (EFI_IFR_SUBTITLE) > Data->BufferSize) {
277 return EFI_BUFFER_TOO_SMALL;
278 }
279
280 Subtitle.Header.OpCode = EFI_IFR_SUBTITLE_OP;
281 Subtitle.Header.Length = sizeof (EFI_IFR_SUBTITLE);
282 Subtitle.Header.Scope = Scope;
283 Subtitle.Statement.Prompt = Prompt;
284 Subtitle.Statement.Help = Help;
285 Subtitle.Flags = Flags;
286
287 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
288 //
289 // CopyMem is used for EFI_IFR_SUBTITLE to cover the unaligned address access.
290 //
e52c5a9f 291 CopyMem (LocalBuffer, &Subtitle, sizeof (EFI_IFR_SUBTITLE));
292 Data->Offset += sizeof (EFI_IFR_SUBTITLE);
293
294 return EFI_SUCCESS;
295}
296
297
ad1b3619 298/**
299 Create EFI_IFR_TEXT_OP opcode.
300
301 @param Prompt String ID for Prompt
302 @param Help String ID for Help
303 @param TextTwo String ID for text two
304 @param Data Destination for the created opcode binary
305
306 @retval EFI_SUCCESS Opcode create success
307 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
308
309**/
e52c5a9f 310EFI_STATUS
311EFIAPI
312CreateTextOpCode (
313 IN EFI_STRING_ID Prompt,
314 IN EFI_STRING_ID Help,
315 IN EFI_STRING_ID TextTwo,
316 IN OUT EFI_HII_UPDATE_DATA *Data
317 )
318{
319 EFI_IFR_TEXT Text;
320 UINT8 *LocalBuffer;
321
322 ASSERT (Data != NULL && Data->Data != NULL);
323
324 if (Data->Offset + sizeof (EFI_IFR_TEXT) > Data->BufferSize) {
325 return EFI_BUFFER_TOO_SMALL;
326 }
327
328 Text.Header.OpCode = EFI_IFR_TEXT_OP;
329 Text.Header.Length = sizeof (EFI_IFR_TEXT);
330 Text.Header.Scope = 0;
331 Text.Statement.Prompt = Prompt;
332 Text.Statement.Help = Help;
333 Text.TextTwo = TextTwo;
334
335 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
336 //
337 // CopyMem is used for EFI_IFR_TEXT to cover the unaligned address access.
338 //
e52c5a9f 339 CopyMem (LocalBuffer, &Text, sizeof (EFI_IFR_TEXT));
340 Data->Offset += sizeof (EFI_IFR_TEXT);
341
342 return EFI_SUCCESS;
343}
344
ad1b3619 345/**
346 Create EFI_IFR_REF_OP opcode.
347
348 @param FormId Destination Form ID
349 @param Prompt String ID for Prompt
350 @param Help String ID for Help
351 @param QuestionFlags Flags in Question Header
352 @param QuestionId Question ID
353 @param Data Destination for the created opcode binary
354
355 @retval EFI_SUCCESS Opcode create success
356 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
357 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
358
359**/
e52c5a9f 360EFI_STATUS
361EFIAPI
362CreateGotoOpCode (
363 IN EFI_FORM_ID FormId,
364 IN EFI_STRING_ID Prompt,
365 IN EFI_STRING_ID Help,
366 IN UINT8 QuestionFlags,
367 IN EFI_QUESTION_ID QuestionId,
368 IN OUT EFI_HII_UPDATE_DATA *Data
369 )
370{
371 EFI_IFR_REF Goto;
372 UINT8 *LocalBuffer;
373
374 ASSERT (Data != NULL && Data->Data != NULL);
375
376 if (!IsValidQuestionFlags (QuestionFlags)) {
377 return EFI_INVALID_PARAMETER;
378 }
379
380 if (Data->Offset + sizeof (EFI_IFR_REF) > Data->BufferSize) {
381 return EFI_BUFFER_TOO_SMALL;
382 }
383
384 Goto.Header.OpCode = EFI_IFR_REF_OP;
385 Goto.Header.Length = sizeof (EFI_IFR_REF);
386 Goto.Header.Scope = 0;
387 Goto.Question.Header.Prompt = Prompt;
388 Goto.Question.Header.Help = Help;
389 Goto.Question.VarStoreId = INVALID_VARSTORE_ID;
390 Goto.Question.QuestionId = QuestionId;
391 Goto.Question.Flags = QuestionFlags;
392 Goto.FormId = FormId;
393
394 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
395 //
396 // CopyMem is used for EFI_IFR_REF to cover the unaligned address access.
397 //
e52c5a9f 398 CopyMem (LocalBuffer, &Goto, sizeof (EFI_IFR_REF));
399 Data->Offset += sizeof (EFI_IFR_REF);
400
401 return EFI_SUCCESS;
402}
403
ad1b3619 404/**
405 Create EFI_IFR_ONE_OF_OPTION_OP opcode.
406
407 @param OptionCount The number of options.
408 @param OptionsList The list of Options.
409 @param Type The data type.
410 @param Data Destination for the created opcode binary
411
412 @retval EFI_SUCCESS Opcode create success
413 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
414
415**/
e52c5a9f 416EFI_STATUS
417EFIAPI
418CreateOneOfOptionOpCode (
419 IN UINTN OptionCount,
420 IN IFR_OPTION *OptionsList,
421 IN UINT8 Type,
422 IN OUT EFI_HII_UPDATE_DATA *Data
423 )
424{
425 UINTN Index;
426 UINT8 *LocalBuffer;
427 EFI_IFR_ONE_OF_OPTION OneOfOption;
428
429 ASSERT (Data != NULL && Data->Data != NULL);
430
431 if ((OptionCount != 0) && (OptionsList == NULL)) {
432 return EFI_INVALID_PARAMETER;
433 }
434
435 if (Data->Offset + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) > Data->BufferSize) {
436 return EFI_BUFFER_TOO_SMALL;
437 }
438
439 for (Index = 0; Index < OptionCount; Index++) {
440 OneOfOption.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;
441 OneOfOption.Header.Length = sizeof (EFI_IFR_ONE_OF_OPTION);
442 OneOfOption.Header.Scope = 0;
443
444 OneOfOption.Option = OptionsList[Index].StringToken;
445 OneOfOption.Value = OptionsList[Index].Value;
446 OneOfOption.Flags = (UINT8) (OptionsList[Index].Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG));
447 OneOfOption.Type = Type;
448
449 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
450 //
451 // CopyMem is used for EFI_IFR_ONF_OF_OPTION to cover the unaligned address access.
452 //
e52c5a9f 453 CopyMem (LocalBuffer, &OneOfOption, sizeof (EFI_IFR_ONE_OF_OPTION));
454 Data->Offset += sizeof (EFI_IFR_ONE_OF_OPTION);
455 }
456
457 return EFI_SUCCESS;
458}
459
ad1b3619 460/**
461 Create EFI_IFR_ONE_OF_OP opcode.
462
463 @param QuestionId Question ID
464 @param VarStoreId Storage ID
465 @param VarOffset Offset in Storage
466 @param Prompt String ID for Prompt
467 @param Help String ID for Help
468 @param QuestionFlags Flags in Question Header
469 @param OneOfFlags Flags for oneof opcode
470 @param OptionsList List of options
471 @param OptionCount Number of options in option list
472 @param Data Destination for the created opcode binary
473
474 @retval EFI_SUCCESS Opcode create success
475 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
476 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
477
478**/
e52c5a9f 479EFI_STATUS
480EFIAPI
481CreateOneOfOpCode (
482 IN EFI_QUESTION_ID QuestionId,
483 IN EFI_VARSTORE_ID VarStoreId,
484 IN UINT16 VarOffset,
485 IN EFI_STRING_ID Prompt,
486 IN EFI_STRING_ID Help,
487 IN UINT8 QuestionFlags,
488 IN UINT8 OneOfFlags,
489 IN IFR_OPTION *OptionsList,
490 IN UINTN OptionCount,
491 IN OUT EFI_HII_UPDATE_DATA *Data
492 )
493{
494 UINTN Length;
495 EFI_IFR_ONE_OF OneOf;
496 UINT8 *LocalBuffer;
497
498 ASSERT (Data != NULL && Data->Data != NULL);
499
500 if (!IsValidNumricFlags (OneOfFlags) ||
501 !IsValidQuestionFlags (QuestionFlags) ||
502 ((OptionCount != 0) && (OptionsList == NULL))) {
503 return EFI_INVALID_PARAMETER;
504 }
505
506 Length = sizeof (EFI_IFR_ONE_OF) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);
507 if (Data->Offset + Length > Data->BufferSize) {
508 return EFI_BUFFER_TOO_SMALL;
509 }
510
511 OneOf.Header.OpCode = EFI_IFR_ONE_OF_OP;
512 OneOf.Header.Length = sizeof (EFI_IFR_ONE_OF);
513 OneOf.Header.Scope = 1;
514 OneOf.Question.Header.Prompt = Prompt;
515 OneOf.Question.Header.Help = Help;
516 OneOf.Question.QuestionId = QuestionId;
517 OneOf.Question.VarStoreId = VarStoreId;
518 OneOf.Question.VarStoreInfo.VarOffset = VarOffset;
519 OneOf.Question.Flags = QuestionFlags;
520 OneOf.Flags = OneOfFlags;
521 ZeroMem ((VOID *) &OneOf.data, sizeof (MINMAXSTEP_DATA));
522
523 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
524 //
525 // CopyMem is used for EFI_IFR_ONF_OF to cover the unaligned address access.
526 //
e52c5a9f 527 CopyMem (LocalBuffer, &OneOf, sizeof (EFI_IFR_ONE_OF));
528 Data->Offset += sizeof (EFI_IFR_ONE_OF);
529
530 CreateOneOfOptionOpCode (OptionCount, OptionsList, (UINT8) (OneOfFlags & EFI_IFR_NUMERIC_SIZE), Data);
531
532 CreateEndOpCode (Data);
533
534 return EFI_SUCCESS;
535}
536
ad1b3619 537/**
538 Create EFI_IFR_ORDERED_LIST_OP opcode.
539
540 @param QuestionId Question ID
541 @param VarStoreId Storage ID
542 @param VarOffset Offset in Storage
543 @param Prompt String ID for Prompt
544 @param Help String ID for Help
545 @param QuestionFlags Flags in Question Header
546 @param OrderedListFlags Flags for ordered list opcode
547 @param DataType Type for option value
548 @param MaxContainers Maximum count for options in this ordered list
549 @param OptionsList List of options
550 @param OptionCount Number of options in option list
551 @param Data Destination for the created opcode binary
552
553 @retval EFI_SUCCESS Opcode create success
554 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
555 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
556
557**/
e52c5a9f 558EFI_STATUS
559EFIAPI
560CreateOrderedListOpCode (
561 IN EFI_QUESTION_ID QuestionId,
562 IN EFI_VARSTORE_ID VarStoreId,
563 IN UINT16 VarOffset,
564 IN EFI_STRING_ID Prompt,
565 IN EFI_STRING_ID Help,
566 IN UINT8 QuestionFlags,
567 IN UINT8 OrderedListFlags,
568 IN UINT8 DataType,
569 IN UINT8 MaxContainers,
570 IN IFR_OPTION *OptionsList,
571 IN UINTN OptionCount,
572 IN OUT EFI_HII_UPDATE_DATA *Data
573 )
574{
575 UINTN Length;
576 EFI_IFR_ORDERED_LIST OrderedList;
577 UINT8 *LocalBuffer;
578
579 ASSERT (Data != NULL && Data->Data != NULL);
580
581 if (!IsValidQuestionFlags (QuestionFlags) ||
582 ((OptionCount != 0) && (OptionsList == NULL))) {
583 return EFI_INVALID_PARAMETER;
584 }
585
586 if ((OrderedListFlags != 0) &&
587 (OrderedListFlags != EFI_IFR_UNIQUE_SET) &&
588 (OrderedListFlags != EFI_IFR_NO_EMPTY_SET)) {
589 return EFI_INVALID_PARAMETER;
590 }
591
592 Length = sizeof (EFI_IFR_ORDERED_LIST) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);
593 if (Data->Offset + Length > Data->BufferSize) {
594 return EFI_BUFFER_TOO_SMALL;
595 }
596
597 OrderedList.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;
598 OrderedList.Header.Length = sizeof (EFI_IFR_ORDERED_LIST);
599 OrderedList.Header.Scope = 1;
600 OrderedList.Question.Header.Prompt = Prompt;
601 OrderedList.Question.Header.Help = Help;
602 OrderedList.Question.QuestionId = QuestionId;
603 OrderedList.Question.VarStoreId = VarStoreId;
604 OrderedList.Question.VarStoreInfo.VarOffset = VarOffset;
605 OrderedList.Question.Flags = QuestionFlags;
606 OrderedList.MaxContainers = MaxContainers;
607 OrderedList.Flags = OrderedListFlags;
608
609 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
610 //
611 // CopyMem is used for EFI_IFR_ORDERED_LIST to cover the unaligned address access.
612 //
e52c5a9f 613 CopyMem (LocalBuffer, &OrderedList, sizeof (EFI_IFR_ORDERED_LIST));
614 Data->Offset += sizeof (EFI_IFR_ORDERED_LIST);
615
616 CreateOneOfOptionOpCode (OptionCount, OptionsList, DataType, Data);
617
618 CreateEndOpCode (Data);
619
620 return EFI_SUCCESS;
621}
622
ad1b3619 623/**
624 Create EFI_IFR_CHECKBOX_OP opcode.
625
626 @param QuestionId Question ID
627 @param VarStoreId Storage ID
628 @param VarOffset Offset in Storage
629 @param Prompt String ID for Prompt
630 @param Help String ID for Help
631 @param QuestionFlags Flags in Question Header
632 @param CheckBoxFlags Flags for checkbox opcode
633 @param Data Destination for the created opcode binary
634
635 @retval EFI_SUCCESS Opcode create success
636 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
637 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
638
639**/
e52c5a9f 640EFI_STATUS
641EFIAPI
642CreateCheckBoxOpCode (
643 IN EFI_QUESTION_ID QuestionId,
644 IN EFI_VARSTORE_ID VarStoreId,
645 IN UINT16 VarOffset,
646 IN EFI_STRING_ID Prompt,
647 IN EFI_STRING_ID Help,
648 IN UINT8 QuestionFlags,
649 IN UINT8 CheckBoxFlags,
650 IN OUT EFI_HII_UPDATE_DATA *Data
651 )
652{
653 EFI_IFR_CHECKBOX CheckBox;
654 UINT8 *LocalBuffer;
655
656 ASSERT (Data != NULL && Data->Data != NULL);
657
658 if (!IsValidQuestionFlags (QuestionFlags) || !IsValidCheckboxFlags (CheckBoxFlags)) {
659 return EFI_INVALID_PARAMETER;
660 }
661
662 if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) {
663 return EFI_BUFFER_TOO_SMALL;
664 }
665
666 CheckBox.Header.OpCode = EFI_IFR_CHECKBOX_OP;
667 CheckBox.Header.Length = sizeof (EFI_IFR_CHECKBOX);
668 CheckBox.Header.Scope = 0;
669 CheckBox.Question.QuestionId = QuestionId;
670 CheckBox.Question.VarStoreId = VarStoreId;
671 CheckBox.Question.VarStoreInfo.VarOffset = VarOffset;
672 CheckBox.Question.Header.Prompt = Prompt;
673 CheckBox.Question.Header.Help = Help;
674 CheckBox.Question.Flags = QuestionFlags;
675 CheckBox.Flags = CheckBoxFlags;
676
677 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
678 //
679 // CopyMem is used for EFI_IFR_CHECKBOX to cover the unaligned address access.
680 //
e52c5a9f 681 CopyMem (LocalBuffer, &CheckBox, sizeof (EFI_IFR_CHECKBOX));
682 Data->Offset += sizeof (EFI_IFR_CHECKBOX);
683
684 return EFI_SUCCESS;
685}
686
ad1b3619 687/**
688 Create EFI_IFR_NUMERIC_OP opcode.
689
690 @param QuestionId Question ID
691 @param VarStoreId Storage ID
692 @param VarOffset Offset in Storage
693 @param Prompt String ID for Prompt
694 @param Help String ID for Help
695 @param QuestionFlags Flags in Question Header
696 @param NumericFlags Flags for numeric opcode
697 @param Minimum Numeric minimum value
698 @param Maximum Numeric maximum value
699 @param Step Numeric step for edit
700 @param Default Numeric default value
701 @param Data Destination for the created opcode binary
702
703 @retval EFI_SUCCESS Opcode create success
704 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
705 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
706
707**/
e52c5a9f 708EFI_STATUS
709EFIAPI
710CreateNumericOpCode (
711 IN EFI_QUESTION_ID QuestionId,
712 IN EFI_VARSTORE_ID VarStoreId,
713 IN UINT16 VarOffset,
714 IN EFI_STRING_ID Prompt,
715 IN EFI_STRING_ID Help,
716 IN UINT8 QuestionFlags,
717 IN UINT8 NumericFlags,
718 IN UINT64 Minimum,
719 IN UINT64 Maximum,
720 IN UINT64 Step,
721 IN UINT64 Default,
722 IN OUT EFI_HII_UPDATE_DATA *Data
723 )
724{
725 EFI_STATUS Status;
726 EFI_IFR_NUMERIC Numeric;
727 MINMAXSTEP_DATA MinMaxStep;
728 EFI_IFR_TYPE_VALUE DefaultValue;
729 UINT8 *LocalBuffer;
730
731 ASSERT (Data != NULL && Data->Data != NULL);
732
733 if (!IsValidQuestionFlags (QuestionFlags) || !IsValidNumricFlags (NumericFlags)) {
734 return EFI_INVALID_PARAMETER;
735 }
736
737 if (Data->Offset + sizeof (EFI_IFR_CHECKBOX) > Data->BufferSize) {
738 return EFI_BUFFER_TOO_SMALL;
739 }
740
741 Numeric.Header.OpCode = EFI_IFR_NUMERIC_OP;
742 Numeric.Header.Length = sizeof (EFI_IFR_NUMERIC);
743 Numeric.Header.Scope = 1;
744 Numeric.Question.QuestionId = QuestionId;
745 Numeric.Question.VarStoreId = VarStoreId;
746 Numeric.Question.VarStoreInfo.VarOffset = VarOffset;
747 Numeric.Question.Header.Prompt = Prompt;
748 Numeric.Question.Header.Help = Help;
749 Numeric.Question.Flags = QuestionFlags;
750 Numeric.Flags = NumericFlags;
751
752 switch (NumericFlags & EFI_IFR_NUMERIC_SIZE) {
753 case EFI_IFR_NUMERIC_SIZE_1:
754 MinMaxStep.u8.MinValue = (UINT8) Minimum;
755 MinMaxStep.u8.MaxValue = (UINT8) Maximum;
756 MinMaxStep.u8.Step = (UINT8) Step;
757 break;
758
759 case EFI_IFR_NUMERIC_SIZE_2:
760 MinMaxStep.u16.MinValue = (UINT16) Minimum;
761 MinMaxStep.u16.MaxValue = (UINT16) Maximum;
762 MinMaxStep.u16.Step = (UINT16) Step;
763 break;
764
765 case EFI_IFR_NUMERIC_SIZE_4:
766 MinMaxStep.u32.MinValue = (UINT32) Minimum;
767 MinMaxStep.u32.MaxValue = (UINT32) Maximum;
768 MinMaxStep.u32.Step = (UINT32) Step;
769 break;
770
771 case EFI_IFR_NUMERIC_SIZE_8:
772 MinMaxStep.u64.MinValue = Minimum;
773 MinMaxStep.u64.MaxValue = Maximum;
774 MinMaxStep.u64.Step = Step;
775 break;
776 }
777
778 CopyMem (&Numeric.data, &MinMaxStep, sizeof (MINMAXSTEP_DATA));
779
780 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
781 //
782 // CopyMem is used for EFI_IFR_NUMERIC to cover the unaligned address access.
783 //
e52c5a9f 784 CopyMem (LocalBuffer, &Numeric, sizeof (EFI_IFR_NUMERIC));
785 Data->Offset += sizeof (EFI_IFR_NUMERIC);
786
787 DefaultValue.u64 = Default;
788 Status = CreateDefaultOpCode (&DefaultValue, (UINT8) (NumericFlags & EFI_IFR_NUMERIC_SIZE), Data);
789 if (EFI_ERROR(Status)) {
790 return Status;
791 }
792
793 CreateEndOpCode (Data);
794
795 return EFI_SUCCESS;
796}
797
ad1b3619 798/**
799 Create EFI_IFR_STRING_OP opcode.
800
801 @param QuestionId Question ID
802 @param VarStoreId Storage ID
803 @param VarOffset Offset in Storage
804 @param Prompt String ID for Prompt
805 @param Help String ID for Help
806 @param QuestionFlags Flags in Question Header
807 @param StringFlags Flags for string opcode
808 @param MinSize String minimum length
809 @param MaxSize String maximum length
810 @param Data Destination for the created opcode binary
811
812 @retval EFI_SUCCESS Opcode create success
813 @retval EFI_BUFFER_TOO_SMALL The space reserved in Data field is too small.
814 @retval EFI_INVALID_PARAMETER If QuestionFlags is not valid.
815
816**/
e52c5a9f 817EFI_STATUS
818EFIAPI
819CreateStringOpCode (
820 IN EFI_QUESTION_ID QuestionId,
821 IN EFI_VARSTORE_ID VarStoreId,
822 IN UINT16 VarOffset,
823 IN EFI_STRING_ID Prompt,
824 IN EFI_STRING_ID Help,
825 IN UINT8 QuestionFlags,
826 IN UINT8 StringFlags,
827 IN UINT8 MinSize,
828 IN UINT8 MaxSize,
829 IN OUT EFI_HII_UPDATE_DATA *Data
830 )
831{
832 EFI_IFR_STRING String;
833 UINT8 *LocalBuffer;
834
835 ASSERT (Data != NULL && Data->Data != NULL);
836
ad1b3619 837 if (!IsValidQuestionFlags (QuestionFlags) || (StringFlags & ~EFI_IFR_STRING_MULTI_LINE) != 0) {
e52c5a9f 838 return EFI_INVALID_PARAMETER;
839 }
840
841 if (Data->Offset + sizeof (EFI_IFR_STRING) > Data->BufferSize) {
842 return EFI_BUFFER_TOO_SMALL;
843 }
844
845 String.Header.OpCode = EFI_IFR_STRING_OP;
846 String.Header.Length = sizeof (EFI_IFR_STRING);
847 String.Header.Scope = 0;
848 String.Question.Header.Prompt = Prompt;
849 String.Question.Header.Help = Help;
850 String.Question.QuestionId = QuestionId;
851 String.Question.VarStoreId = VarStoreId;
852 String.Question.VarStoreInfo.VarOffset = VarOffset;
853 String.Question.Flags = QuestionFlags;
854 String.MinSize = MinSize;
855 String.MaxSize = MaxSize;
856 String.Flags = StringFlags;
857
858 LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
a8ff9715
LG
859 //
860 // CopyMem is used for EFI_IFR_STRING to cover the unaligned address access.
861 //
e52c5a9f 862 CopyMem (LocalBuffer, &String, sizeof (EFI_IFR_STRING));
863 Data->Offset += sizeof (EFI_IFR_STRING);
864
865 return EFI_SUCCESS;
866}
867
868