]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FfsFileStatement.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsFileStatement.py
1 ## @file
2 # process FFS generation from FILE statement
3 #
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 #
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
7 #
8
9 ##
10 # Import Modules
11 #
12 from __future__ import absolute_import
13 from io import BytesIO
14 from struct import pack
15 from CommonDataClass.FdfClass import FileStatementClassObject
16 from Common import EdkLogger
17 from Common.BuildToolError import GENFDS_ERROR
18 from Common.Misc import GuidStructureByteArrayToGuidString, SaveFileOnChange
19 import Common.LongFilePathOs as os
20 from .GuidSection import GuidSection
21 from .FvImageSection import FvImageSection
22 from .Ffs import FdfFvFileTypeToFileType
23 from .GenFdsGlobalVariable import GenFdsGlobalVariable
24
25 ## generate FFS from FILE
26 #
27 #
28 class FileStatement (FileStatementClassObject):
29 ## The constructor
30 #
31 # @param self The object pointer
32 #
33 def __init__(self):
34 FileStatementClassObject.__init__(self)
35 self.CurrentLineNum = None
36 self.CurrentLineContent = None
37 self.FileName = None
38 self.InfFileName = None
39 self.SubAlignment = None
40
41 ## GenFfs() method
42 #
43 # Generate FFS
44 #
45 # @param self The object pointer
46 # @param Dict dictionary contains macro and value pair
47 # @param FvChildAddr Array of the inside FvImage base address
48 # @param FvParentAddr Parent Fv base address
49 # @retval string Generated FFS file name
50 #
51 def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None, IsMakefile=False, FvName=None):
52
53 if self.NameGuid and self.NameGuid.startswith('PCD('):
54 PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid)
55 if len(PcdValue) == 0:
56 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
57 % (self.NameGuid))
58 if PcdValue.startswith('{'):
59 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
60 RegistryGuidStr = PcdValue
61 if len(RegistryGuidStr) == 0:
62 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
63 % (self.NameGuid))
64 self.NameGuid = RegistryGuidStr
65
66 Str = self.NameGuid
67 if FvName:
68 Str += FvName
69 OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, Str)
70 if not os.path.exists(OutputDir):
71 os.makedirs(OutputDir)
72
73 Dict.update(self.DefineVarDict)
74 SectionAlignments = None
75 if self.FvName:
76 Buffer = BytesIO()
77 if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
78 EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName))
79 Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper())
80 FileName = Fv.AddToBuffer(Buffer)
81 SectionFiles = [FileName]
82
83 elif self.FdName:
84 if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict:
85 EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName))
86 Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper())
87 FileName = Fd.GenFd()
88 SectionFiles = [FileName]
89
90 elif self.FileName:
91 if hasattr(self, 'FvFileType') and self.FvFileType == 'RAW':
92 if isinstance(self.FileName, list) and isinstance(self.SubAlignment, list) and len(self.FileName) == len(self.SubAlignment):
93 FileContent = BytesIO()
94 MaxAlignIndex = 0
95 MaxAlignValue = 1
96 for Index, File in enumerate(self.FileName):
97 try:
98 f = open(File, 'rb')
99 except:
100 GenFdsGlobalVariable.ErrorLogger("Error opening RAW file %s." % (File))
101 Content = f.read()
102 f.close()
103 AlignValue = 1
104 if self.SubAlignment[Index]:
105 AlignValue = GenFdsGlobalVariable.GetAlignment(self.SubAlignment[Index])
106 if AlignValue > MaxAlignValue:
107 MaxAlignIndex = Index
108 MaxAlignValue = AlignValue
109 FileContent.write(Content)
110 if len(FileContent.getvalue()) % AlignValue != 0:
111 Size = AlignValue - len(FileContent.getvalue()) % AlignValue
112 for i in range(0, Size):
113 FileContent.write(pack('B', 0xFF))
114
115 if FileContent.getvalue() != b'':
116 OutputRAWFile = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid, self.NameGuid + '.raw')
117 SaveFileOnChange(OutputRAWFile, FileContent.getvalue(), True)
118 self.FileName = OutputRAWFile
119 self.SubAlignment = self.SubAlignment[MaxAlignIndex]
120
121 if self.Alignment and self.SubAlignment:
122 if GenFdsGlobalVariable.GetAlignment (self.Alignment) < GenFdsGlobalVariable.GetAlignment (self.SubAlignment):
123 self.Alignment = self.SubAlignment
124 elif self.SubAlignment:
125 self.Alignment = self.SubAlignment
126
127 self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
128 #Replace $(SAPCE) with real space
129 self.FileName = self.FileName.replace('$(SPACE)', ' ')
130 SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)]
131
132 else:
133 SectionFiles = []
134 Index = 0
135 SectionAlignments = []
136 for section in self.SectionList:
137 Index = Index + 1
138 SecIndex = '%d' %Index
139 # process the inside FvImage from FvSection or GuidSection
140 if FvChildAddr != []:
141 if isinstance(section, FvImageSection):
142 section.FvAddr = FvChildAddr.pop(0)
143 elif isinstance(section, GuidSection):
144 section.FvAddr = FvChildAddr
145 if FvParentAddr and isinstance(section, GuidSection):
146 section.FvParentAddr = FvParentAddr
147
148 if self.KeepReloc == False:
149 section.KeepReloc = False
150 sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict)
151 if sectList != []:
152 for sect in sectList:
153 SectionFiles.append(sect)
154 SectionAlignments.append(align)
155
156 #
157 # Prepare the parameter
158 #
159 FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs')
160 GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles,
161 FdfFvFileTypeToFileType.get(self.FvFileType),
162 self.NameGuid,
163 Fixed=self.Fixed,
164 CheckSum=self.CheckSum,
165 Align=self.Alignment,
166 SectionAlign=SectionAlignments
167 )
168
169 return FfsFileOutput