blob: 34fa86efbe55382763e35cbae60c34d9674dc9d7 [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#*
38#* Filename:
39#* ---------
40#* ckSysDrv.pl
41#*
42#* Project:
43#* --------
44#* Maui_Software
45#*
46#* Description:
47#* ------------
48#* This script parse prepocessed fs_quota.c and nvram_user_config.c to
49#* 1. check if system drive space is enough
50#* 2. display current flash usage
51#*
52#* Author:
53#* -------
54#* Sherman Wang (mtk00590)
55#*
56#*============================================================================
57#* HISTORY
58#* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
59#*------------------------------------------------------------------------------
60#* $Revision: $
61#* $Modtime: $
62#* $Log: $
63#*
64#*
65#*------------------------------------------------------------------------------
66#* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
67#*============================================================================
68#****************************************************************************/
69
70#****************************************************************************
71# Included Modules
72#****************************************************************************
73BEGIN { push @INC , './tools/' } # add additional library path
74use strict;
75use Getopt::Std;
76use POSIX;
77use auto_adjust_mem; # pm file name without case sensitivity
78use constant OWNER => "mtk02704";
79
80#****************************************************************************
81# Constants
82#****************************************************************************
83my $DebugPrint = 0;
84# 0001(1)
85# 0010(2)
86# 0100(4): NVRAM/Quota handling details
87# 1000(8): NVRAM/Quota
88
89#****************************************************************************
90# Usage
91#****************************************************************************
92sub usage
93{
94 print "perl ckSysDrv.pl <Preprocessed fs_quota.c> <Preprocessed nvram_user_config.c>\n";
95 exit(0);
96}
97
98#****************************************************************************
99# parsing command arguments
100#****************************************************************************
101my %option = ();
102if (!getopts('hdc:', \%option) or $option{'h'})
103{
104 &usage;
105 exit(0);
106}
107$DebugPrint = 1 if $option{'d'};
108
109my $FLASH_CFG = $ARGV[0];
110my $FS_STAT = $ARGV[1];
111my $NVRAM_STAT = $ARGV[2];
112my $FEATURE_OVERLOAD = $ARGV[3];
113my $SYSTEM_DRIVE_ON_NAND = $ARGV[4];
114my $NVRAM_PSEUDO_MERGE = $ARGV[5];
115my $BOARD_FOLDER = $ARGV[6];
116my $LINK_INFO = $ARGV[7];
117my $PROJECT = $ARGV[8];
118my $AAPMCLOG = $ARGV[9];
119
120my %cluster_multiple = ();
121
122print "[CkSysDrv] Starting...\n" if ($DebugPrint & 1);
123print "[CkSysDrv] ARGV# = $#ARGV\n" if($DebugPrint & 1);
124my $j = 0;
125my %arguments = (
126 0 => "\$FLASH_CFG",
127 1 => "\$FS_STAT",
128 2 => "\$NVRAM_STAT",
129 3 => "\$FEATURE_OVERLOAD",
130 4 => "\$SYSTEM_DRIVE_ON_NAND",
131 5 => "\$NVRAM_PSEUDO_MERGE",
132 6 => "\$BOARD_FOLDER",
133 7 => "\$LINK_INFO",
134 8 => "\$PROJECT",
135 9 => "\$AAPMCLOG",
136);
137for (; $j < $#ARGV + 1 ; $j++)
138{
139 printf("\t\t\$ARGV[$j]: $arguments{$j} = %s\n", $ARGV[$j]) if($DebugPrint & 1);
140}
141
142#****************************************************************************
143# Parse preprocessed custom_MemoryDevice.h and custom_EMI.h
144#****************************************************************************
145open(FLASH_CFG, "<$FLASH_CFG") or cksysdrv_die(ERR::ERR_UNEXPECTED, "cannot open FLASH_CFG: $FLASH_CFG\n", __FILE__, __LINE__);
146
147my $backup = $/;
148undef $/;
149my $reading = <FLASH_CFG>;
150close FLASH_CFG;
151
152# common variables
153my $fs_auto_config_support;
154my $allocated_fat_space; # in Byte
155my $first_partition_sectors; # in Sector
156my $first_partition_size; # in Byte
157my $system_drive_sectors; # in Sector
158my $system_drive_size; # in Byte
159my $flash_base_address;
160my $system_drive_location;
161 my $ON_NAND = 1;
162 my $ON_NOR = 2;
163 my $ON_EMMC = 3;
164my $app_storage_in_sys_drv;
165
166my $original_base_address;
167my $original_fat_space;
168my $original_first_partition_sectors;
169
170my $free_space = -1;
171my $cksysdrv_enabled;
172my $DEV_PREFIX; # prefix of macros in custom_MemoryDevice.h
173my $DEV_TYPE; # memory type of debug info
174
175# NOR flash specific variables
176my $fs_low_cost_support;
177my $nvram_custom_cfg_max_record_sector_num;
178my $nor_regions;
179my $nor_reserved_blocks;
180my $nor_single_bank_support = 0;
181my $nor_sector_size;
182my $nor_max_blk_size = 0; # in Byte
183my $nor_drive_overhead = 0; # in Byte
184my $blockheader_overhead = 0;
185my $blockheader_overhead_total = 0;
186my $nor_min_reserved_blocks = 2;
187my $nor_extra_reserved_space = 0;
188my $nor_extra_reserved_space_for_power_loss = 0;
189my $nor_protection_mode_reserved_space = 0;
190
191# NAND flash specific variables
192my $nand_block_size; # KB
193my $fat_nand_block_num;
194my $nand_log_block_num;
195my $fat_nand_region_num;
196my $nand_fdm_version;
197
198#
199my $code_boundary_addr=0; #in Byte
200 my $release_all_free = -1; #flag
201my $alignment; #in Byte
202my $code_shortage_size;
203my $short_block;
204my $short_block_size;
205my $diff;
206my $cluster_size; # in Byte
207
208# log
209my @log_buf = ();
210my %error_code = (
211 ERR::NO_MODIFY => "ERR::NO_MODIFY",
212 ERR::MODIFY_SUCCESS => "ERR::MODIFY_SUCCESS",
213 ERR::CANNOT_ADJUST => "ERR::CANNOT_ADJUST",
214 ERR::AAPMCLOG_SUCCESS => "ERR::AAPMCLOG_SUCCESS",
215 ERR::ERR_MODIFYFAIL => "ERR::ERR_MODIFYFAIL",
216 ERR::ERR_UNEXPECTED => "ERR::ERR_UNEXPECTED",
217 ERR::ERR_MODIFYDUPLICATED => "ERR::ERR_MODIFYDUPLICATED",
218);
219
220print "[CkSysDrv] Read common configurations...\n" if ($DebugPrint &1);
221
222#---------------------------------------------------
223# Read common variables
224#---------------------------------------------------
225
226# macth int cksysdrv_enabled = 0 ;
227if ($reading =~ /int\s+cksysdrv_enabled\s*=\s*(.*);/)
228{
229 $cksysdrv_enabled = `perl -e "print ($1)" 2>&1`;
230
231 if ($cksysdrv_enabled == 0)
232 {
233 print "[ckSysDrv] ckSysDrv is disabled!";
234
235 exit(0);
236 }
237}
238
239# macth int fs_auto_config_support = 0 ;
240if ($reading =~ /int\s+fs_auto_config_support\s*=\s*(.*);/)
241{
242 $fs_auto_config_support = `perl -e "print ($1)" 2>&1`;
243
244 if ($fs_auto_config_support == 0)
245 {
246 print "[ckSysDrv] Auto adjust is disabled!\n";
247 }
248
249 if ($#ARGV < 6)
250 {
251 $fs_auto_config_support = 0;
252 }
253 print "[ckSysDrv] \$fs_auto_config_support = $fs_auto_config_support\n";
254}
255
256
257
258# macth int system_drive_location = 0 ;
259if ($reading =~ /int\s+system_drive_location\s*=\s*(.*);/)
260{
261 $system_drive_location = `perl -e "print ($1)" 2>&1`;
262 if ($system_drive_location == $ON_NOR)
263 {
264 print("[Input] System Drive Type = NOR\n")if ($DebugPrint &1);
265 $DEV_PREFIX = "NOR_BOOTING_NOR_";
266 $DEV_TYPE = "NOR";
267 }
268 elsif ($system_drive_location == $ON_NAND)
269 {
270 print("[Input] System Drive Type = NAND\n")if ($DebugPrint &1);
271 $DEV_PREFIX = "NAND_BOOTING_NAND_";
272 $DEV_TYPE = "NAND";
273 }
274 elsif ($system_drive_location == $ON_EMMC)
275 {
276 print("[Input] System Drive Type = EMMC\n")if ($DebugPrint &1);
277 $DEV_PREFIX = "EMMC_BOOTING_UP_";
278 $DEV_TYPE = "EMMC";
279 }
280 else
281 {
282 cksysdrv_die(ERR::ERR_UNEXPECTED, "System drive location is unrecoginzed!", __FILE__, __LINE__);
283 }
284
285
286}
287else
288{
289 cksysdrv_die(ERR::ERR_UNEXPECTED, "System drive location is unrecoginzed!", __FILE__, __LINE__);
290}
291
292#match APP_STORAGE_IN_SYS_DRV
293if ($reading =~ /int\s+app_storage_in_sys_drv\s*=\s*(.*);/)
294{
295 $app_storage_in_sys_drv = `perl -e "print ($1)" 2>&1`;
296 printf("\t[Input] APP_STORAGE_IN_SYS_DRV: $app_storage_in_sys_drv\n") if ($DebugPrint &1);
297}
298
299if ($system_drive_location == $ON_NOR || $system_drive_location == $ON_NAND)
300{
301 # macth int flash_base_address = 0x00E00000 ;
302 if ($reading =~ /int\s+flash_base_address\s*=\s*(.*);/)
303 {
304 $flash_base_address = `perl -e "print ($1)" 2>&1`;
305 $original_base_address = $flash_base_address;
306 printf("[Input] %sFS_BASE_ADDRESS = 0x%08X\n", $DEV_PREFIX, $flash_base_address)if ($DebugPrint &1);
307 }
308 else
309 {
310 cksysdrv_die(ERR::ERR_UNEXPECTED, "FS base address is NOT found!", __FILE__, __LINE__);
311 }
312
313 # macth int allocated_fat_space = 0x00200000 ;
314 if ($reading =~ /int\s+allocated_fat_space\s*=\s*(.*);/)
315 {
316 $allocated_fat_space = `perl -e "print ($1)" 2>&1`;
317 $original_fat_space = $allocated_fat_space;
318 printf("[Input] %sFS_SIZE = 0x%08X\n", $DEV_PREFIX, $allocated_fat_space)if ($DebugPrint &1);
319 }
320 else
321 {
322 cksysdrv_die(ERR::ERR_UNEXPECTED, "FS total size is NOT found!", __FILE__, __LINE__);
323 }
324
325 # macth int partition_sectors = 0 ;
326 if ($reading =~ /int\s+partition_sectors\s*=\s*(.*);/)
327 {
328 $first_partition_sectors = `perl -e "print ($1)" 2>&1`;
329 $original_first_partition_sectors = $first_partition_sectors;
330 $first_partition_size = $first_partition_sectors * 512;
331 printf("[Input] %sFS_FIRST_DRIVE_SECTORS = %d sectors(0x%08X bytes)\n", $DEV_PREFIX, $first_partition_sectors, $first_partition_size)if ($DebugPrint &1);
332 }
333 else
334 {
335
336 cksysdrv_die(ERR::ERR_UNEXPECTED, "The first drive size is NOT found!", __FILE__, __LINE__);
337 }
338}
339elsif ($system_drive_location == $ON_EMMC) # EMMC booting
340{
341 # macth int system_drive_size = 0 ;
342 if ($reading =~ /int\s+system_drive_size\s*=\s*(.*);/)
343 {
344 $system_drive_sectors = `perl -e "print ($1)" 2>&1`;
345 $system_drive_size = $system_drive_sectors * 512;
346 printf("[Input] %sFS_SIZE = %d sectors(0x%08X bytes)\n", $DEV_PREFIX, $system_drive_sectors, $allocated_fat_space)if ($DebugPrint &1);
347 }
348 else
349 {
350 cksysdrv_die(ERR::ERR_UNEXPECTED, "[EMMC Booting] System drive size is NOT found!", __FILE__, __LINE__);
351 }
352}
353else
354{
355 cksysdrv_die(ERR::ERR_UNEXPECTED, "Unrecognizable device type", __FILE__, __LINE__);
356}
357
358print "\n[$DEV_TYPE] Read device specific configurations \n" if ($DebugPrint &1);
359if ($system_drive_location == $ON_NAND) # System drive on NAND flash
360{
361
362 #---------------------------------------------------
363 # NAND flash
364 #---------------------------------------------------
365
366 #print "(NAND)...\n" if ($DebugPrint &1);
367
368 # macth int nand_fdm_version = 0;
369 if ($reading =~ /int\s+nand_fdm_version\s*=\s*(.*);/)
370 {
371 $nand_fdm_version = `perl -e "print ($1)" 2>&1`; # 4 or 5
372 printf("\tFDM version: %d\n", $nand_fdm_version) if ($DebugPrint &1);
373 }
374 else
375 {
376 cksysdrv_die(ERR::ERR_UNEXPECTED, "NAND FDM version is NOT found!", __FILE__, __LINE__);
377 }
378
379 if ($nand_fdm_version != 4 && $nand_fdm_version != 5)
380 {
381 cksysdrv_die(ERR::ERR_UNEXPECTED, "Unsupported NAND FDM version!", __FILE__, __LINE__);
382 }
383
384 # macth int nand_block_size = 0;
385 if ($reading =~ /int\s+nand_block_size\s*=\s*(.*);/)
386 {
387 $nand_block_size = `perl -e "print ($1)" 2>&1`; # (KB)
388 printf("[CkSysDrv:NAND] Block size: %d (KB)\n", $nand_block_size) if ($DebugPrint &1);
389 }
390 else
391 {
392 cksysdrv_die(ERR::ERR_UNEXPECTED, "NAND block size is NOT found!", __FILE__, __LINE__);
393 }
394}
395elsif ($system_drive_location == $ON_NOR) # System drive on NOR flash
396{
397
398 #------------------------------------------------------------
399 # NOR flash
400 #------------------------------------------------------------
401
402 #print "(NOR)...\n";
403
404 # macth int fs_low_cost_support = 0 ;
405 if ($reading =~ /int\s+fs_low_cost_support\s*=\s*(.*);/)
406 {
407 $fs_low_cost_support = `perl -e "print ($1)" 2>&1`;
408 printf("\tUltra-low-cost support: %d\n", $fs_low_cost_support) if ($DebugPrint &1);
409 }
410 else
411 {
412 warn "[CkSysDrv:NOR] Ultra-low-cost indication is NOT found!";
413 undef $fs_low_cost_support;
414 }
415
416 # macth int nvram_custom_cfg_max_record_size = 4 ;
417 if ($reading =~ /int\s+nvram_custom_cfg_max_record_sector_num\s*=\s*(.*);/)
418 {
419 $nvram_custom_cfg_max_record_sector_num = `perl -e "print ($1)" 2>&1`;
420 printf("\tNVRAM maximum record size: %d\n", $nvram_custom_cfg_max_record_sector_num) if ($DebugPrint &1);
421 }
422 else
423 {
424
425 cksysdrv_die(ERR::ERR_UNEXPECTED,
426 "NVRAM_CUSTOM_CFG_MAX_RECORD_SECTOR_NUM is NOT defined! It should be defined in custom\\common\\custom_nvram_config.h", __FILE__, __LINE__);
427 }
428
429 # match {float,int} nor_reserved_blocks = {1.5,5} ;
430 if ($reading =~ /int\s+nor_reserved_blocks\s*=\s*(.*);/)
431 {
432 $nor_reserved_blocks = `perl -e "print ($1)" 2>&1`;
433 printf("\tNOR FDM reserved blocks: %d\n", $nor_reserved_blocks) if ($DebugPrint &1);
434 }
435 elsif ($reading =~ /float\s+nor_reserved_blocks\s*=\s*(.*);/)
436 {
437 $nor_reserved_blocks = `perl -e "print ($1)" 2>&1`;
438 printf("\tNOR FDM reserved blocks: %.2f\n", $nor_reserved_blocks) if ($DebugPrint &1);
439 }
440 else
441 {
442 cksysdrv_die(ERR::ERR_UNEXPECTED, "RESERVED BLOCKS is NOT found!", __FILE__, __LINE__);
443 }
444
445 # match int nor_single_bank_support = {1,0} ;
446 if ($reading =~ /int\s+nor_single_bank_support\s*=\s*(.*);/)
447 {
448 $nor_single_bank_support = `perl -e "print ($1)" 2>&1`;
449 }
450
451 # match int nor_sector_size = 512 ;
452 if ($reading =~ /int\s+nor_sector_size\s*=\s*(.*);/)
453 {
454 $nor_sector_size = `perl -e "print ($1)" 2>&1`;
455 printf("\tSector size: %d (Bytes)\n", $nor_sector_size) if ($DebugPrint &1);
456 }
457 else
458 {
459 cksysdrv_die(ERR::ERR_UNEXPECTED, "SECTOR SIZE is NOT found!\n", __FILE__, __LINE__);
460 }
461
462 # macth FlashRegionInfo RegionInfo[] =
463 # {
464 # {0x20000, 16},
465 # EndRegionInfo
466 # };
467 if ($reading =~ /\s+RegionInfo\s*?\[\s*?\]\s*?=\s*?\{([\w\W]+?)\s*?\{0, 0\}\s*?\}\s*?;/)
468 {
469 $nor_regions = $1;
470 }
471 else
472 {
473 cksysdrv_die(ERR::ERR_UNEXPECTED, "RegionInfo is NOT found!\n", __FILE__, __LINE__);
474 }
475
476 # match {0x20000, 16},
477 while ($nor_regions =~ /\{\s*(0x[\dA-Fa-f]+)\s*,\s*(\d+)\s*\}\s*,/)
478 {
479 my $sectors_per_block;
480
481 $nor_regions = $';
482
483 if ($nor_sector_size == 512)
484 {
485 $blockheader_overhead = 512;
486 $sectors_per_block = (hex($1) - $blockheader_overhead) / 512;
487 while ((($sectors_per_block + 1) * 4) > $blockheader_overhead)
488 {
489 $blockheader_overhead += 512;
490 $sectors_per_block--;
491 }
492 printf("\t\t[i]sectors_per_block = $sectors_per_block\n")if ($DebugPrint & 2);
493 }
494 elsif ($nor_sector_size == 1024)
495 {
496 $blockheader_overhead = 2048;
497 printf("\t\t[i]sectors_per_block = $sectors_per_block\n")if ($DebugPrint & 2);
498 }
499
500 $alignment = hex($1);
501 printf("\t\t[i]alignment = $alignment\n")if ($DebugPrint & 2);
502
503 $nor_max_blk_size = hex($1) - $blockheader_overhead if ($nor_max_blk_size < hex($1) - $blockheader_overhead);
504 printf("\t\t[i]nor_max_blk_size = $nor_max_blk_size\n")if ($DebugPrint & 2);
505
506 $blockheader_overhead_total = $blockheader_overhead * $2;
507 printf("\t\t[i]blockheader_overhead = $blockheader_overhead\n")if ($DebugPrint & 2);
508
509 }
510
511}
512
513
514if ($fs_auto_config_support == 1)
515{
516 # match code_boundary_addr
517 printf ("Parsing $LINK_INFO\n") if ($DebugPrint &1);
518 open(LINK_INFO, "<$LINK_INFO") or warn "cannot open LINK_INFO: $LINK_INFO\n";
519 while (<LINK_INFO>)
520 {
521 printf("\t\t[i]%s\n", $_) if ($DebugPrint &1);
522
523 if ($system_drive_location == $ON_NOR)
524 {
525
526 #multi-bank, we can't adjust because FS addr. must align bank.
527 if ($nor_single_bank_support == 0)
528 {
529 cksysdrv_die(ERR::CANNOT_ADJUST, "Can't adjust FS base address because of multibank! Please consider turning on ENHANCED_SINGLE_BANK_NOR_FLASH_SUPPORT\n", __FILE__, __LINE__);
530 }
531
532 #this is temp solution, because don't know how big is code region when multi-bin
533 # release all freespace once the link error doesn't include key word: EXTSRAM, INTSRAM, CACHED and PAGE_TABLE
534
535 if (/L6220E:\s*Load\s*region\s*(.*)\s*size/)
536 {
537 printf("Link error: Load region = $1\n")if ($DebugPrint &1);
538 if ($1 =~ /(EXTSRAM|INTSRAM|CACHED|PAGE_TABLE)/)
539 {
540 printf("\tFalse alarm\n")if ($DebugPrint &1);
541 }
542 else
543 {
544 $code_boundary_addr = $release_all_free; #free all free space to code region
545 printf("\tRelease all free space\n")if ($DebugPrint &1);
546 }
547 }
548
549 # correct soultion is to calc all shortage,
550 # e.g. Error: L6220E: Load region ROM size (54932988 bytes) exceeds limit (1048576 bytes).
551 # if(/L6220E:\s*Load\s*region\s*ROM\s*size\s*\((.*)\s*bytes\)\s+exceeds\s+limit/)
552 # {
553 # $code_boundary_addr = $1;
554 # }
555
556
557 }
558 elsif ($system_drive_location == $ON_NAND || $system_drive_location == $ON_EMMC)
559 {
560
561 #match Error: BIN (413.52 blocks) and FAT (400 blocks) on NAND Flash overlap risk were detected.
562 if(/Error:\s*BIN\s*\((.*)\s*blocks\)\s*and\s*FAT\s*\((.*)\s*blocks\)/)
563 {
564 $code_boundary_addr = ($1 + 1) * $nand_block_size * 1024;
565 printf("Link error: Load region = $1 blocks\n")if ($DebugPrint &1);
566 }
567
568 if (/BIN\s*size\s*=\((.*)\s*blocks\)\s*on\s*NAND\s*Flash/)
569 {
570 $code_boundary_addr = $1;
571 printf("Load region = $1 blocks\n")if ($DebugPrint &1);
572 }
573
574 }
575 }
576
577 close LINK_INFO;
578
579 my $i = 0;
580 for (; $i < 10 ; $i++)
581 {
582 my $err_level_1 = calc_func();
583 print "\n\n[ckSysdrv result] $error_code{$err_level_1}($err_level_1)\n";
584 if ($err_level_1 == ERR::NO_MODIFY)
585 {
586 my $err_level_2 = adjust_func();
587
588 print "\n\n[AAPMC result] $error_code{$err_level_2}($err_level_2)\n";
589 exit $err_level_2;
590 }
591 elsif ($err_level_1 == ERR::MODIFY_SUCCESS)
592 {
593 print "\n\n[Retrying...]\n";
594 }
595 else
596 {
597 exit $err_level_1;
598 }
599
600 }
601 if ($i == 10)
602 {
603 if ($code_shortage_size > 0)
604 {
605 printf("Error: Shortage of code region (bytes, sectors) = (0x%08X, %d)\n", $code_shortage_size, $code_shortage_size/512);
606 }
607 elsif ($diff >= 0)
608 {
609 printf("Error: Shortage of FAT region: %d clusters (%d Sectors = %.1f KB = %.2f MB)\n", $diff, $diff * ($cluster_size / 512), $diff * $cluster_size / 1024, $diff * $cluster_size / (1024 * 1024));
610 }
611 cksysdrv_die(ERR::CANNOT_ADJUST, "Can't find an available setting. Check ckSysDrv.log for detail!\n", __FILE__, __LINE__);
612 }
613}
614else
615{
616 calc_func();
617
618 if ($code_shortage_size > 0)
619 {
620 printf("Error: Shortage of code region (bytes, sectors) = (0x%08X, %d)\n", $code_shortage_size, $code_shortage_size/512);
621 exit ERR::ERR_UNEXPECTED;
622 }
623 elsif ($diff < 0)
624 {
625 printf("Error: Shortage of FAT region: %d clusters (%d Sectors = %.1f KB = %.2f MB)\n", -1*$diff, -1*$diff * ($cluster_size / 512), 1*$diff * $cluster_size / 1024, 1*$diff * $cluster_size / (1024 * 1024));
626 exit ERR::ERR_UNEXPECTED;
627 }
628
629 cksysdrv_die(ERR::NO_MODIFY, "Auto config is OFF this time!\n", __FILE__, __LINE__);
630}
631
632#---------------------------------------------------------
633# Read device specific variables and calculate free space
634#---------------------------------------------------------
635sub calc_func
636{
637 if ($system_drive_location == $ON_NAND) # System drive on NAND flash
638 {
639
640 print "[CkSysDrv:NAND] Calculate free space...\n" if ($DebugPrint &1);
641
642 if ($nand_block_size != 0)
643 {
644 if ($nand_fdm_version == 4)
645 {
646
647 #----------------------------------------------------------
648 # 12 : Reserved blocks in each region.
649 # 5 : Max possible bad blocks number in each region. (2%)
650 # Log_Block_Number : Number of log blocks. In 2KB NAND, the value is 3. In 528B page size NAND, the value is 6.
651 # Block_Size : 128KB or 16KB.
652 #----------------------------------------------------------
653 printf("allocated_fat_space = %d, nand_block_size = %d\n", $allocated_fat_space, $nand_block_size) if ($DebugPrint & 1);
654
655 $fat_nand_block_num = $allocated_fat_space / ($nand_block_size * 1024);
656 $fat_nand_region_num = ceil($fat_nand_block_num / 256);
657
658 if ($nand_block_size == 128)
659 {
660 $nand_log_block_num = 3;
661 }
662 elsif ($nand_block_size == 16)
663 {
664 $nand_log_block_num = 6;
665 }
666 else
667 {
668 cksysdrv_die(ERR::ERR_UNEXPECTED, "Unsupported NAND block size!\n", __FILE__, __LINE__);
669 }
670
671 $free_space = ($fat_nand_block_num - (($fat_nand_region_num) * (12 + 5)) - ($nand_log_block_num)) * ($nand_block_size * 1024);
672 }
673 else # NAND FDM5
674 {
675
676 #----------------------------------------------------------
677 # Block_Size : 128KB or 16KB.
678 # 40 : Reserved blocks in each region (1024 blocks).
679 #----------------------------------------------------------
680 printf("\t\t[i]allocated_fat_space = %d, nand_block_size = %d\n", $allocated_fat_space, $nand_block_size) if ($DebugPrint & 1);
681
682 $fat_nand_block_num = $allocated_fat_space / ($nand_block_size * 1024);
683 $fat_nand_region_num = ceil($fat_nand_block_num / 1024);
684
685 printf("\t\t[i]nand_block_num = %d, nand_region_num = %d, nand_block_size = %d\n", $fat_nand_block_num, $fat_nand_region_num, $nand_block_size) if ($DebugPrint & 1);
686 $free_space = ($fat_nand_block_num - (($fat_nand_region_num) * 40)) * ($nand_block_size * 1024);
687
688 printf("\t\t[i]first_partition_size = $first_partition_size, first_partition_sectors = $first_partition_sectors\n") if ($DebugPrint & 1);
689
690 printf("\tBlock Number: %d\n", $fat_nand_block_num) if ($DebugPrint &1);
691 printf("\tRegion Number: %d\n", $fat_nand_region_num) if ($DebugPrint &1);
692 printf("\tFree Space: %d B = %d KB = %d MB\n", $free_space, $free_space / 1024, $free_space / (1024 * 1024)) if ($DebugPrint &1);
693
694 }
695 }
696 else # we have no NAND flash geometry information (before 09A), use 2KB page size to do more strict checking.
697 {
698 if ($nand_fdm_version == 4)
699 {
700
701 #----------------------------------------------------------
702 # 12 : Reserved blocks in each region.
703 # 5 : Max possible bad blocks number in each region. (2%)
704 # 3 : Number of log blocks. In 2KB NAND, 3 log blocks.
705 #----------------------------------------------------------
706
707 $fat_nand_block_num = $allocated_fat_space / (128 * 1024);
708 $fat_nand_region_num = ceil($fat_nand_block_num / 256);
709 $free_space = ($fat_nand_block_num - (($fat_nand_region_num) * (12 + 5)) - 3) * (128 * 1024);
710 }
711 else # NAND FDM5
712 {
713
714 #----------------------------------------------------------
715 # 40 : Reserved blocks in each region.
716 #----------------------------------------------------------
717
718 $fat_nand_block_num = $allocated_fat_space / (128 * 1024);
719 $fat_nand_region_num = ceil($fat_nand_block_num / 1024);
720 $free_space = ($fat_nand_block_num - (($fat_nand_region_num) * 40)) * (128 * 1024);
721 }
722 }
723
724 # Calculate system drive free space
725 $free_space = $free_space - $first_partition_size;
726 $alignment = ($nand_block_size * 1024);
727
728 printf("first_partition_size = $first_partition_size, first_partition_sectors = $first_partition_sectors\n") if ($DebugPrint & 1);
729
730 printf("[CkSysDrv:NAND] Block Number: %d\n", $fat_nand_block_num) if ($DebugPrint &1);
731 printf("[CkSysDrv:NAND] Region Number: %d\n", $fat_nand_region_num) if ($DebugPrint &1);
732 printf("[CkSysDrv:NAND] Free Space: %d B = %d KB = %d MB)\n", $free_space, $free_space / 1024, $free_space / (1024 * 1024)) if ($DebugPrint &1);
733
734 }
735 elsif ($system_drive_location == $ON_NOR) # System drive on NOR flash
736 {
737
738 print "[$DEV_TYPE] Calculate free space...\n" if ($DebugPrint &1);
739
740 printf("\t\t[i]nor_sector_size = $nor_sector_size\n")if ($DebugPrint & 2);
741 printf("\t\t[i]nvram_custom_cfg_max_record_sector_num = $nvram_custom_cfg_max_record_sector_num\n")if ($DebugPrint & 2);
742
743 $nor_protection_mode_reserved_space = ($nvram_custom_cfg_max_record_sector_num * 2 + 1) * $nor_sector_size;
744 printf("\t\t[i]nor_protection_mode_reserved_space = $nor_protection_mode_reserved_space\n")if ($DebugPrint & 2);
745
746
747 $nor_extra_reserved_space = 4 * $nor_sector_size if ($nor_reserved_blocks == $nor_min_reserved_blocks);
748 printf("\t\t[i]nor_min_reserved_blocks = $nor_min_reserved_blocks\n")if ($DebugPrint & 2);
749 printf("\t\t[i]nor_reserved_blocks = $nor_reserved_blocks\n")if ($DebugPrint & 2);
750 printf("\t\t[i]nor_extra_reserved_space = $nor_extra_reserved_space\n")if ($DebugPrint & 2);
751
752 $nor_extra_reserved_space_for_power_loss = 6 * $nor_sector_size if ($nor_sector_size == 512);
753 printf("\t\t[i]nor_extra_reserved_space_for_power_loss = $nor_extra_reserved_space_for_power_loss\n")if ($DebugPrint & 2);
754
755
756 $blockheader_overhead_total = ceil($allocated_fat_space/($nor_max_blk_size + $blockheader_overhead)) * $blockheader_overhead;
757 printf("\t\t[i]blockheader_overhead_total = $blockheader_overhead_total\n")if ($DebugPrint & 2);
758 printf("\t\t[i]blocks = %d\n", ceil($allocated_fat_space/$nor_max_blk_size))if ($DebugPrint & 2);
759
760 $nor_drive_overhead = $blockheader_overhead_total + ($nor_reserved_blocks * $nor_max_blk_size + $nor_protection_mode_reserved_space + $nor_extra_reserved_space + $nor_extra_reserved_space_for_power_loss);
761 printf("\t\t[i]nor_drive_overhead = $nor_drive_overhead\n")if ($DebugPrint & 2);
762
763 $free_space = $allocated_fat_space - $first_partition_size - $nor_drive_overhead; # in Byte
764 printf("\t\t[i]free_space = $free_space\n")if ($DebugPrint & 2);
765
766
767 }
768 elsif ($system_drive_location == $ON_EMMC) # System drive on EMMC
769 {
770 $allocated_fat_space = $free_space = $system_drive_size;
771 $alignment = 1;
772
773 }
774 else
775 {
776 cksysdrv_die(ERR::ERR_UNEXPECTED, "Unsupported system drive location!\n", __FILE__, __LINE__);
777
778 }
779
780 print "[CkSysDrv] Calculate FAT type and cluster size...\n" if ($DebugPrint &1);
781
782 $cluster_size = -1; # in Byte
783 my $fat_type = 12;
784
785 if ($free_space == -1)
786 {
787
788 # free space is not available
789 $cluster_size = -2;
790 warn "[CkSysDrv] Free space is not available!";
791 }
792 elsif ($free_space < 1024 * 1024)
793 {
794 $cluster_size = 512;
795 }
796 elsif ($free_space < 4096 * 1024)
797 {
798 $cluster_size = 1024;
799 }
800 elsif ($free_space < 8192 * 1024)
801 {
802 $cluster_size = 2048;
803 }
804 elsif ($free_space < 16384 * 1024)
805 {
806 $cluster_size = 4096;
807 }
808 elsif ($free_space < 32 * 1024 * 1024)
809 {
810 $cluster_size = 1024;
811 $fat_type = 16;
812 }
813 elsif ($free_space < 128 * 1024 * 1024)
814 {
815 $cluster_size = 2048;
816 $fat_type = 16;
817 }
818 elsif ($free_space < 256 * 1024 * 1024)
819 {
820 $cluster_size = 4096;
821 $fat_type = 16;
822 }
823 elsif ($free_space < 512 * 1024 * 1024)
824 {
825 $cluster_size = 8192;
826 $fat_type = 16;
827 }
828 else
829 {
830
831 # when free space >= 512MB, no need to determine system drive free space;
832 # $cluster_size will be set as -1
833 warn "[CkSysDrv] System Drive >= 512MB , such configuration not supported by FileSystem in default";
834 }
835
836 printf("[CkSysDrv] FAT type: FAT%d\n", $fat_type) if ($DebugPrint &1);
837 printf("[CkSysDrv] Cluster size: %d (Bytes)\n", $cluster_size) if ($DebugPrint &1);
838
839 print "[CkSysDrv] Parse FS quota configurations...\n" if ($DebugPrint &1);
840
841#****************************************************************************
842# Parse ~fs_quota_usage.log to determine folder size
843#****************************************************************************
844# my $folder =
845# {
846# FOLDER => $folder_name,
847# COUNT => $count,
848# UNIT => $unit_byte,
849# SIZE => $size_in_byte
850# }
851 my @folder_size = ();
852
853 open(FS_STAT, "<$FS_STAT") or cksysdrv_die(ERR::ERR_UNEXPECTED, "cannot open FS_STAT: $FS_STAT\n\n", __FILE__, __LINE__);
854 $/ = $backup;
855
856 while (<FS_STAT>)
857 {
858
859 # match {Z:\@USER\, 0, 83968, 0xf1f2f3f4 , 0x1 },
860 if (/\{\s*(Z.+\\)\s*,[^,]+,\s*(\d+)\s*,[^,]+,\s*(0x[\dA-Fa-f]+)\s*\}\s*,/i)
861 {
862 my %this_folder = ();
863 $this_folder{FOLDER} = $1;
864 $this_folder{COUNT} = $2;
865 $this_folder{UNIT} = $3;
866 $this_folder{SIZE} = ($this_folder{UNIT} eq '0x1') ? ($this_folder{COUNT}) : ($this_folder{COUNT} * $cluster_size);
867
868 push @folder_size, \%this_folder;
869
870 }
871 }
872
873 close FS_STAT;
874
875 foreach my $folder (@folder_size)
876 {
877 printf("%-20s %10s\n", $folder->{FOLDER}, $folder->{SIZE}) if ($DebugPrint &4);
878 }
879
880 print "[CkSysDrv] Parse NVRAM configurations...\n" if ($DebugPrint &1);
881
882#****************************************************************************
883# Parse ~nvram_lid_size.log to get application's nvram reserved size info.
884#****************************************************************************
885 my @app_rev_size = ();
886
887# my $app =
888# {
889# APPLICATION => $app_name,
890# SIZE => $size_in_byte # unit_size * record_num
891# }
892
893# For NVRAM-PSEUDO-MERGE usage.
894 my %this_app = ();
895 $this_app{APPLICATION} = "Package file size";
896 $this_app{SIZE} = "unknown";
897 push @app_rev_size, \%this_app;
898
899 my %this_app = ();
900 $this_app{APPLICATION} = "Info file A";
901 $this_app{SIZE} = "unknown";
902 push @app_rev_size, \%this_app;
903
904 my %this_app = ();
905 $this_app{APPLICATION} = "Info file B";
906 $this_app{SIZE} = "unknown";
907 push @app_rev_size, \%this_app;
908
909 my %this_app = ();
910 $this_app{APPLICATION} = "Extra size";
911 $this_app{SIZE} = "unknown";
912 push @app_rev_size, \%this_app;
913
914 foreach my $app (@app_rev_size)
915 {
916 printf("%-40s %10s\n", $app->{APPLICATION}, $app->{SIZE}) if ($DebugPrint & 1);
917 $cluster_multiple{$app->{APPLICATION}} = 1;
918 }
919 print("Start parse NVRAM LID\n") if ($DebugPrint &1);
920 open(NVRAM_STAT, "<$NVRAM_STAT") or cksysdrv_die(ERR::ERR_UNEXPECTED, "Cannot open NVRAM_STAT: $NVRAM_STAT\n\n", __FILE__, __LINE__);
921
922 my %app_size = ();
923 $/ = $backup;
924
925 while (<NVRAM_STAT>)
926 {
927 $_ =~ s/\bCUSTPACK\b//;
928 if (/(\d+)\s*(\d+)\s*(\w.+\w)/)
929 {
930 if (!defined($cluster_multiple{$3}))
931 {
932 my %this_app = ();
933 $this_app{APPLICATION} = $3;
934 $this_app{SIZE} = $2;
935 $cluster_multiple{$3} = 1;
936 print "push: " if ($DebugPrint &4);
937 push @app_rev_size, \%this_app;
938 }
939 if (defined $app_size{$3})
940 {
941 cksysdrv_die(ERR::ERR_UNEXPECTED, "$3 has different sizes $app_size{$3} vs. $2!\n", __FILE__, __LINE__) unless ($app_size{$3} == $2);
942 $app_size{$3} += $app_size{$3};
943 $cluster_multiple{$3} += 1;
944 }
945 else
946 {
947 $app_size{$3} = $2;
948 print "$app_size{$3} $3\n" if ($DebugPrint &4);
949 }
950 }
951 }
952
953 close NVRAM_STAT;
954
955 while ((my $key, my $value) = each %app_size)
956 {
957
958# print "$key $value\n" if ($DebugPrint &1);
959 }
960
961 foreach my $app (@app_rev_size)
962 {
963 if ( ($NVRAM_PSEUDO_MERGE =~ /^ON|TRUE$/)
964 && (!exists $app_size{$app->{APPLICATION}}))
965 {
966 $app_size{$app->{APPLICATION}} = 0;
967 }
968
969 if ($app->{SIZE} ne 'unknown')
970 {
971 if ($cluster_multiple{$app->{APPLICATION}} eq "1")
972 {
973 if ($app_size{$app->{APPLICATION}})
974 {
975 warn "$app->{APPLICATION} has different sizes $app->{SIZE} vs. $app_size{$app->{APPLICATION}}!" unless ($app->{SIZE} == $app_size{$app->{APPLICATION}});
976 }
977 }
978 $app->{SIZE} = $app_size{$app->{APPLICATION}};
979 }
980 else
981 {
982 $app->{SIZE} = $app_size{$app->{APPLICATION}};
983 }
984
985 printf("%-40s %10s\n", $app->{APPLICATION}, $app->{SIZE}) if ($DebugPrint &4);
986 }
987
988 print "[CkSysDrv] Parse file system management overhead...\n" if ($DebugPrint &1);
989
990#****************************************************************************
991# Determine FAT overhead
992#****************************************************************************
993# Calculate the freespace by removing MBR & PBR & FAT & Root DIR space.
994 my $fat_overhead_cluster;
995 my $tmp_free_space = $free_space;
996
997# MBR
998 $tmp_free_space -= 512;
999
1000# PBR
1001 $tmp_free_space -= 512;
1002
1003# FAT
1004 if ($fat_type == 12)
1005 {
1006
1007 # FAT-12
1008 # DIR
1009 if ($fs_low_cost_support == 1)
1010 {
1011 $tmp_free_space -= (16 * 32); # 1
1012 }
1013 else
1014 {
1015 $tmp_free_space -= (128 * 32); # 8
1016 }
1017
1018 # FAT Table
1019 my $fat_size = 0;
1020
1021 if ($cluster_size > 0)
1022 {
1023 while (($fat_size * 2 / 3) * $cluster_size < $tmp_free_space)
1024 {
1025 $fat_size += 512;
1026 $tmp_free_space -= 512;
1027 }
1028 }
1029 }
1030 else
1031 {
1032
1033 # FAT-16
1034 # DIR
1035 if ($fs_low_cost_support == 1)
1036 {
1037 $tmp_free_space -= (16 * 32); # 1
1038 }
1039 else
1040 {
1041 $tmp_free_space -= (512 * 32); # 32
1042 }
1043
1044 # FAT Table
1045 my $fat_size = 0;
1046
1047 if ($cluster_size > 0)
1048 {
1049 while (($fat_size / 2) * $cluster_size < $tmp_free_space)
1050 {
1051 $fat_size += 512;
1052 $tmp_free_space -= 512;
1053 }
1054 }
1055 }
1056
1057# Example:
1058#Z:\@WAP\
1059#Z:\@DRM\
1060#Z:\NVRAM\NVD_DATA\NVRAM_EF_PHB_LID
1061# \NVRAM_EF_SMS_LID
1062# dir entry of level-1 (in cluster unit) = 2 (@WAP, @DRM)
1063# dir entry of level-2 (in direntry cnt) = 2 + 1 ("." , ".." , NVD_DATA) at Z:\NVRAM
1064# dir entry of level-3 (in direntry cnt) = 2 + 2 ("." , ".." , NVRAM_EF_PHB_LID, NVRAM_EF_SMS_LID) at Z:\NVRAM\NVD_DATA
1065
1066 my $fat_overhead_cluster;
1067 if ($cluster_size > 0)
1068 {
1069
1070 # level-1 directory entries + level-2 directory entries + level-3 directory entries
1071 $fat_overhead_cluster = ($#folder_size + 1) + ceil((2 + 1) * 32 / $cluster_size) + ceil((2 + ($#app_rev_size + 1)) * 32 / $cluster_size);
1072 }
1073
1074 print "[CkSysDrv] Print result...\n" if ($DebugPrint &1);
1075 print("===========================================================\n");
1076
1077#****************************************************************************
1078# Print out the result
1079#****************************************************************************
1080#1.
1081# die "Free space is greater than 16MB!";
1082#print "SYSTEM_DRIVE_ON_NAND = $SYSTEM_DRIVE_ON_NAND\n";
1083#print "FAT_BASE_ADDRESS = $flash_base_address (".hex($flash_base_address).")\n";
1084 print(" Byte Cluster\n");
1085 print("===========================================================\n");
1086
1087 if ($system_drive_location == $ON_NOR || $system_drive_location == $ON_NAND)
1088 {
1089 printf("FS Total Size %36s %7s\n", $allocated_fat_space, $allocated_fat_space/$cluster_size);
1090 printf("FS Public(First) Drive Size %23s %7s\n", $first_partition_size, $first_partition_size/$cluster_size);
1091 printf("FS Overhead for (MBR + PBR + Root Dir) %12s %7s\n", $free_space - $tmp_free_space, ($free_space - $tmp_free_space)/$cluster_size);
1092 if ($system_drive_location == $ON_NOR)
1093 {
1094 printf("FDM Overhead (NOR) %32s %7s\n", $nor_drive_overhead, $nor_drive_overhead/$cluster_size);
1095 }
1096 elsif ($system_drive_location == $ON_NAND)
1097 {
1098 printf("FDM Overhead (NAND) %31s %7s\n", ($fat_nand_region_num * 40) * ($nand_block_size * 1024), ($fat_nand_region_num * 40) * ($nand_block_size * 1024)/$cluster_size);
1099 }
1100
1101 }
1102 else #EMMC
1103 {
1104 printf("FS System Drive Size %29s \n", $free_space);
1105 }
1106
1107 $free_space = $tmp_free_space;
1108
1109
1110
1111 my $free_space_cluster = floor($free_space / $cluster_size);
1112 my $app_rev_total = 0;
1113 my $app_rev_total_cluster = 0;
1114 my $folder_total = 0;
1115 my $folder_total_cluster = 0;
1116 my $nv_overhead = 0;
1117 my $nv_overhead_cluster = 0;
1118 my $mini_public_drv_sectors = 0;
1119
1120 #CYLEN: need to calc real overhead of NVRAM
1121 if ($NVRAM_PSEUDO_MERGE =~ /^ON|TRUE$/)
1122 {
1123 $nv_overhead = 10;
1124 }
1125 else
1126 {
1127 $nv_overhead = 15;
1128 }
1129
1130 printf("NVRAM reserved folder overhead %20s %7s\n", $nv_overhead * $cluster_size, $nv_overhead);
1131
1132 if ($free_space_cluster >= $nv_overhead)
1133 {
1134 $free_space_cluster -= $nv_overhead;
1135 }
1136 else
1137 {
1138 $free_space_cluster = 0;
1139 }
1140
1141 $nv_overhead = 0;
1142
1143
1144 print("===========================================================\n");
1145
1146
1147 if ($cluster_size > 0)
1148 {
1149 printf("Free Space for NVRAM and App's Folders %12s %7s\n\n", $free_space, $free_space_cluster);
1150 print("-----------------------------------------------------------\n");
1151 printf("FAT Type %38s \n", $fat_type);
1152 printf("Cluster Size %38s 1\n", $cluster_size);
1153 print("-----------------------------------------------------------\n");
1154 printf("FAT Overhead for Sub Dir %26s %7s\n", $fat_overhead_cluster * $cluster_size, $fat_overhead_cluster);
1155 print("-----------------------------------------------------------\n");
1156 foreach my $app (@app_rev_size)
1157 {
1158
1159 if ($app->{SIZE} ne "unknown")
1160 {
1161 printf("%-40s %10s %7s\n", $app->{APPLICATION}, $app->{SIZE}, ceil($app->{SIZE} / $cluster_multiple{$app->{APPLICATION}} / $cluster_size) * $cluster_multiple{$app->{APPLICATION}}) if ($DebugPrint == 0 || ($DebugPrint & 8) == 1);
1162 $app_rev_total += $app->{SIZE};
1163 $app_rev_total_cluster += ceil($app->{SIZE} / $cluster_multiple{$app->{APPLICATION}} / $cluster_size) * $cluster_multiple{$app->{APPLICATION}};
1164 }
1165 else
1166 {
1167 printf("%-40s %10s %7s\n", $app->{APPLICATION}, $app->{SIZE}, $app->{SIZE}) if ($DebugPrint == 0 || ($DebugPrint & 8) == 1);
1168 }
1169 }
1170
1171 for(keys %cluster_multiple)
1172 {
1173 delete $cluster_multiple{$_};
1174 }
1175
1176 if (defined $app_size{'SW CHANGE LID LIST'})
1177 {
1178 printf("%-40s %10s %7s\n", "NVRAM_EXTRA_REPORT_FILES", $app_size{'SW CHANGE LID LIST'}, ceil($app_size{'SW CHANGE LID LIST'} / $cluster_size)) if ($DebugPrint == 0 || ($DebugPrint & 8) == 1);
1179 $nv_overhead += $app_size{'SW CHANGE LID LIST'};
1180 $nv_overhead_cluster += ceil($app_size{'SW CHANGE LID LIST'} / $cluster_size);
1181 }
1182 if (defined $app_size{'SW CHANGE LID DESCRIPTION'})
1183 {
1184 printf("%-40s %10s %7s\n", "NVRAM_EXTRA_REPORT_FILES", $app_size{'SW CHANGE LID DESCRIPTION'}, ceil($app_size{'SW CHANGE LID DESCRIPTION'} / $cluster_size)) if ($DebugPrint == 0 || ($DebugPrint & 8) == 1);
1185 $nv_overhead += $app_size{'SW CHANGE LID DESCRIPTION'};
1186 $nv_overhead_cluster += ceil($app_size{'SW CHANGE LID DESCRIPTION'} / $cluster_size);
1187 }
1188
1189 printf("\nTOTAL %45s %7s\n", $app_rev_total + $nv_overhead, $app_rev_total_cluster + $nv_overhead_cluster);
1190 print("-----------------------------------------------------------\n");
1191
1192 foreach my $folder (@folder_size)
1193 {
1194 if ($folder->{SIZE} ne "unknown")
1195 {
1196 printf("%-40s %10s %7s\n", $folder->{FOLDER}, $folder->{SIZE}, ceil($folder->{SIZE} / $cluster_size)) if ($DebugPrint == 0 || ($DebugPrint & 8) == 1);
1197 $folder_total += $folder->{SIZE};
1198 $folder_total_cluster += ceil($folder->{SIZE} / $cluster_size);
1199 }
1200 else
1201 {
1202 printf("%-40s %10s %7s\n", $folder->{FOLDER}, $folder->{SIZE}, $folder->{SIZE}) if ($DebugPrint == 0 || ($DebugPrint & 8) == 1);
1203 }
1204 }
1205 printf("\nTOTAL %45s %7s\n", $folder_total, $folder_total_cluster);
1206 print("===========================================================\n");
1207
1208 my $folder_and_app_clusters = $fat_overhead_cluster + $app_rev_total_cluster + $nv_overhead_cluster + $folder_total_cluster;
1209 $diff = $free_space_cluster - $folder_and_app_clusters;
1210
1211 print("\nREPORT\n");
1212 print("===========================================================\n");
1213 printf("Cluster Size (Bytes) %38s\n", $cluster_size);
1214 printf("Free Space (Clusters) %37s\n", $free_space_cluster);
1215 printf("Folders and Applications Requirement (Clusters) %11s\n", $folder_and_app_clusters);
1216
1217 print("\n");
1218
1219 if ($system_drive_location == $ON_NAND)
1220 {
1221 $mini_public_drv_sectors = 400;
1222 }
1223 elsif ($system_drive_location == $ON_NOR)
1224 {
1225 $mini_public_drv_sectors = 25;
1226 }
1227
1228
1229
1230 if ($diff >= 0)
1231 {
1232 my $diff_size = $diff * $cluster_size;
1233
1234 print("RESULT: PASS!\n");
1235 printf("%d clusters are left (%.1f KB = %.2f MB)\n", $diff, $diff_size / 1024, $diff_size / (1024 * 1024));
1236
1237 if ($fs_auto_config_support == 0)
1238 {
1239 return ERR::NO_MODIFY;
1240 }
1241
1242 #this is temp solution, because don't know how big is code region when multi-bin
1243 if ($code_boundary_addr == $release_all_free)
1244 {
1245
1246 $code_boundary_addr = $flash_base_address + $diff_size + $first_partition_size;
1247
1248 $code_shortage_size = $first_partition_size + $diff_size;
1249 $short_block = floor($code_shortage_size/$alignment);
1250 $short_block_size = $short_block * $alignment;
1251
1252 }
1253 elsif ($code_boundary_addr > 0)
1254 {
1255 $code_shortage_size = $code_boundary_addr - $flash_base_address;
1256 $short_block = floor($code_shortage_size/$alignment);
1257 $short_block_size = $short_block * $alignment;
1258 }
1259
1260 if ($code_shortage_size > 0)
1261 {
1262 printf("But Code & FAT overlap!\n");
1263 printf("Code region still need 0x%08X bytes (%d sectors, %d blocks)\n", $code_shortage_size, $code_shortage_size/512, $short_block);
1264
1265 printf("\t\t[i]code_boundary_addr = 0x%08X(%d)\n", $code_boundary_addr, $code_boundary_addr) if ($DebugPrint & 2);
1266 printf("\t\t[i]flash_base_address = 0x%08X(%d)\n", $flash_base_address, $flash_base_address) if ($DebugPrint & 2);
1267 printf("\t\t[i]short_block_size = 0x%08X(%d)\n", $short_block_size, $short_block_size) if ($DebugPrint & 2);
1268 printf("\t\t[i]first_partition_size = 0x%08X(%d)\n", $first_partition_size, $first_partition_size) if ($DebugPrint & 2);
1269 printf("\t\t[i]diff = 0x%08X(%d)\n", $diff_size, $diff_size) if ($DebugPrint & 2);
1270
1271 if ($diff_size + $first_partition_size < $alignment) # free space less than one block --> fail
1272 {
1273 printf("FAT region has no block-aligned space to free!\n");
1274 return ERR::CANNOT_ADJUST;
1275 }
1276
1277
1278 #this is temp solution, because don't know how big is code region when multi-bin
1279 $flash_base_address += $short_block_size;
1280 $allocated_fat_space -= $short_block_size;
1281 printf("\t[Adjust] $DEV_PREFIX\FS_BASE_ADDRESS (bytes, sectors) = (0x%08X, %d)\n", $flash_base_address, $allocated_fat_space/512) if ($DebugPrint & 2);
1282 printf("\t[Adjust] $DEV_PREFIX\FS_SIZE (bytes, sectors) = (0x%08X, %d)\n", $allocated_fat_space, $allocated_fat_space/512) if ($DebugPrint & 2);
1283
1284 if ($first_partition_size > 0)
1285 {
1286
1287 if ($first_partition_size < $short_block_size )
1288 {
1289 if ($app_storage_in_sys_drv == 1)
1290 {
1291 $first_partition_size = 0;
1292 }
1293 else
1294 {
1295 if ($first_partition_size > $mini_public_drv_sectors * 1024)
1296 {
1297 $first_partition_size = $mini_public_drv_sectors * 1024;
1298 }
1299 else
1300 {
1301 ;
1302 }
1303 }
1304 }
1305 else
1306 {
1307 if ($app_storage_in_sys_drv == 1)
1308 {
1309 $first_partition_size -= $short_block_size;
1310
1311 if ($first_partition_size < $mini_public_drv_sectors * 1024)
1312 {
1313 $first_partition_size = 0;
1314 }
1315 }
1316 else
1317 {
1318 if ($first_partition_size - $short_block_size > $mini_public_drv_sectors * 1024)
1319 {
1320 $first_partition_size -= $short_block_size;
1321 $short_block_size = 0;
1322 }
1323 else
1324 {
1325 $short_block_size -= ($first_partition_size - $mini_public_drv_sectors * 1024);
1326 $first_partition_size = $mini_public_drv_sectors * 1024;
1327 }
1328 }
1329
1330
1331 }
1332 printf("\t[Adjust] $DEV_PREFIX\FIRST_DRIVE_SIZE (bytes, sectors) = (0x%08X, %d)\n", $first_partition_size, $first_partition_size/512) if ($DebugPrint & 2);
1333 }
1334
1335 #this is temp solution, because don't know how big is code region when multi-bin
1336 $code_boundary_addr = $flash_base_address;
1337 $code_shortage_size = 0;
1338
1339 return ERR::MODIFY_SUCCESS;
1340 }
1341
1342 return ERR::NO_MODIFY;
1343
1344 }
1345 else
1346 {
1347 my $diff_size = $diff * $cluster_size * (-1);
1348 my $free_flash_block_space = ceil(($first_partition_size + $free_space)/$alignment); #in Byte
1349 my $diff_block = ceil($diff_size/$alignment);
1350 my $diff_block_size = $diff_block * $alignment;
1351
1352
1353 print("RESULT: FAIL!\n");
1354 printf("FAT region still need 0x%08X bytes (%d sectors)\n", $diff_block_size, $diff_block_size/512);
1355 warn "Free clusters are NOT enough. ";
1356
1357 #print("\nINSTRUCTION\n");
1358 #print("===========================================================\n");
1359 #print("Please help try following action items to solve this error. Suggested order is \n");
1360 #print("\n");
1361 #printf("1) Shrink FS First Drive Size to enlarge system drive size (Shrink at least %d sectors).\n", $diff * ($cluster_size / 512));
1362 #print("2) Enlarge FS Region Size.\n");
1363 #print("3) Disable some features to shrink quota requirement.\n");
1364 #print("4) Replace flash device with another bigger one (Custom release projects only).\n");
1365 print("\n");
1366
1367
1368 if ($FEATURE_OVERLOAD ne "TRUE")
1369 {
1370
1371
1372 printf("Diff = %dbytes = %dclusters = %dblocks(%d bytes)\n", $diff_size, -1 * $diff, $diff_block, $alignment) if ($DebugPrint & 2);
1373 printf("SYSDRV_OFFSET (bytes, sectors) = %d, %d\n", $first_partition_size, $first_partition_size/512) if ($DebugPrint & 2);
1374 printf("Free space (free_flash_block_space): $free_flash_block_space blocks\n") if ($DebugPrint & 2);
1375
1376
1377 if ($fs_auto_config_support == 1)
1378 {
1379
1380 if ($system_drive_location == $ON_EMMC)
1381 {
1382 $allocated_fat_space = $system_drive_size = $allocated_fat_space + $diff_size;
1383 printf("\t[Adjust] $DEV_PREFIX\FS_SIZE (bytes, sectors) = (0x%08X, %d)\n", $allocated_fat_space, $allocated_fat_space/512) if ($DebugPrint & 2);
1384 }
1385 else
1386 {
1387 if ($first_partition_size > 0) #inside FS, already block-aligned, don't need to calc with alignment
1388 {
1389 if ($first_partition_size < $diff_size )
1390 {
1391 if ($app_storage_in_sys_drv == 1)
1392 {
1393 $diff_size -= $first_partition_size;
1394 $first_partition_size = 0;
1395 }
1396 else
1397 {
1398 if ($first_partition_size > $mini_public_drv_sectors * 1024)
1399 {
1400 $diff_size -= ($first_partition_size - $mini_public_drv_sectors * 1024);
1401 $first_partition_size = $mini_public_drv_sectors * 1024;
1402 }
1403 else
1404 {
1405 ;
1406 }
1407
1408 }
1409
1410 }
1411 else
1412 {
1413 if ($app_storage_in_sys_drv == 1)
1414 {
1415 $first_partition_size -= $diff_size;
1416 if ($first_partition_size < $mini_public_drv_sectors * 1024)
1417 {
1418 $first_partition_size = 0;
1419 }
1420 $diff_size = 0;
1421 }
1422 else
1423 {
1424 if ($first_partition_size - $diff_size > $mini_public_drv_sectors * 1024)
1425 {
1426 $first_partition_size -= $diff_size;
1427 $diff_size = 0;
1428 }
1429 else
1430 {
1431 $diff_size -= ($first_partition_size - $mini_public_drv_sectors * 1024);
1432 $first_partition_size = $mini_public_drv_sectors * 1024;
1433 }
1434
1435 }
1436
1437
1438 }
1439 }
1440 printf("%04d Adjust SYSDRV_OFFSET (bytes, sectors) = (0x%08X, %d)\n", __LINE__, $first_partition_size, $first_partition_size/512) if ($DebugPrint & 2);
1441
1442 #out of FS, must consider alignment
1443
1444 $diff_block = ceil($diff_size/$alignment);
1445 $diff_block_size = $diff_block * $alignment;
1446
1447# if ($diff_block_size > ($free_flash_block_space * $alignment)) # free space less than one block --> fail
1448# {
1449# printf("FAT region has no block-aligned space to free!\n");
1450# return ERR::CANNOT_ADJUST;
1451# }
1452# else
1453 {
1454 $flash_base_address -= $diff_block_size;
1455 $allocated_fat_space += $diff_block_size;
1456 printf("%04d Adjust flash_base_address (bytes, sectors) = (0x%08X, %d)\n", __LINE__, $flash_base_address, $allocated_fat_space/512) if ($DebugPrint & 2);
1457 printf("%04d Adjust allocated_fat_space (bytes, sectors) = (0x%08X, %d)\n", __LINE__, $allocated_fat_space, $allocated_fat_space/512) if ($DebugPrint & 2);
1458 }
1459 }
1460
1461 return ERR::MODIFY_SUCCESS;
1462
1463 }
1464
1465 }
1466
1467 return ERR::NO_MODIFY;
1468
1469 }
1470 }
1471 else
1472 {
1473 printf("Free Space for NVRAM and App's Folders %11s\n\n", $free_space);
1474 print("-----------------------------------------------------------\n");
1475 print("Cluster Size No need to be determined if Free space >= 512MB\n");
1476 print("-----------------------------------------------------------\n");
1477 print("FAT Overhead No need to be determined if Free space >= 512MB\n");
1478 print("-----------------------------------------------------------\n");
1479 foreach my $app (@app_rev_size)
1480 {
1481 printf("%-40s %10s\n", $app->{APPLICATION}, $app->{SIZE});
1482 $app_rev_total += $app->{SIZE} if ($app->{SIZE} ne "unknown");
1483 }
1484 printf("\nTOTAL %45s\n", $app_rev_total);
1485 print("-----------------------------------------------------------\n");
1486 foreach my $folder (@folder_size)
1487 {
1488 printf("%-40s %10s\n", $folder->{FOLDER}, $folder->{SIZE});
1489 $folder_total += $folder->{SIZE} if ($folder->{SIZE} ne "unknown");
1490 }
1491 printf("\nTOTAL %45s\n", $folder_total);
1492
1493 print("===========================================================\n");
1494 print "\n\nFree space >= 512MB are enough for Folders and Applications.\n";
1495 return ERR::NO_MODIFY;
1496 }
1497}
1498sub adjust_func
1499{
1500 my (%ChangeList, %OriginalList);
1501 my $fat_space = sprintf("0x%08X", $allocated_fat_space);
1502 my $base_addr = sprintf("0x%08X", $flash_base_address);
1503 my $sysdrv_offset = sprintf("%d", $first_partition_size/512);
1504
1505 if ($DebugPrint & 4)
1506 {
1507 my $tmp_h_path = "$BOARD_FOLDER\\fs_layout.h";
1508
1509 open(tmp_h_path, "> $tmp_h_path") || cksysdrv_die(ERR::ERR_UNEXPECTED, "cannot open fs_layout.h: $tmp_h_path\n\n", __FILE__, __LINE__);
1510
1511 print tmp_h_path "/* Always generated by ckSysDrv automatically */\n";
1512 print tmp_h_path "\n";
1513 print tmp_h_path "#ifdef __CKSYSDRV_AUTO_ADJ__\n";
1514 print tmp_h_path "\n";
1515 printf(tmp_h_path "#ifdef %sFS_BASE_ADDRESS \n", $DEV_PREFIX);
1516 printf(tmp_h_path "#undef %sFS_BASE_ADDRESS \n", $DEV_PREFIX);
1517 printf(tmp_h_path "#define %sFS_BASE_ADDRESS $base_addr\n", $DEV_PREFIX);
1518 print tmp_h_path "#endif\n";
1519 print tmp_h_path "\n";
1520 printf(tmp_h_path "#ifdef %sFS_SIZE\n", $DEV_PREFIX);
1521 printf(tmp_h_path "#undef %sFS_SIZE\n", $DEV_PREFIX);
1522 printf(tmp_h_path "#define %sFS_SIZE $fat_space\n", $DEV_PREFIX);
1523 print tmp_h_path "#endif\n";
1524 print tmp_h_path "\n";
1525 printf(tmp_h_path "#ifdef %sFS_FIRST_DRIVE_SECTORS\n", $DEV_PREFIX);
1526 printf(tmp_h_path "#undef %sFS_FIRST_DRIVE_SECTORS\n", $DEV_PREFIX);
1527 printf(tmp_h_path "#define %sFS_FIRST_DRIVE_SECTORS %d\n", $DEV_PREFIX, $sysdrv_offset);
1528 print tmp_h_path "#endif\n";
1529 print tmp_h_path "\n";
1530 print tmp_h_path "#endif /* __CKSYSDRV_AUTO_ADJ__ */\n";
1531 close tmp_h_path;
1532 }
1533
1534 if ($original_base_address != $flash_base_address)
1535 {
1536 $ChangeList{"$DEV_PREFIX\FS_BASE_ADDRESS"} = $base_addr;
1537 $OriginalList{"$DEV_PREFIX\FS_BASE_ADDRESS"} = sprintf("0x%08X", $original_base_address);
1538 }
1539
1540 if ($original_fat_space != $allocated_fat_space)
1541 {
1542 $ChangeList{"$DEV_PREFIX\FS_SIZE"} = $fat_space;
1543 $OriginalList{"$DEV_PREFIX\FS_SIZE"} = sprintf("0x%08X", $original_fat_space);
1544
1545 }
1546
1547 if ($original_first_partition_sectors != $first_partition_size/512)
1548 {
1549 $ChangeList{"$DEV_PREFIX\FS_FIRST_DRIVE_SECTORS"} = $sysdrv_offset;
1550 $OriginalList{"$DEV_PREFIX\FS_FIRST_DRIVE_SECTORS"} = sprintf("%d", $original_first_partition_sectors);
1551
1552 }
1553
1554 if (%ChangeList)
1555 {
1556 my $err;
1557 open(LINK_INFO, "> $LINK_INFO") or warn "cannot open $LINK_INFO\n";
1558
1559 system("echo content of AAPMC.log:") if ($DebugPrint & 1);
1560 system("if exist $AAPMCLOG (type $AAPMCLOG) else echo File not exist") if ($DebugPrint & 2);
1561
1562 if( ERR::AAPMCLOG_SUCCESS == &AAPMCLogParser::Open($AAPMCLOG))
1563 {
1564 my $report = "[Before Adjustment]\n";
1565 while(my ($key, $value) = each(%OriginalList))
1566 {
1567 my $string = sprintf(" $key: $value\n");
1568
1569 $report = $report.$string;
1570 }
1571
1572
1573 $report .= "[AfterAdjustment]\n";
1574
1575 while(my ($key, $value) = each(%ChangeList))
1576 {
1577 my $string = sprintf(" $key: $value\n");
1578
1579 $report = $report.$string;
1580 }
1581
1582 my $P4Info_ref = &AUTO_ADJUST::CreateP4InfoTemplate("",#OWNER,
1583 "",#$PROJECT,
1584 "Auto adjust FAT setting",
1585 $report);
1586
1587
1588 $err = &AAPMCLogParser::AddOneChangeRecord("$BOARD_FOLDER\\custom_MemoryDevice.h",
1589 \%ChangeList, \%$P4Info_ref);
1590 print "[AAPMC] return code: $error_code{$err}($err)\n";
1591 if($err == ERR::ERR_MODIFYDUPLICATED)
1592 {
1593 printf(LINK_INFO "[AAPMC] can't modified more than twice\n");
1594
1595 }
1596 elsif ($err == ERR::AAPMCLOG_SUCCESS)
1597 {
1598 printf(LINK_INFO "[AAPMC] add successfully!\n".$report);
1599
1600 }
1601 else
1602 {
1603 printf(LINK_INFO "[AAPMC] unexcept error: $err\n");
1604 }
1605 &AAPMCLogParser::Close($AAPMCLOG);
1606 }
1607 else
1608 {
1609 printf(LINK_INFO "[AAPMC] load AAPMCLog failed\n");
1610 }
1611
1612 close LINK_INFO;
1613 system("echo content of CheckBinaryBlockUsage.log:") if ($DebugPrint & 1);
1614 system("if exist .\\build\\$PROJECT\\log\\CheckBinaryBlockUsage.log (type .\\build\\$PROJECT\\log\\CheckBinaryBlockUsage.log) else echo File not exist") if ($DebugPrint & 2);
1615 system("echo content of $LINK_INFO") if ($DebugPrint & 2);
1616 system("type $LINK_INFO") if ($DebugPrint & 2);
1617
1618 return $err;
1619 }
1620 else
1621 {
1622 system("echo content of CheckBinaryBlockUsage.log") if ($DebugPrint & 1);
1623 system("if exist .\\build\\$PROJECT\\log\\CheckBinaryBlockUsage.log (type .\\build\\$PROJECT\\log\\CheckBinaryBlockUsage.log) else echo File not exist") if ($DebugPrint & 2);
1624 return ERR::NO_MODIFY
1625 }
1626
1627
1628}
1629
1630sub cksysdrv_die
1631{
1632 my ($err, $error_msg, $file, $line_no) = @_;
1633 my $final_error_msg = "[ckSysDrv]: $error_msg at $file line $line_no : ($error_code{$err})!\n";
1634
1635 print($final_error_msg);
1636
1637 if ($#ARGV > 5)
1638 {
1639 open(LINK_INFO, "> $LINK_INFO") or die "cannot open LINK_INFO: $LINK_INFO\n";
1640 printf(LINK_INFO $final_error_msg);
1641 close LINK_INFO;
1642 }
1643 exit $err;
1644}
1645