blob: c5b38b6dd384c25eb1c1a4ac5aae21b2193e5eff [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001#!/usr/bin/perl
2#
3# Copyright Statement:
4# --------------------
5# This software is protected by Copyright and the information contained
6# herein is confidential. The software may not be copied and the information
7# contained herein may not be used or disclosed except with the written
8# permission of MediaTek Inc. (C) 2006
9#
10# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
11# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
12# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
13# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
14# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
15# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
16# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
17# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
18# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
19# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
20# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
21# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
22#
23# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
24# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
25# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
26# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
27# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
28#
29# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
30# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
31# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
32# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
33# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
34#
35#*****************************************************************************
36#*
37#* Filename:
38#* ---------
39#* emigenflash.pl
40#*
41#* Project:
42#* --------
43#*
44#*
45#* Description:
46#* ------------
47#* Parse and generate flash parameter
48#*
49#* Author:
50#* -------
51#* Way Chen (mtk54483)
52#*
53#*============================================================================
54#* HISTORY
55#* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
56#*------------------------------------------------------------------------------
57#* $Revision$
58#* $Modtime$
59#* $Log$
60#*
61#* 05 22 2014 tafang.chen
62#* [MOLY00062786] [UMOLY][SM]
63#* Initial MoDIS build env - fix path problem.
64#*
65#* 04 23 2014 guo-huei.chang
66#* [MOLY00062623] [UMOLY] update TK6291 emi
67#* updat emigen flow for generating external emi size when EMI is not in MD own.
68#*
69#* 04 21 2014 guo-huei.chang
70#* [MOLY00063203] [EMIGEN] Update EMIGEN for Smart Phone Project
71#* Update emigen to generate EMI size for none EMI support
72#*
73#*
74#*------------------------------------------------------------------------------
75#* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
76#*============================================================================
77#****************************************************************************/
78
79my $nor_fat_base_offset;
80my $nor_fat_size_offset;
81my $nor_partition_sector_offset;
82my $nor_nand_fat_base_offset;
83my $nor_nand_fat_size_offset;
84my $nor_nand_partition_sector_offset;
85my $nfb_fat_base_offset;
86my $nfb_fat_size_offset;
87my $nfb_partition_sector_offset;
88my $cmem_max_blocks = 0;
89my $cmem_max_sectors = 0;
90my $DebugPrint = 1; # 1 for debug; 0 for non-debug
91#****************************************************************************
92# subroutine: Calculate_FAT_Info
93# input: $info_list_href: input list reference of list of MDL info
94# $combo_mem_count: number of memory devices selected
95# $combo_sip_count: number of SIPs
96# $mem_dev_type: MEMORY_DEVICE_TYPE
97# $info_output_href: output hash reference for common MDL info,
98# including minimum physical flash size,
99# minimum small block start address
100# maximum default FAT base address
101# minimum default FAT size
102# minimum RAM size
103# common flash series information
104# common single/multiple-bank definition
105# common PBP information
106# minimum PBP size
107#****************************************************************************
108sub Calculate_FAT_Info
109{
110 my ($MAKEFILE_OPTIONS_LOCAL, $CUSTOM_MEM_DEV_OPTIONS_LOCAL, $COMM_MDL_INFO_LOCAL, $MDL_INFO_LIST_LOCAL, $NOR_FLASH_BASE_ADDRESS_VAL_LOCAL, $NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL,$nor_size_Mb_LOCAL, $CUSTOM_FEATURE_CFG_OPTIONS_LOCAL, $ENTIRE_BLOCK_INFO_START_LIST_LOCAL, $ENTIRE_BLOCK_INFO_SIZE_LIST_LOCAL) = @_;
111 ### Print out the physical available flash size
112my $flash_limit = sprintf("0x%08X", $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'});
113
114#print "$COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'}, $COMM_MDL_INFO_LOCAL->{1}->{'Flash Size'}\n" if ($DebugPrint == 1);
115
116### Calculate real FAT start address and size based on customization
117if ((defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_BASE_ADDRESS}) && (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_SIZE}))
118{
119 $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL = hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_BASE_ADDRESS});
120 $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL = hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_SIZE});
121}
122elsif ((defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_BASE_ADDRESS}) && (!defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_SIZE}))
123{
124 $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL = hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_BASE_ADDRESS});
125 if (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{__NOR_FDM5__}) # for NOR FDM5, small blocks at the end of the flash should not be used
126 {
127 $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL = $COMM_MDL_INFO_LOCAL->{0}->{'Small Block Start'} - hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_BASE_ADDRESS});
128 }
129 else
130 {
131 $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL = $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'} - hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_BASE_ADDRESS});
132 }
133}
134elsif ((!defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_BASE_ADDRESS}) && (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_SIZE}))
135{
136 $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL = $COMM_MDL_INFO_LOCAL->{0}->{'Default FAT Base'};
137 $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL = hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_SIZE});
138}
139else
140{
141 $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL = $COMM_MDL_INFO_LOCAL->{0}->{'Default FAT Base'};
142 $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL = $COMM_MDL_INFO_LOCAL->{0}->{'Default FAT Size'};
143}
144
145if($MAKEFILE_OPTIONS_LOCAL->{'serial_flash_support'} eq 'TRUE')
146{
147 $COMM_MDL_INFO_LOCAL->{0}->{'Default FAT Base'} = $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL;
148 $COMM_MDL_INFO_LOCAL->{0}->{'Default FAT Size'} = $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL;
149}
150elsif($MAKEFILE_OPTIONS_LOCAL->{'nand_support'} eq 'TRUE')
151{
152 $COMM_MDL_INFO_LOCAL->{0}->{'Default FAT Base'} = hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NAND_BOOTING_NAND_FS_BASE_ADDRESS});
153 $COMM_MDL_INFO_LOCAL->{0}->{'Default FAT Size'} = hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NAND_BOOTING_NAND_FS_SIZE});
154}
155
156### work-around for bad small block issue
157my $fat_size_shrink;
158if ((($$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL+$$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL)>$COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'}) && (($$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL+$$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL)<=($nor_size_Mb_LOCAL/8*1024*1024)))
159{
160 $fat_size_shrink = sprintf(" - 0x%08x", $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL+$$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL-$COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'});
161 $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL = $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL - ($$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL+$$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL-$COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'});
162}
163
164#print "NOR_FLASH_BASE_ADDRESS_VAL = $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL, NOR_ALLOCATED_FAT_SPACE_VAL = $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL\n" if ($DebugPrint == 1);
165
166### Check FAT settings validity
167&error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: FAT space cannot exceed physical NOR flash size!", __FILE__, __LINE__)
168 if (($$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL<0) || ($$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL<0));
169&error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: FAT space cannot exceed physical NOR flash size!", __FILE__, __LINE__)
170 if (($$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL+$$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL) > ($COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'}));
171if (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{__NOR_FDM5__})
172{
173 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: FAT space cannot include small blocks in NOR FDM 5.0!", __FILE__, __LINE__)
174 if (($$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL+$$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL) > $COMM_MDL_INFO_LOCAL->{0}->{'Small Block Start'});
175}
176
177### FAT tuning for FOTA
178$nor_fat_base_offset = "0x0";
179$nor_fat_size_offset = "0x0";
180$nor_partition_sector_offset = 0;
181$nor_nand_fat_base_offset = "0x0";
182$nor_nand_fat_size_offset = "0x0";
183$nor_nand_partition_sector_offset = 0;
184$nfb_fat_base_offset = "0x0";
185$nfb_fat_size_offset = "0x0";
186$nfb_partition_sector_offset = 0;
187
188##FOTA Feature Related Code, Currently we do not use in MT6290
189if ($MAKEFILE_OPTIONS_LOCAL->{'fota_enable'} eq 'FOTA_DM')
190{
191 if ($MAKEFILE_OPTIONS_LOCAL->{'nand_flash_booting'} ne 'NONE')
192 {
193 ###
194 # image head area size = block number * block size (0x20000)
195 # = (1(FOTA_BL_IMG_MAX_SIZE) + 6(FOTA_UE_RESIDENT_FLASH_SPACE_SIZE) + 6(FOTA_UE_BACKUP_FLASH_SPACE_SIZE) + 8(image list block) + 1(ext_bootloader) + 2(bad block margin)) * 0x20000 = 0x300000
196 my $image_head_area_size = 0x300000;
197
198 my ($package_storage_base, $package_storage_size);
199 ###
200 # FOTA_PACKAGE_STORAGE_BASE = image head area size + all ROM sizes (ROM, SECONDARY_ROM, THIRD_ROM, DEMAND_PAGING_ROM0)
201 if (defined $MAKEFILE_OPTIONS_LOCAL->{'nand_flash_booting'} and $MAKEFILE_OPTIONS_LOCAL->{'nand_flash_booting'} eq 'ENFB')
202 {
203 $package_storage_base = $image_head_area_size + 0x900000 + 0x1500000 + 0x800000;
204 }
205 elsif (defined $MAKEFILE_OPTIONS_LOCAL->{'nand_flash_booting'} and $MAKEFILE_OPTIONS_LOCAL->{'nand_flash_booting'} eq 'ONDEMAND')
206 {
207 $package_storage_base = $image_head_area_size + 0x400000 + 0xC00000 + 0xE00000;
208 }
209 elsif (defined $MAKEFILE_OPTIONS_LOCAL->{'nand_flash_booting'} and $MAKEFILE_OPTIONS_LOCAL->{'nand_flash_booting'} eq 'MIXED')
210 {
211 $package_storage_base = $image_head_area_size + 0x400000 + 0xF00000 + 0x800000 + 0x400000;
212 }
213 elsif (defined $MAKEFILE_OPTIONS_LOCAL->{'nand_flash_booting'} and $MAKEFILE_OPTIONS_LOCAL->{'nand_flash_booting'} eq 'BASIC')
214 {
215 $package_storage_base = $image_head_area_size + 0x800000 + 0x1600000;
216 }
217 $package_storage_size = (hex($CUSTOM_FEATURE_CFG_OPTIONS_LOCAL->{CONFIG_FOTA_PACKAGE_AREA_SIZE}) / 0x20000) * 0x20000;
218
219 my $recommend_fat_base;
220 if ($MAKEFILE_OPTIONS_LOCAL->{'secure_support'} eq 'TRUE')
221 {
222 # When SECURE_SUPPORT = TRUE, FAT_BASE_ADDRESS = FOTA_PACKAGE_STORAGE_BASE + FOTA_PACKAGE_STORAGE_SIZE + ((4 + FOTA_EXTRA_RESERVED_BLOCKS) * (block size)0x20000)
223 $recommend_fat_base = $package_storage_base + $package_storage_size + ((4 + 5) * 0x20000);
224 }
225 else
226 {
227 # When SECURE_SUPPORT = FALSE, FAT_BASE_ADDRESS = FOTA_PACKAGE_STORAGE_BASE + FOTA_PACKAGE_STORAGE_SIZE
228 $recommend_fat_base = $package_storage_base + $package_storage_size;
229 }
230 if (($recommend_fat_base - hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NAND_BOOTING_NAND_FS_BASE_ADDRESS})) > 0)
231 {
232 $nfb_fat_base_offset = sprintf("0x%08X", $recommend_fat_base - hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NAND_BOOTING_NAND_FS_BASE_ADDRESS}));
233 $nfb_fat_size_offset = sprintf("0x%08X", $recommend_fat_base - hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NAND_BOOTING_NAND_FS_BASE_ADDRESS}));
234 if (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NAND_BOOTING_NAND_FS_FIRST_DRIVE_SECTORS})
235 {
236 my $nand_fat_partition_sectors;
237 if ($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NAND_BOOTING_NAND_FS_FIRST_DRIVE_SECTORS} =~ /\(*(\d+)\)*/)
238 {
239 $nand_fat_partition_sectors = $1;
240 }
241 $nfb_partition_sector_offset = sprintf("%d", ($recommend_fat_base - hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NAND_BOOTING_NAND_FS_BASE_ADDRESS})) / 512) if (($nand_fat_partition_sectors - ($recommend_fat_base-hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NAND_BOOTING_NAND_FS_BASE_ADDRESS}))/512) >= 4096); # NAND user drive should be no less than 4096 sectors
242 }
243 }
244 }
245 elsif ($MAKEFILE_OPTIONS_LOCAL->{'system_drive_on_nand'} eq 'TRUE' or $MAKEFILE_OPTIONS_LOCAL->{'fota_update_package_on_nand'} eq 'TRUE')
246 {
247 my $package_storage_size = (hex($CUSTOM_FEATURE_CFG_OPTIONS_LOCAL->{CONFIG_FOTA_PACKAGE_AREA_SIZE}) / 0x20000) * 0x20000;
248 $nor_nand_fat_base_offset = sprintf("0x%08X", $package_storage_size);
249 $nor_nand_fat_size_offset = sprintf("0x%08X", $package_storage_size);
250 if (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NAND_FS_FIRST_DRIVE_SECTORS})
251 {
252 my $nand_fat_partition_sectors;
253 if ($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NAND_FS_FIRST_DRIVE_SECTORS} =~ /\(*(\d+)\)*/)
254 {
255 $nand_fat_partition_sectors = $1;
256 }
257 $nor_nand_partition_sector_offset = sprintf("%d", $package_storage_size / 512) if (($nand_fat_partition_sectors - ($package_storage_size)/512) >= 4096); # NAND user drive should be no less than 4096 sectors
258 }
259 }
260 elsif (!exists $MAKEFILE_OPTIONS_LOCAL->{'emmc_booting'} or $MAKEFILE_OPTIONS_LOCAL->{'emmc_booting'} eq 'NONE') # FOTA update package will be put in a different partition from FS
261 {
262 my $fota_block_number = $CUSTOM_FEATURE_CFG_OPTIONS_LOCAL->{CONFIG_FOTA_PACKAGE_BLOCK_NUMBER};
263 my $ori_nor_flash_base_address_val = $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL;
264 my $ori_nor_allocated_fat_space_val = $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL;
265
266 ### Package Storage
267 while ($fota_block_number > 0)
268 {
269 my $tmp_block_sz;
270 $tmp_block_sz = &config_query_flash_block_sz($$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL, $COMM_MDL_INFO_LOCAL,$ENTIRE_BLOCK_INFO_START_LIST_LOCAL, $ENTIRE_BLOCK_INFO_SIZE_LIST_LOCAL);
271
272 $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL += $tmp_block_sz;
273 $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL -= $tmp_block_sz;
274 $fota_block_number--;
275 }
276
277 ### Backup Storage
278 my $query_address = 0;
279 my $max_block_size = 0;
280 while ($query_address < $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'})
281 {
282 my $cur_block_size = &config_query_flash_block_sz($query_address, $COMM_MDL_INFO_LOCAL, $ENTIRE_BLOCK_INFO_START_LIST_LOCAL, $ENTIRE_BLOCK_INFO_SIZE_LIST_LOCAL);
283 if ($cur_block_size > $max_block_size)
284 {
285 $max_block_size = $cur_block_size;
286 }
287 $query_address += $cur_block_size;
288 }
289 $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL += 2 * $max_block_size;
290 $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL -= 2 * $max_block_size;
291
292 if (($$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL - $ori_nor_flash_base_address_val) > 0)
293 {
294 $nor_fat_base_offset = sprintf("0x%08X", $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL - $ori_nor_flash_base_address_val);
295 $nor_fat_size_offset = sprintf("0x%08X", $$ori_nor_allocated_fat_space_val - $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL);
296 if (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_FIRST_DRIVE_SECTORS})
297 {
298 my $nor_fat_partition_sectors;
299 if ($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_FS_FIRST_DRIVE_SECTORS} =~ /\(*(\d+)\)*/)
300 {
301 $nor_fat_partition_sectors = $1;
302 }
303 $nor_partition_sector_offset = sprintf("%d", ($ori_nor_allocated_fat_space_val - $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL) / 512) if (($nor_fat_partition_sectors - ($ori_nor_allocated_fat_space_val-$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL)/512) >= 128); # NOR user drive should be no less than 128 sectors
304 }
305 }
306 }
307}##end if ($MAKEFILE_OPTIONS_LOCAL->{'fota_enable'} eq 'FOTA_DM')
308
309### Calculate TOTAL_BLOCKS and NOR_BLOCK_SIZE by different memory devices
310$cmem_max_blocks = 0;
311$cmem_max_sectors = 0;
312$nor_block_size = 0;
313for (1..$CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT})
314{
315 my $mem_idx = $_;
316 my (@cur_regions, @cur_banks, @cur_blocks, @cur_new_regions, @cur_blocks_start, @cur_blocks_size);
317 my $cur_blocks_sum = 0;
318 my $cur_regions_sum = 0;
319 my $cur_total_blocks = 0;
320 my $cur_nor_block_size = 0;
321 my $cur_total_sectors = 0;
322 my $cur_sector_size = 0;
323 my $cur_bank_str = 0;
324 my $cur_block_str = 0;
325
326 $cur_sector_size = ($MDL_INFO_LIST_LOCAL->[$mem_idx]->{1}->{'Comm. Series'} eq 'INTEL_SIBLEY') ? 0x400 : 0x200;
327 ##MDL CS1 is flash, COMM MDL number 0 is flash info
328 @cur_regions = &split_info($MDL_INFO_LIST_LOCAL->[$mem_idx]->{1}->{'Last Bank'}->{'Region'});
329 $cur_bank_str = $MDL_INFO_LIST_LOCAL->[$mem_idx]->{1}->{'Device Geometry'}->{'Bank Info.'};
330 @cur_banks = &split_info($cur_bank_str);
331 $cur_block_str = $MDL_INFO_LIST_LOCAL->[$mem_idx]->{1}->{'Device Geometry'}->{'Block Info.'};
332 @cur_blocks = &split_info($cur_block_str);
333
334 for (0..$#cur_blocks)
335 {
336 if ($cur_blocks[$_] =~ /\{(0x\w+),\s*(0x\w+)\}/) # match {0x0,0x10000}
337 {
338 last if (hex($1) >= $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'}); # end block infor traversal when the flash end among all memories has been reached
339 push @cur_blocks_start, $1;
340 push @cur_blocks_size, $2;
341 }
342 }
343 push @cur_blocks_start, $flash_limit;
344 for (0..($#cur_blocks_start-1))
345 {
346 my $target_region = $cur_blocks_size[$_];
347 my $tmp_block_count = 0;
348 print "$_: $target_region\n"if ($DebugPrint == 1);
349
350 while ($cur_blocks_sum < hex($cur_blocks_start[$_+1]))
351 {
352 $cur_blocks_sum += hex($cur_blocks_size[$_]);
353 if ($cur_blocks_sum > $$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL)
354 {
355 $cur_regions_sum += hex($cur_blocks_size[$_]);
356 $tmp_block_count++;
357 }
358 last if ($cur_regions_sum >= $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL);
359 }
360 if ($tmp_block_count > 0)
361 {
362 $cur_total_blocks += $tmp_block_count;
363 if (hex($target_region) > hex($cur_nor_block_size)) # Find the largest block size within FS
364 {
365 $cur_nor_block_size = $target_region;
366 }
367 }
368 last if ($cur_regions_sum >= $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL);
369 }
370 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: FAT space must be multiples of blocks!", __FILE__, __LINE__) if ($cur_regions_sum > $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL);
371
372 ### Calculate the current number of sectors
373 ### S1 = ((NOR_ALLOCATED_FAT_SPACE - NOR_BLOCK_SIZEMCP1 * SNOR_ERASE_QUEUE_SIZE) / SECTOR_SIZE)
374 ### NOR_ALLOCATED_FAT_SPACE := NOR_BOOTING_NOR_FS_SIZE
375 ### SNOR_ERASE_QUEUE_SIZE := NOR_FDM4_ESB_PARAMETER_ERASE_QUEUE_SIZE or 5 (default value)
376 ### NOR_SYSTEM_DRIVE_RESERVED_BLOCK := NOR_PARAMETER_SYSTEM_DRIVE_RESERVED_BLOCK or 3 (default value)
377 ### NOR_BLOCK_SIZEMCP1 := The largest block size within FAT in MCP 1.
378 ### SECTOR_SIZE:
379 ### Sibley:=0x400
380 ### Non-Sibley := 0x200
381 if ($MAKEFILE_OPTIONS_LOCAL->{'enhanced_single_bank_nor_flash_support'} eq 'TRUE')
382 {
383 $cur_total_sectors = ($$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL - (hex($cur_nor_block_size) * $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_FDM4_ESB_PARAMETER_ERASE_QUEUE_SIZE})) / $cur_sector_size;
384 }
385 else
386 {
387 $cur_total_sectors = ($$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL - (hex($cur_nor_block_size) * $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_PARAMETER_SYSTEM_DRIVE_RESERVED_BLOCK})) / $cur_sector_size;
388 }
389 print "FAT SPACE is: $$NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL, BlockSize is: $cur_nor_block_size, SectorSize is $cur_sector_size\n"if ($DebugPrint == 1);
390
391 ### Find the overall max TOTAL_BLOCKS and NOR_BLOCK_SIZE
392 if ($nor_block_size < hex($cur_nor_block_size))
393 {
394 $nor_block_size = hex($cur_nor_block_size);
395 }
396 if ($cmem_max_blocks < $cur_total_blocks)
397 {
398 $cmem_max_blocks = $cur_total_blocks;
399 }
400 if ($cmem_max_sectors < $cur_total_sectors)
401 {
402 $cmem_max_sectors = $cur_total_sectors;
403 }
404}
405print "TOTAL_BLOCKS > 127 , recommend enable FDM5.0 feature!\n" if ($cmem_max_blocks > 127);
406}
407
408#****************************************************************************
409# subroutine: Validate_FAT_NORRAWDISK_OVERLAP
410# input: $info_list_href: input list reference of list of MDL info
411# $combo_mem_count: number of memory devices selected
412# $combo_sip_count: number of SIPs
413# $mem_dev_type: MEMORY_DEVICE_TYPE
414# $info_output_href: output hash reference for common MDL info,
415# including minimum physical flash size,
416# minimum small block start address
417# maximum default FAT base address
418# minimum default FAT size
419# minimum RAM size
420# common flash series information
421# common single/multiple-bank definition
422# common PBP information
423# minimum PBP size
424#****************************************************************************
425sub Validate_FAT_NORRAWDISK_OVERLAP
426{
427 my ($CUSTOM_MEM_DEV_OPTIONS_LOCAL, $COMM_MDL_INFO, $NOR_FLASH_BASE_ADDRESS_VAL_LOCAL, $NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL, $CUSTOM_MEMORY_DEVICE_HDR_LOCAL) = @_;
428 my %dsk_layout_hash;
429 my @dsk_layout_sort_list;
430 $dsk_layout_hash{$NOR_FLASH_BASE_ADDRESS_VAL_LOCAL} = $NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL;
431 if (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK0_BASE_ADDRESS})
432 {
433 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot configure NOR Raw Disk0 larger than physical NOR flash size!", __FILE__, __LINE__)
434 if ((hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK0_BASE_ADDRESS})+hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK0_SIZE})) > $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'});
435 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot configure NOR Raw Disk0 the same base address as FAT!", __FILE__, __LINE__)
436 if (hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK0_BASE_ADDRESS}) == $NOR_FLASH_BASE_ADDRESS_VAL_LOCAL);
437 $dsk_layout_hash{hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK0_BASE_ADDRESS})} = hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK0_SIZE});
438 }
439 if (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL{NOR_BOOTING_NOR_DISK1_BASE_ADDRESS})
440 {
441 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot configure NOR Raw Disk1 larger than physical NOR flash size!", __FILE__, __LINE__)
442 if ((hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK1_BASE_ADDRESS})+hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK1_SIZE})) > $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'});
443 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot configure NOR Raw Disk1 the same base address as FAT!", __FILE__, __LINE__)
444 if (hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK1_BASE_ADDRESS}) == $NOR_FLASH_BASE_ADDRESS_VAL_LOCAL);
445 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot configure NOR Raw Disk1 the same base address as NOR Raw Disk0!", __FILE__, __LINE__)
446 if (hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK1_BASE_ADDRESS}) == hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK0_BASE_ADDRESS}));
447 $dsk_layout_hash{hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK1_BASE_ADDRESS})} = hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK1_SIZE});
448 }
449 foreach (sort {$a <=> $b} keys %dsk_layout_hash)
450 {
451 push @dsk_layout_sort_list, $_;
452 }
453 foreach (1..$#dsk_layout_sort_list)
454 {
455 error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: NOR Flash disk overlapping detected. Please check NOR Raw disk and FAT setting!", __FILE__, __LINE__)
456 if (($dsk_layout_sort_list[$_-1]+$dsk_layout_hash{$dsk_layout_sort_list[$_-1]}) > $dsk_layout_sort_list[$_]);
457 }
458}
459
460#****************************************************************************
461# subroutine: Calculate_NORRAWDISK_Region_Info
462# input: $info_list_href: input list reference of list of MDL info
463# $combo_mem_count: number of memory devices selected
464# $combo_sip_count: number of SIPs
465# $mem_dev_type: MEMORY_DEVICE_TYPE
466# $info_output_href: output hash reference for common MDL info,
467# including minimum physical flash size,
468# minimum small block start address
469# maximum default FAT base address
470# minimum default FAT size
471# minimum RAM size
472# common flash series information
473# common single/multiple-bank definition
474# common PBP information
475# minimum PBP size
476#****************************************************************************
477sub Calculate_NORRAWDISK_Region_Info
478{
479 my ($CUSTOM_MEM_DEV_OPTIONS_LOCAL) = @_;
480 my (@regions_disk0, @regions_disk1);
481 for (0..$CUSTOM_MEM_DEV_OPTIONS_LOCAL->{NOR_BOOTING_NOR_DISK_NUM})
482 {
483 my $nor_booting_nor_disk_base_address = sprintf("NOR_BOOTING_NOR_DISK%d_BASE_ADDRESS", $_);
484 my $nor_booting_nor_disk_size = sprintf("NOR_BOOTING_NOR_DISK%d_SIZE", $_);
485 my $nor_booting_nor_disk_index = $_;
486 #print "[$nor_booting_nor_disk_index] Nor Disk Base: $nor_booting_nor_disk_base_address\n"if ($DebugPrint == 1);
487 #print "[$nor_booting_nor_disk_index] Nor Disk Size: $nor_booting_nor_disk_size\n"if ($DebugPrint == 1);
488
489 if (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{$nor_booting_nor_disk_base_address})
490 {
491 #print "RAW DISK Check!\n"if ($DebugPrint == 1);
492 for (0..($#entire_block_info_start_list-1))
493 {
494 my $target_region;
495 my $tmp_block_count = 0;
496 my $tmp_blocks_sum = 0;
497 my $tmp_regions_sum = 0;
498 while ($tmp_blocks_sum < $entire_block_info_start_list[$_+1])
499 {
500 $tmp_blocks_sum += $entire_block_info_size_list[$_];
501 if ($tmp_blocks_sum > hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{$nor_booting_nor_disk_base_address}))
502 {
503 $tmp_regions_sum += $entire_block_info_size_list[$_];
504 $target_region = sprintf("0x%X", $entire_block_info_size_list[$_]);
505 $tmp_block_count++;
506 }
507 if ($tmp_regions_sum >= hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{$nor_booting_nor_disk_size}))
508 {
509 last;
510 }
511 }
512 if ($tmp_block_count > 0)
513 {
514 if ($nor_booting_nor_disk_index == 0)
515 {
516 push @regions_disk0, "{$target_region,$tmp_block_count}";
517 }
518 elsif ($nor_booting_nor_disk_index == 1)
519 {
520 push @regions_disk1, "{$target_region,$tmp_block_count}";
521 }
522 }
523 if ($tmp_regions_sum >= hex($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{$nor_booting_nor_disk_size}))
524 {
525 last;
526 }
527 }
528 }
529 }
530}
531#****************************************************************************
532# subroutine: get_common_MDL_info
533# input: $info_list_href: input list reference of list of MDL info
534# $combo_mem_count: number of memory devices selected
535# $combo_sip_count: number of SIPs
536# $mem_dev_type: MEMORY_DEVICE_TYPE
537# $info_output_href: output hash reference for common MDL info,
538# including minimum physical flash size,
539# minimum small block start address
540# maximum default FAT base address
541# minimum default FAT size
542# minimum RAM size
543# common flash series information
544# common single/multiple-bank definition
545# common PBP information
546# minimum PBP size
547#****************************************************************************
548sub get_common_MDL_info
549{
550 #my ($info_list_href, $combo_mem_count, $combo_sip_count, $mem_dev_type, $info_output_href, $LPSDRAM_CHIP_SELECT_LOCAL, $MAKEFILE_OPTIONS, $CUSTOM_MEM_DEV_OPTIONS, $CUSTOM_MEMORY_DEVICE_HDR) = @_;
551 my ($info_list_href, $CUSTOM_MEM_DEV_OPTIONS_LOCAL, $info_output_href, $MAKEFILE_OPTIONS_LOCAL, $LPSDRAM_CHIP_SELECT_LOCAL, $CUSTOM_MEMORY_DEVICE_HDR_LOCAL, $emi_is_existed) = @_;
552 my $combo_mem_count = $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT};
553 my $combo_sip_count = $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_SIP_ENTRY_COUNT};
554 my $mem_dev_type = $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{MEMORY_DEVICE_TYPE};
555 my $platform = $MAKEFILE_OPTIONS_LOCAL->{'platform'};
556 my $min_flash_size = 0xffffffff;
557 my $max_nand_block_size = 0;
558 my $min_small_block_start = 0xffffffff;
559 my $max_fat_base = 0;
560 my $min_fat_space = 0xffffffff;
561 my $Size_Mb_ram_min = 0xffffffff*8/1024/1024; # minimum size in "Size (Mb)" field for RAM
562 my $ADMUX_CS0;
563 my $ADMUX_CS1;
564 my $if_DRAM;
565 my $Comm_Series_CS0_all = '*'; # all "Comm. Series" information
566 my $Comm_Series_CS1_all = '*'; # all "Comm. Series" information
567 my $Bank_if_S = 'M'; # mark as 'S' if there is any device whose "Bank" field is 'S'
568 my $PBP_Y_N_if_Y = 'N'; # mark as 'N' if there is any device whose "PBP -> Y/N" field is 'N'
569 my $PBP_Size_W_min = 0xffffffff; # minimum size in "PBP -> Size(W)" field
570 my $Last_Bank_Region; # common "Last Bank -> Region" field
571 my $Geometry_Bank_Info; # common "Geometry -> Bank Info." field
572 my $Geometry_Block_Info; # common "Geometry -> Block Info." field
573
574 #print "Flash PN: $info_list_href->[1]->{1}->{'Part Number'}, $info_list_href->[1]->{1}->{'Flash Size'}\n";
575
576 for (1..$combo_mem_count)
577 {
578 ### Find the smallest default FAT configuration among all MCPs
579 my $cur_flash_size = 0; # physical flash size (excluding bad small blocks for Toshiba)
580 my $cur_small_block_start = 0; # the starting location of small blocks at the end of a flash
581 my $cur_sum_of_regions = 0; # the sum of the regions in the last bank
582 my $cur_fat_base = 0; # default FAT base (physical flash size - last bank size)
583 my $cur_fat_space = 0; # default FAT size (last bank size)
584 my @cur_blocks_start; # list of Block Info starting addresses
585 my @cur_blocks_size; # list of Block Info sizes
586 my @cur_regions = &split_info($info_list_href->[$_]->{1}->{'Last Bank'}->{'Region'}); # list of Last Bank -> Region Info.
587 my $cur_bank_str = $info_list_href->[$_]->{1}->{'Device Geometry'}->{'Bank Info.'};
588 my @cur_banks = &split_info($cur_bank_str); # list of Bank Info.
589 my $cur_block_str = $info_list_href->[$_]->{1}->{'Device Geometry'}->{'Block Info.'};
590 my @cur_blocks = &split_info($cur_block_str); # list of Block Info.
591
592 # Calculate default FAT size/start address (Last Bank)
593 for (0..$#cur_regions) # calculate the sum of last bank
594 {
595 if ($cur_regions[$_] =~ /\{(0x\w+)\s*,\s*(\d+)\}/) # match {0x20000, 7}
596 {
597 $cur_sum_of_regions += hex($1) * $2;
598 }
599 }
600 for (0..$#cur_banks) # calculate the physical flash size
601 {
602 if ($cur_banks[$_] =~ /\{(0x\w+)\s*,\s*(\d+)\}/) # match {0x20000, 7}
603 {
604 $cur_flash_size += hex($1) * $2;
605 $cur_small_block_start += hex($1) * $2;
606 }
607 }
608 if (($#cur_regions>0) && (defined $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{__NOR_FDM5__})) # for NOR FDM5, small blocks at the end of the flash should be excluded
609 {
610 if ($cur_blocks[$#cur_blocks] =~ /\{(0x\w+)\s*,\s*(0x\w+)\}/) # match {0xFF0000,0x2000}
611 {
612 $cur_small_block_start = hex($1);
613 }
614 $cur_fat_space = $cur_sum_of_regions - ($cur_flash_size-$cur_small_block_start);
615 }
616 else
617 {
618 $cur_fat_space = $cur_sum_of_regions;
619 }
620 $cur_fat_base = $cur_flash_size - $cur_sum_of_regions;
621
622 ##MT6290 Operation
623 #if($platform eq 'MT6290')
624 #{
625 if ($MAKEFILE_OPTIONS_LOCAL->{'nand_support'} eq 'TRUE')
626 {
627 if (defined $info_list_href->[$_]->{1}->{'NAND Size(MB)'})##Fill NAND Flash Size if NAND Flash is exist
628 {
629 $cur_flash_size = $info_list_href->[$_]->{1}->{'NAND Size(MB)'} * 1024 * 1024;
630 }
631 else
632 {
633 $cur_flash_size = 0xffffffff;
634 }
635 }
636 #}
637
638 # Temporarily store physical flash size, small block start, and default FAT size/base for future reference
639 $info_list_href->[$_]->{1}->{'Flash Size'} = $cur_flash_size;
640 $info_list_href->[$_]->{1}->{'Small Block Start'} = $cur_small_block_start;
641 $info_list_href->[$_]->{1}->{'Default FAT Base'} = $cur_fat_base;
642 $info_list_href->[$_]->{1}->{'Default FAT Size'} = $cur_fat_space;
643
644 #print "Flash PN: $info_list_href->[$_]->{1}->{'Part Number'}, FlashSize: $info_list_href->[$_]->{1}->{'Flash Size'}, SmallBlockStart: $info_list_href->[$_]->{1}->{'Small Block Start'}, FATBase: $info_list_href->[$_]->{1}->{'Default FAT Base'}, FATSize: $info_list_href->[$_]->{1}->{'Default FAT Size'}\n"if ($DebugPrint == 1);
645 # In order to speed-up, assume the largest FAT base will be smaller than the physical flash size first
646 # Find the largest FAT base
647 if ($max_fat_base < $cur_fat_base)
648 {
649 $max_fat_base = $cur_fat_base;
650 }
651 # Find the smallest flash size
652 if ($min_flash_size > $cur_flash_size)
653 {
654 $min_flash_size = $cur_flash_size;
655 }
656 # Find the smallest small block start
657 if ($min_small_block_start > $cur_small_block_start)
658 {
659 $min_small_block_start = $cur_small_block_start;
660 }
661
662 ### Find the minimum RAM size in Mb
663
664 my $cur_Size_Mb_ram = $info_list_href->[$_]->{0}->{'Density (Mb)'};
665 if ($Size_Mb_ram_min > $cur_Size_Mb_ram)
666 {
667 $Size_Mb_ram_min = $cur_Size_Mb_ram;
668 }
669
670 ### Find common ADMUX definition
671 if ($info_list_href->[$_]->{0}->{'ADMUX'} =~ /YES/i)
672 {
673 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot select ADMUX/AD-DEMUX at one time! Please change selected MCP!", __FILE__, __LINE__) if ($ADMUX_CS0 eq "NO");
674 $ADMUX_CS0 = "YES";
675 }
676 elsif ($info_list_href->[$_]->{0}->{'ADMUX'} =~ /NO/i)
677 {
678 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot select ADMUX/AD-DEMUX at one time! Please change selected MCP!", __FILE__, __LINE__) if ($ADMUX_CS0 eq "YES");
679 $ADMUX_CS0 = "NO";
680 }
681 if ($info_list_href->[$_]->{1}->{'ADMUX'} =~ /YES/i)
682 {
683 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot select ADMUX/AD-DEMUX at one time! Please change selected MCP!", __FILE__, __LINE__) if ($ADMUX_CS1 eq "NO");
684 $ADMUX_CS1 = "YES";
685 }
686 elsif ($info_list_href->[$_]->{1}->{'ADMUX'} =~ /NO/i)
687 {
688 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot select ADMUX/AD-DEMUX at one time! Please change selected MCP!", __FILE__, __LINE__) if ($ADMUX_CS1 eq "YES");
689 $ADMUX_CS1 = "NO";
690 }
691
692 ### Find common "DRAM" information
693 if ($info_list_href->[$_]->{1}->{'DRAM'} =~ /YES/i)
694 {
695 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot select DRAM/PSRAM at one time! Please change selected MCP!", __FILE__, __LINE__) if ($if_DRAM eq "NO");
696 $if_DRAM = "YES";
697 }
698 elsif ($info_list_href->[$_]->{1}->{'DRAM'} =~ /NO/i)
699 {
700 &error_handler("$CUSTOM_MEMORY_DEVICE_HDR_LOCAL: Cannot select DRAM/PSRAM at one time! Please change selected MCP!", __FILE__, __LINE__) if ($if_DRAM eq "YES");
701 $if_DRAM = "NO";
702 }
703
704 ### Find common "Comm. Series" information
705 if ((defined $info_list_href->[$_]->{1}->{'Comm. Series'}) and ($info_list_href->[$_]->{1}->{'Comm. Series'} ne '*'))
706 {
707 if ($Comm_Series_CS0_all eq '*')
708 {
709 $Comm_Series_CS0_all = $info_list_href->[$_]->{1}->{'Comm. Series'};
710 }
711 else
712 {
713 $Comm_Series_CS0_all .= " $info_list_href->[$_]->{1}->{'Comm. Series'}";
714 }
715 }
716
717 if ((defined $info_list_href->[$_]->{1}->{'Comm. Series'}) and ($info_list_href->[$_]->{1}->{'Comm. Series'} ne '*'))
718 {
719 if ($Comm_Series_CS1_all eq '*')
720 {
721 $Comm_Series_CS1_all = $info_list_href->[$_]->{1}->{'Comm. Series'};
722 }
723 else
724 {
725 $Comm_Series_CS1_all .= " $info_list_href->[$_]->{1}->{'Comm. Series'}";
726 }
727 }
728
729 ### Find common single/multiple-bank definition
730 if ($info_list_href->[$_]->{1}->{'Bank'} =~ /S/i)
731 {
732 $Bank_if_S = 'S';
733 }
734
735 ### Find common PBP information
736 if ($info_list_href->[$_]->{1}->{'PBP'}->{'Y / N'} =~ /Y/i)
737 {
738 $PBP_Y_N_if_Y = 'Y';
739 }
740 #print "PBP1: $info_list_href->[$_]->{1}->{'PBP'}->{'Y / N'}, PBP2: $info_list_href->[$_]->{1}->{'PBP'}->{'Size (Byte)'}\n"if ($DebugPrint == 1);
741
742 ### Find the minimum PBP size
743 my $cur_PBP_size_W = ($mem_dev_type eq 'NOR_RAM_MCP') ? ($info_list_href->[$_]->{0}->{'PBP'}->{'Size(W)'}) : ($info_list_href->[$_]->{1}->{'PBP'}->{'Size (Byte)'}/2);
744 if ($cur_PBP_size_W eq '*' or $cur_PBP_size_W eq 'x' or $cur_PBP_size_W eq ' ')
745 {
746 $cur_PBP_size_W = 0;
747 }
748 if ($PBP_Size_W_min > $cur_PBP_size_W)
749 {
750 $PBP_Size_W_min = $cur_PBP_size_W;
751 }
752
753 ### Find the max block size
754 if (defined $info_list_href->[$_]->{$LPSDRAM_CHIP_SELECT_LOCAL}->{'NAND Block Size(KB)'})
755 {
756 if ($max_nand_block_size < $info_list_href->[$_]->{$LPSDRAM_CHIP_SELECT_LOCAL}->{'NAND Block Size(KB)'} * 1024)
757 {
758 $max_nand_block_size = $info_list_href->[$_]->{$LPSDRAM_CHIP_SELECT_LOCAL}->{'NAND Block Size(KB)'} * 1024;
759 }
760 }
761
762 }##end for (1..$combo_mem_count)
763
764 ### Work around when the FAT base is larger than some flash size
765 if (($max_fat_base > $min_flash_size) or ($max_fat_base > $min_small_block_start))
766 {
767 $max_fat_base = 0;
768 for (1..$combo_mem_count)
769 {
770 if (($info_list_href->[$_]->{1}->{'Default FAT Base'} < $min_flash_size) and ($info_list_href->[$_]->{1}->{'Default FAT Base'} < $min_small_block_start) and ($max_fat_base < $info_list_href->[$_]->{1}->{'Default FAT Base'}))
771 {
772 $max_fat_base = $info_list_href->[$_]->{1}->{'Default FAT Base'};
773 }
774 }
775 }
776 $min_fat_space = $min_flash_size - $max_fat_base;
777
778 for (1..$combo_mem_count)
779 {
780 my $cur_Size_Mb_ram;
781 $cur_Size_Mb_ram = $info_list_href->[$_]->{0}->{'Density (Mb)'};
782 if ($Size_Mb_ram_min > $cur_Size_Mb_ram)
783 {
784 $Size_Mb_ram_min = $cur_Size_Mb_ram;
785 }
786 }
787
788 $info_output_href->{0}->{'Flash Size'} = $min_flash_size;
789 $info_output_href->{0}->{'NAND Block Size(KB)'} = $max_nand_block_size / 1024;
790 $info_output_href->{0}->{'Small Block Start'} = $min_small_block_start;
791 $info_output_href->{0}->{'Default FAT Base'} = $max_fat_base;
792 $info_output_href->{0}->{'Default FAT Size'} = $min_fat_space;
793 $info_output_href->{1}->{'Size (Mb)'} = $Size_Mb_ram_min;
794 $info_output_href->{0}->{'ADMUX'} = $ADMUX_CS0;
795 $info_output_href->{1}->{'ADMUX'} = $ADMUX_CS1;
796 $info_output_href->{1}->{'DRAM'} = $if_DRAM;
797 $info_output_href->{0}->{'Comm. Series'} = $Comm_Series_CS0_all;
798 $info_output_href->{1}->{'Comm. Series'} = $Comm_Series_CS1_all;
799 $info_output_href->{0}->{'Bank'} = $Bank_if_S;
800 $info_output_href->{0}->{'PBP'}->{'Y / N'} = $PBP_Y_N_if_Y;
801 $info_output_href->{0}->{'PBP'}->{'Size(W)'} = $PBP_Size_W_min;
802
803
804 #print "FlashSize[0] is $info_output_href->{0}->{'Flash Size'}, FlashSize[1] is $info_output_href->{1}->{'Flash Size'}\n"if ($DebugPrint == 1);
805 #print "NANDBlockSize[0] is $info_output_href->{0}->{'NAND Block Size(KB)'}, NANDBlockSize[1] is $info_output_href->{1}->{'NAND Block Size(KB)'}\n"if ($DebugPrint == 1);
806 #print "SmallBlockStart[0] is $info_output_href->{0}->{'Small Block Start'}, SmallBlockStart[1] is $info_output_href->{1}->{'Small Block Start'}\n"if ($DebugPrint == 1);
807 #print "DefaultFATBase[0] is $info_output_href->{0}->{'Default FAT Base'}, DefaultFATBase[1] is $info_output_href->{1}->{'Default FAT Base'}\n"if ($DebugPrint == 1);
808 #print "DefaultFATSize[0] is $info_output_href->{0}->{'Default FAT Size'}, DefaultFATSize[1] is $info_output_href->{1}->{'Default FAT Size'}\n"if ($DebugPrint == 1);
809 #print "Size[0] is $info_output_href->{0}->{'Size (Mb)'}, Size[1] is $info_output_href->{1}->{'Size (Mb)'}\n"if ($DebugPrint == 1);
810 #print "ADMUX[0] is $info_output_href->{0}->{'ADMUX'}, ADMUX[1] is $info_output_href->{1}->{'ADMUX'}\n"if ($DebugPrint == 1);
811 #print "DRAM[0] is $info_output_href->{0}->{'DRAM'}, DRAM[1] is $info_output_href->{1}->{'DRAM'}\n"if ($DebugPrint == 1);
812 #print "CommSeries[0] is $info_output_href->{0}->{'Comm. Series'}, CommSeries[1] is $info_output_href->{1}->{'Comm. Series'}\n"if ($DebugPrint == 1);
813 #print "Bank[0] is $info_output_href->{0}->{'Bank'}, Bank[1] is $info_output_href->{1}->{'Bank'}\n"if ($DebugPrint == 1);
814 #print "PBPYN[0] is $info_output_href->{0}->{'PBP'}->{'Y / N'}, PBPYN[1] is $info_output_href->{1}->{'PBP'}->{'Y / N'}\n"if ($DebugPrint == 1);
815 #print "PBPSize[0] is $info_output_href->{0}->{'PBP'}->{'Size(W)'}, PBPSize[1] is $info_output_href->{1}->{'PBP'}->{'Size(W)'}\n"if ($DebugPrint == 1);
816}
817#****************************************************************************
818# subroutine: get_common_MDL_Geo_info
819# input: $info_list_href: input list reference of list of MDL info
820# $combo_count: number of memory devices selected
821# $mem_dev_type: MEMORY_DEVICE_TYPE
822# $baseaddr: base address where the geometry list starts
823# $endaddr: end address where the geometry list ends
824# $region_info_size_href: list reference of common RegionInfo of the specified area (Size)
825# $region_info_count_href: list of common RegionInfo of the specified area (Count)
826# $bank_info_size_href: list of common BankInfo of the specified area (Size)
827# $bank_info_count_href: list of common BankInfo of the specified area (Count)
828#****************************************************************************
829sub get_common_MDL_Geo_info
830{
831 my ($info_list_href, $combo_count, $mem_dev_type, $baseaddr, $endaddr, $region_info_size_href, $region_info_count_href, $bank_info_size_href, $bank_info_count_href) = @_;
832 my ($prev_addr, $curr_addr, $idx);
833
834 ### Get common RegionInfo
835 $prev_addr = $baseaddr;
836 $curr_addr = $baseaddr;
837 $idx = 0;
838
839 while ($curr_addr < $endaddr) # traverse till the endaddr
840 {
841 ### Find the largest block/bank offset from the current address to the next boundary
842 ### Stop if the end of BankInfo or RegionInfo has been reached
843 my $largest_offset = 0; # largest offset from curr_addr to the next block/bank boundary
844 my $common_size = 0; # final(common) block/bank size of this round
845 my $size; # current offset from curr_addr to the next block/bank boundary
846 my $cur_combo_idx;
847
848 for (1..$combo_count)
849 {
850 $cur_combo_idx = $_;
851 my $cur_block_str = $info_list_href->[$_]->{1}->{'Device Geometry'}->{'Block Info.'};
852 my @cur_blocks = &split_info($cur_block_str); # list of Block Info.
853 my @cur_entire_regions = &convert_blocks_to_regions(\@cur_blocks, $endaddr); # list of Region Info. (of the entire flash)
854 my (@cur_entire_regions_size, @cur_entire_regions_count);
855 &convert_geo_hash_from_list(\@cur_entire_regions, \@cur_entire_regions_size, \@cur_entire_regions_count);
856 ### Get the offset to the next boundary
857 $size = &get_next_Geo_boundary(\@cur_entire_regions_size, \@cur_entire_regions_count, $curr_addr);
858 last if ($size == 0); # reach the end of RegionInfo/BankInfo
859 if ($size > $largest_offset)
860 {
861 $largest_offset = $size;
862 }
863 }
864 last if ($cur_combo_idx != $combo_count); # early break in for loop represents end of RegionInfo/BankInfo is reached
865
866 ### Check whether curr_address+largest_offset is still on the boundaries of all MCPs
867 for (1..$combo_count)
868 {
869 $cur_combo_idx = $_;
870 my $cur_block_str = $info_list_href->[$_]->{1}->{'Device Geometry'}->{'Block Info.'};
871 my @cur_blocks = &split_info($cur_block_str); # list of Block Info.
872 my @cur_entire_regions = &convert_blocks_to_regions(\@cur_blocks, $endaddr); # list of Region Info. (of the entire flash)
873 my (@cur_entire_regions_size, @cur_entire_regions_count);
874 &convert_geo_hash_from_list(\@cur_entire_regions, \@cur_entire_regions_size, \@cur_entire_regions_count);
875 last if (&query_if_Geo_boundary(\@cur_entire_regions_size, \@cur_entire_regions_count, $curr_addr+$largest_offset) != 1);
876 }
877 # The address is not on the boundaries of all MCPs, need to go to the next address
878 # The next address is curr_addr + largest_offset
879 if ($cur_combo_idx != $combo_count)
880 {
881 $curr_addr += $largest_offset;
882 next;
883 }
884
885 ### Add the address into the output RegionInfo/BankInfo
886 # Get the size of common block/bank size
887 $common_size = $curr_addr + $largest_offset - $prev_addr;
888 if ($prev_addr == $baseaddr) # the first entry
889 {
890 $region_info_size_href->[0] = $common_size;
891 $region_info_count_href->[0] = 1;
892 }
893 elsif ($common_size == $region_info_size_href->[$idx]) # the size is identical to the last bank we added --> count + 1
894 {
895 $region_info_count_href->[$idx]++;
896 }
897 else # tje soze os different from the last bank we added --> append new entry
898 {
899 $idx++;
900 $region_info_size_href->[$idx] = $common_size;
901 $region_info_count_href->[$idx] = 1;
902 }
903
904 ### Increment the current address and then perform the loop again
905 $curr_addr += $largest_offset;
906 $prev_addr = $curr_addr;
907 }
908 print "pass block info\n";
909 ### Get common BankInfo
910 $prev_addr = $baseaddr;
911 $curr_addr = $baseaddr;
912 $idx = 0;
913 while ($curr_addr < $endaddr) # traverse till the endaddr
914 {
915 ### Find the largest block/bank offset from the current address to the next boundary
916 ### Stop if the end of BankInfo or RegionInfo has been reached
917 my $largest_offset = 0; # largest offset from curr_addr to the next block/bank boundary
918 my $common_size = 0; # final(common) block/bank size of this round
919 my $size; # current offset from curr_addr to the next block/bank boundary
920 my $cur_combo_idx;
921
922 for (1..$combo_count)
923 {
924 $cur_combo_idx = $_;
925 my $cur_bank_str = $info_list_href->[$_]->{1}->{'Device Geometry'}->{'Bank Info.'};
926 my @cur_banks = &split_info($cur_bank_str); # list of Bank Info.
927 my (@cur_banks_size, @cur_banks_count);
928 &convert_geo_hash_from_list(\@cur_banks, \@cur_banks_size, \@cur_banks_count);
929
930 ### Get the offset to the next boundary
931 $size = &get_next_Geo_boundary(\@cur_banks_size, \@cur_banks_count, $curr_addr);
932 last if ($size == 0); # reach the end of RegionInfo/BankInfo
933 if ($size > $largest_offset)
934 {
935 $largest_offset = $size;
936 }
937 }
938 last if ($cur_combo_idx != $combo_count); # early break in for loop represents end of RegionInfo/BankInfo is reached
939
940 ### Check whether curr_address+largest_offset is still on the boundaries of all MCPs
941 for (1..$combo_count)
942 {
943 $cur_combo_idx = $_;
944 my $cur_bank_str = $info_list_href->[$_]->{1}->{'Device Geometry'}->{'Bank Info.'};
945 my @cur_banks = &split_info($cur_bank_str); # list of Bank Info.
946 my (@cur_banks_size, @cur_banks_count);
947 &convert_geo_hash_from_list(\@cur_banks, \@cur_banks_size, \@cur_banks_count);
948 last if (&query_if_Geo_boundary(\@cur_banks_size, \@cur_banks_count, $curr_addr+$largest_offset) != 1);
949 }
950 # The address is not on the boundaries of all MCPs, need to go to the next address
951 # The next address is curr_addr + largest_offset
952 if ($cur_combo_idx != $combo_count)
953 {
954 $curr_addr += $largest_offset;
955 next;
956 }
957
958 ### Add the address into the output RegionInfo/BankInfo
959 # Get the size of common block/bank size
960 $common_size = $curr_addr + $largest_offset - $prev_addr;
961
962 if ($prev_addr == $baseaddr) # the first entry
963 {
964 $bank_info_size_href->[0] = $common_size;
965 $bank_info_count_href->[0] = 1;
966 }
967 elsif ($common_size == $bank_info_size_href->[$idx]) # the size is identical to the last bank we added --> count + 1
968 {
969 $bank_info_count_href->[$idx]++;
970 }
971 else # tje soze os different from the last bank we added --> append new entry
972 {
973 $idx++;
974 $bank_info_size_href->[$idx] = $common_size;
975 $bank_info_count_href->[$idx] = 1;
976 }
977
978 ### Increment the current address and then perform the loop again
979 $curr_addr += $largest_offset;
980 $prev_addr = $curr_addr;
981 }
982}
983
984#****************************************************************************
985# subroutine: get_next_Geo_boundary
986# input: $geo_size_list_href: input list reference of geometry (Size list)
987# $geo_count_list_href: input list reference of geometry (Size list)
988# $addr: current address from which to query next boundary
989# output: $size: size from current address to the next boundary
990#****************************************************************************
991sub get_next_Geo_boundary
992{
993 my ($geo_size_list_href, $geo_count_list_href, $addr) = @_;
994 my $size;
995
996 ### for all {Size, Count} pairs
997 for (0..$#$geo_size_list_href)
998 {
999 ### Treat the address as a pile of blocks. Remove them region by region.
1000 if (($geo_size_list_href->[$_]*$geo_count_list_href->[$_]) <= $addr)
1001 {
1002 $addr -= $geo_size_list_href->[$_]*$geo_count_list_href->[$_];
1003 next;
1004 }
1005
1006 ### Blocks that cannot fit-into one region.
1007 # 1. We have found the region that addr belongs to.
1008 # 2. The addr is aligned, if (addr % Size[$_]) equals 0.
1009 # 3. The offset to the next boundary is (Size[$_] - (addr % Size[$_]))
1010 return ($geo_size_list_href->[$_] - ($addr % $geo_size_list_href->[$_]));
1011 }
1012
1013 return 0;
1014}
1015
1016#****************************************************************************
1017# subroutine: query_if_Geo_boundary
1018# input: $geo_size_list_href: input list reference of geometry (Size list)
1019# $geo_count_list_href: input list reference of geometry (Size list)
1020# $addr: address to be checked whether it is on the boundary or not
1021# output: $is_boundary: 1 if the queried address is on the boundary of all MCPs
1022#****************************************************************************
1023sub query_if_Geo_boundary
1024{
1025 my ($geo_size_list_href, $geo_count_list_href, $addr) = @_;
1026 my $ret;
1027
1028 ### for all {Size, Count} pairs
1029 for (0..$#$geo_size_list_href)
1030 {
1031 ### Treat the address as a pile of blocks. Remove them region by region.
1032 if (($geo_size_list_href->[$_]*$geo_count_list_href->[$_]) <= $addr)
1033 {
1034 $addr -= $geo_size_list_href->[$_]*$geo_count_list_href->[$_];
1035 next;
1036 }
1037
1038 ### Blocks that cannot fit-into one region.
1039 # 1. We have found the region that addr belongs to.
1040 # 2. The addr is aligned, if (addr % Size[$_]) equals 0.
1041 # 3. The offset to the next boundary is (Size[$_] - (addr % Size[$_]))
1042 if (($addr % $geo_size_list_href->[$_]) != 0)
1043 {
1044 return 0;
1045 }
1046 }
1047 return 1;
1048}
1049
1050#****************************************************************************
1051# subroutine: split_info
1052# return: List of RegionInfo/BlockInfo/BankInfo
1053# input: $info: Excel value to be split
1054#****************************************************************************
1055sub split_info
1056{
1057 my ($info) = @_;
1058 my $ret_str;
1059 my @ret_info;
1060
1061 if ($info eq '*')
1062 {
1063 push @ret_info, $info;
1064 return @ret_info;
1065 }
1066
1067 while ($info =~ /\{(0x\w+)\s*,\s*(\w+)\}/)
1068 {
1069 $ret_str = "{" . $1 . "," . $2 . "}";
1070 push @ret_info, $ret_str;
1071 $info = $';
1072 }
1073 return @ret_info;
1074}
1075
1076#****************************************************************************
1077# subroutine: split_sfi_driving
1078# return: List of SFI driving
1079# input: $driving_str: Excel value to be split
1080#****************************************************************************
1081sub split_sfi_driving
1082{
1083 my ($driving_str) = @_;
1084 my @ret_driving;
1085
1086 $driving_str =~ s/\{//; # remove parentheses
1087 $driving_str =~ s/\}//; # remove parentheses
1088 $driving_str =~ s/\s+//g; # remove spaces
1089 ### parse the driving string
1090 my $saved_sep = $/;
1091 undef $/;
1092 @ret_driving = split(/\,/, $driving_str);
1093 $/ = $saved_sep;
1094
1095 return @ret_driving;
1096}
1097
1098#****************************************************************************
1099# subroutine: split_sfi_command
1100# return: List of SFI commands
1101# input: $command_str: Excel value to be split
1102#****************************************************************************
1103sub split_sfi_command
1104{
1105 my ($command_str) = @_;
1106 my @ret_command;
1107
1108 while ($command_str =~ /(\{.+\})/)
1109 {
1110 my $tmp_str = $1;
1111 $command_str = $';
1112 $tmp_str =~ s/\{//; # remove parentheses
1113 $tmp_str =~ s/\}//; # remove parentheses
1114 $tmp_str =~ s/\s+//g; # remove spaces
1115 ### parse the driving string
1116 my $saved_sep = $/;
1117 undef $/;
1118 my @tmp_list = split(/\,/, $tmp_str);
1119 $/ = $saved_sep;
1120
1121 ### for commands {SPI, 0x35}, output "SPI, 1, 0x35", where 1 is the number of commands
1122 if ($tmp_list[0] eq 'SPI' or $tmp_list[0] eq 'QPI')
1123 {
1124 push @ret_command, $tmp_list[0];
1125 push @ret_command, $#tmp_list;
1126 for (1..$#tmp_list)
1127 {
1128 push @ret_command, $tmp_list[$_];
1129 }
1130 }
1131 else
1132 {
1133 &error_handler("$MEMORY_DEVICE_LIST_XLS_E: Unknown SFI commands $command_str!", __FILE__, __LINE__);
1134 }
1135 }
1136
1137 return @ret_command;
1138}
1139
1140#****************************************************************************
1141# subroutine: region_info
1142# return: template of part "configure flash memory for FAT"
1143#****************************************************************************
1144sub region_info
1145{
1146 my ($region_size_href, $region_count_href, $naming, $newline) = @_;
1147 my $region_info_lines;
1148
1149 for (0..$#$region_size_href)
1150 {
1151 my $tmp_size = sprintf("0x%X", $region_size_href->[$_]);
1152 my $tmp_count = sprintf("%d", $region_count_href->[$_]);
1153 if ($_ == $#$region_size_href)
1154 {
1155 $region_info_lines .= " \{$tmp_size, $tmp_count\},\n";
1156 }
1157 else
1158 {
1159 $region_info_lines .= " \{$tmp_size, $tmp_count\}, \\$newline\n";
1160 }
1161 }
1162 chomp $region_info_lines;
1163
1164 if (!defined $naming)
1165 {
1166 return $region_info_lines;
1167 }
1168
1169 ###
1170 my $template;
1171 if (defined $newline)
1172 {
1173 $template .= <<"__TEMPLATE";
1174$region_info_lines
1175__TEMPLATE
1176 return $template;
1177 }
1178 my $naming_str = sprintf("$naming\[\]");
1179 if ($naming eq 'oriRegionInfo')
1180 {
1181 $template .= <<"__TEMPLATE";
1182FLASH_REGIONINFO_VAR_MODIFIER FlashRegionInfo $naming_str =
1183{
1184$region_info_lines
1185 EndoriRegionInfo
1186};
1187__TEMPLATE
1188 }
1189 else
1190 {
1191 $template .= <<"__TEMPLATE";
1192#define $naming $region_info_lines
1193__TEMPLATE
1194 }
1195 chomp $template;
1196 return $template;
1197}
1198
1199#****************************************************************************
1200# subroutine: block_info
1201# return: template of part "configure flash memory for FAT"
1202# input: $tmp_blocks: Block Info
1203# $newline: whether there exists newline character and comments in the output Block Info string
1204#****************************************************************************
1205sub block_info
1206{
1207 my ($block_start_href, $block_size_href, $newline) = @_;
1208 my $block_info_lines;
1209
1210 for (0..$#$block_start_href)
1211 {
1212 my $tmp_start = sprintf("0x%X", $block_start_href->[$_]);
1213 my $tmp_size = sprintf("0x%X", $block_size_href->[$_]);
1214 if ($_ == $#$block_start_href)
1215 {
1216 $block_info_lines .= " \{$tmp_start, $tmp_size\},\n";
1217 }
1218 else
1219 {
1220 $block_info_lines .= " \{$tmp_start, $tmp_size\}, $newline\n";
1221 }
1222 }
1223 chomp $block_info_lines;
1224
1225 ###
1226 my $template;
1227 if (defined $newline)
1228 {
1229 $template .= <<"__TEMPLATE";
1230$block_info_lines
1231__TEMPLATE
1232 }
1233 else
1234 {
1235 $template .= <<"__TEMPLATE";
1236/*
1237FLASH_REGIONINFO_VAR_MODIFIER FlashBlockTBL NOTREADYYET[] =
1238{
1239$block_info_lines
1240 EndBlockInfo
1241};
1242*/
1243__TEMPLATE
1244 }
1245
1246 return $template;
1247}
1248
1249#****************************************************************************
1250# subroutine: bank_info
1251# return: template of part "configure flash memory for FAT"
1252# input: $bank_size_href: Bank Info size
1253# $bank_count_href: Bank Info count
1254# $offset: the offset to start counting bank
1255# $target_size: the size of the FAT
1256# $newline: whether there exists newline character and comments in the output Bank Info string
1257#****************************************************************************
1258sub bank_info
1259{
1260 my ($bank_size_href, $bank_count_href, $offset, $target_size, $newline) = @_;
1261 my $template;
1262
1263 if (defined $newline)
1264 {
1265 for (0..$#$bank_size_href)
1266 {
1267 my $tmp_size = sprintf("0x%X", $bank_size_href->[$_]);
1268 my $tmp_count = sprintf("%d", $bank_count_href->[$_]);
1269 if ($_ == $#$bank_size_href)
1270 {
1271 $template .= " \{$tmp_size, $tmp_count\},\n";
1272 }
1273 else
1274 {
1275 $template .= " \{$tmp_size, $tmp_count\}, $newline\n";
1276 }
1277 }
1278 return $template;
1279 }
1280 for (0..$#$bank_size_href)
1281 {
1282 my $tmp_size = sprintf("0x%X", $bank_size_href->[$_]);
1283 my $tmp_count = sprintf("%d", $bank_count_href->[$_]);
1284
1285 my $segment = ( hex($tmp_size) * $tmp_count );
1286 if ($offset <= 0)
1287 # Bank already in
1288 {
1289 if ($target_size >= $segment)
1290 # Bank full in-used
1291 {
1292 $template .= sprintf(" \{ 0x%X, %d \}, %s \\ \n", hex($tmp_size), $tmp_count);
1293 }
1294 elsif ($target_size > 0)
1295 # Bank partial used
1296 {
1297 my $tmp = int($target_size / hex($tmp_size));;
1298 if ( int($target_size / hex($tmp_size)) > 0 )
1299 {
1300 $template .= sprintf(" \{ 0x%X, %d \}, %s\\\n", hex($tmp_size), int($target_size / hex($tmp_size)) );
1301 $target_size -= hex($tmp_size) * int($target_size / hex($tmp_size));
1302 }
1303 if ($target_size > 0)
1304 {
1305 $template .= sprintf(" \{ 0x%X, %d \}, %s\\\n", $target_size , 1 );
1306 }
1307 }
1308 else
1309 # Bank discarded
1310 {
1311 }
1312 $target_size -= $segment;
1313 }
1314 elsif ($offset < $segment)
1315 # Segment cross the FAT Baseaddr
1316 {
1317 my $c = $tmp_count;
1318 while ($offset >= hex($tmp_size))
1319 {
1320 $c--;
1321 $offset -= hex($tmp_size);
1322 }
1323 # Bank partial in-used
1324 if ($offset > 0 and (hex($tmp_size) - $offset) >= $target_size)
1325 {
1326 $template .= sprintf(" \{ 0x%X, %d \}, %s\\\n", $target_size, 1);
1327 $target_size -= hex($tmp_size);
1328 $c--;
1329 }
1330 elsif ($offset > 0)
1331 {
1332 $template .= sprintf(" \{ 0x%X, %d \}, %s\\\n", (hex($tmp_size) - $offset), 1);
1333 $target_size -= (hex($tmp_size) - $offset);
1334 $c--;
1335 }
1336 # discount $offset and make $offset to negative value
1337 $offset -= hex($tmp_size);
1338
1339 next if ($c == 0); # already last one bank on the FAT boundary
1340 if ($target_size >= (hex($tmp_size) * $c))
1341 {
1342 $template .= sprintf(" \{ 0x%X, %d \}, %s \\\n", hex($tmp_size), $c);
1343 $target_size -= (hex($tmp_size) * $c);
1344 }
1345 elsif ($target_size > 0)
1346 {
1347 if ( int($target_size / hex($tmp_size)) > 0 )
1348 {
1349 $template .= sprintf(" \{ 0x%X, %d \}, %s \\\n", hex($tmp_size), int($target_size / hex($tmp_size)) );
1350 $target_size -= hex($1) * int($target_size / hex($tmp_size));
1351 }
1352 if ($target_size > 0)
1353 {
1354 $template .= sprintf(" \{ 0x%X, %d \}, %s \\\n", $target_size , 1 );
1355 }
1356 }
1357 }
1358 # No output and down counting to reach FAT Baseaddr
1359 else
1360 {
1361 $offset -= $segment;
1362 }
1363 }
1364
1365 $template = " {x , x},\n" if not defined $template;
1366 chomp($template);
1367 return $template;
1368}
1369
1370#****************************************************************************
1371# subroutine: convert_blocks_to_regions
1372# return: RegionInfo of the entire flash, in {size, count} format instead of {start, size} format
1373# input: $tmp_blocks: input list of blocks
1374# output: @regions: output list of regions
1375#****************************************************************************
1376sub convert_blocks_to_regions
1377{
1378 my ($tmp_blocks, $endaddr) = @_;
1379 my @regions;
1380 my ($cur_reg_start, $cur_block_size, $prev_reg_start, $prev_block_size);
1381
1382 for (0..$#$tmp_blocks)
1383 {
1384 if ($tmp_blocks->[$_] =~ /\{(\w+)\s*,\s*(\w+)\}/) # match {0x20000, 7}
1385 {
1386 $cur_reg_start = hex($1);
1387 $cur_block_size = hex($2);
1388 }
1389 if ($_ > 0)
1390 {
1391 if ($tmp_blocks->[$_-1] =~ /\{(\w+)\s*,\s*(\w+)\}/) # match {0x20000, 7}
1392 {
1393 $prev_reg_start = hex($1);
1394 $prev_block_size = hex($2);
1395 }
1396 my $tmp_region_info_line = sprintf("\{0x%X,%d\}", $prev_block_size, ($cur_reg_start-$prev_reg_start)/$prev_block_size);
1397 push @regions, $tmp_region_info_line;
1398 }
1399 }
1400 my $tmp_region_info_line;
1401 if ($#$tmp_blocks >= 0)
1402 {
1403 $tmp_region_info_line = sprintf("\{0x%X,%d\}", $cur_block_size, ($endaddr-$cur_reg_start)/$cur_block_size);
1404 }
1405 push @regions, $tmp_region_info_line;
1406
1407 return @regions;
1408}
1409
1410#****************************************************************************
1411# subroutine: convert_regions_to_blocks
1412# return: BlockInfo of the input RegionInfo, in {start, size} format instead of {size, count} format
1413# input: $regions_start: start address of region info
1414# $tmp_regions_size_list: input list of regions size
1415# $tmp_regions_count_list: input list of regions count
1416# output: $output_blocks_start_list: output list of blocks start
1417# $output_blocks_size_list: output list of blocks size
1418#****************************************************************************
1419sub convert_regions_to_blocks
1420{
1421 my ($regions_start, $tmp_regions_size_list, $tmp_regions_count_list, $output_blocks_start_list, $output_blocks_size_list) = @_;
1422 my @ret_blocks;
1423
1424 my $idx = 0;
1425 $output_blocks_start_list->[0] = $regions_start;
1426 for (0..$#$tmp_regions_size_list)
1427 {
1428 $idx = $_;
1429 # the block size is identical to the region block size
1430 $output_blocks_size_list->[$_] = $tmp_regions_size_list->[$_];
1431 # the offset equals to the accumulated size of former regions
1432 if ($_ != $#$tmp_regions_size_list)
1433 {
1434 $output_blocks_start_list->[$_+1] = $output_blocks_start_list->[$_] + ($tmp_regions_size_list->[$_]*$tmp_regions_count_list->[$_]);
1435 }
1436 }
1437}
1438
1439#****************************************************************************
1440# subroutine: convert_geo_hash_from_list
1441# return: lists of flash geometry in {size, count} format
1442# input: $list_href: input list of blocks/banks
1443# $geo_size_list_output_href: Size part of flash geometry pairs
1444# $geo_count_list_output_href: Count part of flash geometry pairs
1445#****************************************************************************
1446sub convert_geo_hash_from_list
1447{
1448 my ($list_href, $geo_size_list_output_href, $geo_count_list_output_href) = @_;
1449
1450 for (0..$#$list_href)
1451 {
1452 if ($list_href->[$_] =~ /\{(\w+)\s*,\s*(\w+)\}/) # match {0x20000, 7}
1453 {
1454 $geo_size_list_output_href->[$_] = hex($1);
1455 $geo_count_list_output_href->[$_] = $2;
1456 }
1457 }
1458}
1459
1460
1461#****************************************************************************
1462# subroutine: SCHEME Configure Routines :: Query Flash Block Size
1463# input: Flash Offset Address
1464# Output: Flash block size
1465#****************************************************************************
1466sub config_query_flash_block_sz
1467{
1468 my ($offset, $COMM_MDL_INFO_LOCAL, $ENTIRE_BLOCK_INFO_START_LIST_LOCAL, $ENTIRE_BLOCK_INFO_SIZE_LIST_LOCAL) = @_;
1469
1470 &error_handler("pcore\\tools\\emigenflash.pl: Query Block Size at $offset larger than available size!", __FILE__, __LINE__) if ($offset > $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'});
1471
1472 for (0..$#$ENTIRE_BLOCK_INFO_START_LIST_LOCAL)
1473 {
1474 return ($ENTIRE_BLOCK_INFO_SIZE_LIST_LOCAL->[$#$ENTIRE_BLOCK_INFO_START_LIST_LOCAL-$_]) if ($offset >= $ENTIRE_BLOCK_INFO_START_LIST_LOCAL->[$#$ENTIRE_BLOCK_INFO_START_LIST_LOCAL-$_]);
1475 }
1476 &error_handler("pcore\\tools\\emigenflash.pl: Unreachable!", __FILE__, __LINE__);
1477}
1478
1479#****************************************************************************
1480# subroutine: flash_opt_h_file_body
1481# return: flash opt header file
1482#****************************************************************************
1483sub flash_opt_gen_h_file_body
1484{
1485 my ($MAKEFILE_OPTIONS_LOCAL, $CUSTOM_MEM_DEV_OPTIONS_LOCAL, $MDL_INFO_LIST_LOCAL, $COMM_MDL_INFO_LOCAL, $CUSTOM_MEMORY_DEVICE_HDR_LOCAL, $THEMF_LOCAL, $entire_bank_info_size_list_LOCAL, $entire_bank_info_count_list_LOCAL, $entire_block_info_start_list_LOCAL, $entire_block_info_size_list_LOCAL, $entire_region_info_size_list_LOCAL, $entire_region_info_count_list_LOCAL) = @_;
1486 my $current_nor_opt;
1487 ##if (($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{MEMORY_DEVICE_TYPE} ne 'LPSDRAM') and ($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{MEMORY_DEVICE_TYPE} ne 'LPDDR') and ($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{MEMORY_DEVICE_TYPE} ne 'LPDDR2'))
1488 #if ($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{MEMORY_DEVICE_TYPE} eq 'LPDDR2')
1489 #if($MAKEFILE_OPTIONS_LOCAL->{'platform'} eq 'MT6290')
1490 #{
1491 if ($COMM_MDL_INFO_LOCAL->{0}->{'PBP'}->{'Y / N'} =~ /Y/i)
1492 {
1493 $current_nor_opt .= "#define __PAGE_BUFFER_PROGRAM__\n";
1494 }
1495
1496 #if ($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{MEMORY_DEVICE_TYPE} eq 'SERIAL_FLASH')
1497 if ($MAKEFILE_OPTIONS_LOCAL->{'serial_flash_support'} eq 'TRUE')
1498 {
1499 $current_nor_opt .= "#define __SERIAL_FLASH__\n";
1500 }
1501
1502 ### Define flash types
1503 my $cnt_sibley = 0;
1504 for (1..$CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT})
1505 {
1506 if ($MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Comm. Series'} =~ /(\w*)/i)
1507 {
1508 my $tmp_series = $1;
1509 if ($current_nor_opt =~ /$tmp_series/)
1510 {
1511 }
1512 else
1513 {
1514 #if ($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{MEMORY_DEVICE_TYPE} eq 'SERIAL_FLASH')
1515 if ($MAKEFILE_OPTIONS_LOCAL->{'serial_flash_support'} eq 'TRUE')
1516 {
1517 $current_nor_opt .= "#define SF_DAL_" . $tmp_series . "\n";
1518 }
1519 else
1520 {
1521 $current_nor_opt .= "#define NOR_FLASH_TYPE_" . $tmp_series . "\n";
1522 if ($tmp_series eq 'INTEL_SIBLEY')
1523 {
1524 $cnt_sibley++;
1525 }
1526 }
1527 }
1528 }
1529 }
1530 if ($MAKEFILE_OPTIONS_LOCAL->{'serial_flash_support'} eq 'TRUE')
1531 {
1532 if ($cnt_sibley != $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT})
1533 {
1534 $current_nor_opt .= "#define __NON_INTEL_SIBLEY__\n";
1535 }
1536
1537
1538 $current_nor_opt .= "\n";
1539 $current_nor_opt .= "\n";
1540
1541 if ($COMM_MDL_INFO_LOCAL->{0}->{'Bank'} =~ /M/i)
1542 {
1543 $current_nor_opt .= "#define __MULTI_BANK_NOR_DEVICE__\n";
1544 }
1545 elsif ($COMM_MDL_INFO_LOCAL->{0}->{'Bank'} =~ /S/i)
1546 {
1547 $current_nor_opt .= "#define __SINGLE_BANK_NOR_DEVICE__\n";
1548 }
1549 }
1550 #}
1551
1552 if (($MAKEFILE_OPTIONS_LOCAL->{'serial_flash_support'} eq 'FALSE') and ($MAKEFILE_OPTIONS_LOCAL->{'nand_support'} eq 'FALSE'))
1553 {
1554 $current_nor_opt .= "#define __SMART_PHONE_PLATFORM__\n";##for Not Run CkSysDrv.pl, will check FAT valid, but no flash now
1555 }
1556
1557 ###
1558 my $pbp_size = ($COMM_MDL_INFO_LOCAL->{0}->{'PBP'}->{'Y / N'} =~ /Y/i)
1559 ? $COMM_MDL_INFO_LOCAL->{0}->{'PBP'}->{'Size(W)'}
1560 : 0;
1561
1562 ###
1563 my $nor_block_size_str = sprintf("0x%X", $nor_block_size);
1564
1565 ###
1566 my $nand_total_size = 0;
1567 my $nand_block_size = 0;
1568
1569 #if($MAKEFILE_OPTIONS_LOCAL->{'platform'} eq 'MT6290')
1570 #{
1571 if ($MAKEFILE_OPTIONS_LOCAL->{'nand_support'} eq 'TRUE')
1572 {
1573 $nand_total_size = ($COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'} == 0xffffffff)
1574 ? 0
1575 : ($COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'} / (1024*1024));
1576 $nand_block_size = $COMM_MDL_INFO_LOCAL->{0}->{'NAND Block Size(KB)'};
1577 }
1578 #}
1579
1580 my $base_addr_string = sprintf("0x%08X", $COMM_MDL_INFO_LOCAL->{0}->{'Default FAT Base'});
1581 my $fat_space_string = sprintf("0x%08X", $COMM_MDL_INFO_LOCAL->{0}->{'Default FAT Size'});
1582
1583 ###
1584 my $fota_check;
1585 if ($MAKEFILE_OPTIONS_LOCAL->{'fota_enable'} eq 'FOTA_DM')
1586 {
1587 $fota_check = <<"__TEMPLATE";
1588#ifndef __FOTA_DM__
1589 #error "$THEMF: Error! FOTA_ENABLE should be set to FOTA_DM!"
1590#endif /* __FOTA_DM__ */
1591__TEMPLATE
1592 }
1593 else
1594 {
1595 $fota_check = <<"__TEMPLATE";
1596#ifdef __FOTA_DM__
1597 #error "$THEMF_LOCAL: Error! FOTA_ENABLE should not be defined!"
1598#endif /* __FOTA_DM__ */
1599__TEMPLATE
1600 }
1601
1602 ###
1603 my ($fota_nor_region_def, $fota_nor_block_def, $fota_nor_bank_def);
1604 if ($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{MEMORY_DEVICE_TYPE} eq 'NOR_RAM_MCP')
1605 {
1606 $fota_nor_region_def = &region_info($entire_region_info_size_list_LOCAL, $entire_region_info_count_list_LOCAL, undef, '\\');
1607 $fota_nor_block_def = &block_info($entire_block_info_start_list_LOCAL, $entire_block_info_size_list_LOCAL, '\\');
1608 $fota_nor_bank_def = &bank_info($entire_bank_info_size_list_LOCAL, $entire_bank_info_count_list_LOCAL, 0, $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'}, '\\');
1609 }
1610
1611 ###
1612 my $template = <<"__TEMPLATE";
1613
1614/*
1615 *******************************************************************************
1616 PART 1:
1617 FLASH CONFIG Options Definition here
1618 *******************************************************************************
1619*/
1620$current_nor_opt
1621
1622/*
1623 *******************************************************************************
1624 PART 2:
1625 FLASH FDM FEATURE CONFIG PARAMETERS translated from Manual custom_Memorydevice.h
1626 *******************************************************************************
1627*/
1628
1629#define BUFFER_PROGRAM_ITERATION_LENGTH ($pbp_size)
1630
1631/*
1632 *******************************************************************************
1633 PART 3:
1634 FLASH GEOMETRY translated from MEMORY DEVICE DATABASE
1635 *******************************************************************************
1636*/
1637
1638/* NOR flash maximum block size (Byte) in file system region */
1639#define NOR_BLOCK_SIZE $nor_block_size_str
1640
1641/* NAND flash total size (MB). PLEASE configure it as 0 if it is unknown. */
1642#define NAND_TOTAL_SIZE $nand_total_size
1643
1644/* NAND flash block size (KB). PLEASE configure it as 0 if it is unknown. */
1645#define NAND_BLOCK_SIZE $nand_block_size
1646
1647/*
1648 *******************************************************************************
1649 PART 4:
1650 FLASH FAT CONFIG translated from Manual custom_Memorydevice.h
1651 *******************************************************************************
1652*/
1653
1654 #define NOR_FLASH_BASE_ADDRESS_DEFAULT ($base_addr_string)
1655 #define NOR_ALLOCATED_FAT_SPACE_DEFAULT ($fat_space_string)
1656 #define FOTA_DM_FS_OFFSET $nfb_fat_size_offset
1657 #define FOTA_DM_FS_SECTOR_OFFSET $nfb_partition_sector_offset
1658
1659/*
1660 *******************************************************************************
1661 PART 6:
1662 FOTA UPDATABLE FLASH AREA
1663 *******************************************************************************
1664*/
1665
1666$fota_check
1667
1668#define CONFIG_FOTA_NOR_REGION_DEF \\
1669$fota_nor_region_def
1670
1671#define CONFIG_FOTA_NOR_BLOCK_DEF \\
1672$fota_nor_block_def
1673
1674#define CONFIG_FOTA_NOR_BANK_DEF \\
1675$fota_nor_bank_def
1676
1677__TEMPLATE
1678
1679 return $template;
1680}
1681
1682#****************************************************************************
1683# subroutine: combo_flash_config_h_file_body
1684# return:
1685#****************************************************************************
1686sub combo_flash_config_h_file_body
1687{
1688 my ($MAKEFILE_OPTIONS_LOCAL, $CUSTOM_MEM_DEV_OPTIONS_LOCAL, $MDL_INFO_LIST_LOCAL, $COMM_MDL_INFO_LOCAL) = @_;
1689 ### There should be totally 8 BlockInfo and BankInfo
1690 my $MAX_BLOCK_INFO = 8;
1691 my $MAX_BANK_INFO = 8;
1692
1693 ### Fill-in the information of each memory
1694 my $combo_mem_info_struct;
1695 for (1..$CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT})
1696 {
1697 my $comma;
1698 my $cmem_fdm_type;
1699 my $pbp_size;
1700 my $cur_block_str;
1701 my @cur_blocks;
1702 my $cur_bank_str;
1703 my @cur_banks;
1704 my $cur_uni_block_str;
1705 my $cur_uni_block;
1706 my ($block_info_template, $bank_info_template);
1707 #if($MAKEFILE_OPTIONS_LOCAL->{'platform'} eq 'MT6290')
1708 #{
1709 if ($CUSTOM_MEM_DEV_OPTIONS_LOCAL->{MEMORY_DEVICE_TYPE} eq 'NAND_RAM_MCP')##MT6290 MCP
1710 {
1711 #todo
1712 }
1713 else ##MT6290 Discrete DRAM/FLASH
1714 {
1715 if ($MAKEFILE_OPTIONS_LOCAL->{'serial_flash_support'} eq 'TRUE')
1716 {
1717 #print "Serial Flash Support!\n"if ($DebugPrint == 1);
1718 $comma = ($_ < $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT}) ? "," : "";
1719 $cmem_fdm_type = 'CMEM_FDM_NOR_DEFAULT';
1720 $pbp_size = 0;
1721 if ($MDL_INFO_LIST_LOCAL->[$_]->{1}->{'PBP'}->{'Y / N'} =~ /Y/i)
1722 {
1723 $pbp_size = $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'PBP'}->{'Size (Byte)'};
1724 }
1725 $cur_block_str = $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Device Geometry'}->{'Block Info.'};
1726 @cur_blocks = &split_info($cur_block_str); # list of Block Info.
1727 $cur_bank_str = $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Device Geometry'}->{'Bank Info.'};
1728 @cur_banks = &split_info($cur_bank_str); # list of Bank Info.
1729 $cur_uni_block_str = $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Device Geometry'}->{'Uniform Block (KB)'};
1730 $cur_uni_block = &split_info_for_UB($cur_uni_block_str);
1731 }
1732 else #if ($MAKEFILE_OPTIONS_LOCAL->{'nand_support'} eq 'TRUE'), No flash or NAND gen dummy file
1733 {
1734 #print "NAND Flash Gen Dummy!\n"if ($DebugPrint == 1);
1735 #$comma = 0;
1736 $comma = ($_ < $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT}) ? "," : "";
1737 $cmem_fdm_type = '';
1738 $pbp_size = 0;
1739 $cur_block_str = '';
1740 @cur_blocks = &split_info($cur_block_str); # list of Block Info.
1741 $cur_bank_str = '';
1742 @cur_banks = &split_info($cur_bank_str); # list of Bank Info.
1743 $cur_uni_block_str = '';
1744 $cur_uni_block = &split_info_for_UB($cur_uni_block_str);
1745 }
1746 }
1747 #}
1748
1749 for (0..($MAX_BLOCK_INFO-1))
1750 {
1751 $block_info_template .= " ";
1752 if (defined $cur_blocks[$_])
1753 {
1754 $block_info_template .= $cur_blocks[$_];
1755 }
1756 else
1757 {
1758 $block_info_template .= "EndRegionInfo";
1759 }
1760 if ($_ != ($MAX_BLOCK_INFO-1))
1761 {
1762 $block_info_template .= ",\n";
1763 }
1764 }
1765 for (0..($MAX_BANK_INFO-1))
1766 {
1767 $bank_info_template .= " ";
1768 if (defined $cur_banks[$_])
1769 {
1770 $bank_info_template .= $cur_banks[$_];
1771 }
1772 else
1773 {
1774 $bank_info_template .= "EndBankInfo";
1775 }
1776 if ($_ != ($MAX_BANK_INFO-1))
1777 {
1778 $bank_info_template .= ",\n";
1779 }
1780 }
1781
1782 $combo_mem_info_struct .= <<"__TEMPLATE";
1783 { // $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Part Number'}
1784 $cmem_fdm_type,
1785 $pbp_size, // Page Buffer Program Size
1786 $cur_uni_block, // Unifom Blocks
1787 { // BlockInfo Start
1788$block_info_template
1789 }, // BlockInfo End
1790 { // BankInfo Start
1791$bank_info_template
1792 } // BankInfo End
1793 }$comma
1794__TEMPLATE
1795 }
1796
1797 ###
1798 my $template = <<"__TEMPLATE";
1799#define CMEM_MAX_BLOCKS $cmem_max_blocks
1800#define CMEM_MAX_SECTORS $cmem_max_sectors
1801
1802COMBO_MEM_TYPE_MODIFIER COMBO_MEM_TYPE_NAME COMBO_MEM_INST_NAME = {
1803 COMBO_MEM_STRUCT_HEAD
1804$combo_mem_info_struct
1805 COMBO_MEM_STRUCT_FOOT
1806};
1807__TEMPLATE
1808}
1809
1810
1811#****************************************************************************
1812# subroutine: combo_nfi_config_h_file_body
1813# return:
1814#****************************************************************************
1815sub combo_nfi_config_h_file_body
1816{
1817 my ($MAKEFILE_OPTIONS_LOCAL, $CUSTOM_MEM_DEV_OPTIONS_LOCAL, $MDL_INFO_LIST_LOCAL, $COMM_MDL_INFO_LOCAL) = @_;
1818
1819 ### Fill-in the information of each memory
1820 my $combo_nfi_info_struct;
1821 ### There should be totally 8 Flash ID entries
1822 my $MAX_FLASH_ID = 8;
1823
1824 for (1..$CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT})
1825 {
1826 $combo_nfi_info_struct .= "/* $_ */\n";
1827 my $vendor = uc($MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Vendor'});
1828 #$combo_nfi_info_struct .= " {\n" ." {" . "\"$vendor $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Part Number'}\"" ."}, // DevName_str (64 bytes)\n";#part time number
1829 $combo_nfi_info_struct .= " {\n" ." 0x00000301,\n" ." {" . "\"$vendor $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Part Number'}\"" ."}, // NFI_Device_Name (64 bytes)\n";#part time number
1830
1831 ###get flash id string
1832 my $flash_id_str = $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Flash ID'};
1833
1834 $flash_id_str =~ s/\{//; # remove parentheses
1835 $flash_id_str =~ s/\}//; # remove parentheses
1836 $flash_id_str =~ s/\s+//g; # remove spaces
1837 ### parse the flash id string
1838 my $saved_sep = $/;
1839 undef $/;
1840 my @flash_id = split(/\,/, $flash_id_str);
1841 $/ = $saved_sep;
1842 my $flash_id_cnt = $#flash_id + 1;
1843
1844 my $flash_id_template;
1845 my $flash_id_mask;
1846 #$flash_id_template .= sprintf("0x%02X", hex($flash_id[$_])) .",";
1847 #$flash_id_mask .= "0xFF" .",";
1848 for (0..($MAX_FLASH_ID-1))
1849 {
1850 if (defined $flash_id[$_])
1851 {
1852 $flash_id_template .= sprintf("0x%02X", hex($flash_id[$_]));
1853 $flash_id_mask .= "0xFF";
1854 }
1855 else
1856 {
1857 $flash_id_template .= "0xFF";
1858 $flash_id_mask .= "0x00";
1859 }
1860
1861 if ($_ != ($MAX_FLASH_ID-1))
1862 {
1863 $flash_id_template .= ", ";
1864 $flash_id_mask .= ", ";
1865 }
1866 }
1867 $combo_nfi_info_struct .= " {" .$flash_id_template ."}, // ID_info\n";
1868 $combo_nfi_info_struct .= " {" .$flash_id_mask ."}, // ID_valid_mask\n";
1869
1870 #$combo_nfi_info_struct .= " " .$MDL_INFO_LIST_LOCAL->[$_]->{1}->{'NAND Size(MB)'} .", // deviceSize (MByte)\n";
1871 $combo_nfi_info_struct .= " " .$MDL_INFO_LIST_LOCAL->[$_]->{1}->{'NAND Size(MB)'} .", // NFI_Device_Size (MByte)\n";
1872
1873 #$combo_nfi_info_struct .= " " .sprintf("0x%05x", $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'NAND Block Size(KB)'}*1024) .", // blockSize (byte)\n";
1874 $combo_nfi_info_struct .= " " .sprintf("0x%05x", $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'NAND Block Size(KB)'}*1024) .", // NFI_Block_Size (byte)\n";
1875
1876 ###Parsing special info
1877 my $nand_flash_key_ref = $MDL_INFO_LIST_LOCAL->[$_]->{1}->{$MAKEFILE_OPTIONS_LOCAL->{'platform'}};
1878
1879 foreach my $nand_flash_key (sort keys %{$nand_flash_key_ref})
1880 {
1881 #print "1-1 $nand_flash_key\n"if ($DebugPrint == 1);
1882 if ($nand_flash_key =~ /(\d+)MHz NFIC Config/)
1883 {
1884 my $nand_flash_cfg = $nand_flash_key;
1885 foreach my $nand_flash_key (sort keys %{$nand_flash_key_ref->{$nand_flash_cfg}})
1886 {
1887 my $val = $nand_flash_key_ref->{$nand_flash_cfg}->{$nand_flash_key};
1888 if (($val ne 'x') && ($val ne 'X') && ($val ne ''))
1889 {
1890 $combo_nfi_info_struct .=" " .$val .", // $nand_flash_key" . "\n";
1891 }
1892 }
1893 }
1894 else
1895 {
1896 my $val = $nand_flash_key_ref->{$nand_flash_key};
1897 #print "1-2 $val\n"if ($DebugPrint == 1);
1898 if (($val ne 'x') && ($val ne 'X') && ($val ne ''))
1899 {
1900 $combo_nfi_info_struct .= " " .$val .", // $nand_flash_key" . "\n";
1901 }
1902 }
1903 }
1904
1905 if($_ != $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT})
1906 {
1907 $combo_nfi_info_struct .= " },\n";
1908 }
1909 else
1910 {
1911 $combo_nfi_info_struct .= " }\n";
1912 }
1913__TEMPLATE
1914 }
1915
1916 ###
1917 my $template = <<"__TEMPLATE";
1918#define COMBO_NAND_FLASH_NUM $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT}
1919const combo_nand_flash_list_v01 COMBO_NAND_Table[] =
1920{
1921$combo_nfi_info_struct
1922};
1923__TEMPLATE
1924
1925 return $template;
1926}
1927
1928#****************************************************************************
1929# subroutine: combo_flash_id_h_file_body
1930# return:
1931#****************************************************************************
1932sub combo_flash_id_h_file_body
1933{
1934 my ($MAKEFILE_OPTIONS_LOCAL, $CUSTOM_MEM_DEV_OPTIONS_LOCAL, $MDL_INFO_LIST_LOCAL, $COMM_MDL_INFO_LOCAL) = @_;
1935 ### There should be totally 8 Flash ID entries
1936 my $MAX_FLASH_ID = 8;
1937
1938 ### Fill-in the information of each memory
1939 my $combo_mem_info_struct;
1940 for (1..$CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT})
1941 {
1942 my $comma = ($_ < $CUSTOM_MEM_DEV_OPTIONS_LOCAL->{COMBO_MEM_ENTRY_COUNT}) ? "," : "";
1943 my $cmem_type;
1944
1945 if ($MAKEFILE_OPTIONS_LOCAL->{'nand_support'} eq 'TRUE')
1946 {
1947 $cmem_type = "CMEM_TYPE_NAND";
1948 }
1949 elsif ($MAKEFILE_OPTIONS_LOCAL->{'serial_flash_support'} eq 'TRUE')
1950 {
1951 $cmem_type = "CMEM_TYPE_SERIAL_NOR_FLASH";
1952 }
1953 else
1954 {
1955 print "No flash support!\n"if ($DebugPrint == 1);
1956 }
1957
1958 ###get nand page size
1959 my $nand_page_size = $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'NAND Page size(B)'};
1960 my $nand_block_size = $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'NAND Block Size(KB)'};
1961 $nand_page_size = $nand_page_size . "," . $nand_block_size;
1962
1963 ###get flash id string
1964 my $flash_id_str = $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Flash ID'};
1965
1966 $flash_id_str =~ s/\{//; # remove parentheses
1967 $flash_id_str =~ s/\}//; # remove parentheses
1968 $flash_id_str =~ s/\s+//g; # remove spaces
1969 ### parse the flash id string
1970 my $saved_sep = $/;
1971 undef $/;
1972 my @flash_id = split(/\,/, $flash_id_str);
1973 $/ = $saved_sep;
1974 my $flash_id_cnt = $#flash_id + 1;
1975
1976 my $flash_id_template;
1977 for (0..($MAX_FLASH_ID-1))
1978 {
1979 if (defined $flash_id[$_])
1980 {
1981 ##$flash_id_template .= $flash_id[$_];
1982 if ($MAKEFILE_OPTIONS_LOCAL->{'nand_support'} eq 'TRUE')
1983 {
1984 $flash_id_template .= sprintf("0x%04X", hex($flash_id[$_]));
1985 #print "$_: $flash_id_template\n"if ($DebugPrint == 1);
1986 }
1987 elsif($MAKEFILE_OPTIONS_LOCAL->{'serial_flash_support'} eq 'TRUE')
1988 {
1989 $flash_id_template .= sprintf("0x%02X", hex($flash_id[$_]));
1990 }
1991 }
1992 else
1993 {
1994 if ($MAKEFILE_OPTIONS_LOCAL->{'nand_support'} eq 'TRUE')
1995 {
1996 $flash_id_template .= "0x0000";
1997 }
1998 elsif($MAKEFILE_OPTIONS_LOCAL->{'serial_flash_support'} eq 'TRUE')
1999 {
2000 $flash_id_template .= "0x00";
2001 }
2002 }
2003 if ($_ != ($MAX_FLASH_ID-1))
2004 {
2005 $flash_id_template .= ", ";
2006 }
2007 }
2008
2009 $combo_mem_info_struct .= <<"__TEMPLATE";
2010 { // $MDL_INFO_LIST_LOCAL->[$_]->{1}->{'Part Number'}
2011 $cmem_type,
2012 $flash_id_cnt, // Valid ID length
2013 {$flash_id_template} // Flash ID
2014 }$comma
2015__TEMPLATE
2016 }
2017
2018 ###
2019 my $template = <<"__TEMPLATE";
2020COMBO_MEM_TYPE_MODIFIER COMBO_MEM_TYPE_NAME COMBO_MEM_INST_NAME = {
2021 COMBO_MEM_STRUCT_HEAD
2022$combo_mem_info_struct
2023 COMBO_MEM_STRUCT_FOOT
2024};
2025__TEMPLATE
2026}
2027
2028#****************************************************************************
2029# subroutine: custom_flash_c_file_body
2030# return:
2031#****************************************************************************
2032sub custom_flash_h_file_body
2033{
2034 my ($MAKEFILE_OPTIONS_LOCAL, $CUSTOM_MEM_DEV_OPTIONS_LOCAL, $MDL_INFO_LIST_LOCAL, $COMM_MDL_INFO_LOCAL, $MCP_LIST_LOCAL, $NOR_FLASH_BASE_ADDRESS_VAL_LOCAL, $NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL,$LPSDRAM_CHIP_SELECT_LOCAL, $CUSTOM_MEMORY_DEVICE_HDR_LOCAL, $nor_size_Mb_LOCAL, $entire_bank_info_size_list_LOCAL, $entire_bank_info_count_list_LOCAL, $entire_block_info_start_list_LOCAL, $entire_block_info_size_list_LOCAL, $fs_region_info_size_list_LOCAL, $fs_region_info_count_list_LOCAL, $entire_region_info_size_list_LOCAL, $entire_region_info_count_list_LOCAL) = @_;
2035 my $cs1_base_address = 0;
2036 my $flash_limit = 0;
2037 my $flash_size = 0;
2038 if($MAKEFILE_OPTIONS_LOCAL->{'platform'} eq 'MT6290')
2039 {
2040 my $SPI_Base = 0xA0000000;
2041 $cs1_base_address = sprintf("0x%08X", $SPI_Base);#MT6290 Flash Memory Base Address
2042 $flash_limit = sprintf("0x%08X", $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'});
2043 $flash_size = sprintf("0x%08X", $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'});
2044 #print "MT6290: $cs1_base_address, $flash_limit, $flash_size\n"if ($DebugPrint == 1);
2045
2046 if($MAKEFILE_OPTIONS_LOCAL->{'nand_support'} eq 'TRUE')
2047 {
2048 ##MT6290 Work aroud for SDS, when in HOSTED/ROUTER Project, NOR_FLASH_SIZE is MD End(96MB), other Projects is Flash Size
2049 if((($MAKEFILE_OPTIONS_LOCAL->{'smart_phone_core'} eq 'ANDROID_MODEM') and ($MAKEFILE_OPTIONS_LOCAL->{'ccci_fs_support'} eq 'FALSE')) or (($MAKEFILE_OPTIONS_LOCAL->{'modem_card'} eq 'FULL') and ($MAKEFILE_OPTIONS_LOCAL->{'smart_phone_core'} eq 'MODEM_HOST')))
2050 #if($MAKEFILE_OPTIONS_LOCAL->{'modem_card'} eq 'FULL')
2051 {
2052 my $MDFlashEnd = 96*1024*1024;
2053 $flash_size = sprintf("0x%08X", $MDFlashEnd);
2054 }
2055 }
2056 }
2057
2058 ###
2059 my $pbp_size = ($COMM_MDL_INFO_LOCAL->{0}->{'PBP'}->{'Y / N'} =~ /Y/i)
2060 ? $COMM_MDL_INFO_LOCAL->{0}->{'PBP'}->{'Size(W)'}
2061 : 0;
2062
2063 ###
2064 my $bank_info_string = &bank_info( $entire_bank_info_size_list_LOCAL, $entire_bank_info_count_list_LOCAL, $NOR_FLASH_BASE_ADDRESS_VAL_LOCAL, $NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL );
2065
2066 ###
2067 my $sub_content_block1 = &region_info($fs_region_info_size_list_LOCAL, $fs_region_info_count_list_LOCAL, 'REGION_INFO_LAYOUT');
2068 my $sub_content_block2 = &block_info($entire_block_info_start_list_LOCAL, $entire_block_info_size_list_LOCAL);
2069 my $sub_content_block3;
2070 my $sub_content_block4;
2071 #if($MAKEFILE_OPTIONS_LOCAL->{'platform'} eq 'MT6290')
2072 #{
2073 my $ori_bank_info = &bank_info($entire_bank_info_size_list_LOCAL, $entire_bank_info_count_list_LOCAL, 0, $COMM_MDL_INFO_LOCAL->{0}->{'Flash Size'});
2074 ### ? what is the purpose?
2075 $sub_content_block3 = &region_info($fs_region_info_size_list_LOCAL, $fs_region_info_count_list_LOCAL, 'oriRegionInfo');
2076 $sub_content_block4 .= <<"__TEMPLATE";
2077
2078static NORBankInfo oriBankInfo[] =
2079{
2080$ori_bank_info
2081 EndBankInfo
2082};
2083
2084__TEMPLATE
2085 chomp $sub_content_block4;
2086 #}
2087
2088 ###
2089 my $region_info_disk0 = &region_info($fs_region_info_size_list_LOCAL, $fs_region_info_count_list_LOCAL, 'DISK0_REGION_INFO_LAYOUT');
2090 my $region_info_disk1 = &region_info($fs_region_info_size_list_LOCAL, $fs_region_info_count_list_LOCAL, 'DISK1_REGION_INFO_LAYOUT');
2091 my $region_info_entire = &region_info($entire_region_info_size_list_LOCAL, $entire_region_info_count_list_LOCAL, 'ENTIRE_DISK_REGION_INFO_LAYOUT');
2092
2093 ###
2094 my $template1;
2095
2096 $template1 .= <<"__TEMPLATE__";
2097/*******************************************************************************
2098 NOTICE: Fill the flash region information table, a region is the memory space
2099 that contains continuous sectors of equal size. Each region element
2100 in the table is the format as below:
2101 {S_sector, N_sector},
2102 S_sector: the size of sector in the region
2103 N_sector: the number of sectors in the region
2104 *******************************************************************************/
2105$sub_content_block1
2106
2107$region_info_disk0
2108
2109$region_info_disk1
2110
2111$region_info_entire
2112
2113/*******************************************************************************
2114 NOTICE. Modify the value of TOTAL_BLOCKS, which is the sum of the number of
2115 sectors in all regions.
2116 Note : The Maximum value of TOTAL_BLOCKS is (127).
2117 *******************************************************************************/
2118#define TOTAL_BLOCKS $cmem_max_blocks
2119
2120/*******************************************************************************
2121 NOTICE. Modify the value of page buffer size in WORD for page buffer program
2122 *******************************************************************************/
2123//kal_uint32 PAGE_BUFFER_SIZE = $pbp_size;
2124
2125#define BANK_INFO_LAYOUT $bank_info_string
2126
2127/*******************************************************************************
2128 NOTICE. NOR FLASH BLOCKS SIZE LOOKUP TABLE
2129 Each entry element
2130 {Offset, Block_Size},
2131 Offset: the offset address
2132 Block_Size: the size of block
2133 *******************************************************************************/
2134$sub_content_block2
2135__TEMPLATE__
2136
2137 ###
2138 my $flash_id_str;
2139 #if($MAKEFILE_OPTIONS_LOCAL->{'platform'} eq 'MT6290')
2140 #{
2141 #print "Flash ID: $MDL_INFO_LIST_LOCAL->[1]->{1}->{'Flash ID'}!\n"if ($DebugPrint == 1);
2142 $flash_id_str .= <<"__TEMPLATE__";
2143const kal_char FLASH_ID[] = "$MDL_INFO_LIST_LOCAL->[1]->{1}->{'Flash ID'}";
2144__TEMPLATE__
2145 #}
2146 chomp $flash_id_str;
2147
2148 ###
2149 my ($cs0_info, $cs1_info);
2150 my ($pn0_str, $pn1_str);
2151 if ((!defined $MAKEFILE_OPTIONS_LOCAL->{'combo_memory_support'}) or ($MAKEFILE_OPTIONS_LOCAL->{'combo_memory_support'} eq 'FALSE'))
2152 {
2153 if (defined $MCP_LIST_LOCAL->[1]->{0})
2154 {
2155 $cs0_info .= <<"__TEMPLATE__";
2156 * CS0_PART_NUMBER: $MCP_LIST_LOCAL->[1]->{0}
2157__TEMPLATE__
2158 chomp $cs0_info;
2159
2160 $pn0_str .= <<"__TEMPLATE__";
2161const kal_char PART_NUMBER_0[] = "$MCP_LIST_LOCAL->[1]->{0}";
2162__TEMPLATE__
2163 chomp $pn0_str;
2164 }
2165 if (defined $MCP_LIST_LOCAL->[1]->{1})
2166 {
2167 $cs1_info .= <<"__TEMPLATE__";
2168 * CS1_PART_NUMBER: $MCP_LIST_LOCAL->[1]->{1}
2169__TEMPLATE__
2170 chomp $cs1_info;
2171
2172 $pn1_str .= <<"__TEMPLATE__";
2173const kal_char PART_NUMBER_1[] = "$MCP_LIST_LOCAL->[1]->{1}";
2174__TEMPLATE__
2175 chomp $pn1_str;
2176 }
2177 }
2178
2179 ###
2180 my $flash_density;
2181 if ($MAKEFILE_OPTIONS_LOCAL->{'serial_flash_support'} eq 'TRUE')
2182 {
2183 $flash_density .= <<"__TEMPLATE__";
2184 * NOR_FLASH_DENSITY: $flash_limit
2185 * NOR_FLASH_SIZE(Mb): $nor_size_Mb_LOCAL
2186__TEMPLATE__
2187 chomp $flash_density;
2188 }
2189
2190 ###
2191 my $template = <<"__TEMPLATE";
2192
2193#define NOR_FLASH_BASE_ADDR $cs1_base_address
2194/*
2195#ifdef REMAPPING
2196#define NOR_FLASH_BASE_ADDR $cs1_base_address
2197#define RAM_BASE_ADDR 0x00000000
2198#else
2199#define NOR_FLASH_BASE_ADDR 0x00000000
2200#define RAM_BASE_ADDR $cs1_base_address
2201#endif
2202*/
2203
2204/*
2205 ****************************************************************************
2206 PART 2:
2207 Essential Information of NOR Flash Geometry Layout Information
2208 ****************************************************************************
2209*/
2210$template1
2211
2212#define NOR_FLASH_SIZE $flash_size
2213
2214$flash_id_str
2215
2216/****************************************************
2217 * This part is for auto-gen validity CHECK *
2218 * Don't modify any content in this comment section *
2219$cs0_info
2220$cs1_info
2221$flash_density
2222
2223$sub_content_block3
2224
2225$sub_content_block4
2226 ****************************************************/
2227
2228__TEMPLATE
2229}
2230
2231#****************************************************************************
2232# subroutine: custom_flash_norfdm5_c_file_body
2233# return:
2234#****************************************************************************
2235sub custom_flash_norfdm5_h_file_body
2236{
2237 my ($MAKEFILE_OPTIONS_LOCAL, $CUSTOM_MEM_DEV_OPTIONS_LOCAL, $MDL_INFO_LIST_LOCAL, $COMM_MDL_INFO_LOCAL, $NOR_FLASH_BASE_ADDRESS_VAL_LOCAL, $NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL, $entire_bank_info_size_list_LOCAL, $entire_bank_info_count_list_LOCAL) = @_;
2238 my $bank_info_string = &bank_info( $entire_bank_info_size_list_LOCAL, $entire_bank_info_count_list_LOCAL, $NOR_FLASH_BASE_ADDRESS_VAL_LOCAL, $NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL );
2239
2240 ###
2241 my $nor_total_lsmt = 1;
2242 my $count = 0;
2243 my $sum = 1;
2244 my $tmp_regions_sum = $NOR_ALLOCATED_FAT_SPACE_VAL_LOCAL;
2245
2246 if ($MEM_DEV_LIST_INFO{0}->{'Comm. Series'} eq 'INTEL_SIBLEY')
2247 {
2248 if ($tmp_regions_sum > (64*1024*1024))
2249 {
2250 my $count = 0;
2251 my $sum = 1;
2252 $tmp_regions_sum /= 1024;
2253 while ($sum < $tmp_regions_sum)
2254 {
2255 $sum *= 2;
2256 $count++;
2257 }
2258 $count -= 8;
2259 for (my $i=0; $i<$count; $i++)
2260 {
2261 $nor_total_lsmt *= 2;
2262 }
2263 }
2264 else
2265 {
2266 my $count = 0;
2267 my $sum = 1;
2268 $tmp_regions_sum /= 1024;
2269 while ($sum < $tmp_regions_sum)
2270 {
2271 $sum *= 2;
2272 $count++;
2273 }
2274 if (($count/2) == 1)
2275 {
2276 $count += 1;
2277 }
2278 $count /= 2;
2279 for (my $i=0; $i<$count; $i++)
2280 {
2281 $nor_total_lsmt *= 2;
2282 }
2283 }
2284 }
2285 else
2286 {
2287 if ($tmp_regions_sum > (32*1024*1024))
2288 {
2289 my $count = 0;
2290 my $sum = 1;
2291 $tmp_regions_sum /= 512;
2292 while ($sum < $tmp_regions_sum)
2293 {
2294 $sum *= 2;
2295 $count++;
2296 }
2297 $count -= 8;
2298 for (my $i=0; $i<$count; $i++)
2299 {
2300 $nor_total_lsmt *= 2;
2301 }
2302 }
2303 else
2304 {
2305 my $count = 0;
2306 my $sum = 1;
2307 $tmp_regions_sum /= 512;
2308 while ($sum < $tmp_regions_sum)
2309 {
2310 $sum *= 2;
2311 $count++;
2312 }
2313 if (($count/2) == 1)
2314 {
2315 $count += 1;
2316 }
2317 $count /= 2;
2318 for (my $i=0; $i<$count; $i++)
2319 {
2320 $nor_total_lsmt *= 2;
2321 }
2322 }
2323 }
2324
2325 ###
2326 my $template = <<"__TEMPLATE";
2327
2328#ifdef __NOR_FDM5__
2329
2330/*******************************************************************************
2331 Follow the 4 steps below to configure flash memory
2332
2333 Step 1. Fill the flash bank (partition) information table,
2334 flash device features flexible, multi-bank read-while-program and
2335 read-while-erase capability, enabling background programming or erasing in
2336 one bank simultaneously with code execution or data reads in another bank.
2337 Each element in the table is the format as below:
2338 {bank size, bank number},
2339
2340 Step 2. Modify the value of LSMT, you can see MemoryDevice_FlashDisk_FAQ for
2341 detail information
2342
2343 Step 2. Define the toal sectors (512bytes) of system drive
2344 the remainder is the size of public drive
2345 If there is no partiton (just one drive, system drive)
2346 set this value to STORAGE_NO_PARTITION (0xFFFFFFFF)
2347
2348
2349 Note : Code region and FAT region can not share the same bank (partition)
2350*******************************************************************************/
2351
2352
2353/***********
2354 * Step 1. *
2355 ***********/
2356#define NOR_FDM5_BANK_INFO_LAYOUT $bank_info_string
2357
2358/***********
2359 * Step 2. *
2360 ***********/
2361#define NOR_TOTAL_LSMT $nor_total_lsmt
2362
2363/***********
2364 * Step 3. *
2365 ***********/
2366// Set NOR_SYSDRV_SECTORS to 0 will disable this setting and use PARTITION_SECTORS in custom_memorydevice.h to set user drive size.
2367#define NOR_SYSDRV_SECTORS 0
2368
2369#endif //__NOR_FDM5__
2370
2371__TEMPLATE
2372
2373 return $template;
2374}
2375
2376#****************************************************************************
2377# subroutine: split_info_for_UB
2378# return: List of RegionInfo/BlockInfo/BankInfo
2379# input: $info: Excel value to be split
2380#****************************************************************************
2381sub split_info_for_UB
2382{
2383 my $text = shift;
2384 my @new = ();
2385 my $ref_str;
2386 my $i;
2387 push(@new, $+) while $text =~ m{
2388 "([^\"\\]*(?:\\.[^\"\\]*)*)", ?
2389 | ([^,]+), ?
2390 | ,
2391 }gx;
2392 push(@new, undef) if substr($text, -1,1) eq ',';
2393 for($i = 0; $i < @new; $i++){
2394 print "$i: $new[$i]\n";
2395 }
2396 $ref_str = "(";
2397 for($i = 0; $i < @new; $i++){
2398 if($i == (@new -1))
2399 {
2400 $ref_str .= $new[$i];
2401 }
2402 else
2403 {
2404 $ref_str .= $new[$i] . "|";
2405 }
2406
2407 }
2408 $ref_str .= ")";
2409 print "$ref_str\n";
2410 return $ref_str;
2411}
2412
2413return 1;