1## @file
2# Routines for generating Pcd Database
3#
4# Copyright (c) 2013, 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#
13from StringIO import StringIO
14from Common.Misc import *
15from Common.String import StringToArray
16from struct import pack
17
18DATABASE_VERSION = 4
19
20gPcdDatabaseAutoGenC = TemplateString("""
21//
22// External PCD database debug information
23//
24#if 0
25${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
26${BEGIN}  { ${INIT_VALUE_UINT64} }, /*  ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}] */
27${END}
28${BEGIN}  ${VARDEF_VALUE_UINT64}, /* ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64} */
29${END}
30${BEGIN}  { ${INIT_VALUE_UINT32} }, /*  ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}] */
31${END}
32${BEGIN}  ${VARDEF_VALUE_UINT32}, /* ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32} */
33${END}
34  /* VPD */
35${BEGIN}  { ${VPD_HEAD_VALUE} }, /* ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}] */
36${END}
37  /* ExMapTable */
38  {
39${BEGIN}    { ${EXMAPPING_TABLE_EXTOKEN}, ${EXMAPPING_TABLE_LOCAL_TOKEN}, ${EXMAPPING_TABLE_GUID_INDEX} },
40${END}
41  },
42  /* LocalTokenNumberTable */
43  {
44${BEGIN}    offsetof(${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.${TOKEN_CNAME}_${TOKEN_GUID}${VARDEF_HEADER}) | ${TOKEN_TYPE},
45${END}
46  },
47  /* GuidTable */
48  {
49${BEGIN}    ${GUID_STRUCTURE},
50${END}
51  },
52${BEGIN}  { ${STRING_HEAD_VALUE} }, /* ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}] */
53${END}
54${BEGIN}  /* ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}_Variable_Header[${VARIABLE_HEAD_NUMSKUS_DECL}] */
55  {
56    ${VARIABLE_HEAD_VALUE}
57  },
58${END}
59/* SkuHead */
60  {
61  ${BEGIN} offsetof (${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.${TOKEN_CNAME}_${TOKEN_GUID}${VARDEF_HEADER}) | ${TOKEN_TYPE}, /* */
62           offsetof (${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.SkuHead)  /* */
63  ${END}
64  },
65 /* StringTable */
66${BEGIN}  ${STRING_TABLE_VALUE}, /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */
67${END}
68  /* SizeTable */
69  {
70${BEGIN}    ${SIZE_TABLE_MAXIMUM_LENGTH}, ${SIZE_TABLE_CURRENT_LENGTH}, /* ${SIZE_TABLE_CNAME}_${SIZE_TABLE_GUID} */
71${END}
72  },
73${BEGIN}  { ${INIT_VALUE_UINT16} }, /*  ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}] */
74${END}
75${BEGIN}  ${VARDEF_VALUE_UINT16}, /* ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16} */
76${END}
77${BEGIN}  { ${INIT_VALUE_UINT8} }, /*  ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}] */
78${END}
79${BEGIN}  ${VARDEF_VALUE_UINT8}, /* ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8} */
80${END}
81${BEGIN}  { ${INIT_VALUE_BOOLEAN} }, /*  ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}] */
82${END}
83${BEGIN}  ${VARDEF_VALUE_BOOLEAN}, /* ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN} */
84${END}
85  /* SkuIdTable */
86  { ${BEGIN}${SKUID_VALUE}, ${END} },
87  ${SYSTEM_SKU_ID_VALUE}
88};
89#endif
90""")
91
92## Mapping between PCD driver type and EFI phase
93gPcdPhaseMap = {
94    "PEI_PCD_DRIVER"    :   "PEI",
95    "DXE_PCD_DRIVER"    :   "DXE"
96}
97
98gPcdDatabaseAutoGenH = TemplateString("""
99#define PCD_${PHASE}_SERVICE_DRIVER_VERSION         ${SERVICE_DRIVER_VERSION}
100
101//
102// External PCD database debug information
103//
104#if 0
105#define ${PHASE}_GUID_TABLE_SIZE                ${GUID_TABLE_SIZE}
106#define ${PHASE}_STRING_TABLE_SIZE              ${STRING_TABLE_SIZE}
107#define ${PHASE}_SKUID_TABLE_SIZE               ${SKUID_TABLE_SIZE}
108#define ${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE  ${LOCAL_TOKEN_NUMBER_TABLE_SIZE}
109#define ${PHASE}_LOCAL_TOKEN_NUMBER             ${LOCAL_TOKEN_NUMBER}
110#define ${PHASE}_EXMAPPING_TABLE_SIZE           ${EXMAPPING_TABLE_SIZE}
111#define ${PHASE}_EX_TOKEN_NUMBER                ${EX_TOKEN_NUMBER}
112#define ${PHASE}_SIZE_TABLE_SIZE                ${SIZE_TABLE_SIZE}
113#define ${PHASE}_SKU_HEAD_SIZE                  ${SKU_HEAD_SIZE}
114#define ${PHASE}_GUID_TABLE_EMPTY               ${GUID_TABLE_EMPTY}
115#define ${PHASE}_STRING_TABLE_EMPTY             ${STRING_TABLE_EMPTY}
116#define ${PHASE}_SKUID_TABLE_EMPTY              ${SKUID_TABLE_EMPTY}
117#define ${PHASE}_DATABASE_EMPTY                 ${DATABASE_EMPTY}
118#define ${PHASE}_EXMAP_TABLE_EMPTY              ${EXMAP_TABLE_EMPTY}
119
120typedef struct {
121${BEGIN}  UINT64             ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}];
122${END}
123${BEGIN}  UINT64             ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64};
124${END}
125${BEGIN}  UINT32             ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}];
126${END}
127${BEGIN}  UINT32             ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32};
128${END}
129${BEGIN}  VPD_HEAD           ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}];
130${END}
131  DYNAMICEX_MAPPING  ExMapTable[${PHASE}_EXMAPPING_TABLE_SIZE];
132  UINT32             LocalTokenNumberTable[${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE];
133  GUID               GuidTable[${PHASE}_GUID_TABLE_SIZE];
134${BEGIN}  STRING_HEAD        ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}];
135${END}
136${BEGIN}  VARIABLE_HEAD      ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}_Variable_Header[${VARIABLE_HEAD_NUMSKUS_DECL}];
137${END}
138${BEGIN}  SKU_HEAD           SkuHead[${PHASE}_SKU_HEAD_SIZE];
139${END}
140${BEGIN}  UINT8              StringTable${STRING_TABLE_INDEX}[${STRING_TABLE_LENGTH}]; /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */
141${END}
142  SIZE_INFO          SizeTable[${PHASE}_SIZE_TABLE_SIZE];
143${BEGIN}  UINT16             ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}];
144${END}
145${BEGIN}  UINT16             ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16};
146${END}
147${BEGIN}  UINT8              ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}];
148${END}
149${BEGIN}  UINT8              ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8};
150${END}
151${BEGIN}  BOOLEAN            ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}];
152${END}
153${BEGIN}  BOOLEAN            ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN};
154${END}
155  UINT8              SkuIdTable[${PHASE}_SKUID_TABLE_SIZE];
156${SYSTEM_SKU_ID}
157} ${PHASE}_PCD_DATABASE_INIT;
158
159typedef struct {
160${PCD_DATABASE_UNINIT_EMPTY}
161${BEGIN}  UINT64   ${UNINIT_CNAME_DECL_UINT64}_${UNINIT_GUID_DECL_UINT64}[${UNINIT_NUMSKUS_DECL_UINT64}];
162${END}
163${BEGIN}  UINT32   ${UNINIT_CNAME_DECL_UINT32}_${UNINIT_GUID_DECL_UINT32}[${UNINIT_NUMSKUS_DECL_UINT32}];
164${END}
165${BEGIN}  UINT16   ${UNINIT_CNAME_DECL_UINT16}_${UNINIT_GUID_DECL_UINT16}[${UNINIT_NUMSKUS_DECL_UINT16}];
166${END}
167${BEGIN}  UINT8    ${UNINIT_CNAME_DECL_UINT8}_${UNINIT_GUID_DECL_UINT8}[${UNINIT_NUMSKUS_DECL_UINT8}];
168${END}
169${BEGIN}  BOOLEAN  ${UNINIT_CNAME_DECL_BOOLEAN}_${UNINIT_GUID_DECL_BOOLEAN}[${UNINIT_NUMSKUS_DECL_BOOLEAN}];
170${END}
171} ${PHASE}_PCD_DATABASE_UNINIT;
172
173typedef struct {
174  //GUID                  Signature;  // PcdDataBaseGuid
175  //UINT32                Length;
176  //UINT32                UninitDataBaseSize;// Total size for PCD those default value with 0.
177  //TABLE_OFFSET          LocalTokenNumberTableOffset;
178  //TABLE_OFFSET          ExMapTableOffset;
179  //TABLE_OFFSET          GuidTableOffset;
180  //TABLE_OFFSET          StringTableOffset;
181  //TABLE_OFFSET          SizeTableOffset;
182  //TABLE_OFFSET          SkuIdTableOffset;
183  //UINT16                LocalTokenCount;  // LOCAL_TOKEN_NUMBER for all
184  //UINT16                ExTokenCount;     // EX_TOKEN_NUMBER for DynamicEx
185  //UINT16                GuidTableCount;   // The Number of Guid in GuidTable
186  //SKU_ID                SystemSkuId;      // Current SkuId value.
187  //UINT8                 Pad;
188  ${PHASE}_PCD_DATABASE_INIT    Init;
189  ${PHASE}_PCD_DATABASE_UNINIT  Uninit;
190} ${PHASE}_PCD_DATABASE;
191
192#define ${PHASE}_NEX_TOKEN_NUMBER (${PHASE}_LOCAL_TOKEN_NUMBER - ${PHASE}_EX_TOKEN_NUMBER)
193#endif
194""")
195
196
197gEmptyPcdDatabaseAutoGenC = TemplateString("""
198//
199// External PCD database debug information
200//
201#if 0
202${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
203  /* ExMapTable */
204  {
205    {0, 0, 0}
206  },
207  /* LocalTokenNumberTable */
208  {
209    0
210  },
211  /* GuidTable */
212  {
213    {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
214  },
215  /* StringTable */
216  { 0 },
217  /* SkuHead */
218  {
219    0, 0
220  },
221  /* SizeTable */
222  {
223    0, 0
224  },
225  /* SkuIdTable */
226  { 0 },
227  ${SYSTEM_SKU_ID_VALUE}
228};
229#endif
230""")
231
232## PackGuid
233#
234# Pack the GUID value in C structure format into data array
235#
236# @param GuidStructureValue:   The GUID value in C structure format
237#
238# @retval Buffer:  a data array contains the Guid
239#
240def PackGuid(GuidStructureValue):
241    GuidString = GuidStructureStringToGuidString(GuidStructureValue)
242    Guid = GuidString.split('-')
243    Buffer = pack('=LHHBBBBBBBB',
244                int(Guid[0], 16),
245                int(Guid[1], 16),
246                int(Guid[2], 16),
247                int(Guid[3][-4:-2], 16),
248                int(Guid[3][-2:], 16),
249                int(Guid[4][-12:-10], 16),
250                int(Guid[4][-10:-8], 16),
251                int(Guid[4][-8:-6], 16),
252                int(Guid[4][-6:-4], 16),
253                int(Guid[4][-4:-2], 16),
254                int(Guid[4][-2:], 16)
255                )
256    return Buffer
257
258def toHex(s):
259    lst = []
260    for ch in s:
261        hv = hex(ord(ch)).replace('0x', ' ')
262        if len(hv) == 1:
263            hv = '0'+hv
264        lst.append(hv)
265    if lst:
266        return reduce(lambda x,y:x+y, lst)
267    else:
268        return 'empty'
269## DbItemList
270#
271#  The class holds the Pcd database items. ItemSize if not zero should match the item datum type in the C structure.
272#  When the structure is changed, remember to check the ItemSize and the related  PackStr in PackData()
273#  RawDataList is the RawData that may need some kind of calculation or transformation,
274#  the DataList corresponds to the data that need to be written to database. If DataList is not present, then RawDataList
275#  will be written to the database.
276#
277class DbItemList:
278    def __init__(self, ItemSize, DataList=None, RawDataList=None):
279        if DataList is None:
280            DataList = []
281        if RawDataList is None:
282            RawDataList = []
283        self.ItemSize = ItemSize
284        self.DataList = DataList
285        self.RawDataList = RawDataList
286        self.ListSize = 0
287
288    def GetInterOffset(self, Index):
289        Offset = 0
290        if self.ItemSize == 0:
291            #
292            # Variable length, need to calculate one by one
293            #
294            assert(Index < len(self.RawDataList))
295            for ItemIndex in xrange(Index):
296                Offset += len(self.RawDataList[ItemIndex])
297        else:
298            for Datas in self.RawDataList:
299                Offset = self.ItemSize * Index
300
301        return Offset
302
303    def GetListSize(self):
304        if self.ListSize:
305            return self.ListSize
306        if len(self.RawDataList) == 0:
307            self.ListSize = 0
308            return self.ListSize
309        if self.ItemSize == 0:
310            self.ListSize = self.GetInterOffset(len(self.RawDataList) - 1) + len(self.RawDataList[len(self.RawDataList)-1])
311        else:
312            self.ListSize = self.ItemSize * len(self.RawDataList)
313        return self.ListSize
314
315    def PackData(self):
316        if self.ItemSize == 8:
317            PackStr = "=Q"
318        elif self.ItemSize == 4:
319            PackStr = "=L"
320        elif self.ItemSize == 2:
321            PackStr = "=H"
322        elif self.ItemSize == 1:
323            PackStr = "=B"
324        elif self.ItemSize == 0:
325            PackStr = "=B"
326        elif self.ItemSize == 16:
327            # pack Guid
328            PackStr = ''
329        else:
330            # should not reach here
331            assert(False)
332
333        Buffer = ''
334        for Datas in self.RawDataList:
335            if type(Datas) in (list, tuple):
336                for Data in Datas:
337                    if PackStr:
338                        Buffer += pack(PackStr, GetIntegerValue(Data))
339                    else:
340                        Buffer += PackGuid(Data)
341            else:
342                if PackStr:
343                    Buffer += pack(PackStr, GetIntegerValue(Datas))
344                else:
345                    Buffer += PackGuid(Datas)
346
347        return Buffer
348
349## DbExMapTblItemList
350#
351#  The class holds the ExMap table
352#
353class DbExMapTblItemList (DbItemList):
354    def __init__(self, ItemSize, DataList=None, RawDataList=None):
355        if DataList is None:
356            DataList = []
357        if RawDataList is None:
358            RawDataList = []
359        DbItemList.__init__(self, ItemSize, DataList, RawDataList)
360    def PackData(self):
361        Buffer = ''
362        PackStr = "=LHH"
363        for Datas in self.RawDataList:
364            Buffer += pack(PackStr,
365                           GetIntegerValue(Datas[0]),
366                           GetIntegerValue(Datas[1]),
367                           GetIntegerValue(Datas[2]))
368        return Buffer
369
370## DbComItemList
371#
372# The DbComItemList is a special kind of DbItemList in case that the size of the List can not be computed by the
373# ItemSize multiply the ItemCount.
374#
375class DbComItemList (DbItemList):
376    def __init__(self, ItemSize, DataList=None, RawDataList=None):
377        if DataList is None:
378            DataList = []
379        if RawDataList is None:
380            RawDataList = []
381        DbItemList.__init__(self, ItemSize, DataList, RawDataList)
382    def GetInterOffset(self, Index):
383        Offset = 0
384        if self.ItemSize == 0:
385            #
386            # Variable length, need to calculte one by one
387            # The only variable table is stringtable, it is not Composite item, should not reach here
388            #
389            assert(False)
390        else:
391            assert(Index < len(self.RawDataList))
392            for ItemIndex in xrange(Index):
393                Offset += len(self.RawDataList[ItemIndex]) * self.ItemSize
394
395        return Offset
396
397    def GetListSize(self):
398        if self.ListSize:
399            return self.ListSize
400        if self.ItemSize == 0:
401            assert(False)
402        else:
403            if len(self.RawDataList) == 0:
404                self.ListSize = 0
405            else:
406                self.ListSize = self.GetInterOffset(len(self.RawDataList) - 1) + len(self.RawDataList[len(self.RawDataList)-1]) * self.ItemSize
407
408        return self.ListSize
409
410    def PackData(self):
411        if self.ItemSize == 8:
412            PackStr = "=Q"
413        elif self.ItemSize == 4:
414            PackStr = "=L"
415        elif self.ItemSize == 2:
416            PackStr = "=H"
417        elif self.ItemSize == 1:
418            PackStr = "=B"
419        elif self.ItemSize == 0:
420            PackStr = "=B"
421        else:
422            assert(False)
423
424        Buffer = ''
425        for DataList in self.RawDataList:
426            for Data in DataList:
427                if type(Data) in (list, tuple):
428                    for SingleData in Data:
429                        Buffer += pack(PackStr, GetIntegerValue(SingleData))
430                else:
431                    Buffer += pack(PackStr, GetIntegerValue(Data))
432
433        return Buffer
434
435## DbVariableTableItemList
436#
437#  The class holds the Variable header value table
438#
439class DbVariableTableItemList (DbComItemList):
440    def __init__(self, ItemSize, DataList=None, RawDataList=None):
441        if DataList is None:
442            DataList = []
443        if RawDataList is None:
444            RawDataList = []
445        DbComItemList.__init__(self, ItemSize, DataList, RawDataList)
446    def PackData(self):
447        PackStr = "=LLHH"
448        Buffer = ''
449        for DataList in self.RawDataList:
450            for Data in DataList:
451                Buffer += pack(PackStr,
452                               GetIntegerValue(Data[0]),
453                               GetIntegerValue(Data[1]),
454                               GetIntegerValue(Data[2]),
455                               GetIntegerValue(Data[3]))
456        return Buffer
457
458class DbStringHeadTableItemList(DbItemList):
459    def __init__(self,ItemSize,DataList=None,RawDataList=None):
460        if DataList is None:
461            DataList = []
462        if RawDataList is None:
463            RawDataList = []
464        DbItemList.__init__(self, ItemSize, DataList, RawDataList)
465
466    def GetInterOffset(self, Index):
467        Offset = 0
468        if self.ItemSize == 0:
469            #
470            # Variable length, need to calculate one by one
471            #
472            assert(Index < len(self.RawDataList))
473            for ItemIndex in xrange(Index):
474                Offset += len(self.RawDataList[ItemIndex])
475        else:
476            for innerIndex in range(Index):
477                if type(self.RawDataList[innerIndex]) in (list, tuple):
478                    Offset += len(self.RawDataList[innerIndex]) * self.ItemSize
479                else:
480                    Offset += self.ItemSize
481
482        return Offset
483
484    def GetListSize(self):
485        if self.ListSize:
486            return self.ListSize
487        if len(self.RawDataList) == 0:
488            self.ListSize = 0
489            return self.ListSize
490        if self.ItemSize == 0:
491            self.ListSize = self.GetInterOffset(len(self.RawDataList) - 1) + len(self.RawDataList[len(self.RawDataList)-1])
492        else:
493            for Datas in self.RawDataList:
494                if type(Datas) in (list, tuple):
495                    self.ListSize += len(Datas) * self.ItemSize
496                else:
497                    self.ListSize += self.ItemSize
498        return self.ListSize
499
500## DbSkuHeadTableItemList
501#
502#  The class holds the Sku header value table
503#
504class DbSkuHeadTableItemList (DbItemList):
505    def __init__(self, ItemSize, DataList=None, RawDataList=None):
506        if DataList is None:
507            DataList = []
508        if RawDataList is None:
509            RawDataList = []
510        DbItemList.__init__(self, ItemSize, DataList, RawDataList)
511    def PackData(self):
512        PackStr = "=LL"
513        Buffer = ''
514        for Data in self.RawDataList:
515            Buffer += pack(PackStr,
516                           GetIntegerValue(Data[0]),
517                           GetIntegerValue(Data[1]))
518        return Buffer
519
520## DbSizeTableItemList
521#
522#  The class holds the size table
523#
524class DbSizeTableItemList (DbItemList):
525    def __init__(self, ItemSize, DataList=None, RawDataList=None):
526        if DataList is None:
527            DataList = []
528        if RawDataList is None:
529            RawDataList = []
530        DbItemList.__init__(self, ItemSize, DataList, RawDataList)
531    def GetListSize(self):
532        length = 0
533        for Data in self.RawDataList:
534            length += (1 + len(Data[1]))
535        return length * self.ItemSize
536    def PackData(self):
537        PackStr = "=H"
538        Buffer = ''
539        for Data in self.RawDataList:
540            Buffer += pack(PackStr,
541                           GetIntegerValue(Data[0]))
542            for subData in Data[1]:
543                Buffer += pack(PackStr,
544                           GetIntegerValue(subData))
545        return Buffer
546
547## DbStringItemList
548#
549#  The class holds the string table
550#
551class DbStringItemList (DbComItemList):
552    def __init__(self, ItemSize, DataList=None, RawDataList=None, LenList=None):
553        if DataList is None:
554            DataList = []
555        if RawDataList is None:
556            RawDataList = []
557        if LenList is None:
558            LenList = []
559
560        assert(len(RawDataList) == len(LenList))
561        DataList = []
562        # adjust DataList according to the LenList
563        for Index in xrange(len(RawDataList)):
564            Len = LenList[Index]
565            RawDatas = RawDataList[Index]
566            assert(Len >= len(RawDatas))
567            ActualDatas = []
568            for i in xrange(len(RawDatas)):
569                ActualDatas.append(RawDatas[i])
570            for i in xrange(len(RawDatas), Len):
571                ActualDatas.append(0)
572            DataList.append(ActualDatas)
573        self.LenList = LenList
574        DbComItemList.__init__(self, ItemSize, DataList, RawDataList)
575    def GetInterOffset(self, Index):
576        Offset = 0
577
578        assert(Index < len(self.LenList))
579        for ItemIndex in xrange(Index):
580            Offset += self.LenList[ItemIndex]
581
582        return Offset
583
584    def GetListSize(self):
585        if self.ListSize:
586            return self.ListSize
587
588        if len(self.LenList) == 0:
589            self.ListSize = 0
590        else:
591            self.ListSize = self.GetInterOffset(len(self.LenList) - 1) + self.LenList[len(self.LenList)-1]
592
593        return self.ListSize
594
595    def PackData(self):
596        self.RawDataList = self.DataList
597        return DbComItemList.PackData(self)
598
599
600
601##  Find the index in two list where the item matches the key separately
602#
603#   @param      Key1   The key used to search the List1
604#   @param      List1  The list that Key1 will be searched
605#   @param      Key2   The key used to search the List2
606#   @param      List2  The list that Key2 will be searched
607#
608#   @retval     Index  The position inside the list where list1[Index] == Key1 and list2[Index] == Key2
609#
610def GetMatchedIndex(Key1, List1, Key2, List2):
611    StartPos = 0
612    while StartPos < len(List1):
613        Index = List1.index(Key1, StartPos)
614        if List2[Index] == Key2:
615            return Index
616        else:
617            StartPos = Index + 1
618
619    return -1
620
621
622##  Get the integer value from string like "14U" or integer like 2
623#
624#   @param      Input   The object that may be either a integer value or a string
625#
626#   @retval     Value    The integer value that the input represents
627#
628def GetIntegerValue(Input):
629    if type(Input) in (int, long):
630        return Input
631    String = Input
632    if String.endswith("U"):
633        String = String[:-1]
634    if String.endswith("ULL"):
635        String = String[:-3]
636    if String.endswith("LL"):
637        String = String[:-2]
638
639    if String.startswith("0x") or String.startswith("0X"):
640        return int(String, 16)
641    elif String == '':
642        return 0
643    else:
644        return int(String)
645
646
647## convert StringArray like {0x36, 0x00, 0x34, 0x00, 0x21, 0x00, 0x36, 0x00, 0x34, 0x00, 0x00, 0x00}
648# to List like [0x36, 0x00, 0x34, 0x00, 0x21, 0x00, 0x36, 0x00, 0x34, 0x00, 0x00, 0x00]
649#
650#   @param      StringArray A string array like {0x36, 0x00, 0x34, 0x00, 0x21, 0x00, 0x36, 0x00, 0x34, 0x00, 0x00, 0x00}
651#
652#   @retval                 A list object of integer items
653#
654def StringArrayToList(StringArray):
655    StringArray = StringArray[1:-1]
656    StringArray = '[' + StringArray + ']'
657    return eval(StringArray)
658
659
660## Convert TokenType String like  "PCD_DATUM_TYPE_UINT32 | PCD_TYPE_HII" to TokenType value
661#
662#   @param      TokenType  A TokenType string like "PCD_DATUM_TYPE_UINT32 | PCD_TYPE_HII"
663#
664#   @retval                A integer representation of the TokenType
665#
666def GetTokenTypeValue(TokenType):
667    TokenTypeDict = {
668        "PCD_TYPE_SHIFT":28,
669        "PCD_TYPE_DATA":(0x0 << 28),
670        "PCD_TYPE_HII":(0x8 << 28),
671        "PCD_TYPE_VPD":(0x4 << 28),
672        "PCD_TYPE_SKU_ENABLED":(0x2 << 28),
673        "PCD_TYPE_STRING":(0x1 << 28),
674
675        "PCD_DATUM_TYPE_SHIFT":24,
676        "PCD_DATUM_TYPE_POINTER":(0x0 << 24),
677        "PCD_DATUM_TYPE_UINT8":(0x1 << 24),
678        "PCD_DATUM_TYPE_UINT16":(0x2 << 24),
679        "PCD_DATUM_TYPE_UINT32":(0x4 << 24),
680        "PCD_DATUM_TYPE_UINT64":(0x8 << 24),
681
682        "PCD_DATUM_TYPE_SHIFT2":20,
683        "PCD_DATUM_TYPE_UINT8_BOOLEAN":(0x1 << 20 | 0x1 << 24),
684        }
685    return eval(TokenType, TokenTypeDict)
686
687## construct the external Pcd database using data from Dict
688#
689#   @param      Dict  A dictionary contains Pcd related tables
690#
691#   @retval     Buffer A byte stream of the Pcd database
692#
693def BuildExDataBase(Dict):
694    # init Db items
695    InitValueUint64 = Dict['INIT_DB_VALUE_UINT64']
696    DbInitValueUint64 = DbComItemList(8, RawDataList = InitValueUint64)
697    VardefValueUint64 = Dict['VARDEF_DB_VALUE_UINT64']
698    DbVardefValueUint64 = DbItemList(8, RawDataList = VardefValueUint64)
699    InitValueUint32 = Dict['INIT_DB_VALUE_UINT32']
700    DbInitValueUint32 = DbComItemList(4, RawDataList = InitValueUint32)
701    VardefValueUint32 = Dict['VARDEF_DB_VALUE_UINT32']
702    DbVardefValueUint32 = DbItemList(4, RawDataList = VardefValueUint32)
703    VpdHeadValue = Dict['VPD_DB_VALUE']
704    DbVpdHeadValue = DbComItemList(4, RawDataList = VpdHeadValue)
705    ExMapTable = zip(Dict['EXMAPPING_TABLE_EXTOKEN'], Dict['EXMAPPING_TABLE_LOCAL_TOKEN'], Dict['EXMAPPING_TABLE_GUID_INDEX'])
706    DbExMapTable = DbExMapTblItemList(8, RawDataList = ExMapTable)
707    LocalTokenNumberTable = Dict['LOCAL_TOKEN_NUMBER_DB_VALUE']
708    DbLocalTokenNumberTable = DbItemList(4, RawDataList = LocalTokenNumberTable)
709    GuidTable = Dict['GUID_STRUCTURE']
710    DbGuidTable = DbItemList(16, RawDataList = GuidTable)
711    StringHeadValue = Dict['STRING_DB_VALUE']
712    # DbItemList to DbStringHeadTableItemList
713    DbStringHeadValue = DbStringHeadTableItemList(4, RawDataList = StringHeadValue)
714    VariableTable = Dict['VARIABLE_DB_VALUE']
715    DbVariableTable = DbVariableTableItemList(12, RawDataList = VariableTable)
716    NumberOfSkuEnabledPcd = GetIntegerValue(Dict['SKU_HEAD_SIZE'])
717    Dict['SKUHEAD_TABLE_VALUE'] = [(0,0) for i in xrange(NumberOfSkuEnabledPcd)]
718    SkuTable = Dict['SKUHEAD_TABLE_VALUE']  # Generated later
719    DbSkuTable = DbSkuHeadTableItemList(8, RawDataList = SkuTable)
720    Dict['STRING_TABLE_DB_VALUE'] = [StringArrayToList(x) for x in Dict['STRING_TABLE_VALUE']]
721
722    StringTableValue = Dict['STRING_TABLE_DB_VALUE']
723    # when calcute the offset, should use StringTableLen instead of StringTableValue, as string maxium len may be different with actual len
724    StringTableLen = Dict['STRING_TABLE_LENGTH']
725    DbStringTableLen = DbStringItemList(0, RawDataList = StringTableValue, LenList = StringTableLen)
726
727
728    PcdTokenTable = Dict['PCD_TOKENSPACE']
729    PcdTokenLen = Dict['PCD_TOKENSPACE_LENGTH']
730    PcdTokenTableValue = [StringArrayToList(x) for x in Dict['PCD_TOKENSPACE']]
731    DbPcdTokenTable = DbStringItemList(0, RawDataList = PcdTokenTableValue, LenList = PcdTokenLen)
732
733    PcdCNameTable = Dict['PCD_CNAME']
734    PcdCNameLen = Dict['PCD_CNAME_LENGTH']
735    PcdCNameTableValue = [StringArrayToList(x) for x in Dict['PCD_CNAME']]
736    DbPcdCNameTable = DbStringItemList(0, RawDataList = PcdCNameTableValue, LenList = PcdCNameLen)
737
738    PcdNameOffsetTable = Dict['PCD_NAME_OFFSET']
739    DbPcdNameOffsetTable = DbItemList(4,RawDataList = PcdNameOffsetTable)
740
741    SizeTableValue = zip(Dict['SIZE_TABLE_MAXIMUM_LENGTH'], Dict['SIZE_TABLE_CURRENT_LENGTH'])
742    DbSizeTableValue = DbSizeTableItemList(2, RawDataList = SizeTableValue)
743    InitValueUint16 = Dict['INIT_DB_VALUE_UINT16']
744    DbInitValueUint16 = DbComItemList(2, RawDataList = InitValueUint16)
745    VardefValueUint16 = Dict['VARDEF_DB_VALUE_UINT16']
746    DbVardefValueUint16 = DbItemList(2, RawDataList = VardefValueUint16)
747    InitValueUint8 = Dict['INIT_DB_VALUE_UINT8']
748    DbInitValueUint8 = DbComItemList(1, RawDataList = InitValueUint8)
749    VardefValueUint8 = Dict['VARDEF_DB_VALUE_UINT8']
750    DbVardefValueUint8 = DbItemList(1, RawDataList = VardefValueUint8)
751    InitValueBoolean = Dict['INIT_DB_VALUE_BOOLEAN']
752    DbInitValueBoolean = DbComItemList(1, RawDataList = InitValueBoolean)
753    VardefValueBoolean = Dict['VARDEF_DB_VALUE_BOOLEAN']
754    DbVardefValueBoolean = DbItemList(1, RawDataList = VardefValueBoolean)
755    SkuidValue = Dict['SKUID_VALUE']
756    DbSkuidValue = DbItemList(1, RawDataList = SkuidValue)
757    SkuIndexValue = Dict['SKU_INDEX_VALUE']
758    DbSkuIndexValue = DbItemList(0,RawDataList = SkuIndexValue)
759
760    # Unit Db Items
761    UnInitValueUint64 = Dict['UNINIT_GUID_DECL_UINT64']
762    DbUnInitValueUint64 = DbItemList(8, RawDataList = UnInitValueUint64)
763    UnInitValueUint32 = Dict['UNINIT_GUID_DECL_UINT32']
764    DbUnInitValueUint32 = DbItemList(4, RawDataList = UnInitValueUint32)
765    UnInitValueUint16 = Dict['UNINIT_GUID_DECL_UINT16']
766    DbUnInitValueUint16 = DbItemList(2, RawDataList = UnInitValueUint16)
767    UnInitValueUint8 = Dict['UNINIT_GUID_DECL_UINT8']
768    DbUnInitValueUint8 = DbItemList(1, RawDataList = UnInitValueUint8)
769    UnInitValueBoolean = Dict['UNINIT_GUID_DECL_BOOLEAN']
770    DbUnInitValueBoolean = DbItemList(1, RawDataList = UnInitValueBoolean)
771    PcdTokenNumberMap = Dict['PCD_ORDER_TOKEN_NUMBER_MAP']
772
773    DbNameTotle = ["InitValueUint64", "VardefValueUint64", "InitValueUint32", "VardefValueUint32", "VpdHeadValue", "ExMapTable",
774               "LocalTokenNumberTable", "GuidTable", "StringHeadValue",  "PcdNameOffsetTable","VariableTable","SkuTable", "StringTableLen", "PcdTokenTable", "PcdCNameTable",
775               "SizeTableValue", "InitValueUint16", "VardefValueUint16", "InitValueUint8", "VardefValueUint8", "InitValueBoolean",
776               "VardefValueBoolean", "SkuidValue", "SkuIndexValue","UnInitValueUint64", "UnInitValueUint32", "UnInitValueUint16", "UnInitValueUint8", "UnInitValueBoolean"]
777
778    DbTotal = [InitValueUint64, VardefValueUint64, InitValueUint32, VardefValueUint32, VpdHeadValue, ExMapTable,
779               LocalTokenNumberTable, GuidTable, StringHeadValue,  PcdNameOffsetTable,VariableTable,SkuTable, StringTableLen, PcdTokenTable,PcdCNameTable,
780               SizeTableValue, InitValueUint16, VardefValueUint16,InitValueUint8, VardefValueUint8, InitValueBoolean,
781               VardefValueBoolean, SkuidValue, SkuIndexValue, UnInitValueUint64, UnInitValueUint32, UnInitValueUint16, UnInitValueUint8, UnInitValueBoolean]
782    DbItemTotal = [DbInitValueUint64, DbVardefValueUint64, DbInitValueUint32, DbVardefValueUint32, DbVpdHeadValue, DbExMapTable,
783               DbLocalTokenNumberTable, DbGuidTable, DbStringHeadValue,  DbPcdNameOffsetTable,DbVariableTable,DbSkuTable, DbStringTableLen, DbPcdTokenTable, DbPcdCNameTable,
784               DbSizeTableValue, DbInitValueUint16, DbVardefValueUint16,DbInitValueUint8, DbVardefValueUint8, DbInitValueBoolean,
785               DbVardefValueBoolean, DbSkuidValue, DbSkuIndexValue, DbUnInitValueUint64, DbUnInitValueUint32, DbUnInitValueUint16, DbUnInitValueUint8, DbUnInitValueBoolean]
786
787    # SkuidValue is the last table in the init table items
788    InitTableNum = DbTotal.index(SkuidValue) + 1 + 1 # +1 is for SkuIndexValue table
789    # The FixedHeader length of the PCD_DATABASE_INIT, from Signature to Pad
790    FixedHeaderLen = 64
791
792    # Get offset of SkuId table in the database
793    SkuIdTableOffset = FixedHeaderLen
794    for DbIndex in xrange(len(DbTotal)):
795        if DbTotal[DbIndex] is SkuidValue:
796            break
797        SkuIdTableOffset += DbItemTotal[DbIndex].GetListSize()
798
799
800    # Get offset of SkuValue table in the database
801    SkuTableOffset = FixedHeaderLen
802    for DbIndex in xrange(len(DbTotal)):
803        if DbTotal[DbIndex] is SkuTable:
804            break
805        SkuTableOffset += DbItemTotal[DbIndex].GetListSize()
806    PcdTokenTableDbOffset = FixedHeaderLen
807    for DbIndex in xrange(len(DbTotal)):
808        if DbTotal[DbIndex] is PcdTokenTable:
809            break
810        PcdTokenTableDbOffset += DbItemTotal[DbIndex].GetListSize()
811
812    PcdCNameTableDbOffset = FixedHeaderLen
813    for DbIndex in xrange(len(DbTotal)):
814        if DbTotal[DbIndex] is PcdCNameTable:
815            break
816        PcdCNameTableDbOffset += DbItemTotal[DbIndex].GetListSize()
817    # Fix up the LocalTokenNumberTable, SkuHeader table
818    SkuHeaderIndex = 0
819    if len(Dict['SKU_INDEX_VALUE']) > 0:
820        SkuIndexIndexTable = [(0) for i in xrange(len(Dict['SKU_INDEX_VALUE']))]
821        SkuIndexIndexTable[0] = 0  #Dict['SKU_INDEX_VALUE'][0][0]
822        for i in range(1,len(Dict['SKU_INDEX_VALUE'])):
823            SkuIndexIndexTable[i] = SkuIndexIndexTable[i-1]+Dict['SKU_INDEX_VALUE'][i-1][0] + 1
824    for (LocalTokenNumberTableIndex, (Offset, Table)) in enumerate(LocalTokenNumberTable):
825        DbIndex = 0
826        DbOffset = FixedHeaderLen
827        for DbIndex in xrange(len(DbTotal)):
828            if DbTotal[DbIndex] is Table:
829                DbOffset += DbItemTotal[DbIndex].GetInterOffset(Offset)
830                break
831            DbOffset += DbItemTotal[DbIndex].GetListSize()
832        else:
833            assert(False)
834
835        TokenTypeValue = Dict['TOKEN_TYPE'][LocalTokenNumberTableIndex]
836        TokenTypeValue = GetTokenTypeValue(TokenTypeValue)
837        LocalTokenNumberTable[LocalTokenNumberTableIndex] = DbOffset|int(TokenTypeValue)
838        # if PCD_TYPE_SKU_ENABLED, then we need to fix up the SkuTable
839
840        SkuIndexTabalOffset = SkuIdTableOffset + Dict['SKUID_VALUE'][0] + 1
841        if (TokenTypeValue & (0x2 << 28)):
842            SkuTable[SkuHeaderIndex] = (DbOffset|int(TokenTypeValue & ~(0x2<<28)), SkuIndexTabalOffset + SkuIndexIndexTable[PcdTokenNumberMap[LocalTokenNumberTableIndex]])
843            LocalTokenNumberTable[LocalTokenNumberTableIndex] = (SkuTableOffset + SkuHeaderIndex * 8) | int(TokenTypeValue)
844            SkuHeaderIndex += 1
845
846
847    if SkuHeaderIndex == 0:
848        SkuHeaderIndex = 1
849    assert(SkuHeaderIndex == NumberOfSkuEnabledPcd)
850
851    # resolve variable table offset
852    for VariableEntries in VariableTable:
853        skuindex = 0
854        for VariableEntryPerSku in VariableEntries:
855            (VariableHeadGuidIndex, VariableHeadStringIndex, SKUVariableOffset, VariableOffset, VariableRefTable) = VariableEntryPerSku[:]
856            DbIndex = 0
857            DbOffset = FixedHeaderLen
858            for DbIndex in xrange(len(DbTotal)):
859                if DbTotal[DbIndex] is VariableRefTable:
860                    DbOffset += DbItemTotal[DbIndex].GetInterOffset(VariableOffset)
861                    break
862                DbOffset += DbItemTotal[DbIndex].GetListSize()
863            else:
864                assert(False)
865            if isinstance(VariableRefTable[0],list):
866                DbOffset += skuindex * 4
867            skuindex += 1
868            if DbIndex >= InitTableNum:
869                assert(False)
870
871            VariableEntryPerSku[:] = (VariableHeadStringIndex, DbOffset, VariableHeadGuidIndex, SKUVariableOffset)
872
873    # calculate various table offset now
874    DbTotalLength = FixedHeaderLen
875    for DbIndex in xrange(len(DbItemTotal)):
876        if DbItemTotal[DbIndex] is DbLocalTokenNumberTable:
877            LocalTokenNumberTableOffset = DbTotalLength
878        elif DbItemTotal[DbIndex] is DbExMapTable:
879            ExMapTableOffset = DbTotalLength
880        elif DbItemTotal[DbIndex] is DbGuidTable:
881            GuidTableOffset = DbTotalLength
882        elif DbItemTotal[DbIndex] is DbStringTableLen:
883            StringTableOffset = DbTotalLength
884        elif DbItemTotal[DbIndex] is DbSizeTableValue:
885            SizeTableOffset = DbTotalLength
886        elif DbItemTotal[DbIndex] is DbSkuidValue:
887            SkuIdTableOffset = DbTotalLength
888        elif DbItemTotal[DbIndex] is DbPcdNameOffsetTable:
889            DbPcdNameOffset = DbTotalLength
890
891        DbTotalLength += DbItemTotal[DbIndex].GetListSize()
892    if not Dict['PCD_INFO_FLAG']:
893        DbPcdNameOffset  = 0
894    LocalTokenCount = GetIntegerValue(Dict['LOCAL_TOKEN_NUMBER'])
895    ExTokenCount = GetIntegerValue(Dict['EX_TOKEN_NUMBER'])
896    GuidTableCount = GetIntegerValue(Dict['GUID_TABLE_SIZE'])
897    SystemSkuId = GetIntegerValue(Dict['SYSTEM_SKU_ID_VALUE'])
898    Pad = 0xDA
899
900    UninitDataBaseSize  = 0
901    for Item in (DbUnInitValueUint64, DbUnInitValueUint32, DbUnInitValueUint16, DbUnInitValueUint8, DbUnInitValueBoolean):
902        UninitDataBaseSize += Item.GetListSize()
903
904    # Construct the database buffer
905    Guid = "{0x3c7d193c, 0x682c, 0x4c14, 0xa6, 0x8f, 0x55, 0x2d, 0xea, 0x4f, 0x43, 0x7e}"
906    Guid = StringArrayToList(Guid)
907    Buffer = pack('=LHHBBBBBBBB',
908                Guid[0],
909                Guid[1],
910                Guid[2],
911                Guid[3],
912                Guid[4],
913                Guid[5],
914                Guid[6],
915                Guid[7],
916                Guid[8],
917                Guid[9],
918                Guid[10],
919                )
920
921    b = pack("=L", DATABASE_VERSION)
922    Buffer += b
923
924    b = pack('=L', DbTotalLength - UninitDataBaseSize)
925
926    Buffer += b
927    b = pack('=L', UninitDataBaseSize)
928
929    Buffer += b
930    b = pack('=L', LocalTokenNumberTableOffset)
931
932    Buffer += b
933    b = pack('=L', ExMapTableOffset)
934
935    Buffer += b
936    b = pack('=L', GuidTableOffset)
937
938    Buffer += b
939    b = pack('=L', StringTableOffset)
940
941    Buffer += b
942    b = pack('=L', SizeTableOffset)
943
944    Buffer += b
945    b = pack('=L', SkuIdTableOffset)
946
947    Buffer += b
948    b = pack('=L', DbPcdNameOffset)
949
950    Buffer += b
951    b = pack('=H', LocalTokenCount)
952
953    Buffer += b
954    b = pack('=H', ExTokenCount)
955
956    Buffer += b
957    b = pack('=H', GuidTableCount)
958
959    Buffer += b
960    b = pack('=B', SystemSkuId)
961
962    Buffer += b
963    b = pack('=B', Pad)
964
965    Buffer += b
966
967    Index = 0
968    for Item in DbItemTotal:
969        Index +=1
970        b = Item.PackData()
971        Buffer += b
972        if Index == InitTableNum:
973            break
974    return Buffer
975
976## Create code for PCD database
977#
978#   @param      Info        The ModuleAutoGen object
979#   @param      AutoGenC    The TemplateString object for C code
980#   @param      AutoGenH    The TemplateString object for header file
981#
982def CreatePcdDatabaseCode (Info, AutoGenC, AutoGenH):
983    if Info.PcdIsDriver == "":
984        return
985    if Info.PcdIsDriver not in gPcdPhaseMap:
986        EdkLogger.error("build", AUTOGEN_ERROR, "Not supported PcdIsDriver type:%s" % Info.PcdIsDriver,
987                        ExtraData="[%s]" % str(Info))
988
989    AdditionalAutoGenH, AdditionalAutoGenC, PcdDbBuffer = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, 'PEI')
990    AutoGenH.Append(AdditionalAutoGenH.String)
991
992    Phase = gPcdPhaseMap[Info.PcdIsDriver]
993    if Phase == 'PEI':
994        AutoGenC.Append(AdditionalAutoGenC.String)
995
996    if Phase == 'DXE':
997        AdditionalAutoGenH, AdditionalAutoGenC, PcdDbBuffer = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, Phase)
998        AutoGenH.Append(AdditionalAutoGenH.String)
999        AutoGenC.Append(AdditionalAutoGenC.String)
1000
1001    if Info.IsBinaryModule:
1002        DbFileName = os.path.join(Info.PlatformInfo.BuildDir, "FV", Phase + "PcdDataBase.raw")
1003    else:
1004        DbFileName = os.path.join(Info.OutputDir, Phase + "PcdDataBase.raw")
1005    DbFile = StringIO()
1006    DbFile.write(PcdDbBuffer)
1007    Changed = SaveFileOnChange(DbFileName, DbFile.getvalue(), True)
1008
1009## Create PCD database in DXE or PEI phase
1010#
1011#   @param      Platform    The platform object
1012#   @retval     tuple       Two TemplateString objects for C code and header file,
1013#                           respectively
1014#
1015def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
1016    AutoGenC = TemplateString()
1017    AutoGenH = TemplateString()
1018
1019    Dict = {
1020        'PHASE'                         : Phase,
1021        'SERVICE_DRIVER_VERSION'        : DATABASE_VERSION,
1022        'GUID_TABLE_SIZE'               : '1U',
1023        'STRING_TABLE_SIZE'             : '1U',
1024        'SKUID_TABLE_SIZE'              : '1U',
1025        'LOCAL_TOKEN_NUMBER_TABLE_SIZE' : '0U',
1026        'LOCAL_TOKEN_NUMBER'            : '0U',
1027        'EXMAPPING_TABLE_SIZE'          : '1U',
1028        'EX_TOKEN_NUMBER'               : '0U',
1029        'SIZE_TABLE_SIZE'               : '2U',
1030        'SKU_HEAD_SIZE'                 : '1U',
1031        'GUID_TABLE_EMPTY'              : 'TRUE',
1032        'STRING_TABLE_EMPTY'            : 'TRUE',
1033        'SKUID_TABLE_EMPTY'             : 'TRUE',
1034        'DATABASE_EMPTY'                : 'TRUE',
1035        'EXMAP_TABLE_EMPTY'             : 'TRUE',
1036        'PCD_DATABASE_UNINIT_EMPTY'     : '  UINT8  dummy; /* PCD_DATABASE_UNINIT is emptry */',
1037        'SYSTEM_SKU_ID'                 : '  SKU_ID             SystemSkuId;',
1038        'SYSTEM_SKU_ID_VALUE'           : '0U'
1039    }
1040
1041
1042    SkuObj = SkuClass(Platform.Platform.SkuName,Platform.Platform.SkuIds)
1043    Dict['SYSTEM_SKU_ID_VALUE'] = Platform.Platform.SkuIds[SkuObj.SystemSkuId]
1044
1045    Dict['PCD_INFO_FLAG'] = Platform.Platform.PcdInfoFlag
1046
1047    for DatumType in ['UINT64','UINT32','UINT16','UINT8','BOOLEAN', "VOID*"]:
1048        Dict['VARDEF_CNAME_' + DatumType] = []
1049        Dict['VARDEF_GUID_' + DatumType]  = []
1050        Dict['VARDEF_SKUID_' + DatumType] = []
1051        Dict['VARDEF_VALUE_' + DatumType] = []
1052        Dict['VARDEF_DB_VALUE_' + DatumType] = []
1053        for Init in ['INIT','UNINIT']:
1054            Dict[Init+'_CNAME_DECL_' + DatumType]   = []
1055            Dict[Init+'_GUID_DECL_' + DatumType]    = []
1056            Dict[Init+'_NUMSKUS_DECL_' + DatumType] = []
1057            Dict[Init+'_VALUE_' + DatumType]        = []
1058            Dict[Init+'_DB_VALUE_'+DatumType] = []
1059
1060    for Type in ['STRING_HEAD','VPD_HEAD','VARIABLE_HEAD']:
1061        Dict[Type + '_CNAME_DECL']   = []
1062        Dict[Type + '_GUID_DECL']    = []
1063        Dict[Type + '_NUMSKUS_DECL'] = []
1064        Dict[Type + '_VALUE'] = []
1065
1066    Dict['STRING_DB_VALUE'] = []
1067    Dict['VPD_DB_VALUE'] = []
1068    Dict['VARIABLE_DB_VALUE'] = []
1069
1070    Dict['STRING_TABLE_INDEX'] = []
1071    Dict['STRING_TABLE_LENGTH']  = []
1072    Dict['STRING_TABLE_CNAME'] = []
1073    Dict['STRING_TABLE_GUID']  = []
1074    Dict['STRING_TABLE_VALUE'] = []
1075    Dict['STRING_TABLE_DB_VALUE'] = []
1076
1077    Dict['SIZE_TABLE_CNAME'] = []
1078    Dict['SIZE_TABLE_GUID']  = []
1079    Dict['SIZE_TABLE_CURRENT_LENGTH']  = []
1080    Dict['SIZE_TABLE_MAXIMUM_LENGTH']  = []
1081
1082    Dict['EXMAPPING_TABLE_EXTOKEN'] = []
1083    Dict['EXMAPPING_TABLE_LOCAL_TOKEN'] = []
1084    Dict['EXMAPPING_TABLE_GUID_INDEX'] = []
1085
1086    Dict['GUID_STRUCTURE'] = []
1087    Dict['SKUID_VALUE'] = [0] # init Dict length
1088    Dict['VARDEF_HEADER'] = []
1089
1090    Dict['LOCAL_TOKEN_NUMBER_DB_VALUE'] = []
1091    Dict['VARIABLE_DB_VALUE'] = []
1092    Dict['SKUHEAD_TABLE_VALUE'] = []
1093    Dict['SKU_INDEX_VALUE'] = []
1094
1095    Dict['PCD_TOKENSPACE'] = []
1096    Dict['PCD_CNAME'] = []
1097    Dict['PCD_TOKENSPACE_LENGTH'] = []
1098    Dict['PCD_CNAME_LENGTH'] = []
1099    Dict['PCD_TOKENSPACE_OFFSET'] = []
1100    Dict['PCD_CNAME_OFFSET'] = []
1101    Dict['PCD_TOKENSPACE_MAP'] = []
1102    Dict['PCD_NAME_OFFSET'] = []
1103
1104    Dict['PCD_ORDER_TOKEN_NUMBER_MAP'] = {}
1105    PCD_STRING_INDEX_MAP = {}
1106
1107    StringTableIndex = 0
1108    StringTableSize = 0
1109    NumberOfLocalTokens = 0
1110    NumberOfPeiLocalTokens = 0
1111    NumberOfDxeLocalTokens = 0
1112    NumberOfExTokens = 0
1113    NumberOfSizeItems = 0
1114    NumberOfSkuEnabledPcd = 0
1115    GuidList = []
1116    i = 0
1117    ReorderedDynPcdList = GetOrderedDynamicPcdList(Platform.DynamicPcdList, Platform.PcdTokenNumber)
1118    for Pcd in ReorderedDynPcdList:
1119        VoidStarTypeCurrSize = []
1120        i += 1
1121        CName = Pcd.TokenCName
1122        TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
1123
1124        EdkLogger.debug(EdkLogger.DEBUG_3, "PCD: %s %s (%s : %s)" % (CName, TokenSpaceGuidCName, Pcd.Phase, Phase))
1125
1126        if Pcd.Phase == 'PEI':
1127            NumberOfPeiLocalTokens += 1
1128        if Pcd.Phase == 'DXE':
1129            NumberOfDxeLocalTokens += 1
1130        if Pcd.Phase != Phase:
1131            continue
1132
1133        #
1134        # TODO: need GetGuidValue() definition
1135        #
1136        TokenSpaceGuidStructure = Pcd.TokenSpaceGuidValue
1137        TokenSpaceGuid = GuidStructureStringToGuidValueName(TokenSpaceGuidStructure)
1138        if Pcd.Type in gDynamicExPcd:
1139            if TokenSpaceGuid not in GuidList:
1140                GuidList += [TokenSpaceGuid]
1141                Dict['GUID_STRUCTURE'].append(TokenSpaceGuidStructure)
1142            NumberOfExTokens += 1
1143
1144        ValueList = []
1145        DbValueList = []
1146        StringHeadOffsetList = []
1147        StringDbOffsetList = []
1148        VpdHeadOffsetList = []
1149        VpdDbOffsetList = []
1150        VariableHeadValueList = []
1151        VariableDbValueList = []
1152        Pcd.InitString = 'UNINIT'
1153
1154        if Pcd.DatumType == 'VOID*':
1155            if Pcd.Type not in ["DynamicVpd", "DynamicExVpd"]:
1156                Pcd.TokenTypeList = ['PCD_TYPE_STRING']
1157            else:
1158                Pcd.TokenTypeList = []
1159        elif Pcd.DatumType == 'BOOLEAN':
1160            Pcd.TokenTypeList = ['PCD_DATUM_TYPE_UINT8_BOOLEAN']
1161        else:
1162            Pcd.TokenTypeList = ['PCD_DATUM_TYPE_' + Pcd.DatumType]
1163
1164        if len(Pcd.SkuInfoList) > 1:
1165            Pcd.TokenTypeList += ['PCD_TYPE_SKU_ENABLED']
1166            NumberOfSkuEnabledPcd += 1
1167
1168        SkuIndexTableTmp = []
1169        SkuIndexTableTmp.append(0)
1170        SkuIdIndex = 1
1171        VariableHeadList = []
1172        for SkuName in Pcd.SkuInfoList:
1173            Sku = Pcd.SkuInfoList[SkuName]
1174            SkuId = Sku.SkuId
1175            if SkuId == None or SkuId == '':
1176                continue
1177
1178            if (SkuId + 'U') not in Dict['SKUID_VALUE']:
1179                Dict['SKUID_VALUE'].append(SkuId + 'U')
1180
1181            SkuIndexTableTmp.append(SkuId+'U')
1182            SkuIdIndex += 1
1183
1184            if len(Sku.VariableName) > 0:
1185                Pcd.TokenTypeList += ['PCD_TYPE_HII']
1186                Pcd.InitString = 'INIT'
1187                # Store all variable names of one HII PCD under different SKU to stringTable
1188                # and calculate the VariableHeadStringIndex
1189                if SkuIdIndex - 2 == 0:
1190                    for SkuName2 in Pcd.SkuInfoList:
1191                        SkuInfo = Pcd.SkuInfoList[SkuName2]
1192                        if SkuInfo.SkuId == None or SkuInfo.SkuId == '':
1193                            continue
1194                        VariableNameStructure = StringToArray(SkuInfo.VariableName)
1195                        if VariableNameStructure not in Dict['STRING_TABLE_VALUE']:
1196                            Dict['STRING_TABLE_CNAME'].append(CName)
1197                            Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)
1198                            if StringTableIndex == 0:
1199                                Dict['STRING_TABLE_INDEX'].append('')
1200                            else:
1201                                Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)
1202                            VarNameSize = len(VariableNameStructure.replace(',',' ').split())
1203                            Dict['STRING_TABLE_LENGTH'].append(VarNameSize )
1204                            Dict['STRING_TABLE_VALUE'].append(VariableNameStructure)
1205                            StringHeadOffsetList.append(str(StringTableSize) + 'U')
1206                            VarStringDbOffsetList = []
1207                            VarStringDbOffsetList.append(StringTableSize)
1208                            Dict['STRING_DB_VALUE'].append(VarStringDbOffsetList)
1209                            StringTableIndex += 1
1210                            StringTableSize += len(VariableNameStructure.replace(',',' ').split())
1211                        VariableHeadStringIndex = 0
1212                        for Index in range(Dict['STRING_TABLE_VALUE'].index(VariableNameStructure)):
1213                            VariableHeadStringIndex += Dict['STRING_TABLE_LENGTH'][Index]
1214                        VariableHeadList.append(VariableHeadStringIndex)
1215
1216                VariableHeadStringIndex = VariableHeadList[SkuIdIndex - 2]
1217                # store VariableGuid to GuidTable and get the VariableHeadGuidIndex
1218                VariableGuidStructure = Sku.VariableGuidValue
1219                VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)
1220
1221                if VariableGuid not in GuidList:
1222                    GuidList += [VariableGuid]
1223                    Dict['GUID_STRUCTURE'].append(VariableGuidStructure)
1224                VariableHeadGuidIndex = GuidList.index(VariableGuid)
1225
1226                if "PCD_TYPE_STRING" in Pcd.TokenTypeList:
1227                    VariableHeadValueList.append('%dU, offsetof(%s_PCD_DATABASE, Init.%s_%s), %dU, %sU' %
1228                                                 (VariableHeadStringIndex, Phase, CName, TokenSpaceGuid,
1229                                                 VariableHeadGuidIndex, Sku.VariableOffset))
1230                else:
1231                    VariableHeadValueList.append('%dU, offsetof(%s_PCD_DATABASE, Init.%s_%s_VariableDefault_%s), %dU, %sU' %
1232                                                 (VariableHeadStringIndex, Phase, CName, TokenSpaceGuid, SkuIdIndex,
1233                                                 VariableHeadGuidIndex, Sku.VariableOffset))
1234                Dict['VARDEF_CNAME_'+Pcd.DatumType].append(CName)
1235                Dict['VARDEF_GUID_'+Pcd.DatumType].append(TokenSpaceGuid)
1236                Dict['VARDEF_SKUID_'+Pcd.DatumType].append(SkuIdIndex)
1237                if "PCD_TYPE_STRING" in  Pcd.TokenTypeList:
1238                    Dict['VARDEF_VALUE_' + Pcd.DatumType].append("%s_%s[%d]" % (Pcd.TokenCName, TokenSpaceGuid, SkuIdIndex))
1239                else:
1240                    #
1241                    # ULL (for UINT64) or U(other integer type) should be append to avoid
1242                    # warning under linux building environment.
1243                    #
1244                    Dict['VARDEF_DB_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue)
1245
1246                    if Pcd.DatumType == "UINT64":
1247                        Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue + "ULL")
1248                    elif Pcd.DatumType in ("UINT32", "UINT16", "UINT8"):
1249                        Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue + "U")
1250                    elif Pcd.DatumType == "BOOLEAN":
1251                        if eval(Sku.HiiDefaultValue) in [1,0]:
1252                            Dict['VARDEF_VALUE_'+Pcd.DatumType].append(str(eval(Sku.HiiDefaultValue)) + "U")
1253                    else:
1254                        Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue)
1255
1256                # construct the VariableHeader value
1257                if "PCD_TYPE_STRING" in Pcd.TokenTypeList:
1258                    VariableHeadValueList.append('%dU, %dU, %sU, offsetof(%s_PCD_DATABASE, Init.%s_%s)' %
1259                                                 (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset,
1260                                                  Phase, CName, TokenSpaceGuid))
1261                    # the Pcd default value will be filled later on
1262                    VariableOffset = len(Dict['STRING_DB_VALUE'])
1263                    VariableRefTable = Dict['STRING_DB_VALUE']
1264                else:
1265                    VariableHeadValueList.append('%dU, %dU, %sU, offsetof(%s_PCD_DATABASE, Init.%s_%s_VariableDefault_%s)' %
1266                                                 (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset,
1267                                                  Phase, CName, TokenSpaceGuid, SkuIdIndex))
1268                    # the Pcd default value was filled before
1269                    VariableOffset = len(Dict['VARDEF_DB_VALUE_' + Pcd.DatumType]) - 1
1270                    VariableRefTable = Dict['VARDEF_DB_VALUE_' + Pcd.DatumType]
1271                VariableDbValueList.append([VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, VariableOffset, VariableRefTable])
1272
1273            elif Sku.VpdOffset != '':
1274                Pcd.TokenTypeList += ['PCD_TYPE_VPD']
1275                Pcd.InitString = 'INIT'
1276                VpdHeadOffsetList.append(str(Sku.VpdOffset) + 'U')
1277                VpdDbOffsetList.append(Sku.VpdOffset)
1278                # Also add the VOID* string of VPD PCD to SizeTable
1279                if Pcd.DatumType == 'VOID*':
1280                    NumberOfSizeItems += 1
1281                    # For VPD type of PCD, its current size is equal to its MAX size.
1282                    VoidStarTypeCurrSize = [str(Pcd.MaxDatumSize) + 'U']
1283                continue
1284
1285            if Pcd.DatumType == 'VOID*':
1286                Pcd.TokenTypeList += ['PCD_TYPE_STRING']
1287                Pcd.InitString = 'INIT'
1288                if Sku.HiiDefaultValue != '' and Sku.DefaultValue == '':
1289                    Sku.DefaultValue = Sku.HiiDefaultValue
1290                if Sku.DefaultValue != '':
1291                    NumberOfSizeItems += 1
1292                    Dict['STRING_TABLE_CNAME'].append(CName)
1293                    Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)
1294
1295                    if StringTableIndex == 0:
1296                        Dict['STRING_TABLE_INDEX'].append('')
1297                    else:
1298                        Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)
1299                    if Sku.DefaultValue[0] == 'L':
1300                        DefaultValueBinStructure = StringToArray(Sku.DefaultValue)
1301                        Size = len(DefaultValueBinStructure.replace(',',' ').split())
1302                        Dict['STRING_TABLE_VALUE'].append(DefaultValueBinStructure)
1303                    elif Sku.DefaultValue[0] == '"':
1304                        DefaultValueBinStructure = StringToArray(Sku.DefaultValue)
1305                        Size = len(Sku.DefaultValue) -2 + 1
1306                        Dict['STRING_TABLE_VALUE'].append(DefaultValueBinStructure)
1307                    elif Sku.DefaultValue[0] == '{':
1308                        DefaultValueBinStructure = StringToArray(Sku.DefaultValue)
1309                        Size = len(Sku.DefaultValue.split(","))
1310                        Dict['STRING_TABLE_VALUE'].append(DefaultValueBinStructure)
1311
1312                    StringHeadOffsetList.append(str(StringTableSize) + 'U')
1313                    StringDbOffsetList.append(StringTableSize)
1314                    if Pcd.MaxDatumSize != '':
1315                        MaxDatumSize = int(Pcd.MaxDatumSize, 0)
1316                        if MaxDatumSize < Size:
1317                            EdkLogger.error("build", AUTOGEN_ERROR,
1318                                            "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
1319                                            ExtraData="[%s]" % str(Platform))
1320                    else:
1321                        MaxDatumSize = Size
1322                    StringTabLen = MaxDatumSize
1323                    if StringTabLen % 2:
1324                        StringTabLen += 1
1325                    if Sku.VpdOffset == '':
1326                        VoidStarTypeCurrSize.append(str(Size) + 'U')
1327                    Dict['STRING_TABLE_LENGTH'].append(StringTabLen)
1328                    StringTableIndex += 1
1329                    StringTableSize += (StringTabLen)
1330            else:
1331                if "PCD_TYPE_HII" not in Pcd.TokenTypeList:
1332                    Pcd.TokenTypeList += ['PCD_TYPE_DATA']
1333                    if Sku.DefaultValue == 'TRUE':
1334                        Pcd.InitString = 'INIT'
1335                    else:
1336                        if int(Sku.DefaultValue, 0) != 0:
1337                            Pcd.InitString = 'INIT'
1338                #
1339                # For UNIT64 type PCD's value, ULL should be append to avoid
1340                # warning under linux building environment.
1341                #
1342                if Pcd.DatumType == "UINT64":
1343                    ValueList.append(Sku.DefaultValue + "ULL")
1344                elif Pcd.DatumType in ("UINT32", "UINT16", "UINT8"):
1345                    ValueList.append(Sku.DefaultValue + "U")
1346                elif Pcd.DatumType == "BOOLEAN":
1347                    if Sku.DefaultValue in ["1", "0"]:
1348                        ValueList.append(Sku.DefaultValue + "U")
1349                else:
1350                    ValueList.append(Sku.DefaultValue)
1351
1352                DbValueList.append(Sku.DefaultValue)
1353
1354        Pcd.TokenTypeList = list(set(Pcd.TokenTypeList))
1355        if Pcd.DatumType == 'VOID*':
1356            Dict['SIZE_TABLE_CNAME'].append(CName)
1357            Dict['SIZE_TABLE_GUID'].append(TokenSpaceGuid)
1358            Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(str(Pcd.MaxDatumSize) + 'U')
1359            Dict['SIZE_TABLE_CURRENT_LENGTH'].append(VoidStarTypeCurrSize)
1360
1361
1362        SkuIndexTableTmp[0] = len(SkuIndexTableTmp) - 1
1363        if len(Pcd.SkuInfoList) > 1:
1364            Dict['SKU_INDEX_VALUE'].append(SkuIndexTableTmp)
1365
1366        if 'PCD_TYPE_HII' in Pcd.TokenTypeList:
1367            Dict['VARIABLE_HEAD_CNAME_DECL'].append(CName)
1368            Dict['VARIABLE_HEAD_GUID_DECL'].append(TokenSpaceGuid)
1369            Dict['VARIABLE_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
1370            Dict['VARIABLE_HEAD_VALUE'].append('{ %s }\n' % ' },\n    { '.join(VariableHeadValueList))
1371            Dict['VARDEF_HEADER'].append('_Variable_Header')
1372            Dict['VARIABLE_DB_VALUE'].append(VariableDbValueList)
1373        else:
1374            Dict['VARDEF_HEADER'].append('')
1375        if 'PCD_TYPE_VPD' in Pcd.TokenTypeList:
1376            Dict['VPD_HEAD_CNAME_DECL'].append(CName)
1377            Dict['VPD_HEAD_GUID_DECL'].append(TokenSpaceGuid)
1378            Dict['VPD_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
1379            Dict['VPD_HEAD_VALUE'].append('{ %s }' % ' }, { '.join(VpdHeadOffsetList))
1380            Dict['VPD_DB_VALUE'].append(VpdDbOffsetList)
1381        if 'PCD_TYPE_STRING' in Pcd.TokenTypeList:
1382            Dict['STRING_HEAD_CNAME_DECL'].append(CName)
1383            Dict['STRING_HEAD_GUID_DECL'].append(TokenSpaceGuid)
1384            Dict['STRING_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
1385            Dict['STRING_HEAD_VALUE'].append(', '.join(StringHeadOffsetList))
1386            Dict['STRING_DB_VALUE'].append(StringDbOffsetList)
1387            PCD_STRING_INDEX_MAP[len(Dict['STRING_HEAD_CNAME_DECL']) -1 ] = len(Dict['STRING_DB_VALUE']) -1
1388        if 'PCD_TYPE_DATA' in Pcd.TokenTypeList:
1389            Dict[Pcd.InitString+'_CNAME_DECL_'+Pcd.DatumType].append(CName)
1390            Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType].append(TokenSpaceGuid)
1391            Dict[Pcd.InitString+'_NUMSKUS_DECL_'+Pcd.DatumType].append(len(Pcd.SkuInfoList))
1392            if Pcd.InitString == 'UNINIT':
1393                Dict['PCD_DATABASE_UNINIT_EMPTY'] = ''
1394            else:
1395                Dict[Pcd.InitString+'_VALUE_'+Pcd.DatumType].append(', '.join(ValueList))
1396                Dict[Pcd.InitString+'_DB_VALUE_'+Pcd.DatumType].append(DbValueList)
1397
1398    if Phase == 'PEI':
1399        NumberOfLocalTokens = NumberOfPeiLocalTokens
1400    if Phase == 'DXE':
1401        NumberOfLocalTokens = NumberOfDxeLocalTokens
1402
1403    Dict['TOKEN_INIT']       = ['' for x in range(NumberOfLocalTokens)]
1404    Dict['TOKEN_CNAME']      = ['' for x in range(NumberOfLocalTokens)]
1405    Dict['TOKEN_GUID']       = ['' for x in range(NumberOfLocalTokens)]
1406    Dict['TOKEN_TYPE']       = ['' for x in range(NumberOfLocalTokens)]
1407    Dict['LOCAL_TOKEN_NUMBER_DB_VALUE'] = ['' for x in range(NumberOfLocalTokens)]
1408    Dict['PCD_CNAME']        = ['' for x in range(NumberOfLocalTokens)]
1409    Dict['PCD_TOKENSPACE_MAP'] = ['' for x in range(NumberOfLocalTokens)]
1410    Dict['PCD_CNAME_LENGTH'] = [0 for x in range(NumberOfLocalTokens)]
1411    SkuEnablePcdIndex = 0
1412    for Pcd in ReorderedDynPcdList:
1413        CName = Pcd.TokenCName
1414        TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
1415        if Pcd.Phase != Phase:
1416            continue
1417
1418        TokenSpaceGuid = GuidStructureStringToGuidValueName(Pcd.TokenSpaceGuidValue) #(Platform.PackageList, TokenSpaceGuidCName))
1419        GeneratedTokenNumber = Platform.PcdTokenNumber[CName, TokenSpaceGuidCName] - 1
1420        if Phase == 'DXE':
1421            GeneratedTokenNumber -= NumberOfPeiLocalTokens
1422
1423        if len(Pcd.SkuInfoList) > 1:
1424            Dict['PCD_ORDER_TOKEN_NUMBER_MAP'][GeneratedTokenNumber] = SkuEnablePcdIndex
1425            SkuEnablePcdIndex += 1
1426        EdkLogger.debug(EdkLogger.DEBUG_1, "PCD = %s.%s" % (CName, TokenSpaceGuidCName))
1427        EdkLogger.debug(EdkLogger.DEBUG_1, "phase = %s" % Phase)
1428        EdkLogger.debug(EdkLogger.DEBUG_1, "GeneratedTokenNumber = %s" % str(GeneratedTokenNumber))
1429
1430        #
1431        # following four Dict items hold the information for LocalTokenNumberTable
1432        #
1433        Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Init'
1434        if Pcd.InitString == 'UNINIT':
1435            Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Uninit'
1436
1437        Dict['TOKEN_CNAME'][GeneratedTokenNumber] = CName
1438        Dict['TOKEN_GUID'][GeneratedTokenNumber] = TokenSpaceGuid
1439        Dict['TOKEN_TYPE'][GeneratedTokenNumber] = ' | '.join(Pcd.TokenTypeList)
1440
1441        if Platform.Platform.PcdInfoFlag:
1442            TokenSpaceGuidCNameArray = StringToArray('"' + TokenSpaceGuidCName + '"' )
1443            if TokenSpaceGuidCNameArray not in Dict['PCD_TOKENSPACE']:
1444                Dict['PCD_TOKENSPACE'].append(TokenSpaceGuidCNameArray)
1445                Dict['PCD_TOKENSPACE_LENGTH'].append( len(TokenSpaceGuidCNameArray.split(",")) )
1446            Dict['PCD_TOKENSPACE_MAP'][GeneratedTokenNumber] = Dict['PCD_TOKENSPACE'].index(TokenSpaceGuidCNameArray)
1447            CNameBinArray = StringToArray('"' + CName + '"' )
1448            Dict['PCD_CNAME'][GeneratedTokenNumber] = CNameBinArray
1449
1450            Dict['PCD_CNAME_LENGTH'][GeneratedTokenNumber] = len(CNameBinArray.split(","))
1451
1452
1453        Pcd.TokenTypeList = list(set(Pcd.TokenTypeList))
1454
1455        # search the Offset and Table, used by LocalTokenNumberTableOffset
1456        if 'PCD_TYPE_HII' in Pcd.TokenTypeList:
1457            # Find index by CName, TokenSpaceGuid
1458            Offset = GetMatchedIndex(CName, Dict['VARIABLE_HEAD_CNAME_DECL'], TokenSpaceGuid, Dict['VARIABLE_HEAD_GUID_DECL'])
1459            assert(Offset != -1)
1460            Table = Dict['VARIABLE_DB_VALUE']
1461        if 'PCD_TYPE_VPD' in Pcd.TokenTypeList:
1462            Offset = GetMatchedIndex(CName, Dict['VPD_HEAD_CNAME_DECL'], TokenSpaceGuid, Dict['VPD_HEAD_GUID_DECL'])
1463            assert(Offset != -1)
1464            Table = Dict['VPD_DB_VALUE']
1465        if 'PCD_TYPE_STRING' in Pcd.TokenTypeList and 'PCD_TYPE_HII' not in Pcd.TokenTypeList:
1466            # Find index by CName, TokenSpaceGuid
1467            Offset = GetMatchedIndex(CName, Dict['STRING_HEAD_CNAME_DECL'], TokenSpaceGuid, Dict['STRING_HEAD_GUID_DECL'])
1468            Offset = PCD_STRING_INDEX_MAP[Offset]
1469            assert(Offset != -1)
1470            Table = Dict['STRING_DB_VALUE']
1471        if 'PCD_TYPE_DATA' in Pcd.TokenTypeList:
1472            # need to store whether it is in init table or not
1473            Offset = GetMatchedIndex(CName, Dict[Pcd.InitString+'_CNAME_DECL_'+Pcd.DatumType], TokenSpaceGuid, Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType])
1474            assert(Offset != -1)
1475            if Pcd.InitString == 'UNINIT':
1476                Table =  Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType]
1477            else:
1478                Table = Dict[Pcd.InitString+'_DB_VALUE_'+Pcd.DatumType]
1479        Dict['LOCAL_TOKEN_NUMBER_DB_VALUE'][GeneratedTokenNumber] = (Offset, Table)
1480
1481        #
1482        # Update VARDEF_HEADER
1483        #
1484        if 'PCD_TYPE_HII' in Pcd.TokenTypeList:
1485            Dict['VARDEF_HEADER'][GeneratedTokenNumber] = '_Variable_Header'
1486        else:
1487            Dict['VARDEF_HEADER'][GeneratedTokenNumber] = ''
1488
1489
1490        if Pcd.Type in gDynamicExPcd:
1491
1492            if Phase == 'DXE':
1493                GeneratedTokenNumber += NumberOfPeiLocalTokens
1494            #
1495            # Per, PCD architecture specification, PCD Token Number is 1 based and 0 is defined as invalid token number.
1496            # For each EX type PCD, a PCD Token Number is assigned. When the
1497            # PCD Driver/PEIM map EX_GUID and EX_TOKEN_NUMBER to the PCD Token Number,
1498            # the non-EX Protocol/PPI interface can be called to get/set the value. This assumption is made by
1499            # Pcd Driver/PEIM in MdeModulePkg.
1500            # Therefore, 1 is added to GeneratedTokenNumber to generate a PCD Token Number before being inserted
1501            # to the EXMAPPING_TABLE.
1502            #
1503
1504
1505            Dict['EXMAPPING_TABLE_EXTOKEN'].append(str(Pcd.TokenValue) + 'U')
1506            Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(str(GeneratedTokenNumber + 1) + 'U')
1507            Dict['EXMAPPING_TABLE_GUID_INDEX'].append(str(GuidList.index(TokenSpaceGuid)) + 'U')
1508
1509    if Platform.Platform.PcdInfoFlag:
1510        for index in range(len(Dict['PCD_TOKENSPACE_MAP'])):
1511            TokenSpaceIndex = StringTableSize
1512            for i in range(Dict['PCD_TOKENSPACE_MAP'][index]):
1513                TokenSpaceIndex += Dict['PCD_TOKENSPACE_LENGTH'][i]
1514            Dict['PCD_TOKENSPACE_OFFSET'].append(TokenSpaceIndex)
1515        for index in range(len(Dict['PCD_TOKENSPACE'])):
1516            StringTableSize += Dict['PCD_TOKENSPACE_LENGTH'][index]
1517            StringTableIndex += 1
1518        for index in range(len(Dict['PCD_CNAME'])):
1519            Dict['PCD_CNAME_OFFSET'].append(StringTableSize)
1520            Dict['PCD_NAME_OFFSET'].append(Dict['PCD_TOKENSPACE_OFFSET'][index])
1521            Dict['PCD_NAME_OFFSET'].append(StringTableSize)
1522            StringTableSize += Dict['PCD_CNAME_LENGTH'][index]
1523            StringTableIndex += 1
1524    if GuidList != []:
1525        Dict['GUID_TABLE_EMPTY'] = 'FALSE'
1526        Dict['GUID_TABLE_SIZE'] = str(len(GuidList)) + 'U'
1527    else:
1528        Dict['GUID_STRUCTURE'] = [GuidStringToGuidStructureString('00000000-0000-0000-0000-000000000000')]
1529
1530    if StringTableIndex == 0:
1531        Dict['STRING_TABLE_INDEX'].append('')
1532        Dict['STRING_TABLE_LENGTH'].append(1)
1533        Dict['STRING_TABLE_CNAME'].append('')
1534        Dict['STRING_TABLE_GUID'].append('')
1535        Dict['STRING_TABLE_VALUE'].append('{ 0 }')
1536    else:
1537        Dict['STRING_TABLE_EMPTY'] = 'FALSE'
1538        Dict['STRING_TABLE_SIZE'] = str(StringTableSize) + 'U'
1539
1540    if Dict['SIZE_TABLE_CNAME'] == []:
1541        Dict['SIZE_TABLE_CNAME'].append('')
1542        Dict['SIZE_TABLE_GUID'].append('')
1543        Dict['SIZE_TABLE_CURRENT_LENGTH'].append(['0U'])
1544        Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append('0U')
1545
1546    if NumberOfLocalTokens != 0:
1547        Dict['DATABASE_EMPTY']                = 'FALSE'
1548        Dict['LOCAL_TOKEN_NUMBER_TABLE_SIZE'] = NumberOfLocalTokens
1549        Dict['LOCAL_TOKEN_NUMBER']            = NumberOfLocalTokens
1550
1551    if NumberOfExTokens != 0:
1552        Dict['EXMAP_TABLE_EMPTY']    = 'FALSE'
1553        Dict['EXMAPPING_TABLE_SIZE'] = str(NumberOfExTokens) + 'U'
1554        Dict['EX_TOKEN_NUMBER']      = str(NumberOfExTokens) + 'U'
1555    else:
1556        Dict['EXMAPPING_TABLE_EXTOKEN'].append('0U')
1557        Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append('0U')
1558        Dict['EXMAPPING_TABLE_GUID_INDEX'].append('0U')
1559
1560    if NumberOfSizeItems != 0:
1561        Dict['SIZE_TABLE_SIZE'] = str(NumberOfSizeItems * 2) + 'U'
1562
1563    if NumberOfSkuEnabledPcd != 0:
1564        Dict['SKU_HEAD_SIZE'] = str(NumberOfSkuEnabledPcd) + 'U'
1565
1566    Dict['SKUID_VALUE'][0] = len(Dict['SKUID_VALUE']) - 1
1567
1568    AutoGenH.Append(gPcdDatabaseAutoGenH.Replace(Dict))
1569    if NumberOfLocalTokens == 0:
1570        AutoGenC.Append(gEmptyPcdDatabaseAutoGenC.Replace(Dict))
1571    else:
1572        #
1573        # Update Size Table to the right order, it should be same with LocalTokenNumberTable
1574        #
1575        SizeCNameTempList = []
1576        SizeGuidTempList = []
1577        SizeCurLenTempList = []
1578        SizeMaxLenTempList = []
1579        ReOrderFlag = True
1580
1581        if len(Dict['SIZE_TABLE_CNAME']) == 1:
1582            if not (Dict['SIZE_TABLE_CNAME'][0] and Dict['SIZE_TABLE_GUID'][0]):
1583                ReOrderFlag = False
1584
1585        if ReOrderFlag:
1586            for Count in range(len(Dict['TOKEN_CNAME'])):
1587                for Count1 in range(len(Dict['SIZE_TABLE_CNAME'])):
1588                    if Dict['TOKEN_CNAME'][Count] == Dict['SIZE_TABLE_CNAME'][Count1] and \
1589                        Dict['TOKEN_GUID'][Count] == Dict['SIZE_TABLE_GUID'][Count1]:
1590                        SizeCNameTempList.append(Dict['SIZE_TABLE_CNAME'][Count1])
1591                        SizeGuidTempList.append(Dict['SIZE_TABLE_GUID'][Count1])
1592                        SizeCurLenTempList.append(Dict['SIZE_TABLE_CURRENT_LENGTH'][Count1])
1593                        SizeMaxLenTempList.append(Dict['SIZE_TABLE_MAXIMUM_LENGTH'][Count1])
1594
1595            for Count in range(len(Dict['SIZE_TABLE_CNAME'])):
1596                Dict['SIZE_TABLE_CNAME'][Count] = SizeCNameTempList[Count]
1597                Dict['SIZE_TABLE_GUID'][Count] = SizeGuidTempList[Count]
1598                Dict['SIZE_TABLE_CURRENT_LENGTH'][Count] = SizeCurLenTempList[Count]
1599                Dict['SIZE_TABLE_MAXIMUM_LENGTH'][Count] = SizeMaxLenTempList[Count]
1600
1601        AutoGenC.Append(gPcdDatabaseAutoGenC.Replace(Dict))
1602
1603    Buffer = BuildExDataBase(Dict)
1604    return AutoGenH, AutoGenC, Buffer
1605
1606def GetOrderedDynamicPcdList(DynamicPcdList, PcdTokenNumberList):
1607    ReorderedDyPcdList = [None for i in range(len(DynamicPcdList))]
1608    for Pcd in DynamicPcdList:
1609        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in PcdTokenNumberList:
1610            ReorderedDyPcdList[PcdTokenNumberList[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]-1] = Pcd
1611    return ReorderedDyPcdList
1612
1613