2 # process FFS generation from FILE statement
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
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
25 ## generate FFS from FILE
28 class FileStatement (FileStatementClassObject
):
31 # @param self The object pointer
34 FileStatementClassObject
.__init
__(self
)
35 self
.CurrentLineNum
= None
36 self
.CurrentLineContent
= None
38 self
.InfFileName
= None
39 self
.SubAlignment
= None
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
51 def GenFfs(self
, Dict
= None, FvChildAddr
=[], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
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.' \
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.' \
64 self
.NameGuid
= RegistryGuidStr
69 OutputDir
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, Str
)
70 if not os
.path
.exists(OutputDir
):
71 os
.makedirs(OutputDir
)
76 Dict
.update(self
.DefineVarDict
)
77 SectionAlignments
= None
80 if self
.FvName
.upper() not in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
:
81 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FV (%s) is NOT described in FDF file!" % (self
.FvName
))
82 Fv
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.get(self
.FvName
.upper())
83 FileName
= Fv
.AddToBuffer(Buffer
)
84 SectionFiles
= [FileName
]
87 if self
.FdName
.upper() not in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
:
88 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FD (%s) is NOT described in FDF file!" % (self
.FdName
))
89 Fd
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.get(self
.FdName
.upper())
91 SectionFiles
= [FileName
]
94 if hasattr(self
, 'FvFileType') and self
.FvFileType
== 'RAW':
95 if isinstance(self
.FileName
, list) and isinstance(self
.SubAlignment
, list) and len(self
.FileName
) == len(self
.SubAlignment
):
96 FileContent
= BytesIO()
99 for Index
, File
in enumerate(self
.FileName
):
103 GenFdsGlobalVariable
.ErrorLogger("Error opening RAW file %s." % (File
))
107 if self
.SubAlignment
[Index
]:
108 AlignValue
= GenFdsGlobalVariable
.GetAlignment(self
.SubAlignment
[Index
])
109 if AlignValue
> MaxAlignValue
:
110 MaxAlignIndex
= Index
111 MaxAlignValue
= AlignValue
112 FileContent
.write(Content
)
113 if len(FileContent
.getvalue()) % AlignValue
!= 0:
114 Size
= AlignValue
- len(FileContent
.getvalue()) % AlignValue
115 for i
in range(0, Size
):
116 FileContent
.write(pack('B', 0xFF))
118 if FileContent
.getvalue() != b
'':
119 OutputRAWFile
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, self
.NameGuid
, self
.NameGuid
+ '.raw')
120 SaveFileOnChange(OutputRAWFile
, FileContent
.getvalue(), True)
121 self
.FileName
= OutputRAWFile
122 self
.SubAlignment
= self
.SubAlignment
[MaxAlignIndex
]
124 if self
.Alignment
and self
.SubAlignment
:
125 if GenFdsGlobalVariable
.GetAlignment (self
.Alignment
) < GenFdsGlobalVariable
.GetAlignment (self
.SubAlignment
):
126 self
.Alignment
= self
.SubAlignment
127 elif self
.SubAlignment
:
128 self
.Alignment
= self
.SubAlignment
130 self
.FileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(self
.FileName
)
131 #Replace $(SAPCE) with real space
132 self
.FileName
= self
.FileName
.replace('$(SPACE)', ' ')
133 SectionFiles
= [GenFdsGlobalVariable
.MacroExtend(self
.FileName
, Dict
)]
138 SectionAlignments
= []
139 for section
in self
.SectionList
:
141 SecIndex
= '%d' %Index
142 # process the inside FvImage from FvSection or GuidSection
143 if FvChildAddr
!= []:
144 if isinstance(section
, FvImageSection
):
145 section
.FvAddr
= FvChildAddr
.pop(0)
146 elif isinstance(section
, GuidSection
):
147 section
.FvAddr
= FvChildAddr
148 if FvParentAddr
and isinstance(section
, GuidSection
):
149 section
.FvParentAddr
= FvParentAddr
151 if self
.KeepReloc
== False:
152 section
.KeepReloc
= False
153 sectList
, align
= section
.GenSection(OutputDir
, self
.NameGuid
, SecIndex
, self
.KeyStringList
, None, Dict
)
155 for sect
in sectList
:
156 SectionFiles
.append(sect
)
157 SectionAlignments
.append(align
)
160 # Prepare the parameter
162 FfsFileOutput
= os
.path
.join(OutputDir
, self
.NameGuid
+ '.ffs')
163 GenFdsGlobalVariable
.GenerateFfs(FfsFileOutput
, SectionFiles
,
164 FdfFvFileTypeToFileType
.get(self
.FvFileType
),
167 CheckSum
=self
.CheckSum
,
168 Align
=self
.Alignment
,
169 SectionAlign
=SectionAlignments