blob: c05a5da7211c2a6fcc8d7e232be184c693a2c6f2 [file] [log] [blame]
yu.dongc33b3072024-08-21 23:14:49 -07001#!/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#* ckScatter.pl
40#*
41#* Project:
42#* --------
43#*
44#*
45#* Description:
46#* ------------
47#* This script parse scatter file and embedded checking rules for it
48#* 1. Load View --- NOR Flash
49#* 2. Execution View --- RAM Device
50#* 3. DSP execution region
51#*
52#* Author:
53#* -------
54#* JI Huang (mtk01077)
55#*
56#****************************************************************************/
57
58#****************************************************************************
59# Included Modules
60#****************************************************************************
61use strict;
62BEGIN { push @INC, "pcore/" , './pcore/tools/' } # add additional library path
63use sysGenUtility; #pm file name without case sensitivity
64use FileInfoParser;
65#****************************************************************************
66# Constants
67#****************************************************************************
68my $CKSCATTER_VERNO = "m0.02";
69 # m0.02 , Support path and filename case sensitive on Linux
70 # m0.01 , skip nfb=SINGLE because it equals to smart phone
71 # v0.48 , skip ckscatter2 check when ALICE_SUPPORT is turned on
72 # v0.47 , No need to check the DSP size sould be 2^N and the alignment restriction of DSP base and DSP length
73 # v0.45 , skip smartphone by using sysgenUtility.pm
74 # v0.44 , skip smartphone if secure turns on
75 # v0.43 , Fix parsing makefile
76 # v0.42 , Remove $$ to support Perl v5.12.*
77 # v0.41 , Support 6255
78 # v0.40 , skip smartphone DSP checking in ckscatter phase 1
79 # v0.39 , Change custom_flash.c to custom_flash.h and skip smartphone in ckscatter phase 2
80 # v0.38 , Refine EMI_EXTSRAM_SIZE pattern-matching to adapt to flexible () and spaces
81 # v0.37 , Skip ckscatter2 check when dcm_compression is turned on because ckscatter cannot see compressed image and will misjudge
82 # v0.36 , Get EXTSRAM_SIZE from custom_EMI_release.h
83 # v0.35 , Support eMMC Booting
84 # v0.34 , Skip SECURE_RO_ME and SECURE_RO_S from load region boundary check because they will be downloaded to CBR region
85 # v0.33 , Skip DSP alignment check for MT6276 shrinking
86 # v0.32 , Skip ckscatter2 check when DUMMY_SCATTER_ENABLE is turned on because invalid memory range will be used in Scatter Gen
87 # v0.31 , To support eMMC Booting
88 # v0.30 , Skip ckscatter2 check when ZIMAGE_SUPPORT is turned on because ckscatter cannot see compressed image and will misjudge
89 # v0.29 , Remove MT6253D
90 # v0.28 , Rename MT6253E/MT6253L as MT6252H/MT6252
91 # v0.27 , Check whether RAM consumption has exceeded DUMMY_END
92 # v0.26 , Move EMI_EXTSRAM_SIZE to custom_EMI_release.h
93 # v0.25 , Resume RAM boundary checking for MT6253E/L
94 # v0.24 , To support MT6253E/L, move EXTSRAM_SIZE to custom_EMI_release.h
95 # v0.23 , To support MT6253DV
96 # v0.22 , To support MT6253E/L, remove RAM boundary check because EXTSRAM_SIZE was moved from custom_EMI.h to custom_EMI_release.h
97 # v0.21 , To support MT6251
98 # v0.20 , Fix sort hex issue
99 # v0.19 , Adapt to NOR_FLASH_DENSITY unit change (Mbit to byte)
100 # v0.18 , Adopt different FAT configuration in custom_MemoryDevice.h
101 # v0.17 , Fix block alignment check errors
102 # v0.16 , Add MT6268 and remove BT/MT check
103 # v0.15 , Add file name and fline number information and unify all auto-gen error messages
104 # v0.14 , NAND_FLASH_BOOTING makefile option is changed
105 # v0.13 , Modify RAM boundary calculation and bypass 6516 boundary check
106 # v0.12 , Modify ~flash_cfg_tmp.c parsing rules for flash_opt.h template change for FOTA
107 # v0.11 , Parse ~flash_cfg_tmp.c only in Phase2 and fix load region calculation issue
108 # v0.10 , Split ckscatter into two phases and arrange checks into each phase
109 # v0.09 , add 2nd phase ckscatter at post-build stage
110 # v0.08 , temporarily remove FAT and load region check due to lack of FAT information and add CODE_PATCH_CODE/DSP_TX/DSP_RX start address alignment check
111 # v0.07 , add FAT and load region overlap check
112 # v0.06 , add SECONDARY_EXTSRAM_DSP_TX
113 # v0.05 , update scatter parser
114 # v0.04 , initial version
115
116#****************************************************************************
117# Input Parameters and Global Variables
118#****************************************************************************
119my $phase = $ARGV[0];
120my $stop_build = $ARGV[1];
121my $SCATTERFILE = $ARGV[2];
122my $LIS_TEMP = $ARGV[3];
123my $FLASH_CFG_TMP = $ARGV[4];
124my $themf = $ARGV[5];
125my $BB_FOLDER = $ARGV[6];
126my $CUSTOM_EMI_H = $ARGV[6] . '/' . "custom_EMI.h";
127my $CUSTOM_EMI_RELEASE_H = $ARGV[6] . '/' . "custom_EMI_release.h";
128my $CUSTOM_FLASH_H = $ARGV[6] . '/' . "custom_flash.h";
129my $DUMMY_SCATTER_ALLOW = $ARGV[7];
130
131my %Scat_Content;
132my %MAKEFILE_OPTIONS;
133my %EMI_H_Value;
134my %FLASH_C_Value;
135my @FLASH_H_Value_BLK_LIST;
136my %FLASH_INFO;
137my %NORFLASH_INFO_BLOCKS_TABLE;
138
139# load/exec regions obtained from scatter file
140my %LoadView;
141my %ExecView;
142
143# load/exec regions obtained from temp lis file
144my %LoadRegion;
145my %ExecRegion;
146
147
148#****************************************************************************
149# 0 >>> parse input parameters and decide ckscatter phase
150#****************************************************************************
151print "phase=$phase, stop_build=$stop_build\n";
152
153 # 0.1 >>> parse Project Make File
154 my $keyname;
155
156 if (!-e $themf)
157 {
158 &error_handler($stop_build, "$themf: NOT exist!", __FILE__, __FILE__, __LINE__) if (!-e $themf);
159 }
160
161 if ($themf =~ /make\/\w+(BT)_\w+.mak/i or $themf =~ /make\/\w+(MT)_\w+.mak/i) {
162 $MAKEFILE_OPTIONS{'type'} = uc($1);
163 }
164
165 open (FILE_HANDLE, "<$themf") or &error_handler($stop_build, "$themf: file error!", __FILE__, __LINE__);
166 while (<FILE_HANDLE>) {
167 if ((/^([^\#]*)\#?.*/) && ($1 =~ /^(\w+)\s*=\s*(.*\S)\s*$/)) {
168 $keyname = lc($1);
169 #defined($MAKEFILE_OPTIONS{$keyname}) && warn "$1 redefined in $themf!\n";
170 $MAKEFILE_OPTIONS{$keyname} = uc($2);
171 }
172 }
173 close (FILE_HANDLE);
174
175 # 0.2 >>> parse key definition in CUSTOM_FLASH_H
176 open (FLASHC_HANDLE, "<$CUSTOM_FLASH_H") or &error_handler($stop_build, "$CUSTOM_FLASH_H: file error!", __FILE__, __LINE__);
177 while (<FLASHC_HANDLE>)
178 {
179 if (/NOR_FLASH_DENSITY:\s*(\w*)/)
180 {
181 $FLASH_INFO{'NOR_FLASH_DENSITY'} = $1;
182 }
183 elsif (/^FLASH_REGIONINFO_VAR_MODIFIER\s+FlashBlockTBL\s+\S+/)
184 {
185 $FLASH_C_Value{'BlockTBLFlag'} ++;
186 }
187 elsif (defined $FLASH_C_Value{'BlockTBLFlag'})
188 {
189 $FLASH_C_Value{'BlockTBLTxt'} .= $_;
190 # debug purpose
191 # print $_;
192 if (/\{\s*(\S+)\s*,\s*(\S+)\s*\}/)
193 {
194 push @FLASH_H_Value_BLK_LIST, $_;
195 }
196 delete $FLASH_C_Value{'BlockTBLFlag'} if (/^\s+EndBlockInfo\s+/);
197 }
198 }
199 close (FLASHC_HANDLE);
200 #&dump_custom_flash_h_values();
201
202 # 0.3 >>> parse key definition in CUSTOM_EMI_RELEASE_H
203 open (EMIRELEASEH_HANDLE, "<$CUSTOM_EMI_RELEASE_H") or &error_handler("$CUSTOM_EMI_RELEASE_H: file error!", __FILE__, __LINE__);
204 while (<EMIRELEASEH_HANDLE>) {
205 if (/^#define EMI_EXTSRAM_SIZE\s+\(\s*\(*\s*\(*\s*(\S+)\)*\s*<<\s*20\s*\)*\s*>>\s*3\s*\)/)
206 {
207 $EMI_H_Value{'EXTSRAM_SIZE'} = $1;
208 }
209 }
210 close (EMIRELEASEH_HANDLE);
211 #&dump_custom_emi_h_values();
212
213 # 0.4 >>> do check in each phase
214 if ($phase == 1)
215 {
216 &ckscatter_phase1();
217 }
218 elsif ($phase == 2)
219 {
220 &ckscatter_phase2();
221 }
222 else
223 {
224 &error_handler($stop_build, "make/pcore/build.mak: Unsupported ckscatter command!", __FILE__, __LINE__);
225 }
226
227 exit;
228
229#****************************************************************************
230# 1 >>> Phase 1
231#****************************************************************************
232sub ckscatter_phase1
233{
234 print "Phase1!\n";
235
236 # 1.1 >>> open and read scatter file, keep the important content in memory
237 open (SCAT_HANDLE, "<$SCATTERFILE") or &error_handler($stop_build, "$SCATTERFILE: file error!", __FILE__, __LINE__);
238 while (<SCAT_HANDLE>) {
239 if (/\(.+\)/) {next;}
240 if (/;/) {s/;.*//;}
241 if (/{/ or /}/ or /\S+/) { $Scat_Content{$.} = $_; }
242 }
243 close (SCAT_HANDLE);
244 #&dump_scatter_file_structure();
245
246 # 1.2 >>> Build the LOAD View List and Execution View List
247 &parse_scatter_file_structure();
248 #&dump_load_view();
249 #&dump_exec_view();
250
251 # 1.3 >>> Check the DSP_TX and DSP_RX execution region
252 if (($MAKEFILE_OPTIONS{'platform'} ne 'MT6276') and ($MAKEFILE_OPTIONS{'platform'} ne 'MT6575') and ($MAKEFILE_OPTIONS{'platform'} ne 'MT6573')) # MT6276 is skipped because these regions no longer obey the alignment rule for shrinking purpose
253 {
254 my $rule = 0;
255
256 foreach my $e ( grep { /EXTSRAM_DSP_[TR]X/ } keys %ExecView )
257 {
258 printf "DSP Checking: $e \n";
259
260 # 1 : No Overlay
261 if ( defined $ExecView{$e}->{'attr'} and $ExecView{$e}->{'attr'} eq "OVERLAY")
262 {
263 printf "$e violate rule , No OVERLAY\n";
264 $rule++;
265 }
266
267 # 2 : Size >= 4KB
268 if ( exists $ExecView{$e}->{'length'} and hex( $ExecView{$e}->{'length'} ) < 4 * 1024 )
269 {
270 my $length = $ExecView{$e}->{'length'};
271 printf "$e violate rule , the Length($length) too small\n";
272 $rule++;
273 }
274 elsif ( not exists $ExecView{$e}->{'length'} )
275 {
276 printf "$e violate rule , please define Length\n";
277 $rule++;
278 next;
279 }
280 # Size must be 4K align
281 my $sz = hex( $ExecView{$e}->{'length'} );
282 if ($sz % (4 * 1024))
283 {
284 printf "$e violate rule , size must be 4K align \n";
285 $rule++;
286 next;
287 }
288
289 # 3 : address need to be assigned
290 if ( defined $ExecView{$e}->{'begin'} and $ExecView{$e} =~ /\+/ )
291 {
292 printf "$e address needs to be assigned\n";
293 $rule++;
294 }
295 elsif ( not defined $ExecView{$e}->{'begin'} )
296 {
297 printf "$e address not calculated, script error , please contact MTK\n";
298 $rule++;
299 }
300 }
301 if ($rule > 0)
302 {
303 &error_handler($stop_build, "$SCATTERFILE: Scatter File DSP check rule fail! Please contact with Scatter File owner!", __FILE__, __LINE__);
304 }
305 }
306
307 # 1.4 >>> CODE_PATCH_CODE, DSP_TX, and DSP_RX start addresses need to be 4KB-aligned
308 {
309 if (exists $MAKEFILE_OPTIONS{'platform'} and (&config_query_arm9($MAKEFILE_OPTIONS{'platform'}) == 1))
310 {
311 foreach my $e ( keys %ExecView )
312 {
313 if (($e =~ /EXTSRAM_DSP_[TR]X/) || ($e eq 'CODE_PATCH_CODE'))
314 {
315 #printf("$e start address = %08X\n", $ExecView{$e}->{'addr'});
316 if (!defined $ExecView{$e}->{'begin'})
317 {
318 &error_handler($stop_build, "$SCATTERFILE: $e lack of start address! Please contact with Scatter File owner!", __FILE__, __LINE__);
319 }
320 if (hex($ExecView{$e}->{'addr'}) % (4*1024) != 0)
321 {
322 &error_handler($stop_build, "$SCATTERFILE: $e start address needs to be 4KB-aligned! Please contact with Scatter File owner!", __FILE__, __LINE__);
323 }
324 }
325 }
326 }
327 }
328
329 # 1.5 >>> BOOTLOADER, __HIDDEN_SECURE_RO, __HIDDEN_FLASHTOOL_CFG, __HIDDEN_CUST_PARA start addresses need to be block-aligned
330 my $SINGLE = ((exists $MAKEFILE_OPTIONS{'nand_flash_booting'} and $MAKEFILE_OPTIONS{'nand_flash_booting'} eq 'SINGLE') or
331 (exists $MAKEFILE_OPTIONS{'emmc_booting'} and $MAKEFILE_OPTIONS{'emmc_booting'} eq 'SINGLE'));
332 if (1 != &FileInfo::is_SmartPhone(\%MAKEFILE_OPTIONS) and 1 != $SINGLE )
333 {
334 &get_block_table();
335 my @offset = sort {$b <=> $a} keys %NORFLASH_INFO_BLOCKS_TABLE;
336
337 foreach ( keys %LoadView )
338 {
339 if (/BOODLOADER|__HIDDEN_SECURE_RO|__HIDDEN_FLASHTOOL_CFG|__HIDDEN_CUST_PARA/)
340 {
341 foreach my $i (@offset)
342 {
343 if (hex($LoadView{$_}->{'begin'}) >= $i)
344 {
345 if (hex($LoadView{$_}->{'begin'}) == $i)
346 {
347 last;
348 }
349 my $tmp = hex($LoadView{$_}->{'begin'}) - $i;
350 while ($tmp > 0)
351 {
352 $tmp -= $NORFLASH_INFO_BLOCKS_TABLE{$i};
353 }
354 if ($tmp != 0)
355 {
356 &error_handler($stop_build, "$SCATTERFILE: $_ start address needs to be block-aligned! Please contact with Scatter File owner!", __FILE__, __LINE__);
357 }
358 else
359 {
360 last;
361 }
362 }
363 }
364 }
365 }
366 }
367}
368
369#****************************************************************************
370# 2 >>> Phase 2
371#****************************************************************************
372sub ckscatter_phase2
373{
374 print "Phase2!\n";
375
376 # 2.10 >>> 6516 series do not have FAT information and thus is bypassed in ckscatter_phase2
377 if (exists $MAKEFILE_OPTIONS{'platform'} and ($MAKEFILE_OPTIONS{'platform'} =~ /6516/ or $MAKEFILE_OPTIONS{'platform'} =~ /6573/ or $MAKEFILE_OPTIONS{'platform'} =~ /6575/))
378 {
379 print "bypass check on Smart Phone!\n";
380 return;
381 }
382
383 # 2.11 >>> BT/MT projects do not contain EXTSRAM and thus is bypassed in ckscatter_phase2
384 if (exists $MAKEFILE_OPTIONS{'type'} and ($MAKEFILE_OPTIONS{'type'} =~ /BT/ or $MAKEFILE_OPTIONS{'type'} =~ /MT/))
385 {
386 print "bypass check on BT/MT!\n";
387 return;
388 }
389
390 # 2.12 >>> When ZIMAGE_SUPPORT or DCM Compression is turned on, ckscatter will misjudge because it cannot recognize compressed case. Besides, another tool will be used to check ZIMAGE_SUPPORT/DCM Compression memory expiration
391 if (exists $MAKEFILE_OPTIONS{'zimage_support'} and ($MAKEFILE_OPTIONS{'zimage_support'} eq 'TRUE'))
392 {
393 print "bypass check when ZIMAGE_SUPPORT = TRUE!\n";
394 return;
395 }
396 if (exists $MAKEFILE_OPTIONS{'dcm_compression_support'} and ($MAKEFILE_OPTIONS{'dcm_compression_support'} eq 'TRUE'))
397 {
398 print "bypass check when dcm_compression_support = TRUE!\n";
399 return;
400 }
401 if (exists $MAKEFILE_OPTIONS{'alice_support'} and ($MAKEFILE_OPTIONS{'alice_support'} eq 'TRUE'))
402 {
403 print "bypass check when alice_support = TRUE!\n";
404 return;
405 }
406
407 # 2.13 >>> When DUMMY_SCATTER_ENABLE is turned on (only available on NOR booting), ckscatter should bypass
408 if ((exists $MAKEFILE_OPTIONS{'nand_flash_booting'} and $MAKEFILE_OPTIONS{'nand_flash_booting'} eq 'NONE') and (!exists $MAKEFILE_OPTIONS{'emmc_booting'} or $MAKEFILE_OPTIONS{'emmc_booting'} eq 'NONE'))
409 {
410 if (exists $MAKEFILE_OPTIONS{'dummy_scatter_enable'} and ($MAKEFILE_OPTIONS{'dummy_scatter_enable'} eq 'TRUE'))
411 {
412 if ($DUMMY_SCATTER_ALLOW == 1)
413 {
414 print "bypass check when DUMMY_SCATTER_ENABLE = TRUE!\n";
415 return;
416 }
417 }
418 }
419
420 # 2.2 >>> open and read temp lis file, keep the important content in memory
421 open (LIS_HANDLE, "<$LIS_TEMP") or &error_handler($stop_build, "$LIS_TEMP: file error!", __FILE__, __LINE__);
422 my $LoadRegion_seq = 0;
423 my $ExecRegion_seq = 0;
424 while (<LIS_HANDLE>) {
425 if (/Load\s+Region\s+(\S+)\s+\(Base:\s+(\w+),\s+Size:\s+(\w+),\s+Max:\s+(\w+)/)
426 {
427# print $_ , "\n";
428 $LoadRegion{$1}->{'Base'} = $2;
429 $LoadRegion{$1}->{'Size'} = $3;
430 $LoadRegion{$1}->{'Max'} = $4;
431 $LoadRegion{$1}->{'Seq'} = $LoadRegion_seq;
432 $LoadRegion_seq++;
433 }
434 elsif (/Execution\s+Region\s+(\S+)\s+\(Base:\s+(\w+),\s+Size:\s+(\w+),\s+Max:\s+(\w+)/)
435 {
436# print $_ , "\n";
437 $ExecRegion{$1}->{'Base'} = $2;
438 $ExecRegion{$1}->{'Size'} = $3;
439 $ExecRegion{$1}->{'Max'} = $4;
440 $ExecRegion{$1}->{'Seq'} = $ExecRegion_seq;
441 $ExecRegion_seq++;
442 }
443 }
444 close (LIS_HANDLE);
445 &dump_temp_lis_structure();
446 &error_handler($stop_build, "$LIS_TEMP: LIS file empty! Please resolve link errors first!", __FILE__, __LINE__) if (($LoadRegion_seq == 0) && ($ExecRegion_seq == 0));
447
448 # 2.3 >>> parse key definition in ~flash_cfg_tmp.c
449 open (FLASH_TMP_HANDLE, "<$FLASH_CFG_TMP") or &error_handler($stop_build, "$FLASH_CFG_TMP: file error!", __FILE__, __LINE__);
450 while (<FLASH_TMP_HANDLE>) {
451 if (/int\s+flash_base_address\s*=\s*(.+);/s)
452 {
453 my $flash_base_address = `perl -e "printf ($1)" 2>&1`;
454 $FLASH_INFO{'FLASH_BASE_ADDRESS'} = sprintf("%X", $flash_base_address);
455 }
456 elsif (/int\s+allocated_fat_space\s*=\s*(.+);/s)
457 {
458 my $allocated_fat_space = `perl -e "printf ($1)" 2>&1`;
459 $FLASH_INFO{'ALLOCATED_FAT_SPACE'} = sprintf("%X", $allocated_fat_space);
460 }
461 }
462 close (FLASH_TMP_HANDLE);
463 #&dump_flash_cfg_tmp_values();
464
465 # 2.4 >>> check size limit validation
466 my $flash_size = &comp_flash_size();
467 my $load_length = &comp_load_length();
468 my ($ram_size, $ram_boundary, $ram_size_dummy_end, $ram_boundary_before_dummy_end);
469 if ($MAKEFILE_OPTIONS{'platform'} ne 'MT6251')
470 {
471 $ram_size = &comp_ram_size();
472 $ram_boundary = &comp_ram_boundary();
473 $ram_size_dummy_end = &comp_ram_size_dummy_end();
474 $ram_boundary_before_dummy_end = &comp_ram_boundary_before_dummy_end($ram_size_dummy_end);
475 }
476
477 #printf "%x, %x, %x, %x\n", $flash_size, $ram_size, $load_length, $ram_boundary;
478
479 if ((exists $MAKEFILE_OPTIONS{'nand_flash_booting'} and $MAKEFILE_OPTIONS{'nand_flash_booting'} ne 'NONE') or (exists $MAKEFILE_OPTIONS{'emmc_booting'} and $MAKEFILE_OPTIONS{'emmc_booting'} ne 'NONE'))
480 {
481 printf "LOAD VIEW , bypass check on NAND FLASH BOOTING\n";
482 printf "EXEC VIEW , Physical Device Density 0x%x , Scatter File Configuration 0x%x , Scatter File DUMMY_END 0x%x , Scatter File Usage 0x%x\n",
483 $ram_size , $ram_boundary, $ram_size_dummy_end, $ram_boundary_before_dummy_end;
484 if ($ram_size < $ram_boundary)
485 {
486 &error_handler($stop_build, "$SCATTERFILE: RAM consumption has exceeded its upper bound! Please turn off some features or change to a larger MCP!", __FILE__, __LINE__);
487 }
488 if ($ram_size_dummy_end < $ram_boundary_before_dummy_end)
489 {
490 &error_handler($stop_build, "$SCATTERFILE: RAM consumption has exceeded its upper bound! Please turn off some features or change to a larger MCP!", __FILE__, __LINE__);
491 }
492 if ($ram_size > $ram_boundary and ($ram_size - $ram_boundary) >= 1024 * 1024)
493 {
494 print "Warnning : RAM / Exec View configure waste at least 1MB\n";
495 }
496 }
497 else
498 {
499 printf "LOAD VIEW , Physical Device Density 0x%x , Scatter File Configuration 0x%x\t%s\n",
500 $flash_size, $load_length, ($flash_size >= $load_length)? "PASS" : "ERROR";
501 if ($flash_size < $load_length)
502 {
503 &error_handler($stop_build, "$SCATTERFILE: ROM consumption has exceeded its upper bound! Please turn off some features or change to a larger MCP!", __FILE__, __LINE__);
504 }
505 if (($MAKEFILE_OPTIONS{'platform'} ne 'MT6251'))
506 {
507 printf "EXEC VIEW , Physical Device Density 0x%x , Scatter File Configuration 0x%x , Scatter File DUMMY_END 0x%x , Scatter File Usage 0x%x\n",
508 $ram_size , $ram_boundary, $ram_size_dummy_end, $ram_boundary_before_dummy_end;
509 if ($ram_size < $ram_boundary)
510 {
511 &error_handler($stop_build, "$SCATTERFILE: RAM consumption has exceeded its upper bound! Please turn off some features or change to a larger MCP!", __FILE__, __LINE__);
512 }
513 if ($ram_size_dummy_end < $ram_boundary_before_dummy_end)
514 {
515 &error_handler($stop_build, "$SCATTERFILE: RAM consumption has exceeded its upper bound! Please turn off some features or change to a larger MCP!", __FILE__, __LINE__);
516 }
517 }
518 if ($flash_size > $load_length and ($flash_size - $load_length) >= 1024 * 1024)
519 {
520 print "Warnning : NOR flash / Load View configure waste at least 1MB\n";
521 }
522 if ($MAKEFILE_OPTIONS{'platform'} ne 'MT6251')
523 {
524 if ($ram_size > $ram_boundary and ($ram_size - $ram_boundary) >= 1024 * 1024)
525 {
526 print "Warnning : RAM / Exec View configure waste at least 1MB\n";
527 }
528 }
529 }
530}
531
532#****************************************************************************
533# subroutine: SCHEME Configure Routines :: Query :: ARM9 Family
534# input: BB chip
535# Output: whether this chip belongs to ARM9 Family
536#****************************************************************************
537sub config_query_arm9
538{
539 my ($bb) = @_;
540 my %BBtbl_ARM9_Family =
541 (
542 'MT6235' => 1,
543 'MT6235B' => 1,
544 'MT6238' => 1,
545 'MT6239' => 1,
546 'MT6268' => 1,
547 );
548 return $BBtbl_ARM9_Family{$bb};
549}
550
551#****************************************************************************
552# subroutine: comp_flash_size
553# return: EMI value
554#****************************************************************************
555sub comp_flash_size
556{
557 my $flash_limit;
558 if ((exists $MAKEFILE_OPTIONS{'nand_flash_booting'} and $MAKEFILE_OPTIONS{'nand_flash_booting'} ne 'NONE') or (exists $MAKEFILE_OPTIONS{'emmc_booting'} and $MAKEFILE_OPTIONS{'emmc_booting'} ne 'NONE'))
559 {
560 $flash_limit = 0;
561 }
562 elsif (exists $MAKEFILE_OPTIONS{'system_drive_on_nand'} and $MAKEFILE_OPTIONS{'system_drive_on_nand'} eq "TRUE")
563 {
564 $flash_limit = hex($FLASH_INFO{'NOR_FLASH_DENSITY'});
565 }
566 else
567 {
568 $flash_limit = hex($FLASH_INFO{'FLASH_BASE_ADDRESS'});
569 }
570 return $flash_limit;
571}
572
573#****************************************************************************
574# subroutine: comp_ram_size
575# return: EMI value
576#****************************************************************************
577sub comp_ram_size
578{
579 $EMI_H_Value{'EXTSRAM_SIZE'} =~ s/\(//;
580 $EMI_H_Value{'EXTSRAM_SIZE'} =~ s/\)//;
581
582 return $EMI_H_Value{'EXTSRAM_SIZE'} * 1024 * 1024 / 8;
583}
584
585#****************************************************************************
586# subroutine: comp_ram_size_dummy_end
587# return: RAM size before DUMMY_END or DSP_TXRX
588#****************************************************************************
589sub comp_ram_size_dummy_end
590{
591 my $extsram_ram_size_before_dummy_end;
592 if (exists $ExecRegion{'CODE_PATCH_CODE'})
593 {
594 $extsram_ram_size_before_dummy_end = hex($ExecRegion{'CODE_PATCH_CODE'}->{'Base'});
595 }
596 elsif (exists $ExecRegion{'CACHED_CODE_PATCH_CODE'})
597 {
598 $extsram_ram_size_before_dummy_end = hex($ExecRegion{'CACHED_CODE_PATCH_CODE'}->{'Base'});
599 }
600 elsif (exists $ExecRegion{'DUMMY_END'})
601 {
602 $extsram_ram_size_before_dummy_end = hex($ExecRegion{'DUMMY_END'}->{'Base'});
603 }
604 elsif (exists $ExecRegion{'CACHED_DUMMY_END'})
605 {
606 $extsram_ram_size_before_dummy_end = hex($ExecRegion{'CACHED_DUMMY_END'}->{'Base'});
607 }
608 elsif (exists $ExecRegion{'EXTSRAM_DSP_TX'})
609 {
610 $extsram_ram_size_before_dummy_end = hex($ExecRegion{'EXTSRAM_DSP_TX'}->{'Base'});
611 }
612 elsif (exists $ExecRegion{'SECONDARY_EXTSRAM_DSP_TX'})
613 {
614 $extsram_ram_size_before_dummy_end = hex($ExecRegion{'SECONDARY_EXTSRAM_DSP_TX'}->{'Base'});
615 }
616 else
617 {
618 die "Unknown Scatter File Structure";
619 }
620
621 printf "RAM DUMMY END , %x\n" , $extsram_ram_size_before_dummy_end;
622
623 return $extsram_ram_size_before_dummy_end;
624}
625
626#****************************************************************************
627# subroutine: comp_load_length
628# return: LoadView
629#****************************************************************************
630sub comp_load_length
631{
632 my @region_list = sort { hex($LoadRegion{$b}->{'Base'}) <=> hex($LoadRegion{$a}->{'Base'}) } keys %LoadRegion;
633 my $last_load_region;
634 for (0..$#region_list)
635 {
636 if (($region_list[$_] ne 'SECURE_RO_ME') and ($region_list[$_] ne 'SECURE_RO_S'))
637 {
638 $last_load_region = $region_list[$_];
639 last;
640 }
641 }
642 return ((hex($LoadRegion{$last_load_region}->{'Base'})+hex($LoadRegion{$last_load_region}->{'Size'})) & (~0xF8000000));
643}
644
645#****************************************************************************
646# subroutine: get_regions_reside_EXTSRAM
647#****************************************************************************
648sub get_regions_reside_EXTSRAM
649{
650 my @regions = (sort { hex($ExecRegion{$a}->{'Base'}) <=> hex($ExecRegion{$b}->{'Base'}) } keys %ExecRegion);
651 my $EXTSRAM_Addr;
652
653 for (my $i=0; $i <= $#regions; $i++)
654 {
655 if ($regions[$i] =~ /EXTSRAM/) # find the start of EXTSRAM
656 {
657 $EXTSRAM_Addr = $ExecRegion{$regions[$i]}->{'Base'};
658 }
659 }
660 @regions = grep { (hex($ExecRegion{$_}->{'Base'}) & 0xF8000000) == (hex($EXTSRAM_Addr) & 0xF8000000) } keys %ExecRegion;
661
662 return @regions;
663}
664
665#****************************************************************************
666# subroutine: comp_ram_boundary
667# return: LoadView
668#****************************************************************************
669sub comp_ram_boundary
670{
671 my @regions1 = sort { hex($ExecRegion{$a}->{'Base'}) <=> hex($ExecRegion{$b}->{'Base'}) } &get_regions_reside_EXTSRAM();
672
673 my $extsram_baseaddr = hex($ExecRegion{ $regions1[0] }->{ 'Base' });
674 #
675 my $extsram_limitaddr;
676 if (exists $ExecRegion{'DUMMY_END'})
677 {
678 $extsram_limitaddr = hex($ExecRegion{'DUMMY_END'}->{'Base'});
679 }
680 elsif (exists $ExecRegion{'EXTSRAM_DSP_RX'})
681 {
682 $extsram_limitaddr = hex($ExecRegion{'EXTSRAM_DSP_RX'}->{'Base'}) + hex($ExecRegion{'EXTSRAM_DSP_RX'}->{'Size'});
683 }
684 elsif (exists $ExecRegion{'SECONDARY_EXTSRAM_DSP_RX'})
685 {
686 $extsram_limitaddr = hex($ExecRegion{'SECONDARY_EXTSRAM_DSP_RX'}->{'Base'}) + hex($ExecRegion{'SECONDARY_EXTSRAM_DSP_RX'}->{'Size'});
687 }
688 elsif (exists $ExecRegion{'CODE_PATCH_CODE'})
689 {
690 $extsram_limitaddr = hex($ExecRegion{'CODE_PATCH_CODE'}->{'Base'}) + hex($ExecRegion{'CODE_PATCH_CODE'}->{'Size'});
691 }
692 elsif (exists $ExecRegion{'CACHED_DUMMY_END'})
693 {
694 $extsram_limitaddr = hex($ExecRegion{'CACHED_DUMMY_END'}->{'Base'}) & (~0xf0000000);
695 }
696 elsif (exists $ExecRegion{'EXTSRAM'} and exists $ExecRegion{'EXTSRAM'}->{'Size'})
697 {
698 $extsram_limitaddr = hex($ExecRegion{'EXTSRAM'}->{'Base'}) + hex($ExecRegion{'EXTSRAM'}->{'Size'});
699 }
700 elsif (exists $ExecRegion{'SECONDARY_EXTSRAM'} and exists $ExecRegion{'SECONDARY_EXTSRAM'}->{'Size'})
701 {
702 $extsram_limitaddr = hex($ExecRegion{'SECONDARY_EXTSRAM'}->{'Base'}) + hex($ExecRegion{'SECONDARY_EXTSRAM'}->{'Size'});
703 }
704 else
705 {
706 die "Unknown Scatter File Structure";
707 }
708
709 #printf "RAM %x , %x\n" , $extsram_baseaddr , $extsram_limitaddr;
710
711 return ($extsram_limitaddr & (~0xf8000000));
712}
713
714#****************************************************************************
715# subroutine: comp_ram_boundary_before_dummy_end
716# return: RAM boundary before DUMMY_END
717#****************************************************************************
718sub comp_ram_boundary_before_dummy_end
719{
720 my ($ram_dummy_end) = @_;
721 my @regions1 = sort { hex($ExecRegion{$b}->{'Seq'}) <=> hex($ExecRegion{$a}->{'Seq'}) } &get_regions_reside_EXTSRAM();
722
723 #
724 my $extsram_limitaddr;
725 my $dummy_end_reached = 0;
726 foreach my $region (@regions1)
727 {
728 if ($dummy_end_reached == 1)
729 {
730 $extsram_limitaddr = hex($ExecRegion{$region}->{'Base'}) + hex($ExecRegion{$region}->{'Size'});
731 last;
732 }
733 if (hex($ExecRegion{$region}->{'Base'}) == $ram_dummy_end)
734 {
735 $dummy_end_reached = 1;
736 }
737 }
738
739 printf "RAM Limit before DUMMY_END , %x\n" , $extsram_limitaddr;
740
741 return $extsram_limitaddr;
742}
743
744#****************************************************************************
745# subroutine: get_block_table
746# return: block table hash
747#****************************************************************************
748sub get_block_table
749{
750 if ($#FLASH_H_Value_BLK_LIST >= 0)
751 {
752 my %blk_href;
753
754 foreach(@FLASH_H_Value_BLK_LIST)
755 {
756 if (/\{(0x\w+),\s*(0x\w+)\}/)
757 {
758 $NORFLASH_INFO_BLOCKS_TABLE{hex($1)} = hex($2);
759 }
760 }
761 }
762}
763
764#****************************************************************************
765# subroutine: dump_exec_view
766# return: all %LoadView ; key = RegionName , value = hash ref , begin , attr , length
767#****************************************************************************
768sub dump_exec_view
769{
770 print "=== EXEC VIEW ===\n";
771 foreach my $region_name (sort { $ExecView{$a}->{'seq'} <=> $ExecView{$b}->{'seq'} } keys %ExecView)
772 {
773 print $region_name, "\t", $ExecView{$region_name}->{'begin'}, "\n";
774 }
775}
776
777#****************************************************************************
778# subroutine: dump_load_view
779# return: all %LoadView ; key = RegionName , value = hash ref , begin , attr , length
780#****************************************************************************
781sub dump_load_view
782{
783 print "=== LOAD VIEW ===\n";
784 foreach my $region_name (sort { $LoadView{$a}->{'seq'} <=> $LoadView{$b}->{'seq'} } keys %LoadView)
785 {
786 print $region_name, "\t", $LoadView{$region_name}->{'begin'}, "\n";
787 }
788}
789
790#****************************************************************************
791# subroutine: parse_region_string
792# input: reference to %LoadView or %ExecView ; Region Name start address string
793# return: %LoadView ; key = RegionName , value = hash ref , begin , attr , length
794#****************************************************************************
795my $sequence = 0;
796sub parse_region_string
797{
798 my ($hash_ref, $string) = @_;
799 my %tmp;
800
801 if ($string =~ m/(\S+)\s+(\S+)\s+OVERLAY\s+(\S+)/)
802 {
803 #print 'PATTERN1', "\t", $1, "\t", $2, "\t", 'OVERLAY', "\t", $3 , "\n";
804 $tmp{'seq'} = ++$sequence;
805 $tmp{'attr'} = "OVERLAY";
806 $tmp{'begin'} = $2;
807 $tmp{'length'} = $3;
808 $hash_ref->{$1} = \%tmp;
809 }
810 elsif ($string =~ m/(\S+)\s+(\S+)\s+ABSOLUTE\s+(\S+)/)
811 {
812 #print 'PATTERN1', "\t", $1, "\t", $2, "\t", 'ABSOLUTE', "\t", $3 , "\n";
813 $tmp{'seq'} = ++$sequence;
814 $tmp{'attr'} = "ABSOLUTE";
815 $tmp{'begin'} = $2;
816 $tmp{'length'} = $3;
817 $hash_ref->{$1} = \%tmp;
818 }
819 elsif ($string =~ m/(\S+)\s+(\S+)\s+FIXED\s+(\S+)/)
820 {
821 #print 'PATTERN1', "\t", $1, "\t", $2, "\t", 'FIXED', "\t", $3, "\n";
822 $tmp{'seq'} = ++$sequence;
823 $tmp{'attr'} = "FIXED";
824 $tmp{'begin'} = $2;
825 $tmp{'length'} = $3;
826 $hash_ref->{$1} = \%tmp;
827 }
828 elsif ($string =~ m/(\S+)\s+(\S+)\s+(\S+)/)
829 {
830 #print 'PATTERN3', "\t", $1, "\t", $2, "\t", $3, "\n";
831 $tmp{'seq'} = ++$sequence;
832 $tmp{'begin'} = $2;
833 $tmp{'length'} = $3;
834 $hash_ref->{$1} = \%tmp;
835 }
836 elsif ($string =~ m/(\S+)\s+(\S+)/)
837 {
838 #print 'PATTERN4', "\t", $1, "\t", $2, "\n";
839 $tmp{'seq'} = ++$sequence;
840 $tmp{'begin'} = $2;
841 $hash_ref->{$1} = \%tmp;
842 }
843 else
844 {
845 warn "UNKNOWN PATTERN : $string";
846 }
847}
848
849#****************************************************************************
850# subroutine: parse_scatter_file_structure
851# return: %LoadView , %ExecView
852#****************************************************************************
853sub parse_scatter_file_structure
854{
855 my $last_line_no;
856 my $text_line;
857 my $view=0; #counter , 1 = load view , 2 = exec view
858 foreach my $file_line_no (sort {$a <=> $b} keys %Scat_Content)
859 {
860 $text_line = $Scat_Content{$file_line_no};
861 if ($text_line =~ m/{/)
862 {
863 if ($view > 1)
864 {
865 &error_handler($stop_build, "$SCATTERFILE: Unrecognizable view at $file_line_no! Please contact with Scatter File owner!", __FILE__, __LINE__);
866 }
867 $view++;
868 if (not defined $last_line_no)
869 {
870 &error_handler($stop_build, "$SCATTERFILE: No region name detected before $file_line_no!Please contact with Scatter File owner!", __FILE__, __LINE__);
871 }
872 &parse_region_string( ($view == 1) ? \%LoadView : \%ExecView , $Scat_Content{$last_line_no} );
873 }
874 elsif ($text_line =~ m/}/)
875 {
876 $view--;
877 if ($view < 0)
878 {
879 &error_handler($stop_build, "$SCATTERFILE: Unrecognizable view at $file_line_no!Please contact with Scatter File owner!", __FILE__, __LINE__);
880 }
881 }
882 $last_line_no = $file_line_no;
883 }
884}
885
886#****************************************************************************
887# subroutine: error_handler
888# return: none
889#****************************************************************************
890sub error_handler
891{
892 my ($todie, $error_msg, $file, $line_no) = @_;
893
894# print $todie, "\n";
895
896 my $final_error_msg = "CKSCATTER ERROR: $error_msg at $file line $line_no\n";
897 print $final_error_msg;
898 die $final_error_msg if ($todie eq 'TRUE');
899}
900
901#****************************************************************************
902# subroutine: dump_scatter_file_structure
903# return: none
904#****************************************************************************
905sub dump_scatter_file_structure
906{
907 foreach my $file_line_no (sort {$a <=> $b} keys %Scat_Content)
908 {
909 print $file_line_no, "\t", $Scat_Content{$file_line_no};
910 }
911}
912
913#****************************************************************************
914# subroutine: dump_temp_lis_structure
915# return: none
916#****************************************************************************
917sub dump_temp_lis_structure
918{
919 print "Dumping temp lis structure: \n";
920 foreach my $lv (sort {hex($LoadRegion{$a}->{'Base'}) <=> hex($LoadRegion{$a}->{'Base'})} keys %LoadRegion)
921 {
922 print $lv, "\t", $LoadRegion{$lv}->{'Base'}, "\t", $LoadRegion{$lv}->{'Size'}, "\t", $LoadRegion{$lv}->{'Max'}, "\t", $LoadRegion{$lv}->{'Seq'}, "\n";
923 }
924 foreach my $ev (sort {hex($ExecRegion{$a}->{'Base'}) <=> hex($ExecRegion{$a}->{'Base'})} keys %ExecRegion)
925 {
926 print $ev, "\t", $ExecRegion{$ev}->{'Base'}, "\t", $ExecRegion{$ev}->{'Size'}, "\t", $ExecRegion{$ev}->{'Max'}, "\t", $ExecRegion{$ev}->{'Seq'}, "\n";
927 }
928}
929
930#****************************************************************************
931# subroutine: dump_custom_emi_h_values
932# return: none
933#****************************************************************************
934sub dump_custom_emi_h_values
935{
936 foreach my $key (sort keys %EMI_H_Value)
937 {
938 print $key, "\t", $EMI_H_Value{$key} , "\n";
939 }
940}
941
942#****************************************************************************
943# subroutine: dump_custom_flash_h_values
944# return: none
945#****************************************************************************
946sub dump_custom_flash_h_values
947{
948 foreach (@FLASH_H_Value_BLK_LIST)
949 {
950 print "$_\n";
951 }
952}
953
954#****************************************************************************
955# subroutine: dump_flash_cfg_tmp_values
956# return: none
957#****************************************************************************
958sub dump_flash_cfg_tmp_values
959{
960 foreach my $key (sort keys %FLASH_INFO)
961 {
962 print $key, "\t", $FLASH_INFO{$key} , "\n";
963 }
964}
965