f3e5b17be8725a5820b9fbf5072dd62509126f29
[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 ActionMessage.debug(this,
194 "Module " + moduleName + "'s PCD header file:\r\n" + hAutoGenString + "\r\n"
195 );
196 ActionMessage.debug(this,
197 "Module " + moduleName + "'s PCD C file:\r\n" + cAutoGenString + "\r\n"
198 );
199 }
200
201 /**
202 Generate all PCD autogen string and the emulated PCD IMAGE array for emulated driver.
203
204 Currently, we should generated all PCD information(maybe all dynamic) as array
205 in Pei emulated driver for simulating PCD runtime database.
206
207 **/
208 private void generateAutogenForPCDEmulatedDriver() {
209 int index;
210 Token[] tokenArray;
211 UsageInstance usageInstance;
212
213 //
214 // Add "#include 'PcdLib.h'" for Header file
215 //
216 hAutoGenString = "#include <MdePkg/Include/Library/PcdLib.h>\r\n";
217
218 tokenArray = dbManager.getRecordArray();
219 for(index = 0; index < tokenArray.length; index ++) {
220 //
221 // Get one consumer instance and generate autogen for this token.
222 //
223 if(tokenArray[index].consumers != null ) {
224 if(tokenArray[index].consumers.size() != 0) {
225 usageInstance = tokenArray[index].consumers.get(0);
226 try {
227 usageInstance.generateAutoGen();
228 } catch(EntityException exp) {
229 throw new BuildActionException(exp.getMessage());
230 }
231
232 hAutoGenString += usageInstance.getHAutogenStr();
233 cAutoGenString += usageInstance.getCAutogenStr();
234
235 hAutoGenString += "\r\n";
236 cAutoGenString += "\r\n";
237 } else {
238 //
239 // If the PCD does *not* usded by any module, also generate
240 // it into autogen.h/autogen.c in Pcd driver according the
241 // information in FPD file.
242 //
243 generateUnReferencePcdAutogenString(tokenArray[index]);
244 }
245 }
246 }
247
248 generatePCDEmulatedArray(tokenArray);
249
250 ActionMessage.debug(this,
251 "PCD emulated driver's header: \r\n" + hAutoGenString + "\r\n"
252 );
253 ActionMessage.debug(this,
254 "PCD emulated driver's C code: \r\n" + cAutoGenString + "\r\n"
255 );
256
257 }
258
259 /**
260 Generate unreference token definition string for PCD emulated string.
261
262 Maybe some PCD token definition in FPD but not used by any module or library, we
263 should also generate token definition in autoge.h/autogen.c, because maybe some
264 driver loaded in shell will use this PCD.
265
266 @param token The token who want be generated autogen string.
267
268 **/
269 private void generateUnReferencePcdAutogenString(Token token) {
270 hAutoGenString += String.format("#define _PCD_TOKEN_%s 0x%016x\r\n",
271 token.cName, token.tokenNumber);
272 switch (token.pcdType) {
273 case FEATURE_FLAG:
274 hAutoGenString += String.format(
275 "#define _PCD_VALUE_%s %s\r\n",
276 token.cName,
277 token.datum.toString()
278 );
279 hAutoGenString += String.format(
280 "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n",
281 token.cName
282 );
283 cAutoGenString += String.format(
284 "GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",
285 token.cName,
286 token.cName
287 );
288 hAutoGenString += String.format(
289 "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n",
290 Token.GetAutogenDefinedatumTypeString(token.datumType),
291 token.cName,
292 token.cName
293 );
294 break;
295 case FIXED_AT_BUILD:
296 hAutoGenString += String.format(
297 "#define _PCD_VALUE_%s %s\r\n",
298 token.cName,
299 token.datum.toString()
300 );
301 hAutoGenString += String.format(
302 "extern const %s _gPcd_FixedAtBuild_%s;\r\n",
303 Token.getAutogendatumTypeString(token.datumType),
304 token.cName
305 );
306 cAutoGenString += String.format(
307 "GLOBAL_REMOVE_IF_UNREFERENCED const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",
308 Token.getAutogendatumTypeString(token.datumType),
309 token.cName,
310 token.cName
311 );
312 hAutoGenString += String.format(
313 "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n",
314 Token.GetAutogenDefinedatumTypeString(token.datumType),
315 token.cName,
316 token.cName
317 );
318 break;
319 case PATCHABLE_IN_MODULE:
320 hAutoGenString += String.format(
321 "#define _PCD_VALUE_%s %s\r\n",
322 token.cName,
323 token.datum.toString()
324 );
325 hAutoGenString += String.format(
326 "extern %s _gPcd_BinaryPatch_%s;\r\n",
327 Token.getAutogendatumTypeString(token.datumType),
328 token.cName
329 );
330 cAutoGenString += String.format(
331 "GLOBAL_REMOVE_IF_UNREFERENCED %s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;\r\n",
332 Token.getAutogendatumTypeString(token.datumType),
333 token.cName,
334 token.cName
335 );
336 hAutoGenString += String.format(
337 "#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n",
338 Token.GetAutogenDefinedatumTypeString(token.datumType),
339 token.cName,
340 token.cName
341 );
342 break;
343 case DYNAMIC:
344 hAutoGenString += String.format(
345 "#define _PCD_MODE_%s_%s LibPcdGet%s(_PCD_TOKEN_%s)\r\n",
346 Token.GetAutogenDefinedatumTypeString(token.datumType),
347 token.cName,
348 Token.getAutogenLibrarydatumTypeString(token.datumType),
349 token.cName
350 );
351 break;
352 case DYNAMIC_EX:
353 break;
354 default:
355 ActionMessage.warning(this,
356 "The PCD_TYPE setted by platform is unknown"
357 );
358 }
359
360 hAutoGenString += "\r\n";
361 cAutoGenString += "\r\n";
362 }
363
364 /**
365 Generate PCDEmulated array in PCDEmulated driver for emulated runtime database.
366
367 @param tokenArray All PCD token in memory database.
368
369 @throws BuildActionException Unknown PCD_TYPE
370 **/
371 private void generatePCDEmulatedArray(Token[] tokenArray)
372 throws BuildActionException {
373 int index;
374 Token token;
375 String[] guidStrArray;
376 String value;
377
378 //
379 // The value of String type of PCD entry maybe use byte array but not string direcly
380 // such as {0x1, 0x2, 0x3}, and define PCD1_STRING_Value as L"string define here"
381 // For this case, we should generate a string array to C output and use the address
382 // of generated string array.
383 //
384 for(index = 0; index < tokenArray.length; index ++) {
385 token = tokenArray[index];
386
387 value = token.datum.toString();
388 if(token.datumType == Token.DATUM_TYPE.POINTER) {
389 if(!((value.charAt(0) == 'L' && value.charAt(1) == '"') ||(value.charAt(0) == '"'))) {
390 cAutoGenString += String.format("UINT8 _mPcdArray%08x[] = %s;\r\n",
391 index,
392 value
393 );
394 }
395 }
396 }
397
398 //
399 // Output emulated PCD entry array
400 //
401 cAutoGenString += "\r\nEMULATED_PCD_ENTRY gEmulatedPcdEntry[] = {\r\n";
402
403 for(index = 0; index < tokenArray.length; index ++) {
404 token = tokenArray[index];
405
406 if(index != 0) {
407 cAutoGenString += ",\r\n";
408 }
409
410 //
411 // Print Start "{" for a Token item in array
412 //
413 cAutoGenString += " {\r\n";
414
415 //
416 // Print Token Name
417 //
418 cAutoGenString += String.format(" _PCD_TOKEN_%s,\r\n", token.cName);
419
420 //
421 // Print Hii information
422 //
423 if(token.hiiEnabled) {
424 cAutoGenString += String.format(" TRUE,\r\n");
425 } else {
426 cAutoGenString += String.format(" FALSE,\r\n");
427 }
428
429 //
430 // Print sku information
431 //
432 if(token.skuEnabled) {
433 cAutoGenString += String.format(" TRUE,\r\n");
434 } else {
435 cAutoGenString += String.format(" FALSE,\r\n");
436 }
437
438 //
439 // Print maxSkuCount
440 //
441 cAutoGenString += String.format(" %d,\r\n", token.maxSkuCount);
442
443 cAutoGenString += String.format(" %d,\r\n", token.skuId);
444
445 if(token.variableGuid == null) {
446 cAutoGenString += " { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\r\n";
447 } else {
448 guidStrArray =(token.variableGuid.toString()).split("-");
449
450 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",
451 guidStrArray[0],
452 guidStrArray[1],
453 guidStrArray[2],
454 (guidStrArray[3].substring(0, 2)),
455 (guidStrArray[3].substring(2, 4)),
456 (guidStrArray[4].substring(0, 2)),
457 (guidStrArray[4].substring(2, 4)),
458 (guidStrArray[4].substring(4, 6)),
459 (guidStrArray[4].substring(6, 8)),
460 (guidStrArray[4].substring(8, 10)),
461 (guidStrArray[4].substring(10, 12))
462 );
463
464 }
465
466 value = token.datum.toString();
467 if(token.datumType == Token.DATUM_TYPE.POINTER) {
468 if((value.charAt(0) == 'L' && value.charAt(1) == '"') || value.charAt(0) == '"') {
469 cAutoGenString += String.format(" sizeof(_PCD_VALUE_%s),\r\n", token.cName);
470 cAutoGenString += String.format(" 0, %s, %s,\r\n", token.variableName, value);
471 } else {
472 cAutoGenString += String.format(" sizeof(_mPcdArray%08x),\r\n", index);
473 cAutoGenString += String.format(" 0, &_mPcdArray%08x, %s,\r\n", index, token.variableName);
474 }
475 } else {
476 switch(token.datumType) {
477 case UINT8:
478 cAutoGenString += " 1,\r\n";
479 break;
480 case UINT16:
481 cAutoGenString += " 2,\r\n";
482 break;
483 case UINT32:
484 cAutoGenString += " 4,\r\n";
485 break;
486 case UINT64:
487 cAutoGenString += " 8,\r\n";
488 break;
489 case BOOLEAN:
490 cAutoGenString += " 1,\r\n";
491 break;
492 default:
493 throw new BuildActionException("Unknown datum size");
494 }
495 cAutoGenString += String.format(" %s, %s, NULL,\r\n", value, token.variableName);
496 }
497
498 //
499 // Print end "}" for a token item in array
500 //
501 cAutoGenString += " }";
502 }
503
504 cAutoGenString += "\r\n};\r\n";
505 cAutoGenString += "\r\n";
506 cAutoGenString += "UINTN\r\n";
507 cAutoGenString += "GetPcdDataBaseSize(\r\n";
508 cAutoGenString += " VOID\r\n";
509 cAutoGenString += " )\r\n";
510 cAutoGenString += "{\r\n";
511 cAutoGenString += " return sizeof(gEmulatedPcdEntry);\r\n";
512 cAutoGenString += "}\r\n";
513 }
514
515 /**
516 Test case function
517
518 @param argv paramter from command line
519 **/
520 public static void main(String argv[]) {
521 String logFilePath = "M:/tianocore/edk2/trunk/edk2/EdkNt32Pkg/Nt32.fpd";
522
523 //
524 // At first, CollectPCDAction should be invoked to collect
525 // all PCD information from SPD, MSA, FPD.
526 //
527 CollectPCDAction collectionAction = new CollectPCDAction();
528 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
529 "M:/tianocore/edk2/trunk/edk2");
530
531 GlobalData.getPCDMemoryDBManager().setLogFileName(logFilePath + ".PCDMemroyDatabaseLog.txt");
532
533 try {
534 collectionAction.perform("M:/tianocore/edk2/trunk/edk2",
535 logFilePath,
536 ActionMessage.MAX_MESSAGE_LEVEL);
537 } catch(Exception e) {
538 e.printStackTrace();
539 }
540
541 //
542 // Then execute the PCDAuotoGenAction to get generated Autogen.h and Autogen.c
543 //
544 PCDAutoGenAction autogenAction = new PCDAutoGenAction("PcdEmulator",
545 true
546 );
547 autogenAction.execute();
548 System.out.println (autogenAction.hAutoGenString);
549 System.out.println (autogenAction.cAutoGenString);
550
551 }
552 }