]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
Fix the bug that using hardcode driver name to judge whether current driver is PCD...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / autogen / AutoGen.java
CommitLineData
878ddf1f 1/** @file\r
2 AutoGen class.\r
3\r
4 This class is to generate Autogen.h and Autogen.c according to module surface area\r
5 or library surface area.\r
ff225cbb 6\r
878ddf1f 7 Copyright (c) 2006, Intel Corporation\r
8 All rights reserved. This program and the accompanying materials\r
9 are licensed and made available under the terms and conditions of the BSD License\r
10 which accompanies this distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
ff225cbb 12\r
878ddf1f 13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16 **/\r
17\r
18package org.tianocore.build.autogen;\r
19\r
878ddf1f 20import java.io.File;\r
73b4e31a 21import java.io.FileInputStream;\r
22import java.io.FileOutputStream;\r
878ddf1f 23import java.io.FileReader;\r
24import java.io.FileWriter;\r
25import java.util.ArrayList;\r
a29c47e0 26import java.util.HashSet;\r
27import java.util.Iterator;\r
893cea14 28import java.util.LinkedHashSet;\r
136adffc 29import java.util.LinkedList;\r
878ddf1f 30import java.util.List;\r
31import java.util.Map;\r
a29c47e0 32import java.util.Set;\r
878ddf1f 33\r
73b4e31a 34import org.apache.tools.ant.BuildException;\r
35import org.apache.xmlbeans.XmlObject;\r
36import org.tianocore.GuidsDocument;\r
37import org.tianocore.LibraryClassDocument.LibraryClass;\r
38import org.tianocore.PPIsDocument;\r
39import org.tianocore.ProtocolsDocument;\r
40import org.tianocore.build.exception.*;\r
41import org.tianocore.build.global.GlobalData;\r
42import org.tianocore.build.global.Spd;\r
43import org.tianocore.build.global.SurfaceAreaQuery;\r
44import org.tianocore.build.id.ModuleIdentification;\r
45import org.tianocore.build.id.PackageIdentification;\r
46import org.tianocore.build.pcd.action.PCDAutoGenAction;\r
ff225cbb 47\r
48import org.tianocore.common.logger.EdkLog;\r
73b4e31a 49\r
878ddf1f 50/**\r
a29c47e0 51 * This class is to generate Autogen.h and Autogen.c according to module surface\r
52 * area or library surface area.\r
53 */\r
878ddf1f 54public class AutoGen {\r
5f907e4a 55 ///\r
56 /// The output path of Autogen.h and Autogen.c\r
57 ///\r
58 private String outputPath;\r
59\r
ff225cbb 60 ///\r
61 /// The name of FV directory\r
62 ///\r
73b4e31a 63 private String fvDir;\r
5f907e4a 64\r
65 ///\r
66 /// The base name of module or library.\r
67 ///\r
68 private ModuleIdentification moduleId;\r
69\r
70 ///\r
71 /// The build architecture\r
72 ///\r
73 private String arch;\r
74\r
75 ///\r
76 /// PcdAutogen instance which is used to manage how to generate the PCD\r
77 /// information.\r
78 ///\r
79 private PCDAutoGenAction myPcdAutogen;\r
80\r
81 ///\r
82 /// the one of type : NOT_PCD_DRIVER, PEI_PCD_DRIVER, DXE_PCD_DRIVER\r
83 /// \r
84 private CommonDefinition.PCD_DRIVER_TYPE pcdDriverType;\r
85\r
86 ///\r
87 /// The protocl list which records in module or library surface area and\r
88 /// it's dependence on library instance surface area.\r
89 ///\r
90 private Set<String> mProtocolList = new HashSet<String>();\r
91\r
92 ///\r
93 /// The Ppi list which recorded in module or library surface area and its\r
94 /// dependency on library instance surface area.\r
95 ///\r
96 private Set<String> mPpiList = new HashSet<String>();\r
97\r
98 ///\r
99 /// The Guid list which recoreded in module or library surface area and it's\r
100 /// dependence on library instance surface area.\r
101 ///\r
102 private Set<String> mGuidList = new HashSet<String>();\r
ff225cbb 103\r
136adffc 104 //\r
105 // The dependence package list which recoreded in module or library surface\r
106 // area and it's dependence on library instance surface are.\r
107 //\r
108 private List<PackageIdentification> mDepPkgList = new LinkedList<PackageIdentification>();\r
2336382f 109\r
5f907e4a 110 //\r
111 // For non library module, add its library instance's construct and destructor to\r
112 // list.\r
113 //\r
114 private List<String> libConstructList = new ArrayList<String>();\r
115 private List<String> libDestructList = new ArrayList<String>();\r
116\r
117 //\r
118 // List to store SetVirtalAddressMapCallBack, ExitBootServiceCallBack\r
119 //\r
120 private List<String> setVirtalAddList = new ArrayList<String>();\r
121 private List<String> exitBootServiceList = new ArrayList<String>();\r
122\r
123\r
124 /**\r
125 * Construct function\r
126 *\r
127 * This function mainly initialize some member variable.\r
128 *\r
129 * @param outputPath\r
130 * Output path of AutoGen file.\r
131 * @param baseName\r
132 * Module base name.\r
133 * @param arch\r
134 * Target architecture.\r
135 */\r
136 public AutoGen(String fvDir, String outputPath, ModuleIdentification moduleId, String arch) {\r
137 this.outputPath = outputPath;\r
138 this.moduleId = moduleId;\r
139 this.arch = arch;\r
73b4e31a 140 this.fvDir = fvDir;\r
136adffc 141\r
5f907e4a 142 }\r
143\r
144 /**\r
145 * saveFile function\r
146 *\r
147 * This function save the content in stringBuffer to file.\r
148 *\r
149 * @param fileName\r
150 * The name of file.\r
151 * @param fileBuffer\r
152 * The content of AutoGen file in buffer.\r
153 * @return "true" successful, "false" failed.\r
154 */\r
155 private boolean saveFile(String fileName, StringBuffer fileBuffer) {\r
156 try {\r
157 File autoGenH = new File(fileName);\r
158\r
159 //\r
160 // if the file exists, compare their content\r
161 //\r
162 if (autoGenH.exists()) {\r
163 FileReader fIn = new FileReader(autoGenH);\r
164 char[] oldFileBuffer = new char[(int) autoGenH.length()];\r
165 fIn.read(oldFileBuffer, 0, (int) autoGenH.length());\r
166 fIn.close();\r
167\r
168 //\r
169 // if we got the same file, don't re-generate it to prevent\r
170 // sources depending on it from re-building\r
171 //\r
172 if (fileBuffer.toString().compareTo(new String(oldFileBuffer)) == 0) {\r
173 return true;\r
174 }\r
175 }\r
176 FileWriter fOut = new FileWriter(autoGenH);\r
177 fOut.write(fileBuffer.toString());\r
178 fOut.close();\r
179 } catch (Exception e) {\r
180 return false;\r
181 }\r
182 return true;\r
183 }\r
184\r
185 /**\r
186 * genAutogen function\r
187 *\r
188 * This function call libGenAutoGen or moduleGenAutogen function, which\r
189 * dependence on generate library autogen or module autogen.\r
190 *\r
191 * @throws BuildException\r
192 * Failed to creat AutoGen.c & AutoGen.h.\r
193 */\r
194 public void genAutogen() throws BuildException {\r
195 try {\r
196 //\r
197 // If outputPath do not exist, create it.\r
198 //\r
199 File path = new File(outputPath);\r
200 path.mkdirs();\r
201\r
202 //\r
203 // Check current is library or not, then call the corresponding\r
204 // function.\r
205 //\r
206 if (this.moduleId.isLibrary()) {\r
207 libGenAutogen();\r
208 } else {\r
209 moduleGenAutogen();\r
210 }\r
211\r
212 } catch (Exception e) {\r
213 throw new BuildException(\r
214 "Failed to create AutoGen.c & AutoGen.h!\n"\r
215 + e.getMessage());\r
216 }\r
217 }\r
218\r
219 /**\r
220 * moduleGenAutogen function\r
221 *\r
222 * This function generates AutoGen.c & AutoGen.h for module.\r
223 *\r
224 * @throws BuildException\r
225 * Faile to create module AutoGen.c & AutoGen.h.\r
226 */\r
227 void moduleGenAutogen() throws BuildException {\r
228\r
229 try {\r
230 collectLibInstanceInfo();\r
231 moduleGenAutogenC();\r
232 moduleGenAutogenH();\r
233 } catch (Exception e) {\r
234 throw new BuildException(\r
235 "Faile to create module AutoGen.c & AutoGen.h!\n"\r
236 + e.getMessage());\r
237 }\r
238 }\r
239\r
240 /**\r
241 * libGenAutogen function\r
242 *\r
243 * This function generates AutoGen.c & AutoGen.h for library.\r
244 *\r
245 * @throws BuildException\r
246 * Faile to create library AutoGen.c & AutoGen.h\r
247 */\r
248 void libGenAutogen() throws BuildException {\r
249 try {\r
250 libGenAutogenC();\r
251 libGenAutogenH();\r
252 } catch (Exception e) {\r
253 throw new BuildException(\r
254 "Failed to create library AutoGen.c & AutoGen.h!\n"\r
255 + e.getMessage());\r
256 }\r
257 }\r
258\r
259 /**\r
260 * moduleGenAutogenH\r
261 *\r
262 * This function generates AutoGen.h for module.\r
263 *\r
264 * @throws BuildException\r
265 * Failed to generate AutoGen.h.\r
266 */\r
267 void moduleGenAutogenH() throws AutoGenException {\r
268\r
269 Set<String> libClassIncludeH;\r
270 String moduleType;\r
271 // List<String> headerFileList;\r
272 List<String> headerFileList;\r
273 Iterator item;\r
274 StringBuffer fileBuffer = new StringBuffer(8192);\r
275\r
276 //\r
277 // Write Autogen.h header notation\r
278 //\r
279 fileBuffer.append(CommonDefinition.autogenHNotation);\r
280\r
281 //\r
282 // Add #ifndef ${BaseName}_AUTOGENH\r
283 // #def ${BseeName}_AUTOGENH\r
284 //\r
285 fileBuffer.append("#ifndef " + "_AUTOGENH_" + this.moduleId.getGuid().replaceAll("-", "_") +"\r\n");\r
286 fileBuffer.append("#define " + "_AUTOGENH_" + this.moduleId.getGuid().replaceAll("-", "_") +"\r\n\r\n");\r
287\r
288 //\r
289 // Write the specification version and release version at the begine\r
290 // of autogen.h file.\r
291 // Note: the specification version and release version should\r
292 // be got from module surface area instead of hard code by it's\r
293 // moduleType.\r
294 //\r
295 moduleType = SurfaceAreaQuery.getModuleType();\r
296\r
297 //\r
298 // Add "extern int __make_me_compile_correctly;" at begin of\r
299 // AutoGen.h.\r
300 //\r
301 fileBuffer.append(CommonDefinition.autoGenHbegin);\r
136adffc 302\r
303 //\r
304 // Put EFI_SPECIFICATION_VERSION, and EDK_RELEASE_VERSION.\r
878ddf1f 305 //\r
a29c47e0 306 String[] specList = SurfaceAreaQuery.getExternSpecificaiton();\r
136adffc 307 for (int i = 0; i < specList.length; i++) {\r
308 fileBuffer.append(CommonDefinition.marcDefineStr + specList[i]\r
5f907e4a 309 + "\r\n");\r
310 }\r
311 //\r
312 // Write consumed package's mdouleInfo related .h file to autogen.h\r
313 //\r
314 // PackageIdentification[] consumedPkgIdList = SurfaceAreaQuery\r
315 // .getDependencePkg(this.arch);\r
316 PackageIdentification[] consumedPkgIdList = SurfaceAreaQuery\r
317 .getDependencePkg(this.arch);\r
318 if (consumedPkgIdList != null) {\r
319 headerFileList = depPkgToAutogenH(consumedPkgIdList, moduleType);\r
320 item = headerFileList.iterator();\r
321 while (item.hasNext()) {\r
322 fileBuffer.append(item.next().toString());\r
323 }\r
324 }\r
325\r
326 //\r
327 // Write library class's related *.h file to autogen.h.\r
328 //\r
329 String[] libClassList = SurfaceAreaQuery\r
330 .getLibraryClasses(CommonDefinition.AlwaysConsumed,this.arch);\r
331 if (libClassList != null) {\r
332 libClassIncludeH = LibraryClassToAutogenH(libClassList);\r
333 item = libClassIncludeH.iterator();\r
334 while (item.hasNext()) {\r
335 fileBuffer.append(item.next().toString());\r
336 }\r
878ddf1f 337 }\r
5f907e4a 338\r
339 libClassList = SurfaceAreaQuery\r
340 .getLibraryClasses(CommonDefinition.AlwaysProduced, this.arch);\r
341 if (libClassList != null) {\r
342 libClassIncludeH = LibraryClassToAutogenH(libClassList);\r
343 item = libClassIncludeH.iterator();\r
344 while (item.hasNext()) {\r
345 fileBuffer.append(item.next().toString());\r
346 }\r
347 }\r
348 fileBuffer.append("\r\n");\r
136adffc 349\r
73b4e31a 350 //\r
ff225cbb 351 // If is TianoR8FlashMap, copy {Fv_DIR}/FlashMap.h to\r
73b4e31a 352 // {DEST_DIR_DRBUG}/FlashMap.h\r
ff225cbb 353 //\r
73b4e31a 354 if (SurfaceAreaQuery.isHaveTianoR8FlashMap()) {\r
355 fileBuffer.append(CommonDefinition.include);\r
356 fileBuffer.append(" <");\r
357 fileBuffer.append(CommonDefinition.tianoR8FlashMapH + ">\r\n");\r
358 copyFlashMapHToDebugDir();\r
359 }\r
360\r
5f907e4a 361 // Write PCD autogen information to AutoGen.h.\r
362 //\r
363 if (this.myPcdAutogen != null) {\r
136adffc 364 fileBuffer.append("\r\n");\r
5f907e4a 365 fileBuffer.append(this.myPcdAutogen.OutputH());\r
366 }\r
367\r
368 //\r
369 // Append the #endif at AutoGen.h\r
370 //\r
371 fileBuffer.append("#endif\r\n");\r
372\r
373 //\r
374 // Save string buffer content in AutoGen.h.\r
375 //\r
376 if (!saveFile(outputPath + File.separatorChar + "AutoGen.h", fileBuffer)) {\r
377 throw new BuildException("Failed to generate AutoGen.h !!!");\r
378 }\r
379 }\r
380\r
381 /**\r
382 * moduleGenAutogenC\r
383 *\r
384 * This function generates AutoGen.c for module.\r
385 *\r
386 * @throws BuildException\r
387 * Failed to generate AutoGen.c.\r
388 */\r
389 void moduleGenAutogenC() throws AutoGenException {\r
390\r
391 StringBuffer fileBuffer = new StringBuffer(8192);\r
392 //\r
393 // Write Autogen.c header notation\r
394 //\r
395 fileBuffer.append(CommonDefinition.autogenCNotation);\r
396\r
397 //\r
398 // Write #include <AutoGen.h> at beginning of AutoGen.c\r
399 //\r
400 fileBuffer.append(CommonDefinition.includeAutogenH);\r
401\r
402 //\r
403 // Get the native MSA file infomation. Since before call autogen,\r
404 // the MSA native <Externs> information were overrided. So before\r
405 // process <Externs> it should be set the DOC as the Native MSA info.\r
406 //\r
407 Map<String, XmlObject> doc = GlobalData.getNativeMsa(this.moduleId);\r
408 SurfaceAreaQuery.push(doc);\r
409 //\r
410 // Write <Extern>\r
411 // DriverBinding/ComponentName/DriverConfiguration/DriverDialog\r
412 // to AutoGen.c\r
413 //\r
414\r
415 ExternsDriverBindingToAutoGenC(fileBuffer);\r
416\r
417 //\r
418 // Write DriverExitBootServicesEvent/DriverSetVirtualAddressMapEvent\r
419 // to Autogen.c\r
420 //\r
421 ExternCallBackToAutoGenC(fileBuffer);\r
422\r
423 //\r
424 // Write EntryPoint to autgoGen.c\r
425 //\r
426 String[] entryPointList = SurfaceAreaQuery.getModuleEntryPointArray();\r
427 EntryPointToAutoGen(CommonDefinition.remDupString(entryPointList), fileBuffer);\r
428\r
429 pcdDriverType = SurfaceAreaQuery.getPcdDriverType();\r
430\r
431 //\r
432 // Restore the DOC which include the FPD module info.\r
433 //\r
434 SurfaceAreaQuery.pop();\r
435\r
436 //\r
437 // Write Guid to autogen.c\r
438 //\r
439 String guid = CommonDefinition.formatGuidName(SurfaceAreaQuery\r
440 .getModuleGuid());\r
441\r
442 fileBuffer\r
443 .append("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiCallerIdGuid = {");\r
444 if (guid == null) {\r
445 throw new AutoGenException("Guid value must set!\n");\r
446 }\r
447\r
448 //\r
449 // Formate Guid as ANSI c form.Example:\r
450 // {0xd2b2b828, 0x826, 0x48a7,{0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24,\r
451 // 0xf0}}\r
452 //\r
453\r
454 fileBuffer.append(guid);\r
455 fileBuffer.append("};\r\n");\r
456\r
457 //\r
458 // Generate library instance consumed protocol, guid, ppi, pcd list.\r
459 // Save those to this.protocolList, this.ppiList, this.pcdList,\r
460 // this.guidList. Write Consumed library constructor and desconstuct to\r
461 // autogen.c\r
462 //\r
136adffc 463 LibInstanceToAutogenC(fileBuffer);\r
ff225cbb 464\r
878ddf1f 465 //\r
136adffc 466 // Get module dependent Package identification.\r
878ddf1f 467 //\r
136adffc 468 PackageIdentification[] packages = SurfaceAreaQuery.getDependencePkg(this.arch);\r
5f907e4a 469 for (int i = 0; i < packages.length; i++) {\r
470 if (!this.mDepPkgList.contains(packages[i])) {\r
136adffc 471 this.mDepPkgList.add(packages[i]);\r
878ddf1f 472 }\r
ff225cbb 473\r
136adffc 474 }\r
ff225cbb 475\r
5f907e4a 476 //\r
477 // Write consumed ppi, guid, protocol to autogen.c\r
478 //\r
479 ProtocolGuidToAutogenC(fileBuffer);\r
480 PpiGuidToAutogenC(fileBuffer);\r
481 GuidGuidToAutogenC(fileBuffer);\r
ff225cbb 482\r
5f907e4a 483 //\r
484 // Call pcd autogen.\r
485 //\r
486 this.myPcdAutogen = new PCDAutoGenAction(moduleId, \r
487 arch, \r
488 false, \r
489 null,\r
490 pcdDriverType);\r
491 try {\r
492 this.myPcdAutogen.execute();\r
493 } catch (Exception exp) {\r
494 throw new PcdAutogenException (exp.getMessage());\r
495 }\r
496\r
497 if (this.myPcdAutogen != null) {\r
498 fileBuffer.append("\r\n");\r
499 fileBuffer.append(this.myPcdAutogen.OutputC());\r
500 }\r
501\r
502 if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {\r
503 throw new BuildException("Failed to generate AutoGen.c !!!");\r
504 }\r
505\r
506 }\r
507\r
508 /**\r
509 * libGenAutogenH\r
510 *\r
511 * This function generates AutoGen.h for library.\r
512 *\r
513 * @throws BuildException\r
514 * Failed to generate AutoGen.c.\r
515 */\r
516 void libGenAutogenH() throws AutoGenException {\r
517\r
518 Set<String> libClassIncludeH;\r
519 String moduleType;\r
520 List<String> headerFileList;\r
521 Iterator item;\r
522 StringBuffer fileBuffer = new StringBuffer(10240);\r
523\r
524 //\r
525 // Write Autogen.h header notation\r
526 //\r
527 fileBuffer.append(CommonDefinition.autogenHNotation);\r
528\r
529 //\r
530 // Add #ifndef ${BaseName}_AUTOGENH\r
531 // #def ${BseeName}_AUTOGENH\r
532 //\r
533 fileBuffer.append("#ifndef " + "_AUTOGENH_" + this.moduleId.getGuid().replaceAll("-", "_") + "\r\n");\r
534 fileBuffer.append("#define " + "_AUTOGENH_" + this.moduleId.getGuid().replaceAll("-", "_") + "\r\n\r\n");\r
535\r
536 //\r
537 // Write EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION\r
538 // to autogen.h file.\r
539 // Note: the specification version and release version should\r
540 // be get from module surface area instead of hard code.\r
541 //\r
542 fileBuffer.append(CommonDefinition.autoGenHbegin);\r
543 String[] specList = SurfaceAreaQuery.getExternSpecificaiton();\r
544 for (int i = 0; i < specList.length; i++) {\r
545 fileBuffer.append(CommonDefinition.marcDefineStr + specList[i]\r
546 + "\r\n");\r
547 }\r
548 // fileBuffer.append(CommonDefinition.autoGenHLine1);\r
549 // fileBuffer.append(CommonDefinition.autoGenHLine2);\r
550\r
551 //\r
552 // Write consumed package's mdouleInfo related *.h file to autogen.h.\r
553 //\r
554 moduleType = SurfaceAreaQuery.getModuleType();\r
555 PackageIdentification[] cosumedPkglist = SurfaceAreaQuery\r
556 .getDependencePkg(this.arch);\r
557 headerFileList = depPkgToAutogenH(cosumedPkglist, moduleType);\r
558 item = headerFileList.iterator();\r
559 while (item.hasNext()) {\r
560 fileBuffer.append(item.next().toString());\r
561 }\r
562 //\r
563 // Write library class's related *.h file to autogen.h\r
564 //\r
565 String[] libClassList = SurfaceAreaQuery\r
566 .getLibraryClasses(CommonDefinition.AlwaysConsumed, this.arch);\r
567 if (libClassList != null) {\r
568 libClassIncludeH = LibraryClassToAutogenH(libClassList);\r
569 item = libClassIncludeH.iterator();\r
570 while (item.hasNext()) {\r
571 fileBuffer.append(item.next().toString());\r
572 }\r
573 }\r
574\r
575 libClassList = SurfaceAreaQuery\r
576 .getLibraryClasses(CommonDefinition.AlwaysProduced, this.arch);\r
577 if (libClassList != null) {\r
578 libClassIncludeH = LibraryClassToAutogenH(libClassList);\r
579 item = libClassIncludeH.iterator();\r
580 while (item.hasNext()) {\r
581 fileBuffer.append(item.next().toString());\r
582 }\r
583 }\r
584 fileBuffer.append("\r\n");\r
136adffc 585\r
73b4e31a 586 //\r
ff225cbb 587 // If is TianoR8FlashMap, copy {Fv_DIR}/FlashMap.h to\r
73b4e31a 588 // {DEST_DIR_DRBUG}/FlashMap.h\r
ff225cbb 589 //\r
73b4e31a 590 if (SurfaceAreaQuery.isHaveTianoR8FlashMap()) {\r
591 fileBuffer.append(CommonDefinition.include);\r
592 fileBuffer.append(" <");\r
593 fileBuffer.append(CommonDefinition.tianoR8FlashMapH + ">\r\n");\r
594 copyFlashMapHToDebugDir();\r
595 }\r
596\r
5f907e4a 597 //\r
598 // Write PCD information to library AutoGen.h.\r
599 //\r
600 if (this.myPcdAutogen != null) {\r
136adffc 601 fileBuffer.append("\r\n");\r
5f907e4a 602 fileBuffer.append(this.myPcdAutogen.OutputH());\r
603 }\r
604\r
605 //\r
606 // Append the #endif at AutoGen.h\r
607 //\r
608 fileBuffer.append("#endif\r\n");\r
609\r
610 //\r
611 // Save content of string buffer to AutoGen.h file.\r
612 //\r
613 if (!saveFile(outputPath + File.separatorChar + "AutoGen.h", fileBuffer)) {\r
614 throw new BuildException("Failed to generate AutoGen.h !!!");\r
615 }\r
616 }\r
617\r
618 /**\r
619 * libGenAutogenC\r
620 *\r
621 * This function generates AutoGen.h for library.\r
622 *\r
623 * @throws BuildException\r
624 * Failed to generate AutoGen.c.\r
625 */\r
626 void libGenAutogenC() throws BuildException, PcdAutogenException {\r
627 StringBuffer fileBuffer = new StringBuffer(10240);\r
628\r
629 //\r
630 // Write Autogen.c header notation\r
631 //\r
632 fileBuffer.append(CommonDefinition.autogenCNotation);\r
633\r
634 fileBuffer.append(CommonDefinition.autoGenCLine1);\r
635 fileBuffer.append("\r\n");\r
636\r
637 //\r
638 // Call pcd autogen.\r
639 //\r
640 this.myPcdAutogen = new PCDAutoGenAction(moduleId,\r
641 arch,\r
642 true,\r
643 SurfaceAreaQuery.getModulePcdEntryNameArray(),\r
644 pcdDriverType);\r
645 try {\r
646 this.myPcdAutogen.execute();\r
647 } catch (Exception e) {\r
648 throw new PcdAutogenException(e.getMessage());\r
649 }\r
650\r
651 if (this.myPcdAutogen != null) {\r
652 fileBuffer.append("\r\n");\r
653 fileBuffer.append(this.myPcdAutogen.OutputC());\r
654 }\r
655\r
656 if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {\r
657 throw new BuildException("Failed to generate AutoGen.c !!!");\r
658 }\r
659 }\r
660\r
661 /**\r
662 * LibraryClassToAutogenH\r
663 *\r
664 * This function returns *.h files declared by library classes which are\r
665 * consumed or produced by current build module or library.\r
666 *\r
667 * @param libClassList\r
668 * List of library class which consumed or produce by current\r
669 * build module or library.\r
670 * @return includeStrList List of *.h file.\r
671 */\r
672 Set<String> LibraryClassToAutogenH(String[] libClassList)\r
673 throws AutoGenException {\r
674 Set<String> includStrList = new LinkedHashSet<String>();\r
675 String includerName[];\r
676 String str = "";\r
677\r
678 //\r
679 // Get include file from GlobalData's SPDTable according to\r
680 // library class name.\r
681 //\r
682\r
683 for (int i = 0; i < libClassList.length; i++) {\r
684 includerName = GlobalData.getLibraryClassHeaderFiles(\r
685 SurfaceAreaQuery.getDependencePkg(this.arch),\r
686 libClassList[i]);\r
687 if (includerName == null) {\r
688 throw new AutoGenException("Can not find library class ["\r
689 + libClassList[i] + "] declaration in any SPD package. ");\r
690 }\r
691 for (int j = 0; j < includerName.length; j++) {\r
692 String includeNameStr = includerName[j];\r
693 if (includeNameStr != null) {\r
694 str = CommonDefinition.include + " " + "<";\r
695 str = str + includeNameStr + ">\r\n";\r
696 includStrList.add(str);\r
697 includeNameStr = null;\r
878ddf1f 698 }\r
5f907e4a 699 }\r
700 }\r
701 return includStrList;\r
702 }\r
703\r
704 /**\r
705 * IncludesToAutogenH\r
706 *\r
707 * This function add include file in AutoGen.h file.\r
708 *\r
709 * @param packageNameList\r
710 * List of module depended package.\r
711 * @param moduleType\r
712 * Module type.\r
713 * @return\r
714 */\r
715 List<String> depPkgToAutogenH(PackageIdentification[] packageNameList,\r
716 String moduleType) throws AutoGenException {\r
717\r
718 List<String> includeStrList = new LinkedList<String>();\r
719 String pkgHeader;\r
720 String includeStr = "";\r
721\r
722 //\r
723 // Get include file from moduleInfo file\r
724 //\r
725 for (int i = 0; i < packageNameList.length; i++) {\r
726 pkgHeader = GlobalData.getPackageHeaderFiles(packageNameList[i],\r
727 moduleType);\r
728 if (pkgHeader == null) {\r
729 throw new AutoGenException("Can not find package ["\r
730 + packageNameList[i]\r
731 + "] declaration in any SPD package. ");\r
732 } else if (!pkgHeader.equalsIgnoreCase("")) {\r
733 includeStr = CommonDefinition.include + " <" + pkgHeader\r
734 + ">\r\n";\r
735 includeStrList.add(includeStr);\r
736 }\r
737 }\r
738\r
739 return includeStrList;\r
740 }\r
741\r
742 /**\r
743 * EntryPointToAutoGen\r
744 *\r
745 * This function convert <ModuleEntryPoint> & <ModuleUnloadImage>\r
746 * information in mas to AutoGen.c\r
747 *\r
748 * @param entryPointList\r
749 * List of entry point.\r
750 * @param fileBuffer\r
751 * String buffer fo AutoGen.c.\r
752 * @throws Exception\r
753 */\r
754 void EntryPointToAutoGen(String[] entryPointList, StringBuffer fileBuffer)\r
755 throws BuildException {\r
756\r
757 String typeStr = SurfaceAreaQuery.getModuleType();\r
758\r
759 //\r
760 // The parameters and return value of entryPoint is difference\r
761 // for difference module type.\r
762 //\r
763 switch (CommonDefinition.getModuleType(typeStr)) {\r
764 \r
765 case CommonDefinition.ModuleTypePeiCore:\r
766 if (entryPointList == null ||entryPointList.length != 1 ) {\r
767 throw new BuildException(\r
768 "Module type = 'PEI_CORE', can have only one module entry point!");\r
769 } else {\r
770 fileBuffer.append("EFI_STATUS\r\n");\r
771 fileBuffer.append("EFIAPI\r\n");\r
772 fileBuffer.append(entryPointList[0]);\r
773 fileBuffer.append(" (\r\n");\r
136adffc 774 fileBuffer\r
5f907e4a 775 .append(" IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,\r\n");\r
136adffc 776 fileBuffer\r
5f907e4a 777 .append(" IN VOID *OldCoreData\r\n");\r
778 fileBuffer.append(" );\r\n\r\n");\r
136adffc 779\r
780 fileBuffer.append("EFI_STATUS\r\n");\r
781 fileBuffer.append("EFIAPI\r\n");\r
782 fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
5f907e4a 783 fileBuffer\r
784 .append(" IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,\r\n");\r
785 fileBuffer\r
786 .append(" IN VOID *OldCoreData\r\n");\r
136adffc 787 fileBuffer.append(" )\r\n\r\n");\r
788 fileBuffer.append("{\r\n");\r
5f907e4a 789 fileBuffer.append(" return ");\r
790 fileBuffer.append(entryPointList[0]);\r
791 fileBuffer.append(" (PeiStartupDescriptor, OldCoreData);\r\n");\r
792 fileBuffer.append("}\r\n\r\n");\r
793 }\r
794 break;\r
878ddf1f 795\r
5f907e4a 796 case CommonDefinition.ModuleTypeDxeCore:\r
797 fileBuffer.append("const UINT32 _gUefiDriverRevision = 0;\r\n");\r
798 if (entryPointList == null || entryPointList.length != 1) {\r
799 throw new BuildException(\r
800 "Module type = 'DXE_CORE', can have only one module entry point!");\r
801 } else {\r
ff225cbb 802\r
5f907e4a 803 fileBuffer.append("VOID\r\n");\r
804 fileBuffer.append("EFIAPI\r\n");\r
805 fileBuffer.append(entryPointList[0]);\r
806 fileBuffer.append(" (\n");\r
807 fileBuffer.append(" IN VOID *HobStart\r\n");\r
808 fileBuffer.append(" );\r\n\r\n");\r
809\r
810 fileBuffer.append("VOID\r\n");\r
811 fileBuffer.append("EFIAPI\r\n");\r
812 fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
813 fileBuffer.append(" IN VOID *HobStart\r\n");\r
814 fileBuffer.append(" )\r\n\r\n");\r
815 fileBuffer.append("{\r\n");\r
816 fileBuffer.append(" ");\r
817 fileBuffer.append(entryPointList[0]);\r
818 fileBuffer.append(" (HobStart);\r\n");\r
819 fileBuffer.append("}\r\n\r\n");\r
820 }\r
821 break;\r
822\r
823 case CommonDefinition.ModuleTypePeim:\r
824 int entryPointCount = 0;\r
825 fileBuffer\r
826 .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;\r\n");\r
827 if (entryPointList == null || entryPointList.length == 0) {\r
828 fileBuffer.append("EFI_STATUS\r\n");\r
829 fileBuffer.append("EFIAPI\r\n");\r
830 fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
831 fileBuffer.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");\r
832 fileBuffer.append(" IN EFI_PEI_SERVICES **PeiServices\r\n");\r
833 fileBuffer.append(" )\r\n\r\n");\r
834 fileBuffer.append("{\r\n");\r
835 fileBuffer.append(" return EFI_SUCCESS;\r\n");\r
836 fileBuffer.append("}\r\n\r\n");\r
837 break;\r
838 }\r
839 for (int i = 0; i < entryPointList.length; i++) {\r
840 fileBuffer.append("EFI_STATUS\r\n");\r
841 fileBuffer.append("EFIAPI\r\n");\r
842 fileBuffer.append(entryPointList[i]);\r
843 fileBuffer.append(" (\r\n");\r
844 fileBuffer\r
845 .append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");\r
846 fileBuffer\r
847 .append(" IN EFI_PEI_SERVICES **PeiServices\r\n");\r
848 fileBuffer.append(" );\r\n");\r
849 entryPointCount++;\r
850\r
851 }\r
852\r
853 fileBuffer.append("EFI_STATUS\r\n");\r
854 fileBuffer.append("EFIAPI\r\n");\r
855 fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
856 fileBuffer.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");\r
857 fileBuffer.append(" IN EFI_PEI_SERVICES **PeiServices\r\n");\r
858 fileBuffer.append(" )\r\n\r\n");\r
859 fileBuffer.append("{\r\n");\r
860 if (entryPointCount == 1) {\r
861 fileBuffer.append(" return ");\r
862 fileBuffer.append(entryPointList[0]);\r
863 fileBuffer.append(" (FfsHeader, PeiServices);\r\n");\r
864 } else {\r
865 fileBuffer.append(" EFI_STATUS Status;\r\n");\r
866 fileBuffer.append(" EFI_STATUS CombinedStatus;\r\n\r\n");\r
867 fileBuffer.append(" CombinedStatus = EFI_LOAD_ERROR;\r\n\r\n");\r
868 for (int i = 0; i < entryPointList.length; i++) {\r
869 if (!entryPointList[i].equals("")) {\r
870 fileBuffer.append(" Status = ");\r
871 fileBuffer.append(entryPointList[i]);\r
872 fileBuffer.append(" (FfsHeader, PeiServices);\r\n");\r
873 fileBuffer\r
874 .append(" if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {\r\n");\r
875 fileBuffer.append(" CombinedStatus = Status;\r\n");\r
876 fileBuffer.append(" }\r\n\r\n");\r
877 } else {\r
878 break;\r
879 }\r
880 }\r
881 fileBuffer.append(" return CombinedStatus;\r\n");\r
882 }\r
883 fileBuffer.append("}\r\n\r\n");\r
884 break;\r
885\r
886 case CommonDefinition.ModuleTypeDxeSmmDriver:\r
887 entryPointCount = 0;\r
888 //\r
889 // If entryPoint is null, create an empty ProcessModuleEntryPointList\r
890 // function.\r
891 //\r
892 if (entryPointList == null || entryPointList.length == 0) {\r
893 fileBuffer\r
894 .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = ");\r
895 fileBuffer.append(Integer.toString(entryPointCount));\r
896 fileBuffer.append(";\r\n");\r
897 fileBuffer.append("EFI_STATUS\r\n");\r
898 fileBuffer.append("EFIAPI\r\n");\r
899 fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
900 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");\r
901 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");\r
902 fileBuffer.append(" )\r\n\r\n");\r
903 fileBuffer.append("{\r\n");\r
904 fileBuffer.append(" return EFI_SUCCESS;\r\n");\r
905 fileBuffer.append("}\r\n\r\n");\r
906\r
907 } else {\r
908 for (int i = 0; i < entryPointList.length; i++) {\r
909 fileBuffer.append("EFI_STATUS\r\n");\r
910 fileBuffer.append("EFIAPI\r\n");\r
911 fileBuffer.append(entryPointList[i]);\r
912 fileBuffer.append(" (\r\n");\r
913 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");\r
914 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");\r
915 fileBuffer.append(" );\r\n");\r
916 entryPointCount++;\r
917 }\r
918 fileBuffer\r
919 .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = ");\r
920 fileBuffer.append(Integer.toString(entryPointCount));\r
921 fileBuffer.append(";\r\n");\r
922 fileBuffer\r
923 .append("static BASE_LIBRARY_JUMP_BUFFER mJumpContext;\r\n");\r
924 fileBuffer\r
925 .append("static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n\r\n");\r
926\r
927 fileBuffer.append("EFI_STATUS\r\n");\r
928 fileBuffer.append("EFIAPI\r\n");\r
929 fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
930 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");\r
931 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");\r
932 fileBuffer.append(" )\r\n\r\n");\r
933 fileBuffer.append("{\r\n");\r
934\r
935\r
936 for (int i = 0; i < entryPointList.length; i++) {\r
937 fileBuffer\r
938 .append(" if (SetJump (&mJumpContext) == 0) {\r\n");\r
939 fileBuffer.append(" ExitDriver (");\r
940 fileBuffer.append(entryPointList[i]);\r
941 fileBuffer.append(" (ImageHandle, SystemTable));\r\n");\r
136adffc 942 fileBuffer.append(" ASSERT (FALSE);\r\n");\r
943 fileBuffer.append(" }\r\n");\r
ff225cbb 944\r
136adffc 945 }\r
946 fileBuffer.append(" return mDriverEntryPointStatus;\r\n");\r
947 fileBuffer.append("}\r\n\r\n");\r
948\r
949 fileBuffer.append("VOID\r\n");\r
950 fileBuffer.append("EFIAPI\r\n");\r
951 fileBuffer.append("ExitDriver (\r\n");\r
952 fileBuffer.append(" IN EFI_STATUS Status\n");\r
953 fileBuffer.append(" )\r\n\r\n");\r
954 fileBuffer.append("{\r\n");\r
955 fileBuffer\r
5f907e4a 956 .append(" if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n");\r
136adffc 957 fileBuffer.append(" mDriverEntryPointStatus = Status;\r\n");\r
958 fileBuffer.append(" }\r\n");\r
959 fileBuffer.append(" LongJump (&mJumpContext, (UINTN)-1);\r\n");\r
960 fileBuffer.append(" ASSERT (FALSE);\r\n");\r
961 fileBuffer.append("}\r\n\r\n");\r
ff225cbb 962\r
136adffc 963 }\r
ff225cbb 964\r
965\r
5f907e4a 966 //\r
967 // Add "ModuleUnloadImage" for DxeSmmDriver module type;\r
968 //\r
969 entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray();\r
136adffc 970 entryPointList = CommonDefinition.remDupString(entryPointList);\r
5f907e4a 971 entryPointCount = 0;\r
136adffc 972\r
5f907e4a 973 if (entryPointList != null) {\r
974 for (int i = 0; i < entryPointList.length; i++) {\r
a84091c4 975 fileBuffer.append("EFI_STATUS\r\n");\r
976 fileBuffer.append("EFIAPI\r\n");\r
977 fileBuffer.append(entryPointList[i]);\r
978 fileBuffer.append(" (\r\n");\r
979 fileBuffer\r
5f907e4a 980 .append(" IN EFI_HANDLE ImageHandle\r\n");\r
a84091c4 981 fileBuffer.append(" );\r\n");\r
982 entryPointCount++;\r
983 }\r
5f907e4a 984 }\r
136adffc 985\r
a84091c4 986 fileBuffer\r
5f907e4a 987 .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ");\r
988 fileBuffer.append(Integer.toString(entryPointCount));\r
989 fileBuffer.append(";\r\n\r\n");\r
990\r
991 fileBuffer.append("EFI_STATUS\r\n");\r
992 fileBuffer.append("EFIAPI\r\n");\r
993 fileBuffer.append("ProcessModuleUnloadList (\r\n");\r
994 fileBuffer.append(" IN EFI_HANDLE ImageHandle\r\n");\r
995 fileBuffer.append(" )\r\n");\r
996 fileBuffer.append("{\r\n");\r
997\r
998 if (entryPointCount == 0) {\r
999 fileBuffer.append(" return EFI_SUCCESS;\r\n");\r
1000 } else if (entryPointCount == 1) {\r
1001 fileBuffer.append(" return ");\r
1002 fileBuffer.append(entryPointList[0]);\r
1003 fileBuffer.append("(ImageHandle);\r\n");\r
1004 } else {\r
1005 fileBuffer.append(" EFI_STATUS Status;\r\n\r\n");\r
1006 fileBuffer.append(" Status = EFI_SUCCESS;\r\n\r\n");\r
1007 for (int i = 0; i < entryPointList.length; i++) {\r
1008 if (i == 0) {\r
136adffc 1009 fileBuffer.append(" Status = ");\r
1010 fileBuffer.append(entryPointList[i]);\r
1011 fileBuffer.append("(ImageHandle);\r\n");\r
5f907e4a 1012 } else {\r
878ddf1f 1013 fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n");\r
1014 fileBuffer.append(" ");\r
1015 fileBuffer.append(entryPointList[i]);\r
1016 fileBuffer.append("(ImageHandle);\r\n");\r
1017 fileBuffer.append(" } else {\r\n");\r
1018 fileBuffer.append(" Status = ");\r
1019 fileBuffer.append(entryPointList[i]);\r
1020 fileBuffer.append("(ImageHandle);\r\n");\r
1021 fileBuffer.append(" }\r\n");\r
878ddf1f 1022 }\r
5f907e4a 1023 }\r
1024 fileBuffer.append(" return Status;\r\n");\r
1025 }\r
1026 fileBuffer.append("}\r\n\r\n");\r
1027 break;\r
1028\r
1029 case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
1030 case CommonDefinition.ModuleTypeDxeDriver:\r
1031 case CommonDefinition.ModuleTypeDxeSalDriver:\r
1032 case CommonDefinition.ModuleTypeUefiDriver:\r
1033 case CommonDefinition.ModuleTypeUefiApplication:\r
1034 entryPointCount = 0;\r
1035 fileBuffer.append("const UINT32 _gUefiDriverRevision = 0;\r\n");\r
136adffc 1036 //\r
1037 // If entry point is null, create a empty ProcessModuleEntryPointList function.\r
1038 //\r
5f907e4a 1039 if (entryPointList == null || entryPointList.length == 0) {\r
a29c47e0 1040 fileBuffer\r
136adffc 1041 .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = 0;\r\n");\r
5f907e4a 1042 fileBuffer.append("EFI_STATUS\r\n");\r
1043 fileBuffer.append("EFIAPI\r\n");\r
1044 fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
1045 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");\r
1046 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");\r
1047 fileBuffer.append(" )\r\n\r\n");\r
1048 fileBuffer.append("{\r\n");\r
1049 fileBuffer.append(" return EFI_SUCCESS;\r\n");\r
1050 fileBuffer.append("}\r\n");\r
1051\r
1052 } else {\r
136adffc 1053 for (int i = 0; i < entryPointList.length; i++) {\r
ff225cbb 1054\r
136adffc 1055 fileBuffer.append("EFI_STATUS\r\n");\r
1056 fileBuffer.append("EFIAPI\r\n");\r
1057 fileBuffer.append(entryPointList[i]);\r
1058 fileBuffer.append(" (\r\n");\r
47f2f011 1059 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");\r
1060 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");\r
136adffc 1061 fileBuffer.append(" );\r\n");\r
1062 entryPointCount++;\r
878ddf1f 1063 }\r
1064\r
878ddf1f 1065 fileBuffer\r
5f907e4a 1066 .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = ");\r
136adffc 1067 fileBuffer.append(Integer.toString(entryPointCount));\r
878ddf1f 1068 fileBuffer.append(";\r\n");\r
136adffc 1069 if (entryPointCount > 1) {\r
1070 fileBuffer\r
5f907e4a 1071 .append("static BASE_LIBRARY_JUMP_BUFFER mJumpContext;\r\n");\r
136adffc 1072 fileBuffer\r
5f907e4a 1073 .append("static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n");\r
136adffc 1074 }\r
1075 fileBuffer.append("\n");\r
878ddf1f 1076\r
136adffc 1077 fileBuffer.append("EFI_STATUS\r\n");\r
1078 fileBuffer.append("EFIAPI\r\n");\r
1079 fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
25832ed3 1080 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");\r
1081 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");\r
136adffc 1082 fileBuffer.append(" )\r\n\r\n");\r
1083 fileBuffer.append("{\r\n");\r
878ddf1f 1084\r
136adffc 1085 if (entryPointCount == 1) {\r
1086 fileBuffer.append(" return (");\r
1087 fileBuffer.append(entryPointList[0]);\r
1088 fileBuffer.append(" (ImageHandle, SystemTable));\r\n");\r
1089 } else {\r
1090 for (int i = 0; i < entryPointList.length; i++) {\r
1091 if (!entryPointList[i].equals("")) {\r
1092 fileBuffer\r
5f907e4a 1093 .append(" if (SetJump (&mJumpContext) == 0) {\r\n");\r
136adffc 1094 fileBuffer.append(" ExitDriver (");\r
1095 fileBuffer.append(entryPointList[i]);\r
1096 fileBuffer.append(" (ImageHandle, SystemTable));\r\n");\r
1097 fileBuffer.append(" ASSERT (FALSE);\r\n");\r
1098 fileBuffer.append(" }\r\n");\r
1099 } else {\r
1100 break;\r
1101 }\r
878ddf1f 1102 }\r
136adffc 1103 fileBuffer.append(" return mDriverEntryPointStatus;\r\n");\r
878ddf1f 1104 }\r
136adffc 1105 fileBuffer.append("}\r\n\r\n");\r
878ddf1f 1106\r
2336382f 1107 fileBuffer.append("VOID\r\n");\r
1108 fileBuffer.append("EFIAPI\r\n");\r
136adffc 1109 fileBuffer.append("ExitDriver (\r\n");\r
2336382f 1110 fileBuffer.append(" IN EFI_STATUS Status\r\n");\r
136adffc 1111 fileBuffer.append(" )\r\n\r\n");\r
1112 fileBuffer.append("{\r\n");\r
1113 if (entryPointCount <= 1) {\r
1114 fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n");\r
1115 fileBuffer\r
5f907e4a 1116 .append(" ProcessLibraryDestructorList (gImageHandle, gST);\r\n");\r
136adffc 1117 fileBuffer.append(" }\r\n");\r
1118 fileBuffer\r
5f907e4a 1119 .append(" gBS->Exit (gImageHandle, Status, 0, NULL);\r\n");\r
878ddf1f 1120 } else {\r
136adffc 1121 fileBuffer\r
5f907e4a 1122 .append(" if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n");\r
136adffc 1123 fileBuffer.append(" mDriverEntryPointStatus = Status;\r\n");\r
1124 fileBuffer.append(" }\r\n");\r
1125 fileBuffer.append(" LongJump (&mJumpContext, (UINTN)-1);\r\n");\r
1126 fileBuffer.append(" ASSERT (FALSE);\r\n");\r
878ddf1f 1127 }\r
136adffc 1128 fileBuffer.append("}\r\n\r\n");\r
878ddf1f 1129\r
878ddf1f 1130 }\r
ff225cbb 1131\r
5f907e4a 1132 //\r
1133 // Add ModuleUnloadImage for DxeDriver and UefiDriver module type.\r
1134 //\r
1135 entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray();\r
878ddf1f 1136 //\r
136adffc 1137 // Remover duplicate unload entry point.\r
878ddf1f 1138 //\r
136adffc 1139 entryPointList = CommonDefinition.remDupString(entryPointList);\r
5f907e4a 1140 entryPointCount = 0;\r
1141 if (entryPointList != null) {\r
1142 for (int i = 0; i < entryPointList.length; i++) {\r
a84091c4 1143 fileBuffer.append("EFI_STATUS\r\n");\r
1144 fileBuffer.append("EFIAPI\r\n");\r
1145 fileBuffer.append(entryPointList[i]);\r
1146 fileBuffer.append(" (\r\n");\r
1147 fileBuffer\r
5f907e4a 1148 .append(" IN EFI_HANDLE ImageHandle\r\n");\r
a84091c4 1149 fileBuffer.append(" );\r\n");\r
1150 entryPointCount++;\r
5f907e4a 1151 }\r
1152 }\r
1153\r
1154 fileBuffer\r
1155 .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ");\r
1156 fileBuffer.append(Integer.toString(entryPointCount));\r
1157 fileBuffer.append(";\r\n\r\n");\r
1158\r
1159 fileBuffer.append("EFI_STATUS\n");\r
1160 fileBuffer.append("EFIAPI\r\n");\r
1161 fileBuffer.append("ProcessModuleUnloadList (\r\n");\r
1162 fileBuffer.append(" IN EFI_HANDLE ImageHandle\r\n");\r
1163 fileBuffer.append(" )\r\n");\r
1164 fileBuffer.append("{\r\n");\r
1165\r
1166 if (entryPointCount == 0) {\r
1167 fileBuffer.append(" return EFI_SUCCESS;\r\n");\r
1168 } else if (entryPointCount == 1) {\r
1169 fileBuffer.append(" return ");\r
1170 fileBuffer.append(entryPointList[0]);\r
1171 fileBuffer.append("(ImageHandle);\r\n");\r
1172 } else {\r
1173 fileBuffer.append(" EFI_STATUS Status;\r\n\r\n");\r
1174 fileBuffer.append(" Status = EFI_SUCCESS;\r\n\r\n");\r
1175 for (int i = 0; i < entryPointList.length; i++) {\r
25832ed3 1176 if (i == 0) {\r
1177 fileBuffer.append(" Status = ");\r
1178 fileBuffer.append(entryPointList[i]);\r
1179 fileBuffer.append("(ImageHandle);\r\n");\r
5f907e4a 1180 } else {\r
25832ed3 1181 fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n");\r
5f907e4a 1182 fileBuffer.append(" ");\r
1183 fileBuffer.append(entryPointList[i]);\r
1184 fileBuffer.append("(ImageHandle);\r\n");\r
1185 fileBuffer.append(" } else {\r\n");\r
1186 fileBuffer.append(" Status = ");\r
1187 fileBuffer.append(entryPointList[i]);\r
1188 fileBuffer.append("(ImageHandle);\r\n");\r
1189 fileBuffer.append(" }\r\n");\r
25832ed3 1190 }\r
5f907e4a 1191 }\r
1192 fileBuffer.append(" return Status;\r\n");\r
1193 }\r
1194 fileBuffer.append("}\r\n\r\n");\r
1195 break;\r
1196 }\r
1197 }\r
1198\r
1199 /**\r
1200 * PpiGuidToAutogenc\r
1201 *\r
1202 * This function gets GUIDs from SPD file accrodeing to <PPIs> information\r
1203 * and write those GUIDs to AutoGen.c.\r
1204 *\r
1205 * @param fileBuffer\r
1206 * String Buffer for Autogen.c file.\r
1207 * @throws BuildException\r
1208 * Guid must set value!\r
1209 */\r
1210 void PpiGuidToAutogenC(StringBuffer fileBuffer) throws AutoGenException {\r
1211 String[] cNameGuid = null;\r
1212\r
1213 //\r
1214 // Get the all PPI adn PPI Notify from MSA file,\r
1215 // then add those PPI ,and PPI Notify name to list.\r
1216 //\r
1217\r
1218 String[] ppiList = SurfaceAreaQuery.getPpiArray(this.arch);\r
1219 for (int i = 0; i < ppiList.length; i++) {\r
1220 this.mPpiList.add(ppiList[i]);\r
1221 }\r
1222\r
1223 String[] ppiNotifyList = SurfaceAreaQuery.getPpiNotifyArray(this.arch);\r
1224 for (int i = 0; i < ppiNotifyList.length; i++) {\r
1225 this.mPpiList.add(ppiNotifyList[i]);\r
1226 }\r
1227\r
1228 //\r
1229 // Find CNAME and GUID from dependence SPD file and write to Autogen.c\r
1230 //\r
1231 Iterator ppiIterator = this.mPpiList.iterator();\r
1232 String ppiKeyWord = null;\r
1233 while (ppiIterator.hasNext()) {\r
1234 ppiKeyWord = ppiIterator.next().toString();\r
1235 cNameGuid = GlobalData.getPpiGuid(this.mDepPkgList, ppiKeyWord);\r
1236 if (cNameGuid != null) {\r
1237 fileBuffer\r
1238 .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");\r
1239 fileBuffer.append(cNameGuid[0]);\r
1240 fileBuffer.append(" = { ");\r
1241 fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1]));\r
1242 fileBuffer.append(" } ;");\r
1243 } else {\r
1244 //\r
1245 // If can't find Ppi GUID declaration in every package\r
1246 //\r
1247 throw new AutoGenException("Can not find Ppi GUID ["\r
1248 + ppiKeyWord + "] declaration in any SPD package!");\r
1249 }\r
1250 }\r
1251 }\r
1252\r
1253 /**\r
1254 * ProtocolGuidToAutogenc\r
1255 *\r
1256 * This function gets GUIDs from SPD file accrodeing to <Protocol>\r
1257 * information and write those GUIDs to AutoGen.c.\r
1258 *\r
1259 * @param fileBuffer\r
1260 * String Buffer for Autogen.c file.\r
1261 * @throws BuildException\r
1262 * Protocol name must set.\r
1263 */\r
1264 void ProtocolGuidToAutogenC(StringBuffer fileBuffer) throws BuildException {\r
1265 String[] cNameGuid = null;\r
1266\r
1267 String[] protocolList = SurfaceAreaQuery.getProtocolArray(this.arch);\r
1268\r
1269 //\r
1270 // Add result to Autogen global list.\r
1271 //\r
1272 for (int i = 0; i < protocolList.length; i++) {\r
1273 this.mProtocolList.add(protocolList[i]);\r
1274 }\r
1275\r
1276 String[] protocolNotifyList = SurfaceAreaQuery\r
1277 .getProtocolNotifyArray(this.arch);\r
1278\r
1279 for (int i = 0; i < protocolNotifyList.length; i++) {\r
1280 this.mProtocolList.add(protocolNotifyList[i]);\r
1281 }\r
1282\r
1283 //\r
1284 // Get the NAME and GUID from dependence SPD and write to Autogen.c\r
1285 //\r
1286 Iterator protocolIterator = this.mProtocolList.iterator();\r
1287 String protocolKeyWord = null;\r
1288\r
1289\r
1290 while (protocolIterator.hasNext()) {\r
1291 protocolKeyWord = protocolIterator.next().toString();\r
1292 cNameGuid = GlobalData.getProtocolGuid(this.mDepPkgList, protocolKeyWord);\r
1293 if (cNameGuid != null) {\r
1294 fileBuffer\r
1295 .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");\r
1296 fileBuffer.append(cNameGuid[0]);\r
1297 fileBuffer.append(" = { ");\r
1298 fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1]));\r
1299 fileBuffer.append(" } ;");\r
1300 } else {\r
1301 //\r
1302 // If can't find protocol GUID declaration in every package\r
1303 //\r
1304 throw new BuildException("Can not find protocol Guid ["\r
1305 + protocolKeyWord + "] declaration in any SPD package!");\r
1306 }\r
1307 }\r
1308 }\r
1309\r
1310 /**\r
1311 * GuidGuidToAutogenc\r
1312 *\r
1313 * This function gets GUIDs from SPD file accrodeing to <Guids> information\r
1314 * and write those GUIDs to AutoGen.c.\r
1315 *\r
1316 * @param fileBuffer\r
1317 * String Buffer for Autogen.c file.\r
1318 *\r
1319 */\r
1320 void GuidGuidToAutogenC(StringBuffer fileBuffer) throws AutoGenException {\r
1321 String[] cNameGuid = null;\r
1322 String guidKeyWord = null;\r
1323\r
1324 String[] guidList = SurfaceAreaQuery.getGuidEntryArray(this.arch);\r
1325\r
1326 for (int i = 0; i < guidList.length; i++) {\r
1327 this.mGuidList.add(guidList[i]);\r
1328 }\r
1329\r
1330\r
1331 Iterator guidIterator = this.mGuidList.iterator();\r
1332 while (guidIterator.hasNext()) {\r
1333 guidKeyWord = guidIterator.next().toString();\r
1334 cNameGuid = GlobalData.getGuid(this.mDepPkgList, guidKeyWord);\r
1335\r
1336 if (cNameGuid != null) {\r
1337 fileBuffer\r
1338 .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");\r
1339 fileBuffer.append(cNameGuid[0]);\r
1340 fileBuffer.append(" = { ");\r
1341 fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1]));\r
1342 fileBuffer.append("} ;");\r
1343 } else {\r
1344 //\r
1345 // If can't find GUID declaration in every package\r
1346 //\r
1347 throw new AutoGenException("Can not find Guid [" + guidKeyWord\r
1348 + "] declaration in any SPD package. ");\r
1349 }\r
1350\r
1351 }\r
1352 }\r
1353\r
1354 /**\r
1355 * LibInstanceToAutogenC\r
1356 *\r
1357 * This function adds dependent library instance to autogen.c,which\r
1358 * includeing library's constructor, destructor, and library dependent ppi,\r
1359 * protocol, guid, pcd information.\r
1360 *\r
1361 * @param fileBuffer\r
1362 * String buffer for AutoGen.c\r
1363 * @throws BuildException\r
1364 */\r
1365 void LibInstanceToAutogenC(StringBuffer fileBuffer) throws BuildException {\r
1366 try {\r
2336382f 1367 String moduleType = this.moduleId.getModuleType();\r
5f907e4a 1368 //\r
1369 // Add library constructor to AutoGen.c\r
1370 //\r
1371 LibConstructorToAutogenC(libConstructList, moduleType,\r
1372 fileBuffer/* autogenC */);\r
1373 //\r
1374 // Add library destructor to AutoGen.c\r
1375 //\r
1376 LibDestructorToAutogenC(libDestructList, moduleType, fileBuffer/* autogenC */);\r
1377 } catch (Exception e) {\r
1378 throw new BuildException(e.getMessage());\r
1379 }\r
1380 }\r
1381\r
1382 /**\r
1383 * LibConstructorToAutogenc\r
1384 *\r
1385 * This function writes library constructor list to AutoGen.c. The library\r
1386 * constructor's parameter and return value depend on module type.\r
1387 *\r
1388 * @param libInstanceList\r
1389 * List of library construct name.\r
1390 * @param moduleType\r
1391 * Module type.\r
1392 * @param fileBuffer\r
1393 * String buffer for AutoGen.c\r
1394 * @throws Exception\r
1395 */\r
1396 void LibConstructorToAutogenC(List<String> libInstanceList,\r
1397 String moduleType, StringBuffer fileBuffer) throws Exception {\r
1398 boolean isFirst = true;\r
1399\r
1400 //\r
1401 // The library constructor's parameter and return value depend on\r
1402 // module type.\r
1403 //\r
1404 for (int i = 0; i < libInstanceList.size(); i++) {\r
1405 switch (CommonDefinition.getModuleType(moduleType)) {\r
1406 case CommonDefinition.ModuleTypeBase:\r
1407 fileBuffer.append("RETURN_STATUS\r\n");\r
1408 fileBuffer.append("EFIAPI\r\n");\r
1409 fileBuffer.append(libInstanceList.get(i));\r
1410 fileBuffer.append(" (\r\n");\r
1411 fileBuffer.append(" VOID\r\n");\r
1412 fileBuffer.append(" );\r\n");\r
1413 break;\r
1414\r
1415 case CommonDefinition.ModuleTypePeiCore:\r
1416 case CommonDefinition.ModuleTypePeim:\r
1417 fileBuffer.append("EFI_STATUS\r\n");\r
1418 fileBuffer.append("EFIAPI\r\n");\r
1419 fileBuffer.append(libInstanceList.get(i));\r
1420 fileBuffer.append(" (\r\n");\r
1421 fileBuffer\r
1422 .append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");\r
1423 fileBuffer\r
1424 .append(" IN EFI_PEI_SERVICES **PeiServices\r\n");\r
1425 fileBuffer.append(" );\r\n");\r
1426 break;\r
1427\r
1428 case CommonDefinition.ModuleTypeDxeCore:\r
1429 case CommonDefinition.ModuleTypeDxeDriver:\r
1430 case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
1431 case CommonDefinition.ModuleTypeDxeSmmDriver:\r
1432 case CommonDefinition.ModuleTypeDxeSalDriver:\r
1433 case CommonDefinition.ModuleTypeUefiDriver:\r
1434 case CommonDefinition.ModuleTypeUefiApplication:\r
1435 fileBuffer.append("EFI_STATUS\r\n");\r
1436 fileBuffer.append("EFIAPI\r\n");\r
1437 fileBuffer.append(libInstanceList.get(i));\r
1438 fileBuffer.append(" (\r\n");\r
1439 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");\r
1440 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");\r
1441 fileBuffer.append(" );\r\n");\r
1442 break;\r
1443 }\r
1444 }\r
1445\r
1446 //\r
1447 // Add ProcessLibraryConstructorList in AutoGen.c\r
1448 //\r
1449 fileBuffer.append("VOID\r\n");\r
1450 fileBuffer.append("EFIAPI\r\n");\r
1451 fileBuffer.append("ProcessLibraryConstructorList (\r\n");\r
1452 switch (CommonDefinition.getModuleType(moduleType)) {\r
1453 case CommonDefinition.ModuleTypeBase:\r
1454 fileBuffer.append(" VOID\r\n");\r
1455 break;\r
1456\r
1457 case CommonDefinition.ModuleTypePeiCore:\r
1458 case CommonDefinition.ModuleTypePeim:\r
1459 fileBuffer.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");\r
1460 fileBuffer\r
1461 .append(" IN EFI_PEI_SERVICES **PeiServices\r\n");\r
1462 break;\r
1463\r
1464 case CommonDefinition.ModuleTypeDxeCore:\r
1465 case CommonDefinition.ModuleTypeDxeDriver:\r
1466 case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
1467 case CommonDefinition.ModuleTypeDxeSmmDriver:\r
1468 case CommonDefinition.ModuleTypeDxeSalDriver:\r
1469 case CommonDefinition.ModuleTypeUefiDriver:\r
1470 case CommonDefinition.ModuleTypeUefiApplication:\r
1471 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");\r
1472 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");\r
1473 break;\r
1474 }\r
1475\r
1476 fileBuffer.append(" )\r\n");\r
1477 fileBuffer.append("{\r\n");\r
136adffc 1478 //\r
1479 // If no constructor function, return EFI_SUCCESS.\r
1480 //\r
1481 //if (libInstanceList.size() == 0){\r
1482 // fileBuffer.append(" return EFI_SUCCESS;\r\n");\r
1483 //}\r
5f907e4a 1484 for (int i = 0; i < libInstanceList.size(); i++) {\r
1485 if (isFirst) {\r
1486 fileBuffer.append(" EFI_STATUS Status;\r\n");\r
136adffc 1487 fileBuffer.append(" Status = EFI_SUCCESS;\r\n");\r
5f907e4a 1488 fileBuffer.append("\r\n");\r
1489 isFirst = false;\r
1490 }\r
1491 switch (CommonDefinition.getModuleType(moduleType)) {\r
1492 case CommonDefinition.ModuleTypeBase:\r
1493 fileBuffer.append(" Status = ");\r
1494 fileBuffer.append(libInstanceList.get(i));\r
1495 fileBuffer.append("();\r\n");\r
1496 fileBuffer.append(" VOID\r\n");\r
1497 break;\r
1498 case CommonDefinition.ModuleTypePeiCore:\r
1499 case CommonDefinition.ModuleTypePeim:\r
1500 fileBuffer.append(" Status = ");\r
1501 fileBuffer.append(libInstanceList.get(i));\r
1502 fileBuffer.append(" (FfsHeader, PeiServices);\r\n");\r
1503 break;\r
1504 case CommonDefinition.ModuleTypeDxeCore:\r
1505 case CommonDefinition.ModuleTypeDxeDriver:\r
1506 case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
1507 case CommonDefinition.ModuleTypeDxeSmmDriver:\r
1508 case CommonDefinition.ModuleTypeDxeSalDriver:\r
1509 case CommonDefinition.ModuleTypeUefiDriver:\r
1510 case CommonDefinition.ModuleTypeUefiApplication:\r
1511 fileBuffer.append(" Status = ");\r
1512 fileBuffer.append(libInstanceList.get(i));\r
1513 fileBuffer.append(" (ImageHandle, SystemTable);\r\n");\r
1514 break;\r
136adffc 1515 default:\r
391dbbb1 1516 EdkLog.log(EdkLog.EDK_INFO,"Autogen doesn't know how to deal with module type - " + moduleType + "!");\r
5f907e4a 1517 }\r
1518 fileBuffer.append(" ASSERT_EFI_ERROR (Status);\r\n");\r
1519 }\r
1520 fileBuffer.append("}\r\n");\r
1521 }\r
1522\r
1523 /**\r
1524 * LibDestructorToAutogenc\r
1525 *\r
1526 * This function writes library destructor list to AutoGen.c. The library\r
1527 * destructor's parameter and return value depend on module type.\r
1528 *\r
1529 * @param libInstanceList\r
1530 * List of library destructor name.\r
1531 * @param moduleType\r
1532 * Module type.\r
1533 * @param fileBuffer\r
1534 * String buffer for AutoGen.c\r
1535 * @throws Exception\r
1536 */\r
1537 void LibDestructorToAutogenC(List<String> libInstanceList,\r
1538 String moduleType, StringBuffer fileBuffer) throws Exception {\r
1539 boolean isFirst = true;\r
1540 for (int i = 0; i < libInstanceList.size(); i++) {\r
1541 switch (CommonDefinition.getModuleType(moduleType)) {\r
1542 case CommonDefinition.ModuleTypeBase:\r
1543 fileBuffer.append("RETURN_STATUS\r\n");\r
1544 fileBuffer.append("EFIAPI\r\n");\r
1545 fileBuffer.append(libInstanceList.get(i));\r
1546 fileBuffer.append(" (\r\n");\r
1547 fileBuffer.append(" VOID\r\n");\r
1548 fileBuffer.append(" );\r\n");\r
1549 break;\r
1550 case CommonDefinition.ModuleTypePeiCore:\r
1551 case CommonDefinition.ModuleTypePeim:\r
1552 fileBuffer.append("EFI_STATUS\r\n");\r
1553 fileBuffer.append("EFIAPI\r\n");\r
1554 fileBuffer.append(libInstanceList.get(i));\r
1555 fileBuffer.append(" (\r\n");\r
1556 fileBuffer\r
1557 .append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");\r
1558 fileBuffer\r
1559 .append(" IN EFI_PEI_SERVICES **PeiServices\r\n");\r
1560 fileBuffer.append(" );\r\n");\r
1561 break;\r
1562 case CommonDefinition.ModuleTypeDxeCore:\r
1563 case CommonDefinition.ModuleTypeDxeDriver:\r
1564 case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
1565 case CommonDefinition.ModuleTypeDxeSmmDriver:\r
1566 case CommonDefinition.ModuleTypeDxeSalDriver:\r
1567 case CommonDefinition.ModuleTypeUefiDriver:\r
1568 case CommonDefinition.ModuleTypeUefiApplication:\r
1569 fileBuffer.append("EFI_STATUS\r\n");\r
1570 fileBuffer.append("EFIAPI\r\n");\r
1571 fileBuffer.append(libInstanceList.get(i));\r
1572 fileBuffer.append(" (\r\n");\r
1573 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");\r
1574 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");\r
1575 fileBuffer.append(" );\r\n");\r
1576 break;\r
1577 }\r
1578 }\r
1579\r
1580 //\r
1581 // Write ProcessLibraryDestructor list to autogen.c\r
1582 //\r
1583 switch (CommonDefinition.getModuleType(moduleType)) {\r
1584 case CommonDefinition.ModuleTypeBase:\r
1585 case CommonDefinition.ModuleTypePeiCore:\r
1586 case CommonDefinition.ModuleTypePeim:\r
1587 break;\r
1588 case CommonDefinition.ModuleTypeDxeCore:\r
1589 case CommonDefinition.ModuleTypeDxeDriver:\r
1590 case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
1591 case CommonDefinition.ModuleTypeDxeSmmDriver:\r
1592 case CommonDefinition.ModuleTypeDxeSalDriver:\r
1593 case CommonDefinition.ModuleTypeUefiDriver:\r
1594 case CommonDefinition.ModuleTypeUefiApplication:\r
1595 fileBuffer.append("VOID\r\n");\r
1596 fileBuffer.append("EFIAPI\r\n");\r
1597 fileBuffer.append("ProcessLibraryDestructorList (\r\n");\r
1598 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");\r
1599 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");\r
1600 fileBuffer.append(" )\r\n");\r
1601 fileBuffer.append("{\r\n");\r
878ddf1f 1602 //\r
136adffc 1603 // If no library destructor function, return EFI_SUCCESS.\r
878ddf1f 1604 //\r
ff225cbb 1605\r
5f907e4a 1606 for (int i = 0; i < libInstanceList.size(); i++) {\r
1607 if (isFirst) {\r
1608 fileBuffer.append(" EFI_STATUS Status;\r\n");\r
136adffc 1609 fileBuffer.append(" Status = EFI_SUCCESS;\r\n");\r
5f907e4a 1610 fileBuffer.append("\r\n");\r
1611 isFirst = false;\r
1612 }\r
1613 fileBuffer.append(" Status = ");\r
1614 fileBuffer.append(libInstanceList.get(i));\r
1615 fileBuffer.append("(ImageHandle, SystemTable);\r\n");\r
1616 fileBuffer.append(" ASSERT_EFI_ERROR (Status);\r\n");\r
1617 }\r
1618 fileBuffer.append("}\r\n");\r
1619 break;\r
1620 }\r
1621 }\r
1622\r
1623 /**\r
1624 * ExternsDriverBindingToAutoGenC\r
1625 *\r
1626 * This function is to write DRIVER_BINDING, COMPONENT_NAME,\r
1627 * DRIVER_CONFIGURATION, DRIVER_DIAGNOSTIC in AutoGen.c.\r
1628 *\r
1629 * @param fileBuffer\r
1630 * String buffer for AutoGen.c\r
1631 */\r
1632 void ExternsDriverBindingToAutoGenC(StringBuffer fileBuffer)\r
1633 throws BuildException {\r
1634\r
1635 //\r
1636 // Check what <extern> contains. And the number of following elements\r
1637 // under <extern> should be same. 1. DRIVER_BINDING 2. COMPONENT_NAME\r
1638 // 3.DRIVER_CONFIGURATION 4. DRIVER_DIAGNOSTIC\r
1639 //\r
1640\r
1641 String[] drvBindList = SurfaceAreaQuery.getDriverBindingArray();\r
1642\r
1643 //\r
1644 // If component name protocol,component configuration protocol,\r
1645 // component diagnostic protocol is not null or empty, check\r
1646 // if every one have the same number of the driver binding protocol.\r
1647 //\r
1648 if (drvBindList == null || drvBindList.length == 0) {\r
1649 return;\r
1650 }\r
1651\r
1652 String[] compNamList = SurfaceAreaQuery.getComponentNameArray();\r
1653 String[] compConfList = SurfaceAreaQuery.getDriverConfigArray();\r
1654 String[] compDiagList = SurfaceAreaQuery.getDriverDiagArray();\r
1655\r
1656 int BitMask = 0;\r
1657\r
1658 //\r
1659 // Write driver binding protocol extern to autogen.c\r
1660 //\r
1661 for (int i = 0; i < drvBindList.length; i++) {\r
1662 fileBuffer.append("extern EFI_DRIVER_BINDING_PROTOCOL ");\r
1663 fileBuffer.append(drvBindList[i]);\r
1664 fileBuffer.append(";\r\n");\r
1665 }\r
1666\r
1667 //\r
1668 // Write component name protocol extern to autogen.c\r
1669 //\r
1670 if (compNamList != null && compNamList.length != 0) {\r
1671 if (drvBindList.length != compNamList.length) {\r
1672 throw new BuildException(\r
1673 "Different number of Driver Binding and Component Name protocols!");\r
1674 }\r
1675\r
1676 BitMask |= 0x01;\r
1677 for (int i = 0; i < compNamList.length; i++) {\r
1678 fileBuffer.append("extern EFI_COMPONENT_NAME_PROTOCOL ");\r
1679 fileBuffer.append(compNamList[i]);\r
1680 fileBuffer.append(";\r\n");\r
1681 }\r
1682 }\r
1683\r
1684 //\r
1685 // Write driver configration protocol extern to autogen.c\r
1686 //\r
1687 if (compConfList != null && compConfList.length != 0) {\r
1688 if (drvBindList.length != compConfList.length) {\r
1689 throw new BuildException(\r
1690 "Different number of Driver Binding and Driver Configuration protocols!");\r
1691 }\r
1692\r
1693 BitMask |= 0x02;\r
1694 for (int i = 0; i < compConfList.length; i++) {\r
1695 fileBuffer.append("extern EFI_DRIVER_CONFIGURATION_PROTOCOL ");\r
1696 fileBuffer.append(compConfList[i]);\r
1697 fileBuffer.append(";\r\n");\r
1698 }\r
1699 }\r
1700\r
1701 //\r
1702 // Write driver dignastic protocol extern to autogen.c\r
1703 //\r
1704 if (compDiagList != null && compDiagList.length != 0) {\r
1705 if (drvBindList.length != compDiagList.length) {\r
1706 throw new BuildException(\r
1707 "Different number of Driver Binding and Driver Diagnosis protocols!");\r
1708 }\r
1709\r
1710 BitMask |= 0x04;\r
1711 for (int i = 0; i < compDiagList.length; i++) {\r
1712 fileBuffer.append("extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL ");\r
1713 fileBuffer.append(compDiagList[i]);\r
1714 fileBuffer.append(";\r\n");\r
1715 }\r
1716 }\r
1717\r
1718 //\r
1719 // Write driver module protocol bitmask.\r
1720 //\r
1721 fileBuffer\r
1722 .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverModelProtocolBitmask = ");\r
1723 fileBuffer.append(Integer.toString(BitMask));\r
1724 fileBuffer.append(";\r\n");\r
1725\r
1726 //\r
1727 // Write driver module protocol list entry\r
1728 //\r
1729 fileBuffer\r
1730 .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINTN _gDriverModelProtocolListEntries = ");\r
1731\r
1732 fileBuffer.append(Integer.toString(drvBindList.length));\r
1733 fileBuffer.append(";\r\n");\r
1734\r
1735 //\r
1736 // Write drive module protocol list to autogen.c\r
1737 //\r
1738 fileBuffer\r
1739 .append("GLOBAL_REMOVE_IF_UNREFERENCED const EFI_DRIVER_MODEL_PROTOCOL_LIST _gDriverModelProtocolList[] = {");\r
1740 for (int i = 0; i < drvBindList.length; i++) {\r
1741 if (i != 0) {\r
1742 fileBuffer.append(",");\r
1743 }\r
1744 fileBuffer.append("\r\n {\r\n");\r
1745 fileBuffer.append(" &");\r
1746 fileBuffer.append(drvBindList[i]);\r
1747 fileBuffer.append(", \r\n");\r
1748\r
1749 if (compNamList != null) {\r
1750 fileBuffer.append(" &");\r
1751 fileBuffer.append(compNamList[i]);\r
1752 fileBuffer.append(", \r\n");\r
1753 } else {\r
1754 fileBuffer.append(" NULL, \r\n");\r
1755 }\r
1756\r
1757 if (compConfList != null) {\r
1758 fileBuffer.append(" &");\r
1759 fileBuffer.append(compConfList[i]);\r
1760 fileBuffer.append(", \r\n");\r
1761 } else {\r
1762 fileBuffer.append(" NULL, \r\n");\r
1763 }\r
1764\r
1765 if (compDiagList != null) {\r
1766 fileBuffer.append(" &");\r
1767 fileBuffer.append(compDiagList[i]);\r
1768 fileBuffer.append(", \r\n");\r
1769 } else {\r
1770 fileBuffer.append(" NULL, \r\n");\r
1771 }\r
1772 fileBuffer.append(" }");\r
1773 }\r
1774 fileBuffer.append("\r\n};\r\n");\r
1775 }\r
1776\r
1777 /**\r
1778 * ExternCallBackToAutoGenC\r
1779 *\r
1780 * This function adds <SetVirtualAddressMapCallBack> and\r
1781 * <ExitBootServicesCallBack> infomation to AutoGen.c\r
1782 *\r
1783 * @param fileBuffer\r
1784 * String buffer for AutoGen.c\r
1785 * @throws BuildException\r
1786 */\r
1787 void ExternCallBackToAutoGenC(StringBuffer fileBuffer)\r
1788 throws BuildException {\r
1789 //\r
1790 // Collect module's <SetVirtualAddressMapCallBack> and\r
1791 // <ExitBootServiceCallBack> and add to setVirtualAddList\r
1792 // exitBootServiceList.\r
1793 //\r
a2733a33 1794 String[] setVirtuals = SurfaceAreaQuery.getSetVirtualAddressMapCallBackArray();\r
1795 String[] exitBoots = SurfaceAreaQuery.getExitBootServicesCallBackArray();\r
1796 if (setVirtuals != null) {\r
1797 for (int j = 0; j < setVirtuals.length; j++) {\r
5f907e4a 1798 this.setVirtalAddList.add(setVirtuals[j]);\r
1799 }\r
1800 }\r
1801 if (exitBoots != null) {\r
1802 for (int k = 0; k < exitBoots.length; k++) {\r
1803 this.exitBootServiceList.add(exitBoots[k]);\r
1804 }\r
1805 }\r
1806 //\r
1807 // Add c code in autogen.c which relate to <SetVirtualAddressMapCallBack>\r
1808 // and <ExitBootServicesCallBack>\r
1809 //\r
1810 String moduleType = this.moduleId.getModuleType();\r
1811 boolean UefiOrDxeModule = false;\r
1812 int Count = 0;\r
1813 int i;\r
1814 switch (CommonDefinition.getModuleType(moduleType)) {\r
1815 case CommonDefinition.ModuleTypeDxeDriver:\r
1816 case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
1817 case CommonDefinition.ModuleTypeDxeSalDriver:\r
1818 case CommonDefinition.ModuleTypeUefiDriver:\r
1819 case CommonDefinition.ModuleTypeUefiApplication:\r
1820 //\r
1821 // Entry point lib for these module types needs to know the count\r
1822 // of entryPoint.\r
1823 //\r
1824 UefiOrDxeModule = true;\r
1825 fileBuffer\r
1826 .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const UINTN _gDriverSetVirtualAddressMapEventCount = ");\r
1827\r
1828 //\r
1829 // If the list is not valid or has no entries set count to zero else\r
1830 // set count to the number of valid entries\r
1831 //\r
1832 Count = 0;\r
1833 if (this.setVirtalAddList != null) {\r
1834 for (i = 0; i < this.setVirtalAddList.size(); i++) {\r
1835 if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) {\r
1836 break;\r
1837 }\r
1838 }\r
1839 Count = i;\r
1840 }\r
1841\r
1842 fileBuffer.append(Integer.toString(Count));\r
1843 fileBuffer.append(";\r\n\r\n");\r
1844 break;\r
1845 default:\r
1846 break;\r
1847 }\r
1848\r
1849 if (this.setVirtalAddList == null || this.setVirtalAddList.size() == 0) {\r
1850 if (UefiOrDxeModule) {\r
1851 //\r
1852 // No data so make a NULL list\r
1853 //\r
1854 fileBuffer\r
1855 .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {\r\n");\r
1856 fileBuffer.append(" NULL\r\n");\r
1857 fileBuffer.append("};\r\n\r\n");\r
1858 }\r
1859 } else {\r
1860 //\r
1861 // Write SetVirtualAddressMap function definition.\r
1862 //\r
1863 for (i = 0; i < this.setVirtalAddList.size(); i++) {\r
1864 if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) {\r
1865 break;\r
1866 }\r
1867 fileBuffer.append("VOID\r\n");\r
1868 fileBuffer.append("EFIAPI\r\n");\r
1869 fileBuffer.append(this.setVirtalAddList.get(i));\r
1870 fileBuffer.append(" (\r\n");\r
1871 fileBuffer.append(" IN EFI_EVENT Event,\r\n");\r
1872 fileBuffer.append(" IN VOID *Context\r\n");\r
1873 fileBuffer.append(" );\r\n\r\n");\r
1874 }\r
1875\r
1876 //\r
1877 // Write SetVirtualAddressMap entry point array.\r
1878 //\r
1879 fileBuffer\r
1880 .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {");\r
1881 for (i = 0; i < this.setVirtalAddList.size(); i++) {\r
1882 if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) {\r
1883 break;\r
1884 }\r
1885\r
1886 if (i == 0) {\r
1887 fileBuffer.append("\r\n ");\r
1888 } else {\r
1889 fileBuffer.append(",\r\n ");\r
1890 }\r
1891\r
1892 fileBuffer.append(this.setVirtalAddList.get(i));\r
1893 }\r
1894 //\r
1895 // If module is not DXE_DRIVER, DXE_RUNTIME_DIRVER, UEFI_DRIVER\r
1896 // UEFI_APPLICATION and DXE_SAL_DRIVER add the NULL at the end of\r
1897 // _gDriverSetVirtualAddressMapEvent list.\r
1898 //\r
1899 if (!UefiOrDxeModule) {\r
1900 fileBuffer.append(",\r\n NULL");\r
1901 }\r
1902 fileBuffer.append("\r\n};\r\n\r\n");\r
1903 }\r
1904\r
1905 if (UefiOrDxeModule) {\r
1906 //\r
1907 // Entry point lib for these module types needs to know the count.\r
1908 //\r
1909 fileBuffer\r
1910 .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const UINTN _gDriverExitBootServicesEventCount = ");\r
1911\r
1912 //\r
1913 // If the list is not valid or has no entries set count to zero else\r
1914 // set count to the number of valid entries.\r
1915 //\r
1916 Count = 0;\r
1917 if (this.exitBootServiceList != null) {\r
1918 for (i = 0; i < this.exitBootServiceList.size(); i++) {\r
1919 if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) {\r
1920 break;\r
1921 }\r
1922 }\r
1923 Count = i;\r
1924 }\r
1925 fileBuffer.append(Integer.toString(Count));\r
1926 fileBuffer.append(";\r\n\r\n");\r
1927 }\r
1928\r
1929 if (this.exitBootServiceList == null || this.exitBootServiceList.size() == 0) {\r
1930 if (UefiOrDxeModule) {\r
1931 //\r
1932 // No data so make a NULL list.\r
1933 //\r
1934 fileBuffer\r
1935 .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {\r\n");\r
1936 fileBuffer.append(" NULL\r\n");\r
1937 fileBuffer.append("};\r\n\r\n");\r
1938 }\r
1939 } else {\r
1940 //\r
1941 // Write DriverExitBootServices function definition.\r
1942 //\r
1943 for (i = 0; i < this.exitBootServiceList.size(); i++) {\r
1944 if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) {\r
1945 break;\r
1946 }\r
1947\r
1948 fileBuffer.append("VOID\r\n");\r
1949 fileBuffer.append("EFIAPI\r\n");\r
1950 fileBuffer.append(this.exitBootServiceList.get(i));\r
1951 fileBuffer.append(" (\r\n");\r
1952 fileBuffer.append(" IN EFI_EVENT Event,\r\n");\r
1953 fileBuffer.append(" IN VOID *Context\r\n");\r
1954 fileBuffer.append(" );\r\n\r\n");\r
1955 }\r
1956\r
1957 //\r
1958 // Write DriverExitBootServices entry point array.\r
1959 //\r
1960 fileBuffer\r
1961 .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {");\r
1962 for (i = 0; i < this.exitBootServiceList.size(); i++) {\r
1963 if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) {\r
1964 break;\r
1965 }\r
1966\r
1967 if (i == 0) {\r
1968 fileBuffer.append("\r\n ");\r
1969 } else {\r
1970 fileBuffer.append(",\r\n ");\r
1971 }\r
1972 fileBuffer.append(this.exitBootServiceList.get(i));\r
1973 }\r
1974 if (!UefiOrDxeModule) {\r
1975 fileBuffer.append(",\r\n NULL");\r
1976 }\r
1977 fileBuffer.append("\r\n};\r\n\r\n");\r
1978 }\r
1979\r
1980 }\r
878ddf1f 1981\r
73b4e31a 1982 private void copyFlashMapHToDebugDir() throws AutoGenException{\r
ff225cbb 1983\r
73b4e31a 1984 File inFile = new File(fvDir + File.separatorChar + CommonDefinition.flashMapH);\r
1985 int size = (int)inFile.length();\r
1986 byte[] buffer = new byte[size];\r
1987 File outFile = new File (this.outputPath + File.separatorChar + CommonDefinition.tianoR8FlashMapH);\r
5f907e4a 1988 //\r
1989 // If TianoR8FlashMap.h existed and the flashMap.h don't change,\r
1990 // do nothing.\r
1991 //\r
31a9215c 1992 if ((!outFile.exists()) ||(inFile.lastModified() - outFile.lastModified()) >= 0) {\r
5f907e4a 1993 try {\r
31a9215c 1994 if (inFile.exists()) {\r
1995 FileInputStream fis = new FileInputStream (inFile);\r
1996 fis.read(buffer);\r
1997 FileOutputStream fos = new FileOutputStream(outFile);\r
1998 fos.write(buffer);\r
1999 fis.close();\r
2000 fos.close();\r
5f907e4a 2001 } else {\r
391dbbb1 2002 throw new AutoGenException("The file, flashMap.h doesn't exist!");\r
31a9215c 2003 }\r
5f907e4a 2004 } catch (Exception e) {\r
31a9215c 2005 throw new AutoGenException(e.getMessage());\r
73b4e31a 2006 }\r
5f907e4a 2007 }\r
73b4e31a 2008 }\r
ff225cbb 2009\r
2336382f 2010 /**\r
2011 *This function first order the library instances, then collect\r
2012 *library instance 's PPI, Protocol, GUID,\r
2013 *SetVirtalAddressMapCallBack, ExitBootServiceCallBack, and\r
2014 *Destructor, Constructor.\r
2015 *\r
5f907e4a 2016 **/\r
2017 private void collectLibInstanceInfo(){\r
2018 int index;\r
2019\r
2020 String moduleType = SurfaceAreaQuery.getModuleType();\r
2021 String libConstructName = null;\r
2022 String libDestructName = null;\r
2023 String[] setVirtuals = null;\r
2024 String[] exitBoots = null;\r
2025\r
2026 ModuleIdentification[] libraryIdList = SurfaceAreaQuery\r
2027 .getLibraryInstance(this.arch);\r
2028 try {\r
2029 if (libraryIdList != null) {\r
2030 //\r
2031 // Reorder library instance sequence.\r
2032 //\r
2033 AutogenLibOrder libOrder = new AutogenLibOrder(libraryIdList,\r
2034 this.arch);\r
2035 List<ModuleIdentification> orderList = libOrder\r
2036 .orderLibInstance();\r
2037\r
2038 if (orderList != null) {\r
2039 //\r
2040 // Process library instance one by one.\r
2041 //\r
2042 for (int i = 0; i < orderList.size(); i++) {\r
2043\r
2044 //\r
2045 // Get library instance basename.\r
2046 //\r
2047 ModuleIdentification libInstanceId = orderList.get(i);\r
2048\r
2049 //\r
2050 // Get override map\r
2051 //\r
2052\r
2053 Map<String, XmlObject> libDoc = GlobalData.getDoc(\r
2054 libInstanceId, this.arch);\r
2055 SurfaceAreaQuery.push(libDoc);\r
2056 //\r
2057 // Get <PPis>, <Protocols>, <Guids> list of this library\r
2058 // instance.\r
2059 //\r
2060 String[] ppiList = SurfaceAreaQuery.getPpiArray(this.arch);\r
2061 String[] ppiNotifyList = SurfaceAreaQuery\r
2062 .getPpiNotifyArray(this.arch);\r
2063 String[] protocolList = SurfaceAreaQuery\r
2064 .getProtocolArray(this.arch);\r
2065 String[] protocolNotifyList = SurfaceAreaQuery\r
2066 .getProtocolNotifyArray(this.arch);\r
2067 String[] guidList = SurfaceAreaQuery\r
2068 .getGuidEntryArray(this.arch);\r
2069 PackageIdentification[] pkgList = SurfaceAreaQuery.getDependencePkg(this.arch);\r
2070\r
2071 //\r
2072 // Add those ppi, protocol, guid in global ppi,\r
2073 // protocol, guid\r
2074 // list.\r
2075 //\r
2076 for (index = 0; index < ppiList.length; index++) {\r
2077 this.mPpiList.add(ppiList[index]);\r
2078 }\r
2079\r
2080 for (index = 0; index < ppiNotifyList.length; index++) {\r
2081 this.mPpiList.add(ppiNotifyList[index]);\r
2082 }\r
2083\r
2084 for (index = 0; index < protocolList.length; index++) {\r
2085 this.mProtocolList.add(protocolList[index]);\r
2086 }\r
2087\r
2088 for (index = 0; index < protocolNotifyList.length; index++) {\r
2089 this.mProtocolList.add(protocolNotifyList[index]);\r
2090 }\r
2091\r
2092 for (index = 0; index < guidList.length; index++) {\r
2093 this.mGuidList.add(guidList[index]);\r
2094 }\r
2095 for (index = 0; index < pkgList.length; index++) {\r
2096 if (!this.mDepPkgList.contains(pkgList[index])) {\r
2097 this.mDepPkgList.add(pkgList[index]);\r
2098 }\r
2099 }\r
2100\r
2101 //\r
2102 // If not yet parse this library instance's constructor\r
2103 // element,parse it.\r
2104 //\r
2105 libConstructName = SurfaceAreaQuery\r
2106 .getLibConstructorName();\r
2107 libDestructName = SurfaceAreaQuery\r
2108 .getLibDestructorName();\r
2109\r
2110 //\r
2111 // Collect SetVirtualAddressMapCallBack and\r
2112 // ExitBootServiceCallBack.\r
2113 //\r
2336382f 2114 setVirtuals = SurfaceAreaQuery.getSetVirtualAddressMapCallBackArray();\r
2115 exitBoots = SurfaceAreaQuery.getExitBootServicesCallBackArray();\r
2116 if (setVirtuals != null) {\r
2117 for (int j = 0; j < setVirtuals.length; j++) {\r
5f907e4a 2118 this.setVirtalAddList.add(setVirtuals[j]);\r
2119 }\r
2120 }\r
2121 if (exitBoots != null) {\r
2122 for (int k = 0; k < exitBoots.length; k++) {\r
2123 this.exitBootServiceList.add(exitBoots[k]);\r
2124 }\r
2125 }\r
2126 SurfaceAreaQuery.pop();\r
2127 //\r
2128 // Add dependent library instance constructor function.\r
2129 //\r
2130 if (libConstructName != null) {\r
2131 this.libConstructList.add(libConstructName);\r
2132 }\r
2133 //\r
2134 // Add dependent library instance destructor fuction.\r
2135 //\r
2136 if (libDestructName != null) {\r
2137 this.libDestructList.add(libDestructName);\r
2138 }\r
2139 }\r
2140 }\r
2141\r
2142 }\r
2143\r
2144 } catch (Exception e) {\r
2145 System.out.println(e.getMessage());\r
2146 System.out.println("Collect library instance failed!");\r
2147 }\r
2148 }\r
2336382f 2149}\r