2 # process FFS generation from FILE statement
4 # Copyright (c) 2007 - 2016, 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.
20 import Common
.LongFilePathOs
as os
24 from GenFdsGlobalVariable
import GenFdsGlobalVariable
25 from CommonDataClass
.FdfClass
import FileStatementClassObject
26 from Common
import EdkLogger
27 from Common
.BuildToolError
import *
28 from Common
.Misc
import GuidStructureByteArrayToGuidString
29 from GuidSection
import GuidSection
30 from FvImageSection
import FvImageSection
31 from Common
.Misc
import SaveFileOnChange
34 ## generate FFS from FILE
37 class FileStatement (FileStatementClassObject
) :
40 # @param self The object pointer
43 FileStatementClassObject
.__init
__(self
)
44 self
.CurrentLineNum
= None
45 self
.CurrentLineContent
= None
47 self
.InfFileName
= None
48 self
.SubAlignment
= None
54 # @param self The object pointer
55 # @param Dict dictionary contains macro and value pair
56 # @param FvChildAddr Array of the inside FvImage base address
57 # @param FvParentAddr Parent Fv base address
58 # @retval string Generated FFS file name
60 def GenFfs(self
, Dict
= {}, FvChildAddr
=[], FvParentAddr
=None):
62 if self
.NameGuid
!= None and self
.NameGuid
.startswith('PCD('):
63 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(self
.NameGuid
)
64 if len(PcdValue
) == 0:
65 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
67 if PcdValue
.startswith('{'):
68 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
69 RegistryGuidStr
= PcdValue
70 if len(RegistryGuidStr
) == 0:
71 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
73 self
.NameGuid
= RegistryGuidStr
75 OutputDir
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, self
.NameGuid
)
76 if not os
.path
.exists(OutputDir
):
77 os
.makedirs(OutputDir
)
79 Dict
.update(self
.DefineVarDict
)
80 SectionAlignments
= None
81 if self
.FvName
!= None :
82 Buffer
= StringIO
.StringIO('')
83 if self
.FvName
.upper() not in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.keys():
84 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FV (%s) is NOT described in FDF file!" % (self
.FvName
))
85 Fv
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.get(self
.FvName
.upper())
86 FileName
= Fv
.AddToBuffer(Buffer
)
87 SectionFiles
= [FileName
]
89 elif self
.FdName
!= None:
90 if self
.FdName
.upper() not in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
91 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FD (%s) is NOT described in FDF file!" % (self
.FdName
))
92 Fd
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.get(self
.FdName
.upper())
94 SectionFiles
= [FileName
]
96 elif self
.FileName
!= None:
97 if hasattr(self
, 'FvFileType') and self
.FvFileType
== 'RAW':
98 if isinstance(self
.FileName
, list) and isinstance(self
.SubAlignment
, list) and len(self
.FileName
) == len(self
.SubAlignment
):
102 for Index
, File
in enumerate(self
.FileName
):
104 f
= open(File
, 'r+b')
106 GenFdsGlobalVariable
.ErrorLogger("Error opening RAW file %s." % (File
))
110 if self
.SubAlignment
[Index
] != None:
111 AlignValue
= GenFdsGlobalVariable
.GetAlignment(self
.SubAlignment
[Index
])
112 if AlignValue
> MaxAlignValue
:
113 MaxAlignIndex
= Index
114 MaxAlignValue
= AlignValue
115 FileContent
+= Content
116 if len(FileContent
) % AlignValue
!= 0:
117 Size
= AlignValue
- len(FileContent
) % AlignValue
118 for i
in range(0, Size
):
119 FileContent
+= pack('B', 0xFF)
122 OutputRAWFile
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, self
.NameGuid
, self
.NameGuid
+ '.raw')
123 SaveFileOnChange(OutputRAWFile
, FileContent
, True)
124 self
.FileName
= OutputRAWFile
125 self
.SubAlignment
= self
.SubAlignment
[MaxAlignIndex
]
127 if self
.Alignment
and self
.SubAlignment
:
128 if GenFdsGlobalVariable
.GetAlignment (self
.Alignment
) < GenFdsGlobalVariable
.GetAlignment (self
.SubAlignment
):
129 self
.Alignment
= self
.SubAlignment
130 elif self
.SubAlignment
:
131 self
.Alignment
= self
.SubAlignment
133 self
.FileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(self
.FileName
)
134 #Replace $(SAPCE) with real space
135 self
.FileName
= self
.FileName
.replace('$(SPACE)', ' ')
136 SectionFiles
= [GenFdsGlobalVariable
.MacroExtend(self
.FileName
, Dict
)]
141 SectionAlignments
= []
142 for section
in self
.SectionList
:
144 SecIndex
= '%d' %Index
145 # process the inside FvImage from FvSection or GuidSection
146 if FvChildAddr
!= []:
147 if isinstance(section
, FvImageSection
):
148 section
.FvAddr
= FvChildAddr
.pop(0)
149 elif isinstance(section
, GuidSection
):
150 section
.FvAddr
= FvChildAddr
151 if FvParentAddr
!= None and isinstance(section
, GuidSection
):
152 section
.FvParentAddr
= FvParentAddr
154 if self
.KeepReloc
== False:
155 section
.KeepReloc
= False
156 sectList
, align
= section
.GenSection(OutputDir
, self
.NameGuid
, SecIndex
, self
.KeyStringList
, None, Dict
)
158 for sect
in sectList
:
159 SectionFiles
.append(sect
)
160 SectionAlignments
.append(align
)
163 # Prepare the parameter
165 FfsFileOutput
= os
.path
.join(OutputDir
, self
.NameGuid
+ '.ffs')
166 GenFdsGlobalVariable
.GenerateFfs(FfsFileOutput
, SectionFiles
,
167 Ffs
.Ffs
.FdfFvFileTypeToFileType
.get(self
.FvFileType
),
170 CheckSum
=self
.CheckSum
,
171 Align
=self
.Alignment
,
172 SectionAlign
=SectionAlignments