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