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