2 # process FFS generation from FILE statement
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
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
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.
18 from __future__
import absolute_import
21 import Common
.LongFilePathOs
as os
22 from io
import BytesIO
25 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
26 from CommonDataClass
.FdfClass
import FileStatementClassObject
27 from Common
import EdkLogger
28 from Common
.BuildToolError
import *
29 from Common
.Misc
import GuidStructureByteArrayToGuidString
30 from .GuidSection
import GuidSection
31 from .FvImageSection
import FvImageSection
32 from Common
.Misc
import SaveFileOnChange
35 ## generate FFS from FILE
38 class FileStatement (FileStatementClassObject
) :
41 # @param self The object pointer
44 FileStatementClassObject
.__init
__(self
)
45 self
.CurrentLineNum
= None
46 self
.CurrentLineContent
= None
48 self
.InfFileName
= None
49 self
.SubAlignment
= None
55 # @param self The object pointer
56 # @param Dict dictionary contains macro and value pair
57 # @param FvChildAddr Array of the inside FvImage base address
58 # @param FvParentAddr Parent Fv base address
59 # @retval string Generated FFS file name
61 def GenFfs(self
, Dict
= {}, FvChildAddr
=[], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
63 if self
.NameGuid
is not None and self
.NameGuid
.startswith('PCD('):
64 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(self
.NameGuid
)
65 if len(PcdValue
) == 0:
66 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
68 if PcdValue
.startswith('{'):
69 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
70 RegistryGuidStr
= PcdValue
71 if len(RegistryGuidStr
) == 0:
72 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
74 self
.NameGuid
= RegistryGuidStr
79 OutputDir
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, Str
)
80 if not os
.path
.exists(OutputDir
):
81 os
.makedirs(OutputDir
)
83 Dict
.update(self
.DefineVarDict
)
84 SectionAlignments
= None
85 if self
.FvName
is not None :
87 if self
.FvName
.upper() not in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
:
88 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FV (%s) is NOT described in FDF file!" % (self
.FvName
))
89 Fv
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.get(self
.FvName
.upper())
90 FileName
= Fv
.AddToBuffer(Buffer
)
91 SectionFiles
= [FileName
]
93 elif self
.FdName
is not None:
94 if self
.FdName
.upper() not in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
:
95 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FD (%s) is NOT described in FDF file!" % (self
.FdName
))
96 Fd
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.get(self
.FdName
.upper())
98 SectionFiles
= [FileName
]
100 elif self
.FileName
is not None:
101 if hasattr(self
, 'FvFileType') and self
.FvFileType
== 'RAW':
102 if isinstance(self
.FileName
, list) and isinstance(self
.SubAlignment
, list) and len(self
.FileName
) == len(self
.SubAlignment
):
106 for Index
, File
in enumerate(self
.FileName
):
110 GenFdsGlobalVariable
.ErrorLogger("Error opening RAW file %s." % (File
))
114 if self
.SubAlignment
[Index
] is not None:
115 AlignValue
= GenFdsGlobalVariable
.GetAlignment(self
.SubAlignment
[Index
])
116 if AlignValue
> MaxAlignValue
:
117 MaxAlignIndex
= Index
118 MaxAlignValue
= AlignValue
119 FileContent
+= Content
120 if len(FileContent
) % AlignValue
!= 0:
121 Size
= AlignValue
- len(FileContent
) % AlignValue
122 for i
in range(0, Size
):
123 FileContent
+= pack('B', 0xFF)
126 OutputRAWFile
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, self
.NameGuid
, self
.NameGuid
+ '.raw')
127 SaveFileOnChange(OutputRAWFile
, FileContent
, True)
128 self
.FileName
= OutputRAWFile
129 self
.SubAlignment
= self
.SubAlignment
[MaxAlignIndex
]
131 if self
.Alignment
and self
.SubAlignment
:
132 if GenFdsGlobalVariable
.GetAlignment (self
.Alignment
) < GenFdsGlobalVariable
.GetAlignment (self
.SubAlignment
):
133 self
.Alignment
= self
.SubAlignment
134 elif self
.SubAlignment
:
135 self
.Alignment
= self
.SubAlignment
137 self
.FileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(self
.FileName
)
138 #Replace $(SAPCE) with real space
139 self
.FileName
= self
.FileName
.replace('$(SPACE)', ' ')
140 SectionFiles
= [GenFdsGlobalVariable
.MacroExtend(self
.FileName
, Dict
)]
145 SectionAlignments
= []
146 for section
in self
.SectionList
:
148 SecIndex
= '%d' %Index
149 # process the inside FvImage from FvSection or GuidSection
150 if FvChildAddr
!= []:
151 if isinstance(section
, FvImageSection
):
152 section
.FvAddr
= FvChildAddr
.pop(0)
153 elif isinstance(section
, GuidSection
):
154 section
.FvAddr
= FvChildAddr
155 if FvParentAddr
is not None and isinstance(section
, GuidSection
):
156 section
.FvParentAddr
= FvParentAddr
158 if self
.KeepReloc
== False:
159 section
.KeepReloc
= False
160 sectList
, align
= section
.GenSection(OutputDir
, self
.NameGuid
, SecIndex
, self
.KeyStringList
, None, Dict
)
162 for sect
in sectList
:
163 SectionFiles
.append(sect
)
164 SectionAlignments
.append(align
)
167 # Prepare the parameter
169 FfsFileOutput
= os
.path
.join(OutputDir
, self
.NameGuid
+ '.ffs')
170 GenFdsGlobalVariable
.GenerateFfs(FfsFileOutput
, SectionFiles
,
171 Ffs
.Ffs
.FdfFvFileTypeToFileType
.get(self
.FvFileType
),
174 CheckSum
=self
.CheckSum
,
175 Align
=self
.Alignment
,
176 SectionAlign
=SectionAlignments