]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/BPDG/GenVpd.py
05f5b6cf9506284dcf9210a4aff4a88fb410a014
[mirror_edk2.git] / BaseTools / Source / Python / BPDG / GenVpd.py
1 ## @file
2 # This file include GenVpd class for fix the Vpd type PCD offset, and PcdEntry for describe
3 # and process each entry of vpd type PCD.
4 #
5 # Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
6 #
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
11 #
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #
15
16 import os
17 import StringIO
18 import StringTable as st
19 import array
20
21 from struct import *
22 import Common.EdkLogger as EdkLogger
23 import Common.BuildToolError as BuildToolError
24
25 _FORMAT_CHAR = {1: 'B',
26 2: 'H',
27 4: 'I',
28 8: 'Q'
29 }
30
31 class PcdEntry:
32 def __init__(self, PcdCName, PcdOffset, PcdSize, PcdValue, Lineno=None, FileName=None, PcdUnpackValue=None,
33 PcdBinOffset=None, PcdBinSize=None):
34 self.PcdCName = PcdCName.strip()
35 self.PcdOffset = PcdOffset.strip()
36 self.PcdSize = PcdSize.strip()
37 self.PcdValue = PcdValue.strip()
38 self.Lineno = Lineno.strip()
39 self.FileName = FileName.strip()
40 self.PcdUnpackValue = PcdUnpackValue
41 self.PcdBinOffset = PcdBinOffset
42 self.PcdBinSize = PcdBinSize
43
44 if self.PcdValue == '' :
45 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
46 "Invalid PCD format(Name: %s File: %s line: %s) , no Value specified!" %(self.PcdCName, self.FileName, self.Lineno))
47
48 if self.PcdOffset == '' :
49 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
50 "Invalid PCD format(Name: %s File: %s Line: %s) , no Offset specified!" %(self.PcdCName, self.FileName, self.Lineno))
51
52 if self.PcdSize == '' :
53 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
54 "Invalid PCD format(Name: %s File: %s Line: %s), no PcdSize specified!" %(self.PcdCName, self.FileName, self.Lineno))
55
56 self._GenOffsetValue ()
57
58 def _IsBoolean(self, ValueString):
59 if ValueString.upper() in ["TRUE", "FALSE"]:
60 return True
61 return False
62
63 def _GenOffsetValue(self):
64 if self.PcdOffset != "*" :
65 try:
66 self.PcdBinOffset = int (self.PcdOffset)
67 except:
68 try:
69 self.PcdBinOffset = int(self.PcdOffset, 16)
70 except:
71 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
72 "Invalid offset value %s for PCD %s (File: %s Line: %s)" % (self.PcdOffset, self.PcdCName, self.FileName, self.Lineno))
73
74 def _PackBooleanValue(self, ValueString):
75 if ValueString.upper() == "TRUE":
76 try:
77 self.PcdValue = pack(_FORMAT_CHAR[1], 1)
78 except:
79 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
80 "Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno))
81 else:
82 try:
83 self.PcdValue = pack(_FORMAT_CHAR[1], 0)
84 except:
85 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
86 "Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno))
87
88 def _PackIntValue(self, IntValue, Size):
89 if Size not in _FORMAT_CHAR.keys():
90 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
91 "Invalid size %d for PCD %s in integer datum size(File: %s Line: %s)." % (Size, self.PcdCName, self.FileName, self.Lineno))
92 try:
93 self.PcdValue = pack(_FORMAT_CHAR[Size], IntValue)
94 except:
95 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
96 "Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno))
97
98 def _PackPtrValue(self, ValueString, Size):
99 if ValueString.startswith('L"'):
100 self._PackUnicode(ValueString, Size)
101 elif ValueString.startswith('{') and ValueString.endswith('}'):
102 self._PackByteArray(ValueString, Size)
103 elif ValueString.startswith('"') and ValueString.endswith('"'):
104 self._PackString(ValueString, Size)
105 else:
106 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
107 "Invalid VOID* type PCD %s value %s (File: %s Line: %s)" % (self.PcdCName, ValueString, self.FileName, self.Lineno))
108
109 def _PackString(self, ValueString, Size):
110 if (Size < 0):
111 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
112 "Invalid parameter Size %s of PCD %s!(File: %s Line: %s)" % (self.PcdBinSize, self.PcdCName, self.FileName, self.Lineno))
113 if (ValueString == ""):
114 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "Invalid parameter ValueString %s of PCD %s!(File: %s Line: %s)" % (self.PcdUnpackValue, self.PcdCName, self.FileName, self.Lineno))
115 if (len(ValueString) < 2):
116 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "For PCD: %s ,ASCII string %s at least contains two!(File: %s Line: %s)" % (self.PcdCName, self.PcdUnpackValue, self.FileName, self.Lineno))
117
118 ValueString = ValueString[1:-1]
119 if len(ValueString) + 1 > Size:
120 EdkLogger.error("BPDG", BuildToolError.RESOURCE_OVERFLOW,
121 "PCD value string %s is exceed to size %d(File: %s Line: %s)" % (ValueString, Size, self.FileName, self.Lineno))
122 try:
123 self.PcdValue= pack('%ds' % Size, ValueString)
124 except:
125 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
126 "Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno))
127
128 def _PackByteArray(self, ValueString, Size):
129 if (Size < 0):
130 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "Invalid parameter Size %s of PCD %s!(File: %s Line: %s)" % (self.PcdBinSize, self.PcdCName, self.FileName, self.Lineno))
131 if (ValueString == ""):
132 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "Invalid parameter ValueString %s of PCD %s!(File: %s Line: %s)" % (self.PcdUnpackValue, self.PcdCName, self.FileName, self.Lineno))
133
134 ValueString = ValueString.strip()
135 ValueString = ValueString.lstrip('{').strip('}')
136 ValueList = ValueString.split(',')
137 ValueList = [item.strip() for item in ValueList]
138
139 if len(ValueList) > Size:
140 EdkLogger.error("BPDG", BuildToolError.RESOURCE_OVERFLOW,
141 "The byte array %s is too large for size %d(File: %s Line: %s)" % (ValueString, Size, self.FileName, self.Lineno))
142
143 ReturnArray = array.array('B')
144
145 for Index in xrange(len(ValueList)):
146 Value = None
147 if ValueList[Index].startswith('0x'):
148 # translate hex value
149 try:
150 Value = int(ValueList[Index], 16)
151 except:
152 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
153 "The value item %s in byte array %s is an invalid HEX value.(File: %s Line: %s)" % \
154 (ValueList[Index], ValueString, self.FileName, self.Lineno))
155 else:
156 # translate decimal value
157 try:
158 Value = int(ValueList[Index], 10)
159 except:
160 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
161 "The value item %s in byte array %s is an invalid DECIMAL value.(File: %s Line: %s)" % \
162 (ValueList[Index], ValueString, self.FileName, self.Lineno))
163
164 if Value > 255:
165 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
166 "The value item %s in byte array %s do not in range 0 ~ 0xFF(File: %s Line: %s)" %\
167 (ValueList[Index], ValueString, self.FileName, self.Lineno))
168
169 ReturnArray.append(Value)
170
171 for Index in xrange(len(ValueList), Size):
172 ReturnArray.append(0)
173
174 self.PcdValue = ReturnArray.tolist()
175
176 ## Pack a unicode PCD value into byte array.
177 #
178 # A unicode string for a PCD should be in format as L"".
179 #
180 def _PackUnicode(self, UnicodeString, Size):
181 if (Size < 0):
182 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "Invalid parameter Size %s of PCD %s!(File: %s Line: %s)" %\
183 (self.PcdBinSize, self.PcdCName, self.FileName, self.Lineno))
184 if (len(UnicodeString) < 3):
185 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "For PCD: %s ,ASCII string %s at least contains two!(File: %s Line: %s)" %\
186 (self.PcdCName, self.PcdUnpackValue, self.FileName, self.Lineno))
187
188 UnicodeString = UnicodeString[2:-1]
189
190 if (len(UnicodeString) + 1) * 2 > Size:
191 EdkLogger.error("BPDG", BuildToolError.RESOURCE_OVERFLOW,
192 "The size of unicode string %s is too larger for size %s(File: %s Line: %s)" % \
193 (UnicodeString, Size, self.FileName, self.Lineno))
194
195 ReturnArray = array.array('B')
196 for Value in UnicodeString:
197 try:
198 ReturnArray.append(ord(Value))
199 ReturnArray.append(0)
200 except:
201 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID,
202 "Invalid unicode character %s in unicode string %s(File: %s Line: %s)" % \
203 (Value, UnicodeString, self.FileName, self.Lineno))
204
205 for Index in range(len(UnicodeString) * 2, Size):
206 ReturnArray.append(0)
207
208 self.PcdValue = ReturnArray.tolist()
209
210 class GenVPD :
211
212 ## Constructor of DscBuildData
213 #
214 # Initialize object of GenVPD
215 # @Param InputFileName The filename include the vpd type pcd information
216 # @param MapFileName The filename of map file that stores vpd type pcd information.
217 # This file will be generated by the BPDG tool after fix the offset
218 # and adjust the offset to make the pcd data aligned.
219 # @param VpdFileName The filename of Vpd file that hold vpd pcd information.
220 #
221 def __init__(self, InputFileName, MapFileName, VpdFileName):
222 self.InputFileName = InputFileName
223 self.MapFileName = MapFileName
224 self.VpdFileName = VpdFileName
225 self.FileLinesList = []
226 self.PcdFixedOffsetSizeList = []
227 self.PcdUnknownOffsetList = []
228 try:
229 fInputfile = open(InputFileName, "r", 0)
230 try:
231 self.FileLinesList = fInputfile.readlines()
232 except:
233 EdkLogger.error("BPDG", BuildToolError.FILE_READ_FAILURE, "File read failed for %s" %InputFileName,None)
234 finally:
235 fInputfile.close()
236 except:
237 EdkLogger.error("BPDG", BuildToolError.FILE_OPEN_FAILURE, "File open failed for %s" %InputFileName,None)
238
239 ##
240 # Parser the input file which is generated by the build tool. Convert the value of each pcd's
241 # from string to it's real format. Also remove the useless line in the input file.
242 #
243 def ParserInputFile (self):
244 count = 0
245 for line in self.FileLinesList:
246 # Strip "\r\n" generated by readlines ().
247 line = line.strip()
248 line = line.rstrip(os.linesep)
249
250 # Skip the comment line
251 if (not line.startswith("#")) and len(line) > 1 :
252 self.FileLinesList[count] = line.split('|')
253 # Store the line number
254 self.FileLinesList[count].append(str(count+1))
255 elif len(line) <= 1 :
256 # Set the blank line to "None"
257 self.FileLinesList[count] = None
258 else :
259 # Set the comment line to "None"
260 self.FileLinesList[count] = None
261 count += 1
262
263 # The line count contain usage information
264 count = 0
265 # Delete useless lines
266 while (True) :
267 try :
268 if (self.FileLinesList[count] == None) :
269 del(self.FileLinesList[count])
270 else :
271 count += 1
272 except :
273 break
274 #
275 # After remove the useless line, if there are no data remain in the file line list,
276 # Report warning messages to user's.
277 #
278 if len(self.FileLinesList) == 0 :
279 EdkLogger.warn('BPDG', BuildToolError.RESOURCE_NOT_AVAILABLE,
280 "There are no VPD type pcds defined in DSC file, Please check it.")
281
282 # Process the pcds one by one base on the pcd's value and size
283 count = 0
284 for line in self.FileLinesList:
285 if line != None :
286 PCD = PcdEntry(line[0], line[1], line[2], line[3], line[4], self.InputFileName)
287 # Strip the space char
288 PCD.PcdCName = PCD.PcdCName.strip(' ')
289 PCD.PcdOffset = PCD.PcdOffset.strip(' ')
290 PCD.PcdSize = PCD.PcdSize.strip(' ')
291 PCD.PcdValue = PCD.PcdValue.strip(' ')
292 PCD.Lineno = PCD.Lineno.strip(' ')
293
294 #
295 # Store the original pcd value.
296 # This information will be useful while generate the output map file.
297 #
298 PCD.PcdUnpackValue = str(PCD.PcdValue)
299
300 #
301 # Translate PCD size string to an integer value.
302 PackSize = None
303 try:
304 PackSize = int(PCD.PcdSize, 10)
305 PCD.PcdBinSize = PackSize
306 except:
307 try:
308 PackSize = int(PCD.PcdSize, 16)
309 PCD.PcdBinSize = PackSize
310 except:
311 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "Invalid PCD size value %s at file: %s line: %s" % (PCD.PcdSize, self.InputFileName, PCD.Lineno))
312
313 if PCD._IsBoolean(PCD.PcdValue):
314 PCD._PackBooleanValue(PCD.PcdValue)
315 self.FileLinesList[count] = PCD
316 count += 1
317 continue
318 #
319 # Try to translate value to an integer firstly.
320 #
321 IsInteger = True
322 PackValue = None
323 try:
324 PackValue = int(PCD.PcdValue)
325 except:
326 try:
327 PackValue = int(PCD.PcdValue, 16)
328 except:
329 IsInteger = False
330
331 if IsInteger:
332 PCD._PackIntValue(PackValue, PackSize)
333 else:
334 PCD._PackPtrValue(PCD.PcdValue, PackSize)
335
336 self.FileLinesList[count] = PCD
337 count += 1
338 else :
339 continue
340
341 ##
342 # This function used to create a clean list only contain useful information and reorganized to make it
343 # easy to be sorted
344 #
345 def FormatFileLine (self) :
346
347 for eachPcd in self.FileLinesList :
348 if eachPcd.PcdOffset != '*' :
349 # Use pcd's Offset value as key, and pcd's Value as value
350 self.PcdFixedOffsetSizeList.append(eachPcd)
351 else :
352 # Use pcd's CName as key, and pcd's Size as value
353 self.PcdUnknownOffsetList.append(eachPcd)
354
355
356 ##
357 # This function is use to fix the offset value which the not specified in the map file.
358 # Usually it use the star (meaning any offset) character in the offset field
359 #
360 def FixVpdOffset (self):
361 # At first, the offset should start at 0
362 # Sort fixed offset list in order to find out where has free spaces for the pcd's offset
363 # value is "*" to insert into.
364
365 self.PcdFixedOffsetSizeList.sort(lambda x,y: cmp(x.PcdBinOffset, y.PcdBinOffset))
366
367 #
368 # Sort the un-fixed pcd's offset by it's size.
369 #
370 self.PcdUnknownOffsetList.sort(lambda x,y: cmp(x.PcdBinSize, y.PcdBinSize))
371
372 #
373 # Process all Offset value are "*"
374 #
375 if (len(self.PcdFixedOffsetSizeList) == 0) and (len(self.PcdUnknownOffsetList) != 0) :
376 # The offset start from 0
377 NowOffset = 0
378 for Pcd in self.PcdUnknownOffsetList :
379 Pcd.PcdBinOffset = NowOffset
380 Pcd.PcdOffset = str(hex(Pcd.PcdBinOffset))
381 NowOffset += Pcd.PcdBinSize
382
383 self.PcdFixedOffsetSizeList = self.PcdUnknownOffsetList
384 return
385
386 # Check the offset of VPD type pcd's offset start from 0.
387 if self.PcdFixedOffsetSizeList[0].PcdBinOffset != 0 :
388 EdkLogger.warn("BPDG", "The offset of VPD type pcd should start with 0, please check it.",
389 None)
390
391 # Judge whether the offset in fixed pcd offset list is overlapped or not.
392 lenOfList = len(self.PcdFixedOffsetSizeList)
393 count = 0
394 while (count < lenOfList - 1) :
395 PcdNow = self.PcdFixedOffsetSizeList[count]
396 PcdNext = self.PcdFixedOffsetSizeList[count+1]
397 # Two pcd's offset is same
398 if PcdNow.PcdBinOffset == PcdNext.PcdBinOffset :
399 EdkLogger.error("BPDG", BuildToolError.ATTRIBUTE_GET_FAILURE,
400 "The offset of %s at line: %s is same with %s at line: %s in file %s" %\
401 (PcdNow.PcdCName, PcdNow.Lineno, PcdNext.PcdCName, PcdNext.Lineno, PcdNext.FileName),
402 None)
403
404 # Overlapped
405 if PcdNow.PcdBinOffset + PcdNow.PcdBinSize > PcdNext.PcdBinOffset :
406 EdkLogger.error("BPDG", BuildToolError.ATTRIBUTE_GET_FAILURE,
407 "The offset of %s at line: %s is overlapped with %s at line: %s in file %s" %\
408 (PcdNow.PcdCName, PcdNow.Lineno, PcdNext.PcdCName, PcdNext.Lineno, PcdNext.FileName),
409 None)
410
411 # Has free space, raise a warning message
412 if PcdNow.PcdBinOffset + PcdNow.PcdBinSize < PcdNext.PcdBinOffset :
413 EdkLogger.warn("BPDG", BuildToolError.ATTRIBUTE_GET_FAILURE,
414 "The offsets have free space of between %s at line: %s and %s at line: %s in file %s" %\
415 (PcdNow.PcdCName, PcdNow.Lineno, PcdNext.PcdCName, PcdNext.Lineno, PcdNext.FileName),
416 None)
417 count += 1
418
419 LastOffset = self.PcdFixedOffsetSizeList[0].PcdBinOffset
420 FixOffsetSizeListCount = 0
421 lenOfList = len(self.PcdFixedOffsetSizeList)
422 lenOfUnfixedList = len(self.PcdUnknownOffsetList)
423
424 ##
425 # Insert the un-fixed offset pcd's list into fixed offset pcd's list if has free space between those pcds.
426 #
427 while (FixOffsetSizeListCount < lenOfList) :
428
429 eachFixedPcd = self.PcdFixedOffsetSizeList[FixOffsetSizeListCount]
430 NowOffset = eachFixedPcd.PcdBinOffset
431
432 # Has free space
433 if LastOffset < NowOffset :
434 if lenOfUnfixedList != 0 :
435 countOfUnfixedList = 0
436 while(countOfUnfixedList < lenOfUnfixedList) :
437 #needFixPcdCName, needFixPcdOffset, needFixPcdSize, needFixPcdValue, needFixUnpackValue = self.PcdUnknownOffsetList[countOfUnfixedList][0:6]
438 eachUnfixedPcd = self.PcdUnknownOffsetList[countOfUnfixedList]
439 needFixPcdSize = eachUnfixedPcd.PcdBinSize
440 needFixPcdOffset = eachUnfixedPcd.PcdOffset
441 # Not been fixed
442 if eachUnfixedPcd.PcdOffset == '*' :
443 # The offset un-fixed pcd can write into this free space
444 if needFixPcdSize <= (NowOffset - LastOffset) :
445 # Change the offset value of un-fixed pcd
446 eachUnfixedPcd.PcdOffset = str(hex(LastOffset))
447 eachUnfixedPcd.PcdBinOffset = LastOffset
448 # Insert this pcd into fixed offset pcd list.
449 self.PcdFixedOffsetSizeList.insert(FixOffsetSizeListCount,eachUnfixedPcd)
450
451 # Delete the item's offset that has been fixed and added into fixed offset list
452 self.PcdUnknownOffsetList.pop(countOfUnfixedList)
453
454 # After item added, should enlarge the length of fixed pcd offset list
455 lenOfList += 1
456 FixOffsetSizeListCount += 1
457
458 # Decrease the un-fixed pcd offset list's length
459 countOfUnfixedList += 1
460 lenOfUnfixedList -= 1
461
462 # Modify the last offset value
463 LastOffset += needFixPcdSize
464 continue
465 else :
466 # It can not insert into those two pcds, need to check stiil has other space can store it.
467 FixOffsetSizeListCount += 1
468 break
469 else :
470 continue
471 # Set the FixOffsetSizeListCount = lenOfList for quit the loop
472 else :
473 FixOffsetSizeListCount = lenOfList
474
475 # No free space, smoothly connect with previous pcd.
476 elif LastOffset == NowOffset :
477 LastOffset = NowOffset + eachFixedPcd.PcdBinSize
478 FixOffsetSizeListCount += 1
479 # Usually it will not enter into this thunk, if so, means it overlapped.
480 else :
481 EdkLogger.error("BPDG", BuildToolError.ATTRIBUTE_NOT_AVAILABLE,
482 "The offset value definition has overlapped at pcd: %s, it's offset is: %s, in file: %s line: %s" %\
483 (eachFixedPcd.PcdCName, eachFixedPcd.PcdOffset, eachFixedPcd.InputFileName, eachFixedPcd.Lineno),
484 None)
485 FixOffsetSizeListCount += 1
486
487 # Continue to process the un-fixed offset pcd's list, add this time, just append them behind the fixed pcd's offset list.
488 lenOfUnfixedList = len(self.PcdUnknownOffsetList)
489 lenOfList = len(self.PcdFixedOffsetSizeList)
490 while (lenOfUnfixedList > 0) :
491 # Still has items need to process
492 # The last pcd instance
493 LastPcd = self.PcdFixedOffsetSizeList[lenOfList-1]
494 NeedFixPcd = self.PcdUnknownOffsetList[0]
495
496 NeedFixPcd.PcdBinOffset = LastPcd.PcdBinOffset + LastPcd.PcdBinSize
497 NeedFixPcd.PcdOffset = str(hex(NeedFixPcd.PcdBinOffset))
498
499 # Insert this pcd into fixed offset pcd list's tail.
500 self.PcdFixedOffsetSizeList.insert(lenOfList, NeedFixPcd)
501 # Delete the item's offset that has been fixed and added into fixed offset list
502 self.PcdUnknownOffsetList.pop(0)
503
504 lenOfList += 1
505 lenOfUnfixedList -= 1
506 ##
507 # Write the final data into output files.
508 #
509 def GenerateVpdFile (self, MapFileName, BinFileName):
510 #Open an VPD file to process
511
512 try:
513 fVpdFile = open (BinFileName, "wb", 0)
514 except:
515 # Open failed
516 EdkLogger.error("BPDG", BuildToolError.FILE_OPEN_FAILURE, "File open failed for %s" %self.VpdFileName,None)
517
518 try :
519 fMapFile = open (MapFileName, "w", 0)
520 except:
521 # Open failed
522 EdkLogger.error("BPDG", BuildToolError.FILE_OPEN_FAILURE, "File open failed for %s" %self.MapFileName,None)
523
524 # Use a instance of StringIO to cache data
525 fStringIO = StringIO.StringIO('')
526
527 # Write the header of map file.
528 try :
529 fMapFile.write (st.MAP_FILE_COMMENT_TEMPLATE + "\n")
530 except:
531 EdkLogger.error("BPDG", BuildToolError.FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %self.MapFileName,None)
532
533 for eachPcd in self.PcdFixedOffsetSizeList :
534 # write map file
535 try :
536 fMapFile.write("%s | %s | %s | %s \n" % (eachPcd.PcdCName, eachPcd.PcdOffset, eachPcd.PcdSize,eachPcd.PcdUnpackValue))
537 except:
538 EdkLogger.error("BPDG", BuildToolError.FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %self.MapFileName,None)
539
540 # Write Vpd binary file
541 fStringIO.seek (eachPcd.PcdBinOffset)
542 if isinstance(eachPcd.PcdValue, list):
543 ValueList = [chr(Item) for Item in eachPcd.PcdValue]
544 fStringIO.write(''.join(ValueList))
545 else:
546 fStringIO.write (eachPcd.PcdValue)
547
548 try :
549 fVpdFile.write (fStringIO.getvalue())
550 except:
551 EdkLogger.error("BPDG", BuildToolError.FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %self.VpdFileName,None)
552
553 fStringIO.close ()
554 fVpdFile.close ()
555 fMapFile.close ()
556