Home | History | Annotate | Download | only in AutoGen
      1 ## @file

      2 # Routines for generating AutoGen.h and AutoGen.c

      3 #

      4 # Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>

      5 # 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 from GenPcdDb import CreatePcdDatabaseCode
     26 
     27 ## PCD type string

     28 gItemTypeStringDatabase  = {
     29     TAB_PCDS_FEATURE_FLAG       :   'FixedAtBuild',
     30     TAB_PCDS_FIXED_AT_BUILD     :   'FixedAtBuild',
     31     TAB_PCDS_PATCHABLE_IN_MODULE:   'BinaryPatch',
     32     TAB_PCDS_DYNAMIC            :   '',
     33     TAB_PCDS_DYNAMIC_DEFAULT    :   '',
     34     TAB_PCDS_DYNAMIC_VPD        :   '',
     35     TAB_PCDS_DYNAMIC_HII        :   '',
     36     TAB_PCDS_DYNAMIC_EX         :   '',
     37     TAB_PCDS_DYNAMIC_EX_DEFAULT :   '',
     38     TAB_PCDS_DYNAMIC_EX_VPD     :   '',
     39     TAB_PCDS_DYNAMIC_EX_HII     :   '',
     40 }
     41 
     42 ## Dynamic PCD types

     43 gDynamicPcd = [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII]
     44 
     45 ## Dynamic-ex PCD types

     46 gDynamicExPcd = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII]
     47 
     48 ## Datum size

     49 gDatumSizeStringDatabase = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOLEAN','VOID*':'8'}
     50 gDatumSizeStringDatabaseH = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOL','VOID*':'PTR'}
     51 gDatumSizeStringDatabaseLib = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'Bool','VOID*':'Ptr'}
     52 
     53 ## AutoGen File Header Templates

     54 gAutoGenHeaderString = TemplateString("""\
     55 /**
     56   DO NOT EDIT
     57   FILE auto-generated
     58   Module name:
     59     ${FileName}
     60   Abstract:       Auto-generated ${FileName} for building module or library.
     61 **/
     62 """)
     63 
     64 gAutoGenHPrologueString = TemplateString("""
     65 #ifndef _${File}_${Guid}
     66 #define _${File}_${Guid}
     67 
     68 """)
     69 
     70 gAutoGenHCppPrologueString = """\
     71 #ifdef __cplusplus
     72 extern "C" {
     73 #endif
     74 
     75 """
     76 
     77 gAutoGenHEpilogueString = """
     78 
     79 #ifdef __cplusplus
     80 }
     81 #endif
     82 
     83 #endif
     84 """
     85 
     86 ## PEI Core Entry Point Templates

     87 gPeiCoreEntryPointPrototype = TemplateString("""
     88 ${BEGIN}
     89 VOID
     90 EFIAPI
     91 ${Function} (
     92   IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,
     93   IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,
     94   IN VOID                           *Context
     95   );
     96 ${END}
     97 """)
     98 
     99 gPeiCoreEntryPointString = TemplateString("""
    100 ${BEGIN}
    101 VOID
    102 EFIAPI
    103 ProcessModuleEntryPointList (
    104   IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,
    105   IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,
    106   IN VOID                           *Context
    107   )
    108 
    109 {
    110   ${Function} (SecCoreData, PpiList, Context);
    111 }
    112 ${END}
    113 """)
    114 
    115 
    116 ## DXE Core Entry Point Templates

    117 gDxeCoreEntryPointPrototype = TemplateString("""
    118 ${BEGIN}
    119 VOID
    120 EFIAPI
    121 ${Function} (
    122   IN VOID  *HobStart
    123   );
    124 ${END}
    125 """)
    126 
    127 gDxeCoreEntryPointString = TemplateString("""
    128 ${BEGIN}
    129 VOID
    130 EFIAPI
    131 ProcessModuleEntryPointList (
    132   IN VOID  *HobStart
    133   )
    134 
    135 {
    136   ${Function} (HobStart);
    137 }
    138 ${END}
    139 """)
    140 
    141 ## PEIM Entry Point Templates

    142 gPeimEntryPointPrototype = TemplateString("""
    143 ${BEGIN}
    144 EFI_STATUS
    145 EFIAPI
    146 ${Function} (
    147   IN       EFI_PEI_FILE_HANDLE  FileHandle,
    148   IN CONST EFI_PEI_SERVICES     **PeiServices
    149   );
    150 ${END}
    151 """)
    152 
    153 gPeimEntryPointString = [
    154 TemplateString("""
    155 GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
    156 
    157 EFI_STATUS
    158 EFIAPI
    159 ProcessModuleEntryPointList (
    160   IN       EFI_PEI_FILE_HANDLE  FileHandle,
    161   IN CONST EFI_PEI_SERVICES     **PeiServices
    162   )
    163 
    164 {
    165   return EFI_SUCCESS;
    166 }
    167 """),
    168 TemplateString("""
    169 GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
    170 ${BEGIN}
    171 EFI_STATUS
    172 EFIAPI
    173 ProcessModuleEntryPointList (
    174   IN       EFI_PEI_FILE_HANDLE  FileHandle,
    175   IN CONST EFI_PEI_SERVICES     **PeiServices
    176   )
    177 
    178 {
    179   return ${Function} (FileHandle, PeiServices);
    180 }
    181 ${END}
    182 """),
    183 TemplateString("""
    184 GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
    185 
    186 EFI_STATUS
    187 EFIAPI
    188 ProcessModuleEntryPointList (
    189   IN       EFI_PEI_FILE_HANDLE  FileHandle,
    190   IN CONST EFI_PEI_SERVICES     **PeiServices
    191   )
    192 
    193 {
    194   EFI_STATUS  Status;
    195   EFI_STATUS  CombinedStatus;
    196 
    197   CombinedStatus = EFI_LOAD_ERROR;
    198 ${BEGIN}
    199   Status = ${Function} (FileHandle, PeiServices);
    200   if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {
    201     CombinedStatus = Status;
    202   }
    203 ${END}
    204   return CombinedStatus;
    205 }
    206 """)
    207 ]
    208 
    209 ## SMM_CORE Entry Point Templates

    210 gSmmCoreEntryPointPrototype = TemplateString("""
    211 ${BEGIN}
    212 EFI_STATUS
    213 EFIAPI
    214 ${Function} (
    215   IN EFI_HANDLE         ImageHandle,
    216   IN EFI_SYSTEM_TABLE   *SystemTable
    217   );
    218 ${END}
    219 """)
    220 
    221 gSmmCoreEntryPointString = TemplateString("""
    222 ${BEGIN}
    223 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
    224 const UINT32 _gDxeRevision = ${PiSpecVersion};
    225 
    226 EFI_STATUS
    227 EFIAPI
    228 ProcessModuleEntryPointList (
    229   IN EFI_HANDLE         ImageHandle,
    230   IN EFI_SYSTEM_TABLE   *SystemTable
    231   )
    232 {
    233   return ${Function} (ImageHandle, SystemTable);
    234 }
    235 ${END}
    236 """)
    237 
    238 ## DXE SMM Entry Point Templates

    239 gDxeSmmEntryPointPrototype = TemplateString("""
    240 ${BEGIN}
    241 EFI_STATUS
    242 EFIAPI
    243 ${Function} (
    244   IN EFI_HANDLE        ImageHandle,
    245   IN EFI_SYSTEM_TABLE  *SystemTable
    246   );
    247 ${END}
    248 """)
    249 
    250 gDxeSmmEntryPointString = [
    251 TemplateString("""
    252 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
    253 const UINT32 _gDxeRevision = ${PiSpecVersion};
    254 
    255 EFI_STATUS
    256 EFIAPI
    257 ProcessModuleEntryPointList (
    258   IN EFI_HANDLE        ImageHandle,
    259   IN EFI_SYSTEM_TABLE  *SystemTable
    260   )
    261 
    262 {
    263   return EFI_SUCCESS;
    264 }
    265 """),
    266 TemplateString("""
    267 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
    268 const UINT32 _gDxeRevision = ${PiSpecVersion};
    269 
    270 static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
    271 static EFI_STATUS  mDriverEntryPointStatus;
    272 
    273 VOID
    274 EFIAPI
    275 ExitDriver (
    276   IN EFI_STATUS  Status
    277   )
    278 {
    279   if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
    280     mDriverEntryPointStatus = Status;
    281   }
    282   LongJump (&mJumpContext, (UINTN)-1);
    283   ASSERT (FALSE);
    284 }
    285 
    286 EFI_STATUS
    287 EFIAPI
    288 ProcessModuleEntryPointList (
    289   IN EFI_HANDLE        ImageHandle,
    290   IN EFI_SYSTEM_TABLE  *SystemTable
    291   )
    292 {
    293   mDriverEntryPointStatus = EFI_LOAD_ERROR;
    294 
    295 ${BEGIN}
    296   if (SetJump (&mJumpContext) == 0) {
    297     ExitDriver (${Function} (ImageHandle, SystemTable));
    298     ASSERT (FALSE);
    299   }
    300 ${END}
    301 
    302   return mDriverEntryPointStatus;
    303 }
    304 """)
    305 ]
    306 
    307 ## UEFI Driver Entry Point Templates

    308 gUefiDriverEntryPointPrototype = TemplateString("""
    309 ${BEGIN}
    310 EFI_STATUS
    311 EFIAPI
    312 ${Function} (
    313   IN EFI_HANDLE        ImageHandle,
    314   IN EFI_SYSTEM_TABLE  *SystemTable
    315   );
    316 ${END}
    317 """)
    318 
    319 gUefiDriverEntryPointString = [
    320 TemplateString("""
    321 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
    322 const UINT32 _gDxeRevision = ${PiSpecVersion};
    323 
    324 EFI_STATUS
    325 EFIAPI
    326 ProcessModuleEntryPointList (
    327   IN EFI_HANDLE        ImageHandle,
    328   IN EFI_SYSTEM_TABLE  *SystemTable
    329   )
    330 {
    331   return EFI_SUCCESS;
    332 }
    333 """),
    334 TemplateString("""
    335 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
    336 const UINT32 _gDxeRevision = ${PiSpecVersion};
    337 
    338 ${BEGIN}
    339 EFI_STATUS
    340 EFIAPI
    341 ProcessModuleEntryPointList (
    342   IN EFI_HANDLE        ImageHandle,
    343   IN EFI_SYSTEM_TABLE  *SystemTable
    344   )
    345 
    346 {
    347   return ${Function} (ImageHandle, SystemTable);
    348 }
    349 ${END}
    350 VOID
    351 EFIAPI
    352 ExitDriver (
    353   IN EFI_STATUS  Status
    354   )
    355 {
    356   if (EFI_ERROR (Status)) {
    357     ProcessLibraryDestructorList (gImageHandle, gST);
    358   }
    359   gBS->Exit (gImageHandle, Status, 0, NULL);
    360 }
    361 """),
    362 TemplateString("""
    363 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
    364 const UINT32 _gDxeRevision = ${PiSpecVersion};
    365 
    366 static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
    367 static EFI_STATUS  mDriverEntryPointStatus;
    368 
    369 EFI_STATUS
    370 EFIAPI
    371 ProcessModuleEntryPointList (
    372   IN EFI_HANDLE        ImageHandle,
    373   IN EFI_SYSTEM_TABLE  *SystemTable
    374   )
    375 {
    376   mDriverEntryPointStatus = EFI_LOAD_ERROR;
    377   ${BEGIN}
    378   if (SetJump (&mJumpContext) == 0) {
    379     ExitDriver (${Function} (ImageHandle, SystemTable));
    380     ASSERT (FALSE);
    381   }
    382   ${END}
    383   return mDriverEntryPointStatus;
    384 }
    385 
    386 VOID
    387 EFIAPI
    388 ExitDriver (
    389   IN EFI_STATUS  Status
    390   )
    391 {
    392   if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
    393     mDriverEntryPointStatus = Status;
    394   }
    395   LongJump (&mJumpContext, (UINTN)-1);
    396   ASSERT (FALSE);
    397 }
    398 """)
    399 ]
    400 
    401 
    402 ## UEFI Application Entry Point Templates

    403 gUefiApplicationEntryPointPrototype = TemplateString("""
    404 ${BEGIN}
    405 EFI_STATUS
    406 EFIAPI
    407 ${Function} (
    408   IN EFI_HANDLE        ImageHandle,
    409   IN EFI_SYSTEM_TABLE  *SystemTable
    410   );
    411 ${END}
    412 """)
    413 
    414 gUefiApplicationEntryPointString = [
    415 TemplateString("""
    416 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
    417 
    418 EFI_STATUS
    419 EFIAPI
    420 ProcessModuleEntryPointList (
    421   IN EFI_HANDLE        ImageHandle,
    422   IN EFI_SYSTEM_TABLE  *SystemTable
    423   )
    424 {
    425   return EFI_SUCCESS;
    426 }
    427 """),
    428 TemplateString("""
    429 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
    430 
    431 ${BEGIN}
    432 EFI_STATUS
    433 EFIAPI
    434 ProcessModuleEntryPointList (
    435   IN EFI_HANDLE        ImageHandle,
    436   IN EFI_SYSTEM_TABLE  *SystemTable
    437   )
    438 
    439 {
    440   return ${Function} (ImageHandle, SystemTable);
    441 }
    442 ${END}
    443 VOID
    444 EFIAPI
    445 ExitDriver (
    446   IN EFI_STATUS  Status
    447   )
    448 {
    449   if (EFI_ERROR (Status)) {
    450     ProcessLibraryDestructorList (gImageHandle, gST);
    451   }
    452   gBS->Exit (gImageHandle, Status, 0, NULL);
    453 }
    454 """),
    455 TemplateString("""
    456 const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
    457 
    458 EFI_STATUS
    459 EFIAPI
    460 ProcessModuleEntryPointList (
    461   IN EFI_HANDLE        ImageHandle,
    462   IN EFI_SYSTEM_TABLE  *SystemTable
    463   )
    464 
    465 {
    466   ${BEGIN}
    467   if (SetJump (&mJumpContext) == 0) {
    468     ExitDriver (${Function} (ImageHandle, SystemTable));
    469     ASSERT (FALSE);
    470   }
    471   ${END}
    472   return mDriverEntryPointStatus;
    473 }
    474 
    475 static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
    476 static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;
    477 
    478 VOID
    479 EFIAPI
    480 ExitDriver (
    481   IN EFI_STATUS  Status
    482   )
    483 {
    484   if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
    485     mDriverEntryPointStatus = Status;
    486   }
    487   LongJump (&mJumpContext, (UINTN)-1);
    488   ASSERT (FALSE);
    489 }
    490 """)
    491 ]
    492 
    493 ## UEFI Unload Image Templates

    494 gUefiUnloadImagePrototype = TemplateString("""
    495 ${BEGIN}
    496 EFI_STATUS
    497 EFIAPI
    498 ${Function} (
    499   IN EFI_HANDLE        ImageHandle
    500   );
    501 ${END}
    502 """)
    503 
    504 gUefiUnloadImageString = [
    505 TemplateString("""
    506 GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
    507 
    508 EFI_STATUS
    509 EFIAPI
    510 ProcessModuleUnloadList (
    511   IN EFI_HANDLE        ImageHandle
    512   )
    513 {
    514   return EFI_SUCCESS;
    515 }
    516 """),
    517 TemplateString("""
    518 GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
    519 
    520 ${BEGIN}
    521 EFI_STATUS
    522 EFIAPI
    523 ProcessModuleUnloadList (
    524   IN EFI_HANDLE        ImageHandle
    525   )
    526 {
    527   return ${Function} (ImageHandle);
    528 }
    529 ${END}
    530 """),
    531 TemplateString("""
    532 GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
    533 
    534 EFI_STATUS
    535 EFIAPI
    536 ProcessModuleUnloadList (
    537   IN EFI_HANDLE        ImageHandle
    538   )
    539 {
    540   EFI_STATUS  Status;
    541 
    542   Status = EFI_SUCCESS;
    543 ${BEGIN}
    544   if (EFI_ERROR (Status)) {
    545     ${Function} (ImageHandle);
    546   } else {
    547     Status = ${Function} (ImageHandle);
    548   }
    549 ${END}
    550   return Status;
    551 }
    552 """)
    553 ]
    554 
    555 gLibraryStructorPrototype = {
    556 'BASE'  : TemplateString("""${BEGIN}
    557 RETURN_STATUS
    558 EFIAPI
    559 ${Function} (
    560   VOID
    561   );${END}
    562 """),
    563 
    564 'PEI'   : TemplateString("""${BEGIN}
    565 EFI_STATUS
    566 EFIAPI
    567 ${Function} (
    568   IN       EFI_PEI_FILE_HANDLE       FileHandle,
    569   IN CONST EFI_PEI_SERVICES          **PeiServices
    570   );${END}
    571 """),
    572 
    573 'DXE'   : TemplateString("""${BEGIN}
    574 EFI_STATUS
    575 EFIAPI
    576 ${Function} (
    577   IN EFI_HANDLE        ImageHandle,
    578   IN EFI_SYSTEM_TABLE  *SystemTable
    579   );${END}
    580 """),
    581 }
    582 
    583 gLibraryStructorCall = {
    584 'BASE'  : TemplateString("""${BEGIN}
    585   Status = ${Function} ();
    586   ASSERT_EFI_ERROR (Status);${END}
    587 """),
    588 
    589 'PEI'   : TemplateString("""${BEGIN}
    590   Status = ${Function} (FileHandle, PeiServices);
    591   ASSERT_EFI_ERROR (Status);${END}
    592 """),
    593 
    594 'DXE'   : TemplateString("""${BEGIN}
    595   Status = ${Function} (ImageHandle, SystemTable);
    596   ASSERT_EFI_ERROR (Status);${END}
    597 """),
    598 }
    599 
    600 ## Library Constructor and Destructor Templates

    601 gLibraryString = {
    602 'BASE'  :   TemplateString("""
    603 ${BEGIN}${FunctionPrototype}${END}
    604 
    605 VOID
    606 EFIAPI
    607 ProcessLibrary${Type}List (
    608   VOID
    609   )
    610 {
    611 ${BEGIN}  EFI_STATUS  Status;
    612 ${FunctionCall}${END}
    613 }
    614 """),
    615 
    616 'PEI'   :   TemplateString("""
    617 ${BEGIN}${FunctionPrototype}${END}
    618 
    619 VOID
    620 EFIAPI
    621 ProcessLibrary${Type}List (
    622   IN       EFI_PEI_FILE_HANDLE       FileHandle,
    623   IN CONST EFI_PEI_SERVICES          **PeiServices
    624   )
    625 {
    626 ${BEGIN}  EFI_STATUS  Status;
    627 ${FunctionCall}${END}
    628 }
    629 """),
    630 
    631 'DXE'   :   TemplateString("""
    632 ${BEGIN}${FunctionPrototype}${END}
    633 
    634 VOID
    635 EFIAPI
    636 ProcessLibrary${Type}List (
    637   IN EFI_HANDLE        ImageHandle,
    638   IN EFI_SYSTEM_TABLE  *SystemTable
    639   )
    640 {
    641 ${BEGIN}  EFI_STATUS  Status;
    642 ${FunctionCall}${END}
    643 }
    644 """),
    645 }
    646 
    647 gBasicHeaderFile = "Base.h"
    648 
    649 gModuleTypeHeaderFile = {
    650     "BASE"              :   [gBasicHeaderFile],
    651     "SEC"               :   ["PiPei.h", "Library/DebugLib.h"],
    652     "PEI_CORE"          :   ["PiPei.h", "Library/DebugLib.h", "Library/PeiCoreEntryPoint.h"],
    653     "PEIM"              :   ["PiPei.h", "Library/DebugLib.h", "Library/PeimEntryPoint.h"],
    654     "DXE_CORE"          :   ["PiDxe.h", "Library/DebugLib.h", "Library/DxeCoreEntryPoint.h"],
    655     "DXE_DRIVER"        :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
    656     "DXE_SMM_DRIVER"    :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
    657     "DXE_RUNTIME_DRIVER":   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
    658     "DXE_SAL_DRIVER"    :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
    659     "UEFI_DRIVER"       :   ["Uefi.h",  "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
    660     "UEFI_APPLICATION"  :   ["Uefi.h",  "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiApplicationEntryPoint.h"],
    661     "SMM_CORE"          :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiDriverEntryPoint.h"],
    662     "USER_DEFINED"      :   [gBasicHeaderFile]
    663 }
    664 
    665 ## Autogen internal worker macro to define DynamicEx PCD name includes both the TokenSpaceGuidName 

    666 #  the TokenName and Guid comparison to avoid define name collisions.

    667 #

    668 #   @param      Info        The ModuleAutoGen object

    669 #   @param      AutoGenH    The TemplateString object for header file

    670 #

    671 #

    672 def DynExPcdTokenNumberMapping(Info, AutoGenH):
    673     ExTokenCNameList = []
    674     PcdExList        = []
    675     if Info.IsLibrary:
    676         PcdList = Info.LibraryPcdList
    677     else:
    678         PcdList = Info.ModulePcdList
    679     for Pcd in PcdList:
    680         if Pcd.Type in gDynamicExPcd:
    681             ExTokenCNameList.append(Pcd.TokenCName)
    682             PcdExList.append(Pcd)
    683     if len(ExTokenCNameList) == 0:
    684         return
    685     AutoGenH.Append('\n#define COMPAREGUID(Guid1, Guid2) (BOOLEAN)(*(CONST UINT64*)Guid1 == *(CONST UINT64*)Guid2 && *((CONST UINT64*)Guid1 + 1) == *((CONST UINT64*)Guid2 + 1))\n')
    686     # AutoGen for each PCD listed in a [PcdEx] section of a Module/Lib INF file.

    687     # Auto generate a macro for each TokenName that takes a Guid pointer as a parameter.  

    688     # Use the Guid pointer to see if it matches any of the token space GUIDs.

    689     TokenCNameList = []
    690     for TokenCName in ExTokenCNameList:
    691         if TokenCName in TokenCNameList:
    692             continue
    693         Index = 0
    694         Count = ExTokenCNameList.count(TokenCName)
    695         for Pcd in PcdExList:
    696             if Pcd.TokenCName == TokenCName:
    697                 Index = Index + 1
    698                 if Index == 1:
    699                     AutoGenH.Append('\n#define __PCD_%s_ADDR_CMP(GuidPtr)  (' % (Pcd.TokenCName))
    700                     AutoGenH.Append('\\\n  (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:' 
    701                                     % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
    702                 else:
    703                     AutoGenH.Append('\\\n  (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:' 
    704                                     % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
    705                 if Index == Count:
    706                     AutoGenH.Append('0 \\\n  )\n')
    707                 TokenCNameList.append(TokenCName)
    708     
    709     TokenCNameList = []
    710     for TokenCName in ExTokenCNameList:
    711         if TokenCName in TokenCNameList:
    712             continue
    713         Index = 0
    714         Count = ExTokenCNameList.count(TokenCName)
    715         for Pcd in PcdExList:
    716             if Pcd.Type in gDynamicExPcd and Pcd.TokenCName == TokenCName:
    717                 Index = Index + 1
    718                 if Index == 1:
    719                     AutoGenH.Append('\n#define __PCD_%s_VAL_CMP(GuidPtr)  (' % (Pcd.TokenCName))
    720                     AutoGenH.Append('\\\n  (GuidPtr == NULL) ? 0:')
    721                     AutoGenH.Append('\\\n  COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:' 
    722                                     % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
    723                 else:
    724                     AutoGenH.Append('\\\n  COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:' 
    725                                     % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
    726                 if Index == Count:
    727                     AutoGenH.Append('0 \\\n  )\n')
    728                     # Autogen internal worker macro to compare GUIDs.  Guid1 is a pointer to a GUID.  

    729                     # Guid2 is a C name for a GUID. Compare pointers first because optimizing compiler

    730                     # can do this at build time on CONST GUID pointers and optimize away call to COMPAREGUID().

    731                     #  COMPAREGUID() will only be used if the Guid passed in is local to the module.

    732                     AutoGenH.Append('#define _PCD_TOKEN_EX_%s(GuidPtr)   __PCD_%s_ADDR_CMP(GuidPtr) ? __PCD_%s_ADDR_CMP(GuidPtr) : __PCD_%s_VAL_CMP(GuidPtr)  \n'
    733                                     % (Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
    734                 TokenCNameList.append(TokenCName)
    735 
    736 def GetPcdSize(Pcd):
    737     if Pcd.DatumType == 'VOID*':
    738         Value = Pcd.DefaultValue
    739         if Value in [None, '']:
    740             return 1
    741         elif Value[0] == 'L':
    742             return (len(Value) - 2) * 2
    743         elif Value[0] == '{':
    744             return len(Value.split(','))
    745         else:
    746             return len(Value) - 1
    747     if Pcd.DatumType == 'UINT64':
    748         return 8
    749     if Pcd.DatumType == 'UINT32':
    750         return 4
    751     if Pcd.DatumType == 'UINT16':
    752         return 2
    753     if Pcd.DatumType == 'UINT8':
    754         return 1
    755     if Pcd.DatumType == 'BOOLEAN':
    756         return 1
    757 
    758 
    759 ## Create code for module PCDs

    760 #

    761 #   @param      Info        The ModuleAutoGen object

    762 #   @param      AutoGenC    The TemplateString object for C code

    763 #   @param      AutoGenH    The TemplateString object for header file

    764 #   @param      Pcd         The PCD object

    765 #

    766 def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
    767     TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[Pcd.TokenSpaceGuidCName]

    768     PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
    769     #

    770     # Write PCDs

    771     #

    772     PcdTokenName = '_PCD_TOKEN_' + Pcd.TokenCName
    773     PatchPcdSizeTokenName = '_PCD_PATCHABLE_' + Pcd.TokenCName +'_SIZE'
    774     PatchPcdSizeVariableName = '_gPcd_BinaryPatch_Size_' + Pcd.TokenCName
    775     FixPcdSizeTokenName = '_PCD_SIZE_' + Pcd.TokenCName
    776     
    777     if Pcd.Type in gDynamicExPcd:
    778         TokenNumber = int(Pcd.TokenValue, 0)
    779         # Add TokenSpaceGuidValue value to PcdTokenName to discriminate the DynamicEx PCDs with 

    780         # different Guids but same TokenCName

    781         PcdExTokenName = '_PCD_TOKEN_' + Pcd.TokenSpaceGuidCName + '_' + Pcd.TokenCName
    782         AutoGenH.Append('\n#define %s  %dU\n' % (PcdExTokenName, TokenNumber))
    783     else:
    784         if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
    785             # If one of the Source built modules listed in the DSC is not listed in FDF modules, 

    786             # and the INF lists a PCD can only use the PcdsDynamic access method (it is only 

    787             # listed in the DEC file that declares the PCD as PcdsDynamic), then build tool will 

    788             # report warning message notify the PI that they are attempting to build a module 

    789             # that must be included in a flash image in order to be functional. These Dynamic PCD 

    790             # will not be added into the Database unless it is used by other modules that are 

    791             # included in the FDF file. 

    792             # In this case, just assign an invalid token number to make it pass build.

    793             if Pcd.Type in PCD_DYNAMIC_TYPE_LIST:
    794                 TokenNumber = 0
    795             else:
    796                 EdkLogger.error("build", AUTOGEN_ERROR,
    797                                 "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    798                                 ExtraData="[%s]" % str(Info))
    799         else:
    800             TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
    801         AutoGenH.Append('\n#define %s  %dU\n' % (PcdTokenName, TokenNumber))
    802 
    803     EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + Pcd.TokenCName + "." + Pcd.TokenSpaceGuidCName)
    804     if Pcd.Type not in gItemTypeStringDatabase:
    805         EdkLogger.error("build", AUTOGEN_ERROR,
    806                         "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    807                         ExtraData="[%s]" % str(Info))
    808     if Pcd.DatumType not in gDatumSizeStringDatabase:
    809         EdkLogger.error("build", AUTOGEN_ERROR,
    810                         "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    811                         ExtraData="[%s]" % str(Info))
    812 
    813     DatumSize = gDatumSizeStringDatabase[Pcd.DatumType]
    814     DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]
    815     GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
    816     SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
    817     SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + Pcd.TokenCName
    818     GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + Pcd.TokenCName
    819     
    820     PcdExCNameList  = []
    821     if Pcd.Type in gDynamicExPcd:
    822         if Info.IsLibrary:
    823             PcdList = Info.LibraryPcdList
    824         else:
    825             PcdList = Info.ModulePcdList
    826         for PcdModule in PcdList:
    827             if PcdModule.Type in gDynamicExPcd:
    828                 PcdExCNameList.append(PcdModule.TokenCName)
    829         # Be compatible with the current code which using PcdToken and PcdGet/Set for DynamicEx Pcd.

    830         # If only PcdToken and PcdGet/Set used in all Pcds with different CName, it should succeed to build.

    831         # If PcdToken and PcdGet/Set used in the Pcds with different Guids but same CName, it should failed to build.

    832         if PcdExCNameList.count(Pcd.TokenCName) > 1:
    833             AutoGenH.Append('// Disabled the macros, as PcdToken and PcdGet/Set are not allowed in the case that more than one DynamicEx Pcds are different Guids but same CName.\n')
    834             AutoGenH.Append('// #define %s  %s\n' % (PcdTokenName, PcdExTokenName))
    835             AutoGenH.Append('// #define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
    836             AutoGenH.Append('// #define %s  LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))
    837             if Pcd.DatumType == 'VOID*':
    838                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
    839                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
    840             else:
    841                 AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
    842                 AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
    843         else:
    844             AutoGenH.Append('#define %s  %s\n' % (PcdTokenName, PcdExTokenName))
    845             AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
    846             AutoGenH.Append('#define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))
    847             if Pcd.DatumType == 'VOID*':
    848                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
    849                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
    850             else:
    851                 AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
    852                 AutoGenH.Append('#define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
    853     elif Pcd.Type in gDynamicPcd:
    854         PcdList = []
    855         PcdCNameList = []
    856         PcdList.extend(Info.LibraryPcdList)
    857         PcdList.extend(Info.ModulePcdList)
    858         for PcdModule in PcdList:
    859             if PcdModule.Type in gDynamicPcd:
    860                 PcdCNameList.append(PcdModule.TokenCName)
    861         if PcdCNameList.count(Pcd.TokenCName) > 1:
    862             EdkLogger.error("build", AUTOGEN_ERROR, "More than one Dynamic Pcds [%s] are different Guids but same CName. They need to be changed to DynamicEx type to avoid the confliction.\n" % (Pcd.TokenCName), ExtraData="[%s]" % str(Info.MetaFile.Path))
    863         else:
    864             AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
    865             AutoGenH.Append('#define %s  LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))
    866             if Pcd.DatumType == 'VOID*':
    867                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
    868                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
    869             else:
    870                 AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
    871                 AutoGenH.Append('#define %s(Value)  LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
    872     else:
    873         PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName
    874         Const = 'const'
    875         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
    876             Const = ''
    877         Type = ''
    878         Array = ''
    879         Value = Pcd.DefaultValue
    880         Unicode = False
    881         ValueNumber = 0
    882 
    883         if Pcd.DatumType == 'BOOLEAN':
    884             BoolValue = Value.upper()
    885             if BoolValue == 'TRUE' or BoolValue == '1':
    886                 Value = '1U'
    887             elif BoolValue == 'FALSE' or BoolValue == '0':
    888                 Value = '0U'
    889 
    890         if Pcd.DatumType in ['UINT64', 'UINT32', 'UINT16', 'UINT8']:
    891             try:
    892                 if Value.upper().startswith('0X'):
    893                     ValueNumber = int (Value, 16)
    894                 else:
    895                     ValueNumber = int (Value)
    896             except:
    897                 EdkLogger.error("build", AUTOGEN_ERROR,
    898                                 "PCD value is not valid dec or hex number for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    899                                 ExtraData="[%s]" % str(Info))
    900             if Pcd.DatumType == 'UINT64':
    901                 if ValueNumber < 0:
    902                     EdkLogger.error("build", AUTOGEN_ERROR,
    903                                     "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    904                                     ExtraData="[%s]" % str(Info))
    905                 elif ValueNumber >= 0x10000000000000000:
    906                     EdkLogger.error("build", AUTOGEN_ERROR,
    907                                     "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    908                                     ExtraData="[%s]" % str(Info))
    909                 if not Value.endswith('ULL'):
    910                     Value += 'ULL'
    911             elif Pcd.DatumType == 'UINT32':
    912                 if ValueNumber < 0:
    913                     EdkLogger.error("build", AUTOGEN_ERROR,
    914                                     "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    915                                     ExtraData="[%s]" % str(Info))
    916                 elif ValueNumber >= 0x100000000:
    917                     EdkLogger.error("build", AUTOGEN_ERROR,
    918                                     "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    919                                     ExtraData="[%s]" % str(Info))
    920                 if not Value.endswith('U'):
    921                     Value += 'U'
    922             elif Pcd.DatumType == 'UINT16':
    923                 if ValueNumber < 0:
    924                     EdkLogger.error("build", AUTOGEN_ERROR,
    925                                     "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    926                                     ExtraData="[%s]" % str(Info))
    927                 elif ValueNumber >= 0x10000:
    928                     EdkLogger.error("build", AUTOGEN_ERROR,
    929                                     "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    930                                     ExtraData="[%s]" % str(Info))
    931                 if not Value.endswith('U'):
    932                     Value += 'U'                    
    933             elif Pcd.DatumType == 'UINT8':
    934                 if ValueNumber < 0:
    935                     EdkLogger.error("build", AUTOGEN_ERROR,
    936                                     "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    937                                     ExtraData="[%s]" % str(Info))
    938                 elif ValueNumber >= 0x100:
    939                     EdkLogger.error("build", AUTOGEN_ERROR,
    940                                     "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    941                                     ExtraData="[%s]" % str(Info))
    942                 if not Value.endswith('U'):
    943                     Value += 'U'
    944         if Pcd.DatumType == 'VOID*':
    945             if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
    946                 EdkLogger.error("build", AUTOGEN_ERROR,
    947                                 "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    948                                 ExtraData="[%s]" % str(Info))
    949 
    950             ArraySize = int(Pcd.MaxDatumSize, 0)
    951             if Value[0] == '{':
    952                 Type = '(VOID *)'
    953             else:
    954                 if Value[0] == 'L':
    955                     Unicode = True
    956                 Value = Value.lstrip('L')   #.strip('"')

    957                 Value = eval(Value)         # translate escape character

    958                 NewValue = '{'
    959                 for Index in range(0,len(Value)):
    960                     if Unicode:
    961                         NewValue = NewValue + str(ord(Value[Index]) % 0x10000) + ', '
    962                     else:
    963                         NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ', '
    964                 if Unicode:
    965                     ArraySize = ArraySize / 2;
    966 
    967                 if ArraySize < (len(Value) + 1):
    968                     EdkLogger.error("build", AUTOGEN_ERROR,
    969                                     "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
    970                                     ExtraData="[%s]" % str(Info))
    971                 Value = NewValue + '0 }'
    972             Array = '[%d]' % ArraySize
    973         #

    974         # skip casting for fixed at build since it breaks ARM assembly.

    975         # Long term we need PCD macros that work in assembly

    976         #

    977         elif Pcd.Type != TAB_PCDS_FIXED_AT_BUILD:
    978             Value = "((%s)%s)" % (Pcd.DatumType, Value)
    979 
    980         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
    981             PcdValueName = '_PCD_PATCHABLE_VALUE_' + Pcd.TokenCName
    982         else:
    983             PcdValueName = '_PCD_VALUE_' + Pcd.TokenCName
    984             
    985         if Pcd.DatumType == 'VOID*':
    986             #

    987             # For unicode, UINT16 array will be generated, so the alignment of unicode is guaranteed.

    988             #

    989             if Unicode:
    990                 AutoGenH.Append('#define %s  %s%s\n' %(PcdValueName, Type, PcdVariableName))
    991                 AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT16 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
    992                 AutoGenH.Append('extern %s UINT16 %s%s;\n' %(Const, PcdVariableName, Array))
    993                 AutoGenH.Append('#define %s  %s%s\n' %(GetModeName, Type, PcdVariableName))
    994             else:
    995                 AutoGenH.Append('#define %s  %s%s\n' %(PcdValueName, Type, PcdVariableName))
    996                 AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT8 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
    997                 AutoGenH.Append('extern %s UINT8 %s%s;\n' %(Const, PcdVariableName, Array))
    998                 AutoGenH.Append('#define %s  %s%s\n' %(GetModeName, Type, PcdVariableName))
    999                 
   1000             PcdDataSize = GetPcdSize(Pcd)
   1001             if Pcd.Type == TAB_PCDS_FIXED_AT_BUILD:
   1002                 AutoGenH.Append('#define %s %s\n' % (FixPcdSizeTokenName, PcdDataSize))
   1003                 AutoGenH.Append('#define %s  %s \n' % (GetModeSizeName,FixPcdSizeTokenName))
   1004             
   1005             if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
   1006                 AutoGenH.Append('#define %s %s\n' % (PatchPcdSizeTokenName, Pcd.MaxDatumSize))
   1007                 AutoGenH.Append('#define %s  %s \n' % (GetModeSizeName,PatchPcdSizeVariableName))
   1008                 AutoGenH.Append('extern UINTN %s; \n' % PatchPcdSizeVariableName)
   1009                 AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED UINTN %s = %s;\n' % (PatchPcdSizeVariableName,PcdDataSize))
   1010         elif Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
   1011             AutoGenH.Append('#define %s  %s\n' %(PcdValueName, Value))
   1012             AutoGenC.Append('volatile %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
   1013             AutoGenH.Append('extern volatile %s  %s  %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
   1014             AutoGenH.Append('#define %s  %s%s\n' % (GetModeName, Type, PcdVariableName))
   1015             
   1016             PcdDataSize = GetPcdSize(Pcd)
   1017             AutoGenH.Append('#define %s %s\n' % (PatchPcdSizeTokenName, PcdDataSize))
   1018             
   1019             AutoGenH.Append('#define %s  %s \n' % (GetModeSizeName,PatchPcdSizeVariableName))
   1020             AutoGenH.Append('extern UINTN %s; \n' % PatchPcdSizeVariableName)
   1021             AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED UINTN %s = %s;\n' % (PatchPcdSizeVariableName,PcdDataSize))
   1022         else:
   1023             PcdDataSize = GetPcdSize(Pcd)
   1024             AutoGenH.Append('#define %s %s\n' % (FixPcdSizeTokenName, PcdDataSize))
   1025             AutoGenH.Append('#define %s  %s \n' % (GetModeSizeName,FixPcdSizeTokenName))
   1026             
   1027             AutoGenH.Append('#define %s  %s\n' %(PcdValueName, Value))
   1028             AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
   1029             AutoGenH.Append('extern %s  %s  %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
   1030             AutoGenH.Append('#define %s  %s%s\n' % (GetModeName, Type, PcdVariableName))
   1031 
   1032         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
   1033             if Pcd.DatumType == 'VOID*':
   1034                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
   1035                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
   1036             else:
   1037                 AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))
   1038                 AutoGenH.Append('#define %s(Value)  ((%s = (Value)), RETURN_SUCCESS) \n' % (SetModeStatusName, PcdVariableName))
   1039         else:
   1040             AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
   1041 
   1042 ## Create code for library module PCDs

   1043 #

   1044 #   @param      Info        The ModuleAutoGen object

   1045 #   @param      AutoGenC    The TemplateString object for C code

   1046 #   @param      AutoGenH    The TemplateString object for header file

   1047 #   @param      Pcd         The PCD object

   1048 #

   1049 def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
   1050     PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
   1051     TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
   1052     TokenCName  = Pcd.TokenCName
   1053     PcdTokenName = '_PCD_TOKEN_' + TokenCName
   1054     FixPcdSizeTokenName = '_PCD_SIZE_' + Pcd.TokenCName
   1055     PatchPcdSizeTokenName = '_PCD_PATCHABLE_' + Pcd.TokenCName +'_SIZE'
   1056     PatchPcdSizeVariableName = '_gPcd_BinaryPatch_Size_' + Pcd.TokenCName
   1057     
   1058     #

   1059     # Write PCDs

   1060     #

   1061     if Pcd.Type in gDynamicExPcd:
   1062         TokenNumber = int(Pcd.TokenValue, 0)
   1063     else:
   1064         if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
   1065             # If one of the Source built modules listed in the DSC is not listed in FDF modules, 

   1066             # and the INF lists a PCD can only use the PcdsDynamic access method (it is only 

   1067             # listed in the DEC file that declares the PCD as PcdsDynamic), then build tool will 

   1068             # report warning message notify the PI that they are attempting to build a module 

   1069             # that must be included in a flash image in order to be functional. These Dynamic PCD 

   1070             # will not be added into the Database unless it is used by other modules that are 

   1071             # included in the FDF file. 

   1072             # In this case, just assign an invalid token number to make it pass build.

   1073             if Pcd.Type in PCD_DYNAMIC_TYPE_LIST:
   1074                 TokenNumber = 0
   1075             else:
   1076                 EdkLogger.error("build", AUTOGEN_ERROR,
   1077                                 "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
   1078                                 ExtraData="[%s]" % str(Info))
   1079         else:
   1080             TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
   1081 
   1082     if Pcd.Type not in gItemTypeStringDatabase:
   1083         EdkLogger.error("build", AUTOGEN_ERROR,
   1084                         "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
   1085                         ExtraData="[%s]" % str(Info))
   1086     if Pcd.DatumType not in gDatumSizeStringDatabase:
   1087         EdkLogger.error("build", AUTOGEN_ERROR,
   1088                         "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
   1089                         ExtraData="[%s]" % str(Info))
   1090 
   1091     DatumType   = Pcd.DatumType
   1092     DatumSize   = gDatumSizeStringDatabaseH[DatumType]
   1093     DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType]
   1094     GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName
   1095     SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName
   1096     SetModeStatusName = '_PCD_SET_MODE_' + DatumSize + '_S_' + TokenCName
   1097     GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + Pcd.TokenCName
   1098 
   1099     Type = ''
   1100     Array = ''
   1101     if Pcd.DatumType == 'VOID*':
   1102         Type = '(VOID *)'
   1103         Array = '[]'
   1104     PcdItemType = Pcd.Type
   1105     PcdExCNameList  = []
   1106     if PcdItemType in gDynamicExPcd:
   1107         PcdExTokenName = '_PCD_TOKEN_' + TokenSpaceGuidCName + '_' + Pcd.TokenCName
   1108         AutoGenH.Append('\n#define %s  %dU\n' % (PcdExTokenName, TokenNumber))
   1109         
   1110         if Info.IsLibrary:
   1111             PcdList = Info.LibraryPcdList
   1112         else:
   1113             PcdList = Info.ModulePcdList
   1114         for PcdModule in PcdList:
   1115             if PcdModule.Type in gDynamicExPcd:
   1116                 PcdExCNameList.append(PcdModule.TokenCName)
   1117         # Be compatible with the current code which using PcdGet/Set for DynamicEx Pcd.

   1118         # If only PcdGet/Set used in all Pcds with different CName, it should succeed to build.

   1119         # If PcdGet/Set used in the Pcds with different Guids but same CName, it should failed to build.

   1120         if PcdExCNameList.count(Pcd.TokenCName) > 1:
   1121             AutoGenH.Append('// Disabled the macros, as PcdToken and PcdGet/Set are not allowed in the case that more than one DynamicEx Pcds are different Guids but same CName.\n')
   1122             AutoGenH.Append('// #define %s  %s\n' % (PcdTokenName, PcdExTokenName))
   1123             AutoGenH.Append('// #define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
   1124             AutoGenH.Append('// #define %s  LibPcdGetExSize(&%s, %s \n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))
   1125             if Pcd.DatumType == 'VOID*':
   1126                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
   1127                 AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
   1128             else:
   1129                 AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
   1130                 AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
   1131         else:
   1132             AutoGenH.Append('#define %s  %s\n' % (PcdTokenName, PcdExTokenName))
   1133             AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
   1134             AutoGenH.Append('#define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))
   1135             if Pcd.DatumType == 'VOID*':
   1136                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
   1137                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
   1138             else:
   1139                 AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
   1140                 AutoGenH.Append('#define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
   1141     else:
   1142         AutoGenH.Append('#define _PCD_TOKEN_%s  %dU\n' % (TokenCName, TokenNumber))
   1143     if PcdItemType in gDynamicPcd:
   1144         PcdList = []
   1145         PcdCNameList = []
   1146         PcdList.extend(Info.LibraryPcdList)
   1147         PcdList.extend(Info.ModulePcdList)
   1148         for PcdModule in PcdList:
   1149             if PcdModule.Type in gDynamicPcd:
   1150                 PcdCNameList.append(PcdModule.TokenCName)
   1151         if PcdCNameList.count(Pcd.TokenCName) > 1:
   1152             EdkLogger.error("build", AUTOGEN_ERROR, "More than one Dynamic Pcds [%s] are different Guids but same CName.They need to be changed to DynamicEx type to avoid the confliction.\n" % (Pcd.TokenCName), ExtraData="[%s]" % str(Info.MetaFile.Path))
   1153         else:
   1154             AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
   1155             AutoGenH.Append('#define %s  LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))
   1156             if DatumType == 'VOID*':
   1157                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
   1158                 AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
   1159             else:
   1160                 AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
   1161                 AutoGenH.Append('#define %s(Value)  LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
   1162     if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:
   1163         PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName
   1164         AutoGenH.Append('extern volatile %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) )
   1165         AutoGenH.Append('#define %s  %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))
   1166         if Pcd.DatumType == 'VOID*':
   1167             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
   1168             AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
   1169         else:
   1170             AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))
   1171             AutoGenH.Append('#define %s(Value)  ((%s = (Value)), RETURN_SUCCESS)\n' % (SetModeStatusName, PcdVariableName))
   1172         
   1173         PcdDataSize = GetPcdSize(Pcd)
   1174         AutoGenH.Append('#define %s %s\n' % (PatchPcdSizeTokenName, PcdDataSize))
   1175         AutoGenH.Append('#define %s %s\n' % (GetModeSizeName,PatchPcdSizeVariableName))
   1176         AutoGenH.Append('extern UINTN %s; \n' % PatchPcdSizeVariableName)
   1177         
   1178     if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:
   1179         key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))
   1180         
   1181         if DatumType == 'VOID*' and Array == '[]':
   1182             DatumType = ['UINT8', 'UINT16'][Pcd.DefaultValue[0] == 'L']
   1183         AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))
   1184         AutoGenH.Append('#define %s  %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName))
   1185         AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
   1186         
   1187         if PcdItemType == TAB_PCDS_FIXED_AT_BUILD and key in Info.ConstPcd:
   1188             AutoGenH.Append('#define _PCD_VALUE_%s %s\n' %(TokenCName, Pcd.DefaultValue))
   1189         
   1190         if PcdItemType == TAB_PCDS_FIXED_AT_BUILD:
   1191             PcdDataSize = GetPcdSize(Pcd)
   1192             AutoGenH.Append('#define %s %s\n' % (FixPcdSizeTokenName, PcdDataSize))
   1193             AutoGenH.Append('#define %s %s\n' % (GetModeSizeName,FixPcdSizeTokenName))
   1194 
   1195 ## Create code for library constructor

   1196 #

   1197 #   @param      Info        The ModuleAutoGen object

   1198 #   @param      AutoGenC    The TemplateString object for C code

   1199 #   @param      AutoGenH    The TemplateString object for header file

   1200 #

   1201 def CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH):
   1202     #

   1203     # Library Constructors

   1204     #

   1205     ConstructorPrototypeString = TemplateString()
   1206     ConstructorCallingString = TemplateString()
   1207     if Info.IsLibrary:
   1208         DependentLibraryList = [Info.Module]
   1209     else:
   1210         DependentLibraryList = Info.DependentLibraryList
   1211     for Lib in DependentLibraryList:
   1212         if len(Lib.ConstructorList) <= 0:
   1213             continue
   1214         Dict = {'Function':Lib.ConstructorList}
   1215         if Lib.ModuleType in ['BASE', 'SEC']:
   1216             ConstructorPrototypeString.Append(gLibraryStructorPrototype['BASE'].Replace(Dict))
   1217             ConstructorCallingString.Append(gLibraryStructorCall['BASE'].Replace(Dict))
   1218         elif Lib.ModuleType in ['PEI_CORE','PEIM']:
   1219             ConstructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict))
   1220             ConstructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict))
   1221         elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
   1222                                 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
   1223             ConstructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict))
   1224             ConstructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict))
   1225 
   1226     if str(ConstructorPrototypeString) == '':
   1227         ConstructorPrototypeList = []
   1228     else:
   1229         ConstructorPrototypeList = [str(ConstructorPrototypeString)]
   1230     if str(ConstructorCallingString) == '':
   1231         ConstructorCallingList = []
   1232     else:
   1233         ConstructorCallingList = [str(ConstructorCallingString)]
   1234 
   1235     Dict = {
   1236         'Type'              :   'Constructor',
   1237         'FunctionPrototype' :   ConstructorPrototypeList,
   1238         'FunctionCall'      :   ConstructorCallingList
   1239     }
   1240     if Info.IsLibrary:
   1241         AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict)
   1242     else:
   1243         if Info.ModuleType in ['BASE', 'SEC']:
   1244             AutoGenC.Append(gLibraryString['BASE'].Replace(Dict))
   1245         elif Info.ModuleType in ['PEI_CORE','PEIM']:
   1246             AutoGenC.Append(gLibraryString['PEI'].Replace(Dict))
   1247         elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
   1248                                  'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
   1249             AutoGenC.Append(gLibraryString['DXE'].Replace(Dict))
   1250 
   1251 ## Create code for library destructor

   1252 #

   1253 #   @param      Info        The ModuleAutoGen object

   1254 #   @param      AutoGenC    The TemplateString object for C code

   1255 #   @param      AutoGenH    The TemplateString object for header file

   1256 #

   1257 def CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH):
   1258     #

   1259     # Library Destructors

   1260     #

   1261     DestructorPrototypeString = TemplateString()
   1262     DestructorCallingString = TemplateString()
   1263     if Info.IsLibrary:
   1264         DependentLibraryList = [Info.Module]
   1265     else:
   1266         DependentLibraryList = Info.DependentLibraryList
   1267     for Index in range(len(DependentLibraryList)-1, -1, -1):
   1268         Lib = DependentLibraryList[Index]
   1269         if len(Lib.DestructorList) <= 0:
   1270             continue
   1271         Dict = {'Function':Lib.DestructorList}
   1272         if Lib.ModuleType in ['BASE', 'SEC']:
   1273             DestructorPrototypeString.Append(gLibraryStructorPrototype['BASE'].Replace(Dict))
   1274             DestructorCallingString.Append(gLibraryStructorCall['BASE'].Replace(Dict))
   1275         elif Lib.ModuleType in ['PEI_CORE','PEIM']:
   1276             DestructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict))
   1277             DestructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict))
   1278         elif Lib.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
   1279                                 'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION', 'SMM_CORE']:
   1280             DestructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict))
   1281             DestructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict))
   1282 
   1283     if str(DestructorPrototypeString) == '':
   1284         DestructorPrototypeList = []
   1285     else:
   1286         DestructorPrototypeList = [str(DestructorPrototypeString)]
   1287     if str(DestructorCallingString) == '':
   1288         DestructorCallingList = []
   1289     else:
   1290         DestructorCallingList = [str(DestructorCallingString)]
   1291 
   1292     Dict = {
   1293         'Type'              :   'Destructor',
   1294         'FunctionPrototype' :   DestructorPrototypeList,
   1295         'FunctionCall'      :   DestructorCallingList
   1296     }
   1297     if Info.IsLibrary:
   1298         AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict)
   1299     else:
   1300         if Info.ModuleType in ['BASE', 'SEC']:
   1301             AutoGenC.Append(gLibraryString['BASE'].Replace(Dict))
   1302         elif Info.ModuleType in ['PEI_CORE','PEIM']:
   1303             AutoGenC.Append(gLibraryString['PEI'].Replace(Dict))
   1304         elif Info.ModuleType in ['DXE_CORE','DXE_DRIVER','DXE_SMM_DRIVER','DXE_RUNTIME_DRIVER',
   1305                                  'DXE_SAL_DRIVER','UEFI_DRIVER','UEFI_APPLICATION','SMM_CORE']:
   1306             AutoGenC.Append(gLibraryString['DXE'].Replace(Dict))
   1307 
   1308 
   1309 ## Create code for ModuleEntryPoint

   1310 #

   1311 #   @param      Info        The ModuleAutoGen object

   1312 #   @param      AutoGenC    The TemplateString object for C code

   1313 #   @param      AutoGenH    The TemplateString object for header file

   1314 #

   1315 def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH):
   1316     if Info.IsLibrary or Info.ModuleType in ['USER_DEFINED', 'SEC']:
   1317         return
   1318     #

   1319     # Module Entry Points

   1320     #

   1321     NumEntryPoints = len(Info.Module.ModuleEntryPointList)
   1322     if 'PI_SPECIFICATION_VERSION' in Info.Module.Specification:
   1323         PiSpecVersion = Info.Module.Specification['PI_SPECIFICATION_VERSION']
   1324     else:
   1325         PiSpecVersion = '0x00000000'
   1326     if 'UEFI_SPECIFICATION_VERSION' in Info.Module.Specification:
   1327         UefiSpecVersion = Info.Module.Specification['UEFI_SPECIFICATION_VERSION']
   1328     else:
   1329         UefiSpecVersion = '0x00000000'
   1330     Dict = {
   1331         'Function'       :   Info.Module.ModuleEntryPointList,
   1332         'PiSpecVersion'  :   PiSpecVersion + 'U',
   1333         'UefiSpecVersion':   UefiSpecVersion + 'U'
   1334     }
   1335 
   1336     if Info.ModuleType in ['PEI_CORE', 'DXE_CORE', 'SMM_CORE']:
   1337         if Info.SourceFileList <> None and Info.SourceFileList <> []:
   1338           if NumEntryPoints != 1:
   1339               EdkLogger.error(
   1340                   "build",
   1341                   AUTOGEN_ERROR,
   1342                   '%s must have exactly one entry point' % Info.ModuleType,
   1343                   File=str(Info),
   1344                   ExtraData= ", ".join(Info.Module.ModuleEntryPointList)
   1345                   )
   1346     if Info.ModuleType == 'PEI_CORE':
   1347         AutoGenC.Append(gPeiCoreEntryPointString.Replace(Dict))
   1348         AutoGenH.Append(gPeiCoreEntryPointPrototype.Replace(Dict))
   1349     elif Info.ModuleType == 'DXE_CORE':
   1350         AutoGenC.Append(gDxeCoreEntryPointString.Replace(Dict))
   1351         AutoGenH.Append(gDxeCoreEntryPointPrototype.Replace(Dict))
   1352     elif Info.ModuleType == 'SMM_CORE':
   1353         AutoGenC.Append(gSmmCoreEntryPointString.Replace(Dict))
   1354         AutoGenH.Append(gSmmCoreEntryPointPrototype.Replace(Dict))
   1355     elif Info.ModuleType == 'PEIM':
   1356         if NumEntryPoints < 2:
   1357             AutoGenC.Append(gPeimEntryPointString[NumEntryPoints].Replace(Dict))
   1358         else:
   1359             AutoGenC.Append(gPeimEntryPointString[2].Replace(Dict))
   1360         AutoGenH.Append(gPeimEntryPointPrototype.Replace(Dict))
   1361     elif Info.ModuleType in ['DXE_RUNTIME_DRIVER','DXE_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER']:
   1362         if NumEntryPoints < 2:
   1363             AutoGenC.Append(gUefiDriverEntryPointString[NumEntryPoints].Replace(Dict))
   1364         else:
   1365             AutoGenC.Append(gUefiDriverEntryPointString[2].Replace(Dict))
   1366         AutoGenH.Append(gUefiDriverEntryPointPrototype.Replace(Dict))
   1367     elif Info.ModuleType == 'DXE_SMM_DRIVER':
   1368         if NumEntryPoints == 0:
   1369             AutoGenC.Append(gDxeSmmEntryPointString[0].Replace(Dict))
   1370         else:
   1371             AutoGenC.Append(gDxeSmmEntryPointString[1].Replace(Dict))
   1372         AutoGenH.Append(gDxeSmmEntryPointPrototype.Replace(Dict))    
   1373     elif Info.ModuleType == 'UEFI_APPLICATION':
   1374         if NumEntryPoints < 2:
   1375             AutoGenC.Append(gUefiApplicationEntryPointString[NumEntryPoints].Replace(Dict))
   1376         else:
   1377             AutoGenC.Append(gUefiApplicationEntryPointString[2].Replace(Dict))
   1378         AutoGenH.Append(gUefiApplicationEntryPointPrototype.Replace(Dict))
   1379 
   1380 ## Create code for ModuleUnloadImage

   1381 #

   1382 #   @param      Info        The ModuleAutoGen object

   1383 #   @param      AutoGenC    The TemplateString object for C code

   1384 #   @param      AutoGenH    The TemplateString object for header file

   1385 #

   1386 def CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH):
   1387     if Info.IsLibrary or Info.ModuleType in ['USER_DEFINED', 'SEC']:
   1388         return
   1389     #

   1390     # Unload Image Handlers

   1391     #

   1392     NumUnloadImage = len(Info.Module.ModuleUnloadImageList)
   1393     Dict = {'Count':str(NumUnloadImage) + 'U', 'Function':Info.Module.ModuleUnloadImageList}
   1394     if NumUnloadImage < 2:
   1395         AutoGenC.Append(gUefiUnloadImageString[NumUnloadImage].Replace(Dict))
   1396     else:
   1397         AutoGenC.Append(gUefiUnloadImageString[2].Replace(Dict))
   1398     AutoGenH.Append(gUefiUnloadImagePrototype.Replace(Dict))
   1399 
   1400 ## Create code for GUID

   1401 #

   1402 #   @param      Info        The ModuleAutoGen object

   1403 #   @param      AutoGenC    The TemplateString object for C code

   1404 #   @param      AutoGenH    The TemplateString object for header file

   1405 #

   1406 def CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH):
   1407     if Info.ModuleType in ["USER_DEFINED", "BASE"]:
   1408         GuidType = "GUID"
   1409     else:
   1410         GuidType = "EFI_GUID"
   1411 
   1412     if Info.GuidList:
   1413         if not Info.IsLibrary:
   1414             AutoGenC.Append("\n// Guids\n")
   1415         AutoGenH.Append("\n// Guids\n")
   1416     #

   1417     # GUIDs

   1418     #

   1419     for Key in Info.GuidList:
   1420         if not Info.IsLibrary:
   1421             AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.GuidList[Key]))
   1422         AutoGenH.Append('extern %s %s;\n' % (GuidType, Key))
   1423 
   1424 ## Create code for protocol

   1425 #

   1426 #   @param      Info        The ModuleAutoGen object

   1427 #   @param      AutoGenC    The TemplateString object for C code

   1428 #   @param      AutoGenH    The TemplateString object for header file

   1429 #

   1430 def CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH):
   1431     if Info.ModuleType in ["USER_DEFINED", "BASE"]:
   1432         GuidType = "GUID"
   1433     else:
   1434         GuidType = "EFI_GUID"
   1435 
   1436     if Info.ProtocolList:
   1437         if not Info.IsLibrary:
   1438             AutoGenC.Append("\n// Protocols\n")
   1439         AutoGenH.Append("\n// Protocols\n")
   1440     #

   1441     # Protocol GUIDs

   1442     #

   1443     for Key in Info.ProtocolList:
   1444         if not Info.IsLibrary:
   1445             AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.ProtocolList[Key]))
   1446         AutoGenH.Append('extern %s %s;\n' % (GuidType, Key))
   1447 
   1448 ## Create code for PPI

   1449 #

   1450 #   @param      Info        The ModuleAutoGen object

   1451 #   @param      AutoGenC    The TemplateString object for C code

   1452 #   @param      AutoGenH    The TemplateString object for header file

   1453 #

   1454 def CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH):
   1455     if Info.ModuleType in ["USER_DEFINED", "BASE"]:
   1456         GuidType = "GUID"
   1457     else:
   1458         GuidType = "EFI_GUID"
   1459 
   1460     if Info.PpiList:
   1461         if not Info.IsLibrary:
   1462             AutoGenC.Append("\n// PPIs\n")
   1463         AutoGenH.Append("\n// PPIs\n")
   1464     #

   1465     # PPI GUIDs

   1466     #

   1467     for Key in Info.PpiList:
   1468         if not Info.IsLibrary:
   1469             AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.PpiList[Key]))
   1470         AutoGenH.Append('extern %s %s;\n' % (GuidType, Key))
   1471 
   1472 ## Create code for PCD

   1473 #

   1474 #   @param      Info        The ModuleAutoGen object

   1475 #   @param      AutoGenC    The TemplateString object for C code

   1476 #   @param      AutoGenH    The TemplateString object for header file

   1477 #

   1478 def CreatePcdCode(Info, AutoGenC, AutoGenH):
   1479 
   1480     # Collect Token Space GUIDs used by DynamicEc PCDs

   1481     TokenSpaceList = []
   1482     for Pcd in Info.ModulePcdList:
   1483         if Pcd.Type in gDynamicExPcd and Pcd.TokenSpaceGuidCName not in TokenSpaceList:
   1484             TokenSpaceList += [Pcd.TokenSpaceGuidCName]
   1485             
   1486     # Add extern declarations to AutoGen.h if one or more Token Space GUIDs were found

   1487     if TokenSpaceList <> []:            
   1488         AutoGenH.Append("\n// Definition of PCD Token Space GUIDs used in this module\n\n")
   1489         if Info.ModuleType in ["USER_DEFINED", "BASE"]:
   1490             GuidType = "GUID"
   1491         else:
   1492             GuidType = "EFI_GUID"              
   1493         for Item in TokenSpaceList:
   1494             AutoGenH.Append('extern %s %s;\n' % (GuidType, Item))
   1495 
   1496     if Info.IsLibrary:
   1497         if Info.ModulePcdList:
   1498             AutoGenH.Append("\n// PCD definitions\n")
   1499         for Pcd in Info.ModulePcdList:
   1500             CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd)
   1501         DynExPcdTokenNumberMapping (Info, AutoGenH)
   1502     else:
   1503         if Info.ModulePcdList:
   1504             AutoGenH.Append("\n// Definition of PCDs used in this module\n")
   1505             AutoGenC.Append("\n// Definition of PCDs used in this module\n")
   1506         for Pcd in Info.ModulePcdList:
   1507             CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd)
   1508         DynExPcdTokenNumberMapping (Info, AutoGenH)
   1509         if Info.LibraryPcdList:
   1510             AutoGenH.Append("\n// Definition of PCDs used in libraries is in AutoGen.c\n")
   1511             AutoGenC.Append("\n// Definition of PCDs used in libraries\n")
   1512         for Pcd in Info.LibraryPcdList:
   1513             CreateModulePcdCode(Info, AutoGenC, AutoGenC, Pcd)
   1514     CreatePcdDatabaseCode(Info, AutoGenC, AutoGenH)
   1515 
   1516 ## Create code for unicode string definition

   1517 #

   1518 #   @param      Info        The ModuleAutoGen object

   1519 #   @param      AutoGenC    The TemplateString object for C code

   1520 #   @param      AutoGenH    The TemplateString object for header file

   1521 #   @param      UniGenCFlag     UniString is generated into AutoGen C file when it is set to True

   1522 #   @param      UniGenBinBuffer Buffer to store uni string package data

   1523 #

   1524 def CreateUnicodeStringCode(Info, AutoGenC, AutoGenH, UniGenCFlag, UniGenBinBuffer):
   1525     WorkingDir = os.getcwd()
   1526     os.chdir(Info.WorkspaceDir)
   1527 
   1528     IncList = [Info.MetaFile.Dir]
   1529     # Get all files under [Sources] section in inf file for EDK-II module

   1530     EDK2Module = True
   1531     SrcList = [F for F in Info.SourceFileList]
   1532     if Info.AutoGenVersion < 0x00010005:
   1533         EDK2Module = False
   1534         # Get all files under the module directory for EDK-I module

   1535         Cwd = os.getcwd()
   1536         os.chdir(Info.MetaFile.Dir)
   1537         for Root, Dirs, Files in os.walk("."):
   1538             if 'CVS' in Dirs:
   1539                 Dirs.remove('CVS')
   1540             if '.svn' in Dirs:
   1541                 Dirs.remove('.svn')
   1542             for File in Files:
   1543                 File = PathClass(os.path.join(Root, File), Info.MetaFile.Dir)
   1544                 if File in SrcList:
   1545                     continue
   1546                 SrcList.append(File)
   1547         os.chdir(Cwd)
   1548 
   1549     if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-c') > -1:
   1550         CompatibleMode = True
   1551     else:
   1552         CompatibleMode = False
   1553 
   1554     #

   1555     # -s is a temporary option dedicated for building .UNI files with ISO 639-2 language codes of EDK Shell in EDK2

   1556     #

   1557     if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-s') > -1:
   1558         if CompatibleMode:
   1559             EdkLogger.error("build", AUTOGEN_ERROR,
   1560                             "-c and -s build options should be used exclusively",
   1561                             ExtraData="[%s]" % str(Info))
   1562         ShellMode = True
   1563     else:
   1564         ShellMode = False
   1565 
   1566     #RFC4646 is only for EDKII modules and ISO639-2 for EDK modules

   1567     if EDK2Module:
   1568         FilterInfo = [EDK2Module] + [Info.PlatformInfo.Platform.RFCLanguages]
   1569     else:
   1570         FilterInfo = [EDK2Module] + [Info.PlatformInfo.Platform.ISOLanguages]
   1571     Header, Code = GetStringFiles(Info.UnicodeFileList, SrcList, IncList, Info.IncludePathList, ['.uni', '.inf'], Info.Name, CompatibleMode, ShellMode, UniGenCFlag, UniGenBinBuffer, FilterInfo)
   1572     if CompatibleMode or UniGenCFlag:
   1573         AutoGenC.Append("\n//\n//Unicode String Pack Definition\n//\n")
   1574         AutoGenC.Append(Code)
   1575         AutoGenC.Append("\n")
   1576     AutoGenH.Append("\n//\n//Unicode String ID\n//\n")
   1577     AutoGenH.Append(Header)
   1578     if CompatibleMode or UniGenCFlag:
   1579         AutoGenH.Append("\n#define STRING_ARRAY_NAME %sStrings\n" % Info.Name)
   1580     os.chdir(WorkingDir)
   1581 
   1582 ## Create common code

   1583 #

   1584 #   @param      Info        The ModuleAutoGen object

   1585 #   @param      AutoGenC    The TemplateString object for C code

   1586 #   @param      AutoGenH    The TemplateString object for header file

   1587 #

   1588 def CreateHeaderCode(Info, AutoGenC, AutoGenH):
   1589     # file header

   1590     AutoGenH.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.h'}))
   1591     # header file Prologue

   1592     AutoGenH.Append(gAutoGenHPrologueString.Replace({'File':'AUTOGENH','Guid':Info.Guid.replace('-','_')}))
   1593     AutoGenH.Append(gAutoGenHCppPrologueString)
   1594     if Info.AutoGenVersion >= 0x00010005:
   1595         # header files includes

   1596         AutoGenH.Append("#include <%s>\n" % gBasicHeaderFile)
   1597         if Info.ModuleType in gModuleTypeHeaderFile \
   1598            and gModuleTypeHeaderFile[Info.ModuleType][0] != gBasicHeaderFile:
   1599             AutoGenH.Append("#include <%s>\n" % gModuleTypeHeaderFile[Info.ModuleType][0])
   1600         #

   1601         # if either PcdLib in [LibraryClasses] sections or there exist Pcd section, add PcdLib.h 

   1602         # As if modules only uses FixedPcd, then PcdLib is not needed in [LibraryClasses] section.

   1603         #

   1604         if 'PcdLib' in Info.Module.LibraryClasses or Info.Module.Pcds:
   1605             AutoGenH.Append("#include <Library/PcdLib.h>\n")
   1606 
   1607         AutoGenH.Append('\nextern GUID  gEfiCallerIdGuid;')
   1608         AutoGenH.Append('\nextern CHAR8 *gEfiCallerBaseName;\n\n')
   1609 
   1610         if Info.IsLibrary:
   1611             return
   1612 
   1613         AutoGenH.Append("#define EFI_CALLER_ID_GUID \\\n  %s\n" % GuidStringToGuidStructureString(Info.Guid))
   1614 
   1615     if Info.IsLibrary:
   1616         return
   1617     # C file header

   1618     AutoGenC.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.c'}))
   1619     if Info.AutoGenVersion >= 0x00010005:
   1620         # C file header files includes

   1621         if Info.ModuleType in gModuleTypeHeaderFile:
   1622             for Inc in gModuleTypeHeaderFile[Info.ModuleType]:
   1623                 AutoGenC.Append("#include <%s>\n" % Inc)
   1624         else:
   1625             AutoGenC.Append("#include <%s>\n" % gBasicHeaderFile)
   1626 
   1627         #

   1628         # Publish the CallerId Guid

   1629         #

   1630         AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = %s;\n' % GuidStringToGuidStructureString(Info.Guid))
   1631         AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *gEfiCallerBaseName = "%s";\n' % Info.Name)
   1632 
   1633 ## Create common code for header file

   1634 #

   1635 #   @param      Info        The ModuleAutoGen object

   1636 #   @param      AutoGenC    The TemplateString object for C code

   1637 #   @param      AutoGenH    The TemplateString object for header file

   1638 #

   1639 def CreateFooterCode(Info, AutoGenC, AutoGenH):
   1640     AutoGenH.Append(gAutoGenHEpilogueString)
   1641 
   1642 ## Create code for a module

   1643 #

   1644 #   @param      Info        The ModuleAutoGen object

   1645 #   @param      AutoGenC    The TemplateString object for C code

   1646 #   @param      AutoGenH    The TemplateString object for header file

   1647 #   @param      UniGenCFlag     UniString is generated into AutoGen C file when it is set to True

   1648 #   @param      UniGenBinBuffer Buffer to store uni string package data

   1649 #

   1650 def CreateCode(Info, AutoGenC, AutoGenH, StringH, UniGenCFlag, UniGenBinBuffer):
   1651     CreateHeaderCode(Info, AutoGenC, AutoGenH)
   1652 
   1653     if Info.AutoGenVersion >= 0x00010005:
   1654         CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH)
   1655         CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH)
   1656         CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH)
   1657         CreatePcdCode(Info, AutoGenC, AutoGenH)
   1658         CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH)
   1659         CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH)
   1660         CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH)
   1661         CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH)
   1662 
   1663     if Info.UnicodeFileList:
   1664         FileName = "%sStrDefs.h" % Info.Name
   1665         StringH.Append(gAutoGenHeaderString.Replace({'FileName':FileName}))
   1666         StringH.Append(gAutoGenHPrologueString.Replace({'File':'STRDEFS', 'Guid':Info.Guid.replace('-','_')}))
   1667         CreateUnicodeStringCode(Info, AutoGenC, StringH, UniGenCFlag, UniGenBinBuffer)
   1668 
   1669         GuidMacros = []
   1670         for Guid in Info.Module.Guids:
   1671             if Guid in Info.Module.GetGuidsUsedByPcd():
   1672                 continue
   1673             GuidMacros.append('#define %s %s' % (Guid, Info.Module.Guids[Guid]))
   1674         for Guid, Value in Info.Module.Protocols.items() + Info.Module.Ppis.items():
   1675             GuidMacros.append('#define %s %s' % (Guid, Value))
   1676         if GuidMacros:
   1677             StringH.Append('\n#ifdef VFRCOMPILE\n%s\n#endif\n' % '\n'.join(GuidMacros))
   1678 
   1679         StringH.Append("\n#endif\n")
   1680         AutoGenH.Append('#include "%s"\n' % FileName)
   1681 
   1682     CreateFooterCode(Info, AutoGenC, AutoGenH)
   1683 
   1684     # no generation of AutoGen.c for Edk modules without unicode file

   1685     if Info.AutoGenVersion < 0x00010005 and len(Info.UnicodeFileList) == 0:
   1686         AutoGenC.String = ''
   1687 
   1688 ## Create the code file

   1689 #

   1690 #   @param      FilePath     The path of code file

   1691 #   @param      Content      The content of code file

   1692 #   @param      IsBinaryFile The flag indicating if the file is binary file or not

   1693 #

   1694 #   @retval     True        If file content is changed or file doesn't exist

   1695 #   @retval     False       If the file exists and the content is not changed

   1696 #

   1697 def Generate(FilePath, Content, IsBinaryFile):
   1698     return SaveFileOnChange(FilePath, Content, IsBinaryFile)
   1699 
   1700