[Feature]Upload Modem source code

Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/tools/zImageConfig.pl b/mcu/tools/zImageConfig.pl
new file mode 100644
index 0000000..604cf3c
--- /dev/null
+++ b/mcu/tools/zImageConfig.pl
@@ -0,0 +1,541 @@
+#!/usr/bin/perl

+#

+#  Copyright Statement:

+#  --------------------

+#  This software is protected by Copyright and the information contained

+#  herein is confidential. The software may not be copied and the information

+#  contained herein may not be used or disclosed except with the written

+#  permission of MediaTek Inc. (C) 2006

+#

+#  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES

+#  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")

+#  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON

+#  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,

+#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF

+#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.

+#  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE

+#  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR

+#  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH

+#  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO

+#  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S

+#  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.

+#

+#  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE

+#  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,

+#  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,

+#  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO

+#  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.

+#

+#  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE

+#  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF

+#  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND

+#  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER

+#  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).

+#

+#*****************************************************************************

+#*

+#* Filename:

+#* ---------

+#*   zImageConfig.pl

+#*

+#* Project:

+#* --------

+#*

+#*

+#* Description:

+#* ------------

+#*   This script parse scatter file and 

+#*       1. force generate custom_scatstruct.h if update required

+#*       2. force generate custom_scatstruct.c if update required

+#*       3. force generate custom_blconfig.c if update required

+#*

+#* Author:

+#* -------

+#*   Ken Lin  (mtk02554)

+#*

+#*============================================================================

+#*             HISTORY

+#* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!

+#*------------------------------------------------------------------------------

+#* $Revision$

+#* $Modtime$

+#* $Log$

+#*

+#* 05 22 2014 tafang.chen

+#* [MOLY00062786] [UMOLY][SM]

+#* Initial MoDIS build env - fix path problem.

+#*

+#*

+#*------------------------------------------------------------------------------

+#* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!

+#*============================================================================

+#****************************************************************************/

+

+#****************************************************************************

+# Included Modules

+#****************************************************************************

+use strict;

+BEGIN { push @INC, "pcore/" , '.\\pcore\\tools\\' }  # add additional library path 

+use auto_adjust_mem; #pm file name without case sensitivity 

+use File::Copy;

+

+#****************************************************************************

+# Constants

+#****************************************************************************

+my $ZIMAGECONFIG_VERNO     = " v0.11";

+                       #  v0.11 , show healthy check error on the console

+                       #  v0.10 , AAPMC auto check-in support

+                       #  v0.09 , deduct the dcm share pool from $max_compressed_size

+                       #  v0.08 , detect if ZIMAGE overflows as a healthy check in advance

+                       #  v0.07 , take cached dummy end into account in free ram size calculation

+                       #  v0.06 , healthy check for RAM leakage

+                       #  v0.05 , align interface of DemandPagingConfig.pl

+                       #  v0.04 , get zimage config in custom_FeatureConfig.h

+                       #  v0.03 , get FS base address in ~flash_cfg_tmp.c

+                       #  v0.02 , take DCM into account

+                       #  v0.01 , initial draft

+

+#****************************************************************************

+# File Names

+#****************************************************************************

+my $LIS_FILE = $ARGV[0];

+my $DUMMY_ZIMAGE = $ARGV[1];

+my $CUSTOM_EMI_RELEASE_H = $ARGV[2] . '\\' . "custom_EMI_release.h";

+my $CUSTOM_FEATURE_CONFIG_H = $ARGV[2] . '\\' . "custom_FeatureConfig.h";

+my $MAKEFILE = $ARGV[3];

+my $FLASH_CFG_TMP_C = $ARGV[4];

+my $INTERMEDIATE_FILE = $ARGV[5];

+my $LOG_PATH = $ARGV[6];

+

+# to align error message file name format

+$LIS_FILE =~ s/^.\\|^\\//;

+$DUMMY_ZIMAGE =~ s/^.\\|^\\//;

+$CUSTOM_EMI_RELEASE_H   =~ s/^.\\|^\\//;

+$CUSTOM_FEATURE_CONFIG_H =~ s/^.\\|^\\//;

+$MAKEFILE =~ s/^.\\|^\\//;

+$FLASH_CFG_TMP_C =~ s/^.\\|^\\//;

+$INTERMEDIATE_FILE =~ s/^.\\|^\\//;

+$LOG_PATH =~ s/^.\\|^\\//;

+

+my $DebugPrint    = 1; # 1 for debug; 0 for non-debug

+

+#****************************************************************************

+# 0 >>>  Print out input parameters for checking

+#****************************************************************************

+if ($DebugPrint == 1) {

+  print "LIS_FILE: $LIS_FILE\n";

+  print "DUMMY_ZIMAGE: $DUMMY_ZIMAGE\n";

+  print "CUSTOM_EMI_RELEASE_H: $CUSTOM_EMI_RELEASE_H\n";

+  print "CUSTOM_FEATURE_CONFIG_H: $CUSTOM_FEATURE_CONFIG_H\n";

+  print "MAKEFILE: $MAKEFILE\n";

+  print "FLASH_CFG_TMP_C: $FLASH_CFG_TMP_C\n";  

+  print "INTERMEDIATE_FILE: $INTERMEDIATE_FILE\n";

+  print "LOG_PATH: $LOG_PATH\n";

+  print "\n";  

+}

+

+#****************************************************************************

+# 1 >>>  Parse Makefile

+#****************************************************************************

+# assumption: same category should be put together

+use constant FEATURE_NAME => 0;

+use constant CATEGORY => 1;

+use constant LOAD_REGION => 2;

+use constant SWITCH => 3;

+use constant SIZE => 4;

+

+my @feature_option = (

+# feature name             category       load region                 switch(OFF)    size

+  ['MP4_DECODE',             'video',       'DYNAMIC_COMP_MP4DEC',      0,        0],

+  ['H264_DECODE',            'video',       'DYNAMIC_COMP_H264DEC',     0,        0],

+  ['MP4_ENCODE',             'video',       'DYNAMIC_COMP_MP4ENC',      0,        0],  

+  ['BES_LOUDNESS_SUPPORT',   'audio',       'DYNAMIC_COMP_BESLOUDNESS', 0,        0],

+  ['BT_AUDIO_VIA_SCO',       'audio',       'DYNAMIC_COMP_RESAMPLE',    0,        0],

+  ['BT_A2DP_PROFILE',        'audio',       'DYNAMIC_COMP_SBC',         0,        0],

+);

+my $auto_config;

+

+print "Starting stage1 ... \n" if($DebugPrint == 1);

+

+&error_handler("$MAKEFILE: NOT exist!", __FILE__, __LINE__) if (!-e $MAKEFILE);

+

+open (FILE_HANDLE, "<$MAKEFILE") or &error_handler("$MAKEFILE: file error!", __FILE__, __LINE__);

+while (<FILE_HANDLE>) {

+    if (/^(\S+)\s*=\s*TRUE/) {

+        # DCM

+        foreach $_ (@feature_option) {

+            if ($_->[FEATURE_NAME] eq $1) {

+                $_->[SWITCH] = 1; # ON

+            }

+        }

+

+        # ZIMAGE_AUTO_CONFIG

+        if ($1 eq 'ZIMAGE_AUTO_CONFIG') {

+            $auto_config = 1;

+        }

+    }

+}

+

+print "\n";

+

+#****************************************************************************

+# 2 >>>  Parse LIS File

+#****************************************************************************

+my $total_rom;

+my $basic_rom_size;

+my $rw_bound;

+my $dsp_tx_reserved;

+my $dsp_rx_reserved;

+my $orig_zimage_size;

+my $static_zimage_size;

+my $dcm_rom_size;

+my $dcm_ram_size;

+

+

+print "Starting stage2 ... \n" if($DebugPrint == 1);

+

+&error_handler("$LIS_FILE: NOT exist!", __FILE__, __LINE__) if (!-e $LIS_FILE);

+

+open (FILE_HANDLE, "<$LIS_FILE") or &error_handler("$LIS_FILE: file error!", __FILE__, __LINE__);

+while (<FILE_HANDLE>) {

+  if (/Total ROM Size \(Code \+ RO Data \+ RW Data\)\s+(\S+)/) {

+    $total_rom = $1;

+  }

+  elsif (/Execution Region ROM1 \(Base: (\S+), Size: (\S+)/) {

+    $basic_rom_size = (hex($1) & hex("0x07FFFFFF")) + hex($2);

+  }

+  elsif (/Execution Region DYNAMIC_CACHEABLE_EXTSRAM_DEFAULT_CACHEABLE_ZI \(Base: (\S+), Size: (\S+)/) {

+    $rw_bound = (hex($1) & hex("0x07FFFFFF")) + hex($2);

+  }

+  elsif (/Execution Region EXTSRAM_DSP_TX \(Base: (\S+), Size: (\S+), Max: (\S+)/) {

+    $dsp_tx_reserved = hex($3);

+  }

+  elsif (/Execution Region EXTSRAM_DSP_RX \(Base: (\S+), Size: (\S+), Max: (\S+)/) {

+    $dsp_rx_reserved = hex($3);

+  }  

+  elsif (/Load Region ZIMAGE \(Base: (\S+), Size: (\S+)/) {

+    $orig_zimage_size = hex($2);

+  }

+  elsif (/Execution Region ZIMAGE \(Base: (\S+), Size: (\S+)/) {

+    $static_zimage_size = hex($2);

+  }

+  

+  # DCM RO

+  if (/Load Region (\S+) \(Base: (\S+), Size: (\S+)/) {

+    foreach $_ (@feature_option) {

+      if ($_->[SWITCH] == 1 && $_->[LOAD_REGION] eq $1) {

+        $_->[SIZE] = hex($3); # ON

+        $dcm_rom_size += hex($3);

+      }

+    }

+  }

+}

+close (FILE_HANDLE);

+

+# calculate $dcm_ram_size

+my $current_category = $feature_option[0][1];

+my $category_max_size;

+foreach $_ (@feature_option) {

+  print "$_->[FEATURE_NAME], $_->[CATEGORY], $_->[LOAD_REGION], $_->[SWITCH], $_->[SIZE]\n" if($DebugPrint == 1);

+

+  # next category

+  if ($current_category ne $_->[CATEGORY]) {

+    $dcm_ram_size += $category_max_size;

+    $category_max_size = $_->[SIZE];

+    $current_category = $_->[CATEGORY];

+  }

+  # same category, then update the max size

+  elsif ($category_max_size < $_->[SIZE]) {

+    $category_max_size = $_->[SIZE];

+  }

+}

+$dcm_ram_size += $category_max_size; # last category

+print "\n" if($DebugPrint == 1);

+

+if ($DebugPrint == 1) {

+  print "total_rom: $total_rom\n";

+  print "basic_rom_size: $basic_rom_size\n";

+  print "rw_bound: $rw_bound\n";

+  print "dsp_tx_reserved: $dsp_tx_reserved\n";

+  print "dsp_rx_reserved: $dsp_rx_reserved\n";

+  print "orig_zimage_size: $orig_zimage_size\n";  

+  print "static_zimage_size: $static_zimage_size\n";  

+  print "dcm_rom_size: $dcm_rom_size\n";

+  print "dcm_ram_size: $dcm_ram_size\n";

+  print "\n";

+}

+

+#****************************************************************************

+# 3 >>>  Parse custom_FeatureConfig.h 

+#****************************************************************************

+my $orig_decompressed_size;

+my $orig_max_compressed_size;

+

+print "Starting stage3 ... \n" if($DebugPrint == 1);

+

+&error_handler("$CUSTOM_FEATURE_CONFIG_H: NOT exist!", __FILE__, __LINE__) if (!-e $CUSTOM_FEATURE_CONFIG_H);

+

+open (FILE_HANDLE, "<$CUSTOM_FEATURE_CONFIG_H") or &error_handler("$CUSTOM_FEATURE_CONFIG_H: file error!", __FILE__, __LINE__);

+while (<FILE_HANDLE>) {

+  if (/\#define CONFIG_ZIMAGE_DECOMPRESSED_SIZE\s+((\S|\s)+)/) {

+    $orig_decompressed_size = hex($1);

+  }

+  elsif (/\#define CONFIG_ZIMAGE_MAX_COMPRESSED_SIZE\s+((\S|\s)+)/) {

+    $orig_max_compressed_size = hex($1);

+  }

+}

+close (FILE_HANDLE);

+

+if ($DebugPrint == 1) {

+  print "orig_decompressed_size: $orig_decompressed_size\n";

+  print "orig_max_compressed_size: $orig_max_compressed_size\n";

+  print "\n";

+}

+

+#****************************************************************************

+# 4 >>>  Parse custom_EMI_release.h (EMI_EXTSRAM_SIZE)

+#****************************************************************************

+my $max_ram;

+my $ram_bound;

+

+print "Starting stage4 ... \n" if($DebugPrint == 1);

+

+&error_handler("$CUSTOM_EMI_RELEASE_H: NOT exist!", __FILE__, __LINE__) if (!-e $CUSTOM_EMI_RELEASE_H);

+

+open (FILE_HANDLE, "<$CUSTOM_EMI_RELEASE_H") or &error_handler("$CUSTOM_EMI_RELEASE_H: file error!", __FILE__, __LINE__);

+while (<FILE_HANDLE>) {

+  if (/\#define EMI_EXTSRAM_SIZE ((\S|\s)+)/) {

+    $max_ram = eval($1);

+    last;

+  }

+}

+close (FILE_HANDLE);

+

+$ram_bound = $max_ram - $dsp_tx_reserved - $dsp_rx_reserved;

+

+if ($DebugPrint == 1) {

+  print "max_ram: $max_ram\n";

+  print "ram_bound: $ram_bound\n";

+  print "\n";

+}

+

+#****************************************************************************

+# 5 >>>  Parse ~flash_cfg_tmp.c

+#****************************************************************************

+my $fs_base_addr;

+

+print "Starting stage5 ... \n" if($DebugPrint == 1);

+

+&error_handler("$FLASH_CFG_TMP_C: NOT exist!", __FILE__, __LINE__) if (!-e $FLASH_CFG_TMP_C);

+

+open (FILE_HANDLE, "<$FLASH_CFG_TMP_C") or &error_handler("$FLASH_CFG_TMP_C: file error!", __FILE__, __LINE__);

+while (<FILE_HANDLE>) {

+  if (/int flash_base_address\s+=\s+((\S|\s)+);/) {

+    $fs_base_addr = eval($1);

+  }

+}

+close (FILE_HANDLE);

+

+if ($DebugPrint == 1) {

+  print "fs_base_addr: $fs_base_addr\n";  

+  print "\n";

+}

+

+#****************************************************************************

+# 6 >>>  Calculate compression ratio

+#****************************************************************************

+my $zimage_size;

+my $compression_ratio;

+

+print "Starting stage6 ... \n" if($DebugPrint == 1);

+

+$zimage_size = -s $DUMMY_ZIMAGE;

+$compression_ratio = $zimage_size / $orig_zimage_size;

+

+if ($DebugPrint == 1) {

+  print "zimage_size: $zimage_size\n";

+  print "compression_ratio: $compression_ratio\n";  

+  print "\n";

+}

+

+#****************************************************************************

+# 7 >>>  Calculate CONFIG_ZIMAGE_DECOMPRESSED_SIZE 

+#                           & CONFIG_ZIMAGE_MAX_COMPRESSED_SIZE

+#****************************************************************************

+my $decompressed_size;

+my $max_compressed_size;

+my $free_ram_size;

+my $max_decompressed_size;

+my $cached_dummy_end_size = 4;

+

+print "Starting stage7 ... \n" if($DebugPrint == 1);

+

+# calculate $free_ram_size & $max_decompressed_size

+$free_ram_size = $ram_bound - $rw_bound - $cached_dummy_end_size;

+$max_decompressed_size = $total_rom - $basic_rom_size;

+

+# calculate $decompressed_size & $max_compressed_size

+$decompressed_size = min($free_ram_size, $max_decompressed_size);

+$max_compressed_size = int(($decompressed_size - $dcm_ram_size) * $compression_ratio + 0.99); # ceil

+

+if ($DebugPrint == 1) {

+  print "basic_rom_size: $basic_rom_size\n";

+  print "free_ram_size: $free_ram_size\n";

+  print "max_decompressed_size: $max_decompressed_size\n";

+  print "decompressed_size: $decompressed_size\n";

+  print "max_compressed_size: $max_compressed_size\n";

+  print "\n";

+}

+

+#****************************************************************************

+# 8 >>>  Healthy check

+#****************************************************************************

+my $actual_rom_size;

+my $total_compressed_size;

+my $alignment = 4 * 1024;

+

+print "Starting stage8 ... \n" if($DebugPrint == 1);

+

+# health check (1)

+if ($decompressed_size - $dcm_ram_size <= 0) {

+    my $exceeded = -($decompressed_size - $dcm_ram_size);

+    &write_log($INTERMEDIATE_FILE, "Error: Insufficient RAM space. ($exceeded bytes exceeded)\nRecommend: Please turn off some features. (e.g. DCM_COMPRESSION_SUPPORT)\n");

+    exit ERR::CANNOT_ADJUST;    

+}

+

+$actual_rom_size = $total_rom - ($decompressed_size - $dcm_ram_size) - $dcm_rom_size;

+$total_compressed_size = int(($decompressed_size + $dcm_rom_size) * $compression_ratio + 0.99);  # ceil

+if ($DebugPrint == 1) {

+  print "actual_rom_size: $actual_rom_size\n";

+  print "total_compressed_size: $total_compressed_size\n";  

+  print "\n";  

+}

+

+# health check (2)

+if ($actual_rom_size + $total_compressed_size >= $fs_base_addr) {

+    my $exceeded = $actual_rom_size + $total_compressed_size - $fs_base_addr;

+    &write_log($INTERMEDIATE_FILE, "Error: Insufficient flash space. ($exceeded bytes exceeded)\nRecommend: Please turn off some features.\n");

+    exit ERR::CANNOT_ADJUST;

+}

+

+# health check (3)

+if ($free_ram_size < 0) {

+    my $exceeded = -$free_ram_size;

+    &write_log($INTERMEDIATE_FILE, "Error: Insufficient RAM space. ($exceeded bytes exceeded)\nRecommend: Please turn off some features.\n");

+    exit ERR::CANNOT_ADJUST;

+}

+

+# make alignment (floor)

+$decompressed_size = int($decompressed_size / $alignment) * $alignment;

+$max_compressed_size = int($max_compressed_size / $alignment) * $alignment;

+

+# health check (4)

+if (($decompressed_size - $dcm_ram_size) <= $static_zimage_size) {

+    my $exceeded = $static_zimage_size - ($decompressed_size - $dcm_ram_size);

+    &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");

+    exit ERR::CANNOT_ADJUST;

+}

+

+# health check (5)

+if ($decompressed_size == $orig_decompressed_size && $max_compressed_size == $orig_max_compressed_size) {

+    &write_log($INTERMEDIATE_FILE, "Error: Invalid configuration.\nRecommend: Please call for help.\n");

+    exit ERR::CANNOT_ADJUST;

+}

+

+#****************************************************************************

+# 9 >>>  Output

+#****************************************************************************

+my $err;

+

+print "Starting stage9 ... \n" if($DebugPrint == 1);

+

+# convert to hex

+$orig_decompressed_size = sprintf("0x%X", $orig_decompressed_size);

+$orig_max_compressed_size = sprintf("0x%X", $orig_max_compressed_size);

+

+$decompressed_size = sprintf("0x%X", $decompressed_size);

+$max_compressed_size = sprintf("0x%X", $max_compressed_size);

+

+if ($auto_config) {

+    if( ERR::AAPMCLOG_SUCCESS == &AAPMCLogParser::Open($LOG_PATH)) {

+        my $P4Info_ref = &AUTO_ADJUST::CreateP4InfoTemplate("mtk01892", "", "zImage auto config",

+                         "[Before]\n($orig_decompressed_size, $orig_max_compressed_size)\n[After]\n($decompressed_size, $max_compressed_size)\n");

+    

+    my %ChangeList = (

+        'CONFIG_ZIMAGE_DECOMPRESSED_SIZE' => $decompressed_size,

+        'CONFIG_ZIMAGE_MAX_COMPRESSED_SIZE' => $max_compressed_size,

+    );

+        $err = &AAPMCLogParser::AddOneChangeRecord($CUSTOM_FEATURE_CONFIG_H, \%ChangeList, \%$P4Info_ref);

+        if($err == ERR::ERR_MODIFYDUPLICATED) {

+            print "can't modified more than twice\n";

+        }

+        elsif ($err == ERR::AAPMCLOG_SUCCESS) {

+            print "add successfully!\n";

+            &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");

+        }

+        &AAPMCLogParser::Close($LOG_PATH);        

+    }

+    else {

+        print "load AAPMCLog failed";

+    }  

+}

+else {

+    print "No modification\n";

+    &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");

+    exit ERR::NO_MODIFY;    

+}

+

+

+#****************************************************************************

+# oo >>>  Finished

+#****************************************************************************

+exit $err;

+

+

+#****************************************************************************

+# subroutine:  min

+# input:       $m, $n

+#****************************************************************************

+sub min

+{

+    my ($m, $n) = @_;

+	   

+    if ($m < $n) {

+        $m

+    }

+    else {

+        $n

+    }

+}

+

+

+#****************************************************************************

+# subroutine:  error_handler

+# input:       $error_msg:     error message

+#              $file:          filename

+#              $line_no:       line number

+#****************************************************************************

+sub error_handler

+{

+    my ($error_msg, $file, $line_no) = @_;

+

+    print "ZIMAGE CONFIG ERROR: $error_msg at $file line $line_no\n";	   

+    my $final_error_msg = "ZIMAGE CONFIG ERROR: $error_msg at $file line $line_no\n";

+    die $final_error_msg;

+}

+

+

+#****************************************************************************

+# subroutine:  write_log

+# input:     $log_path

+#****************************************************************************

+sub write_log

+{

+    my ($log_path, $message) = @_;

+    

+    print $message;

+    

+    open (FILE_HANDLE, ">$log_path") or &error_handler("Cannot open log: $log_path\n", __FILE__, __LINE__);

+    print FILE_HANDLE $message;

+    close FILE_HANDLE;

+}