blob: dd0bc489c1178f84d79643ac8c83297e6a9c2bfc [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001#!/usr/bin/perl
2#
3# Copyright Statement:
4# --------------------
5# This software is protected by Copyright and the information contained
6# herein is confidential. The software may not be copied and the information
7# contained herein may not be used or disclosed except with the written
8# permission of MediaTek Inc. (C) 2006
9#
10# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
11# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
12# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
13# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
14# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
15# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
16# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
17# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
18# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
19# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
20# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
21# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
22#
23# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
24# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
25# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
26# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
27# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
28#
29# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
30# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
31# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
32# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
33# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
34#
35#*****************************************************************************
36#*
37#* Filename:
38#* ---------
39#* config_MemSegment.pm
40#*
41#* Project:
42#* --------
43#*
44#*
45#* Description:
46#* ------------
47#* This module collects the subroutines for common utility.
48#*
49#*
50#* Author:
51#* -------
52#* Carina Liao (mtk04017)
53#*
54#****************************************************************************/
55package memConfig;
56use strict;
57#use warnings;
58BEGIN { push @INC, './pcore/tools/' } # add additional library path
59use sysGenUtility; #pm file name without case sensitivity
60use FileInfoParser;
61use CommonUtility;
62use File::Basename;
63#****************************************************************************
64# Version
65#****************************************************************************
66my $CONFIGMEMSEGMENT_VERNO = " m0.06";
67 # m0.06 , 2012/09/18, Change getting flash size rule and add error checking in GetPhysicalFlashEnd()
68 # m0.05 , 2012/08/17, Support Smartphone
69 # m0.04 , 2012/08/10, Support GetBlockSize() in Get_SDS_total_size() directly
70 # m0.03 , 2012/08/07, Add Memory Parsing Rule and Verification
71 # m0.02 , 2012/07/26, Replace is_NOR() by is_NonSPNOR() and add some error handling
72 # m0.01 , 2012/07/12, Move booting type query from sysGenUtility to FileInfoParser
73 # v0.02 , 2012/05/28, Support path and filename case sensitive on Linux
74 # v0.01 , 2012/05/14, Initial revision
75#****************************************************************************
76# Constants
77#****************************************************************************
78#Parse File Type
79use constant MEMORY_DEVICE => "CUSTOM_MEMORY_DEVICE";
80use constant FEATURE_CONFIG => "CUSTOM_FEATURE_CONFIG";
81use constant CUSTOM_IMG_CONFIG => "CUSTOM_IMG_CONFIG";
82use constant CUSTOM_EMI => "CUSTOM_EMI_RELEASE";
83use constant CUSTOM_FLASH => "CUSTOM_FLASH";
84#****************************************************************************
85# Global variable
86#****************************************************************************
87my %g_MemConfigValues; # $MemConfigValues{Type} = href;
88#Keyword needs to be case sensitive:
89# ----- RAM -----
90# nEMI_EXTSRAM_SIZE : exported by GetPhysicalExtRAM()
91# strEMI_EXTSRAM_SIZE : exported by GetPhysicalExtRAM()
92# nPROCESSED_RAMSIZE : exported by GetExtRamSize()
93
94# ----- Flash Info -----
95# RegionInfoTxt : exported by GetFlashInfoLog()
96# BlkInfoTxt : exported by GetFlashInfoLog()
97# BankInfoTxt : exported by GetFlashInfoLog()
98# REGION_LIST
99# BANK_LIST
100# BLK_LIST
101# BLK_TABLE : exported by GetBlockTable()
102
103# ----- Flash Size -----
104# NOR_FLASH_DENSITY : exported by GetFlashInfoLog()
105# nNOR_FLASH_DENSITY
106# NOR_FLASH_SIZE : exported by GetFlashInfoLog()
107# nNOR_FLASH_SIZE : exported by GetPhysicalFlashEnd()
108# nCODESize : exported by GetROMSize()
109
110#****************************************************************************
111# oo >>> Finished
112#****************************************************************************
113return 1;
114
115sub Parse
116{
117 my ($strFilePath, $Source, $INSIDE_MTK, $bIsDummy) = @_;
118 return if(!defined $Source);
119 my %Results;
120 $Results{PATH} = $strFilePath;
121 $Results{path} = $strFilePath;
122 if($Source eq FEATURE_CONFIG)
123 {
124 &FileInfo::ParseDefinition($strFilePath, \%Results, 0);
125 &_PostProcessFeatureConfig(\%Results, $INSIDE_MTK, $bIsDummy);
126 }
127 elsif($Source eq CUSTOM_IMG_CONFIG)
128 {
129 &FileInfo::ParseDefinition($strFilePath, \%Results, 1);
130 &_PostProcessIMG_CONFIG(\%Results);
131 }
132 elsif($Source eq CUSTOM_EMI)
133 {
134 &FileInfo::ParseDefinition($strFilePath, \%Results, 0);
135 &_PostProcessRamSize(\%Results, $bIsDummy);
136 }
137 elsif($Source eq CUSTOM_FLASH)
138 {
139 &_ParseFlashInfo($strFilePath, \%Results);
140 &_PostProcessFlashSize(\%Results, $bIsDummy);
141 }
142 else
143 {
144 &FileInfo::ParseDefinition($strFilePath, \%Results, 0);
145 }
146 $g_MemConfigValues{$Source} = \%Results;
147}
148
149sub _PostProcessFeatureConfig
150{
151 my ($Hash_ref, $INSIDE_MTK, $bIsDummy)=@_;
152 if($INSIDE_MTK == 0)
153 {
154 delete $Hash_ref->{"PROJECT_EXPECTED_CODE_LIMIT"} if (exists $Hash_ref->{"PROJECT_EXPECTED_CODE_LIMIT"});
155 delete $Hash_ref->{"PROJECT_EXPECTED_RAM_LIMIT"} if (exists $Hash_ref->{"PROJECT_EXPECTED_RAM_LIMIT"});
156 delete $Hash_ref->{"PROJECT_EXPECTED_RAM_LIMIT_NFB"} if (exists $Hash_ref->{"PROJECT_EXPECTED_RAM_LIMIT_NFB"});
157 }
158 if($bIsDummy)
159 {
160 $Hash_ref->{'CONFIG_ZIMAGE_DECOMPRESSED_SIZE'} = "0x2000000";
161 }
162 $Hash_ref->{CONFIG_FOTA_UE_FLASH_SPACE} = "0x0" if(!defined $Hash_ref->{CONFIG_FOTA_UE_FLASH_SPACE});
163 $Hash_ref->{CONFIG_FOTA_PACKAGE_BLOCK_NUMBER} = "4" if(!defined $Hash_ref->{CONFIG_FOTA_PACKAGE_BLOCK_NUMBER});
164 $Hash_ref->{CONFIG_FOTA_PACKAGE_AREA_SIZE} = "0x0" if(!defined $Hash_ref->{CONFIG_FOTA_PACKAGE_AREA_SIZE});
165 $Hash_ref->{CONFIG_FOTA_NAND_MAP_TABLE_SIZE} = "0x800" if(!defined $Hash_ref->{CONFIG_FOTA_NAND_MAP_TABLE_SIZE});
166}
167sub _PostProcessIMG_CONFIG
168{
169 my ($Hash_ref) = @_;
170 if(defined $g_MemConfigValues{FEATURE_CONFIG})
171 {
172 $Hash_ref->{CONFIG_FOTA_UE_FLASH_SPACE} = &get("CONFIG_FOTA_UE_FLASH_SPACE", FEATURE_CONFIG);
173 $Hash_ref->{CONFIG_FOTA_PACKAGE_BLOCK_NUMBER} = &get("CONFIG_FOTA_PACKAGE_BLOCK_NUMBER", FEATURE_CONFIG);
174 $Hash_ref->{CONFIG_FOTA_PACKAGE_AREA_SIZE} = &get("CONFIG_FOTA_PACKAGE_AREA_SIZE", FEATURE_CONFIG);
175 $Hash_ref->{CONFIG_FOTA_NAND_MAP_TABLE_SIZE} = &get("CONFIG_FOTA_NAND_MAP_TABLE_SIZE", FEATURE_CONFIG);
176 }
177}
178sub _PostProcessRamSize
179{
180 my ($Hash_ref, $bIsDummy) = @_;
181 $Hash_ref->{nEMI_EXTSRAM_SIZE} = eval($Hash_ref->{EMI_EXTSRAM_SIZE});
182 $Hash_ref->{strEMI_EXTSRAM_SIZE} = &CommonUtil::Dec2Hex($Hash_ref->{nEMI_EXTSRAM_SIZE});
183 if($bIsDummy)
184 {
185 $Hash_ref->{nPROCESSED_RAMSIZE} = 0x8000000;
186 }
187 else
188 {
189 &DieIfNotParsing(FEATURE_CONFIG, __FILE__, __LINE__);
190 if(&FileInfo::is_NonSPNOR() and &exist('PROJECT_EXPECTED_RAM_LIMIT', FEATURE_CONFIG))
191 {
192 $Hash_ref->{nPROCESSED_RAMSIZE} = hex(&get('PROJECT_EXPECTED_RAM_LIMIT', FEATURE_CONFIG));
193 }
194 elsif(!&FileInfo::is_NonSPNOR() and &exist('PROJECT_EXPECTED_RAM_LIMIT_NFB', FEATURE_CONFIG))
195 {
196 $Hash_ref->{nPROCESSED_RAMSIZE} = hex(&get('PROJECT_EXPECTED_RAM_LIMIT_NFB', FEATURE_CONFIG));
197 }
198 else
199 {
200 $Hash_ref->{nPROCESSED_RAMSIZE} = $Hash_ref->{"nEMI_EXTSRAM_SIZE"};
201 }
202 }
203}
204sub _ParseFlashInfo
205{
206 my ($strFilePath, $Hash_ref) = @_;
207 my (@REGION_LIST, @BANK_LIST, @BLK_LIST, %BLK_TABLE);
208 my $content = &CommonUtil::GetFileContent($strFilePath);
209 my @lines = split(/\n|\r/, $content);
210 &_parse_flash_size(\@lines, $Hash_ref);
211 if(&FileInfo::is_NonSPNOR())
212 {
213 $Hash_ref->{RegionInfoTxt} = &_parse_norflash_list(\@lines, \@REGION_LIST,
214 'FLASH_REGIONINFO_VAR_MODIFIER\s+FlashRegionInfo\s+oriRegionInfo\S+',
215 'EndoriRegionInfo');
216 $Hash_ref->{BlkInfoTxt} = &_parse_norflash_list(\@lines, \@BLK_LIST,
217 'FLASH_REGIONINFO_VAR_MODIFIER\s+FlashBlockTBL\s+\S+',
218 'EndBlockInfo');
219 $Hash_ref->{BankInfoTxt} = &_parse_norflash_list(\@lines, \@BANK_LIST,
220 'static\s+NORBankInfo\s+oriBankInfo\S+',
221 'EndBankInfo');
222 if (scalar(@BLK_LIST) > 0)
223 {
224 foreach my $item (@BLK_LIST)
225 { #{0x0, 0x10000}
226 $BLK_TABLE{hex($item->[0])} = hex($item->[1]);
227 }
228 }
229 $Hash_ref->{REGION_LIST} = \@REGION_LIST;
230 $Hash_ref->{BANK_LIST} = \@BANK_LIST;
231 $Hash_ref->{BLK_LIST} = \@BLK_LIST;
232 $Hash_ref->{BLK_TABLE} = \%BLK_TABLE;
233 }
234}
235sub _parse_norflash_list #called by _ProcessFlash
236{
237 my ($lines_aref, $list_aref, $strSearch, $strEnd) = @_;
238 my $strParsedString;
239 my $bFound = undef;
240 foreach my $line (@$lines_aref)
241 {
242 if ($line =~ /^$strSearch/)
243 {
244 $bFound = 1;
245 }
246 elsif ($bFound)
247 {
248 if ($line =~ /\{\s*(\S+)\s*,\s*(\S+)\s*\}/)
249 {
250 $strParsedString .= $line . "\n";
251 push @$list_aref, [$1,$2];
252 }
253 last if ($line =~ /^\s*$strEnd\s*/);
254 }
255 }
256 return $strParsedString;
257}
258sub _parse_flash_size # called by _ProcessFlash
259{
260 my ($lines_aref, $Hash_ref) = @_;
261 foreach my $line (@$lines_aref)
262 {
263 # NOR_FLASH_DENSITY = NOR_FLASH_SIZE but in different units
264 # NOR_FLASH_DENSITY is only generated in nor project by emiGen
265 # #define NOR_FLASH_SIZE is generated in both nand(means nand flash size) and nor project by emiGen
266 if($line =~ /^\s*\*\s+NOR_FLASH_DENSITY:\s*(\w*)/)
267 { # * NOR_FLASH_DENSITY: 0x02000000 - got from MDL's bank/block calculation
268 $Hash_ref->{NOR_FLASH_DENSITY} = $1; # in string
269 $Hash_ref->{nNOR_FLASH_DENSITY} = hex($1); # in num
270 }
271 elsif($line =~ /^\s*\#define\s+NOR_FLASH_SIZE\s+(\w+)/)
272 { # #define NOR_FLASH_SIZE 0x08000000
273 $Hash_ref->{NOR_FLASH_SIZE} = $1; # in string
274 $Hash_ref->{nNOR_FLASH_SIZE} = hex($1); # in num
275 }
276 }
277}
278sub _PostProcessFlashSize
279{
280 my ($Hash_ref, $bIsDummy) = @_;
281 &DieIfNotParsing(FEATURE_CONFIG, __FILE__, __LINE__);
282 if(&FileInfo::is_NonSPNOR())
283 {
284 if($bIsDummy)
285 {
286 $Hash_ref->{nCODESize} = 0x8000000;
287 }
288 elsif(&exist('PROJECT_EXPECTED_CODE_LIMIT', FEATURE_CONFIG))
289 {
290 $Hash_ref->{nCODESize} = hex(&get('PROJECT_EXPECTED_CODE_LIMIT', FEATURE_CONFIG));
291 }
292 else
293 {
294 ($Hash_ref->{nCODESize}, my $temp) = &_GetFSInfo($Hash_ref);
295 }
296 }
297}
298sub _GetFSInfo
299{
300 my ($Hash_ref) = @_;
301 &DieIfNotNonSPNOR(__FILE__, __LINE__);
302 &DieIfNotParsing(MEMORY_DEVICE, __FILE__, __LINE__);
303 my ($nFSBase, $nFSSize) = (undef, undef);
304 if(&exist("NOR_BOOTING_NOR_FS_BASE_ADDRESS", MEMORY_DEVICE) and &exist("NOR_BOOTING_NOR_FS_SIZE", MEMORY_DEVICE))
305 {
306 $nFSBase = hex(&get("NOR_BOOTING_NOR_FS_BASE_ADDRESS", MEMORY_DEVICE));
307 $nFSSize = hex(&get("NOR_BOOTING_NOR_FS_SIZE", MEMORY_DEVICE));
308 }
309 elsif(&exist("NOR_BOOTING_NOR_FS_BASE_ADDRESS", MEMORY_DEVICE) and !&exist("NOR_BOOTING_NOR_FS_SIZE" , MEMORY_DEVICE))
310 {
311 my ($nFATBase , $nFATSpace, $nSmallBlockStart) = &_GetFATInfo($Hash_ref);
312 $nFSBase = hex(&get("NOR_BOOTING_NOR_FS_BASE_ADDRESS", MEMORY_DEVICE));
313 $nFSSize = $nSmallBlockStart - $nFSBase;
314 }
315 elsif(!&exist("NOR_BOOTING_NOR_FS_BASE_ADDRESS", MEMORY_DEVICE) and &exist("NOR_BOOTING_NOR_FS_SIZE", MEMORY_DEVICE))
316 {
317 ($nFSBase , my $nFATSpace, my $nSmallBlockStart) = &_GetFATInfo($Hash_ref);
318 $nFSSize = hex(&get("NOR_BOOTING_NOR_FS_SIZE", MEMORY_DEVICE));
319 }
320 else
321 {
322 ($nFSBase , $nFSSize, my $nSmallBlockStart) = &_GetFATInfo($Hash_ref);
323 }
324 ### work-around for bad small block issue
325 #To correct Toshiba(NOR Flash on 36) for some small blocks which can't be used
326 if((($nFSBase+$nFSSize) > $Hash_ref->{nNOR_FLASH_DENSITY}) and
327 (($nFSBase+$nFSSize) <= ($Hash_ref->{nNOR_FLASH_SIZE})))
328 {
329 $nFSSize = $Hash_ref->{nNOR_FLASH_DENSITY} - $nFSBase;
330 }
331 return ($nFSBase, $nFSSize);
332}
333sub _GetFATInfo ### Calculate FAT size/start address
334{
335 my ($Hash_ref) = @_; #parsed hash from custom_flash.h
336 &DieIfNotNonSPNOR(__FILE__, __LINE__);
337 &DieIfNotParsing(MEMORY_DEVICE, __FILE__, __LINE__);
338 my ($Regions_aref, $BLK_aref) = ($Hash_ref->{REGION_LIST}, $Hash_ref->{BLK_LIST});
339 my ($nFATBase , $nFATSpace) = (0, 0);
340 my $nFlashSize = $Hash_ref->{nNOR_FLASH_DENSITY};
341 my $sum_of_regions = 0;
342 my $nSmallBlockStart = $nFlashSize;
343 for (0..scalar(@{$Regions_aref})-1)
344 {
345 $sum_of_regions += hex($Regions_aref->[$_][0]) * $Regions_aref->[$_][1];
346 }
347 if ((scalar(@{$Regions_aref})>0) && &is("__NOR_FDM5__", "TRUE", MEMORY_DEVICE))
348 {
349 $nSmallBlockStart = hex($BLK_aref->[-1]->[0]);# match {0xFF0000,0x2000}
350 $nFATSpace = $sum_of_regions - ($nFlashSize - $nSmallBlockStart); #To avoid Toshiba(NOR Flash) some small blocks can't be used
351 }
352 else
353 {
354 $nFATSpace = $sum_of_regions;
355 }
356 $nFATBase = $nFlashSize - $sum_of_regions;
357 return ($nFATBase , $nFATSpace, $nSmallBlockStart);
358}
359sub VerifyFSInfo
360{
361 my ($isDummy) = @_;
362 return if($isDummy or !&FileInfo::is_NonSPNOR());
363 my $Flash_href = &GetSource(CUSTOM_FLASH);
364 my ($nFSBase, $nFSSize) = &_GetFSInfo($Flash_href);
365
366 # 1. Ensure that FS Base and Size are correct
367 my $nPhysicalFlashSize = &GetPhysicalFlashEnd();
368 &config_die("FAT space($nFSBase+$nFSSize) cannot exceed physical NOR flash size($nPhysicalFlashSize)!", __FILE__, __LINE__)
369 if(($nFSBase < 0) or ($nFSSize < 0) or (($nFSBase+ $nFSSize) > $nPhysicalFlashSize));
370
371 # 2. Ensure small block workaround
372 if(&exist("__NOR_FDM5__", MEMORY_DEVICE))
373 {
374 my ($nFATBase , $nFATSpace, $nSmallBlockStart) = &_GetFATInfo($Flash_href);
375 &config_die("FAT space($nFSBase+$nFSSize) cannot include small blocks(SmallBlockStart:$nSmallBlockStart) in NOR FDM 5.0!", __FILE__, __LINE__)
376 if(($nFSBase+$nFSSize) > $nSmallBlockStart);
377 }
378
379 # 3. if FS Base is defined by the customer, help to check bank/block alignment.
380 if(&exist("NOR_BOOTING_NOR_FS_BASE_ADDRESS", MEMORY_DEVICE))
381 {
382 if(&FileInfo::is("enhanced_single_bank_nor_flash_support","TRUE"))
383 { #single-bank FAT start address needs to be block-aligned
384 my $bBlockAligned = &isBlockAligned($nFSBase);
385 my $BlkInfoTxt = &get("BlkInfoTxt", CUSTOM_FLASH);
386 &config_die("FS Base($nFSBase) needs to be block-aligned in single-bank setting!\nBlockInfo:\n$BlkInfoTxt\n",
387 __FILE__, __LINE__) if(!$bBlockAligned);
388 }
389 else
390 { #multi-bank FAT start address needs to be bank-aligned
391 my ($bBankAligned, $nSum_of_banks) = &isBankAligned($nFSBase);
392 &config_die("FS Base($nFSBase) needs to be bank-aligned (SumOfBank=$nSum_of_banks) in multi-bank setting!",
393 __FILE__, __LINE__) if(!$bBankAligned);
394 }
395 }
396 # 4. Check CODE setting validity
397 my $strROMLimit = &get("PROJECT_EXPECTED_CODE_LIMIT", FEATURE_CONFIG);
398 &config_die("Expected ROM Limit($strROMLimit) in ".&GetMappingPath(FEATURE_CONFIG).
399 " is larger than FS Base(".&CommonUtil::Dec2Hex($nFSBase).")!\n" , __FILE__, __LINE__)
400 if(defined $strROMLimit and hex($strROMLimit) > $nFSBase);
401}
402sub isBlockAligned
403{
404 my ($nBase) = @_;
405 my $BLK_aref = &get("BLK_LIST", CUSTOM_FLASH);
406 my $bBlockAligned = 1;
407 foreach my $nIndex (scalar(@{$BLK_aref})-1 .. 0)
408 {
409 if($nBase >= hex($BLK_aref->[$nIndex]->[0]))
410 {
411 my $nCurrentBlockSize = hex($BLK_aref->[$nIndex]->[1]);
412 if(($nBase-hex($BLK_aref->[$nIndex]->[0])) % $nCurrentBlockSize)
413 { # block aligned should be 0 after %
414 $bBlockAligned = 0;
415 }
416 }
417 }
418 return $bBlockAligned;
419}
420sub isBankAligned
421{
422 my ($nBase) = @_;
423 my $BANK_aref = &get("BANK_LIST", CUSTOM_FLASH);
424 my $bBankAligned = 1;
425 my $nSum_of_banks = 0;
426 foreach my $nIndex (0 .. scalar(@{$BANK_aref})-1)
427 {
428 foreach (0 .. $BANK_aref->[$nIndex]->[1])
429 {
430 $nSum_of_banks += hex($BANK_aref->[$nIndex]->[0]);
431 last if($nSum_of_banks >= $nBase);
432 }
433 last if($nSum_of_banks >= $nBase);
434 }
435 $bBankAligned = ($nSum_of_banks == $nBase);
436 return ($bBankAligned, $nSum_of_banks);
437}
438sub VerifyRAMInfo
439{
440 my ($isDummy) = @_;
441 return if($isDummy);
442 # Check RAM setting validity
443 my $strRamSize = &GetPhysicalExtRAMSize(1);
444 my $strRamLimit = (&FileInfo::is_NonSPNOR()) ? &get("PROJECT_EXPECTED_RAM_LIMIT", FEATURE_CONFIG)
445 : &get("PROJECT_EXPECTED_RAM_LIMIT_NFB", FEATURE_CONFIG) ;
446 &config_die("Expected Ram Limit($strRamLimit) in ".&GetMappingPath(FEATURE_CONFIG).
447 " is larger than physical Ram size($strRamSize)!\n" , __FILE__, __LINE__)
448 if(defined $strRamLimit and hex($strRamLimit) > hex($strRamSize));
449}
450
451#****************************************************************************
452# subroutine: Get_SDS_total_size: To get the SDS total size according to the block size
453# input: $block_size : the block size for SDS
454# $feature_config_ref : a hash reference to query defined values in custom_FeatureConfig.h
455# $feature_option_ref : a hash reference to query feature options in projec.mak
456# return: $sds_total_size
457#****************************************************************************
458sub Get_SDS_total_size
459{
460 my ($block_size, $feature_config_ref, $feature_option_ref) = @_;
461 my $sds_data_size = 0;
462 my $sds_spare_size = 0;
463 my $sds_total_size = 0;
464 $feature_config_ref = &GetSource(FEATURE_CONFIG) if(!defined $feature_config_ref);
465 if(!&FileInfo::is_NonSPNOR($feature_option_ref))
466 {
467 $sds_data_size = (defined $feature_config_ref->{'SDS_MAX_SIZE'}) ? hex($feature_config_ref->{'SDS_MAX_SIZE'}) : 256*1024;
468 $sds_spare_size = (defined $feature_config_ref->{'SDS_RESERVED_SIZE_FOR_BBM'}) ? hex($feature_config_ref->{'SDS_RESERVED_SIZE_FOR_BBM'}) : 256*1024;
469 }
470 else
471 {
472 my $mode = $feature_option_ref->{'MODE'};
473 if(!defined $block_size)
474 {
475 $block_size = &GetBlockSize(&GetPhysicalFlashEnd() -1, __FILE__, __LINE__);
476 }
477 my $two_blocks_size = 2 * $block_size; #the number of blocks for SDS need to be 2N
478
479 if(defined $feature_config_ref->{'SDS_MAX_SIZE'})
480 {
481 $sds_data_size = hex($feature_config_ref->{'SDS_MAX_SIZE'});
482 }
483 elsif(($mode eq 'GSM') or ($mode eq 'GPRS'))
484 {
485 my $sds_temp_size = 0;
486 &config_die("Input parameter: Block Size($block_size) can't be less than 1",__FILE__, __LINE__)
487 if(!defined $block_size or $block_size <= 0);
488 while($sds_temp_size < 32*1024)
489 {
490 $sds_temp_size += $two_blocks_size;
491 }
492 $sds_data_size = ($block_size <= 12*1024) ? $sds_temp_size : $two_blocks_size;
493 }
494 else
495 {
496 my $sds_temp_size = 0;
497 &config_die("Input parameter: Block Size($block_size) can't be less than 1",__FILE__, __LINE__)
498 if(!defined $block_size or $block_size <= 0);
499 while($sds_temp_size < 128*1024)
500 {
501 $sds_temp_size += $two_blocks_size;
502 }
503 $sds_data_size = ($block_size <= 64*1024) ? $sds_temp_size : $two_blocks_size;
504 }
505 }
506 $sds_total_size = $sds_data_size + $sds_spare_size;
507 return $sds_total_size;
508}
509sub GetExtRamSize
510{
511 &DieIfNotParsing(CUSTOM_EMI, __FILE__, __LINE__);
512 return &get("nPROCESSED_RAMSIZE", CUSTOM_EMI);
513}
514sub GetROMSize
515{
516 &DieIfNotParsing(CUSTOM_FLASH, __FILE__, __LINE__);
517 return &get("nCODESize", CUSTOM_FLASH);
518}
519sub GetPhysicalExtRAMSize
520{
521 my ($bNeedString) = @_;
522 my $ExtRamSize = &get("nEMI_EXTSRAM_SIZE", CUSTOM_EMI) ;
523 $ExtRamSize = &get("strEMI_EXTSRAM_SIZE", CUSTOM_EMI) if($bNeedString);
524 return $ExtRamSize;
525}
526sub GetPhysicalFlashEnd
527{
528 &DieIfNotParsing(CUSTOM_FLASH, __FILE__, __LINE__);
529 return &get("nNOR_FLASH_SIZE", CUSTOM_FLASH);
530}
531
532sub GetBlockTable
533{
534 &DieIfNotParsing(CUSTOM_FLASH, __FILE__, __LINE__);
535 return &get("BLK_TABLE", CUSTOM_FLASH);
536}
537
538sub GetFlashInfoLog
539{
540 &DieIfNotParsing(CUSTOM_FLASH, __FILE__, __LINE__);
541 my $Blk = &get("BlkInfoTxt", CUSTOM_FLASH);
542 my $Region = &get("RegionInfoTxt", CUSTOM_FLASH);
543 my $Bank = &get("BankInfoTxt", CUSTOM_FLASH);
544 my $NOR_Density = &get("NOR_FLASH_DENSITY", CUSTOM_FLASH);
545 my $FlashSize = &get("NOR_FLASH_SIZE", CUSTOM_FLASH);
546 return ($Blk, $Region, $Bank, $NOR_Density, $FlashSize);
547}
548
549#****************************************************************************
550# subroutine: GetNextBlockAlignedAddr : Query Next Block-aligned Addr from input Addr
551# input: $nAddr : Address to the next destination
552# $bReturnItselfIfAligned : 1=if $nAddr is block aligned, return itself directly.
553# 0=return next block aligned address against $nAddr
554# $file = __FILE__ , $line_no= __LINE__
555# Output: Next block-aligned addr
556#****************************************************************************
557sub GetNextBlockAlignedAddr
558{
559 my ($nAddr, $bReturnItselfIfAligned, $file, $line_no) = @_;
560 &DieIfNotNonSPNOR($file, $line_no);
561 my $nFlashSize = &GetPhysicalFlashEnd();
562 &config_die("Query Block-aligned addr at ($nAddr) larger than FlashSize($nFlashSize)!", $file, $line_no)
563 if ($nAddr > $nFlashSize);
564
565 my $nNextAddr = undef;
566 my $BLK_aref = &get("BLK_LIST", CUSTOM_FLASH);
567 foreach my $nIndex (scalar(@{$BLK_aref})-1 .. 0)
568 {
569 if($nAddr >= hex($BLK_aref->[$nIndex]->[0]))
570 {
571 my $nCurrentBlockSize = hex($BLK_aref->[$nIndex]->[1]);
572 my $bBlockAligned = ($nAddr - hex($BLK_aref->[$nIndex]->[0])) % $nCurrentBlockSize;
573 if($bBlockAligned)
574 {
575 $nNextAddr = $nAddr;
576 $nNextAddr += $nCurrentBlockSize if(!$bReturnItselfIfAligned);
577 last;
578 }
579 else
580 {
581 my $nBlocks = int(($nAddr - hex($BLK_aref->[$nIndex]->[0])) / $nCurrentBlockSize);
582 $nNextAddr = hex($BLK_aref->[$nIndex]->[0]) + $nBlocks*$nCurrentBlockSize;
583 last;
584 }
585 }
586 }
587 if(!defined $nNextAddr)
588 {
589 my $BlkInfoTxt = &get("BlkInfoTxt", CUSTOM_FLASH);
590 &config_die("Can't find next Block-aligned addr. Please check block table:\n$BlkInfoTxt\n", $file, $line_no);
591 }
592 &config_die("Next Block-aligned addr at $nNextAddr is larger than FlashSize($nFlashSize)!", $file, $line_no)
593 if ($nNextAddr > $nFlashSize);
594 return $nNextAddr;
595}
596sub GetBlockSize #by address
597{
598 my ($nAddr, $file, $line_no) = @_;
599 &DieIfNotNonSPNOR($file, $line_no);
600 my $nFlashSize = &GetPhysicalFlashEnd();
601 &config_die("[GetBlockSize]Current Address($nAddr) can't be larger than FlashSize($nFlashSize)!", $file, $line_no)
602 if ($nAddr > $nFlashSize);
603
604 my $href = &GetBlockTable();
605 my @offset = sort {$b <=> $a} keys %$href;
606 foreach my $i (@offset)
607 {
608 return $href->{$i} if ($nAddr >= $i);
609 }
610 my $BlkInfoTxt = &get("BlkInfoTxt", CUSTOM_FLASH);
611 &config_die("Block table information:\n$BlkInfoTxt\n is not enough for Current Address($nAddr)!", $file, $line_no);
612}
613
614
615sub get
616{
617 my ($strKey, $Source) = @_;
618 my $strValue = undef;
619 if(defined $Source)
620 {
621 &DieIfNotParsing($Source, __FILE__, __LINE__);
622 if(exists $g_MemConfigValues{$Source}->{$strKey})
623 {
624 $strValue = $g_MemConfigValues{$Source}->{$strKey};
625 }
626 }
627 return $strValue;
628}
629sub GetSource
630{
631 my ($Source) = @_;
632 &DieIfNotParsing($Source);
633 return $g_MemConfigValues{$Source}; # return href
634}
635sub GetMemDev #MemoryDevice
636{
637 my ($strKey) = @_;
638 return &get($strKey, MEMORY_DEVICE);
639}
640sub GetFtCfg #FeatureConfig
641{
642 my ($strKey) = @_;
643 return &get($strKey, FEATURE_CONFIG);
644}
645sub GetPath
646{
647 my ($Source) = @_;
648 return &get("PATH", $Source);
649}
650sub GetMappingPath
651{
652 my ($Source) = @_;
653 my $strFileName = basename(&get("PATH", $Source));
654 my $strBoard = &FileInfo::get("BOARD_VER");
655 my $strFlavor = &FileInfo::get("FLAVOR");
656 my $strPath = "pcore/custom/system/$strBoard/$strFlavor/$strFileName\.conf";
657 return $strPath;
658}
659sub is
660{
661 my ($strKey, $strValue, $Source) = @_;
662 my $bIsTheSame = 0;
663 if(defined $Source)
664 {
665 &DieIfNotParsing($Source, __FILE__, __LINE__);
666 $bIsTheSame = 1 if(exists $g_MemConfigValues{$Source}->{uc($strKey)} and
667 $g_MemConfigValues{$Source}->{uc($strKey)} eq $strValue);
668 }
669 return $bIsTheSame;
670}
671sub exist
672{
673 my ($strKey, $Source) = @_;
674 my $bExist = 0;
675 if(defined $Source)
676 {
677 &DieIfNotParsing($Source, __FILE__, __LINE__);
678 $bExist = 1 if(exists $g_MemConfigValues{$Source}->{uc($strKey)});
679 }
680 return $bExist;
681}
682
683sub config_die
684{
685 my ($error_msg, $file, $line_no) = @_;
686 &sysUtil::error_handler($error_msg, $file, $line_no, '[Memory Config]');
687}
688
689sub DieIfNotParsing
690{
691 my ($Source, $file, $line_no) = @_;
692 &config_die("Please parse $Source in advance.", $file, $line_no) if(!exists $g_MemConfigValues{$Source});
693}
694
695sub DieIfNotNonSPNOR
696{
697 my ($file, $line_no) = @_;
698 &config_die("This function is unsupported on non NOR platform.", $file, $line_no) if(!&FileInfo::is_NonSPNOR());
699}