BaseTools: Replace StringIO.StringIO with io.BytesIO
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FvImageSection.py
1 ## @file
2 # process FV image section generation
3 #
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 #
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 ##
16 # Import Modules
17 #
18 import Section
19 from io import BytesIO
20 from Ffs import Ffs
21 import subprocess
22 from GenFdsGlobalVariable import GenFdsGlobalVariable
23 import Common.LongFilePathOs as os
24 from CommonDataClass.FdfClass import FvImageSectionClassObject
25 from Common import EdkLogger
26 from Common.BuildToolError import *
27 from Common.DataType import *
28
29 ## generate FV image section
30 #
31 #
32 class FvImageSection(FvImageSectionClassObject):
33
34 ## The constructor
35 #
36 # @param self The object pointer
37 #
38 def __init__(self):
39 FvImageSectionClassObject.__init__(self)
40
41 ## GenSection() method
42 #
43 # Generate FV image section
44 #
45 # @param self The object pointer
46 # @param OutputPath Where to place output file
47 # @param ModuleName Which module this section belongs to
48 # @param SecNum Index of section
49 # @param KeyStringList Filter for inputs of section generation
50 # @param FfsInf FfsInfStatement object that contains this section data
51 # @param Dict dictionary contains macro and its value
52 # @retval tuple (Generated file name, section alignment)
53 #
54 def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False):
55
56 OutputFileList = []
57 if self.FvFileType is not None:
58 FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FvFileType, self.FvFileExtension)
59 if IsSect :
60 return FileList, self.Alignment
61
62 Num = SecNum
63
64 MaxFvAlignment = 0
65 for FvFileName in FileList:
66 FvAlignmentValue = 0
67 if os.path.isfile(FvFileName):
68 FvFileObj = open (FvFileName, 'rb')
69 FvFileObj.seek(0)
70 # PI FvHeader is 0x48 byte
71 FvHeaderBuffer = FvFileObj.read(0x48)
72 # FV alignment position.
73 FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)
74 FvFileObj.close()
75 if FvAlignmentValue > MaxFvAlignment:
76 MaxFvAlignment = FvAlignmentValue
77
78 OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + Ffs.SectionSuffix.get("FV_IMAGE"))
79 GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile)
80 OutputFileList.append(OutputFile)
81
82 # MaxFvAlignment is larger than or equal to 1K
83 if MaxFvAlignment >= 0x400:
84 if MaxFvAlignment >= 0x100000:
85 #The max alignment supported by FFS is 16M.
86 if MaxFvAlignment >= 0x1000000:
87 self.Alignment = "16M"
88 else:
89 self.Alignment = str(MaxFvAlignment / 0x100000) + "M"
90 else:
91 self.Alignment = str (MaxFvAlignment / 0x400) + "K"
92 else:
93 # MaxFvAlignment is less than 1K
94 self.Alignment = str (MaxFvAlignment)
95
96 return OutputFileList, self.Alignment
97 #
98 # Generate Fv
99 #
100 if self.FvName is not None:
101 Buffer = BytesIO('')
102 Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName)
103 if Fv is not None:
104 self.Fv = Fv
105 FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict, Flag=IsMakefile)
106 if Fv.FvAlignment is not None:
107 if self.Alignment is None:
108 self.Alignment = Fv.FvAlignment
109 else:
110 if GenFdsGlobalVariable.GetAlignment (Fv.FvAlignment) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
111 self.Alignment = Fv.FvAlignment
112 else:
113 if self.FvFileName is not None:
114 FvFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvFileName)
115 if os.path.isfile(FvFileName):
116 FvFileObj = open (FvFileName, 'rb')
117 FvFileObj.seek(0)
118 # PI FvHeader is 0x48 byte
119 FvHeaderBuffer = FvFileObj.read(0x48)
120 # FV alignment position.
121 FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)
122 # FvAlignmentValue is larger than or equal to 1K
123 if FvAlignmentValue >= 0x400:
124 if FvAlignmentValue >= 0x100000:
125 #The max alignment supported by FFS is 16M.
126 if FvAlignmentValue >= 0x1000000:
127 self.Alignment = "16M"
128 else:
129 self.Alignment = str(FvAlignmentValue / 0x100000) + "M"
130 else:
131 self.Alignment = str (FvAlignmentValue / 0x400) + "K"
132 else:
133 # FvAlignmentValue is less than 1K
134 self.Alignment = str (FvAlignmentValue)
135 FvFileObj.close()
136 else:
137 if len (mws.getPkgPath()) == 0:
138 EdkLogger.error("GenFds", FILE_NOT_FOUND, "%s is not found in WORKSPACE: %s" % self.FvFileName, GenFdsGlobalVariable.WorkSpaceDir)
139 else:
140 EdkLogger.error("GenFds", FILE_NOT_FOUND, "%s is not found in packages path:\n\t%s" % (self.FvFileName, '\n\t'.join(mws.getPkgPath())))
141
142 else:
143 EdkLogger.error("GenFds", GENFDS_ERROR, "FvImageSection Failed! %s NOT found in FDF" % self.FvName)
144
145 #
146 # Prepare the parameter of GenSection
147 #
148 OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + Ffs.SectionSuffix.get("FV_IMAGE"))
149 GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile)
150 OutputFileList.append(OutputFile)
151
152 return OutputFileList, self.Alignment