]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/Region.py
Check In tool source code based on Build tool project revision r1655.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / Region.py
CommitLineData
30fdf114
LG
1## @file\r
2# process FD Region generation\r
3#\r
4# Copyright (c) 2007, Intel Corporation\r
5#\r
6# All rights reserved. This program and the accompanying materials\r
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
15##\r
16# Import Modules\r
17#\r
18from struct import *\r
19from GenFdsGlobalVariable import GenFdsGlobalVariable\r
20import StringIO\r
21from CommonDataClass.FdfClass import RegionClassObject\r
22import os\r
23from Common import EdkLogger\r
24from Common.BuildToolError import *\r
25\r
26\r
27## generate Region\r
28#\r
29#\r
30class Region(RegionClassObject):\r
31\r
32 ## The constructor\r
33 #\r
34 # @param self The object pointer\r
35 #\r
36 def __init__(self):\r
37 RegionClassObject.__init__(self)\r
38\r
39\r
40 ## AddToBuffer()\r
41 #\r
42 # Add region data to the Buffer\r
43 #\r
44 # @param self The object pointer\r
45 # @param Buffer The buffer generated region data will be put\r
46 # @param BaseAddress base address of region\r
47 # @param BlockSize block size of region\r
48 # @param BlockNum How many blocks in region\r
49 # @param ErasePolarity Flash erase polarity\r
50 # @param VtfDict VTF objects\r
51 # @param MacroDict macro value pair\r
52 # @retval string Generated FV file path\r
53 #\r
54\r
55 def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, FvBinDict, vtfDict = None, MacroDict = {}):\r
56 Size = self.Size\r
57 GenFdsGlobalVariable.InfLogger('Generate Region at Offset 0x%X' % self.Offset)\r
58 GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" %Size)\r
59 GenFdsGlobalVariable.SharpCounter = 0\r
60\r
61 if self.RegionType == 'FV':\r
62 #\r
63 # Get Fv from FvDict\r
64 #\r
65 FvBuffer = StringIO.StringIO('')\r
66 RegionBlockSize = self.BlockSizeOfRegion(BlockSizeList)\r
67 RegionBlockNum = self.BlockNumOfRegion(RegionBlockSize)\r
68\r
69 self.FvAddress = int(BaseAddress, 16) + self.Offset\r
70 FvBaseAddress = '0x%X' %self.FvAddress\r
71\r
72 for RegionData in self.RegionDataList:\r
73\r
74 if RegionData.endswith(".fv"):\r
75 RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)\r
76 GenFdsGlobalVariable.InfLogger(' Region FV File Name = .fv : %s'%RegionData)\r
77 if RegionData[1] != ':' :\r
78 RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)\r
79 if not os.path.exists(RegionData):\r
80 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)\r
81\r
82 BinFile = open (RegionData, 'r+b')\r
83 FvBuffer.write(BinFile.read())\r
84 if FvBuffer.len > Size:\r
85 EdkLogger.error("GenFds", GENFDS_ERROR,\r
86 "Size of FV File (%s) is larger than Region Size 0x%X specified." \\r
87 % (RegionData, Size))\r
88 break\r
89\r
90 if RegionData.upper() in FvBinDict.keys():\r
91 continue\r
92\r
93 FvObj = None\r
94 if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
95 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper())\r
96\r
97 if FvObj != None :\r
98 GenFdsGlobalVariable.InfLogger(' Region Name = FV')\r
99 #\r
100 # Call GenFv tool\r
101 #\r
102 BlockSize = RegionBlockSize\r
103 BlockNum = RegionBlockNum\r
104 if FvObj.BlockSizeList != []:\r
105 if FvObj.BlockSizeList[0][0] != None:\r
106 BlockSize = FvObj.BlockSizeList[0][0]\r
107 if FvObj.BlockSizeList[0][1] != None:\r
108 BlockNum = FvObj.BlockSizeList[0][1]\r
109 self.FvAddress = self.FvAddress + FvBuffer.len\r
110 FvAlignValue = self.GetFvAlignValue(FvObj.FvAlignment)\r
111 if self.FvAddress % FvAlignValue != 0:\r
112 EdkLogger.error("GenFds", GENFDS_ERROR,\r
113 "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment))\r
114 FvBaseAddress = '0x%X' %self.FvAddress\r
115 FileName = FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict)\r
116\r
117 if FvBuffer.len > Size:\r
118 EdkLogger.error("GenFds", GENFDS_ERROR,\r
119 "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size))\r
120 else:\r
121 EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData))\r
122\r
123\r
124 if FvBuffer.len > 0:\r
125 Buffer.write(FvBuffer.getvalue())\r
126 else:\r
127 BinFile = open (FileName, 'rb')\r
128 Buffer.write(BinFile.read())\r
129\r
130 FvBuffer.close()\r
131\r
132 if self.RegionType == 'FILE':\r
133 FvBuffer = StringIO.StringIO('')\r
134 for RegionData in self.RegionDataList:\r
135 RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)\r
136 GenFdsGlobalVariable.InfLogger(' Region File Name = FILE: %s'%RegionData)\r
137 if RegionData[1] != ':' :\r
138 RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)\r
139 if not os.path.exists(RegionData):\r
140 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)\r
141\r
142 BinFile = open (RegionData, 'r+b')\r
143 FvBuffer.write(BinFile.read())\r
144 if FvBuffer.len > Size :\r
145 EdkLogger.error("GenFds", GENFDS_ERROR,\r
146 "Size of File (%s) large than Region Size " % RegionData)\r
147\r
148 #\r
149 # If File contents less than region size, append "0xff" after it\r
150 #\r
151 if FvBuffer.len < Size:\r
152 for index in range(0, (Size-FvBuffer.len)):\r
153 if (ErasePolarity == '1'):\r
154 FvBuffer.write(pack('B', int('0xFF', 16)))\r
155 else:\r
156 FvBuffer.write(pack('B', int('0x00', 16)))\r
157 Buffer.write(FvBuffer.getvalue())\r
158 FvBuffer.close()\r
159\r
160 if self.RegionType == 'DATA' :\r
161 GenFdsGlobalVariable.InfLogger(' Region Name = DATA')\r
162 DataSize = 0\r
163 for RegionData in self.RegionDataList:\r
164 Data = RegionData.split(',')\r
165 DataSize = DataSize + len(Data)\r
166 if DataSize > Size:\r
167 EdkLogger.error("GenFds", GENFDS_ERROR, "Size of DATA is larger than Region Size ")\r
168 else:\r
169 for item in Data :\r
170 Buffer.write(pack('B', int(item, 16)))\r
171 if DataSize < Size:\r
172 if (ErasePolarity == '1'):\r
173 PadData = 0xFF\r
174 else:\r
175 PadData = 0\r
176 for i in range(Size - DataSize):\r
177 Buffer.write(pack('B', PadData))\r
178\r
179 if self.RegionType == None:\r
180 GenFdsGlobalVariable.InfLogger(' Region Name = None')\r
181 if (ErasePolarity == '1') :\r
182 PadData = 0xFF\r
183 else :\r
184 PadData = 0\r
185 for i in range(0, Size):\r
186 Buffer.write(pack('B', PadData))\r
187\r
188 def GetFvAlignValue(self, Str):\r
189 AlignValue = 1\r
190 Granu = 1\r
191 Str = Str.strip().upper()\r
192 if Str.endswith('K'):\r
193 Granu = 1024\r
194 Str = Str[:-1]\r
195 elif Str.endswith('M'):\r
196 Granu = 1024*1024\r
197 Str = Str[:-1]\r
198 elif Str.endswith('G'):\r
199 Granu = 1024*1024*1024\r
200 Str = Str[:-1]\r
201 else:\r
202 pass\r
203\r
204 AlignValue = int(Str)*Granu\r
205 return AlignValue\r
206 ## BlockSizeOfRegion()\r
207 #\r
208 # @param BlockSizeList List of block information\r
209 # @retval int Block size of region\r
210 #\r
211 def BlockSizeOfRegion(self, BlockSizeList):\r
212 Offset = 0x00\r
213 BlockSize = 0\r
214 for item in BlockSizeList:\r
215 Offset = Offset + item[0] * item[1]\r
216 GenFdsGlobalVariable.VerboseLogger ("Offset = 0x%X" %Offset)\r
217 GenFdsGlobalVariable.VerboseLogger ("self.Offset 0x%X" %self.Offset)\r
218\r
219 if self.Offset < Offset :\r
220 if Offset - self.Offset < self.Size:\r
221 EdkLogger.error("GenFds", GENFDS_ERROR,\r
222 "Region at Offset 0x%X can NOT fit into Block array with BlockSize %X" \\r
223 % (self.Offset, item[0]))\r
224 BlockSize = item[0]\r
225 GenFdsGlobalVariable.VerboseLogger ("BlockSize = %X" %BlockSize)\r
226 return BlockSize\r
227 return BlockSize\r
228\r
229 ## BlockNumOfRegion()\r
230 #\r
231 # @param BlockSize block size of region\r
232 # @retval int Block number of region\r
233 #\r
234 def BlockNumOfRegion (self, BlockSize):\r
235 if BlockSize == 0 :\r
236 EdkLogger.error("GenFds", GENFDS_ERROR, "Region: %s is not in the FD address scope!" % self.Offset)\r
237 BlockNum = self.Size / BlockSize\r
238 GenFdsGlobalVariable.VerboseLogger ("BlockNum = 0x%X" %BlockNum)\r
239 return BlockNum\r
240\r