]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Sample/Tools/Source/UefiVfrCompile/VfrFormPkg.cpp
8a0675b859a9a91fc75ded2b52c248eb25da54d6
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / UefiVfrCompile / VfrFormPkg.cpp
1 /*++
2
3 Copyright (c) 2004 - 2010, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 VfrFormPkg.cpp
15
16 Abstract:
17
18 --*/
19
20 #include "stdio.h"
21 #include "VfrFormPkg.h"
22
23 /*
24 * The definition of CFormPkg's member function
25 */
26
27 SPendingAssign::SPendingAssign (
28 IN INT8 *Key,
29 IN VOID *Addr,
30 IN UINT32 Len,
31 IN UINT32 LineNo
32 )
33 {
34 if (Key != NULL) {
35 mKey = new INT8[strlen (Key) + 1];
36 if (mKey != NULL) {
37 strcpy (mKey, Key);
38 }
39 } else {
40 mKey = NULL;
41 }
42 mAddr = Addr;
43 mLen = Len;
44 mFlag = PENDING;
45 mLineNo = LineNo;
46 mNext = NULL;
47 }
48
49 SPendingAssign::~SPendingAssign (
50 VOID
51 )
52 {
53 if (mKey != NULL) {
54 delete mKey;
55 }
56 mAddr = NULL;
57 mLen = 0;
58 mLineNo = 0;
59 mNext = NULL;
60 }
61
62 VOID
63 SPendingAssign::SetAddrAndLen (
64 IN VOID *Addr,
65 IN UINT32 LineNo
66 )
67 {
68 mAddr = Addr;
69 mLineNo = LineNo;
70 }
71
72 VOID
73 SPendingAssign::AssignValue (
74 IN VOID *Addr,
75 IN UINT32 Len
76 )
77 {
78 memcpy (mAddr, Addr, (mLen < Len ? mLen : Len));
79 mFlag = ASSIGNED;
80 }
81
82 INT8 *
83 SPendingAssign::GetKey (
84 VOID
85 )
86 {
87 return mKey;
88 }
89
90 CFormPkg::CFormPkg (
91 IN UINT32 BufferSize = 4096
92 )
93 {
94 CHAR8 *BufferStart;
95 CHAR8 *BufferEnd;
96 SBufferNode *Node;
97
98 mPkgLength = 0;
99 mBufferNodeQueueHead = NULL;
100 mCurrBufferNode = NULL;
101
102 Node = new SBufferNode;
103 if (Node == NULL) {
104 return ;
105 }
106 BufferStart = new CHAR8[BufferSize];
107 if (BufferStart == NULL) {
108 return;
109 }
110 BufferEnd = BufferStart + BufferSize;
111
112 memset (BufferStart, 0, BufferSize);
113 Node->mBufferStart = BufferStart;
114 Node->mBufferEnd = BufferEnd;
115 Node->mBufferFree = BufferStart;
116 Node->mNext = NULL;
117
118 mBufferSize = BufferSize;
119 mBufferNodeQueueHead = Node;
120 mBufferNodeQueueTail = Node;
121 mCurrBufferNode = Node;
122 }
123
124 CFormPkg::~CFormPkg ()
125 {
126 SBufferNode *pBNode;
127 SPendingAssign *pPNode;
128
129 while (mBufferNodeQueueHead != NULL) {
130 pBNode = mBufferNodeQueueHead;
131 mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;
132 if (pBNode->mBufferStart != NULL) {
133 delete pBNode->mBufferStart;
134 delete pBNode;
135 }
136 }
137 mBufferNodeQueueTail = NULL;
138 mCurrBufferNode = NULL;
139
140 while (PendingAssignList != NULL) {
141 pPNode = PendingAssignList;
142 PendingAssignList = PendingAssignList->mNext;
143 delete pPNode;
144 }
145 PendingAssignList = NULL;
146 }
147
148 CHAR8 *
149 CFormPkg::IfrBinBufferGet (
150 IN UINT32 Len
151 )
152 {
153 CHAR8 *BinBuffer = NULL;
154
155 if ((Len == 0) || (Len > mBufferSize)) {
156 return NULL;
157 }
158
159 if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {
160 BinBuffer = mCurrBufferNode->mBufferFree;
161 mCurrBufferNode->mBufferFree += Len;
162 } else {
163 SBufferNode *Node;
164
165 Node = new SBufferNode;
166 if (Node == NULL) {
167 return NULL;
168 }
169
170 Node->mBufferStart = new CHAR8[mBufferSize];
171 if (Node->mBufferStart == NULL) {
172 delete Node;
173 return NULL;
174 } else {
175 memset (Node->mBufferStart, 0, mBufferSize);
176 Node->mBufferEnd = Node->mBufferStart + mBufferSize;
177 Node->mBufferFree = Node->mBufferStart;
178 Node->mNext = NULL;
179 }
180
181 if (mBufferNodeQueueTail == NULL) {
182 mBufferNodeQueueHead = mBufferNodeQueueTail = Node;
183 } else {
184 mBufferNodeQueueTail->mNext = Node;
185 mBufferNodeQueueTail = Node;
186 }
187 mCurrBufferNode = Node;
188
189 //
190 // Now try again.
191 //
192 BinBuffer = mCurrBufferNode->mBufferFree;
193 mCurrBufferNode->mBufferFree += Len;
194 }
195
196 mPkgLength += Len;
197
198 return BinBuffer;
199 }
200
201 inline
202 UINT32
203 CFormPkg::GetPkgLength (
204 VOID
205 )
206 {
207 return mPkgLength;
208 }
209
210 VOID
211 CFormPkg::Open (
212 VOID
213 )
214 {
215 mReadBufferNode = mBufferNodeQueueHead;
216 mReadBufferOffset = 0;
217 }
218
219 VOID
220 CFormPkg::Close (
221 VOID
222 )
223 {
224 mReadBufferNode = NULL;
225 mReadBufferOffset = 0;
226 }
227
228 UINT32
229 CFormPkg::Read (
230 IN CHAR8 *Buffer,
231 IN UINT32 Size
232 )
233 {
234 UINT32 Index;
235
236 if ((Size == 0) || (Buffer == NULL)) {
237 return 0;
238 }
239
240 if (mReadBufferNode == NULL) {
241 return 0;
242 }
243
244 for (Index = 0; Index < Size; Index++) {
245 if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {
246 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];
247 } else {
248 if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {
249 return Index;
250 } else {
251 mReadBufferOffset = 0;
252 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];
253 }
254 }
255 }
256
257 return Size;
258 }
259
260 EFI_VFR_RETURN_CODE
261 CFormPkg::BuildPkgHdr (
262 OUT EFI_HII_PACKAGE_HEADER **PkgHdr
263 )
264 {
265 if (PkgHdr == NULL) {
266 return VFR_RETURN_FATAL_ERROR;
267 }
268
269 if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {
270 return VFR_RETURN_OUT_FOR_RESOURCES;
271 }
272
273 (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;
274 (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);
275 return VFR_RETURN_SUCCESS;
276 }
277
278 EFI_VFR_RETURN_CODE
279 CFormPkg::BuildPkg (
280 IN FILE *Output
281 )
282 {
283 EFI_VFR_RETURN_CODE Ret;
284 CHAR8 Buffer[1024];
285 UINT32 Size;
286 EFI_HII_PACKAGE_HEADER *PkgHdr;
287
288 if (Output == NULL) {
289 return VFR_RETURN_FATAL_ERROR;
290 }
291
292 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
293 return Ret;
294 }
295 fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);
296 delete PkgHdr;
297
298 Open ();
299 while ((Size = Read (Buffer, 1024)) != 0) {
300 fwrite (Buffer, Size, 1, Output);
301 }
302 Close ();
303
304 return VFR_RETURN_SUCCESS;
305 }
306
307 VOID
308 CFormPkg::_WRITE_PKG_LINE (
309 IN FILE *pFile,
310 IN UINT32 LineBytes,
311 IN INT8 *LineHeader,
312 IN INT8 *BlkBuf,
313 IN UINT32 BlkSize
314 )
315 {
316 UINT32 Index;
317
318 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
319 return;
320 }
321
322 for (Index = 0; Index < BlkSize; Index++) {
323 if ((Index % LineBytes) == 0) {
324 fprintf (pFile, "\n%s", LineHeader);
325 }
326 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
327 }
328 }
329
330 VOID
331 CFormPkg::_WRITE_PKG_END (
332 IN FILE *pFile,
333 IN UINT32 LineBytes,
334 IN INT8 *LineHeader,
335 IN INT8 *BlkBuf,
336 IN UINT32 BlkSize
337 )
338 {
339 UINT32 Index;
340
341 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
342 return;
343 }
344
345 for (Index = 0; Index < BlkSize - 1; Index++) {
346 if ((Index % LineBytes) == 0) {
347 fprintf (pFile, "\n%s", LineHeader);
348 }
349 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
350 }
351
352 if ((Index % LineBytes) == 0) {
353 fprintf (pFile, "\n%s", LineHeader);
354 }
355 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
356 }
357
358 #define BYTES_PRE_LINE 0x10
359
360 EFI_VFR_RETURN_CODE
361 CFormPkg::GenCFile (
362 IN INT8 *BaseName,
363 IN FILE *pFile
364 )
365 {
366 EFI_VFR_RETURN_CODE Ret;
367 INT8 Buffer[BYTES_PRE_LINE * 8];
368 EFI_HII_PACKAGE_HEADER *PkgHdr;
369 UINT32 PkgLength = 0;
370 UINT32 ReadSize = 0;
371
372 if ((BaseName == NULL) || (pFile == NULL)) {
373 return VFR_RETURN_FATAL_ERROR;
374 }
375
376 fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);
377
378 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
379 return Ret;
380 }
381
382 fprintf (pFile, " // ARRAY LENGTH\n");
383 PkgLength = PkgHdr->Length + sizeof (UINT32);
384 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (INT8 *)&PkgLength, sizeof (UINT32));
385
386 fprintf (pFile, "\n\n // PACKAGE HEADER\n");
387 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (INT8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));
388 PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);
389
390 fprintf (pFile, "\n\n // PACKAGE DATA\n");
391 Open ();
392 while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {
393 PkgLength += ReadSize;
394 if (PkgLength < PkgHdr->Length) {
395 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);
396 } else {
397 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);
398 }
399 }
400 Close ();
401
402 delete PkgHdr;
403 fprintf (pFile, "\n};\n");
404
405 return VFR_RETURN_SUCCESS;
406 }
407
408 EFI_VFR_RETURN_CODE
409 CFormPkg::AssignPending (
410 IN INT8 *Key,
411 IN VOID *ValAddr,
412 IN UINT32 ValLen,
413 IN UINT32 LineNo
414 )
415 {
416 SPendingAssign *pNew;
417
418 pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo);
419 if (pNew == NULL) {
420 return VFR_RETURN_OUT_FOR_RESOURCES;
421 }
422
423 pNew->mNext = PendingAssignList;
424 PendingAssignList = pNew;
425 return VFR_RETURN_SUCCESS;
426 }
427
428 VOID
429 CFormPkg::DoPendingAssign (
430 IN INT8 *Key,
431 IN VOID *ValAddr,
432 IN UINT32 ValLen
433 )
434 {
435 SPendingAssign *pNode;
436
437 if ((Key == NULL) || (ValAddr == NULL)) {
438 return;
439 }
440
441 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
442 if (strcmp (pNode->mKey, Key) == 0) {
443 pNode->AssignValue (ValAddr, ValLen);
444 }
445 }
446 }
447
448 bool
449 CFormPkg::HavePendingUnassigned (
450 VOID
451 )
452 {
453 SPendingAssign *pNode;
454
455 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
456 if (pNode->mFlag == PENDING) {
457 return TRUE;
458 }
459 }
460
461 return FALSE;
462 }
463
464 VOID
465 CFormPkg::PendingAssignPrintAll (
466 VOID
467 )
468 {
469 SPendingAssign *pNode;
470
471 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
472 if (pNode->mFlag == PENDING) {
473 gCVfrErrorHandle.PrintError (pNode->mLineNo, pNode->mKey, "can not assign value because not defined");
474 }
475 }
476 }
477
478 CFormPkg gCFormPkg;
479
480 SIfrRecord::SIfrRecord (
481 VOID
482 )
483 {
484 mIfrBinBuf = NULL;
485 mBinBufLen = 0;
486 mLineNo = 0xFFFFFFFF;
487 mOffset = 0xFFFFFFFF;
488 mNext = NULL;
489 }
490
491 SIfrRecord::~SIfrRecord (
492 VOID
493 )
494 {
495 if (mIfrBinBuf != NULL) {
496 delete mIfrBinBuf;
497 mIfrBinBuf = NULL;
498 }
499 mLineNo = 0xFFFFFFFF;
500 mOffset = 0xFFFFFFFF;
501 mBinBufLen = 0;
502 mNext = NULL;
503 }
504
505 CIfrRecordInfoDB::CIfrRecordInfoDB (
506 VOID
507 )
508 {
509 mSwitch = FALSE;
510 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;
511 mIfrRecordListHead = NULL;
512 mIfrRecordListTail = NULL;
513 }
514
515 CIfrRecordInfoDB::~CIfrRecordInfoDB (
516 VOID
517 )
518 {
519 SIfrRecord *pNode;
520
521 while (mIfrRecordListHead != NULL) {
522 pNode = mIfrRecordListHead;
523 mIfrRecordListHead = mIfrRecordListHead->mNext;
524 delete pNode;
525 }
526 }
527
528 SIfrRecord *
529 CIfrRecordInfoDB::GetRecordInfoFromIdx (
530 IN UINT32 RecordIdx
531 )
532 {
533 UINT32 Idx;
534 SIfrRecord *pNode = NULL;
535
536 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {
537 return NULL;
538 }
539
540 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;
541 (Idx != RecordIdx) && (pNode != NULL);
542 Idx++, pNode = pNode->mNext)
543 ;
544
545 return pNode;
546 }
547
548 UINT32
549 CIfrRecordInfoDB::IfrRecordRegister (
550 IN UINT32 LineNo,
551 IN CHAR8 *IfrBinBuf,
552 IN UINT8 BinBufLen,
553 IN UINT32 Offset
554 )
555 {
556 SIfrRecord *pNew;
557
558 if (mSwitch == FALSE) {
559 return EFI_IFR_RECORDINFO_IDX_INVALUD;
560 }
561
562 if ((pNew = new SIfrRecord) == NULL) {
563 return EFI_IFR_RECORDINFO_IDX_INVALUD;
564 }
565
566 if (mIfrRecordListHead == NULL) {
567 mIfrRecordListHead = pNew;
568 mIfrRecordListTail = pNew;
569 } else {
570 mIfrRecordListTail->mNext = pNew;
571 mIfrRecordListTail = pNew;
572 }
573 mRecordCount++;
574
575 return mRecordCount;
576 }
577
578 VOID
579 CIfrRecordInfoDB::IfrRecordInfoUpdate (
580 IN UINT32 RecordIdx,
581 IN UINT32 LineNo,
582 IN CHAR8 *BinBuf,
583 IN UINT8 BinBufLen,
584 IN UINT32 Offset
585 )
586 {
587 SIfrRecord *pNode;
588
589 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {
590 return;
591 }
592
593 pNode->mLineNo = LineNo;
594 pNode->mOffset = Offset;
595 pNode->mBinBufLen = BinBufLen;
596 if (BinBuf != NULL) {
597 if (pNode->mIfrBinBuf != NULL) {
598 delete pNode->mIfrBinBuf;
599 }
600 pNode->mIfrBinBuf = new CHAR8[BinBufLen];
601 if (pNode->mIfrBinBuf != NULL) {
602 memcpy (pNode->mIfrBinBuf, BinBuf, BinBufLen);
603 }
604 }
605 }
606
607 VOID
608 CIfrRecordInfoDB::IfrRecordOutput (
609 IN FILE *File,
610 IN UINT32 LineNo
611 )
612 {
613 SIfrRecord *pNode;
614 UINT8 Index;
615
616 if (mSwitch == FALSE) {
617 return;
618 }
619
620 if (File == NULL) {
621 return;
622 }
623
624 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
625 if (pNode->mLineNo == LineNo) {
626 fprintf (File, ">%08X: ", pNode->mOffset);
627 if (pNode->mIfrBinBuf != NULL) {
628 for (Index = 0; Index < pNode->mBinBufLen; Index++) {
629 fprintf (File, "%02X ", pNode->mIfrBinBuf[Index]);
630 }
631 }
632 fprintf (File, "\n");
633 }
634 }
635 }
636
637 CIfrRecordInfoDB gCIfrRecordInfoDB;
638
639 VOID
640 CIfrObj::_EMIT_PENDING_OBJ (
641 VOID
642 )
643 {
644 CHAR8 *ObjBinBuf = NULL;
645
646 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);
647 if (ObjBinBuf != NULL) {
648 memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);
649 }
650
651 if (mObjBinBuf != NULL) {
652 delete mObjBinBuf;
653 }
654 }
655
656 /*
657 * The definition of CIfrObj's member function
658 */
659 static struct {
660 UINT8 mSize;
661 UINT8 mScope;
662 } gOpcodeSizesScopeTable[] = {
663 { 0, 0 }, // EFI_IFR_INVALID - 0x00
664 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP
665 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP
666 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP
667 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP
668 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
669 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP
670 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP
671 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP
672 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
673 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
674 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP
675 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP
676 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP
677 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE
678 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP
679 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
680 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
681 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP
682 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP
683 { sizeof (EFI_IFR_EQ_ID_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
684 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP
685 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP
686 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP
687 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP
688 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
689 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP
690 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP
691 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP
692 { sizeof (EFI_IFR_REFRESH), 1 }, // EFI_IFR_REFRESH_OP
693 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
694 { 0, 0 }, // 0x1F
695 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
696 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
697 { 0, 0 }, // 0x22
698 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
699 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP
700 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
701 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP
702 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
703 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28
704 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP
705 { sizeof (EFI_IFR_MATCH), 1 }, // EFI_IFR_MATCH_OP - 0x2A
706 { 0, 0 }, { 0, 0} , { 0, 0} , { 0, 0} , // 0x2B ~ 0x2E
707 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
708 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP
709 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP
710 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP
711 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP
712 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
713 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP
714 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP
715 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP
716 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP
717 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
718 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A
719 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP
720 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP
721 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP
722 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E
723 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP
724 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP
725 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
726 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8
727 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16
728 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32
729 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64
730 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46
731 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP
732 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP
733 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP
734 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP
735 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP
736 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP
737 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP
738 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
739 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP
740 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP
741 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP
742 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP
743 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP
744 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP
745 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP
746 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP
747 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57
748 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP
749 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP
750 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP
751 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP
752 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
753 { 0, 0}, // 0x5D
754 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP
755 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP
756 };
757
758 #ifdef CIFROBJ_DEUBG
759 static struct {
760 INT8 *mIfrName;
761 } gIfrObjPrintDebugTable[] = {
762 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
763 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
764 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
765 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
766 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
767 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_INVALID", "EFI_IFR_ORDERED_LIST",
768 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
769 "EFI_IFR_MATCH", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_EQUAL",
770 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
771 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
772 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
773 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
774 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
775 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
776 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
777 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_INVALID", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
778 };
779
780 VOID
781 CIFROBJ_DEBUG_PRINT (
782 IN UINT8 OpCode
783 )
784 {
785 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);
786 }
787 #else
788
789 #define CIFROBJ_DEBUG_PRINT(OpCode)
790
791 #endif
792
793 bool gCreateOp = TRUE;
794
795 CIfrObj::CIfrObj (
796 IN UINT8 OpCode,
797 OUT CHAR8 **IfrObj,
798 IN UINT8 ObjBinLen,
799 IN BOOLEAN DelayEmit
800 )
801 {
802 mDelayEmit = DelayEmit;
803 mPkgOffset = gCFormPkg.GetPkgLength ();
804 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;
805 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];
806 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;
807
808 if (IfrObj != NULL) {
809 *IfrObj = mObjBinBuf;
810 }
811
812 CIFROBJ_DEBUG_PRINT (OpCode);
813 }
814
815 CIfrObj::~CIfrObj (
816 VOID
817 )
818 {
819 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {
820 _EMIT_PENDING_OBJ ();
821 }
822
823 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);
824 }
825
826 /*
827 * The definition of CIfrObj's member function
828 */
829 UINT8 gScopeCount = 0;
830
831 CIfrOpHeader::CIfrOpHeader (
832 IN UINT8 OpCode,
833 IN VOID *StartAddr,
834 IN UINT8 Length
835 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)
836 {
837 mHeader->OpCode = OpCode;
838 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;
839 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;
840 }
841
842 CIfrOpHeader::CIfrOpHeader (
843 IN CIfrOpHeader &OpHdr
844 )
845 {
846 mHeader = OpHdr.mHeader;
847 }
848
849 UINT32 CIfrForm::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };