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