blob: 604cf3caa955293cbb9106f7a41fda803d47b595 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001#!/usr/bin/perl
2#
3# Copyright Statement:
4# --------------------
5# This software is protected by Copyright and the information contained
6# herein is confidential. The software may not be copied and the information
7# contained herein may not be used or disclosed except with the written
8# permission of MediaTek Inc. (C) 2006
9#
10# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
11# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
12# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
13# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
14# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
15# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
16# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
17# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
18# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
19# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
20# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
21# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
22#
23# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
24# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
25# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
26# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
27# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
28#
29# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
30# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
31# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
32# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
33# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
34#
35#*****************************************************************************
36#*
37#* Filename:
38#* ---------
39#* zImageConfig.pl
40#*
41#* Project:
42#* --------
43#*
44#*
45#* Description:
46#* ------------
47#* This script parse scatter file and
48#* 1. force generate custom_scatstruct.h if update required
49#* 2. force generate custom_scatstruct.c if update required
50#* 3. force generate custom_blconfig.c if update required
51#*
52#* Author:
53#* -------
54#* Ken Lin (mtk02554)
55#*
56#*============================================================================
57#* HISTORY
58#* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
59#*------------------------------------------------------------------------------
60#* $Revision$
61#* $Modtime$
62#* $Log$
63#*
64#* 05 22 2014 tafang.chen
65#* [MOLY00062786] [UMOLY][SM]
66#* Initial MoDIS build env - fix path problem.
67#*
68#*
69#*------------------------------------------------------------------------------
70#* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
71#*============================================================================
72#****************************************************************************/
73
74#****************************************************************************
75# Included Modules
76#****************************************************************************
77use strict;
78BEGIN { push @INC, "pcore/" , '.\\pcore\\tools\\' } # add additional library path
79use auto_adjust_mem; #pm file name without case sensitivity
80use File::Copy;
81
82#****************************************************************************
83# Constants
84#****************************************************************************
85my $ZIMAGECONFIG_VERNO = " v0.11";
86 # v0.11 , show healthy check error on the console
87 # v0.10 , AAPMC auto check-in support
88 # v0.09 , deduct the dcm share pool from $max_compressed_size
89 # v0.08 , detect if ZIMAGE overflows as a healthy check in advance
90 # v0.07 , take cached dummy end into account in free ram size calculation
91 # v0.06 , healthy check for RAM leakage
92 # v0.05 , align interface of DemandPagingConfig.pl
93 # v0.04 , get zimage config in custom_FeatureConfig.h
94 # v0.03 , get FS base address in ~flash_cfg_tmp.c
95 # v0.02 , take DCM into account
96 # v0.01 , initial draft
97
98#****************************************************************************
99# File Names
100#****************************************************************************
101my $LIS_FILE = $ARGV[0];
102my $DUMMY_ZIMAGE = $ARGV[1];
103my $CUSTOM_EMI_RELEASE_H = $ARGV[2] . '\\' . "custom_EMI_release.h";
104my $CUSTOM_FEATURE_CONFIG_H = $ARGV[2] . '\\' . "custom_FeatureConfig.h";
105my $MAKEFILE = $ARGV[3];
106my $FLASH_CFG_TMP_C = $ARGV[4];
107my $INTERMEDIATE_FILE = $ARGV[5];
108my $LOG_PATH = $ARGV[6];
109
110# to align error message file name format
111$LIS_FILE =~ s/^.\\|^\\//;
112$DUMMY_ZIMAGE =~ s/^.\\|^\\//;
113$CUSTOM_EMI_RELEASE_H =~ s/^.\\|^\\//;
114$CUSTOM_FEATURE_CONFIG_H =~ s/^.\\|^\\//;
115$MAKEFILE =~ s/^.\\|^\\//;
116$FLASH_CFG_TMP_C =~ s/^.\\|^\\//;
117$INTERMEDIATE_FILE =~ s/^.\\|^\\//;
118$LOG_PATH =~ s/^.\\|^\\//;
119
120my $DebugPrint = 1; # 1 for debug; 0 for non-debug
121
122#****************************************************************************
123# 0 >>> Print out input parameters for checking
124#****************************************************************************
125if ($DebugPrint == 1) {
126 print "LIS_FILE: $LIS_FILE\n";
127 print "DUMMY_ZIMAGE: $DUMMY_ZIMAGE\n";
128 print "CUSTOM_EMI_RELEASE_H: $CUSTOM_EMI_RELEASE_H\n";
129 print "CUSTOM_FEATURE_CONFIG_H: $CUSTOM_FEATURE_CONFIG_H\n";
130 print "MAKEFILE: $MAKEFILE\n";
131 print "FLASH_CFG_TMP_C: $FLASH_CFG_TMP_C\n";
132 print "INTERMEDIATE_FILE: $INTERMEDIATE_FILE\n";
133 print "LOG_PATH: $LOG_PATH\n";
134 print "\n";
135}
136
137#****************************************************************************
138# 1 >>> Parse Makefile
139#****************************************************************************
140# assumption: same category should be put together
141use constant FEATURE_NAME => 0;
142use constant CATEGORY => 1;
143use constant LOAD_REGION => 2;
144use constant SWITCH => 3;
145use constant SIZE => 4;
146
147my @feature_option = (
148# feature name category load region switch(OFF) size
149 ['MP4_DECODE', 'video', 'DYNAMIC_COMP_MP4DEC', 0, 0],
150 ['H264_DECODE', 'video', 'DYNAMIC_COMP_H264DEC', 0, 0],
151 ['MP4_ENCODE', 'video', 'DYNAMIC_COMP_MP4ENC', 0, 0],
152 ['BES_LOUDNESS_SUPPORT', 'audio', 'DYNAMIC_COMP_BESLOUDNESS', 0, 0],
153 ['BT_AUDIO_VIA_SCO', 'audio', 'DYNAMIC_COMP_RESAMPLE', 0, 0],
154 ['BT_A2DP_PROFILE', 'audio', 'DYNAMIC_COMP_SBC', 0, 0],
155);
156my $auto_config;
157
158print "Starting stage1 ... \n" if($DebugPrint == 1);
159
160&error_handler("$MAKEFILE: NOT exist!", __FILE__, __LINE__) if (!-e $MAKEFILE);
161
162open (FILE_HANDLE, "<$MAKEFILE") or &error_handler("$MAKEFILE: file error!", __FILE__, __LINE__);
163while (<FILE_HANDLE>) {
164 if (/^(\S+)\s*=\s*TRUE/) {
165 # DCM
166 foreach $_ (@feature_option) {
167 if ($_->[FEATURE_NAME] eq $1) {
168 $_->[SWITCH] = 1; # ON
169 }
170 }
171
172 # ZIMAGE_AUTO_CONFIG
173 if ($1 eq 'ZIMAGE_AUTO_CONFIG') {
174 $auto_config = 1;
175 }
176 }
177}
178
179print "\n";
180
181#****************************************************************************
182# 2 >>> Parse LIS File
183#****************************************************************************
184my $total_rom;
185my $basic_rom_size;
186my $rw_bound;
187my $dsp_tx_reserved;
188my $dsp_rx_reserved;
189my $orig_zimage_size;
190my $static_zimage_size;
191my $dcm_rom_size;
192my $dcm_ram_size;
193
194
195print "Starting stage2 ... \n" if($DebugPrint == 1);
196
197&error_handler("$LIS_FILE: NOT exist!", __FILE__, __LINE__) if (!-e $LIS_FILE);
198
199open (FILE_HANDLE, "<$LIS_FILE") or &error_handler("$LIS_FILE: file error!", __FILE__, __LINE__);
200while (<FILE_HANDLE>) {
201 if (/Total ROM Size \(Code \+ RO Data \+ RW Data\)\s+(\S+)/) {
202 $total_rom = $1;
203 }
204 elsif (/Execution Region ROM1 \(Base: (\S+), Size: (\S+)/) {
205 $basic_rom_size = (hex($1) & hex("0x07FFFFFF")) + hex($2);
206 }
207 elsif (/Execution Region DYNAMIC_CACHEABLE_EXTSRAM_DEFAULT_CACHEABLE_ZI \(Base: (\S+), Size: (\S+)/) {
208 $rw_bound = (hex($1) & hex("0x07FFFFFF")) + hex($2);
209 }
210 elsif (/Execution Region EXTSRAM_DSP_TX \(Base: (\S+), Size: (\S+), Max: (\S+)/) {
211 $dsp_tx_reserved = hex($3);
212 }
213 elsif (/Execution Region EXTSRAM_DSP_RX \(Base: (\S+), Size: (\S+), Max: (\S+)/) {
214 $dsp_rx_reserved = hex($3);
215 }
216 elsif (/Load Region ZIMAGE \(Base: (\S+), Size: (\S+)/) {
217 $orig_zimage_size = hex($2);
218 }
219 elsif (/Execution Region ZIMAGE \(Base: (\S+), Size: (\S+)/) {
220 $static_zimage_size = hex($2);
221 }
222
223 # DCM RO
224 if (/Load Region (\S+) \(Base: (\S+), Size: (\S+)/) {
225 foreach $_ (@feature_option) {
226 if ($_->[SWITCH] == 1 && $_->[LOAD_REGION] eq $1) {
227 $_->[SIZE] = hex($3); # ON
228 $dcm_rom_size += hex($3);
229 }
230 }
231 }
232}
233close (FILE_HANDLE);
234
235# calculate $dcm_ram_size
236my $current_category = $feature_option[0][1];
237my $category_max_size;
238foreach $_ (@feature_option) {
239 print "$_->[FEATURE_NAME], $_->[CATEGORY], $_->[LOAD_REGION], $_->[SWITCH], $_->[SIZE]\n" if($DebugPrint == 1);
240
241 # next category
242 if ($current_category ne $_->[CATEGORY]) {
243 $dcm_ram_size += $category_max_size;
244 $category_max_size = $_->[SIZE];
245 $current_category = $_->[CATEGORY];
246 }
247 # same category, then update the max size
248 elsif ($category_max_size < $_->[SIZE]) {
249 $category_max_size = $_->[SIZE];
250 }
251}
252$dcm_ram_size += $category_max_size; # last category
253print "\n" if($DebugPrint == 1);
254
255if ($DebugPrint == 1) {
256 print "total_rom: $total_rom\n";
257 print "basic_rom_size: $basic_rom_size\n";
258 print "rw_bound: $rw_bound\n";
259 print "dsp_tx_reserved: $dsp_tx_reserved\n";
260 print "dsp_rx_reserved: $dsp_rx_reserved\n";
261 print "orig_zimage_size: $orig_zimage_size\n";
262 print "static_zimage_size: $static_zimage_size\n";
263 print "dcm_rom_size: $dcm_rom_size\n";
264 print "dcm_ram_size: $dcm_ram_size\n";
265 print "\n";
266}
267
268#****************************************************************************
269# 3 >>> Parse custom_FeatureConfig.h
270#****************************************************************************
271my $orig_decompressed_size;
272my $orig_max_compressed_size;
273
274print "Starting stage3 ... \n" if($DebugPrint == 1);
275
276&error_handler("$CUSTOM_FEATURE_CONFIG_H: NOT exist!", __FILE__, __LINE__) if (!-e $CUSTOM_FEATURE_CONFIG_H);
277
278open (FILE_HANDLE, "<$CUSTOM_FEATURE_CONFIG_H") or &error_handler("$CUSTOM_FEATURE_CONFIG_H: file error!", __FILE__, __LINE__);
279while (<FILE_HANDLE>) {
280 if (/\#define CONFIG_ZIMAGE_DECOMPRESSED_SIZE\s+((\S|\s)+)/) {
281 $orig_decompressed_size = hex($1);
282 }
283 elsif (/\#define CONFIG_ZIMAGE_MAX_COMPRESSED_SIZE\s+((\S|\s)+)/) {
284 $orig_max_compressed_size = hex($1);
285 }
286}
287close (FILE_HANDLE);
288
289if ($DebugPrint == 1) {
290 print "orig_decompressed_size: $orig_decompressed_size\n";
291 print "orig_max_compressed_size: $orig_max_compressed_size\n";
292 print "\n";
293}
294
295#****************************************************************************
296# 4 >>> Parse custom_EMI_release.h (EMI_EXTSRAM_SIZE)
297#****************************************************************************
298my $max_ram;
299my $ram_bound;
300
301print "Starting stage4 ... \n" if($DebugPrint == 1);
302
303&error_handler("$CUSTOM_EMI_RELEASE_H: NOT exist!", __FILE__, __LINE__) if (!-e $CUSTOM_EMI_RELEASE_H);
304
305open (FILE_HANDLE, "<$CUSTOM_EMI_RELEASE_H") or &error_handler("$CUSTOM_EMI_RELEASE_H: file error!", __FILE__, __LINE__);
306while (<FILE_HANDLE>) {
307 if (/\#define EMI_EXTSRAM_SIZE ((\S|\s)+)/) {
308 $max_ram = eval($1);
309 last;
310 }
311}
312close (FILE_HANDLE);
313
314$ram_bound = $max_ram - $dsp_tx_reserved - $dsp_rx_reserved;
315
316if ($DebugPrint == 1) {
317 print "max_ram: $max_ram\n";
318 print "ram_bound: $ram_bound\n";
319 print "\n";
320}
321
322#****************************************************************************
323# 5 >>> Parse ~flash_cfg_tmp.c
324#****************************************************************************
325my $fs_base_addr;
326
327print "Starting stage5 ... \n" if($DebugPrint == 1);
328
329&error_handler("$FLASH_CFG_TMP_C: NOT exist!", __FILE__, __LINE__) if (!-e $FLASH_CFG_TMP_C);
330
331open (FILE_HANDLE, "<$FLASH_CFG_TMP_C") or &error_handler("$FLASH_CFG_TMP_C: file error!", __FILE__, __LINE__);
332while (<FILE_HANDLE>) {
333 if (/int flash_base_address\s+=\s+((\S|\s)+);/) {
334 $fs_base_addr = eval($1);
335 }
336}
337close (FILE_HANDLE);
338
339if ($DebugPrint == 1) {
340 print "fs_base_addr: $fs_base_addr\n";
341 print "\n";
342}
343
344#****************************************************************************
345# 6 >>> Calculate compression ratio
346#****************************************************************************
347my $zimage_size;
348my $compression_ratio;
349
350print "Starting stage6 ... \n" if($DebugPrint == 1);
351
352$zimage_size = -s $DUMMY_ZIMAGE;
353$compression_ratio = $zimage_size / $orig_zimage_size;
354
355if ($DebugPrint == 1) {
356 print "zimage_size: $zimage_size\n";
357 print "compression_ratio: $compression_ratio\n";
358 print "\n";
359}
360
361#****************************************************************************
362# 7 >>> Calculate CONFIG_ZIMAGE_DECOMPRESSED_SIZE
363# & CONFIG_ZIMAGE_MAX_COMPRESSED_SIZE
364#****************************************************************************
365my $decompressed_size;
366my $max_compressed_size;
367my $free_ram_size;
368my $max_decompressed_size;
369my $cached_dummy_end_size = 4;
370
371print "Starting stage7 ... \n" if($DebugPrint == 1);
372
373# calculate $free_ram_size & $max_decompressed_size
374$free_ram_size = $ram_bound - $rw_bound - $cached_dummy_end_size;
375$max_decompressed_size = $total_rom - $basic_rom_size;
376
377# calculate $decompressed_size & $max_compressed_size
378$decompressed_size = min($free_ram_size, $max_decompressed_size);
379$max_compressed_size = int(($decompressed_size - $dcm_ram_size) * $compression_ratio + 0.99); # ceil
380
381if ($DebugPrint == 1) {
382 print "basic_rom_size: $basic_rom_size\n";
383 print "free_ram_size: $free_ram_size\n";
384 print "max_decompressed_size: $max_decompressed_size\n";
385 print "decompressed_size: $decompressed_size\n";
386 print "max_compressed_size: $max_compressed_size\n";
387 print "\n";
388}
389
390#****************************************************************************
391# 8 >>> Healthy check
392#****************************************************************************
393my $actual_rom_size;
394my $total_compressed_size;
395my $alignment = 4 * 1024;
396
397print "Starting stage8 ... \n" if($DebugPrint == 1);
398
399# health check (1)
400if ($decompressed_size - $dcm_ram_size <= 0) {
401 my $exceeded = -($decompressed_size - $dcm_ram_size);
402 &write_log($INTERMEDIATE_FILE, "Error: Insufficient RAM space. ($exceeded bytes exceeded)\nRecommend: Please turn off some features. (e.g. DCM_COMPRESSION_SUPPORT)\n");
403 exit ERR::CANNOT_ADJUST;
404}
405
406$actual_rom_size = $total_rom - ($decompressed_size - $dcm_ram_size) - $dcm_rom_size;
407$total_compressed_size = int(($decompressed_size + $dcm_rom_size) * $compression_ratio + 0.99); # ceil
408if ($DebugPrint == 1) {
409 print "actual_rom_size: $actual_rom_size\n";
410 print "total_compressed_size: $total_compressed_size\n";
411 print "\n";
412}
413
414# health check (2)
415if ($actual_rom_size + $total_compressed_size >= $fs_base_addr) {
416 my $exceeded = $actual_rom_size + $total_compressed_size - $fs_base_addr;
417 &write_log($INTERMEDIATE_FILE, "Error: Insufficient flash space. ($exceeded bytes exceeded)\nRecommend: Please turn off some features.\n");
418 exit ERR::CANNOT_ADJUST;
419}
420
421# health check (3)
422if ($free_ram_size < 0) {
423 my $exceeded = -$free_ram_size;
424 &write_log($INTERMEDIATE_FILE, "Error: Insufficient RAM space. ($exceeded bytes exceeded)\nRecommend: Please turn off some features.\n");
425 exit ERR::CANNOT_ADJUST;
426}
427
428# make alignment (floor)
429$decompressed_size = int($decompressed_size / $alignment) * $alignment;
430$max_compressed_size = int($max_compressed_size / $alignment) * $alignment;
431
432# health check (4)
433if (($decompressed_size - $dcm_ram_size) <= $static_zimage_size) {
434 my $exceeded = $static_zimage_size - ($decompressed_size - $dcm_ram_size);
435 &write_log($INTERMEDIATE_FILE, "Error: ZIMAGE overflow. ($exceeded bytes exceeded)\nRecommend: Please either\n (1) remove xxx.lib/xxx.obj from ZIMAGE, or\n (2) turn off some features\n");
436 exit ERR::CANNOT_ADJUST;
437}
438
439# health check (5)
440if ($decompressed_size == $orig_decompressed_size && $max_compressed_size == $orig_max_compressed_size) {
441 &write_log($INTERMEDIATE_FILE, "Error: Invalid configuration.\nRecommend: Please call for help.\n");
442 exit ERR::CANNOT_ADJUST;
443}
444
445#****************************************************************************
446# 9 >>> Output
447#****************************************************************************
448my $err;
449
450print "Starting stage9 ... \n" if($DebugPrint == 1);
451
452# convert to hex
453$orig_decompressed_size = sprintf("0x%X", $orig_decompressed_size);
454$orig_max_compressed_size = sprintf("0x%X", $orig_max_compressed_size);
455
456$decompressed_size = sprintf("0x%X", $decompressed_size);
457$max_compressed_size = sprintf("0x%X", $max_compressed_size);
458
459if ($auto_config) {
460 if( ERR::AAPMCLOG_SUCCESS == &AAPMCLogParser::Open($LOG_PATH)) {
461 my $P4Info_ref = &AUTO_ADJUST::CreateP4InfoTemplate("mtk01892", "", "zImage auto config",
462 "[Before]\n($orig_decompressed_size, $orig_max_compressed_size)\n[After]\n($decompressed_size, $max_compressed_size)\n");
463
464 my %ChangeList = (
465 'CONFIG_ZIMAGE_DECOMPRESSED_SIZE' => $decompressed_size,
466 'CONFIG_ZIMAGE_MAX_COMPRESSED_SIZE' => $max_compressed_size,
467 );
468 $err = &AAPMCLogParser::AddOneChangeRecord($CUSTOM_FEATURE_CONFIG_H, \%ChangeList, \%$P4Info_ref);
469 if($err == ERR::ERR_MODIFYDUPLICATED) {
470 print "can't modified more than twice\n";
471 }
472 elsif ($err == ERR::AAPMCLOG_SUCCESS) {
473 print "add successfully!\n";
474 &write_log($INTERMEDIATE_FILE, "[Before auto adjustment]\nCONFIG_ZIMAGE_DECOMPRESSED_SIZE=$orig_decompressed_size\nCONFIG_ZIMAGE_MAX_COMPRESSED_SIZE=$orig_max_compressed_size\n[After auto adjustment]\nRECOMMAND: CONFIG_ZIMAGE_DECOMPRESSED_SIZE=$decompressed_size\nRECOMMAND: CONFIG_ZIMAGE_MAX_COMPRESSED_SIZE=$max_compressed_size\n");
475 }
476 &AAPMCLogParser::Close($LOG_PATH);
477 }
478 else {
479 print "load AAPMCLog failed";
480 }
481}
482else {
483 print "No modification\n";
484 &write_log($INTERMEDIATE_FILE, "[Before auto adjustment]\nCONFIG_ZIMAGE_DECOMPRESSED_SIZE=$orig_decompressed_size\nCONFIG_ZIMAGE_MAX_COMPRESSED_SIZE=$orig_max_compressed_size\n[After auto adjustment]\nRECOMMAND: CONFIG_ZIMAGE_DECOMPRESSED_SIZE=$decompressed_size\nRECOMMAND: CONFIG_ZIMAGE_MAX_COMPRESSED_SIZE=$max_compressed_size\n");
485 exit ERR::NO_MODIFY;
486}
487
488
489#****************************************************************************
490# oo >>> Finished
491#****************************************************************************
492exit $err;
493
494
495#****************************************************************************
496# subroutine: min
497# input: $m, $n
498#****************************************************************************
499sub min
500{
501 my ($m, $n) = @_;
502
503 if ($m < $n) {
504 $m
505 }
506 else {
507 $n
508 }
509}
510
511
512#****************************************************************************
513# subroutine: error_handler
514# input: $error_msg: error message
515# $file: filename
516# $line_no: line number
517#****************************************************************************
518sub error_handler
519{
520 my ($error_msg, $file, $line_no) = @_;
521
522 print "ZIMAGE CONFIG ERROR: $error_msg at $file line $line_no\n";
523 my $final_error_msg = "ZIMAGE CONFIG ERROR: $error_msg at $file line $line_no\n";
524 die $final_error_msg;
525}
526
527
528#****************************************************************************
529# subroutine: write_log
530# input: $log_path
531#****************************************************************************
532sub write_log
533{
534 my ($log_path, $message) = @_;
535
536 print $message;
537
538 open (FILE_HANDLE, ">$log_path") or &error_handler("Cannot open log: $log_path\n", __FILE__, __LINE__);
539 print FILE_HANDLE $message;
540 close FILE_HANDLE;
541}