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