PCD tools update:
[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.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Comparator;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.UUID;
31
32 import org.apache.xmlbeans.XmlException;
33 import org.apache.xmlbeans.XmlObject;
34 import org.tianocore.FrameworkModulesDocument;
35 import org.tianocore.FrameworkPlatformDescriptionDocument;
36 import org.tianocore.FrameworkPlatformDescriptionDocument.FrameworkPlatformDescription;
37 import org.tianocore.ModuleSADocument;
38 import org.tianocore.ModuleSADocument.ModuleSA;
39 import org.tianocore.PackageSurfaceAreaDocument;
40 import org.tianocore.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData;
41 import org.tianocore.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData.SkuData;
42 import org.tianocore.PcdDefinitionsDocument.PcdDefinitions;
43 import org.tianocore.PcdDynamicBuildDeclarationsDocument.PcdDynamicBuildDeclarations;
44 import org.tianocore.build.autogen.CommonDefinition;
45 import org.tianocore.build.global.GlobalData;
46 import org.tianocore.build.global.SurfaceAreaQuery;
47 import org.tianocore.build.pcd.action.ActionMessage;
48 import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
49 import org.tianocore.build.pcd.entity.SkuInstance;
50 import org.tianocore.build.pcd.entity.Token;
51 import org.tianocore.build.pcd.entity.UsageInstance;
52 import org.tianocore.build.pcd.exception.EntityException;
53
54 class StringTable {
55 private ArrayList<String> al;
56 private ArrayList<String> alComments;
57 private String phase;
58 int len;
59 int bodyStart;
60 int bodyLineNum;
61
62 public StringTable (String phase) {
63 this.phase = phase;
64 al = new ArrayList<String>();
65 alComments = new ArrayList<String>();
66 len = 0;
67 bodyStart = 0;
68 bodyLineNum = 0;
69 }
70
71 public String getSizeMacro () {
72 return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());
73 }
74
75 private int getSize () {
76 //
77 // We have at least one Unicode Character in the table.
78 //
79 return len == 0 ? 1 : len;
80 }
81
82 public int getTableLen () {
83 return al.size() == 0 ? 1 : al.size();
84 }
85
86 public String getExistanceMacro () {
87 return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
88 }
89
90 public String getTypeDeclaration () {
91
92 String output;
93
94 final String stringTable = "StringTable";
95 final String tab = "\t";
96 final String newLine = ";\r\n";
97
98 output = "/* StringTable */\r\n";
99
100 if (al.size() == 0) {
101 output += tab + String.format("UINT16 %s[1] /* StringTable is Empty */", stringTable) + newLine;
102 }
103
104 for (int i = 0; i < al.size(); i++) {
105 String str = al.get(i);
106
107 if (i == 0) {
108 //
109 // StringTable is a well-known name in the PCD DXE driver
110 //
111 output += tab + String.format("UINT16 %s[%d] /* %s */", stringTable, str.length() + 1, alComments.get(i)) + newLine;
112 } else {
113 output += tab + String.format("UINT16 %s_%d[%d] /* %s */", stringTable, i, str.length() + 1, alComments.get(i)) + newLine;
114 }
115 }
116
117 return output;
118
119 }
120
121 public ArrayList<String> getInstantiation () {
122 ArrayList<String> output = new ArrayList<String>();
123
124 output.add("/* StringTable */");
125
126 if (al.size() == 0) {
127 output.add("{ 0 }");
128 } else {
129 String str;
130
131 for (int i = 0; i < al.size(); i++) {
132 str = String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));
133 if (i != al.size() - 1) {
134 str += ",";
135 }
136 output.add(str);
137 }
138 }
139
140 return output;
141 }
142
143 public int add (String str, Token token) {
144 int i;
145
146 i = len;
147 //
148 // Include the NULL character at the end of String
149 //
150 len += str.length() + 1;
151 al.add(str);
152 alComments.add(token.getPrimaryKeyString());
153
154 return i;
155 }
156 }
157
158 class SizeTable {
159 private ArrayList<Integer> al;
160 private ArrayList<String> alComments;
161 private String phase;
162 private int len;
163 private int bodyStart;
164 private int bodyLineNum;
165
166 public SizeTable (String phase) {
167 this.phase = phase;
168 al = new ArrayList<Integer>();
169 alComments = new ArrayList<String>();
170 len = 0;
171 bodyStart = 0;
172 bodyLineNum = 0;
173 }
174
175 public String getTypeDeclaration () {
176 return String.format(PcdDatabase.SizeTableDeclaration, phase);
177 }
178
179 public ArrayList<String> getInstantiation () {
180 ArrayList<String> Output = new ArrayList<String>();
181
182 Output.add("/* SizeTable */");
183 Output.add("{");
184 bodyStart = 2;
185
186 if (al.size() == 0) {
187 Output.add("0");
188 } else {
189 for (int index = 0; index < al.size(); index++) {
190 Integer n = al.get(index);
191 String str = n.toString();
192
193 if (index != (al.size() - 1)) {
194 str += ",";
195 }
196
197 str += " /* " + alComments.get(index) + " */";
198 Output.add(str);
199 bodyLineNum++;
200
201 }
202 }
203 Output.add("}");
204
205 return Output;
206 }
207
208 public int getBodyStart() {
209 return bodyStart;
210 }
211
212 public int getBodyLineNum () {
213 return bodyLineNum;
214 }
215
216 public int add (Token token) {
217 int index = len;
218
219 len++;
220 al.add(token.datumSize);
221 alComments.add(token.getPrimaryKeyString());
222
223 return index;
224 }
225
226 private int getDatumSize(Token token) {
227 /*
228 switch (token.datumType) {
229 case Token.DATUM_TYPE.UINT8:
230 return 1;
231 default:
232 return 0;
233 }
234 */
235 return 0;
236 }
237
238 public int getTableLen () {
239 return al.size() == 0 ? 1 : al.size();
240 }
241
242 }
243
244 class GuidTable {
245 private ArrayList<UUID> al;
246 private ArrayList<String> alComments;
247 private String phase;
248 private int len;
249 private int bodyStart;
250 private int bodyLineNum;
251
252 public GuidTable (String phase) {
253 this.phase = phase;
254 al = new ArrayList<UUID>();
255 alComments = new ArrayList<String>();
256 len = 0;
257 bodyStart = 0;
258 bodyLineNum = 0;
259 }
260
261 public String getSizeMacro () {
262 return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());
263 }
264
265 private int getSize () {
266 return (al.size() == 0)? 1 : al.size();
267 }
268
269 public String getExistanceMacro () {
270 return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
271 }
272
273 public String getTypeDeclaration () {
274 return String.format(PcdDatabase.GuidTableDeclaration, phase);
275 }
276
277 private String getUuidCString (UUID uuid) {
278 String[] guidStrArray;
279
280 guidStrArray =(uuid.toString()).split("-");
281
282 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 } }",
283 guidStrArray[0],
284 guidStrArray[1],
285 guidStrArray[2],
286 (guidStrArray[3].substring(0, 2)),
287 (guidStrArray[3].substring(2, 4)),
288 (guidStrArray[4].substring(0, 2)),
289 (guidStrArray[4].substring(2, 4)),
290 (guidStrArray[4].substring(4, 6)),
291 (guidStrArray[4].substring(6, 8)),
292 (guidStrArray[4].substring(8, 10)),
293 (guidStrArray[4].substring(10, 12))
294 );
295 }
296
297 public ArrayList<String> getInstantiation () {
298 ArrayList<String> Output = new ArrayList<String>();
299
300 Output.add("/* GuidTable */");
301 Output.add("{");
302 bodyStart = 2;
303
304 if (al.size() == 0) {
305 Output.add(getUuidCString(new UUID(0, 0)));
306 }
307
308 for (Object u : al) {
309 UUID uuid = (UUID)u;
310 String str = getUuidCString(uuid);
311
312 if (al.indexOf(u) != (al.size() - 1)) {
313 str += ",";
314 }
315 Output.add(str);
316 bodyLineNum++;
317
318 }
319 Output.add("}");
320
321 return Output;
322 }
323
324 public int getBodyStart() {
325 return bodyStart;
326 }
327
328 public int getBodyLineNum () {
329 return bodyLineNum;
330 }
331
332 public int add (UUID uuid, String name) {
333 int index = len;
334 //
335 // Include the NULL character at the end of String
336 //
337 len++;
338 al.add(uuid);
339
340 return index;
341 }
342
343 public int getTableLen () {
344 return al.size() == 0 ? 0 : al.size();
345 }
346
347 }
348
349 class SkuIdTable {
350 private ArrayList<Integer[]> al;
351 private ArrayList<String> alComment;
352 private String phase;
353 private int len;
354 private int bodyStart;
355 private int bodyLineNum;
356
357 public SkuIdTable (String phase) {
358 this.phase = phase;
359 al = new ArrayList<Integer[]>();
360 alComment = new ArrayList<String>();
361 bodyStart = 0;
362 bodyLineNum = 0;
363 len = 0;
364 }
365
366 public String getSizeMacro () {
367 return String.format(PcdDatabase.SkuIdTableSizeMacro, 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.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
376 }
377
378 public String getTypeDeclaration () {
379 return String.format(PcdDatabase.SkuIdTableDeclaration, phase);
380 }
381
382 public ArrayList<String> getInstantiation () {
383 ArrayList<String> Output = new ArrayList<String> ();
384
385 Output.add("/* SkuIdTable */");
386 Output.add("{");
387 bodyStart = 2;
388
389 if (al.size() == 0) {
390 Output.add("0");
391 }
392
393 for (int index = 0; index < al.size(); index++) {
394 String str;
395
396 str = "/* " + alComment.get(index) + "*/ ";
397 str += "/* MaxSku */ ";
398
399
400 Integer[] ia = al.get(index);
401
402 str += ia[0].toString() + ", ";
403 for (int index2 = 1; index2 < ia.length; index2++) {
404 str += ia[index2].toString();
405 if (index != al.size() - 1) {
406 str += ", ";
407 }
408 }
409
410 Output.add(str);
411 bodyLineNum++;
412
413 }
414
415 Output.add("}");
416
417 return Output;
418 }
419
420 public int add (Token token) {
421
422 int index;
423
424 Integer [] skuIds = new Integer[token.maxSkuCount + 1];
425 skuIds[0] = new Integer(token.maxSkuCount);
426 for (index = 1; index < skuIds.length; index++) {
427 skuIds[index] = new Integer(token.skuData.get(index - 1).id);
428 }
429
430 index = len;
431
432 len += skuIds.length;
433 al.add(skuIds);
434 alComment.add(token.getPrimaryKeyString());
435
436 return index;
437 }
438
439 public int getTableLen () {
440 return al.size() == 0 ? 1 : al.size();
441 }
442
443 }
444
445 class LocalTokenNumberTable {
446 private ArrayList<String> al;
447 private ArrayList<String> alComment;
448 private String phase;
449 private int len;
450
451 public LocalTokenNumberTable (String phase) {
452 this.phase = phase;
453 al = new ArrayList<String>();
454 alComment = new ArrayList<String>();
455
456 len = 0;
457 }
458
459 public String getSizeMacro () {
460 return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())
461 + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());
462 }
463
464 public int getSize () {
465 return (al.size() == 0)? 1 : al.size();
466 }
467
468 public String getExistanceMacro () {
469 return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
470 }
471
472 public String getTypeDeclaration () {
473 return String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);
474 }
475
476 public ArrayList<String> getInstantiation () {
477 ArrayList<String> output = new ArrayList<String>();
478
479 output.add("/* LocalTokenNumberTable */");
480 output.add("{");
481
482 if (al.size() == 0) {
483 output.add("0");
484 }
485
486 for (int index = 0; index < al.size(); index++) {
487 String str;
488
489 str = (String)al.get(index);
490
491 str += " /* " + alComment.get(index) + " */ ";
492
493
494 if (index != (al.size() - 1)) {
495 str += ",";
496 }
497
498 output.add(str);
499
500 }
501
502 output.add("}");
503
504 return output;
505 }
506
507 public int add (Token token) {
508 int index = len;
509 String str;
510
511 len++;
512
513 str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());
514
515 if (token.isStringType()) {
516 str += " | PCD_TYPE_STRING";
517 }
518
519 if (token.skuEnabled) {
520 str += " | PCD_TYPE_SKU_ENABLED";
521 }
522
523 if (token.hiiEnabled) {
524 str += " | PCD_TYPE_HII";
525 }
526
527 if (token.vpdEnabled) {
528 str += " | PCD_TYPE_VPD";
529 }
530
531 al.add(str);
532 alComment.add(token.getPrimaryKeyString());
533
534 return index;
535 }
536 }
537
538 class ExMapTable {
539
540 class ExTriplet {
541 public Integer guidTableIdx;
542 public Long exTokenNumber;
543 public Long localTokenIdx;
544
545 public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {
546 this.guidTableIdx = new Integer(guidTableIdx);
547 this.exTokenNumber = new Long(exTokenNumber);
548 this.localTokenIdx = new Long(localTokenIdx);
549 }
550 }
551
552 private ArrayList<ExTriplet> al;
553 private ArrayList<String> alComment;
554 private String phase;
555 private int len;
556 private int bodyStart;
557 private int bodyLineNum;
558 private int base;
559
560 public ExMapTable (String phase) {
561 this.phase = phase;
562 al = new ArrayList<ExTriplet>();
563 alComment = new ArrayList<String>();
564 bodyStart = 0;
565 bodyLineNum = 0;
566 len = 0;
567 }
568
569 public String getSizeMacro () {
570 return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())
571 + String.format(PcdDatabase.ExTokenNumber, phase, al.size());
572 }
573
574 private int getSize () {
575 return (al.size() == 0)? 1 : al.size();
576 }
577
578 public String getExistanceMacro () {
579 return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
580 }
581
582 public String getTypeDeclaration () {
583 return String.format(PcdDatabase.ExMapTableDeclaration, phase);
584 }
585
586 public ArrayList<String> getInstantiation () {
587 ArrayList<String> Output = new ArrayList<String>();
588
589 Output.add("/* ExMapTable */");
590 Output.add("{");
591 bodyStart = 2;
592
593 if (al.size() == 0) {
594 Output.add("{0, 0, 0}");
595 }
596
597 int index;
598 for (index = 0; index < al.size(); index++) {
599 String str;
600
601 ExTriplet e = (ExTriplet)al.get(index);
602
603 str = "{ " + e.exTokenNumber.toString() + ", ";
604 str += e.localTokenIdx.toString() + ", ";
605 str += e.guidTableIdx.toString();
606
607 str += " /* " + alComment.get(index) + " */";
608
609 if (index != al.size() - 1) {
610 str += ",";
611 }
612
613 Output.add(str);
614 bodyLineNum++;
615
616 }
617
618 Output.add("}");
619
620 return Output;
621 }
622
623 public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {
624 int index = len;
625
626 len++;
627 al.add(new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx));
628 alComment.add(name);
629
630 return index;
631 }
632
633 public int getTableLen () {
634 return al.size() == 0 ? 1 : al.size();
635 }
636
637 }
638
639 class PcdDatabase {
640
641 public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";
642 public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";
643 public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
644 public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";
645 public final static String SizeTableDeclaration = "UINT16 SizeTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
646 public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";
647
648
649 public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";
650 public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";
651 public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n";
652 public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";
653 public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";
654 public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";
655 public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";
656
657
658 public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n";
659 public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";
660 public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";
661 public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";
662 public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";
663
664 public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";
665 public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";
666
667 private StringTable stringTable;
668 private GuidTable guidTable;
669 private LocalTokenNumberTable localTokenNumberTable;
670 private SkuIdTable skuIdTable;
671 private SizeTable sizeTable;
672 private ExMapTable exMapTable;
673
674 private ArrayList<Token> alTokens;
675 private String phase;
676 private int assignedTokenNumber;
677
678 //
679 // After Major changes done to the PCD
680 // database generation class PcdDatabase
681 // Please increment the version and please
682 // also update the version number in PCD
683 // service PEIM and DXE driver accordingly.
684 //
685 private final int version = 1;
686
687 private String hString;
688 private String cString;
689
690
691 class AlignmentSizeComp implements Comparator<Token> {
692 public int compare (Token a, Token b) {
693 return getAlignmentSize(b)
694 - getAlignmentSize(a);
695 }
696 }
697
698 public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {
699 phase = exePhase;
700
701 stringTable = new StringTable(phase);
702 guidTable = new GuidTable(phase);
703 localTokenNumberTable = new LocalTokenNumberTable(phase);
704 skuIdTable = new SkuIdTable(phase);
705 sizeTable = new SizeTable(phase);
706 exMapTable = new ExMapTable(phase);
707
708 assignedTokenNumber = startLen;
709 this.alTokens = alTokens;
710 }
711
712 private void getTwoGroupsOfTokens (ArrayList<Token> alTokens, List<Token> initTokens, List<Token> uninitTokens) {
713 for (int i = 0; i < alTokens.size(); i++) {
714 Token t = (Token)alTokens.get(i);
715 if (t.hasDefaultValue()) {
716 initTokens.add(t);
717 } else {
718 uninitTokens.add(t);
719 }
720 }
721
722 return;
723 }
724
725 private int getAlignmentSize (Token token) {
726 if (token.hiiEnabled) {
727 return 2;
728 }
729
730 if (token.vpdEnabled) {
731 return 4;
732 }
733
734 if (token.isStringType()) {
735 return 2;
736 }
737
738 switch (token.datumType) {
739 case UINT8:
740 return 1;
741 case UINT16:
742 return 2;
743 case UINT32:
744 return 4;
745 case UINT64:
746 return 8;
747 case POINTER:
748 return 1;
749 case BOOLEAN:
750 return 1;
751 }
752 return 1;
753 }
754
755 public String getCString () {
756 return cString;
757 }
758
759 public String getHString () {
760 return hString;
761 }
762
763 public void genCode () {
764
765 final String newLine = "\r\n";
766 final String declNewLine = ";\r\n";
767 final String tab = "\t";
768 final String commaNewLine = ", \r\n";
769
770 int i;
771 ArrayList<String> decla;
772 ArrayList<String> inst;
773
774 String macroStr = "";
775 String initDeclStr = "";
776 String initInstStr = "";
777 String uninitDeclStr = "";
778
779 List<Token> initTokens = new ArrayList<Token> ();
780 List<Token> uninitTokens = new ArrayList<Token> ();
781
782 HashMap <String, ArrayList<String>> initCode = new HashMap<String, ArrayList<String>> ();
783 HashMap <String, ArrayList<String>> uninitCode = new HashMap<String, ArrayList<String>> ();
784
785 getTwoGroupsOfTokens (alTokens, initTokens, uninitTokens);
786
787 //
788 // Generate Structure Declaration for PcdTokens without Default Value
789 // PEI_PCD_DATABASE_INIT
790 //
791 java.util.Comparator<Token> comparator = new AlignmentSizeComp();
792 java.util.Collections.sort(initTokens, comparator);
793 initCode = processTokens(initTokens);
794
795 //
796 // Generate Structure Declaration for PcdTokens without Default Value
797 // PEI_PCD_DATABASE_UNINIT
798 //
799 java.util.Collections.sort(uninitTokens, comparator);
800 uninitCode = processTokens(uninitTokens);
801
802 //
803 // Generate size info Macro for all Tables
804 //
805 macroStr += guidTable.getSizeMacro();
806 macroStr += stringTable.getSizeMacro();
807 macroStr += skuIdTable.getSizeMacro();
808 macroStr += localTokenNumberTable.getSizeMacro();
809 macroStr += exMapTable.getSizeMacro();
810
811 //
812 // Generate existance info Macro for all Tables
813 //
814 macroStr += guidTable.getExistanceMacro();
815 macroStr += stringTable.getExistanceMacro();
816 macroStr += skuIdTable.getExistanceMacro();
817 macroStr += localTokenNumberTable.getExistanceMacro();
818 macroStr += exMapTable.getExistanceMacro();
819
820 //
821 // Generate Structure Declaration for PcdTokens with Default Value
822 // for example PEI_PCD_DATABASE_INIT
823 //
824 initDeclStr += "typedef struct {" + newLine;
825 {
826 initDeclStr += tab + exMapTable.getTypeDeclaration();
827 initDeclStr += tab + guidTable.getTypeDeclaration();
828 initDeclStr += tab + localTokenNumberTable.getTypeDeclaration();
829 initDeclStr += tab + stringTable.getTypeDeclaration();
830 initDeclStr += tab + sizeTable.getTypeDeclaration();
831 initDeclStr += tab + skuIdTable.getTypeDeclaration();
832 if (phase.equalsIgnoreCase("PEI")) {
833 initDeclStr += tab + "SKU_ID SystemSkuId;" + newLine;
834 }
835
836 decla = initCode.get(new String("Declaration"));
837 for (i = 0; i < decla.size(); i++) {
838 initDeclStr += tab + decla.get(i) + declNewLine;
839 }
840
841 //
842 // Generate Structure Declaration for PcdToken with SkuEnabled
843 //
844 decla = initCode.get("DeclarationForSku");
845
846 for (i = 0; i < decla.size(); i++) {
847 initDeclStr += tab + decla.get(i) + declNewLine;
848 }
849 }
850 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;\r\n\r\n", phase);
851
852 //
853 // Generate MACRO for structure intialization of PCDTokens with Default Value
854 // The sequence must match the sequence of declaration of the memembers in the structure
855 String tmp = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase());
856 initInstStr += tmp + newLine;
857 initInstStr += tab + genInstantiationStr(exMapTable.getInstantiation()) + commaNewLine;
858 initInstStr += tab + genInstantiationStr(guidTable.getInstantiation()) + commaNewLine;
859 initInstStr += tab + genInstantiationStr(localTokenNumberTable.getInstantiation()) + commaNewLine;
860 initInstStr += tab + genInstantiationStr(stringTable.getInstantiation()) + commaNewLine;
861 initInstStr += tab + genInstantiationStr(sizeTable.getInstantiation()) + commaNewLine;
862 initInstStr += tab + genInstantiationStr(skuIdTable.getInstantiation()) + commaNewLine;
863 //
864 // For SystemSkuId
865 //
866 if (phase.equalsIgnoreCase("PEI")) {
867 initInstStr += tab + "0" + tab + "/* SystemSkuId */" + commaNewLine;
868 }
869
870 inst = initCode.get("Instantiation");
871 for (i = 0; i < inst.size(); i++) {
872 initInstStr += tab + inst.get(i) + commaNewLine;
873 }
874
875 inst = initCode.get("InstantiationForSku");
876 for (i = 0; i < inst.size(); i++) {
877 initInstStr += tab + inst.get(i);
878 if (i != inst.size() - 1) {
879 initInstStr += commaNewLine;
880 }
881 }
882
883 initInstStr += "};";
884
885 uninitDeclStr += "typedef struct {" + newLine;
886 {
887 decla = uninitCode.get("Declaration");
888 if (decla.size() == 0) {
889 uninitDeclStr += "UINT8 dummy /* The UINT struct is empty */" + declNewLine;
890 } else {
891
892 for (i = 0; i < decla.size(); i++) {
893 uninitDeclStr += tab + decla.get(i) + declNewLine;
894 }
895
896 decla = uninitCode.get("DeclarationForSku");
897
898 for (i = 0; i < decla.size(); i++) {
899 uninitDeclStr += tab + decla.get(i) + declNewLine;
900 }
901 }
902 }
903 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;\r\n\r\n", phase);
904
905 cString = initInstStr + newLine;
906 hString = macroStr + newLine
907 + initDeclStr + newLine
908 + uninitDeclStr + newLine
909 + newLine;
910
911 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);
912
913 }
914
915 private String genInstantiationStr (ArrayList<String> alStr) {
916 String str = "";
917 for (int i = 0; i< alStr.size(); i++) {
918 str += "\t" + alStr.get(i);
919 if (i != alStr.size() - 1) {
920 str += "\r\n";
921 }
922 }
923
924 return str;
925 }
926
927 private HashMap<String, ArrayList<String>> processTokens (List<Token> alToken) {
928
929 HashMap <String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
930
931 ArrayList<String> decl = new ArrayList<String>();
932 ArrayList<String> declForSkuEnableType = new ArrayList<String>();
933 ArrayList<String> inst = new ArrayList<String>();
934 ArrayList<String> instForSkuEnableType = new ArrayList<String>();
935
936 for (int index = 0; index < alToken.size(); index++) {
937 Token token = alToken.get(index);
938
939 if (token.skuEnabled) {
940 //
941 // BugBug: Schema only support Data type now
942 //
943 int tableIdx;
944
945 tableIdx = skuIdTable.add(token);
946
947 decl.add(getSkuEnabledTypeDeclaration(token));
948 if (token.hasDefaultValue()) {
949 inst.add(getSkuEnabledTypeInstantiaion(token, tableIdx));
950 }
951
952 declForSkuEnableType.add(getDataTypeDeclarationForSkuEnabled(token));
953 if (token.hasDefaultValue()) {
954 instForSkuEnableType.add(getDataTypeInstantiationForSkuEnabled(token));
955 }
956
957 } else {
958 if (token.hiiEnabled) {
959 decl.add(getVariableEnableTypeDeclaration(token));
960 inst.add(getVariableEnableInstantiation(token));
961 } else if (token.vpdEnabled) {
962 decl.add(getVpdEnableTypeDeclaration(token));
963 inst.add(getVpdEnableTypeInstantiation(token));
964 } else if (token.isStringType()) {
965 decl.add(getStringTypeDeclaration(token));
966 inst.add(getStringTypeInstantiation(stringTable.add(token.getStringTypeString(), token), token));
967 }
968 else {
969 decl.add(getDataTypeDeclaration(token));
970 if (token.hasDefaultValue()) {
971 inst.add(getDataTypeInstantiation(token));
972 }
973 }
974 }
975
976 sizeTable.add(token);
977 localTokenNumberTable.add(token);
978 token.tokenNumber = assignedTokenNumber++;
979
980 }
981
982 map.put("Declaration", decl);
983 map.put("DeclarationForSku", declForSkuEnableType);
984 map.put("Instantiation", inst);
985 map.put("InstantiationForSku", instForSkuEnableType);
986
987 return map;
988 }
989
990 private String getSkuEnabledTypeDeclaration (Token token) {
991 return String.format("SKU_HEAD %s;\r\n", token.getPrimaryKeyString());
992 }
993
994 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {
995
996 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());
997 return String.format("{ %s, %d }", offsetof, SkuTableIdx);
998 }
999
1000 private String getDataTypeDeclarationForSkuEnabled (Token token) {
1001 String typeStr = "";
1002
1003 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1004 typeStr = "UINT8 %s_%s[%d];\r\n";
1005 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1006 typeStr = "UINT16 %s_%s[%d];\r\n";
1007 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1008 typeStr = "UINT32 %s_%s[%d];\r\n";
1009 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1010 typeStr = "UINT64 %s_%s[%d];\r\n";
1011 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1012 typeStr = "BOOLEAN %s_%s[%d];\r\n";
1013 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1014 return String.format("UINT8 %s_s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount);
1015 }
1016
1017 return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.maxSkuCount);
1018
1019 }
1020
1021 private String getDataTypeInstantiationForSkuEnabled (Token token) {
1022 String str = "";
1023
1024 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1025 return String.format("UINT8 %s_s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount);
1026 } else {
1027 str = "{ ";
1028 for (int idx = 0; idx < token.maxSkuCount; idx++) {
1029 str += token.skuData.get(idx).toString();
1030 if (idx != token.maxSkuCount - 1) {
1031 str += ", ";
1032 }
1033 }
1034 str += "}";
1035
1036 return str;
1037 }
1038
1039 }
1040
1041 private String getDataTypeInstantiation (Token token) {
1042
1043 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1044 return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());
1045 } else {
1046 return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());
1047 }
1048 }
1049
1050
1051 private String getDataTypeDeclaration (Token token) {
1052
1053 String typeStr = "";
1054
1055 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1056 typeStr = "UINT8";
1057 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1058 typeStr = "UINT16";
1059 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1060 typeStr = "UINT32";
1061 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1062 typeStr = "UINT64";
1063 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1064 typeStr = "BOOLEAN";
1065 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1066 return String.format("UINT8 %s[%d]", token.getPrimaryKeyString(), token.datumSize);
1067 } else {
1068 }
1069
1070 return String.format("%s %s", typeStr, token.getPrimaryKeyString());
1071 }
1072
1073 private String getVpdEnableTypeDeclaration (Token token) {
1074 return String.format("VPD_HEAD %s", token.getPrimaryKeyString());
1075 }
1076
1077 private String getVpdEnableTypeInstantiation (Token token) {
1078 return String.format("{ %d } /* %s */", token.vpdOffset,
1079 token.getPrimaryKeyString());
1080 }
1081
1082 private String getStringTypeDeclaration (Token token) {
1083 return String.format("UINT16 %s", token.getPrimaryKeyString());
1084 }
1085
1086 private String getStringTypeInstantiation (int StringTableIdx, Token token) {
1087 return String.format ("%d /* %s */", StringTableIdx,
1088 token.getPrimaryKeyString());
1089 }
1090
1091
1092 private String getVariableEnableTypeDeclaration (Token token) {
1093 return String.format("VARIABLE_HEAD %s", token.getPrimaryKeyString());
1094 }
1095
1096 private String getVariableEnableInstantiation (Token token) {
1097 return String.format("{ %d, %d, %d } /* %s */", guidTable.add(token.variableGuid, token.getPrimaryKeyString()),
1098 stringTable.add(token.variableName, token),
1099 token.variableOffset,
1100 token.getPrimaryKeyString());
1101 }
1102
1103 public int getTotalTokenNumber () {
1104 return sizeTable.getTableLen();
1105 }
1106
1107 public static String getPcdDatabaseCommonDefinitions ()
1108 throws EntityException {
1109
1110 String retStr = "";
1111 try {
1112 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1113 "Tools" + File.separator +
1114 "Conf" + File.separator +
1115 "Pcd" + File.separator +
1116 "PcdDatabaseCommonDefinitions.sample");
1117 FileReader reader = new FileReader(file);
1118 BufferedReader in = new BufferedReader(reader);
1119 String str;
1120 while ((str = in.readLine()) != null) {
1121 retStr = retStr +"\r\n" + str;
1122 }
1123 } catch (Exception ex) {
1124 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");
1125 }
1126
1127 return retStr;
1128 }
1129
1130 public static String getPcdDxeDatabaseDefinitions ()
1131 throws EntityException {
1132
1133 String retStr = "";
1134 try {
1135 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1136 "Tools" + File.separator +
1137 "Conf" + File.separator +
1138 "Pcd" + File.separator +
1139 "PcdDatabaseDxeDefinitions.sample");
1140 FileReader reader = new FileReader(file);
1141 BufferedReader in = new BufferedReader(reader);
1142 String str;
1143 while ((str = in.readLine()) != null) {
1144 retStr = retStr +"\r\n" + str;
1145 }
1146 } catch (Exception ex) {
1147 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");
1148 }
1149
1150 return retStr;
1151 }
1152
1153 public static String getPcdPeiDatabaseDefinitions ()
1154 throws EntityException {
1155
1156 String retStr = "";
1157 try {
1158 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1159 "Tools" + File.separator +
1160 "Conf" + File.separator +
1161 "Pcd" + File.separator +
1162 "PcdDatabasePeiDefinitions.sample");
1163 FileReader reader = new FileReader(file);
1164 BufferedReader in = new BufferedReader(reader);
1165 String str;
1166 while ((str = in.readLine()) != null) {
1167 retStr = retStr +"\r\n" + str;
1168 }
1169 } catch (Exception ex) {
1170 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");
1171 }
1172
1173 return retStr;
1174 }
1175
1176 }
1177
1178 class ModuleInfo {
1179 public ModuleSADocument.ModuleSA module;
1180 public UsageInstance.MODULE_TYPE type;
1181
1182 public ModuleInfo (ModuleSADocument.ModuleSA module, UsageInstance.MODULE_TYPE type) {
1183 this.module = module;
1184 this.type = type;
1185 }
1186 }
1187
1188 /** This action class is to collect PCD information from MSA, SPD, FPD xml file.
1189 This class will be used for wizard and build tools, So it can *not* inherit
1190 from buildAction or UIAction.
1191 **/
1192 public class CollectPCDAction {
1193 /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.
1194 private MemoryDatabaseManager dbManager;
1195
1196 /// Workspacepath hold the workspace information.
1197 private String workspacePath;
1198
1199 /// FPD file is the root file.
1200 private String fpdFilePath;
1201
1202 /// Message level for CollectPCDAction.
1203 private int originalMessageLevel;
1204
1205 /// Cache the fpd docment instance for private usage.
1206 private FrameworkPlatformDescriptionDocument fpdDocInstance;
1207
1208 /**
1209 Set WorkspacePath parameter for this action class.
1210
1211 @param workspacePath parameter for this action
1212 **/
1213 public void setWorkspacePath(String workspacePath) {
1214 this.workspacePath = workspacePath;
1215 }
1216
1217 /**
1218 Set action message level for CollectPcdAction tool.
1219
1220 The message should be restored when this action exit.
1221
1222 @param actionMessageLevel parameter for this action
1223 **/
1224 public void setActionMessageLevel(int actionMessageLevel) {
1225 originalMessageLevel = ActionMessage.messageLevel;
1226 ActionMessage.messageLevel = actionMessageLevel;
1227 }
1228
1229 /**
1230 Set FPDFileName parameter for this action class.
1231
1232 @param fpdFilePath fpd file path
1233 **/
1234 public void setFPDFilePath(String fpdFilePath) {
1235 this.fpdFilePath = fpdFilePath;
1236 }
1237
1238 /**
1239 Common function interface for outer.
1240
1241 @param workspacePath The path of workspace of current build or analysis.
1242 @param fpdFilePath The fpd file path of current build or analysis.
1243 @param messageLevel The message level for this Action.
1244
1245 @throws Exception The exception of this function. Because it can *not* be predict
1246 where the action class will be used. So only Exception can be throw.
1247
1248 **/
1249 public void perform(String workspacePath, String fpdFilePath,
1250 int messageLevel) throws Exception {
1251 setWorkspacePath(workspacePath);
1252 setFPDFilePath(fpdFilePath);
1253 setActionMessageLevel(messageLevel);
1254 checkParameter();
1255 execute();
1256 ActionMessage.messageLevel = originalMessageLevel;
1257 }
1258
1259 /**
1260 Core execution function for this action class.
1261
1262 This function work flows will be:
1263 1) Collect and prepocess PCD information from FPD file, all PCD
1264 information will be stored into memory database.
1265 2) Generate 3 strings for
1266 a) All modules using Dynamic(Ex) PCD entry.(Token Number)
1267 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.
1268 c) DXE PCD Database (C structure) for PCD Service DXE.
1269
1270
1271 @throws EntityException Exception indicate failed to execute this action.
1272
1273 **/
1274 private void execute() throws EntityException {
1275 //
1276 // Get memoryDatabaseManager instance from GlobalData.
1277 // The memoryDatabaseManager should be initialized for whatever build
1278 // tools or wizard tools
1279 //
1280 if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {
1281 throw new EntityException("The instance of PCD memory database manager is null");
1282 }
1283
1284 //
1285 // Collect all PCD information defined in FPD file.
1286 // Evenry token defind in FPD will be created as an token into
1287 // memory database.
1288 //
1289 createTokenInDBFromFPD();
1290
1291
1292 //
1293 // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver
1294 // 1) Generate for PEI, DXE PCD DATABASE's definition and initialization.
1295 //
1296 genPcdDatabaseSourceCode ();
1297
1298 }
1299
1300 /**
1301 This function generates source code for PCD Database.
1302
1303 @param void
1304 @throws EntityException If the token does *not* exist in memory database.
1305
1306 **/
1307 private void genPcdDatabaseSourceCode()
1308 throws EntityException {
1309 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions ();
1310
1311 ArrayList<Token> alPei = new ArrayList<Token> ();
1312 ArrayList<Token> alDxe = new ArrayList<Token> ();
1313
1314 dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);
1315 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);
1316 pcdPeiDatabase.genCode();
1317 dbManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString()
1318 + PcdDatabase.getPcdPeiDatabaseDefinitions();
1319 dbManager.PcdPeimCString = pcdPeiDatabase.getCString();
1320
1321 PcdDatabase pcdDxeDatabase = new PcdDatabase (alDxe,
1322 "DXE",
1323 alPei.size()
1324 );
1325 pcdDxeDatabase.genCode();
1326 dbManager.PcdDxeHString = dbManager.PcdPeimHString + pcdDxeDatabase.getHString()
1327 + PcdDatabase.getPcdDxeDatabaseDefinitions();
1328 dbManager.PcdDxeCString = pcdDxeDatabase.getCString();
1329 }
1330
1331 /**
1332 Get component array from FPD.
1333
1334 This function maybe provided by some Global class.
1335
1336 @return List<ModuleInfo> the component array.
1337
1338 */
1339 private List<ModuleInfo> getComponentsFromFPD()
1340 throws EntityException {
1341 HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();
1342 List<ModuleInfo> allModules = new ArrayList<ModuleInfo>();
1343 ModuleInfo current = null;
1344 int index = 0;
1345 org.tianocore.Components components = null;
1346 FrameworkModulesDocument.FrameworkModules fModules = null;
1347 java.util.List<ModuleSADocument.ModuleSA> modules = null;
1348
1349
1350 if (fpdDocInstance == null) {
1351 try {
1352 fpdDocInstance = (FrameworkPlatformDescriptionDocument)XmlObject.Factory.parse(new File(fpdFilePath));
1353 } catch(IOException ioE) {
1354 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
1355 } catch(XmlException xmlE) {
1356 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
1357 }
1358
1359 }
1360
1361 //
1362 // Check whether FPD contians <FramworkModules>
1363 //
1364 fModules = fpdDocInstance.getFrameworkPlatformDescription().getFrameworkModules();
1365 if (fModules == null) {
1366 return null;
1367 }
1368
1369 //
1370 // BUGBUG: The following is work around code, the final component type should be get from
1371 // GlobalData class.
1372 //
1373 components = fModules.getSEC();
1374 if (components != null) {
1375 modules = components.getModuleSAList();
1376 for (index = 0; index < modules.size(); index ++) {
1377 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.SEC));
1378 }
1379 }
1380
1381 components = fModules.getPEICORE();
1382 if (components != null) {
1383 modules = components.getModuleSAList();
1384 for (index = 0; index < modules.size(); index ++) {
1385 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.PEI_CORE));
1386 }
1387 }
1388
1389 components = fModules.getPEIM();
1390 if (components != null) {
1391 modules = components.getModuleSAList();
1392 for (index = 0; index < modules.size(); index ++) {
1393 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.PEIM));
1394 }
1395 }
1396
1397 components = fModules.getDXECORE();
1398 if (components != null) {
1399 modules = components.getModuleSAList();
1400 for (index = 0; index < modules.size(); index ++) {
1401 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.DXE_CORE));
1402 }
1403 }
1404
1405 components = fModules.getDXEDRIVERS();
1406 if (components != null) {
1407 modules = components.getModuleSAList();
1408 for (index = 0; index < modules.size(); index ++) {
1409 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.DXE_DRIVERS));
1410 }
1411 }
1412
1413 components = fModules.getOTHERCOMPONENTS();
1414 if (components != null) {
1415 modules = components.getModuleSAList();
1416 for (index = 0; index < modules.size(); index ++) {
1417 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.OTHER_COMPONENTS));
1418 }
1419 }
1420
1421 return allModules;
1422 }
1423
1424 /**
1425 Create token instance object into memory database, the token information
1426 comes for FPD file. Normally, FPD file will contain all token platform
1427 informations.
1428
1429 @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.
1430
1431 @throws EntityException Failed to parse FPD xml file.
1432
1433 **/
1434 private void createTokenInDBFromFPD()
1435 throws EntityException {
1436 int index = 0;
1437 int index2 = 0;
1438 int pcdIndex = 0;
1439 List<PcdBuildData> pcdBuildDataArray = new ArrayList<PcdBuildData>();
1440 PcdBuildData pcdBuildData = null;
1441 Token token = null;
1442 UUID nullUUID = new UUID(0,0);
1443 UUID platformTokenSpace= nullUUID;
1444 SkuInstance skuInstance = null;
1445 int skuIndex = 0;
1446 List<ModuleInfo> modules = null;
1447 String primaryKey = null;
1448 PcdBuildData.SkuData[] skuDataArray = null;
1449 String exceptionString = null;
1450 UsageInstance usageInstance = null;
1451 String primaryKey1 = null;
1452 String primaryKey2 = null;
1453 boolean isDuplicate = false;
1454 java.util.List<java.lang.String> tokenGuidStringArray = null;
1455
1456 //
1457 // Get all <ModuleSA> from FPD file.
1458 //
1459 modules = getComponentsFromFPD();
1460
1461 if (modules == null) {
1462 throw new EntityException("No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");
1463 }
1464
1465 //
1466 // Loop all modules to process <PcdBuildDeclarations> for each module.
1467 //
1468 for (index = 0; index < modules.size(); index ++) {
1469 isDuplicate = false;
1470 for (index2 = 0; index2 < index; index2 ++) {
1471 //
1472 // BUGBUG: For transition schema, we can *not* get module's version from
1473 // <ModuleSAs>, It is work around code.
1474 //
1475 primaryKey1 = UsageInstance.getPrimaryKey(modules.get(index).module.getModuleName(),
1476 translateSchemaStringToUUID(modules.get(index).module.getModuleGuid()),
1477 modules.get(index).module.getPackageName(),
1478 translateSchemaStringToUUID(modules.get(index).module.getPackageGuid()),
1479 modules.get(index).module.getArch().toString(),
1480 null);
1481 primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).module.getModuleName(),
1482 translateSchemaStringToUUID(modules.get(index2).module.getModuleGuid()),
1483 modules.get(index2).module.getPackageName(),
1484 translateSchemaStringToUUID(modules.get(index2).module.getPackageGuid()),
1485 modules.get(index2).module.getArch().toString(),
1486 null);
1487 if (primaryKey1.equalsIgnoreCase(primaryKey2)) {
1488 isDuplicate = true;
1489 break;
1490 }
1491 }
1492
1493 if (isDuplicate) {
1494 continue;
1495 }
1496
1497 if (modules.get(index).module.getPcdBuildDeclarations() == null) {
1498 continue;
1499 }
1500 pcdBuildDataArray = modules.get(index).module.getPcdBuildDeclarations().getPcdBuildDataList();
1501 if (pcdBuildDataArray == null) {
1502 continue;
1503 }
1504 if (pcdBuildDataArray.size() == 0) {
1505 continue;
1506 }
1507
1508 //
1509 // Loop all Pcd entry for a module and add it into memory database.
1510 //
1511 for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) {
1512 pcdBuildData = pcdBuildDataArray.get(pcdIndex);
1513 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),
1514 translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid()));
1515
1516
1517 if (dbManager.isTokenInDatabase(primaryKey)) {
1518 //
1519 // If the token is already exist in database, do some necessary checking
1520 // and add a usage instance into this token in database
1521 //
1522 token = dbManager.getTokenByKey(primaryKey);
1523
1524 //
1525 // Checking for DatumSize
1526 //
1527 if (token.datumSize != pcdBuildData.getDatumSize()) {
1528 exceptionString = String.format("The datum size of PCD entry %s is %d, which is different with %d defined in before!",
1529 pcdBuildData.getCName(), pcdBuildData.getDatumSize(), token.datumSize);
1530 throw new EntityException(exceptionString);
1531 }
1532
1533 //
1534 // checking for DatumType
1535 //
1536 if (token.datumType != Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString())) {
1537 exceptionString = String.format("The datum type of PCD entry %s is %s, which is different with %s defined in before!",
1538 pcdBuildData.getCName(),
1539 pcdBuildData.getDatumType().toString(),
1540 Token.getStringOfdatumType(token.datumType));
1541 throw new EntityException(exceptionString);
1542 }
1543 } else {
1544 //
1545 // If the token is not in database, create a new token instance and add
1546 // a usage instance into this token in database.
1547 //
1548 token = new Token(pcdBuildData.getCName(),
1549 translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid()));
1550
1551 token.datum = pcdBuildData.getDefaultValue();
1552 token.pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());
1553 token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());
1554 token.datumSize = pcdBuildData.getDatumSize();
1555 token.skuId = Integer.decode(pcdBuildData.getSkuId());
1556
1557 if (pcdBuildData.getToken() == null) {
1558 exceptionString = String.format("In FPD file, No <TokenNumber> defined for PCD entry %s in module %s",
1559 token.cName,
1560 modules.get(index).module.getModuleName());
1561 throw new EntityException(exceptionString);
1562 }
1563 token.tokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue());
1564
1565 if ((token.pcdType == Token.PCD_TYPE.DYNAMIC) ||
1566 (token.pcdType == Token.PCD_TYPE.DYNAMIC_EX)) {
1567 updateDynamicInformation(modules.get(index).module.getModuleName(), token);
1568 }
1569
1570 dbManager.addTokenToDatabase(primaryKey, token);
1571 }
1572
1573 //
1574 // Create an usage instance for this token
1575 //
1576 usageInstance = new UsageInstance(token,
1577 Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()),
1578 modules.get(index).module.getModuleName(),
1579 translateSchemaStringToUUID(modules.get(index).module.getModuleGuid()),
1580 modules.get(index).module.getPackageName(),
1581 translateSchemaStringToUUID(modules.get(index).module.getPackageGuid()),
1582 modules.get(index).type,
1583 Token.getpcdTypeFromString(pcdBuildData.getItemType().toString()),
1584 modules.get(index).module.getArch().toString(),
1585 null,
1586 pcdBuildData.getDefaultValue());
1587 token.addUsageInstance(usageInstance);
1588 }
1589 }
1590 }
1591
1592 /**
1593 Update dynamic information for PCD entry.
1594
1595 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in
1596 FPD file.
1597
1598 @param moduleName
1599 @param token
1600
1601 @return Token
1602 **/
1603 private Token updateDynamicInformation(String moduleName, Token token)
1604 throws EntityException {
1605 PcdDynamicBuildDeclarations pcdDynamicBuildDescriptions = null;
1606
1607 boolean isFound = false;
1608 int index = 0;
1609 String primaryKey = null;
1610 SkuInstance skuInstance = null;
1611 int skuIndex = 0;
1612 String exceptionString = null;
1613 PcdDynamicBuildDeclarations.PcdBuildData.SkuData[] skuDataArray = null;
1614 List<PcdDynamicBuildDeclarations.PcdBuildData> pcdDynamicBuildDataArray = null;
1615
1616 //
1617 // If FPD document is not be opened, open and initialize it.
1618 //
1619 if (fpdDocInstance == null) {
1620 try {
1621 fpdDocInstance = (FrameworkPlatformDescriptionDocument)XmlObject.Factory.parse(new File(fpdFilePath));
1622 } catch(IOException ioE) {
1623 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
1624 } catch(XmlException xmlE) {
1625 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
1626 }
1627 }
1628
1629 pcdDynamicBuildDescriptions = fpdDocInstance.getFrameworkPlatformDescription().getPcdDynamicBuildDeclarations();
1630 if (pcdDynamicBuildDescriptions == null) {
1631 throw new EntityException(String.format("There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+
1632 "PCD entry %s in module %s!",
1633 token.cName,
1634 moduleName));
1635 }
1636
1637 pcdDynamicBuildDataArray = pcdDynamicBuildDescriptions.getPcdBuildDataList();
1638 if (pcdDynamicBuildDataArray == null) {
1639 throw new EntityException(String.format("There are no PcdDynamicBuildData in <PcdDynamicBuildDeclaration> section but contains Dynamic type"+
1640 "PCD entry %s in module %s.!",
1641 token.cName,
1642 moduleName));
1643 }
1644
1645 isFound = false;
1646 for (index = 0; index < pcdDynamicBuildDataArray.size(); index ++) {
1647 if (pcdDynamicBuildDataArray.get(index).getTokenSpaceGuidList().size() != 0) {
1648 primaryKey = Token.getPrimaryKeyString(pcdDynamicBuildDataArray.get(index).getCName(),
1649 translateSchemaStringToUUID(pcdDynamicBuildDataArray.get(index).getTokenSpaceGuidList().get(0)));
1650 } else {
1651 primaryKey = Token.getPrimaryKeyString(pcdDynamicBuildDataArray.get(index).getCName(),
1652 translateSchemaStringToUUID(null));
1653 }
1654
1655 if (primaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {
1656 isFound = true;
1657
1658 //
1659 // For Hii related value
1660 //
1661 token.hiiEnabled = pcdDynamicBuildDataArray.get(index).getHiiEnable();
1662 if (token.hiiEnabled) {
1663 token.variableGuid = Token.getGUIDFromSchemaObject(pcdDynamicBuildDataArray.get(index).getVariableGuid());
1664 if (token.variableGuid == null) {
1665 throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, HiiEnable is true" +
1666 "but no <VariableGuid> is found! Please fix the FPD file!",
1667 token.cName));
1668
1669 }
1670 token.variableName = pcdDynamicBuildDataArray.get(index).getVariableName();
1671 if (token.variableName == null) {
1672 throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, HiiEnable is true" +
1673 "but no <VariableName> is found! Please fix the FPD file!",
1674 token.cName));
1675 }
1676
1677 if (pcdDynamicBuildDataArray.get(index).getDataOffset() == null) {
1678 throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, HiiEnable is true" +
1679 "but no <DataOffset> is found! Please fix the FPD file!",
1680 token.cName));
1681 }
1682 token.variableOffset = Integer.decode(pcdDynamicBuildDataArray.get(index).getDataOffset());
1683 }
1684
1685 //
1686 // For Vpd related value
1687 //
1688 token.vpdEnabled = pcdDynamicBuildDataArray.get(index).getVpdEnable();
1689 if (token.vpdEnabled) {
1690 if (pcdDynamicBuildDataArray.get(index).getDataOffset() == null) {
1691 throw new EntityException(String.format("In <PcdDynamicBuildDeclarations> for PCD entry %s, VpdEnable is true" +
1692 "but no <DataOffset> is found! Please fix the FPD file!",
1693 token.cName));
1694 }
1695 token.vpdOffset = Integer.decode(pcdDynamicBuildDataArray.get(index).getDataOffset());
1696 }
1697
1698 //
1699 // For SkuData
1700 //
1701 token.skuEnabled = pcdDynamicBuildDataArray.get(index).getSkuEnable();
1702 if (token.skuEnabled) {
1703 skuDataArray = (PcdDynamicBuildDeclarations.PcdBuildData.SkuData[])pcdDynamicBuildDataArray.get(index).getSkuDataList().toArray();
1704 token.maxSkuCount = Integer.decode(pcdDynamicBuildDataArray.get(index).getMaxSku());
1705 if (skuDataArray == null) {
1706 exceptionString = String.format("In FPD file, the <SkuEnable> is true for PCD entry %s in module %s, But no any sku data.",
1707 token.cName, moduleName);
1708 throw new EntityException(exceptionString);
1709 }
1710 if (token.maxSkuCount != pcdDynamicBuildDataArray.get(index).sizeOfSkuDataArray()) {
1711 exceptionString = String.format("In FPD file, <MaxSku> is not equal to the size of <SkuDataArray> for PCD entry %s in module %s",
1712 token.cName, moduleName);
1713 throw new EntityException(exceptionString);
1714 }
1715
1716 for (skuIndex = 0; skuIndex < pcdDynamicBuildDataArray.get(index).sizeOfSkuDataArray(); skuIndex ++) {
1717 skuInstance = new SkuInstance(skuDataArray[skuIndex].getId(),
1718 skuDataArray[skuIndex].getValue());
1719 token.skuData.add(skuInstance);
1720 }
1721 }
1722 break;
1723 }
1724 }
1725 if (!isFound) {
1726 exceptionString = String.format("In FPD file, No dynamic PCD data for PCD entry %s in module %s",
1727 token.cName,
1728 moduleName);
1729 throw new EntityException(exceptionString);
1730 }
1731
1732 return token;
1733 }
1734
1735 /**
1736 Translate the schema string to UUID instance.
1737
1738 In schema, the string of UUID is defined as following two types string:
1739 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
1740 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
1741
1742 2) GuidNamingConvention: pattern =
1743 [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}
1744
1745 This function will convert string and create uuid instance.
1746
1747 @param uuidString UUID string in XML file
1748
1749 @return UUID UUID instance
1750 **/
1751 private UUID translateSchemaStringToUUID(String uuidString)
1752 throws EntityException {
1753 String temp;
1754 String[] splitStringArray;
1755 int index;
1756 int chIndex;
1757 int chLen;
1758
1759 if (uuidString == null) {
1760 return null;
1761 }
1762
1763 if (uuidString.length() == 0) {
1764 return null;
1765 }
1766
1767 //
1768 // If the UUID schema string is GuidArrayType type then need translate
1769 // to GuidNamingConvention type at first.
1770 //
1771 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {
1772 splitStringArray = uuidString.split("," );
1773 if (splitStringArray.length != 11) {
1774 throw new EntityException ("Wrong format for UUID string: " + uuidString);
1775 }
1776
1777 //
1778 // Remove blank space from these string and remove header string "0x"
1779 //
1780 for (index = 0; index < 11; index ++) {
1781 splitStringArray[index] = splitStringArray[index].trim();
1782 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());
1783 }
1784
1785 //
1786 // Add heading '0' to normalize the string length
1787 //
1788 for (index = 3; index < 11; index ++) {
1789 chLen = splitStringArray[index].length();
1790 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {
1791 splitStringArray[index] = "0" + splitStringArray[index];
1792 }
1793 }
1794
1795 //
1796 // construct the final GuidNamingConvention string
1797 //
1798 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
1799 splitStringArray[0],
1800 splitStringArray[1],
1801 splitStringArray[2],
1802 splitStringArray[3],
1803 splitStringArray[4],
1804 splitStringArray[5],
1805 splitStringArray[6],
1806 splitStringArray[7],
1807 splitStringArray[8],
1808 splitStringArray[9],
1809 splitStringArray[10]);
1810 uuidString = temp;
1811 }
1812
1813 return UUID.fromString(uuidString);
1814 }
1815
1816 /**
1817 check parameter for this action.
1818
1819 @throws EntityException Bad parameter.
1820 **/
1821 private void checkParameter() throws EntityException {
1822 File file = null;
1823
1824 if((fpdFilePath == null) ||(workspacePath == null)) {
1825 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
1826 }
1827
1828 if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {
1829 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
1830 }
1831
1832 file = new File(workspacePath);
1833 if(!file.exists()) {
1834 throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");
1835 }
1836
1837 file = new File(fpdFilePath);
1838
1839 if(!file.exists()) {
1840 throw new EntityException("FPD File " + fpdFilePath + " does not exist!");
1841 }
1842 }
1843
1844 /**
1845 Test case function
1846
1847 @param argv parameter from command line
1848 **/
1849 public static void main(String argv[]) throws EntityException {
1850 CollectPCDAction ca = new CollectPCDAction();
1851 ca.setWorkspacePath("M:/ForPcd/edk2");
1852 ca.setFPDFilePath("M:/ForPcd/edk2/EdkNt32Pkg/Nt32.fpd");
1853 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);
1854 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
1855 "M:/ForPcd/edk2");
1856 ca.execute();
1857 }
1858 }