]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
8c91b2fe16372b64e9a6612d6ae0cb793770809c
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / CollectPCDAction.java
1 /** @file
2 CollectPCDAction class.
3
4 This action class is to collect PCD information from MSA, SPD, FPD xml file.
5 This class will be used for wizard and build tools, So it can *not* inherit
6 from buildAction or wizardAction.
7
8 Copyright (c) 2006, Intel Corporation
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
13
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16
17 **/
18 package org.tianocore.build.pcd.action;
19
20 import java.io.BufferedReader;
21 import java.io.File;
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.math.BigInteger;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.Comparator;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.UUID;
34 import java.util.regex.Matcher;
35 import java.util.regex.Pattern;
36
37 import org.apache.xmlbeans.XmlException;
38 import org.apache.xmlbeans.XmlObject;
39 import org.tianocore.DynamicPcdBuildDefinitionsDocument;
40 import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;
41 import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions.PcdBuildData;
42 import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo;
43 import org.tianocore.FrameworkModulesDocument;
44 import org.tianocore.PcdDeclarationsDocument;
45 import org.tianocore.PlatformSurfaceAreaDocument;
46 import org.tianocore.PcdBuildDefinitionDocument;
47 import org.tianocore.PlatformSurfaceAreaDocument.PlatformSurfaceArea;
48 import org.tianocore.ModuleSADocument;
49 import org.tianocore.ModuleSADocument.ModuleSA;
50 import org.tianocore.PackageSurfaceAreaDocument;
51 import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;
52 import org.tianocore.build.autogen.CommonDefinition;
53 import org.tianocore.build.global.GlobalData;
54 import org.tianocore.build.global.SurfaceAreaQuery;
55 import org.tianocore.build.id.FpdModuleIdentification;
56 import org.tianocore.build.pcd.action.ActionMessage;
57 import org.tianocore.build.pcd.entity.DynamicTokenValue;
58 import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
59 import org.tianocore.build.pcd.entity.SkuInstance;
60 import org.tianocore.build.pcd.entity.Token;
61 import org.tianocore.build.pcd.entity.UsageInstance;
62 import org.tianocore.build.pcd.exception.EntityException;
63 import org.tianocore.logger.EdkLog;
64 import org.tianocore.ModuleTypeDef;
65
66 class CStructTypeDeclaration {
67 String key;
68 int alignmentSize;
69 String cCode;
70 boolean initTable;
71
72 public CStructTypeDeclaration (String key, int alignmentSize, String cCode, boolean initTable) {
73 this.key = key;
74 this.alignmentSize = alignmentSize;
75 this.cCode = cCode;
76 this.initTable = initTable;
77 }
78 }
79
80 class StringTable {
81 private ArrayList<String> al;
82 private ArrayList<String> alComments;
83 private String phase;
84 int len;
85
86 public StringTable (String phase) {
87 this.phase = phase;
88 al = new ArrayList<String>();
89 alComments = new ArrayList<String>();
90 len = 0;
91 }
92
93 public String getSizeMacro () {
94 return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());
95 }
96
97 private int getSize () {
98 //
99 // We have at least one Unicode Character in the table.
100 //
101 return len == 0 ? 1 : len;
102 }
103
104 public int getTableLen () {
105 return al.size() == 0 ? 1 : al.size();
106 }
107
108 public String getExistanceMacro () {
109 return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
110 }
111
112 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable) {
113 final String stringTable = "StringTable";
114 final String tab = "\t";
115 final String newLine = "\r\n";
116 final String commaNewLine = ",\r\n";
117
118 CStructTypeDeclaration decl;
119
120 String cDeclCode = "";
121 String cInstCode = "";
122
123 //
124 // If we have a empty StringTable
125 //
126 if (al.size() == 0) {
127 cDeclCode += String.format("%-20s%s[1]; /* StringTable is empty */", "UINT16", stringTable) + newLine;
128 decl = new CStructTypeDeclaration (
129 stringTable,
130 2,
131 cDeclCode,
132 true
133 );
134 declaList.add(decl);
135
136 cInstCode = String.format("/* %s */", stringTable) + newLine + tab + "{ 0 }";
137 instTable.put(stringTable, cInstCode);
138 } else {
139
140 //
141 // If there is any String in the StringTable
142 //
143 for (int i = 0; i < al.size(); i++) {
144 String str = al.get(i);
145 String stringTableName;
146
147 if (i == 0) {
148 //
149 // StringTable is a well-known name in the PCD DXE driver
150 //
151 stringTableName = stringTable;
152
153 } else {
154 stringTableName = String.format("%s_%d", stringTable, i);
155 cDeclCode += tab;
156 }
157 cDeclCode += String.format("%-20s%s[%d]; /* %s */", "UINT16", stringTableName, str.length() + 1, alComments.get(i)) + newLine;
158
159 if (i == 0) {
160 cInstCode = "/* StringTable */" + newLine;
161 }
162 cInstCode += tab + String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));
163 if (i != al.size() - 1) {
164 cInstCode += commaNewLine;
165 }
166 }
167
168 decl = new CStructTypeDeclaration (
169 stringTable,
170 2,
171 cDeclCode,
172 true
173 );
174 declaList.add(decl);
175
176 instTable.put(stringTable, cInstCode);
177 }
178 }
179
180 public String getTypeDeclaration () {
181
182 String output;
183
184 final String stringTable = "StringTable";
185 final String tab = "\t";
186 final String newLine = ";\r\n";
187
188 output = "/* StringTable */\r\n";
189
190 if (al.size() == 0) {
191 output += tab + String.format("UINT16 %s[1] /* StringTable is Empty */", stringTable) + newLine;
192 }
193
194 for (int i = 0; i < al.size(); i++) {
195 String str = al.get(i);
196
197 if (i == 0) {
198 //
199 // StringTable is a well-known name in the PCD DXE driver
200 //
201 output += tab + String.format("UINT16 %s[%d] /* %s */", stringTable, str.length() + 1, alComments.get(i)) + newLine;
202 } else {
203 output += tab + String.format("UINT16 %s_%d[%d] /* %s */", stringTable, i, str.length() + 1, alComments.get(i)) + newLine;
204 }
205 }
206
207 return output;
208
209 }
210
211 public ArrayList<String> getInstantiation () {
212 ArrayList<String> output = new ArrayList<String>();
213
214 output.add("/* StringTable */");
215
216 if (al.size() == 0) {
217 output.add("{ 0 }");
218 } else {
219 String str;
220
221 for (int i = 0; i < al.size(); i++) {
222 str = String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));
223 if (i != al.size() - 1) {
224 str += ",";
225 }
226 output.add(str);
227 }
228 }
229
230 return output;
231 }
232
233 public int add (String inputStr, Token token) {
234 int i;
235 int pos;
236
237 String str = inputStr;
238
239 //
240 // The input can be two types:
241 // "L\"Bootmode\"" or "Bootmode".
242 // We drop the L\" and \" for the first type.
243 if (str.startsWith("L\"") && str.endsWith("\"")) {
244 str = str.substring(2, str.length() - 1);
245 }
246 //
247 // Check if StringTable has this String already.
248 // If so, return the current pos.
249 //
250 for (i = 0, pos = 0; i < al.size(); i++) {
251 String s = al.get(i);;
252
253 if (str.equals(s)) {
254 return pos;
255 }
256 pos = s.length() + 1;
257
258 }
259
260 i = len;
261 //
262 // Include the NULL character at the end of String
263 //
264 len += str.length() + 1;
265 al.add(str);
266 alComments.add(token.getPrimaryKeyString());
267
268 return i;
269 }
270 }
271
272 class SizeTable {
273 private ArrayList<Integer> al;
274 private ArrayList<String> alComments;
275 private String phase;
276 private int len;
277
278 public SizeTable (String phase) {
279 this.phase = phase;
280 al = new ArrayList<Integer>();
281 alComments = new ArrayList<String>();
282 len = 0;
283 }
284
285 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
286 final String name = "SizeTable";
287
288 CStructTypeDeclaration decl;
289 String cCode;
290
291 cCode = String.format(PcdDatabase.SizeTableDeclaration, phase);
292 decl = new CStructTypeDeclaration (
293 name,
294 2,
295 cCode,
296 true
297 );
298 declaList.add(decl);
299
300
301 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
302 instTable.put(name, cCode);
303 }
304
305 public String getTypeDeclaration () {
306 return String.format(PcdDatabase.SizeTableDeclaration, phase);
307 }
308
309 public ArrayList<String> getInstantiation () {
310 ArrayList<String> Output = new ArrayList<String>();
311
312 Output.add("/* SizeTable */");
313 Output.add("{");
314 if (al.size() == 0) {
315 Output.add("\t0");
316 } else {
317 for (int index = 0; index < al.size(); index++) {
318 Integer n = al.get(index);
319 String str = "\t" + n.toString();
320
321 if (index != (al.size() - 1)) {
322 str += ",";
323 }
324
325 str += " /* " + alComments.get(index) + " */";
326 Output.add(str);
327
328 }
329 }
330 Output.add("}");
331
332 return Output;
333 }
334
335 public int add (Token token) {
336 int index = len;
337
338 len++;
339 al.add(token.datumSize);
340 alComments.add(token.getPrimaryKeyString());
341
342 return index;
343 }
344
345 public int getTableLen () {
346 return al.size() == 0 ? 1 : al.size();
347 }
348
349 }
350
351 class GuidTable {
352 private ArrayList<UUID> al;
353 private ArrayList<String> alComments;
354 private String phase;
355 private int len;
356 private int bodyLineNum;
357
358 public GuidTable (String phase) {
359 this.phase = phase;
360 al = new ArrayList<UUID>();
361 alComments = new ArrayList<String>();
362 len = 0;
363 bodyLineNum = 0;
364 }
365
366 public String getSizeMacro () {
367 return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());
368 }
369
370 private int getSize () {
371 return (al.size() == 0)? 1 : al.size();
372 }
373
374 public String getExistanceMacro () {
375 return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
376 }
377
378 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
379 final String name = "GuidTable";
380
381 CStructTypeDeclaration decl;
382 String cCode = "";
383
384 cCode += String.format(PcdDatabase.GuidTableDeclaration, phase);
385 decl = new CStructTypeDeclaration (
386 name,
387 8,
388 cCode,
389 true
390 );
391 declaList.add(decl);
392
393
394 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
395 instTable.put(name, cCode);
396 }
397
398 public String getTypeDeclaration () {
399 return String.format(PcdDatabase.GuidTableDeclaration, phase);
400 }
401
402 private String getUuidCString (UUID uuid) {
403 String[] guidStrArray;
404
405 guidStrArray =(uuid.toString()).split("-");
406
407 return String.format("{0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}",
408 guidStrArray[0],
409 guidStrArray[1],
410 guidStrArray[2],
411 (guidStrArray[3].substring(0, 2)),
412 (guidStrArray[3].substring(2, 4)),
413 (guidStrArray[4].substring(0, 2)),
414 (guidStrArray[4].substring(2, 4)),
415 (guidStrArray[4].substring(4, 6)),
416 (guidStrArray[4].substring(6, 8)),
417 (guidStrArray[4].substring(8, 10)),
418 (guidStrArray[4].substring(10, 12))
419 );
420 }
421
422 public ArrayList<String> getInstantiation () {
423 ArrayList<String> Output = new ArrayList<String>();
424
425 Output.add("/* GuidTable */");
426 Output.add("{");
427
428 if (al.size() == 0) {
429 Output.add("\t" + getUuidCString(new UUID(0, 0)));
430 }
431
432 for (int i = 0; i < al.size(); i++) {
433 String str = "\t" + getUuidCString(al.get(i));
434
435 str += "/* " + alComments.get(i) + " */";
436 if (i != (al.size() - 1)) {
437 str += ",";
438 }
439 Output.add(str);
440 bodyLineNum++;
441
442 }
443 Output.add("}");
444
445 return Output;
446 }
447
448 public int add (UUID uuid, String name) {
449 //
450 // Check if GuidTable has this entry already.
451 // If so, return the GuidTable index.
452 //
453 for (int i = 0; i < al.size(); i++) {
454 if (al.get(i).equals(uuid)) {
455 return i;
456 }
457 }
458
459 len++;
460 al.add(uuid);
461 alComments.add(name);
462
463 //
464 // Return the previous Table Index
465 //
466 return len - 1;
467 }
468
469 public int getTableLen () {
470 return al.size() == 0 ? 0 : al.size();
471 }
472
473 }
474
475 class SkuIdTable {
476 private ArrayList<Integer[]> al;
477 private ArrayList<String> alComment;
478 private String phase;
479 private int len;
480
481 public SkuIdTable (String phase) {
482 this.phase = phase;
483 al = new ArrayList<Integer[]>();
484 alComment = new ArrayList<String>();
485 len = 0;
486 }
487
488 public String getSizeMacro () {
489 return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());
490 }
491
492 private int getSize () {
493 return (len == 0)? 1 : len;
494 }
495
496 public String getExistanceMacro () {
497 return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
498 }
499
500 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
501 final String name = "SkuIdTable";
502
503 CStructTypeDeclaration decl;
504 String cCode = "";
505
506 cCode += String.format(PcdDatabase.SkuIdTableDeclaration, phase);
507 decl = new CStructTypeDeclaration (
508 name,
509 1,
510 cCode,
511 true
512 );
513 declaList.add(decl);
514
515
516 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
517 instTable.put(name, cCode);
518
519 //
520 // SystemSkuId is in PEI phase PCD Database
521 //
522 if (phase.equalsIgnoreCase("PEI")) {
523 decl = new CStructTypeDeclaration (
524 "SystemSkuId",
525 1,
526 String.format("%-20sSystemSkuId;\r\n", "SKU_ID"),
527 true
528 );
529 declaList.add(decl);
530
531 instTable.put("SystemSkuId", "0");
532 }
533
534 }
535
536 public String getTypeDeclaration () {
537 return String.format(PcdDatabase.SkuIdTableDeclaration, phase);
538 }
539
540 public ArrayList<String> getInstantiation () {
541 ArrayList<String> Output = new ArrayList<String> ();
542
543 Output.add("/* SkuIdTable */");
544 Output.add("{");
545
546 if (al.size() == 0) {
547 Output.add("\t0");
548 }
549
550 for (int index = 0; index < al.size(); index++) {
551 String str;
552
553 str = "/* " + alComment.get(index) + "*/ ";
554 str += "/* MaxSku */ ";
555
556
557 Integer[] ia = al.get(index);
558
559 str += "\t" + ia[0].toString() + ", ";
560 for (int index2 = 1; index2 < ia.length; index2++) {
561 str += ia[index2].toString();
562 if (!((index2 == ia.length - 1) && (index == al.size() - 1))) {
563 str += ", ";
564 }
565 }
566
567 Output.add(str);
568
569 }
570
571 Output.add("}");
572
573 return Output;
574 }
575
576 public int add (Token token) {
577
578 int index;
579 int pos;
580
581 //
582 // Check if this SKU_ID Array is already in the table
583 //
584 pos = 0;
585 for (Object o: al) {
586 Integer [] s = (Integer[]) o;
587 boolean different = false;
588 if (s[0] == token.getSkuIdCount()) {
589 for (index = 1; index < s.length; index++) {
590 if (s[index] != token.skuData.get(index-1).id) {
591 different = true;
592 break;
593 }
594 }
595 } else {
596 different = true;
597 }
598 if (different) {
599 pos += s[0] + 1;
600 } else {
601 return pos;
602 }
603 }
604
605 Integer [] skuIds = new Integer[token.skuData.size() + 1];
606 skuIds[0] = new Integer(token.skuData.size());
607 for (index = 1; index < skuIds.length; index++) {
608 skuIds[index] = new Integer(token.skuData.get(index - 1).id);
609 }
610
611 index = len;
612
613 len += skuIds.length;
614 al.add(skuIds);
615 alComment.add(token.getPrimaryKeyString());
616
617 return index;
618 }
619
620 public int getTableLen () {
621 return al.size() == 0 ? 1 : al.size();
622 }
623
624 }
625
626 class LocalTokenNumberTable {
627 private ArrayList<String> al;
628 private ArrayList<String> alComment;
629 private String phase;
630 private int len;
631
632 public LocalTokenNumberTable (String phase) {
633 this.phase = phase;
634 al = new ArrayList<String>();
635 alComment = new ArrayList<String>();
636
637 len = 0;
638 }
639
640 public String getSizeMacro () {
641 return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())
642 + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());
643 }
644
645 public int getSize () {
646 return (al.size() == 0)? 1 : al.size();
647 }
648
649 public String getExistanceMacro () {
650 return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
651 }
652
653 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
654 final String name = "LocalTokenNumberTable";
655
656 CStructTypeDeclaration decl;
657 String cCode = "";
658
659 cCode += String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);
660 decl = new CStructTypeDeclaration (
661 name,
662 4,
663 cCode,
664 true
665 );
666 declaList.add(decl);
667
668 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
669 instTable.put(name, cCode);
670 }
671
672 public String getTypeDeclaration () {
673 return String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);
674 }
675
676 public ArrayList<String> getInstantiation () {
677 ArrayList<String> output = new ArrayList<String>();
678
679 output.add("/* LocalTokenNumberTable */");
680 output.add("{");
681
682 if (al.size() == 0) {
683 output.add("\t0");
684 }
685
686 for (int index = 0; index < al.size(); index++) {
687 String str;
688
689 str = "\t" + (String)al.get(index);
690
691 str += " /* " + alComment.get(index) + " */ ";
692
693
694 if (index != (al.size() - 1)) {
695 str += ",";
696 }
697
698 output.add(str);
699
700 }
701
702 output.add("}");
703
704 return output;
705 }
706
707 public int add (Token token) {
708 int index = len;
709 String str;
710
711 len++;
712
713 str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());
714
715 if (token.isUnicodeStringType()) {
716 str += " | PCD_TYPE_STRING";
717 }
718
719 if (token.isSkuEnable()) {
720 str += " | PCD_TYPE_SKU_ENABLED";
721 }
722
723 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
724 str += " | PCD_TYPE_HII";
725 }
726
727 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
728 str += " | PCD_TYPE_VPD";
729 }
730
731 al.add(str);
732 alComment.add(token.getPrimaryKeyString());
733
734 return index;
735 }
736 }
737
738 class ExMapTable {
739
740 class ExTriplet {
741 public Integer guidTableIdx;
742 public Long exTokenNumber;
743 public Long localTokenIdx;
744
745 public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {
746 this.guidTableIdx = new Integer(guidTableIdx);
747 this.exTokenNumber = new Long(exTokenNumber);
748 this.localTokenIdx = new Long(localTokenIdx);
749 }
750 }
751
752 private ArrayList<ExTriplet> al;
753 private ArrayList<String> alComment;
754 private String phase;
755 private int len;
756 private int bodyLineNum;
757
758 public ExMapTable (String phase) {
759 this.phase = phase;
760 al = new ArrayList<ExTriplet>();
761 alComment = new ArrayList<String>();
762 bodyLineNum = 0;
763 len = 0;
764 }
765
766 public String getSizeMacro () {
767 return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())
768 + String.format(PcdDatabase.ExTokenNumber, phase, al.size());
769 }
770
771 public String getExistanceMacro () {
772 return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
773 }
774
775 public void genCodeNew (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {
776 final String exMapTableName = "ExMapTable";
777
778 sortTable();
779
780 CStructTypeDeclaration decl;
781 String cCode = "";
782
783 cCode += String.format(PcdDatabase.ExMapTableDeclaration, phase);
784 decl = new CStructTypeDeclaration (
785 exMapTableName,
786 4,
787 cCode,
788 true
789 );
790 declaList.add(decl);
791
792
793 cCode = PcdDatabase.genInstantiationStr(getInstantiation());
794 instTable.put(exMapTableName, cCode);
795 }
796
797 public String getTypeDeclaration () {
798 return String.format(PcdDatabase.ExMapTableDeclaration, phase);
799 }
800
801 public ArrayList<String> getInstantiation () {
802 ArrayList<String> Output = new ArrayList<String>();
803
804 Output.add("/* ExMapTable */");
805 Output.add("{");
806 if (al.size() == 0) {
807 Output.add("\t{0, 0, 0}");
808 }
809
810 int index;
811 for (index = 0; index < al.size(); index++) {
812 String str;
813
814 ExTriplet e = (ExTriplet)al.get(index);
815
816 str = "\t" + "{ " + String.format("0x%08X", e.exTokenNumber) + ", ";
817 str += e.localTokenIdx.toString() + ", ";
818 str += e.guidTableIdx.toString();
819
820 str += "}" + " /* " + alComment.get(index) + " */" ;
821
822 if (index != al.size() - 1) {
823 str += ",";
824 }
825
826 Output.add(str);
827 bodyLineNum++;
828
829 }
830
831 Output.add("}");
832
833 return Output;
834 }
835
836 public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {
837 int index = len;
838
839 len++;
840 al.add(new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx));
841 alComment.add(name);
842
843 return index;
844 }
845
846 public int getTableLen () {
847 return al.size() == 0 ? 1 : al.size();
848 }
849
850 //
851 // To simplify the algorithm for GetNextToken and GetNextTokenSpace in
852 // PCD PEIM/Driver, we need to sort the ExMapTable according to the
853 // following order:
854 // 1) ExGuid
855 // 2) ExTokenNumber
856 //
857 class ExTripletComp implements Comparator<ExTriplet> {
858 public int compare (ExTriplet a, ExTriplet b) {
859 if (a.guidTableIdx == b.guidTableIdx ) {
860 if (a.exTokenNumber > b.exTokenNumber) {
861 return 1;
862 } else if (a.exTokenNumber > b.exTokenNumber) {
863 return 1;
864 } else {
865 return 0;
866 }
867 }
868
869 return a.guidTableIdx - b.guidTableIdx;
870 }
871 }
872
873 private void sortTable () {
874 java.util.Comparator<ExTriplet> comparator = new ExTripletComp();
875 java.util.Collections.sort(al, comparator);
876 }
877 }
878
879 class PcdDatabase {
880
881 private final static int SkuHeadAlignmentSize = 4;
882 private final String newLine = "\r\n";
883 private final String commaNewLine = ",\r\n";
884 private final String tab = "\t";
885 public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";
886 public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";
887 public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
888 public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";
889 public final static String SizeTableDeclaration = "UINT16 SizeTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
890 public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";
891
892
893 public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";
894 public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";
895 public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n";
896 public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";
897 public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";
898 public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";
899 public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";
900
901
902 public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n";
903 public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";
904 public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";
905 public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";
906 public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";
907
908 public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";
909 public final static String offsetOfVariableEnabledDefault = "offsetof(%s_PCD_DATABASE, %s.%s_VariableDefault_%d)";
910 public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";
911
912 private final static String skuDataTableTemplate = "SkuDataTable";
913
914
915 private StringTable stringTable;
916 private GuidTable guidTable;
917 private LocalTokenNumberTable localTokenNumberTable;
918 private SkuIdTable skuIdTable;
919 private SizeTable sizeTable;
920 private ExMapTable exMapTable;
921
922 private ArrayList<Token> alTokens;
923 private String phase;
924 private int assignedTokenNumber;
925
926 //
927 // Use two class global variable to store
928 // temperary
929 //
930 private String privateGlobalName;
931 private String privateGlobalCCode;
932 //
933 // After Major changes done to the PCD
934 // database generation class PcdDatabase
935 // Please increment the version and please
936 // also update the version number in PCD
937 // service PEIM and DXE driver accordingly.
938 //
939 private final int version = 2;
940
941 private String hString;
942 private String cString;
943
944
945 class AlignmentSizeComp implements Comparator<Token> {
946 public int compare (Token a, Token b) {
947 return getAlignmentSize(b)
948 - getAlignmentSize(a);
949 }
950 }
951
952 public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {
953 phase = exePhase;
954
955 stringTable = new StringTable(phase);
956 guidTable = new GuidTable(phase);
957 localTokenNumberTable = new LocalTokenNumberTable(phase);
958 skuIdTable = new SkuIdTable(phase);
959 sizeTable = new SizeTable(phase);
960 exMapTable = new ExMapTable(phase);
961
962 assignedTokenNumber = startLen + 1;
963 this.alTokens = alTokens;
964 }
965
966 private void getNonExAndExTokens (ArrayList<Token> alTokens, List<Token> nexTokens, List<Token> exTokens) {
967 for (int i = 0; i < alTokens.size(); i++) {
968 Token t = (Token)alTokens.get(i);
969 if (t.isDynamicEx()) {
970 exTokens.add(t);
971 } else {
972 nexTokens.add(t);
973 }
974 }
975
976 return;
977 }
978
979 private void getTwoGroupsOfTokens (ArrayList<Token> alTokens, List<Token> initTokens, List<Token> uninitTokens) {
980 for (int i = 0; i < alTokens.size(); i++) {
981 Token t = (Token)alTokens.get(i);
982 if (t.hasDefaultValue()) {
983 initTokens.add(t);
984 } else {
985 uninitTokens.add(t);
986 }
987 }
988
989 return;
990 }
991
992 private int getDataTypeAlignmentSize (Token token) {
993 switch (token.datumType) {
994 case UINT8:
995 return 1;
996 case UINT16:
997 return 2;
998 case UINT32:
999 return 4;
1000 case UINT64:
1001 return 8;
1002 case POINTER:
1003 return 1;
1004 case BOOLEAN:
1005 return 1;
1006 default:
1007 return 1;
1008 }
1009 }
1010
1011 private int getAlignmentSize (Token token) {
1012 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
1013 return 2;
1014 }
1015
1016 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
1017 return 4;
1018 }
1019
1020 if (token.isUnicodeStringType()) {
1021 return 2;
1022 }
1023
1024 return getDataTypeAlignmentSize(token);
1025 }
1026
1027 public String getCString () {
1028 return cString;
1029 }
1030
1031 public String getHString () {
1032 return hString;
1033 }
1034
1035 private void genCodeWorker(Token t,
1036 ArrayList<CStructTypeDeclaration> declaList,
1037 HashMap<String, String> instTable, String phase)
1038 throws EntityException {
1039
1040 CStructTypeDeclaration decl;
1041
1042 //
1043 // Insert SKU_HEAD if isSkuEnable is true
1044 //
1045 if (t.isSkuEnable()) {
1046 int tableIdx;
1047 tableIdx = skuIdTable.add(t);
1048 decl = new CStructTypeDeclaration(t.getPrimaryKeyString(),
1049 SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true);
1050 declaList.add(decl);
1051 instTable.put(t.getPrimaryKeyString(),
1052 getSkuEnabledTypeInstantiaion(t, tableIdx));
1053 }
1054
1055 //
1056 // Insert PCD_ENTRY declaration and instantiation
1057 //
1058 getCDeclarationString(t);
1059
1060 decl = new CStructTypeDeclaration(privateGlobalName,
1061 getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue());
1062 declaList.add(decl);
1063
1064 if (t.hasDefaultValue()) {
1065 instTable.put(privateGlobalName,
1066 getTypeInstantiation(t, declaList, instTable, phase)
1067 );
1068 }
1069
1070 }
1071
1072 private void ProcessTokensNew (List<Token> tokens,
1073 ArrayList<CStructTypeDeclaration> cStructDeclList,
1074 HashMap<String, String> cStructInstTable,
1075 String phase
1076 )
1077 throws EntityException {
1078
1079 for (int idx = 0; idx < tokens.size(); idx++) {
1080 Token t = tokens.get(idx);
1081
1082 genCodeWorker (t, cStructDeclList, cStructInstTable, phase);
1083
1084 sizeTable.add(t);
1085 localTokenNumberTable.add(t);
1086 t.tokenNumber = assignedTokenNumber++;
1087
1088 //
1089 // Add a mapping if this dynamic PCD entry is a EX type
1090 //
1091 if (t.isDynamicEx()) {
1092 exMapTable.add((int)t.tokenNumber,
1093 t.dynamicExTokenNumber,
1094 guidTable.add(t.tokenSpaceName, t.getPrimaryKeyString()),
1095 t.getPrimaryKeyString()
1096 );
1097 }
1098 }
1099
1100 }
1101
1102 public void genCodeNew () throws EntityException {
1103
1104 ArrayList<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();
1105 HashMap<String, String> cStructInstTable = new HashMap<String, String>();
1106
1107 List<Token> nexTokens = new ArrayList<Token> ();
1108 List<Token> exTokens = new ArrayList<Token> ();
1109
1110 getNonExAndExTokens (alTokens, nexTokens, exTokens);
1111
1112 //
1113 // We have to process Non-Ex type PCD entry first. The reason is
1114 // that our optimization assumes that the Token Number of Non-Ex
1115 // PCD entry start from 1 (for PEI phase) and grows continously upwards.
1116 //
1117 // EX type token number starts from the last Non-EX PCD entry and
1118 // grows continously upwards.
1119 //
1120 ProcessTokensNew (nexTokens, cStructDeclList, cStructInstTable, phase);
1121 ProcessTokensNew (exTokens, cStructDeclList, cStructInstTable, phase);
1122
1123 stringTable.genCodeNew(cStructDeclList, cStructInstTable);
1124 skuIdTable.genCodeNew(cStructDeclList, cStructInstTable, phase);
1125 exMapTable.genCodeNew(cStructDeclList, cStructInstTable, phase);
1126 localTokenNumberTable.genCodeNew(cStructDeclList, cStructInstTable, phase);
1127 sizeTable.genCodeNew(cStructDeclList, cStructInstTable, phase);
1128 guidTable.genCodeNew(cStructDeclList, cStructInstTable, phase);
1129
1130 hString = genCMacroCode ();
1131
1132 HashMap <String, String> result;
1133
1134 result = genCStructCode(cStructDeclList,
1135 cStructInstTable,
1136 phase
1137 );
1138
1139 hString += result.get("initDeclStr");
1140 hString += result.get("uninitDeclStr");
1141
1142 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);
1143
1144 cString = newLine + newLine + result.get("initInstStr");
1145
1146 }
1147
1148 private String genCMacroCode () {
1149 String macroStr = "";
1150
1151 //
1152 // Generate size info Macro for all Tables
1153 //
1154 macroStr += guidTable.getSizeMacro();
1155 macroStr += stringTable.getSizeMacro();
1156 macroStr += skuIdTable.getSizeMacro();
1157 macroStr += localTokenNumberTable.getSizeMacro();
1158 macroStr += exMapTable.getSizeMacro();
1159
1160 //
1161 // Generate existance info Macro for all Tables
1162 //
1163 macroStr += guidTable.getExistanceMacro();
1164 macroStr += stringTable.getExistanceMacro();
1165 macroStr += skuIdTable.getExistanceMacro();
1166 macroStr += localTokenNumberTable.getExistanceMacro();
1167 macroStr += exMapTable.getExistanceMacro();
1168
1169 macroStr += newLine;
1170
1171 return macroStr;
1172 }
1173
1174 private HashMap <String, String> genCStructCode(
1175 ArrayList<CStructTypeDeclaration> declaList,
1176 HashMap<String, String> instTable,
1177 String phase
1178 ) {
1179
1180 int i;
1181 HashMap <String, String> result = new HashMap<String, String>();
1182 HashMap <Integer, ArrayList<String>> alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();
1183 HashMap <Integer, ArrayList<String>> alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();
1184 HashMap <Integer, ArrayList<String>> alignmentInitInst = new HashMap<Integer, ArrayList<String>>();
1185
1186 //
1187 // Initialize the storage for each alignment
1188 //
1189 for (i = 8; i > 0; i>>=1) {
1190 alignmentInitDecl.put(new Integer(i), new ArrayList<String>());
1191 alignmentInitInst.put(new Integer(i), new ArrayList<String>());
1192 alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());
1193 }
1194
1195 String initDeclStr = "typedef struct {" + newLine;
1196 String initInstStr = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine;
1197 String uninitDeclStr = "typedef struct {" + newLine;
1198
1199 //
1200 // Sort all C declaration and instantiation base on Alignment Size
1201 //
1202 for (Object d : declaList) {
1203 CStructTypeDeclaration decl = (CStructTypeDeclaration) d;
1204
1205 if (decl.initTable) {
1206 alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);
1207 alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key));
1208 } else {
1209 alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);
1210 }
1211 }
1212
1213 //
1214 // Generate code for every alignment size
1215 //
1216 boolean uinitDatabaseEmpty = true;
1217 for (int align = 8; align > 0; align >>= 1) {
1218 ArrayList<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));
1219 ArrayList<String> instListBasedOnAlignment = alignmentInitInst.get(new Integer(align));
1220 for (i = 0; i < declaListBasedOnAlignment.size(); i++) {
1221 initDeclStr += tab + declaListBasedOnAlignment.get(i);
1222 initInstStr += tab + instListBasedOnAlignment.get(i);
1223
1224 //
1225 // We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE
1226 // has a least one data memember with alignment size of 1. So we can
1227 // remove the last "," in the C structure instantiation string. Luckily,
1228 // this is true as both data structure has SKUID_TABLE anyway.
1229 //
1230 if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) {
1231 initInstStr += newLine;
1232 } else {
1233 initInstStr += commaNewLine;
1234 }
1235 }
1236
1237 declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align));
1238
1239 if (declaListBasedOnAlignment.size() != 0) {
1240 uinitDatabaseEmpty = false;
1241 }
1242
1243 for (Object d : declaListBasedOnAlignment) {
1244 String s = (String)d;
1245 uninitDeclStr += tab + s;
1246 }
1247 }
1248
1249 if (uinitDatabaseEmpty) {
1250 uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8");
1251 }
1252
1253 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine;
1254 initInstStr += "};" + newLine;
1255 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine;
1256
1257 result.put("initDeclStr", initDeclStr);
1258 result.put("initInstStr", initInstStr);
1259 result.put("uninitDeclStr", uninitDeclStr);
1260
1261 return result;
1262 }
1263
1264 public void genCode ()
1265 throws EntityException {
1266
1267 final String newLine = "\r\n";
1268 final String declNewLine = ";\r\n";
1269 final String tab = "\t";
1270 final String commaNewLine = ", \r\n";
1271
1272 int i;
1273 ArrayList<String> decla;
1274 ArrayList<String> inst;
1275
1276 String macroStr = "";
1277 String initDeclStr = "";
1278 String initInstStr = "";
1279 String uninitDeclStr = "";
1280
1281 List<Token> initTokens = new ArrayList<Token> ();
1282 List<Token> uninitTokens = new ArrayList<Token> ();
1283
1284 HashMap <String, ArrayList<String>> initCode = new HashMap<String, ArrayList<String>> ();
1285 HashMap <String, ArrayList<String>> uninitCode = new HashMap<String, ArrayList<String>> ();
1286
1287 getTwoGroupsOfTokens (alTokens, initTokens, uninitTokens);
1288
1289 //
1290 // Generate Structure Declaration for PcdTokens without Default Value
1291 // PEI_PCD_DATABASE_INIT
1292 //
1293 java.util.Comparator<Token> comparator = new AlignmentSizeComp();
1294 java.util.Collections.sort(initTokens, comparator);
1295 initCode = processTokens(initTokens);
1296
1297 //
1298 // Generate Structure Declaration for PcdTokens without Default Value
1299 // PEI_PCD_DATABASE_UNINIT
1300 //
1301 java.util.Collections.sort(uninitTokens, comparator);
1302 uninitCode = processTokens(uninitTokens);
1303
1304 //
1305 // Generate size info Macro for all Tables
1306 //
1307 macroStr += guidTable.getSizeMacro();
1308 macroStr += stringTable.getSizeMacro();
1309 macroStr += skuIdTable.getSizeMacro();
1310 macroStr += localTokenNumberTable.getSizeMacro();
1311 macroStr += exMapTable.getSizeMacro();
1312
1313 //
1314 // Generate existance info Macro for all Tables
1315 //
1316 macroStr += guidTable.getExistanceMacro();
1317 macroStr += stringTable.getExistanceMacro();
1318 macroStr += skuIdTable.getExistanceMacro();
1319 macroStr += localTokenNumberTable.getExistanceMacro();
1320 macroStr += exMapTable.getExistanceMacro();
1321
1322 //
1323 // Generate Structure Declaration for PcdTokens with Default Value
1324 // for example PEI_PCD_DATABASE_INIT
1325 //
1326 initDeclStr += "typedef struct {" + newLine;
1327 {
1328 initDeclStr += tab + exMapTable.getTypeDeclaration();
1329 initDeclStr += tab + guidTable.getTypeDeclaration();
1330 initDeclStr += tab + localTokenNumberTable.getTypeDeclaration();
1331 initDeclStr += tab + stringTable.getTypeDeclaration();
1332 initDeclStr += tab + sizeTable.getTypeDeclaration();
1333 initDeclStr += tab + skuIdTable.getTypeDeclaration();
1334 if (phase.equalsIgnoreCase("PEI")) {
1335 initDeclStr += tab + "SKU_ID SystemSkuId;" + newLine;
1336 }
1337
1338 decla = initCode.get(new String("Declaration"));
1339 for (i = 0; i < decla.size(); i++) {
1340 initDeclStr += tab + decla.get(i) + declNewLine;
1341 }
1342
1343 //
1344 // Generate Structure Declaration for PcdToken with SkuEnabled
1345 //
1346 decla = initCode.get("DeclarationForSku");
1347
1348 for (i = 0; i < decla.size(); i++) {
1349 initDeclStr += tab + decla.get(i) + declNewLine;
1350 }
1351 }
1352 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;\r\n\r\n", phase);
1353
1354 //
1355 // Generate MACRO for structure intialization of PCDTokens with Default Value
1356 // The sequence must match the sequence of declaration of the memembers in the structure
1357 String tmp = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase());
1358 initInstStr += tmp + newLine;
1359 initInstStr += tab + genInstantiationStr(exMapTable.getInstantiation()) + commaNewLine;
1360 initInstStr += tab + genInstantiationStr(guidTable.getInstantiation()) + commaNewLine;
1361 initInstStr += tab + genInstantiationStr(localTokenNumberTable.getInstantiation()) + commaNewLine;
1362 initInstStr += tab + genInstantiationStr(stringTable.getInstantiation()) + commaNewLine;
1363 initInstStr += tab + genInstantiationStr(sizeTable.getInstantiation()) + commaNewLine;
1364 initInstStr += tab + genInstantiationStr(skuIdTable.getInstantiation()) + commaNewLine;
1365 //
1366 // For SystemSkuId
1367 //
1368 if (phase.equalsIgnoreCase("PEI")) {
1369 initInstStr += tab + "0" + tab + "/* SystemSkuId */" + commaNewLine;
1370 }
1371
1372 inst = initCode.get("Instantiation");
1373 for (i = 0; i < inst.size(); i++) {
1374 initInstStr += tab + inst.get(i) + commaNewLine;
1375 }
1376
1377 inst = initCode.get("InstantiationForSku");
1378 for (i = 0; i < inst.size(); i++) {
1379 initInstStr += tab + inst.get(i);
1380 if (i != inst.size() - 1) {
1381 initInstStr += commaNewLine;
1382 }
1383 }
1384
1385 initInstStr += "};";
1386
1387 uninitDeclStr += "typedef struct {" + newLine;
1388 {
1389 decla = uninitCode.get("Declaration");
1390 if (decla.size() == 0) {
1391 uninitDeclStr += "UINT8 dummy /* The UINT struct is empty */" + declNewLine;
1392 } else {
1393
1394 for (i = 0; i < decla.size(); i++) {
1395 uninitDeclStr += tab + decla.get(i) + declNewLine;
1396 }
1397
1398 decla = uninitCode.get("DeclarationForSku");
1399
1400 for (i = 0; i < decla.size(); i++) {
1401 uninitDeclStr += tab + decla.get(i) + declNewLine;
1402 }
1403 }
1404 }
1405 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;\r\n\r\n", phase);
1406
1407 cString = initInstStr + newLine;
1408 hString = macroStr + newLine
1409 + initDeclStr + newLine
1410 + uninitDeclStr + newLine
1411 + newLine;
1412
1413 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);
1414
1415 }
1416
1417 public static String genInstantiationStr (ArrayList<String> alStr) {
1418 String str = "";
1419 for (int i = 0; i< alStr.size(); i++) {
1420 if (i != 0) {
1421 str += "\t";
1422 }
1423 str += alStr.get(i);
1424 if (i != alStr.size() - 1) {
1425 str += "\r\n";
1426 }
1427 }
1428
1429 return str;
1430 }
1431
1432 private HashMap<String, ArrayList<String>> processTokens (List<Token> alToken)
1433 throws EntityException {
1434
1435 HashMap <String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
1436
1437 ArrayList<String> decl = new ArrayList<String>();
1438 ArrayList<String> declForSkuEnableType = new ArrayList<String>();
1439 ArrayList<String> inst = new ArrayList<String>();
1440 ArrayList<String> instForSkuEnableType = new ArrayList<String>();
1441
1442 for (int index = 0; index < alToken.size(); index++) {
1443 Token token = alToken.get(index);
1444
1445 if (token.isSkuEnable()) {
1446 //
1447 // BugBug: Schema only support Data type now
1448 //
1449 int tableIdx;
1450
1451 tableIdx = skuIdTable.add(token);
1452
1453 decl.add(getSkuEnabledTypeDeclaration(token));
1454 if (token.hasDefaultValue()) {
1455 inst.add(getSkuEnabledTypeInstantiaion(token, tableIdx));
1456 }
1457
1458 declForSkuEnableType.add(getDataTypeDeclarationForSkuEnabled(token));
1459 if (token.hasDefaultValue()) {
1460 instForSkuEnableType.add(getDataTypeInstantiationForSkuEnabled(token));
1461 }
1462
1463 } else {
1464 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
1465 decl.add(getVariableEnableTypeDeclaration(token));
1466 inst.add(getVariableEnableInstantiation(token));
1467 } else if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
1468 decl.add(getVpdEnableTypeDeclaration(token));
1469 inst.add(getVpdEnableTypeInstantiation(token));
1470 } else if (token.isUnicodeStringType()) {
1471 decl.add(getStringTypeDeclaration(token));
1472 inst.add(getStringTypeInstantiation(stringTable.add(token.getStringTypeString(), token), token));
1473 }
1474 else {
1475 decl.add(getDataTypeDeclaration(token));
1476 if (token.hasDefaultValue()) {
1477 inst.add(getDataTypeInstantiation(token));
1478 }
1479 }
1480 }
1481
1482 sizeTable.add(token);
1483 localTokenNumberTable.add(token);
1484 token.tokenNumber = assignedTokenNumber++;
1485
1486 }
1487
1488 map.put("Declaration", decl);
1489 map.put("DeclarationForSku", declForSkuEnableType);
1490 map.put("Instantiation", inst);
1491 map.put("InstantiationForSku", instForSkuEnableType);
1492
1493 return map;
1494 }
1495
1496 private String getSkuEnabledTypeDeclaration (Token token) {
1497 return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString());
1498 }
1499
1500 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {
1501
1502 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());
1503 return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString());
1504 }
1505
1506 private String getDataTypeDeclarationForSkuEnabled (Token token) {
1507 String typeStr = "";
1508
1509 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1510 typeStr = "UINT8 %s_%s[%d];\r\n";
1511 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1512 typeStr = "UINT16 %s_%s[%d];\r\n";
1513 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1514 typeStr = "UINT32 %s_%s[%d];\r\n";
1515 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1516 typeStr = "UINT64 %s_%s[%d];\r\n";
1517 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1518 typeStr = "BOOLEAN %s_%s[%d];\r\n";
1519 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1520 return String.format("UINT8 %s_%s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size());
1521 }
1522
1523 return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.skuData.size());
1524
1525 }
1526
1527 private String getDataTypeInstantiationForSkuEnabled (Token token) {
1528 String str = "";
1529
1530 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1531 return String.format("UINT8 %s_%s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size());
1532 } else {
1533 str = "{ ";
1534 for (int idx = 0; idx < token.skuData.size(); idx++) {
1535 str += token.skuData.get(idx).toString();
1536 if (idx != token.skuData.size() - 1) {
1537 str += ", ";
1538 }
1539 }
1540 str += "}";
1541
1542 return str;
1543 }
1544
1545 }
1546
1547 private String getDataTypeInstantiationForVariableDefault_new (Token token, String cName, int skuId) {
1548 return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName);
1549 }
1550
1551 private String getDataTypeInstantiation (Token token) {
1552
1553 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1554 return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString());
1555 } else {
1556 return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString());
1557 }
1558 }
1559
1560 private String getCType (Token t)
1561 throws EntityException {
1562
1563 if (t.isHiiEnable()) {
1564 return "VARIABLE_HEAD";
1565 }
1566
1567 if (t.isVpdEnable()) {
1568 return "VPD_HEAD";
1569 }
1570
1571 if (t.isUnicodeStringType()) {
1572 return "STRING_HEAD";
1573 }
1574
1575 switch (t.datumType) {
1576 case UINT64:
1577 return "UINT64";
1578 case UINT32:
1579 return "UINT32";
1580 case UINT16:
1581 return "UINT16";
1582 case UINT8:
1583 return "UINT8";
1584 case BOOLEAN:
1585 return "BOOLEAN";
1586 case POINTER:
1587 return "UINT8";
1588 default:
1589 throw new EntityException("Unknown type in getDataTypeCDeclaration");
1590 }
1591 }
1592
1593 private void getCDeclarationString(Token t)
1594 throws EntityException {
1595
1596 if (t.isSkuEnable()) {
1597 privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate);
1598 } else {
1599 privateGlobalName = t.getPrimaryKeyString();
1600 }
1601
1602 if (t.isUnicodeStringType()) {
1603 privateGlobalCCode = String.format("%-20s%s[%d];\r\n", "STRING_HEAD", t.getPrimaryKeyString(), t.getSkuIdCount());
1604 } else {
1605 String type = getCType(t);
1606 if (t.datumType == Token.DATUM_TYPE.POINTER) {
1607 int bufferSize;
1608 if (t.isASCIIStringType()) {
1609 //
1610 // Build tool will add a NULL string at the end of the ASCII string
1611 //
1612 bufferSize = t.datumSize + 1;
1613 } else {
1614 bufferSize = t.datumSize;
1615 }
1616 privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize);
1617 } else {
1618 privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount());
1619 }
1620 }
1621 }
1622
1623 private String getDataTypeDeclarationForVariableDefault_new (Token token, String cName, int skuId) {
1624
1625 String typeStr;
1626
1627 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1628 typeStr = "UINT8";
1629 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1630 typeStr = "UINT16";
1631 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1632 typeStr = "UINT32";
1633 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1634 typeStr = "UINT64";
1635 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1636 typeStr = "BOOLEAN";
1637 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1638 return String.format("%-20s%s[%d];\r\n", cName, token.datumSize);
1639 } else {
1640 typeStr = "";
1641 }
1642
1643 return String.format("%-20s%s;\r\n", typeStr, cName);
1644 }
1645
1646 private String getDataTypeDeclaration (Token token) {
1647
1648 String typeStr = "";
1649
1650 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1651 typeStr = "UINT8";
1652 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1653 typeStr = "UINT16";
1654 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1655 typeStr = "UINT32";
1656 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1657 typeStr = "UINT64";
1658 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1659 typeStr = "BOOLEAN";
1660 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1661 return String.format("UINT8 %s[%d]", token.getPrimaryKeyString(), token.datumSize);
1662 } else {
1663 }
1664
1665 return String.format("%s %s", typeStr, token.getPrimaryKeyString());
1666 }
1667
1668 private String getVpdEnableTypeDeclaration (Token token) {
1669 return String.format("VPD_HEAD %s", token.getPrimaryKeyString());
1670 }
1671
1672 private String getTypeInstantiation (Token t, ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) throws EntityException {
1673
1674 int i;
1675
1676 String s;
1677 s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine;
1678 s += tab + "{" + newLine;
1679
1680 for (i = 0; i < t.skuData.size(); i++) {
1681 if (t.isUnicodeStringType() && !t.isHiiEnable()) {
1682 s += tab + tab + String.format("{ %d }", stringTable.add(t.skuData.get(i).value.value, t));
1683 } else if (t.isHiiEnable()) {
1684 /* VPD_HEAD definition
1685 typedef struct {
1686 UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.
1687 UINT16 StringIndex; // Offset in String Table in units of UINT16.
1688 UINT16 Offset; // Offset in Variable
1689 } VARIABLE_HEAD ;
1690 */
1691 String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i);
1692
1693 s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()),
1694 stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t),
1695 t.skuData.get(i).value.variableOffset,
1696 String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName)
1697 );
1698 //
1699 // We need to support the default value, so we add the declaration and
1700 // the instantiation for the default value.
1701 //
1702 CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName,
1703 getDataTypeAlignmentSize(t),
1704 getDataTypeDeclarationForVariableDefault_new(t, variableDefaultName, i),
1705 true
1706 );
1707 declaList.add(decl);
1708 instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault_new (t, variableDefaultName, i));
1709 } else if (t.isVpdEnable()) {
1710 /* typedef struct {
1711 UINT32 Offset;
1712 } VPD_HEAD;
1713 */
1714 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset);
1715 } else {
1716 if (t.isByteStreamType()) {
1717 //
1718 // Byte stream type input has their own "{" "}", so we won't help to insert.
1719 //
1720 s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value);
1721 } else {
1722 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value);
1723 }
1724 }
1725
1726 if (i != t.skuData.size() - 1) {
1727 s += commaNewLine;
1728 } else {
1729 s += newLine;
1730 }
1731
1732 }
1733
1734 s += tab + "}";
1735
1736 return s;
1737 }
1738
1739 private String getVpdEnableTypeInstantiation (Token token) {
1740 return String.format("{ %s } /* %s */", token.getDefaultSku().vpdOffset,
1741 token.getPrimaryKeyString());
1742 }
1743
1744 private String getStringTypeDeclaration (Token token) {
1745 return String.format("UINT16 %s", token.getPrimaryKeyString());
1746 }
1747
1748 private String getStringTypeInstantiation (int StringTableIdx, Token token) {
1749 return String.format ("%d /* %s */", StringTableIdx,
1750 token.getPrimaryKeyString());
1751 }
1752
1753
1754 private String getVariableEnableTypeDeclaration (Token token) {
1755 return String.format("VARIABLE_HEAD %s", token.getPrimaryKeyString());
1756 }
1757
1758 private String getVariableEnableInstantiation (Token token)
1759 throws EntityException {
1760 //
1761 // Need scott fix
1762 //
1763 return String.format("{ %d, %d, %s } /* %s */", guidTable.add(token.getDefaultSku().variableGuid, token.getPrimaryKeyString()),
1764 stringTable.add(token.getDefaultSku().getStringOfVariableName(), token),
1765 token.getDefaultSku().variableOffset,
1766 token.getPrimaryKeyString());
1767 }
1768
1769 public int getTotalTokenNumber () {
1770 return sizeTable.getTableLen();
1771 }
1772
1773 public static String getPcdDatabaseCommonDefinitions ()
1774 throws EntityException {
1775
1776 String retStr = "";
1777 try {
1778 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1779 "Tools" + File.separator +
1780 "Conf" + File.separator +
1781 "Pcd" + File.separator +
1782 "PcdDatabaseCommonDefinitions.sample");
1783 FileReader reader = new FileReader(file);
1784 BufferedReader in = new BufferedReader(reader);
1785 String str;
1786 while ((str = in.readLine()) != null) {
1787 retStr = retStr +"\r\n" + str;
1788 }
1789 } catch (Exception ex) {
1790 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");
1791 }
1792
1793 return retStr;
1794 }
1795
1796 public static String getPcdDxeDatabaseDefinitions ()
1797 throws EntityException {
1798
1799 String retStr = "";
1800 try {
1801 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1802 "Tools" + File.separator +
1803 "Conf" + File.separator +
1804 "Pcd" + File.separator +
1805 "PcdDatabaseDxeDefinitions.sample");
1806 FileReader reader = new FileReader(file);
1807 BufferedReader in = new BufferedReader(reader);
1808 String str;
1809 while ((str = in.readLine()) != null) {
1810 retStr = retStr +"\r\n" + str;
1811 }
1812 } catch (Exception ex) {
1813 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");
1814 }
1815
1816 return retStr;
1817 }
1818
1819 public static String getPcdPeiDatabaseDefinitions ()
1820 throws EntityException {
1821
1822 String retStr = "";
1823 try {
1824 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1825 "Tools" + File.separator +
1826 "Conf" + File.separator +
1827 "Pcd" + File.separator +
1828 "PcdDatabasePeiDefinitions.sample");
1829 FileReader reader = new FileReader(file);
1830 BufferedReader in = new BufferedReader(reader);
1831 String str;
1832 while ((str = in.readLine()) != null) {
1833 retStr = retStr +"\r\n" + str;
1834 }
1835 } catch (Exception ex) {
1836 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");
1837 }
1838
1839 return retStr;
1840 }
1841
1842 }
1843
1844 class ModuleInfo {
1845 private String type;
1846 private FpdModuleIdentification moduleId;
1847 private PcdBuildDefinitionDocument.PcdBuildDefinition pcdBuildDef;
1848
1849
1850
1851 public ModuleInfo (FpdModuleIdentification moduleId, String type, XmlObject pcdDef) {
1852 this.moduleId = moduleId;
1853 this.type = type;
1854 this.pcdBuildDef = ((PcdBuildDefinitionDocument)pcdDef).getPcdBuildDefinition();
1855 }
1856 public String getModuleType (){
1857 return this.type;
1858 }
1859 public FpdModuleIdentification getModuleId (){
1860 return this.moduleId;
1861 }
1862 public PcdBuildDefinitionDocument.PcdBuildDefinition getPcdBuildDef(){
1863 return this.pcdBuildDef;
1864 }
1865 }
1866
1867 /** This action class is to collect PCD information from MSA, SPD, FPD xml file.
1868 This class will be used for wizard and build tools, So it can *not* inherit
1869 from buildAction or UIAction.
1870 **/
1871 public class CollectPCDAction {
1872 /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.
1873 private MemoryDatabaseManager dbManager;
1874
1875 /// Workspacepath hold the workspace information.
1876 private String workspacePath;
1877
1878 /// FPD file is the root file.
1879 private String fpdFilePath;
1880
1881 /// Message level for CollectPCDAction.
1882 private int originalMessageLevel;
1883
1884 /// Cache the fpd docment instance for private usage.
1885 private PlatformSurfaceAreaDocument fpdDocInstance;
1886
1887 /// xmlObject name
1888 private static String xmlObjectName = "PcdBuildDefinition";
1889
1890 /**
1891 Set WorkspacePath parameter for this action class.
1892
1893 @param workspacePath parameter for this action
1894 **/
1895 public void setWorkspacePath(String workspacePath) {
1896 this.workspacePath = workspacePath;
1897 }
1898
1899 /**
1900 Set action message level for CollectPcdAction tool.
1901
1902 The message should be restored when this action exit.
1903
1904 @param actionMessageLevel parameter for this action
1905 **/
1906 public void setActionMessageLevel(int actionMessageLevel) {
1907 originalMessageLevel = ActionMessage.messageLevel;
1908 ActionMessage.messageLevel = actionMessageLevel;
1909 }
1910
1911 /**
1912 Set FPDFileName parameter for this action class.
1913
1914 @param fpdFilePath fpd file path
1915 **/
1916 public void setFPDFilePath(String fpdFilePath) {
1917 this.fpdFilePath = fpdFilePath;
1918 }
1919
1920 /**
1921 Common function interface for outer.
1922
1923 @param workspacePath The path of workspace of current build or analysis.
1924 @param fpdFilePath The fpd file path of current build or analysis.
1925 @param messageLevel The message level for this Action.
1926
1927 @throws Exception The exception of this function. Because it can *not* be predict
1928 where the action class will be used. So only Exception can be throw.
1929
1930 **/
1931 public void perform(String workspacePath, String fpdFilePath,
1932 int messageLevel) throws Exception {
1933 setWorkspacePath(workspacePath);
1934 setFPDFilePath(fpdFilePath);
1935 setActionMessageLevel(messageLevel);
1936 checkParameter();
1937 execute();
1938 ActionMessage.messageLevel = originalMessageLevel;
1939 }
1940
1941 /**
1942 Core execution function for this action class.
1943
1944 This function work flows will be:
1945 1) Collect and prepocess PCD information from FPD file, all PCD
1946 information will be stored into memory database.
1947 2) Generate 3 strings for
1948 a) All modules using Dynamic(Ex) PCD entry.(Token Number)
1949 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.
1950 c) DXE PCD Database (C structure) for PCD Service DXE.
1951
1952
1953 @throws EntityException Exception indicate failed to execute this action.
1954
1955 **/
1956 public void execute() throws EntityException {
1957 //
1958 // Get memoryDatabaseManager instance from GlobalData.
1959 // The memoryDatabaseManager should be initialized for whatever build
1960 // tools or wizard tools
1961 //
1962 if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {
1963 throw new EntityException("The instance of PCD memory database manager is null");
1964 }
1965
1966 //
1967 // Collect all PCD information defined in FPD file.
1968 // Evenry token defind in FPD will be created as an token into
1969 // memory database.
1970 //
1971 createTokenInDBFromFPD();
1972
1973 //
1974 // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver
1975 // 1) Generate for PEI, DXE PCD DATABASE's definition and initialization.
1976 //
1977 genPcdDatabaseSourceCode ();
1978
1979 }
1980
1981 /**
1982 This function generates source code for PCD Database.
1983
1984 @param void
1985 @throws EntityException If the token does *not* exist in memory database.
1986
1987 **/
1988 private void genPcdDatabaseSourceCode()
1989 throws EntityException {
1990 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions ();
1991
1992 ArrayList<Token> alPei = new ArrayList<Token> ();
1993 ArrayList<Token> alDxe = new ArrayList<Token> ();
1994
1995 dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);
1996 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);
1997 pcdPeiDatabase.genCodeNew();
1998 MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString()
1999 + PcdDatabase.getPcdPeiDatabaseDefinitions();
2000 MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();
2001
2002 PcdDatabase pcdDxeDatabase = new PcdDatabase (alDxe,
2003 "DXE",
2004 alPei.size()
2005 );
2006 pcdDxeDatabase.genCodeNew();
2007 MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString()
2008 + PcdDatabase.getPcdDxeDatabaseDefinitions();
2009 MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();
2010 }
2011
2012 /**
2013 Get component array from FPD.
2014
2015 This function maybe provided by some Global class.
2016
2017 @return List<ModuleInfo> the component array.
2018
2019 */
2020 private List<ModuleInfo> getComponentsFromFPD()
2021 throws EntityException {
2022 List<ModuleInfo> allModules = new ArrayList<ModuleInfo>();
2023 ModuleInfo current = null;
2024 int index = 0;
2025 FrameworkModulesDocument.FrameworkModules fModules = null;
2026 ModuleSADocument.ModuleSA[] modules = null;
2027 HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();
2028
2029 if (fpdDocInstance == null) {
2030 try {
2031 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));
2032 } catch(IOException ioE) {
2033 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
2034 } catch(XmlException xmlE) {
2035 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
2036 }
2037
2038 }
2039
2040 //map.put("FrameworkPlatformDescription", fpdDocInstance);
2041 //SurfaceAreaQuery.setDoc(map);
2042 Map<FpdModuleIdentification,XmlObject>pcdBuildDef = GlobalData.getFpdModuleSaXmlObject(CollectPCDAction.xmlObjectName);
2043 Set<FpdModuleIdentification> pcdBuildKeySet = pcdBuildDef.keySet();
2044 Iterator item = pcdBuildKeySet.iterator();
2045 while (item.hasNext()){
2046 FpdModuleIdentification id = (FpdModuleIdentification)item.next();
2047 try {
2048 allModules.add(new ModuleInfo(id, id.getModule().getModuleType(),pcdBuildDef.get(id)));
2049 } catch (Exception e){
2050 System.out.println(e.getMessage());
2051 //EdkLog.log(EdkLog.EDK_INFO,e.getMessage());
2052 }
2053
2054
2055 }
2056 // //modules = SurfaceAreaQuery.getFpdModuleSAs();
2057 // for (index = 0; index < modules.length; index ++) {
2058 // //SurfaceAreaQuery.setDoc(GlobalData.getDoc(modules[index].getModuleName()));
2059 // allModules.add(new ModuleInfo(modules[index],
2060 // ModuleTypeDef.Enum.forString(SurfaceAreaQuery.getModuleType())));
2061 // }
2062
2063 return allModules;
2064 }
2065
2066 /**
2067 Create token instance object into memory database, the token information
2068 comes for FPD file. Normally, FPD file will contain all token platform
2069 informations.
2070
2071 @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.
2072
2073 @throws EntityException Failed to parse FPD xml file.
2074
2075 **/
2076 private void createTokenInDBFromFPD()
2077 throws EntityException {
2078 int index = 0;
2079 int index2 = 0;
2080 int pcdIndex = 0;
2081 List<PcdBuildDefinition.PcdData> pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();
2082 PcdBuildDefinition.PcdData pcdBuildData = null;
2083 Token token = null;
2084 SkuInstance skuInstance = null;
2085 int skuIndex = 0;
2086 List<ModuleInfo> modules = null;
2087 String primaryKey = null;
2088 String exceptionString = null;
2089 UsageInstance usageInstance = null;
2090 String primaryKey1 = null;
2091 String primaryKey2 = null;
2092 boolean isDuplicate = false;
2093 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
2094 Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;
2095 long tokenNumber = 0;
2096 String moduleName = null;
2097 String datum = null;
2098 int maxDatumSize = 0;
2099 String tokenSpaceGuidString = null;
2100
2101 //
2102 // ----------------------------------------------
2103 // 1), Get all <ModuleSA> from FPD file.
2104 // ----------------------------------------------
2105 //
2106 modules = getComponentsFromFPD();
2107
2108 if (modules == null) {
2109 throw new EntityException("[FPD file error] No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");
2110 }
2111
2112 //
2113 // -------------------------------------------------------------------
2114 // 2), Loop all modules to process <PcdBuildDeclarations> for each module.
2115 // -------------------------------------------------------------------
2116 //
2117 for (index = 0; index < modules.size(); index ++) {
2118 isDuplicate = false;
2119 for (index2 = 0; index2 < index; index2 ++) {
2120 //
2121 // BUGBUG: For transition schema, we can *not* get module's version from
2122 // <ModuleSAs>, It is work around code.
2123 //
2124 primaryKey1 = UsageInstance.getPrimaryKey(modules.get(index).getModuleId().getModule().getName(),
2125 null,
2126 null,
2127 null,
2128 modules.get(index).getModuleId().getArch(),
2129 null);
2130 primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).getModuleId().getModule().getName(),
2131 null,
2132 null,
2133 null,
2134 modules.get(index2).getModuleId().getArch(),
2135 null);
2136 if (primaryKey1.equalsIgnoreCase(primaryKey2)) {
2137 isDuplicate = true;
2138 break;
2139 }
2140 }
2141
2142 if (isDuplicate) {
2143 continue;
2144 }
2145
2146 //
2147 // It is legal for a module does not contains ANY pcd build definitions.
2148 //
2149 if (modules.get(index).getPcdBuildDef() == null) {
2150 continue;
2151 }
2152
2153 pcdBuildDataArray = modules.get(index).getPcdBuildDef().getPcdDataList();
2154
2155 moduleName = modules.get(index).getModuleId().getModule().getName();
2156
2157 //
2158 // ----------------------------------------------------------------------
2159 // 2.1), Loop all Pcd entry for a module and add it into memory database.
2160 // ----------------------------------------------------------------------
2161 //
2162 for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) {
2163 //tokenSpaceGuidString = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName())[1];
2164 tokenSpaceGuidString = null;
2165 pcdBuildData = pcdBuildDataArray.get(pcdIndex);
2166 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),
2167 translateSchemaStringToUUID(tokenSpaceGuidString));
2168 pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());
2169 datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());
2170 tokenNumber = Long.decode(pcdBuildData.getToken().toString());
2171 if (pcdBuildData.getValue() != null) {
2172 datum = pcdBuildData.getValue().toString();
2173 } else {
2174 datum = null;
2175 }
2176 maxDatumSize = pcdBuildData.getMaxDatumSize();
2177
2178 if ((pcdType == Token.PCD_TYPE.FEATURE_FLAG) &&
2179 (datumType != Token.DATUM_TYPE.BOOLEAN)){
2180 exceptionString = String.format("[FPD file error] For PCD %s in module %s, the PCD type is FEATRUE_FLAG but "+
2181 "datum type of this PCD entry is not BOOLEAN!",
2182 pcdBuildData.getCName(),
2183 moduleName);
2184 throw new EntityException(exceptionString);
2185 }
2186
2187 //
2188 // -------------------------------------------------------------------------------------------
2189 // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule
2190 // -------------------------------------------------------------------------------------------
2191 //
2192 if (!Token.isDynamic(pcdType)) {
2193 //
2194 // Value is required.
2195 //
2196 if (datum == null) {
2197 exceptionString = String.format("[FPD file error] There is no value for PCD entry %s in module %s!",
2198 pcdBuildData.getCName(),
2199 moduleName);
2200 throw new EntityException(exceptionString);
2201 }
2202
2203 //
2204 // Check whether the datum size is matched datum type.
2205 //
2206 if ((exceptionString = verifyDatum(pcdBuildData.getCName(),
2207 moduleName,
2208 datum,
2209 datumType,
2210 maxDatumSize)) != null) {
2211 throw new EntityException(exceptionString);
2212 }
2213 }
2214
2215 //
2216 // ---------------------------------------------------------------------------------
2217 // 2.1.2), Create token or update token information for current anaylized PCD data.
2218 // ---------------------------------------------------------------------------------
2219 //
2220 if (dbManager.isTokenInDatabase(primaryKey)) {
2221 //
2222 // If the token is already exist in database, do some necessary checking
2223 // and add a usage instance into this token in database
2224 //
2225 token = dbManager.getTokenByKey(primaryKey);
2226
2227 //
2228 // checking for DatumType, DatumType should be unique for one PCD used in different
2229 // modules.
2230 //
2231 if (token.datumType != datumType) {
2232 exceptionString = String.format("[FPD file error] The datum type of PCD entry %s is %s, which is different with %s defined in before!",
2233 pcdBuildData.getCName(),
2234 pcdBuildData.getDatumType().toString(),
2235 Token.getStringOfdatumType(token.datumType));
2236 throw new EntityException(exceptionString);
2237 }
2238
2239 //
2240 // Check token number is valid
2241 //
2242 if (tokenNumber != token.tokenNumber) {
2243 exceptionString = String.format("[FPD file error] The token number of PCD entry %s in module %s is different with same PCD entry in other modules!",
2244 pcdBuildData.getCName(),
2245 moduleName);
2246 throw new EntityException(exceptionString);
2247 }
2248
2249 //
2250 // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.
2251 //
2252 if (token.isDynamicPCD != Token.isDynamic(pcdType)) {
2253 exceptionString = String.format("[FPD file error] For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+
2254 "is different with others module's",
2255 token.cName,
2256 moduleName);
2257 throw new EntityException(exceptionString);
2258 }
2259
2260 if (token.isDynamicPCD) {
2261 //
2262 // Check datum is equal the datum in dynamic information.
2263 // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,
2264 // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.
2265 //
2266 if (!token.isSkuEnable() &&
2267 (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) &&
2268 (datum != null)) {
2269 if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) {
2270 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the datum in <ModuleSA> is "+
2271 "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+
2272 "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",
2273 token.cName,
2274 moduleName);
2275 throw new EntityException(exceptionString);
2276 }
2277 }
2278
2279 if ((maxDatumSize != 0) &&
2280 (maxDatumSize != token.datumSize)){
2281 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the max datum size is %d which "+
2282 "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",
2283 token.cName,
2284 moduleName,
2285 maxDatumSize,
2286 token.datumSize);
2287 throw new EntityException(exceptionString);
2288 }
2289 }
2290
2291 } else {
2292 //
2293 // If the token is not in database, create a new token instance and add
2294 // a usage instance into this token in database.
2295 //
2296 //String tokenSpaceString = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName())[1];
2297 String tokenSpaceString = null;
2298 token = new Token(pcdBuildData.getCName(),
2299 translateSchemaStringToUUID(tokenSpaceString));
2300
2301 token.datumType = datumType;
2302 token.tokenNumber = tokenNumber;
2303 token.isDynamicPCD = Token.isDynamic(pcdType);
2304 token.datumSize = maxDatumSize;
2305
2306 if (token.isDynamicPCD) {
2307 //
2308 // For Dynamic and Dynamic Ex type, need find the dynamic information
2309 // in <DynamicPcdBuildDefinition> section in FPD file.
2310 //
2311 updateDynamicInformation(moduleName,
2312 token,
2313 datum,
2314 maxDatumSize);
2315 }
2316
2317 dbManager.addTokenToDatabase(primaryKey, token);
2318 }
2319
2320 //
2321 // -----------------------------------------------------------------------------------
2322 // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.
2323 // -----------------------------------------------------------------------------------
2324 //
2325 token.updateSupportPcdType(pcdType);
2326
2327 //
2328 // ------------------------------------------------
2329 // 2.1.4), Create an usage instance for this token.
2330 // ------------------------------------------------
2331 //
2332 usageInstance = new UsageInstance(token,
2333 moduleName,
2334 null,
2335 null,
2336 null,
2337 CommonDefinition.getModuleType(modules.get(index).getModuleType()),
2338 pcdType,
2339 modules.get(index).getModuleId().getArch(),
2340 null,
2341 datum,
2342 maxDatumSize);
2343 token.addUsageInstance(usageInstance);
2344 }
2345 }
2346 }
2347
2348 /**
2349 Verify the datum value according its datum size and datum type, this
2350 function maybe moved to FPD verification tools in future.
2351
2352 @param cName
2353 @param moduleName
2354 @param datum
2355 @param datumType
2356 @param maxDatumSize
2357
2358 @return String
2359 */
2360 /***/
2361 public String verifyDatum(String cName,
2362 String moduleName,
2363 String datum,
2364 Token.DATUM_TYPE datumType,
2365 int maxDatumSize) {
2366 String exceptionString = null;
2367 int value;
2368 BigInteger value64;
2369 String subStr;
2370 int index;
2371
2372 if (moduleName == null) {
2373 moduleName = "section <DynamicPcdBuildDefinitions>";
2374 } else {
2375 moduleName = "module " + moduleName;
2376 }
2377
2378 if (maxDatumSize == 0) {
2379 exceptionString = String.format("[FPD file error] You maybe miss <MaxDatumSize> for PCD %s in %s",
2380 cName,
2381 moduleName);
2382 return exceptionString;
2383 }
2384
2385 switch (datumType) {
2386 case UINT8:
2387 if (maxDatumSize != 1) {
2388 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2389 "is UINT8, but datum size is %d, they are not matched!",
2390 cName,
2391 moduleName,
2392 maxDatumSize);
2393 return exceptionString;
2394 }
2395
2396 if (datum != null) {
2397 try {
2398 value = Integer.decode(datum);
2399 } catch (NumberFormatException nfeExp) {
2400 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid "+
2401 "digital format of UINT8",
2402 cName,
2403 moduleName);
2404 return exceptionString;
2405 }
2406 if (value > 0xFF) {
2407 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s exceed"+
2408 " the max size of UINT8 - 0xFF",
2409 cName,
2410 moduleName,
2411 datum);
2412 return exceptionString;
2413 }
2414 }
2415 break;
2416 case UINT16:
2417 if (maxDatumSize != 2) {
2418 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2419 "is UINT16, but datum size is %d, they are not matched!",
2420 cName,
2421 moduleName,
2422 maxDatumSize);
2423 return exceptionString;
2424 }
2425 if (datum != null) {
2426 try {
2427 value = Integer.decode(datum);
2428 } catch (NumberFormatException nfeExp) {
2429 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is "+
2430 "not valid digital of UINT16",
2431 cName,
2432 moduleName);
2433 return exceptionString;
2434 }
2435 if (value > 0xFFFF) {
2436 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+
2437 "which exceed the range of UINT16 - 0xFFFF",
2438 cName,
2439 moduleName,
2440 datum);
2441 return exceptionString;
2442 }
2443 }
2444 break;
2445 case UINT32:
2446 if (maxDatumSize != 4) {
2447 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2448 "is UINT32, but datum size is %d, they are not matched!",
2449 cName,
2450 moduleName,
2451 maxDatumSize);
2452 return exceptionString;
2453 }
2454
2455 if (datum != null) {
2456 try {
2457 if (datum.length() > 2) {
2458 if ((datum.charAt(0) == '0') &&
2459 ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){
2460 subStr = datum.substring(2, datum.length());
2461 value64 = new BigInteger(subStr, 16);
2462 } else {
2463 value64 = new BigInteger(datum);
2464 }
2465 } else {
2466 value64 = new BigInteger(datum);
2467 }
2468 } catch (NumberFormatException nfeExp) {
2469 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not "+
2470 "valid digital of UINT32",
2471 cName,
2472 moduleName);
2473 return exceptionString;
2474 }
2475
2476 if (value64.bitLength() > 32) {
2477 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s which "+
2478 "exceed the range of UINT32 - 0xFFFFFFFF",
2479 cName,
2480 moduleName,
2481 datum);
2482 return exceptionString;
2483 }
2484 }
2485 break;
2486 case UINT64:
2487 if (maxDatumSize != 8) {
2488 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2489 "is UINT64, but datum size is %d, they are not matched!",
2490 cName,
2491 moduleName,
2492 maxDatumSize);
2493 return exceptionString;
2494 }
2495
2496 if (datum != null) {
2497 try {
2498 if (datum.length() > 2) {
2499 if ((datum.charAt(0) == '0') &&
2500 ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){
2501 subStr = datum.substring(2, datum.length());
2502 value64 = new BigInteger(subStr, 16);
2503 } else {
2504 value64 = new BigInteger(datum);
2505 }
2506 } else {
2507 value64 = new BigInteger(datum);
2508 }
2509 } catch (NumberFormatException nfeExp) {
2510 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid"+
2511 " digital of UINT64",
2512 cName,
2513 moduleName);
2514 return exceptionString;
2515 }
2516
2517 if (value64.bitLength() > 64) {
2518 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+
2519 "exceed the range of UINT64 - 0xFFFFFFFFFFFFFFFF",
2520 cName,
2521 moduleName,
2522 datum);
2523 return exceptionString;
2524 }
2525 }
2526 break;
2527 case BOOLEAN:
2528 if (maxDatumSize != 1) {
2529 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2530 "is BOOLEAN, but datum size is %d, they are not matched!",
2531 cName,
2532 moduleName,
2533 maxDatumSize);
2534 return exceptionString;
2535 }
2536
2537 if (datum != null) {
2538 if (!(datum.equalsIgnoreCase("TRUE") ||
2539 datum.equalsIgnoreCase("FALSE"))) {
2540 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
2541 "is BOOELAN, but value is not 'true'/'TRUE' or 'FALSE'/'false'",
2542 cName,
2543 moduleName);
2544 return exceptionString;
2545 }
2546
2547 }
2548 break;
2549 case POINTER:
2550 if (datum == null) {
2551 break;
2552 }
2553
2554 char ch = datum.charAt(0);
2555 int start, end;
2556 String strValue;
2557 //
2558 // For void* type PCD, only three datum is support:
2559 // 1) Unicode: string with start char is "L"
2560 // 2) Ansci: String start char is ""
2561 // 3) byte array: String start char "{"
2562 //
2563 if (ch == 'L') {
2564 start = datum.indexOf('\"');
2565 end = datum.lastIndexOf('\"');
2566 if ((start > end) ||
2567 (end > datum.length())||
2568 ((start == end) && (datum.length() > 0))) {
2569 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+
2570 "a UNICODE string because start with L\", but format maybe"+
2571 "is not right, correct UNICODE string is L\"...\"!",
2572 cName,
2573 moduleName);
2574 return exceptionString;
2575 }
2576
2577 strValue = datum.substring(start + 1, end);
2578 if ((strValue.length() * 2) > maxDatumSize) {
2579 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+
2580 "a UNICODE string, but the datum size is %d exceed to <MaxDatumSize> : %d",
2581 cName,
2582 moduleName,
2583 strValue.length() * 2,
2584 maxDatumSize);
2585 return exceptionString;
2586 }
2587 } else if (ch == '\"'){
2588 start = datum.indexOf('\"');
2589 end = datum.lastIndexOf('\"');
2590 if ((start > end) ||
2591 (end > datum.length())||
2592 ((start == end) && (datum.length() > 0))) {
2593 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+
2594 "a ANSCII string because start with \", but format maybe"+
2595 "is not right, correct ANSIC string is \"...\"!",
2596 cName,
2597 moduleName);
2598 return exceptionString;
2599 }
2600 strValue = datum.substring(start + 1, end);
2601 if ((strValue.length()) > maxDatumSize) {
2602 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+
2603 "a ANSCI string, but the datum size is %d which exceed to <MaxDatumSize> : %d",
2604 cName,
2605 moduleName,
2606 strValue.length(),
2607 maxDatumSize);
2608 return exceptionString;
2609 }
2610 } else if (ch =='{') {
2611 String[] strValueArray;
2612
2613 start = datum.indexOf('{');
2614 end = datum.lastIndexOf('}');
2615 strValue = datum.substring(start + 1, end);
2616 strValue = strValue.trim();
2617 if (strValue.length() == 0) {
2618 break;
2619 }
2620 strValueArray = strValue.split(",");
2621 for (index = 0; index < strValueArray.length; index ++) {
2622 try{
2623 value = Integer.decode(strValueArray[index].trim());
2624 } catch (NumberFormatException nfeEx) {
2625 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+
2626 "it is byte array in fact. For every byte in array should be a valid"+
2627 "byte digital, but element %s is not a valid byte digital!",
2628 cName,
2629 moduleName,
2630 strValueArray[index]);
2631 return exceptionString;
2632 }
2633 if (value > 0xFF) {
2634 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, "+
2635 "it is byte array in fact. But the element of %s exceed the byte range",
2636 cName,
2637 moduleName,
2638 strValueArray[index]);
2639 return exceptionString;
2640 }
2641 }
2642
2643 if (strValueArray.length > maxDatumSize) {
2644 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is byte"+
2645 "array, but the number of bytes is %d which exceed to <MaxDatumSzie> : %d!",
2646 cName,
2647 moduleName,
2648 strValueArray.length,
2649 maxDatumSize);
2650 return exceptionString;
2651 }
2652 } else {
2653 exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*. For VOID* type, you have three format choise:\n "+
2654 "1) UNICODE string: like L\"xxxx\";\r\n"+
2655 "2) ANSIC string: like \"xxx\";\r\n"+
2656 "3) Byte array: like {0x2, 0x45, 0x23}\r\n"+
2657 "But the datum in seems does not following above format!",
2658 cName,
2659 moduleName);
2660 return exceptionString;
2661 }
2662 break;
2663 default:
2664 exceptionString = String.format("[FPD file error] For PCD entry %s in %s, datum type is unknown, it should be one of "+
2665 "UINT8, UINT16, UINT32, UINT64, VOID*, BOOLEAN",
2666 cName,
2667 moduleName);
2668 return exceptionString;
2669 }
2670 return null;
2671 }
2672
2673 /**
2674 Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.
2675
2676 This function should be implemented in GlobalData in future.
2677
2678 @param token The token instance which has hold module's PCD information
2679 @param moduleName The name of module who will use this Dynamic PCD.
2680
2681 @return DynamicPcdBuildDefinitions.PcdBuildData
2682 */
2683 /***/
2684 private DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFPD(Token token,
2685 String moduleName)
2686 throws EntityException {
2687 int index = 0;
2688 String exceptionString = null;
2689 String dynamicPrimaryKey = null;
2690 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;
2691 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;
2692
2693 //
2694 // If FPD document is not be opened, open and initialize it.
2695 //
2696 if (fpdDocInstance == null) {
2697 try {
2698 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));
2699 } catch(IOException ioE) {
2700 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
2701 } catch(XmlException xmlE) {
2702 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
2703 }
2704 }
2705
2706 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();
2707 if (dynamicPcdBuildDefinitions == null) {
2708 exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+
2709 "PCD entry %s in module %s!",
2710 token.cName,
2711 moduleName);
2712 throw new EntityException(exceptionString);
2713 }
2714
2715 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();
2716 for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {
2717 //String tokenSpaceGuidString = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName())[1];
2718 String tokenSpaceGuidString = null;
2719 dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),
2720 translateSchemaStringToUUID(tokenSpaceGuidString));
2721 if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {
2722 return dynamicPcdBuildDataArray.get(index);
2723 }
2724 }
2725
2726 return null;
2727 }
2728
2729 /**
2730 Update dynamic information for PCD entry.
2731
2732 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in
2733 FPD file.
2734
2735 @param moduleName The name of the module who use this PCD
2736 @param token The token instance
2737 @param datum The <datum> in module's PCD information
2738 @param maxDatumSize The <maxDatumSize> in module's PCD information
2739
2740 @return Token
2741 */
2742 private Token updateDynamicInformation(String moduleName,
2743 Token token,
2744 String datum,
2745 int maxDatumSize)
2746 throws EntityException {
2747 int index = 0;
2748 int offset;
2749 String exceptionString = null;
2750 DynamicTokenValue dynamicValue;
2751 SkuInstance skuInstance = null;
2752 String temp;
2753 boolean hasSkuId0 = false;
2754 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
2755 long tokenNumber = 0;
2756 String hiiDefaultValue = null;
2757 String[] variableGuidString = null;
2758
2759 List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;
2760 DynamicPcdBuildDefinitions.PcdBuildData dynamicInfo = null;
2761
2762 dynamicInfo = getDynamicInfoFromFPD(token, moduleName);
2763 if (dynamicInfo == null) {
2764 exceptionString = String.format("[FPD file error] For Dynamic PCD %s used by module %s, "+
2765 "there is no dynamic information in <DynamicPcdBuildDefinitions> "+
2766 "in FPD file, but it is required!",
2767 token.cName,
2768 moduleName);
2769 throw new EntityException(exceptionString);
2770 }
2771
2772 token.datumSize = dynamicInfo.getMaxDatumSize();
2773
2774 exceptionString = verifyDatum(token.cName,
2775 moduleName,
2776 null,
2777 token.datumType,
2778 token.datumSize);
2779 if (exceptionString != null) {
2780 throw new EntityException(exceptionString);
2781 }
2782
2783 if ((maxDatumSize != 0) &&
2784 (maxDatumSize != token.datumSize)) {
2785 exceptionString = String.format("FPD file error] For dynamic PCD %s, the datum size in module %s is %d, but "+
2786 "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",
2787 token.cName,
2788 moduleName,
2789 maxDatumSize,
2790 dynamicInfo.getMaxDatumSize());
2791 throw new EntityException(exceptionString);
2792 }
2793 tokenNumber = Long.decode(dynamicInfo.getToken().toString());
2794 if (tokenNumber != token.tokenNumber) {
2795 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the token number in module %s is 0x%x, but"+
2796 "in <DynamicPcdBuildDefinictions>, the token number is 0x%x, they are not match!",
2797 token.cName,
2798 moduleName,
2799 token.tokenNumber,
2800 tokenNumber);
2801 throw new EntityException(exceptionString);
2802 }
2803
2804 pcdType = Token.getpcdTypeFromString(dynamicInfo.getItemType().toString());
2805 if (pcdType == Token.PCD_TYPE.DYNAMIC_EX) {
2806 token.dynamicExTokenNumber = tokenNumber;
2807 }
2808
2809 skuInfoList = dynamicInfo.getSkuInfoList();
2810
2811 //
2812 // Loop all sku data
2813 //
2814 for (index = 0; index < skuInfoList.size(); index ++) {
2815 skuInstance = new SkuInstance();
2816 //
2817 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.
2818 //
2819 temp = skuInfoList.get(index).getSkuId().toString();
2820 skuInstance.id = Integer.decode(temp);
2821 if (skuInstance.id == 0) {
2822 hasSkuId0 = true;
2823 }
2824 //
2825 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.
2826 //
2827 if (skuInfoList.get(index).getValue() != null) {
2828 skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());
2829 if ((exceptionString = verifyDatum(token.cName,
2830 null,
2831 skuInfoList.get(index).getValue().toString(),
2832 token.datumType,
2833 token.datumSize)) != null) {
2834 throw new EntityException(exceptionString);
2835 }
2836
2837 token.skuData.add(skuInstance);
2838
2839 //
2840 // Judege wether is same of datum between module's information
2841 // and dynamic information.
2842 //
2843 if (datum != null) {
2844 if ((skuInstance.id == 0) &&
2845 !datum.toString().equalsIgnoreCase(skuInfoList.get(index).getValue().toString())) {
2846 exceptionString = "[FPD file error] For dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+
2847 "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance.value.value + ". They are must be same!"+
2848 " or you could not define value for a dynamic PCD in every <ModuleSA>!";
2849 throw new EntityException(exceptionString);
2850 }
2851 }
2852 continue;
2853 }
2854
2855 //
2856 // Judge whether is HII group case.
2857 //
2858 if (skuInfoList.get(index).getVariableName() != null) {
2859 exceptionString = null;
2860 if (skuInfoList.get(index).getVariableGuid() == null) {
2861 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
2862 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",
2863 token.cName,
2864 index);
2865 if (exceptionString != null) {
2866 throw new EntityException(exceptionString);
2867 }
2868 }
2869
2870 if (skuInfoList.get(index).getVariableOffset() == null) {
2871 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
2872 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",
2873 token.cName,
2874 index);
2875 if (exceptionString != null) {
2876 throw new EntityException(exceptionString);
2877 }
2878 }
2879
2880 if (skuInfoList.get(index).getHiiDefaultValue() == null) {
2881 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
2882 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",
2883 token.cName,
2884 index);
2885 if (exceptionString != null) {
2886 throw new EntityException(exceptionString);
2887 }
2888 }
2889
2890 if (skuInfoList.get(index).getHiiDefaultValue() != null) {
2891 hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();
2892 } else {
2893 hiiDefaultValue = null;
2894 }
2895
2896 if ((exceptionString = verifyDatum(token.cName,
2897 null,
2898 hiiDefaultValue,
2899 token.datumType,
2900 token.datumSize)) != null) {
2901 throw new EntityException(exceptionString);
2902 }
2903
2904 offset = Integer.decode(skuInfoList.get(index).getVariableOffset());
2905 if (offset > 0xFFFF) {
2906 throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+
2907 "exceed 64K, it is not allowed!",
2908 token.cName,
2909 index));
2910 }
2911
2912 //
2913 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.
2914 //
2915 variableGuidString = GlobalData.getGuidInfoFromCname(skuInfoList.get(index).getVariableGuid().toString());
2916 if (variableGuidString == null) {
2917 throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",
2918 token.cName,
2919 skuInfoList.get(index).getVariableGuid().toString()));
2920 }
2921 String variableStr = skuInfoList.get(index).getVariableName();
2922 Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");
2923 Matcher matcher = pattern.matcher(variableStr);
2924 List<String> varNameList = new ArrayList<String>();
2925 while (matcher.find()){
2926 String str = variableStr.substring(matcher.start(),matcher.end());
2927 varNameList.add(str);
2928 }
2929
2930 skuInstance.value.setHiiData(varNameList,
2931 translateSchemaStringToUUID(variableGuidString[1]),
2932 skuInfoList.get(index).getVariableOffset(),
2933 skuInfoList.get(index).getHiiDefaultValue().toString());
2934 token.skuData.add(skuInstance);
2935 continue;
2936 }
2937
2938 if (skuInfoList.get(index).getVpdOffset() != null) {
2939 skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());
2940 token.skuData.add(skuInstance);
2941 continue;
2942 }
2943
2944 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+
2945 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",
2946 token.cName);
2947 throw new EntityException(exceptionString);
2948 }
2949
2950 if (!hasSkuId0) {
2951 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+
2952 "no sku id = 0 data, which is required for every dynamic PCD",
2953 token.cName);
2954 throw new EntityException(exceptionString);
2955 }
2956
2957 return token;
2958 }
2959
2960 /**
2961 Translate the schema string to UUID instance.
2962
2963 In schema, the string of UUID is defined as following two types string:
2964 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
2965 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
2966
2967 2) GuidNamingConvention: pattern =
2968 [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}
2969
2970 This function will convert string and create uuid instance.
2971
2972 @param uuidString UUID string in XML file
2973
2974 @return UUID UUID instance
2975 **/
2976 private UUID translateSchemaStringToUUID(String uuidString)
2977 throws EntityException {
2978 String temp;
2979 String[] splitStringArray;
2980 int index;
2981 int chIndex;
2982 int chLen;
2983
2984 if (uuidString == null) {
2985 return null;
2986 }
2987
2988 if (uuidString.length() == 0) {
2989 return null;
2990 }
2991
2992 if (uuidString.equals("0") ||
2993 uuidString.equalsIgnoreCase("0x0")) {
2994 return new UUID(0, 0);
2995 }
2996
2997 uuidString = uuidString.replaceAll("\\{", "");
2998 uuidString = uuidString.replaceAll("\\}", "");
2999
3000 //
3001 // If the UUID schema string is GuidArrayType type then need translate
3002 // to GuidNamingConvention type at first.
3003 //
3004 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {
3005 splitStringArray = uuidString.split("," );
3006 if (splitStringArray.length != 11) {
3007 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);
3008 }
3009
3010 //
3011 // Remove blank space from these string and remove header string "0x"
3012 //
3013 for (index = 0; index < 11; index ++) {
3014 splitStringArray[index] = splitStringArray[index].trim();
3015 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());
3016 }
3017
3018 //
3019 // Add heading '0' to normalize the string length
3020 //
3021 for (index = 3; index < 11; index ++) {
3022 chLen = splitStringArray[index].length();
3023 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {
3024 splitStringArray[index] = "0" + splitStringArray[index];
3025 }
3026 }
3027
3028 //
3029 // construct the final GuidNamingConvention string
3030 //
3031 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
3032 splitStringArray[0],
3033 splitStringArray[1],
3034 splitStringArray[2],
3035 splitStringArray[3],
3036 splitStringArray[4],
3037 splitStringArray[5],
3038 splitStringArray[6],
3039 splitStringArray[7],
3040 splitStringArray[8],
3041 splitStringArray[9],
3042 splitStringArray[10]);
3043 uuidString = temp;
3044 }
3045
3046 return UUID.fromString(uuidString);
3047 }
3048
3049 /**
3050 check parameter for this action.
3051
3052 @throws EntityException Bad parameter.
3053 **/
3054 private void checkParameter() throws EntityException {
3055 File file = null;
3056
3057 if((fpdFilePath == null) ||(workspacePath == null)) {
3058 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
3059 }
3060
3061 if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {
3062 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
3063 }
3064
3065 file = new File(workspacePath);
3066 if(!file.exists()) {
3067 throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");
3068 }
3069
3070 file = new File(fpdFilePath);
3071
3072 if(!file.exists()) {
3073 throw new EntityException("FPD File " + fpdFilePath + " does not exist!");
3074 }
3075 }
3076
3077 /**
3078 Test case function
3079
3080 @param argv parameter from command line
3081 **/
3082 public static void main(String argv[]) throws EntityException {
3083 CollectPCDAction ca = new CollectPCDAction();
3084 ca.setWorkspacePath("m:/tianocore/edk2");
3085 ca.setFPDFilePath("m:/tianocore/edk2/EdkNt32Pkg/Nt32.fpd");
3086 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);
3087 // GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
3088 // "m:/tianocore/edk2");
3089 // ca.execute();
3090 }
3091 }