Sync EDKII BaseTools to BaseTools project r1903.
[efi/edk2/.git] / edk2 / BaseTools / Source / Python / AutoGen / GenC.py
1 ## @file
2 # Routines for generating AutoGen.h and AutoGen.c
3 #
4 # Copyright (c) 2007 - 2010, Intel Corporation
5 # All rights reserved. This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution.  The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
9 #
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 #
13
14 ## Import Modules
15 #
16 import string
17
18 from Common import EdkLogger
19
20 from Common.BuildToolError import *
21 from Common.DataType import *
22 from Common.Misc import *
23 from Common.String import StringToArray
24 from StrGather import *
25
26 ## PCD type string
27 gItemTypeStringDatabase  = {
28     TAB_PCDS_FEATURE_FLAG       :   'FixedAtBuild',
29     TAB_PCDS_FIXED_AT_BUILD     :   'FixedAtBuild',
30     TAB_PCDS_PATCHABLE_IN_MODULE:   'BinaryPatch',
31     TAB_PCDS_DYNAMIC            :   '',
32     TAB_PCDS_DYNAMIC_DEFAULT    :   '',
33     TAB_PCDS_DYNAMIC_VPD        :   '',
34     TAB_PCDS_DYNAMIC_HII        :   '',
35     TAB_PCDS_DYNAMIC_EX         :   '',
36     TAB_PCDS_DYNAMIC_EX_DEFAULT :   '',
37     TAB_PCDS_DYNAMIC_EX_VPD     :   '',
38     TAB_PCDS_DYNAMIC_EX_HII     :   '',
39 }
40
41 ## Dynamic PCD types
42 gDynamicPcd = [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII]
43
44 ## Dynamic-ex PCD types
45 gDynamicExPcd = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII]
46
47 ## Datum size
48 gDatumSizeStringDatabase = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOLEAN','VOID*':'8'}
49 gDatumSizeStringDatabaseH = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOL','VOID*':'PTR'}
50 gDatumSizeStringDatabaseLib = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'Bool','VOID*':'Ptr'}
51
52 ## Mapping between PCD driver type and EFI phase
53 gPcdPhaseMap = {
54     "PEI_PCD_DRIVER"    :   "PEI",
55     "DXE_PCD_DRIVER"    :   "DXE"
56 }
57
58 gPcdDatabaseCommonAutoGenH = """
59 //
60 // The following definition will be generated by build tool
61 //
62
63 //
64 // Common definitions
65 //
66 typedef UINT8 SKU_ID;
67
68 #define PCD_TYPE_SHIFT        28
69
70 #define PCD_TYPE_DATA         (0x0 << PCD_TYPE_SHIFT)
71 #define PCD_TYPE_HII          (0x8 << PCD_TYPE_SHIFT)
72 #define PCD_TYPE_VPD          (0x4 << PCD_TYPE_SHIFT)
73 #define PCD_TYPE_SKU_ENABLED  (0x2 << PCD_TYPE_SHIFT)
74 #define PCD_TYPE_STRING       (0x1 << PCD_TYPE_SHIFT)
75
76 #define PCD_TYPE_ALL_SET      (PCD_TYPE_DATA | PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING)
77
78 #define PCD_DATUM_TYPE_SHIFT  24
79
80 #define PCD_DATUM_TYPE_POINTER  (0x0 << PCD_DATUM_TYPE_SHIFT)
81 #define PCD_DATUM_TYPE_UINT8    (0x1 << PCD_DATUM_TYPE_SHIFT)
82 #define PCD_DATUM_TYPE_UINT16   (0x2 << PCD_DATUM_TYPE_SHIFT)
83 #define PCD_DATUM_TYPE_UINT32   (0x4 << PCD_DATUM_TYPE_SHIFT)
84 #define PCD_DATUM_TYPE_UINT64   (0x8 << PCD_DATUM_TYPE_SHIFT)
85
86 #define PCD_DATUM_TYPE_ALL_SET  (PCD_DATUM_TYPE_POINTER | \\
87                                  PCD_DATUM_TYPE_UINT8   | \\
88                                  PCD_DATUM_TYPE_UINT16  | \\
89                                  PCD_DATUM_TYPE_UINT32  | \\
90                                  PCD_DATUM_TYPE_UINT64)
91
92 #define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_ALL_SET | PCD_DATUM_TYPE_ALL_SET))
93
94 typedef struct  {
95   UINT32  ExTokenNumber;
96   UINT16  LocalTokenNumber;   // PCD Number of this particular platform build
97   UINT16  ExGuidIndex;        // Index of GuidTable
98 } DYNAMICEX_MAPPING;
99
100 typedef struct {
101   UINT32  SkuDataStartOffset; //We have to use offsetof MACRO as we don't know padding done by compiler
102   UINT32  SkuIdTableOffset;   //Offset from the PCD_DB
103 } SKU_HEAD;
104
105 typedef struct {
106   UINT16  GuidTableIndex;     // Offset in Guid Table in units of GUID.
107   UINT16  StringIndex;        // Offset in String Table in units of UINT16.
108   UINT16  Offset;             // Offset in Variable
109   UINT16  DefaultValueOffset; // Offset of the Default Value
110 } VARIABLE_HEAD;
111
112 typedef  struct {
113   UINT32  Offset;
114 } VPD_HEAD;
115
116 typedef UINT16 STRING_HEAD;
117
118 typedef UINT16 SIZE_INFO;
119
120 #define offsetof(s,m)  (UINT32) (UINTN) &(((s *)0)->m)
121
122 """
123
124 gPcdDatabaseEpilogueAutoGenH = """
125 typedef struct {
126   PEI_PCD_DATABASE PeiDb;
127   DXE_PCD_DATABASE DxeDb;
128 } PCD_DATABASE;
129
130 #define PCD_TOTAL_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER)
131
132 """
133
134 gPcdDatabaseAutoGenH = TemplateString("""
135 #define ${PHASE}_GUID_TABLE_SIZE                ${GUID_TABLE_SIZE}
136 #define ${PHASE}_STRING_TABLE_SIZE              ${STRING_TABLE_SIZE}
137 #define ${PHASE}_SKUID_TABLE_SIZE               ${SKUID_TABLE_SIZE}
138 #define ${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE  ${LOCAL_TOKEN_NUMBER_TABLE_SIZE}
139 #define ${PHASE}_LOCAL_TOKEN_NUMBER             ${LOCAL_TOKEN_NUMBER}
140 #define ${PHASE}_EXMAPPING_TABLE_SIZE           ${EXMAPPING_TABLE_SIZE}
141 #define ${PHASE}_EX_TOKEN_NUMBER                ${EX_TOKEN_NUMBER}
142 #define ${PHASE}_SIZE_TABLE_SIZE                ${SIZE_TABLE_SIZE}
143 #define ${PHASE}_GUID_TABLE_EMPTY               ${GUID_TABLE_EMPTY}
144 #define ${PHASE}_STRING_TABLE_EMPTY             ${STRING_TABLE_EMPTY}
145 #define ${PHASE}_SKUID_TABLE_EMPTY              ${SKUID_TABLE_EMPTY}
146 #define ${PHASE}_DATABASE_EMPTY                 ${DATABASE_EMPTY}
147 #define ${PHASE}_EXMAP_TABLE_EMPTY              ${EXMAP_TABLE_EMPTY}
148
149 typedef struct {
150 ${BEGIN}  UINT64             ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}];
151 ${END}
152 ${BEGIN}  UINT64             ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64};
153 ${END}
154 ${BEGIN}  UINT32             ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}];
155 ${END}
156 ${BEGIN}  UINT32             ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32};
157 ${END}
158 ${BEGIN}  VPD_HEAD           ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}];
159 ${END}
160   DYNAMICEX_MAPPING  ExMapTable[${PHASE}_EXMAPPING_TABLE_SIZE];
161   UINT32             LocalTokenNumberTable[${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE];
162   GUID               GuidTable[${PHASE}_GUID_TABLE_SIZE];
163 ${BEGIN}  STRING_HEAD        ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}];
164 ${END}
165 ${BEGIN}  VARIABLE_HEAD      ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}_Variable_Header[${VARIABLE_HEAD_NUMSKUS_DECL}];
166 ${END}
167 ${BEGIN}  UINT8              StringTable${STRING_TABLE_INDEX}[${STRING_TABLE_LENGTH}]; /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */
168 ${END}
169   SIZE_INFO          SizeTable[${PHASE}_SIZE_TABLE_SIZE];
170 ${BEGIN}  UINT16             ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}];
171 ${END}
172 ${BEGIN}  UINT16             ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16};
173 ${END}
174 ${BEGIN}  UINT8              ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}];
175 ${END}
176 ${BEGIN}  UINT8              ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8};
177 ${END}
178 ${BEGIN}  BOOLEAN            ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}];
179 ${END}
180 ${BEGIN}  BOOLEAN            ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN};
181 ${END}
182   UINT8              SkuIdTable[${PHASE}_SKUID_TABLE_SIZE];
183 ${SYSTEM_SKU_ID}
184 } ${PHASE}_PCD_DATABASE_INIT;
185
186 typedef struct {
187 ${PCD_DATABASE_UNINIT_EMPTY}
188 ${BEGIN}  UINT64   ${UNINIT_CNAME_DECL_UINT64}_${UNINIT_GUID_DECL_UINT64}[${UNINIT_NUMSKUS_DECL_UINT64}];
189 ${END}
190 ${BEGIN}  UINT32   ${UNINIT_CNAME_DECL_UINT32}_${UNINIT_GUID_DECL_UINT32}[${UNINIT_NUMSKUS_DECL_UINT32}];
191 ${END}
192 ${BEGIN}  UINT16   ${UNINIT_CNAME_DECL_UINT16}_${UNINIT_GUID_DECL_UINT16}[${UNINIT_NUMSKUS_DECL_UINT16}];
193 ${END}
194 ${BEGIN}  UINT8    ${UNINIT_CNAME_DECL_UINT8}_${UNINIT_GUID_DECL_UINT8}[${UNINIT_NUMSKUS_DECL_UINT8}];
195 ${END}
196 ${BEGIN}  BOOLEAN  ${UNINIT_CNAME_DECL_BOOLEAN}_${UNINIT_GUID_DECL_BOOLEAN}[${UNINIT_NUMSKUS_DECL_BOOLEAN}];
197 ${END}
198 } ${PHASE}_PCD_DATABASE_UNINIT;
199
200 #define PCD_${PHASE}_SERVICE_DRIVER_VERSION         2
201
202 typedef struct {
203   ${PHASE}_PCD_DATABASE_INIT    Init;
204   ${PHASE}_PCD_DATABASE_UNINIT  Uninit;
205 } ${PHASE}_PCD_DATABASE;
206
207 #define ${PHASE}_NEX_TOKEN_NUMBER (${PHASE}_LOCAL_TOKEN_NUMBER - ${PHASE}_EX_TOKEN_NUMBER)
208 """)
209
210 gEmptyPcdDatabaseAutoGenC = TemplateString("""
211 ${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
212   /* ExMapTable */
213   {
214     {0, 0, 0}
215   },
216   /* LocalTokenNumberTable */
217   {
218     0
219   },
220   /* GuidTable */
221   {
222     {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
223   },
224   /* StringTable */
225   { 0 },
226   /* SizeTable */
227   {
228     0, 0
229   },
230   /* SkuIdTable */
231   { 0 },
232   ${SYSTEM_SKU_ID_VALUE}
233 };
234 """)
235
236 gPcdDatabaseAutoGenC = TemplateString("""
237 ${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
238 ${BEGIN}  { ${INIT_VALUE_UINT64} }, /*  ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}] */
239 ${END}
240 ${BEGIN}  ${VARDEF_VALUE_UINT64}, /* ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64} */
241 ${END}
242 ${BEGIN}  { ${INIT_VALUE_UINT32} }, /*  ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}] */
243 ${END}
244 ${BEGIN}  ${VARDEF_VALUE_UINT32}, /* ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32} */
245 ${END}
246   /* VPD */
247 ${BEGIN}  { ${VPD_HEAD_VALUE} }, /* ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}] */
248 ${END}
249   /* ExMapTable */
250   {
251 ${BEGIN}    { ${EXMAPPING_TABLE_EXTOKEN}, ${EXMAPPING_TABLE_LOCAL_TOKEN}, ${EXMAPPING_TABLE_GUID_INDEX} },
252 ${END}
253   },
254   /* LocalTokenNumberTable */
255   {
256 ${BEGIN}    offsetof(${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.${TOKEN_CNAME}_${TOKEN_GUID}${VARDEF_HEADER}) | ${TOKEN_TYPE},
257 ${END}
258   },
259   /* GuidTable */
260   {
261 ${BEGIN}    ${GUID_STRUCTURE},
262 ${END}
263   },
264 ${BEGIN}  { ${STRING_HEAD_VALUE} }, /* ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}] */
265 ${END}
266 ${BEGIN}  /* ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}_Variable_Header[${VARIABLE_HEAD_NUMSKUS_DECL}] */
267   {
268     ${VARIABLE_HEAD_VALUE}
269   },
270 ${END}
271  /* StringTable */
272 ${BEGIN}  ${STRING_TABLE_VALUE}, /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */
273 ${END}
274   /* SizeTable */
275   {
276 ${BEGIN}    ${SIZE_TABLE_MAXIMUM_LENGTH}, ${SIZE_TABLE_CURRENT_LENGTH}, /* ${SIZE_TABLE_CNAME}_${SIZE_TABLE_GUID} */
277 ${END}
278   },
279 ${BEGIN}  { ${INIT_VALUE_UINT16} }, /*  ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}] */
280 ${END}
281 ${BEGIN}  ${VARDEF_VALUE_UINT16}, /* ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16} */
282 ${END}
283 ${BEGIN}  { ${INIT_VALUE_UINT8} }, /*  ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}] */
284 ${END}
285 ${BEGIN}  ${VARDEF_VALUE_UINT8}, /* ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8} */
286 ${END}
287 ${BEGIN}  { ${INIT_VALUE_BOOLEAN} }, /*  ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}] */
288 ${END}
289 ${BEGIN}  ${VARDEF_VALUE_BOOLEAN}, /* ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN} */
290 ${END}
291   /* SkuIdTable */
292   { ${BEGIN}${SKUID_VALUE}, ${END} },
293   ${SYSTEM_SKU_ID_VALUE}
294 };
295 """)
296
297
298 ## AutoGen File Header Templates
299 gAutoGenHeaderString = TemplateString("""\
300 /**
301   DO NOT EDIT
302   FILE auto-generated
303   Module name:
304     ${FileName}
305   Abstract:       Auto-generated ${FileName} for building module or library.
306 **/
307 """)
308
309 gAutoGenHPrologueString = TemplateString("""
310 #ifndef _${File}_${Guid}
311 #define _${File}_${Guid}
312
313 """)
314
315 gAutoGenHEpilogueString = """
316 #endif
317 """
318
319 ## PEI Core Entry Point Templates
320 gPeiCoreEntryPointPrototype = TemplateString("""
321 ${BEGIN}
322 VOID
323 EFIAPI
324 ${Function} (
325   IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,
326   IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,
327   IN VOID                           *Context
328   );
329 ${END}
330 """)
331
332 gPeiCoreEntryPointString = TemplateString("""
333 ${BEGIN}
334 VOID
335 EFIAPI
336 ProcessModuleEntryPointList (
337   IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,
338   IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,
339   IN VOID                           *Context
340   )
341
342 {
343   ${Function} (SecCoreData, PpiList, Context);
344 }
345 ${END}
346 """)
347
348
349 ## DXE Core Entry Point Templates
350 gDxeCoreEntryPointPrototype = TemplateString("""
351 ${BEGIN}
352 VOID
353 EFIAPI
354 ${Function} (
355   IN VOID  *HobStart
356   );
357 ${END}
358 """)
359
360 gDxeCoreEntryPointString = TemplateString("""
361 ${BEGIN}
362 VOID
363 EFIAPI
364 ProcessModuleEntryPointList (
365   IN VOID  *HobStart
366   )
367
368 {
369   ${Function} (HobStart);
370 }
371 ${END}
372 """)
373
374 ## PEIM Entry Point Templates
375 gPeimEntryPointPrototype = TemplateString("""
376 ${BEGIN}
377 EFI_STATUS
378 EFIAPI
379 ${Function} (
380   IN       EFI_PEI_FILE_HANDLE  FileHandle,
381   IN CONST EFI_PEI_SERVICES     **PeiServices
382   );
383 ${END}
384 """)
385
386 gPeimEntryPointString = [
387 TemplateString("""
388 GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
389
390 EFI_STATUS
391 EFIAPI
392 ProcessModuleEntryPointList (
393   IN       EFI_PEI_FILE_HANDLE  FileHandle,
394   IN CONST EFI_PEI_SERVICES     **PeiServices
395   )
396
397 {
398   return EFI_SUCCESS;
399 }
400 """),
401 TemplateString("""
402 GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
403 ${BEGIN}
404 EFI_STATUS
405 EFIAPI
406 ProcessModuleEntryPointList (
407   IN       EFI_PEI_FILE_HANDLE  FileHandle,
408   IN CONST EFI_PEI_SERVICES     **PeiServices
409   )
410
411 {
412   return ${Function} (FileHandle, PeiServices);
413 }
414 ${END}
415 """),
416 TemplateString("""
417 GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
418
419 EFI_STATUS
420 EFIAPI
421 ProcessModuleEntryPointList (
422   IN       EFI_PEI_FILE_HANDLE  FileHandle,
423   IN CONST EFI_PEI_SERVICES     **PeiServices
424   )
425
426 {
427   EFI_STATUS  Status;
428   EFI_STATUS  CombinedStatus;
429
430   CombinedStatus = EFI_LOAD_ERROR;
431 ${BEGIN}
432   Status = ${Function} (FileHandle, PeiServices);
433   if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {
434     CombinedStatus = Status;
435   }
436 ${END}
437   return CombinedStatus;
438 }
439 """)
440 ]
441
442 ## SMM_CORE Entry Point Templates
443 gSmmCoreEntryPointPrototype = TemplateString("""
444 ${BEGIN}
445 EFI_STATUS
446 EFIAPI
447 ${Function} (
448   IN EFI_HANDLE         ImageHandle,
449   IN EFI_SYSTEM_TABLE   *SystemTable
450   );
451 ${END}
452 """)
453
454 gSmmCoreEntryPointString = TemplateString("""
455 ${BEGIN}
456 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
457 const UINT32 _gDxeRevision = ${PiSpecVersion};
458
459 EFI_STATUS
460 EFIAPI
461 ProcessModuleEntryPointList (
462   IN EFI_HANDLE         ImageHandle,
463   IN EFI_SYSTEM_TABLE   *SystemTable
464   )
465 {
466   return ${Function} (ImageHandle, SystemTable);
467 }
468 ${END}
469 """)
470
471 ## DXE SMM Entry Point Templates
472 gDxeSmmEntryPointPrototype = TemplateString("""
473 ${BEGIN}
474 EFI_STATUS
475 EFIAPI
476 ${Function} (
477   IN EFI_HANDLE        ImageHandle,
478   IN EFI_SYSTEM_TABLE  *SystemTable
479   );
480 ${END}
481 """)
482
483 gDxeSmmEntryPointString = [
484 TemplateString("""
485 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
486 const UINT32 _gDxeRevision = ${PiSpecVersion};
487
488 EFI_STATUS
489 EFIAPI
490 ProcessModuleEntryPointList (
491   IN EFI_HANDLE        ImageHandle,
492   IN EFI_SYSTEM_TABLE  *SystemTable
493   )
494
495 {
496   return EFI_SUCCESS;
497 }
498 """),
499 TemplateString("""
500 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
501 const UINT32 _gDxeRevision = ${PiSpecVersion};
502
503 static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
504 static EFI_STATUS  mDriverEntryPointStatus;
505
506 VOID
507 EFIAPI
508 ExitDriver (
509   IN EFI_STATUS  Status
510   )
511 {
512   if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
513     mDriverEntryPointStatus = Status;
514   }
515   LongJump (&mJumpContext, (UINTN)-1);
516   ASSERT (FALSE);
517 }
518
519 EFI_STATUS
520 EFIAPI
521 ProcessModuleEntryPointList (
522   IN EFI_HANDLE        ImageHandle,
523   IN EFI_SYSTEM_TABLE  *SystemTable
524   )
525 {
526   mDriverEntryPointStatus = EFI_LOAD_ERROR;
527
528 ${BEGIN}
529   if (SetJump (&mJumpContext) == 0) {
530     ExitDriver (${Function} (ImageHandle, SystemTable));
531     ASSERT (FALSE);
532   }
533 ${END}
534
535   return mDriverEntryPointStatus;
536 }
537 """)
538 ]
539
540 ## UEFI Driver Entry Point Templates
541 gUefiDriverEntryPointPrototype = TemplateString("""
542 ${BEGIN}
543 EFI_STATUS
544 EFIAPI
545 ${Function} (
546   IN EFI_HANDLE        ImageHandle,
547   IN EFI_SYSTEM_TABLE  *SystemTable
548   );
549 ${END}
550 """)
551
552 gUefiDriverEntryPointString = [
553 TemplateString("""
554 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
555 const UINT32 _gDxeRevision = ${PiSpecVersion};
556
557 EFI_STATUS
558 EFIAPI
559 ProcessModuleEntryPointList (
560   IN EFI_HANDLE        ImageHandle,
561   IN EFI_SYSTEM_TABLE  *SystemTable
562   )
563 {
564   return EFI_SUCCESS;
565 }
566 """),
567 TemplateString("""
568 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
569 const UINT32 _gDxeRevision = ${PiSpecVersion};
570
571 ${BEGIN}
572 EFI_STATUS
573 EFIAPI
574 ProcessModuleEntryPointList (
575   IN EFI_HANDLE        ImageHandle,
576   IN EFI_SYSTEM_TABLE  *SystemTable
577   )
578
579 {
580   return ${Function} (ImageHandle, SystemTable);
581 }
582 ${END}
583 VOID
584 EFIAPI
585 ExitDriver (
586   IN EFI_STATUS  Status
587   )
588 {
589   if (EFI_ERROR (Status)) {
590     ProcessLibraryDestructorList (gImageHandle, gST);
591   }
592   gBS->Exit (gImageHandle, Status, 0, NULL);
593 }
594 """),
595 TemplateString("""
596 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
597 const UINT32 _gDxeRevision = ${PiSpecVersion};
598
599 static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
600 static EFI_STATUS  mDriverEntryPointStatus;
601
602 EFI_STATUS
603 EFIAPI
604 ProcessModuleEntryPointList (
605   IN EFI_HANDLE        ImageHandle,
606   IN EFI_SYSTEM_TABLE  *SystemTable
607   )
608 {
609   mDriverEntryPointStatus = EFI_LOAD_ERROR;
610   ${BEGIN}
611   if (SetJump (&mJumpContext) == 0) {
612     ExitDriver (${Function} (ImageHandle, SystemTable));
613     ASSERT (FALSE);
614   }
615   ${END}
616   return mDriverEntryPointStatus;
617 }
618
619 VOID
620 EFIAPI
621 ExitDriver (
622   IN EFI_STATUS  Status
623   )
624 {
625   if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
626     mDriverEntryPointStatus = Status;
627   }
628   LongJump (&mJumpContext, (UINTN)-1);
629   ASSERT (FALSE);
630 }
631 """)
632 ]
633
634
635 ## UEFI Application Entry Point Templates
636 gUefiApplicationEntryPointPrototype = TemplateString("""
637 ${BEGIN}
638 EFI_STATUS
639 EFIAPI
640 ${Function} (
641   IN EFI_HANDLE        ImageHandle,
642   IN EFI_SYSTEM_TABLE  *SystemTable
643   );
644 ${END}
645 """)
646
647 gUefiApplicationEntryPointString = [
648 TemplateString("""
649 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
650
651 EFI_STATUS
652 EFIAPI
653 ProcessModuleEntryPointList (
654   IN EFI_HANDLE        ImageHandle,
655   IN EFI_SYSTEM_TABLE  *SystemTable
656   )
657 {
658   return EFI_SUCCESS;
659 }
660 """),
661 TemplateString("""
662 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
663
664 ${BEGIN}
665 EFI_STATUS
666 EFIAPI
667 ProcessModuleEntryPointList (
668   IN EFI_HANDLE        ImageHandle,
669   IN EFI_SYSTEM_TABLE  *SystemTable
670   )
671
672 {
673   return ${Function} (ImageHandle, SystemTable);
674 }
675 ${END}
676 VOID
677 EFIAPI
678 ExitDriver (
679   IN EFI_STATUS  Status
680   )
681 {
682   if (EFI_ERROR (Status)) {
683     ProcessLibraryDestructorList (gImageHandle, gST);
684   }
685   gBS->Exit (gImageHandle, Status, 0, NULL);
686 }
687 """),
688 TemplateString("""
689 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
690
691 EFI_STATUS
692 EFIAPI
693 ProcessModuleEntryPointList (
694   IN EFI_HANDLE        ImageHandle,
695   IN EFI_SYSTEM_TABLE  *SystemTable
696   )
697
698 {
699   ${BEGIN}
700   if (SetJump (&mJumpContext) == 0) {
701     ExitDriver (${Function} (ImageHandle, SystemTable));
702     ASSERT (FALSE);
703   }
704   ${END}
705   return mDriverEntryPointStatus;
706 }
707
708 static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
709 static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;
710
711 VOID
712 EFIAPI
713 ExitDriver (
714   IN EFI_STATUS  Status
715   )
716 {
717   if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
718     mDriverEntryPointStatus = Status;
719   }
720   LongJump (&mJumpContext, (UINTN)-1);
721   ASSERT (FALSE);
722 }
723 """)
724 ]
725
726 ## UEFI Unload Image Templates
727 gUefiUnloadImagePrototype = TemplateString("""
728 ${BEGIN}
729 EFI_STATUS
730 EFIAPI
731 ${Function} (
732   IN EFI_HANDLE        ImageHandle
733   );
734 ${END}
735 """)
736
737 gUefiUnloadImageString = [
738 TemplateString("""
739 GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
740
741 EFI_STATUS
742 EFIAPI
743 ProcessModuleUnloadList (
744   IN EFI_HANDLE        ImageHandle
745   )
746 {
747   return EFI_SUCCESS;
748 }
749 """),
750 TemplateString("""
751 GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
752
753 ${BEGIN}
754 EFI_STATUS
755 EFIAPI
756 ProcessModuleUnloadList (
757   IN EFI_HANDLE        ImageHandle
758   )
759 {
760   return ${Function} (ImageHandle);
761 }
762 ${END}
763 """),
764 TemplateString("""
765 GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
766
767 EFI_STATUS
768 EFIAPI
769 ProcessModuleUnloadList (
770   IN EFI_HANDLE        ImageHandle
771   )
772 {
773   EFI_STATUS  Status;
774
775   Status = EFI_SUCCESS;
776 ${BEGIN}
777   if (EFI_ERROR (Status)) {
778     ${Function} (ImageHandle);
779   } else {
780     Status = ${Function} (ImageHandle);
781   }
782 ${END}
783   return Status;
784 }
785 """)
786 ]
787
788 gLibraryStructorPrototype = {
789 'BASE'  : TemplateString("""${BEGIN}
790 RETURN_STATUS
791 EFIAPI
792 ${Function} (
793   VOID
794   );${END}
795 """),
796
797 'PEI'   : TemplateString("""${BEGIN}
798 EFI_STATUS
799 EFIAPI
800 ${Function} (
801   IN       EFI_PEI_FILE_HANDLE       FileHandle,
802   IN CONST EFI_PEI_SERVICES          **PeiServices
803   );${END}
804 """),
805
806 'DXE'   : TemplateString("""${BEGIN}
807 EFI_STATUS
808 EFIAPI
809 ${Function} (
810   IN EFI_HANDLE        ImageHandle,
811   IN EFI_SYSTEM_TABLE  *SystemTable
812   );${END}
813 """),
814 }
815
816 gLibraryStructorCall = {
817 'BASE'  : TemplateString("""${BEGIN}
818   Status = ${Function} ();
819   ASSERT_EFI_ERROR (Status);${END}
820 """),
821
822 'PEI'   : TemplateString("""${BEGIN}
823   Status = ${Function} (FileHandle, PeiServices);
824   ASSERT_EFI_ERROR (Status);${END}
825 """),
826
827 'DXE'   : TemplateString("""${BEGIN}
828   Status = ${Function} (ImageHandle, SystemTable);
829   ASSERT_EFI_ERROR (Status);${END}
830 """),
831 }
832
833 ## Library Constructor and Destructor Templates
834 gLibraryString = {
835 'BASE'  :   TemplateString("""
836 ${BEGIN}${FunctionPrototype}${END}
837
838 VOID
839 EFIAPI
840 ProcessLibrary${Type}List (
841   VOID
842   )
843 {
844 ${BEGIN}  EFI_STATUS  Status;
845 ${FunctionCall}${END}
846 }
847 """),
848
849 'PEI'   :   TemplateString("""
850 ${BEGIN}${FunctionPrototype}${END}
851
852 VOID
853 EFIAPI
854 ProcessLibrary${Type}List (
855   IN       EFI_PEI_FILE_HANDLE       FileHandle,
856   IN CONST EFI_PEI_SERVICES          **PeiServices
857   )
858 {
859 ${BEGIN}  EFI_STATUS  Status;
860 ${FunctionCall}${END}
861 }
862 """),
863
864 'DXE'   :   TemplateString("""
865 ${BEGIN}${FunctionPrototype}${END}
866
867 VOID
868 EFIAPI
869 ProcessLibrary${Type}List (
870   IN EFI_HANDLE        ImageHandle,
871   IN EFI_SYSTEM_TABLE  *SystemTable
872   )
873 {
874 ${BEGIN}  EFI_STATUS  Status;
875 ${FunctionCall}${END}
876 }
877 """),
878 }
879
880 gBasicHeaderFile = "Base.h"
881
882 gModuleTypeHeaderFile = {
883     "BASE"              :   [gBasicHeaderFile],
884     "SEC"               :   ["PiPei.h", "Library/DebugLib.h"],
885     "PEI_CORE"          :   ["PiPei.h", "Library/DebugLib.h", "Library/PeiCoreEntryPoint.h"],
886     "PEIM"              :   ["PiPei.h", "Library/DebugLib.h", "Library/PeimEntryPoint.h"],
887     "DXE_CORE"          :   ["PiDxe.h", "Library/DebugLib.h", "Library/DxeCoreEntryPoint.h"],
888     "DXE_DRIVER"        :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
889     "DXE_SMM_DRIVER"    :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
890     "DXE_RUNTIME_DRIVER":   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
891     "DXE_SAL_DRIVER"    :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
892     "UEFI_DRIVER"       :   ["Uefi.h",  "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
893     "UEFI_APPLICATION"  :   ["Uefi.h",  "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiApplicationEntryPoint.h"],
894     "SMM_CORE"          :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiDriverEntryPoint.h"],
895     "USER_DEFINED"      :   [gBasicHeaderFile]
896 }
897
898 ## Create code for module PCDs
899 #
900 #   @param      Info        The ModuleAutoGen object
901 #   @param      AutoGenC    The TemplateString object for C code
902 #   @param      AutoGenH    The TemplateString object for header file
903 #   @param      Pcd         The PCD object
904 #
905 def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
906     TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[Pcd.TokenSpaceGuidCName]
907     PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
908     #
909     # Write PCDs
910     #
911     PcdTokenName = '_PCD_TOKEN_' + Pcd.TokenCName
912     if Pcd.Type in gDynamicExPcd:
913         TokenNumber = int(Pcd.TokenValue, 0)
914     else:
915         if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
916             EdkLogger.error("build", AUTOGEN_ERROR,
917                             "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
918                             ExtraData="[%s]" % str(Info))
919         TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
920     AutoGenH.Append('\n#define %s  %d\n' % (PcdTokenName, TokenNumber))
921
922     EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + Pcd.TokenCName + "." + Pcd.TokenSpaceGuidCName)
923     if Pcd.Type not in gItemTypeStringDatabase:
924         EdkLogger.error("build", AUTOGEN_ERROR,
925                         "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
926                         ExtraData="[%s]" % str(Info))
927     if Pcd.DatumType not in gDatumSizeStringDatabase:
928         EdkLogger.error("build", AUTOGEN_ERROR,
929                         "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
930                         ExtraData="[%s]" % str(Info))
931
932     DatumSize = gDatumSizeStringDatabase[Pcd.DatumType]
933     DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]
934     GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
935     SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
936
937     if Pcd.Type in gDynamicExPcd:
938         AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
939         if Pcd.DatumType == 'VOID*':
940             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
941         else:
942             AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
943     elif Pcd.Type in gDynamicPcd:
944         AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
945         if Pcd.DatumType == 'VOID*':
946             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
947         else:
948             AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
949     else:
950         PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName
951         Const = 'const'
952         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
953             Const = ''
954         Type = ''
955         Array = ''
956         Value = Pcd.DefaultValue
957         Unicode = False
958         ValueNumber = 0
959         if Pcd.DatumType in ['UINT64', 'UINT32', 'UINT16', 'UINT8']:
960             try:
961                 if Value.upper().startswith('0X'):
962                     ValueNumber = int (Value, 16)
963                 else:
964                     ValueNumber = int (Value)
965             except:
966                 EdkLogger.error("build", AUTOGEN_ERROR,
967                                 "PCD value is not valid dec or hex number for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
968                                 ExtraData="[%s]" % str(Info))
969             if Pcd.DatumType == 'UINT64':
970                 if ValueNumber < 0:
971                     EdkLogger.error("build", AUTOGEN_ERROR,
972                                     "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
973                                     ExtraData="[%s]" % str(Info))
974                 elif ValueNumber >= 0x10000000000000000:
975                     EdkLogger.error("build", AUTOGEN_ERROR,
976                                     "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
977                                     ExtraData="[%s]" % str(Info))
978                 if not Value.endswith('ULL'):
979                     Value += 'ULL'
980             elif Pcd.DatumType == 'UINT32':
981                 if ValueNumber < 0:
982                     EdkLogger.error("build", AUTOGEN_ERROR,
983                                     "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
984                                     ExtraData="[%s]" % str(Info))
985                 elif ValueNumber >= 0x100000000:
986                     EdkLogger.error("build", AUTOGEN_ERROR,
987                                     "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
988                                     ExtraData="[%s]" % str(Info))
989             elif Pcd.DatumType == 'UINT16':
990                 if ValueNumber < 0:
991                     EdkLogger.error("build", AUTOGEN_ERROR,
992                                     "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
993                                     ExtraData="[%s]" % str(Info))
994                 elif ValueNumber >= 0x10000:
995                     EdkLogger.error("build", AUTOGEN_ERROR,
996                                     "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
997                                     ExtraData="[%s]" % str(Info))
998             elif Pcd.DatumType == 'UINT8':
999                 if ValueNumber < 0:
1000                     EdkLogger.error("build", AUTOGEN_ERROR,
1001                                     "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
1002                                     ExtraData="[%s]" % str(Info))
1003                 elif ValueNumber >= 0x100:
1004                     EdkLogger.error("build", AUTOGEN_ERROR,
1005                                     "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
1006                                     ExtraData="[%s]" % str(Info))
1007         if Pcd.DatumType == 'VOID*':
1008             if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
1009                 EdkLogger.error("build", AUTOGEN_ERROR,
1010                                 "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
1011                                 ExtraData="[%s]" % str(Info))
1012
1013             ArraySize = int(Pcd.MaxDatumSize, 0)
1014             if Value[0] == '{':
1015                 Type = '(VOID *)'
1016             else:
1017                 if Value[0] == 'L':
1018                     Unicode = True
1019                 Value = Value.lstrip('L')   #.strip('"')
1020                 Value = eval(Value)         # translate escape character
1021                 NewValue = '{'
1022                 for Index in range(0,len(Value)):
1023                     if Unicode:
1024                         NewValue = NewValue + str(ord(Value[Index]) % 0x10000) + ', '
1025                     else:
1026                         NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ', '
1027                 if Unicode:
1028                     ArraySize = ArraySize / 2;
1029
1030                 if ArraySize < (len(Value) + 1):
1031                     ArraySize = len(Value) + 1
1032                 Value = NewValue + '0 }'
1033             Array = '[%d]' % ArraySize
1034         #
1035         # skip casting for fixed at build since it breaks ARM assembly.
1036         # Long term we need PCD macros that work in assembly
1037         #
1038         elif Pcd.Type != TAB_PCDS_FIXED_AT_BUILD:
1039             Value = "((%s)%s)" % (Pcd.DatumType, Value)
1040
1041         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
1042             PcdValueName = '_PCD_PATCHABLE_VALUE_' + Pcd.TokenCName
1043         else:
1044             PcdValueName = '_PCD_VALUE_' + Pcd.TokenCName
1045             
1046         if Pcd.DatumType == 'VOID*':
1047             #
1048             # For unicode, UINT16 array will be generated, so the alignment of unicode is guaranteed.
1049             #
1050             if Unicode:
1051                 AutoGenH.Append('#define _PCD_PATCHABLE_%s_SIZE %s\n' % (Pcd.TokenCName, Pcd.MaxDatumSize))
1052                 AutoGenH.Append('#define %s  %s%s\n' %(PcdValueName, Type, PcdVariableName))
1053                 AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT16 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
1054                 AutoGenH.Append('extern %s UINT16 %s%s;\n' %(Const, PcdVariableName, Array))
1055                 AutoGenH.Append('#define %s  %s%s\n' %(GetModeName, Type, PcdVariableName))
1056             else:
1057                 AutoGenH.Append('#define _PCD_PATCHABLE_%s_SIZE %s\n' % (Pcd.TokenCName, Pcd.MaxDatumSize))
1058                 AutoGenH.Append('#define %s  %s%s\n' %(PcdValueName, Type, PcdVariableName))
1059                 AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT8 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
1060                 AutoGenH.Append('extern %s UINT8 %s%s;\n' %(Const, PcdVariableName, Array))
1061                 AutoGenH.Append('#define %s  %s%s\n' %(GetModeName, Type, PcdVariableName))
1062         elif Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
1063             AutoGenH.Append('#define %s  %s\n' %(PcdValueName, Value))
1064             AutoGenC.Append('volatile %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
1065             AutoGenH.Append('extern volatile %s  %s  %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
1066             AutoGenH.Append('#define %s  %s%s\n' % (GetModeName, Type, PcdVariableName))
1067         else:
1068             AutoGenH.Append('#define %s  %s\n' %(PcdValueName, Value))
1069             AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
1070             AutoGenH.Append('extern %s  %s  %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
1071             AutoGenH.Append('#define %s  %s%s\n' % (GetModeName, Type, PcdVariableName))
1072
1073         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
1074             if Pcd.DatumType == 'VOID*':
1075                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtr(_gPcd_BinaryPatch_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName))
1076             else:
1077                 AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))
1078         else:
1079             AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
1080
1081 ## Create code for library module PCDs
1082 #
1083 #   @param      Info        The ModuleAutoGen object
1084 #   @param      AutoGenC    The TemplateString object for C code
1085 #   @param      AutoGenH    The TemplateString object for header file
1086 #   @param      Pcd         The PCD object
1087 #
1088 def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
1089     PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
1090     TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
1091     TokenCName  = Pcd.TokenCName
1092     TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[TokenSpaceGuidCName]
1093     if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
1094         EdkLogger.error("build", AUTOGEN_ERROR,
1095                         "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
1096                         ExtraData="[%s]" % str(Info))
1097     TokenNumber = PcdTokenNumber[TokenCName, TokenSpaceGuidCName]
1098
1099     if Pcd.Type not in gItemTypeStringDatabase:
1100         EdkLogger.error("build", AUTOGEN_ERROR,
1101                         "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
1102                         ExtraData="[%s]" % str(Info))
1103     if Pcd.DatumType not in gDatumSizeStringDatabase:
1104         EdkLogger.error("build", AUTOGEN_ERROR,
1105                         "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
1106                         ExtraData="[%s]" % str(Info))
1107
1108     DatumType   = Pcd.DatumType
1109     DatumSize   = gDatumSizeStringDatabaseH[DatumType]
1110     DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType]
1111     GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName
1112     SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName
1113
1114     Type = ''
1115     Array = ''
1116     if Pcd.DatumType == 'VOID*':
1117         Type = '(VOID *)'
1118         Array = '[]'
1119
1120     AutoGenH.Append('#define _PCD_TOKEN_%s  %d\n' % (TokenCName, TokenNumber))
1121
1122     PcdItemType = Pcd.Type
1123     #if PcdItemType in gDynamicPcd:
1124     #    PcdItemType = TAB_PCDS_FIXED_AT_BUILD
1125     #    if (TokenCName, TokenSpaceGuidCName) in Info.PlatformInfo.Platform.Pcds:
1126     #        PcdItemType  = Info.PlatformInfo.Platform.Pcds[TokenCName, TokenSpaceGuidCName].Type
1127     if PcdItemType in gDynamicExPcd:
1128         PcdTokenName = '_PCD_TOKEN_' + TokenCName
1129         AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))
1130         if DatumType == 'VOID*':
1131             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName,DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))
1132         else:
1133             AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))
1134     if PcdItemType in gDynamicPcd:
1135         PcdTokenName = '_PCD_TOKEN_' + TokenCName
1136         AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
1137         if DatumType == 'VOID*':
1138             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
1139         else:
1140             AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
1141     if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:
1142         PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName
1143         AutoGenH.Append('extern %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) )
1144         AutoGenH.Append('#define %s  %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))
1145         AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))
1146     if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:
1147         AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))
1148         #AutoGenH.Append('#define _PCD_VALUE_%s  _gPcd_FixedAtBuild_%s\n' %(TokenCName, TokenCName))
1149         AutoGenH.Append('#define %s  %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName))
1150         AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
1151
1152 ## Create code for PCD database in DXE or PEI phase
1153 #
1154 #   @param      Platform    The platform object
1155 #   @retval     tuple       Two TemplateString objects for C code and header file,
1156 #                           respectively
1157 #
1158 def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
1159     AutoGenC = TemplateString()
1160     AutoGenH = TemplateString()
1161
1162     Dict = {
1163         'PHASE'                         : Phase,
1164         'GUID_TABLE_SIZE'               : '1',
1165         'STRING_TABLE_SIZE'             : '1',
1166         'SKUID_TABLE_SIZE'              : '1',
1167         'LOCAL_TOKEN_NUMBER_TABLE_SIZE' : '1',
1168         'LOCAL_TOKEN_NUMBER'            : '0',
1169         'EXMAPPING_TABLE_SIZE'          : '1',
1170         'EX_TOKEN_NUMBER'               : '0',
1171         'SIZE_TABLE_SIZE'               : '2',
1172         'GUID_TABLE_EMPTY'              : 'TRUE',
1173         'STRING_TABLE_EMPTY'            : 'TRUE',
1174         'SKUID_TABLE_EMPTY'             : 'TRUE',
1175         'DATABASE_EMPTY'                : 'TRUE',
1176         'EXMAP_TABLE_EMPTY'             : 'TRUE',
1177         'PCD_DATABASE_UNINIT_EMPTY'     : '  UINT8  dummy; /* PCD_DATABASE_UNINIT is emptry */',
1178         'SYSTEM_SKU_ID'                 : '  SKU_ID             SystemSkuId;',
1179         'SYSTEM_SKU_ID_VALUE'           : '0'
1180     }
1181
1182     for DatumType in ['UINT64','UINT32','UINT16','UINT8','BOOLEAN', "VOID*"]:
1183         Dict['VARDEF_CNAME_' + DatumType] = []
1184         Dict['VARDEF_GUID_' + DatumType]  = []
1185         Dict['VARDEF_SKUID_' + DatumType] = []
1186         Dict['VARDEF_VALUE_' + DatumType] = []
1187         for Init in ['INIT','UNINIT']:
1188             Dict[Init+'_CNAME_DECL_' + DatumType]   = []
1189             Dict[Init+'_GUID_DECL_' + DatumType]    = []
1190             Dict[Init+'_NUMSKUS_DECL_' + DatumType] = []
1191             Dict[Init+'_VALUE_' + DatumType]        = []
1192
1193     for Type in ['STRING_HEAD','VPD_HEAD','VARIABLE_HEAD']:
1194         Dict[Type + '_CNAME_DECL']   = []
1195         Dict[Type + '_GUID_DECL']    = []
1196         Dict[Type + '_NUMSKUS_DECL'] = []
1197         Dict[Type + '_VALUE'] = []
1198
1199     Dict['STRING_TABLE_INDEX'] = []
1200     Dict['STRING_TABLE_LENGTH']  = []
1201     Dict['STRING_TABLE_CNAME'] = []
1202     Dict['STRING_TABLE_GUID']  = []
1203     Dict['STRING_TABLE_VALUE'] = []
1204
1205     Dict['SIZE_TABLE_CNAME'] = []
1206     Dict['SIZE_TABLE_GUID']  = []
1207     Dict['SIZE_TABLE_CURRENT_LENGTH']  = []
1208     Dict['SIZE_TABLE_MAXIMUM_LENGTH']  = []
1209
1210     Dict['EXMAPPING_TABLE_EXTOKEN'] = []
1211     Dict['EXMAPPING_TABLE_LOCAL_TOKEN'] = []
1212     Dict['EXMAPPING_TABLE_GUID_INDEX'] = []
1213
1214     Dict['GUID_STRUCTURE'] = []
1215
1216     Dict['SKUID_VALUE'] = []
1217     Dict['VARDEF_HEADER'] = []
1218     if Phase == 'DXE':
1219         Dict['SYSTEM_SKU_ID'] = ''
1220         Dict['SYSTEM_SKU_ID_VALUE'] = ''
1221
1222     StringTableIndex = 0
1223     StringTableSize = 0
1224     NumberOfLocalTokens = 0
1225     NumberOfPeiLocalTokens = 0
1226     NumberOfDxeLocalTokens = 0
1227     NumberOfExTokens = 0
1228     NumberOfSizeItems = 0
1229     GuidList = []
1230
1231     for Pcd in Platform.DynamicPcdList:
1232         CName = Pcd.TokenCName
1233         TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
1234
1235         EdkLogger.debug(EdkLogger.DEBUG_3, "PCD: %s %s (%s : %s)" % (CName, TokenSpaceGuidCName, Pcd.Phase, Phase))
1236         if Pcd.DatumType not in gDatumSizeStringDatabase:
1237             EdkLogger.error("build", AUTOGEN_ERROR,
1238                             "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
1239                             ExtraData="[%s]" % str(Platform))
1240
1241         if Pcd.Phase == 'PEI':
1242             NumberOfPeiLocalTokens += 1
1243         if Pcd.Phase == 'DXE':
1244             NumberOfDxeLocalTokens += 1
1245         if Pcd.Phase != Phase:
1246             continue
1247
1248         #
1249         # TODO: need GetGuidValue() definition
1250         #
1251         TokenSpaceGuidStructure = Pcd.TokenSpaceGuidValue
1252         TokenSpaceGuid = GuidStructureStringToGuidValueName(TokenSpaceGuidStructure)
1253         if Pcd.Type in gDynamicExPcd:
1254             if TokenSpaceGuid not in GuidList:
1255                 GuidList += [TokenSpaceGuid]
1256                 Dict['GUID_STRUCTURE'].append(TokenSpaceGuidStructure)
1257             NumberOfExTokens += 1
1258
1259         ValueList = []
1260         StringHeadOffsetList = []
1261         VpdHeadOffsetList = []
1262         VariableHeadValueList = []
1263         Pcd.InitString = 'UNINIT'
1264
1265         if Pcd.DatumType == 'VOID*':
1266             Pcd.TokenTypeList = ['PCD_TYPE_STRING']
1267         elif Pcd.DatumType == 'BOOLEAN':
1268             Pcd.TokenTypeList = ['PCD_DATUM_TYPE_UINT8']
1269         else:
1270             Pcd.TokenTypeList = ['PCD_DATUM_TYPE_' + Pcd.DatumType]
1271
1272         if len(Pcd.SkuInfoList) > 1:
1273             Pcd.TokenTypeList += ['PCD_TYPE_SKU_ENABLED']
1274
1275         for SkuName in Pcd.SkuInfoList:
1276             Sku = Pcd.SkuInfoList[SkuName]
1277             SkuId = Sku.SkuId
1278             if SkuId == None or SkuId == '':
1279                 continue
1280
1281             if SkuId not in Dict['SKUID_VALUE']:
1282                 Dict['SKUID_VALUE'].append(SkuId)
1283
1284             SkuIdIndex =   Dict['SKUID_VALUE'].index(SkuId)
1285             if len(Sku.VariableName) > 0:
1286                 Pcd.TokenTypeList += ['PCD_TYPE_HII']
1287                 Pcd.InitString = 'INIT'
1288                 VariableNameStructure = StringToArray(Sku.VariableName)
1289                 if VariableNameStructure not in Dict['STRING_TABLE_VALUE']:
1290                     Dict['STRING_TABLE_CNAME'].append(CName)
1291                     Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)
1292                     if StringTableIndex == 0:
1293                         Dict['STRING_TABLE_INDEX'].append('')
1294                     else:
1295                         Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)
1296
1297                     Dict['STRING_TABLE_LENGTH'].append((len(Sku.VariableName) - 3 + 1) * 2)
1298                     Dict['STRING_TABLE_VALUE'].append(VariableNameStructure)
1299                     StringTableIndex += 1
1300                     StringTableSize += (len(Sku.VariableName) - 3 + 1) * 2
1301
1302                 VariableHeadStringIndex = 0
1303                 for Index in range(Dict['STRING_TABLE_VALUE'].index(VariableNameStructure)):
1304                     VariableHeadStringIndex += Dict['STRING_TABLE_LENGTH'][Index]
1305
1306                 VariableGuidStructure = Sku.VariableGuidValue
1307                 VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)
1308                 if VariableGuid not in GuidList:
1309                     GuidList += [VariableGuid]
1310                     Dict['GUID_STRUCTURE'].append(VariableGuidStructure)
1311                 VariableHeadGuidIndex = GuidList.index(VariableGuid)
1312
1313                 if "PCD_TYPE_STRING" in Pcd.TokenTypeList:
1314                     VariableHeadValueList.append('%d, %d, %s, offsetof(%s_PCD_DATABASE, Init.%s_%s)' %
1315                                                  (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset,
1316                                                   Phase, CName, TokenSpaceGuid))
1317                 else:
1318                     VariableHeadValueList.append('%d, %d, %s, offsetof(%s_PCD_DATABASE, Init.%s_%s_VariableDefault_%s)' %
1319                                                  (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset,
1320                                                   Phase, CName, TokenSpaceGuid, SkuIdIndex))
1321                 Dict['VARDEF_CNAME_'+Pcd.DatumType].append(CName)
1322                 Dict['VARDEF_GUID_'+Pcd.DatumType].append(TokenSpaceGuid)
1323                 Dict['VARDEF_SKUID_'+Pcd.DatumType].append(SkuIdIndex)
1324                 if "PCD_TYPE_STRING" in  Pcd.TokenTypeList:
1325                     Dict['VARDEF_VALUE_' + Pcd.DatumType].append("%s_%s[%d]" % (Pcd.TokenCName, TokenSpaceGuid, SkuIdIndex))
1326                 else:
1327                     Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue)
1328             elif Sku.VpdOffset != '':
1329                 Pcd.TokenTypeList += ['PCD_TYPE_VPD']
1330                 Pcd.InitString = 'INIT'
1331                 VpdHeadOffsetList.append(Sku.VpdOffset)
1332             
1333           
1334             if Pcd.DatumType == 'VOID*':
1335                 Pcd.TokenTypeList += ['PCD_TYPE_STRING']
1336                 Pcd.InitString = 'INIT'
1337                 if Sku.HiiDefaultValue != '' and Sku.DefaultValue == '':
1338                     Sku.DefaultValue = Sku.HiiDefaultValue
1339                 if Sku.DefaultValue != '':
1340                     NumberOfSizeItems += 1
1341                     Dict['STRING_TABLE_CNAME'].append(CName)
1342                     Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)
1343
1344                     if StringTableIndex == 0:
1345                         Dict['STRING_TABLE_INDEX'].append('')
1346                     else:
1347                         Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)
1348                     if Sku.DefaultValue[0] == 'L':
1349                         Size = (len(Sku.DefaultValue) - 3 + 1) * 2
1350                         Dict['STRING_TABLE_VALUE'].append(StringToArray(Sku.DefaultValue))
1351                     elif Sku.DefaultValue[0] == '"':
1352                         Size = len(Sku.DefaultValue) - 2 + 1
1353                         Dict['STRING_TABLE_VALUE'].append(StringToArray(Sku.DefaultValue))
1354                     elif Sku.DefaultValue[0] == '{':
1355                         Size = len(Sku.DefaultValue.replace(',',' ').split())
1356                         Dict['STRING_TABLE_VALUE'].append(Sku.DefaultValue)
1357
1358                     StringHeadOffsetList.append(str(StringTableSize))
1359                     Dict['SIZE_TABLE_CNAME'].append(CName)
1360                     Dict['SIZE_TABLE_GUID'].append(TokenSpaceGuid)
1361                     Dict['SIZE_TABLE_CURRENT_LENGTH'].append(Size)
1362                     Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(Pcd.MaxDatumSize)
1363                     if Pcd.MaxDatumSize != '':
1364                         MaxDatumSize = int(Pcd.MaxDatumSize, 0)
1365                         if MaxDatumSize > Size:
1366                             Size = MaxDatumSize
1367                     Dict['STRING_TABLE_LENGTH'].append(Size)
1368                     StringTableIndex += 1
1369                     StringTableSize += (Size)
1370             else:
1371                 if "PCD_TYPE_HII" not in Pcd.TokenTypeList:
1372                     Pcd.TokenTypeList += ['PCD_TYPE_DATA']
1373                     if Sku.DefaultValue == 'TRUE':
1374                         Pcd.InitString = 'INIT'
1375                     else:
1376                         try:
1377                             if int(Sku.DefaultValue, 0) != 0:
1378                                 Pcd.InitString = 'INIT'
1379                         except:
1380                             pass
1381                 
1382                 #
1383                 # For UNIT64 type PCD's value, ULL should be append to avoid
1384                 # warning under linux building environment.
1385                 #
1386                 if Pcd.DatumType == "UINT64":
1387                     ValueList.append(Sku.DefaultValue + "ULL")
1388                 else:
1389                     ValueList.append(Sku.DefaultValue)
1390
1391         Pcd.TokenTypeList = list(set(Pcd.TokenTypeList))
1392         
1393
1394         if 'PCD_TYPE_HII' in Pcd.TokenTypeList:
1395             Dict['VARIABLE_HEAD_CNAME_DECL'].append(CName)
1396             Dict['VARIABLE_HEAD_GUID_DECL'].append(TokenSpaceGuid)
1397             Dict['VARIABLE_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
1398             Dict['VARIABLE_HEAD_VALUE'].append('{ %s }\n' % ' },\n    { '.join(VariableHeadValueList))
1399             Dict['VARDEF_HEADER'].append('_Variable_Header')
1400         else:
1401             Dict['VARDEF_HEADER'].append('')
1402         if 'PCD_TYPE_VPD' in Pcd.TokenTypeList:
1403             Dict['VPD_HEAD_CNAME_DECL'].append(CName)
1404             Dict['VPD_HEAD_GUID_DECL'].append(TokenSpaceGuid)
1405             Dict['VPD_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
1406             Dict['VPD_HEAD_VALUE'].append('{ %s }' % ' }, { '.join(VpdHeadOffsetList))
1407         if 'PCD_TYPE_STRING' in Pcd.TokenTypeList:
1408             Dict['STRING_HEAD_CNAME_DECL'].append(CName)
1409             Dict['STRING_HEAD_GUID_DECL'].append(TokenSpaceGuid)
1410             Dict['STRING_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
1411             Dict['STRING_HEAD_VALUE'].append(', '.join(StringHeadOffsetList))
1412         if 'PCD_TYPE_DATA' in Pcd.TokenTypeList:
1413             Dict[Pcd.InitString+'_CNAME_DECL_'+Pcd.DatumType].append(CName)
1414             Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType].append(TokenSpaceGuid)
1415             Dict[Pcd.InitString+'_NUMSKUS_DECL_'+Pcd.DatumType].append(len(Pcd.SkuInfoList))
1416             if Pcd.InitString == 'UNINIT':
1417                 Dict['PCD_DATABASE_UNINIT_EMPTY'] = ''
1418             else:
1419                 Dict[Pcd.InitString+'_VALUE_'+Pcd.DatumType].append(', '.join(ValueList))
1420
1421     if Phase == 'PEI':
1422         NumberOfLocalTokens = NumberOfPeiLocalTokens
1423     if Phase == 'DXE':
1424         NumberOfLocalTokens = NumberOfDxeLocalTokens
1425
1426     Dict['TOKEN_INIT']       = ['' for x in range(NumberOfLocalTokens)]
1427     Dict['TOKEN_CNAME']      = ['' for x in range(NumberOfLocalTokens)]
1428     Dict['TOKEN_GUID']       = ['' for x in range(NumberOfLocalTokens)]
1429     Dict['TOKEN_TYPE']       = ['' for x in range(NumberOfLocalTokens)]
1430     
1431     for Pcd in Platform.DynamicPcdList:
1432         CName = Pcd.TokenCName
1433         TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
1434         if Pcd.Phase != Phase:
1435             continue
1436
1437         TokenSpaceGuid = GuidStructureStringToGuidValueName(Pcd.TokenSpaceGuidValue) #(Platform.PackageList, TokenSpaceGuidCName))
1438         GeneratedTokenNumber = Platform.PcdTokenNumber[CName, TokenSpaceGuidCName] - 1
1439         if Phase == 'DXE':
1440             GeneratedTokenNumber -= NumberOfPeiLocalTokens
1441
1442         EdkLogger.debug(EdkLogger.DEBUG_1, "PCD = %s.%s" % (CName, TokenSpaceGuidCName))
1443         EdkLogger.debug(EdkLogger.DEBUG_1, "phase = %s" % Phase)
1444         EdkLogger.debug(EdkLogger.DEBUG_1, "GeneratedTokenNumber = %s" % str(GeneratedTokenNumber))
1445
1446         Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Init'
1447         if Pcd.InitString == 'UNINIT':
1448             Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Uninit'
1449         Dict['TOKEN_CNAME'][GeneratedTokenNumber] = CName
1450         Dict['TOKEN_GUID'][GeneratedTokenNumber] = TokenSpaceGuid
1451         Dict['TOKEN_TYPE'][GeneratedTokenNumber] = ' | '.join(Pcd.TokenTypeList)
1452         if Pcd.Type in gDynamicExPcd:
1453             Dict['EXMAPPING_TABLE_EXTOKEN'].append(Pcd.TokenValue)
1454             if Phase == 'DXE':
1455                 GeneratedTokenNumber += NumberOfPeiLocalTokens
1456             #
1457             # Per, PCD architecture specification, PCD Token Number is 1 based and 0 is defined as invalid token number.
1458             # For each EX type PCD, a PCD Token Number is assigned. When the
1459             # PCD Driver/PEIM map EX_GUID and EX_TOKEN_NUMBER to the PCD Token Number,
1460             # the non-EX Protocol/PPI interface can be called to get/set the value. This assumption is made by
1461             # Pcd Driver/PEIM in MdeModulePkg.
1462             # Therefore, 1 is added to GeneratedTokenNumber to generate a PCD Token Number before being inserted
1463             # to the EXMAPPING_TABLE.
1464             #
1465             Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(GeneratedTokenNumber + 1)
1466             Dict['EXMAPPING_TABLE_GUID_INDEX'].append(GuidList.index(TokenSpaceGuid))
1467
1468     if GuidList != []:
1469         Dict['GUID_TABLE_EMPTY'] = 'FALSE'
1470         Dict['GUID_TABLE_SIZE'] = len(GuidList)
1471     else:
1472         Dict['GUID_STRUCTURE'] = [GuidStringToGuidStructureString('00000000-0000-0000-0000-000000000000')]
1473
1474     if StringTableIndex == 0:
1475         Dict['STRING_TABLE_INDEX'].append('')
1476         Dict['STRING_TABLE_LENGTH'].append(1)
1477         Dict['STRING_TABLE_CNAME'].append('')
1478         Dict['STRING_TABLE_GUID'].append('')
1479         Dict['STRING_TABLE_VALUE'].append('{ 0 }')
1480     else:
1481         Dict['STRING_TABLE_EMPTY'] = 'FALSE'
1482         Dict['STRING_TABLE_SIZE'] = StringTableSize
1483
1484     if Dict['SIZE_TABLE_CNAME'] == []:
1485         Dict['SIZE_TABLE_CNAME'].append('')
1486         Dict['SIZE_TABLE_GUID'].append('')
1487         Dict['SIZE_TABLE_CURRENT_LENGTH'].append(0)
1488         Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(0)
1489
1490     if NumberOfLocalTokens != 0:
1491         Dict['DATABASE_EMPTY']                = 'FALSE'
1492         Dict['LOCAL_TOKEN_NUMBER_TABLE_SIZE'] = NumberOfLocalTokens
1493         Dict['LOCAL_TOKEN_NUMBER']            = NumberOfLocalTokens
1494
1495     if NumberOfExTokens != 0:
1496         Dict['EXMAP_TABLE_EMPTY']    = 'FALSE'
1497         Dict['EXMAPPING_TABLE_SIZE'] = NumberOfExTokens
1498         Dict['EX_TOKEN_NUMBER']      = NumberOfExTokens
1499     else:
1500         Dict['EXMAPPING_TABLE_EXTOKEN'].append(0)
1501         Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(0)
1502         Dict['EXMAPPING_TABLE_GUID_INDEX'].append(0)
1503
1504     if NumberOfSizeItems != 0:
1505         Dict['SIZE_TABLE_SIZE'] = NumberOfSizeItems * 2
1506
1507     AutoGenH.Append(gPcdDatabaseAutoGenH.Replace(Dict))
1508     if NumberOfLocalTokens == 0:
1509         AutoGenC.Append(gEmptyPcdDatabaseAutoGenC.Replace(Dict))
1510     else:
1511         AutoGenC.Append(gPcdDatabaseAutoGenC.Replace(Dict))
1512
1513     return AutoGenH, AutoGenC
1514
1515 ## Create code for PCD database
1516 #
1517 #   @param      Info        The ModuleAutoGen object
1518 #   @param      AutoGenC    The TemplateString object for C code
1519 #   @param      AutoGenH    The TemplateString object for header file
1520 #
1521 def CreatePcdDatabaseCode (Info, AutoGenC, AutoGenH):
1522     if Info.PcdIsDriver == "":
1523         return
1524     if Info.PcdIsDriver not in gPcdPhaseMap:
1525         EdkLogger.error("build", AUTOGEN_ERROR, "Not supported PcdIsDriver type:%s" % Info.PcdIsDriver,
1526                         ExtraData="[%s]" % str(Info))
1527
1528     AutoGenH.Append(gPcdDatabaseCommonAutoGenH)
1529     AdditionalAutoGenH, AdditionalAutoGenC = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, 'PEI')
1530     AutoGenH.Append(AdditionalAutoGenH.String)
1531
1532     Phase = gPcdPhaseMap[Info.PcdIsDriver]
1533     if Phase == 'PEI':
1534         AutoGenC.Append(AdditionalAutoGenC.String)
1535
1536     if Phase == 'DXE':
1537         AdditionalAutoGenH, AdditionalAutoGenC = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, Phase)
1538         AutoGenH.Append(AdditionalAutoGenH.String)
1539         AutoGenC.Append(AdditionalAutoGenC.String)
1540         AutoGenH.Append(gPcdDatabaseEpilogueAutoGenH)
1541
1542 ## Create code for library constructor
1543 #
1544 #   @param      Info        The ModuleAutoGen object
1545 #   @param      AutoGenC    The TemplateString object for C code
1546 #   @param      AutoGenH    The TemplateString object for header file
1547 #
1548 def CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH):
1549     #
1550     # Library Constructors
1551     #
1552     ConstructorPrototypeString = TemplateString()
1553     ConstructorCallingString = TemplateString()
1554     if Info.IsLibrary:
1555         DependentLibraryList = [Info.Module]
1556     else:
1557         DependentLibraryList = Info.DependentLibraryList
1558     for Lib in DependentLibraryList:
1559         if len(Lib.ConstructorList) <= 0:
1560             continue
1561         Dict = {'Function':Lib.ConstructorList}
1562         if Lib.ModuleType in ['BASE', 'SEC']:
1563             ConstructorPrototypeString.Append(gLibraryStructorPrototype['BASE'].Replace(Dict))
1564             ConstructorCallingString.Append(gLibraryStructorCall['BASE'].Replace(Dict))
1565         elif Lib.ModuleType in ['PEI_CORE','PEIM']:
1566             ConstructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict))
1567             ConstructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict))
1568         elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
1569                                 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
1570             ConstructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict))
1571             ConstructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict))
1572
1573     if str(ConstructorPrototypeString) == '':
1574         ConstructorPrototypeList = []
1575     else:
1576         ConstructorPrototypeList = [str(ConstructorPrototypeString)]
1577     if str(ConstructorCallingString) == '':
1578         ConstructorCallingList = []
1579     else:
1580         ConstructorCallingList = [str(ConstructorCallingString)]
1581
1582     Dict = {
1583         'Type'              :   'Constructor',
1584         'FunctionPrototype' :   ConstructorPrototypeList,
1585         'FunctionCall'      :   ConstructorCallingList
1586     }
1587     if Info.IsLibrary:
1588         AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict)
1589     else:
1590         if Info.ModuleType in ['BASE', 'SEC']:
1591             AutoGenC.Append(gLibraryString['BASE'].Replace(Dict))
1592         elif Info.ModuleType in ['PEI_CORE','PEIM']:
1593             AutoGenC.Append(gLibraryString['PEI'].Replace(Dict))
1594         elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
1595                                  'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
1596             AutoGenC.Append(gLibraryString['DXE'].Replace(Dict))
1597
1598 ## Create code for library destructor
1599 #
1600 #   @param      Info        The ModuleAutoGen object
1601 #   @param      AutoGenC    The TemplateString object for C code
1602 #   @param      AutoGenH    The TemplateString object for header file
1603 #
1604 def CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH):
1605     #
1606     # Library Destructors
1607     #
1608     DestructorPrototypeString = TemplateString()
1609     DestructorCallingString = TemplateString()
1610     if Info.IsLibrary:
1611         DependentLibraryList = [Info.Module]
1612     else:
1613         DependentLibraryList = Info.DependentLibraryList
1614     for Index in range(len(DependentLibraryList)-1, -1, -1):
1615         Lib = DependentLibraryList[Index]
1616         if len(Lib.DestructorList) <= 0:
1617             continue
1618         Dict = {'Function':Lib.DestructorList}
1619         if Lib.ModuleType in ['BASE', 'SEC']:
1620             DestructorPrototypeString.Append(gLibraryStructorPrototype['BASE'].Replace(Dict))
1621             DestructorCallingString.Append(gLibraryStructorCall['BASE'].Replace(Dict))
1622         elif Lib.ModuleType in ['PEI_CORE','PEIM']:
1623             DestructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict))
1624             DestructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict))
1625         elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
1626                                 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION', 'SMM_CORE']:
1627             DestructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict))
1628             DestructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict))
1629
1630     if str(DestructorPrototypeString) == '':
1631         DestructorPrototypeList = []
1632     else:
1633         DestructorPrototypeList = [str(DestructorPrototypeString)]
1634     if str(DestructorCallingString) == '':
1635         DestructorCallingList = []
1636     else:
1637         DestructorCallingList = [str(DestructorCallingString)]
1638
1639     Dict = {
1640         'Type'              :   'Destructor',
1641         'FunctionPrototype' :   DestructorPrototypeList,
1642         'FunctionCall'      :   DestructorCallingList
1643     }
1644     if Info.IsLibrary:
1645         AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict)
1646     else:
1647         if Info.ModuleType in ['BASE', 'SEC']:
1648             AutoGenC.Append(gLibraryString['BASE'].Replace(Dict))
1649         elif Info.ModuleType in ['PEI_CORE','PEIM']:
1650             AutoGenC.Append(gLibraryString['PEI'].Replace(Dict))
1651         elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
1652                                  'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
1653             AutoGenC.Append(gLibraryString['DXE'].Replace(Dict))
1654
1655
1656 ## Create code for ModuleEntryPoint
1657 #
1658 #   @param      Info        The ModuleAutoGen object
1659 #   @param      AutoGenC    The TemplateString object for C code
1660 #   @param      AutoGenH    The TemplateString object for header file
1661 #
1662 def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH):
1663     if Info.IsLibrary or Info.ModuleType in ['USER_DEFINED', 'SEC']:
1664         return
1665     #
1666     # Module Entry Points
1667     #
1668     NumEntryPoints = len(Info.Module.ModuleEntryPointList)
1669     if 'PI_SPECIFICATION_VERSION' in Info.Module.Specification:
1670         PiSpecVersion = Info.Module.Specification['PI_SPECIFICATION_VERSION']
1671     else:
1672         PiSpecVersion = 0
1673     if 'UEFI_SPECIFICATION_VERSION' in Info.Module.Specification:
1674         UefiSpecVersion = Info.Module.Specification['UEFI_SPECIFICATION_VERSION']
1675     else:
1676         UefiSpecVersion = 0
1677     Dict = {
1678         'Function'       :   Info.Module.ModuleEntryPointList,
1679         'PiSpecVersion'  :   PiSpecVersion,
1680         'UefiSpecVersion':   UefiSpecVersion
1681     }
1682
1683     if Info.ModuleType in ['PEI_CORE', 'DXE_CORE', 'SMM_CORE']:
1684         if NumEntryPoints != 1:
1685             EdkLogger.error(
1686                 "build",
1687                 AUTOGEN_ERROR,
1688                 '%s must have exactly one entry point' % Info.ModuleType,
1689                 File=str(Info),
1690                 ExtraData= ", ".join(Info.Module.ModuleEntryPointList)
1691                 )
1692     if Info.ModuleType == 'PEI_CORE':
1693         AutoGenC.Append(gPeiCoreEntryPointString.Replace(Dict))
1694         AutoGenH.Append(gPeiCoreEntryPointPrototype.Replace(Dict))
1695     elif Info.ModuleType == 'DXE_CORE':
1696         AutoGenC.Append(gDxeCoreEntryPointString.Replace(Dict))
1697         AutoGenH.Append(gDxeCoreEntryPointPrototype.Replace(Dict))
1698     elif Info.ModuleType == 'SMM_CORE':
1699         AutoGenC.Append(gSmmCoreEntryPointString.Replace(Dict))
1700         AutoGenH.Append(gSmmCoreEntryPointPrototype.Replace(Dict))
1701     elif Info.ModuleType == 'PEIM':
1702         if NumEntryPoints < 2:
1703             AutoGenC.Append(gPeimEntryPointString[NumEntryPoints].Replace(Dict))
1704         else:
1705             AutoGenC.Append(gPeimEntryPointString[2].Replace(Dict))
1706         AutoGenH.Append(gPeimEntryPointPrototype.Replace(Dict))
1707     elif Info.ModuleType in ['DXE_RUNTIME_DRIVER','DXE_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER']:
1708         if NumEntryPoints < 2:
1709             AutoGenC.Append(gUefiDriverEntryPointString[NumEntryPoints].Replace(Dict))
1710         else:
1711             AutoGenC.Append(gUefiDriverEntryPointString[2].Replace(Dict))
1712         AutoGenH.Append(gUefiDriverEntryPointPrototype.Replace(Dict))
1713     elif Info.ModuleType == 'DXE_SMM_DRIVER':
1714         if NumEntryPoints == 0:
1715             AutoGenC.Append(gDxeSmmEntryPointString[0].Replace(Dict))
1716         else:
1717             AutoGenC.Append(gDxeSmmEntryPointString[1].Replace(Dict))
1718         AutoGenH.Append(gDxeSmmEntryPointPrototype.Replace(Dict))    
1719     elif Info.ModuleType == 'UEFI_APPLICATION':
1720         if NumEntryPoints < 2:
1721             AutoGenC.Append(gUefiApplicationEntryPointString[NumEntryPoints].Replace(Dict))
1722         else:
1723             AutoGenC.Append(gUefiApplicationEntryPointString[2].Replace(Dict))
1724         AutoGenH.Append(gUefiApplicationEntryPointPrototype.Replace(Dict))
1725
1726 ## Create code for ModuleUnloadImage
1727 #
1728 #   @param      Info        The ModuleAutoGen object
1729 #   @param      AutoGenC    The TemplateString object for C code
1730 #   @param      AutoGenH    The TemplateString object for header file
1731 #
1732 def CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH):
1733     if Info.IsLibrary or Info.ModuleType in ['USER_DEFINED', 'SEC']:
1734         return
1735     #
1736     # Unload Image Handlers
1737     #
1738     NumUnloadImage = len(Info.Module.ModuleUnloadImageList)
1739     Dict = {'Count':NumUnloadImage, 'Function':Info.Module.ModuleUnloadImageList}
1740     if NumUnloadImage < 2:
1741         AutoGenC.Append(gUefiUnloadImageString[NumUnloadImage].Replace(Dict))
1742     else:
1743         AutoGenC.Append(gUefiUnloadImageString[2].Replace(Dict))
1744     AutoGenH.Append(gUefiUnloadImagePrototype.Replace(Dict))
1745
1746 ## Create code for GUID
1747 #
1748 #   @param      Info        The ModuleAutoGen object
1749 #   @param      AutoGenC    The TemplateString object for C code
1750 #   @param      AutoGenH    The TemplateString object for header file
1751 #
1752 def CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH):
1753     if Info.IsLibrary:
1754         return
1755
1756     if Info.ModuleType in ["USER_DEFINED", "BASE"]:
1757         GuidType = "GUID"
1758     else:
1759         GuidType = "EFI_GUID"
1760
1761     if Info.GuidList:
1762         AutoGenC.Append("\n// Guids\n")
1763     #
1764     # GUIDs
1765     #
1766     for Key in Info.GuidList:
1767         AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.GuidList[Key]))
1768
1769 ## Create code for protocol
1770 #
1771 #   @param      Info        The ModuleAutoGen object
1772 #   @param      AutoGenC    The TemplateString object for C code
1773 #   @param      AutoGenH    The TemplateString object for header file
1774 #
1775 def CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH):
1776     if Info.IsLibrary:
1777         return
1778
1779     if Info.ModuleType in ["USER_DEFINED", "BASE"]:
1780         GuidType = "GUID"
1781     else:
1782         GuidType = "EFI_GUID"
1783
1784     if Info.ProtocolList:
1785         AutoGenC.Append("\n// Protocols\n")
1786     #
1787     # Protocol GUIDs
1788     #
1789     for Key in Info.ProtocolList:
1790         AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.ProtocolList[Key]))
1791
1792 ## Create code for PPI
1793 #
1794 #   @param      Info        The ModuleAutoGen object
1795 #   @param      AutoGenC    The TemplateString object for C code
1796 #   @param      AutoGenH    The TemplateString object for header file
1797 #
1798 def CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH):
1799     if Info.IsLibrary:
1800         return
1801
1802     if Info.ModuleType in ["USER_DEFINED", "BASE"]:
1803         GuidType = "GUID"
1804     else:
1805         GuidType = "EFI_GUID"
1806
1807     if Info.PpiList:
1808         AutoGenC.Append("\n// PPIs\n")
1809     #
1810     # PPI GUIDs
1811     #
1812     for Key in Info.PpiList:
1813         AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.PpiList[Key]))
1814
1815 ## Create code for PCD
1816 #
1817 #   @param      Info        The ModuleAutoGen object
1818 #   @param      AutoGenC    The TemplateString object for C code
1819 #   @param      AutoGenH    The TemplateString object for header file
1820 #
1821 def CreatePcdCode(Info, AutoGenC, AutoGenH):
1822     if Info.IsLibrary:
1823         if Info.ModulePcdList:
1824             AutoGenH.Append("\n// PCD definitions\n")
1825         for Pcd in Info.ModulePcdList:
1826             CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd)
1827     else:
1828         if Info.ModulePcdList:
1829             AutoGenH.Append("\n// Definition of PCDs used in this module\n")
1830             AutoGenC.Append("\n// Definition of PCDs used in this module\n")
1831         for Pcd in Info.ModulePcdList:
1832             CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd)
1833
1834         if Info.LibraryPcdList:
1835             AutoGenH.Append("\n// Definition of PCDs used in libraries is in AutoGen.c\n")
1836             AutoGenC.Append("\n// Definition of PCDs used in libraries\n")
1837         for Pcd in Info.LibraryPcdList:
1838             CreateModulePcdCode(Info, AutoGenC, AutoGenC, Pcd)
1839     CreatePcdDatabaseCode(Info, AutoGenC, AutoGenH)
1840
1841 ## Create code for unicode string definition
1842 #
1843 #   @param      Info        The ModuleAutoGen object
1844 #   @param      AutoGenC    The TemplateString object for C code
1845 #   @param      AutoGenH    The TemplateString object for header file
1846 #   @param      UniGenCFlag     UniString is generated into AutoGen C file when it is set to True
1847 #   @param      UniGenBinBuffer Buffer to store uni string package data
1848 #
1849 def CreateUnicodeStringCode(Info, AutoGenC, AutoGenH, UniGenCFlag, UniGenBinBuffer):
1850     WorkingDir = os.getcwd()
1851     os.chdir(Info.WorkspaceDir)
1852
1853     IncList = [Info.MetaFile.Dir]
1854     # Get all files under [Sources] section in inf file for EDK-II module
1855     SrcList = [F for F in Info.SourceFileList]
1856     if Info.AutoGenVersion < 0x00010005:
1857         # Get all files under the module directory for EDK-I module
1858         Cwd = os.getcwd()
1859         os.chdir(Info.MetaFile.Dir)
1860         for Root, Dirs, Files in os.walk("."):
1861             if 'CVS' in Dirs:
1862                 Dirs.remove('CVS')
1863             if '.svn' in Dirs:
1864                 Dirs.remove('.svn')
1865             for File in Files:
1866                 File = PathClass(os.path.join(Root, File), Info.MetaFile.Dir)
1867                 if File in SrcList:
1868                     continue
1869                 SrcList.append(File)
1870         os.chdir(Cwd)
1871
1872     if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-c') > -1:
1873         CompatibleMode = True
1874     else:
1875         CompatibleMode = False
1876
1877     #
1878     # -s is a temporary option dedicated for building .UNI files with ISO 639-2 lanauge codes of EDK Shell in EDK2
1879     #
1880     if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-s') > -1:
1881         if CompatibleMode:
1882             EdkLogger.error("build", AUTOGEN_ERROR,
1883                             "-c and -s build options should be used exclusively",
1884                             ExtraData="[%s]" % str(Info))
1885         ShellMode = True
1886     else:
1887         ShellMode = False
1888
1889     Header, Code = GetStringFiles(Info.UnicodeFileList, SrcList, IncList, ['.uni', '.inf'], Info.Name, CompatibleMode, ShellMode, UniGenCFlag, UniGenBinBuffer)
1890     if CompatibleMode or UniGenCFlag:
1891         AutoGenC.Append("\n//\n//Unicode String Pack Definition\n//\n")
1892         AutoGenC.Append(Code)
1893         AutoGenC.Append("\n")
1894     AutoGenH.Append("\n//\n//Unicode String ID\n//\n")
1895     AutoGenH.Append(Header)
1896     if CompatibleMode or UniGenCFlag:
1897         AutoGenH.Append("\n#define STRING_ARRAY_NAME %sStrings\n" % Info.Name)
1898     os.chdir(WorkingDir)
1899
1900 ## Create common code
1901 #
1902 #   @param      Info        The ModuleAutoGen object
1903 #   @param      AutoGenC    The TemplateString object for C code
1904 #   @param      AutoGenH    The TemplateString object for header file
1905 #
1906 def CreateHeaderCode(Info, AutoGenC, AutoGenH):
1907     # file header
1908     AutoGenH.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.h'}))
1909     # header file Prologue
1910     AutoGenH.Append(gAutoGenHPrologueString.Replace({'File':'AUTOGENH','Guid':Info.Guid.replace('-','_')}))
1911     if Info.AutoGenVersion >= 0x00010005:
1912         # header files includes
1913         AutoGenH.Append("#include <%s>\n" % gBasicHeaderFile)
1914         if Info.ModuleType in gModuleTypeHeaderFile \
1915            and gModuleTypeHeaderFile[Info.ModuleType][0] != gBasicHeaderFile:
1916             AutoGenH.Append("#include <%s>\n" % gModuleTypeHeaderFile[Info.ModuleType][0])
1917         AutoGenH.Append('\nextern GUID  gEfiCallerIdGuid;\n\n')
1918
1919         if Info.IsLibrary:
1920             return
1921
1922         AutoGenH.Append("#define EFI_CALLER_ID_GUID \\\n  %s\n" % GuidStringToGuidStructureString(Info.Guid))
1923
1924     if Info.IsLibrary:
1925         return
1926     # C file header
1927     AutoGenC.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.c'}))
1928     if Info.AutoGenVersion >= 0x00010005:
1929         # C file header files includes
1930         if Info.ModuleType in gModuleTypeHeaderFile:
1931             for Inc in gModuleTypeHeaderFile[Info.ModuleType]:
1932                 AutoGenC.Append("#include <%s>\n" % Inc)
1933         else:
1934             AutoGenC.Append("#include <%s>\n" % gBasicHeaderFile)
1935
1936         #
1937         # Publish the CallerId Guid
1938         #
1939         AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = %s;\n' % GuidStringToGuidStructureString(Info.Guid))
1940
1941 ## Create common code for header file
1942 #
1943 #   @param      Info        The ModuleAutoGen object
1944 #   @param      AutoGenC    The TemplateString object for C code
1945 #   @param      AutoGenH    The TemplateString object for header file
1946 #
1947 def CreateFooterCode(Info, AutoGenC, AutoGenH):
1948     AutoGenH.Append(gAutoGenHEpilogueString)
1949
1950 ## Create code for a module
1951 #
1952 #   @param      Info        The ModuleAutoGen object
1953 #   @param      AutoGenC    The TemplateString object for C code
1954 #   @param      AutoGenH    The TemplateString object for header file
1955 #   @param      UniGenCFlag     UniString is generated into AutoGen C file when it is set to True
1956 #   @param      UniGenBinBuffer Buffer to store uni string package data
1957 #
1958 def CreateCode(Info, AutoGenC, AutoGenH, StringH, UniGenCFlag, UniGenBinBuffer):
1959     CreateHeaderCode(Info, AutoGenC, AutoGenH)
1960
1961     if Info.AutoGenVersion >= 0x00010005:
1962         CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH)
1963         CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH)
1964         CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH)
1965         CreatePcdCode(Info, AutoGenC, AutoGenH)
1966         CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH)
1967         CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH)
1968         CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH)
1969         CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH)
1970
1971     if Info.UnicodeFileList:
1972         FileName = "%sStrDefs.h" % Info.Name
1973         StringH.Append(gAutoGenHeaderString.Replace({'FileName':FileName}))
1974         StringH.Append(gAutoGenHPrologueString.Replace({'File':'STRDEFS', 'Guid':Info.Guid.replace('-','_')}))
1975         CreateUnicodeStringCode(Info, AutoGenC, StringH, UniGenCFlag, UniGenBinBuffer)
1976         StringH.Append("\n#endif\n")
1977         AutoGenH.Append('#include "%s"\n' % FileName)
1978
1979     CreateFooterCode(Info, AutoGenC, AutoGenH)
1980
1981     # no generation of AutoGen.c for R8 modules without unicode file
1982     if Info.AutoGenVersion < 0x00010005 and len(Info.UnicodeFileList) == 0:
1983         AutoGenC.String = ''
1984
1985 ## Create the code file
1986 #
1987 #   @param      FilePath     The path of code file
1988 #   @param      Content      The content of code file
1989 #   @param      IsBinaryFile The flag indicating if the file is binary file or not
1990 #
1991 #   @retval     True        If file content is changed or file doesn't exist
1992 #   @retval     False       If the file exists and the content is not changed
1993 #
1994 def Generate(FilePath, Content, IsBinaryFile):
1995     return SaveFileOnChange(FilePath, Content, IsBinaryFile)
1996