git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@250 6f19259b...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PCDAutoGenAction.java
1 /** @file
2 PCDAutoGenAction class.
3
4 This class is to manage how to generate the PCD information into Autogen.c and
5 Autogen.h.
6
7 Copyright (c) 2006, Intel Corporation
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
12
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
16 **/
17 package org.tianocore.build.pcd.action;
18
19 import java.io.File;
20 import java.util.List;
21
22 import org.tianocore.build.global.GlobalData;
23 import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
24 import org.tianocore.build.pcd.entity.Token;
25 import org.tianocore.build.pcd.entity.UsageInstance;
26 import org.tianocore.build.pcd.exception.BuildActionException;
27 import org.tianocore.build.pcd.exception.EntityException;
28
29 /** This class is to manage how to generate the PCD information into Autogen.c and
30 Autogen.h.
31 **/
32 public class PCDAutoGenAction extends BuildAction {
33 ///
34 /// The reference of DBManager in GlobalData class.
35 ///
36 private MemoryDatabaseManager dbManager;
37 ///
38 /// The name of module which is analysised currently.
39 ///
40 private String moduleName;
41 ///
42 /// Wheter current module is PCD emulated driver. It is only for
43 /// emulated PCD driver and will be kept until PCD IMAGE tool ready.
44 ///
45 private boolean isEmulatedPCDDriver;
46 ///
47 /// The generated string for header file.
48 ///
49 private String hAutoGenString;
50 ///
51 /// The generated string for C code file.
52 ///
53 private String cAutoGenString;
54
55 /**
56 Set parameter ModuleName
57
58 @param moduleName the module name parameter.
59 **/
60 public void setModuleName(String moduleName) {
61 this.moduleName = moduleName;
62 }
63
64 /**
65 Set parameter isEmulatedPCDDriver
66
67 @param isEmulatedPCDDriver whether this module is PeiEmulatedPCD driver
68 **/
69 public void setIsEmulatedPCDDriver(boolean isEmulatedPCDDriver) {
70 this.isEmulatedPCDDriver = isEmulatedPCDDriver;
71 }
72
73 /**
74 Get the output of generated string for header file.
75
76 @return the string of header file for PCD
77 **/
78 public String OutputH() {
79 return hAutoGenString;
80 }
81
82 /**
83 Get the output of generated string for C Code file.
84
85 @return the string of C code file for PCD
86 **/
87 public String OutputC() {
88 return cAutoGenString;
89 }
90
91 /**
92 Construct function
93
94 This function mainly initialize some member variable.
95
96 @param moduleName Parameter of this action class.
97 @param isEmulatedPCDDriver Parameter of this action class.
98 **/
99 public PCDAutoGenAction(String moduleName, boolean isEmulatedPCDDriver) {
100 dbManager = null;
101 setIsEmulatedPCDDriver(isEmulatedPCDDriver);
102 setModuleName(moduleName);
103 }
104
105 /**
106 check the parameter for action class.
107
108 @throws BuildActionException Bad parameter.
109 **/
110 void checkParameter() throws BuildActionException {
111 if(!isEmulatedPCDDriver &&(moduleName == null)) {
112 throw new BuildActionException("Wrong module name parameter for PCDAutoGenAction tool!");
113 }
114
115 if(!isEmulatedPCDDriver && moduleName.length() == 0) {
116 throw new BuildActionException("Wrong module name parameter for PCDAutoGenAction tool!");
117 }
118 }
119
120 /**
121 Core execution function for this action class.
122
123 All PCD information of this module comes from memory dabase. The collection
124 work should be done before this action execution.
125 Currently, we should generated all PCD information(maybe all dynamic) as array
126 in Pei emulated driver for simulating PCD runtime database.
127
128 @throws BuildActionException Failed to execute this aciton class.
129 **/
130 void performAction() throws BuildActionException {
131 ActionMessage.debug(this,
132 "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");
133
134 //
135 // Check the PCD memory database manager is valid.
136 //
137 if(GlobalData.getPCDMemoryDBManager() == null) {
138 throw new BuildActionException("Memory database has not been initlizated!");
139 }
140
141 dbManager = GlobalData.getPCDMemoryDBManager();
142
143 if(dbManager.getDBSize() == 0) {
144 return;
145 }
146
147 ActionMessage.debug(this,
148 "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens");
149
150 hAutoGenString = "";
151 cAutoGenString = "";
152
153 if(isEmulatedPCDDriver) {
154 generateAutogenForPCDEmulatedDriver();
155 } else {
156 generateAutogenForModule();
157 }
158 }
159
160 /**
161 Generate the autogen string for a common module.
162
163 All PCD information of this module comes from memory dabase. The collection
164 work should be done before this action execution.
165 **/
166 private void generateAutogenForModule()
167 {
168 int index;
169 List<UsageInstance> usageInstanceArray;
170
171 usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(moduleName);
172
173 if(usageInstanceArray.size() != 0) {
174 //
175 // Add "#include 'PcdLib.h'" for Header file
176 //
177 hAutoGenString = "#include <MdePkg/Include/Library/PcdLib.h>\r\n";
178 }
179
180 for(index = 0; index < usageInstanceArray.size(); index ++) {
181 ActionMessage.debug(this,
182 "Module " + moduleName + "'s PCD [" + Integer.toHexString(index) +
183 "]: " + usageInstanceArray.get(index).parentToken.cName);
184 try {
185 usageInstanceArray.get(index).generateAutoGen();
186 hAutoGenString += usageInstanceArray.get(index).getHAutogenStr() + "\r\n";
187 cAutoGenString += usageInstanceArray.get(index).getCAutogenStr() + "\r\n";
188 } catch(EntityException exp) {
189 throw new BuildActionException(exp.getMessage());
190 }
191 }
192
193 if (moduleName.equalsIgnoreCase("PcdPeim")) {
194 hAutoGenString += dbManager.PcdPeimHString;
195 cAutoGenString += dbManager.PcdPeimCString;
196 } else if (moduleName.equalsIgnoreCase("PcdDxe")) {
197 hAutoGenString += dbManager.PcdDxeHString;
198 cAutoGenString += dbManager.PcdDxeCString;
199 }
200
201 ActionMessage.debug(this,
202 "Module " + moduleName + "'s PCD header file:\r\n" + hAutoGenString + "\r\n"
203 );
204 ActionMessage.debug(this,
205 "Module " + moduleName + "'s PCD C file:\r\n" + cAutoGenString + "\r\n"
206 );
207 }
208
209 /**
210 Generate all PCD autogen string and the emulated PCD IMAGE array for emulated driver.
211
212 Currently, we should generated all PCD information(maybe all dynamic) as array
213 in Pei emulated driver for simulating PCD runtime database.
214
215 **/
216 private void generateAutogenForPCDEmulatedDriver() {
217 int index;
218 Token[] tokenArray;
219 UsageInstance usageInstance;
220
221 //
222 // Add "#include 'PcdLib.h'" for Header file
223 //
224 hAutoGenString = "#include <MdePkg/Include/Library/PcdLib.h>\r\n";
225
226 tokenArray = dbManager.getRecordArray();
227 for(index = 0; index < tokenArray.length; index ++) {
228 //
229 // Get one consumer instance and generate autogen for this token.
230 //
231 if(tokenArray[index].consumers != null ) {
232 if(tokenArray[index].consumers.size() != 0) {
233 usageInstance = tokenArray[index].consumers.get(0);
234 try {
235 usageInstance.generateAutoGen();
236 } catch(EntityException exp) {
237 throw new BuildActionException(exp.getMessage());
238 }
239
240 hAutoGenString += usageInstance.getHAutogenStr();
241 cAutoGenString += usageInstance.getCAutogenStr();
242
243 hAutoGenString += "\r\n";
244 cAutoGenString += "\r\n";
245 } else {
246 //
247 // If the PCD does *not* usded by any module, also generate
248 // it into autogen.h/autogen.c in Pcd driver according the
249 // information in FPD file.
250 //
251 generateUnReferencePcdAutogenString(tokenArray[index]);
252 }
253 }
254 }
255
256 generatePCDEmulatedArray(tokenArray);
257
258 ActionMessage.debug(this,
259 "PCD emulated driver's header: \r\n" + hAutoGenString + "\r\n"
260 );
261 ActionMessage.debug(this,
262 "PCD emulated driver's C code: \r\n" + cAutoGenString + "\r\n"
263 );
264
265 }
266
267 /**
268 Generate unreference token definition string for PCD emulated string.
269
270 Maybe some PCD token definition in FPD but not used by any module or library, we
271 should also generate token definition in autoge.h/autogen.c, because maybe some
272 driver loaded in shell will use this PCD.
273
274 @param token The token who want be generated autogen string.
275
276 **/
277 private void generateUnReferencePcdAutogenString(Token token) {
278 hAutoGenString += String.format("#define _PCD_TOKEN_%s 0x%016x\r\n",
279 token.cName, token.tokenNumber);
280 switch (token.pcdType) {
281 case FEATURE_FLAG:
282 hAutoGenString += String.format(
283 "#define _PCD_VALUE_%s %s\r\n",
284 token.cName,
285 token.datum.toString()
286 );
287 hAutoGenString += String.format(
288 "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n",
289 token.cName
290 );
291 cAutoGenString += String.format(
292 "GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",
293 token.cName,
294 token.cName
295 );
296 hAutoGenString += String.format(
297 "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n",
298 Token.GetAutogenDefinedatumTypeString(token.datumType),
299 token.cName,
300 token.cName
301 );
302 break;
303 case FIXED_AT_BUILD:
304 hAutoGenString += String.format(
305 "#define _PCD_VALUE_%s %s\r\n",
306 token.cName,
307 token.datum.toString()
308 );
309 hAutoGenString += String.format(
310 "extern const %s _gPcd_FixedAtBuild_%s;\r\n",
311 Token.getAutogendatumTypeString(token.datumType),
312 token.cName
313 );
314 cAutoGenString += String.format(
315 "GLOBAL_REMOVE_IF_UNREFERENCED const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",
316 Token.getAutogendatumTypeString(token.datumType),
317 token.cName,
318 token.cName
319 );
320 hAutoGenString += String.format(
321 "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n",
322 Token.GetAutogenDefinedatumTypeString(token.datumType),
323 token.cName,
324 token.cName
325 );
326 break;
327 case PATCHABLE_IN_MODULE:
328 hAutoGenString += String.format(
329 "#define _PCD_VALUE_%s %s\r\n",
330 token.cName,
331 token.datum.toString()
332 );
333 hAutoGenString += String.format(
334 "extern %s _gPcd_BinaryPatch_%s;\r\n",
335 Token.getAutogendatumTypeString(token.datumType),
336 token.cName
337 );
338 cAutoGenString += String.format(
339 "GLOBAL_REMOVE_IF_UNREFERENCED %s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;\r\n",
340 Token.getAutogendatumTypeString(token.datumType),
341 token.cName,
342 token.cName
343 );
344 hAutoGenString += String.format(
345 "#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n",
346 Token.GetAutogenDefinedatumTypeString(token.datumType),
347 token.cName,
348 token.cName
349 );
350 break;
351 case DYNAMIC:
352 hAutoGenString += String.format(
353 "#define _PCD_MODE_%s_%s LibPcdGet%s(_PCD_TOKEN_%s)\r\n",
354 Token.GetAutogenDefinedatumTypeString(token.datumType),
355 token.cName,
356 Token.getAutogenLibrarydatumTypeString(token.datumType),
357 token.cName
358 );
359 break;
360 case DYNAMIC_EX:
361 break;
362 default:
363 ActionMessage.warning(this,
364 "The PCD_TYPE setted by platform is unknown"
365 );
366 }
367
368 hAutoGenString += "\r\n";
369 cAutoGenString += "\r\n";
370 }
371
372 /**
373 Generate PCDEmulated array in PCDEmulated driver for emulated runtime database.
374
375 @param tokenArray All PCD token in memory database.
376
377 @throws BuildActionException Unknown PCD_TYPE
378 **/
379 private void generatePCDEmulatedArray(Token[] tokenArray)
380 throws BuildActionException {
381 int index;
382 Token token;
383 String[] guidStrArray;
384 String value;
385
386 //
387 // The value of String type of PCD entry maybe use byte array but not string direcly
388 // such as {0x1, 0x2, 0x3}, and define PCD1_STRING_Value as L"string define here"
389 // For this case, we should generate a string array to C output and use the address
390 // of generated string array.
391 //
392 for(index = 0; index < tokenArray.length; index ++) {
393 token = tokenArray[index];
394
395 value = token.datum.toString();
396 if(token.datumType == Token.DATUM_TYPE.POINTER) {
397 if(!((value.charAt(0) == 'L' && value.charAt(1) == '"') ||(value.charAt(0) == '"'))) {
398 cAutoGenString += String.format("UINT8 _mPcdArray%08x[] = %s;\r\n",
399 index,
400 value
401 );
402 }
403 }
404 }
405
406 //
407 // Output emulated PCD entry array
408 //
409 cAutoGenString += "\r\nEMULATED_PCD_ENTRY gEmulatedPcdEntry[] = {\r\n";
410
411 for(index = 0; index < tokenArray.length; index ++) {
412 token = tokenArray[index];
413
414 if(index != 0) {
415 cAutoGenString += ",\r\n";
416 }
417
418 //
419 // Print Start "{" for a Token item in array
420 //
421 cAutoGenString += " {\r\n";
422
423 //
424 // Print Token Name
425 //
426 cAutoGenString += String.format(" _PCD_TOKEN_%s,\r\n", token.cName);
427
428 //
429 // Print Hii information
430 //
431 if(token.hiiEnabled) {
432 cAutoGenString += String.format(" TRUE,\r\n");
433 } else {
434 cAutoGenString += String.format(" FALSE,\r\n");
435 }
436
437 //
438 // Print sku information
439 //
440 if(token.skuEnabled) {
441 cAutoGenString += String.format(" TRUE,\r\n");
442 } else {
443 cAutoGenString += String.format(" FALSE,\r\n");
444 }
445
446 //
447 // Print maxSkuCount
448 //
449 cAutoGenString += String.format(" %d,\r\n", token.maxSkuCount);
450
451 cAutoGenString += String.format(" %d,\r\n", token.skuId);
452
453 if(token.variableGuid == null) {
454 cAutoGenString += " { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\r\n";
455 } else {
456 guidStrArray =(token.variableGuid.toString()).split("-");
457
458 cAutoGenString += String.format(" { 0x%s, 0x%s, 0x%s, { 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s } },\r\n",
459 guidStrArray[0],
460 guidStrArray[1],
461 guidStrArray[2],
462 (guidStrArray[3].substring(0, 2)),
463 (guidStrArray[3].substring(2, 4)),
464 (guidStrArray[4].substring(0, 2)),
465 (guidStrArray[4].substring(2, 4)),
466 (guidStrArray[4].substring(4, 6)),
467 (guidStrArray[4].substring(6, 8)),
468 (guidStrArray[4].substring(8, 10)),
469 (guidStrArray[4].substring(10, 12))
470 );
471
472 }
473
474 value = token.datum.toString();
475 if(token.datumType == Token.DATUM_TYPE.POINTER) {
476 if((value.charAt(0) == 'L' && value.charAt(1) == '"') || value.charAt(0) == '"') {
477 cAutoGenString += String.format(" sizeof(_PCD_VALUE_%s),\r\n", token.cName);
478 cAutoGenString += String.format(" 0, %s, %s,\r\n", token.variableName, value);
479 } else {
480 cAutoGenString += String.format(" sizeof(_mPcdArray%08x),\r\n", index);
481 cAutoGenString += String.format(" 0, &_mPcdArray%08x, %s,\r\n", index, token.variableName);
482 }
483 } else {
484 switch(token.datumType) {
485 case UINT8:
486 cAutoGenString += " 1,\r\n";
487 break;
488 case UINT16:
489 cAutoGenString += " 2,\r\n";
490 break;
491 case UINT32:
492 cAutoGenString += " 4,\r\n";
493 break;
494 case UINT64:
495 cAutoGenString += " 8,\r\n";
496 break;
497 case BOOLEAN:
498 cAutoGenString += " 1,\r\n";
499 break;
500 default:
501 throw new BuildActionException("Unknown datum size");
502 }
503 cAutoGenString += String.format(" %s, %s, NULL,\r\n", value, token.variableName);
504 }
505
506 //
507 // Print end "}" for a token item in array
508 //
509 cAutoGenString += " }";
510 }
511
512 cAutoGenString += "\r\n};\r\n";
513 cAutoGenString += "\r\n";
514 cAutoGenString += "UINTN\r\n";
515 cAutoGenString += "GetPcdDataBaseSize(\r\n";
516 cAutoGenString += " VOID\r\n";
517 cAutoGenString += " )\r\n";
518 cAutoGenString += "{\r\n";
519 cAutoGenString += " return sizeof(gEmulatedPcdEntry);\r\n";
520 cAutoGenString += "}\r\n";
521 }
522
523 /**
524 Test case function
525
526 @param argv paramter from command line
527 **/
528 public static void main(String argv[]) {
529
530 String WorkSpace = "G:/edk2";
531 String logFilePath = WorkSpace + "/EdkNt32Pkg/Nt32.fpd";
532
533 //
534 // At first, CollectPCDAction should be invoked to collect
535 // all PCD information from SPD, MSA, FPD.
536 //
537 CollectPCDAction collectionAction = new CollectPCDAction();
538 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
539 WorkSpace);
540
541 GlobalData.getPCDMemoryDBManager().setLogFileName(logFilePath + ".PCDMemroyDatabaseLog.txt");
542
543 try {
544 collectionAction.perform(WorkSpace,
545 logFilePath,
546 ActionMessage.MAX_MESSAGE_LEVEL);
547 } catch(Exception e) {
548 e.printStackTrace();
549 }
550
551 //
552 // Then execute the PCDAuotoGenAction to get generated Autogen.h and Autogen.c
553 //
554 PCDAutoGenAction autogenAction = new PCDAutoGenAction("PcdDxe",
555 false
556 );
557 autogenAction.execute();
558
559 System.out.println(autogenAction.OutputH());
560 System.out.println("WQWQWQWQWQ");
561 System.out.println(autogenAction.OutputC());
562
563
564 System.out.println (autogenAction.hAutoGenString);
565 System.out.println (autogenAction.cAutoGenString);
566
567 }
568 }