[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/tools/link.pl b/mcu/tools/link.pl
new file mode 100644
index 0000000..42d78ea
--- /dev/null
+++ b/mcu/tools/link.pl
@@ -0,0 +1,225 @@
+#!/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) 2005
+#
+# 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:
+#* ---------
+#* link.pl
+#*
+#* Project:
+#* --------
+#*
+#*
+#* Description:
+#* ------------
+#* 1. This script will read link error and decide to enter two-phase linking
+#* 2. If need, it will adjust ROM LENGTH.
+#*
+#*
+#* Author:
+#* -------
+#* Frank Hu
+#*
+#*============================================================================
+#* HISTORY
+#* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+#*------------------------------------------------------------------------------
+#*
+#*------------------------------------------------------------------------------
+#* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+#*============================================================================
+#****************************************************************************
+
+use strict;
+BEGIN { push @INC , './tools/', './tools/MemoryUtility/' } # add additional library path
+use LinkerOutputParser;
+use POSIX qw(floor ceil);
+use FileInfoParser;
+
+package Type;
+use constant Log => 0;
+use constant Warning => 1;
+use constant Fatal => 2;
+
+my ($LD, $LDS, $LinkLog, $LibTemp, $Makefile, $Mapfile) = @ARGV;
+
+die "$LD does not exist!\n" unless(-e $LD);
+
+system("$LD \@$LibTemp > $LinkLog 2>&1");
+exit 0 if($? == 0);
+
+&msg_handler(Type::Warning, "First link failed and check if it is UROM overflow.", __FILE__, __LINE__);
+my %makefile_option;
+&msg_handler(Type::Fatal, "Fail to open $LinkLog.", __FILE__, __LINE__) if(1 != &FileInfo::Parse_MAKEFILE($Makefile, \%makefile_option));
+
+my ($bUROMOverflow, $ExceedSize, $address, $new_UROM_size) = (0, undef);
+if (FileInfo::is("COMPILER_ISA", "NANOMIPS")) {
+ open LINK, "< $LinkLog" or &msg_handler(Type::Fatal, "Fail to open $LinkLog.", __FILE__, __LINE__);
+ my $last_ROM_section;
+ if (FileInfo::is("AMMS_DRDI_SUPPORT", "TRUE")) {
+ $last_ROM_section = "CACHED_EXTSRAM_MCURO_HWRW_DRDI_NR_63";
+ } else {
+ $last_ROM_section = "ROM_SIGNATURE_SECTION";
+ }
+ map { ($address, $bUROMOverflow) = ($1, 1) if(/^$LD: error: address (0x\w+) of section $last_ROM_section is not within region UROM/); } (<LINK>);
+ close LINK;
+
+ $new_UROM_size = hex($address) + Get_LastSection_Size($last_ROM_section);
+
+} elsif (FileInfo::is("COMPILER_ISA", "MIPS16") or FileInfo::is("COMPILER_ISA", "MIPS32")) {
+ open LINK, "< $LinkLog" or &msg_handler(Type::Fatal, "Fail to open $LinkLog.", __FILE__, __LINE__);
+ map { ($ExceedSize, $bUROMOverflow) = ($1, 1) if(/^$LD: region `UROM' overflowed by (\d+) bytes/); } (<LINK>);
+ close LINK;
+
+} else {
+ &msg_handler(Type::Fatal, "Mismatch COMPILER_ISA, please check in project makefile.", __FILE__, __LINE__);
+}
+
+if($bUROMOverflow == 1) {
+ &msg_handler(Type::Warning, "UROM overflow, Second-Link will be executed next.", __FILE__, __LINE__);
+
+ my $nUROMAdjustedLength;
+ my ($nUROMOrigin, $nUROMLength) = &GetUROMInfo();
+ if (FileInfo::is("COMPILER_ISA", "NANOMIPS")) {
+ $nUROMAdjustedLength = POSIX::ceil(($new_UROM_size) / (1024 * 1024)) * 1024 * 1024 ;
+ } elsif (FileInfo::is("COMPILER_ISA", "MIPS16") or FileInfo::is("COMPILER_ISA", "MIPS32")) {
+ $nUROMAdjustedLength = POSIX::ceil(($nUROMLength + $ExceedSize) / (1024 * 1024)) * 1024 * 1024 ;
+ } else {
+ &msg_handler(Type::Fatal, "Mismatch COMPILER_ISA, please check in project makefile.", __FILE__, __LINE__);
+ }
+ my $nUROMAdjustedStrLength = sprintf("0x%08x", $nUROMAdjustedLength);
+ my $RAM_AdjustedOrigin = POSIX::ceil(($nUROMOrigin + $nUROMAdjustedLength) / (1024 * 1024)) * 1024 * 1024;
+ my $RAM_AdjustedStrOrigin = sprintf("0x%08x", $RAM_AdjustedOrigin);
+
+ &UpdateLDS($nUROMAdjustedStrLength, $RAM_AdjustedStrOrigin);
+
+ my $Log = "\n";
+ $Log .= sprintf "|----------------Memory Space Adjustment-------------|\n";
+ $Log .= sprintf "+----------------------+--------------+--------------+\n";
+ $Log .= sprintf "+----------------------+--------------+--------------+\n";
+ $Log .= sprintf "+ Memory Space + Old Setting + New Setting +\n";
+ $Log .= sprintf "+----------------------+--------------+--------------+\n";
+
+ $Log .= (sprintf "| %20s | 0x%.8x | 0x%.8x |\n", "UROM/ROM (LENGTH)", $nUROMLength, $nUROMAdjustedLength);
+ $Log .= (sprintf "| %20s | 0x%.8x | 0x%.8x |\n", "RAM (ORIGIN)", $nUROMLength, $RAM_AdjustedOrigin);
+ $Log .= sprintf "+----------------------+--------------+--------------+\n";
+
+ &msg_handler(Type::Log, $Log, __FILE__, __LINE__);
+
+ #start the second link.
+ &msg_handler(Type::Warning, "======== Second Linking Process Start ========", __FILE__, __LINE__);
+
+ system("$LD \@$LibTemp > $LinkLog 2>&1");
+ if($? == 0) {
+ &msg_handler(Type::Warning, "======== Second Linking Process End ========", __FILE__, __LINE__);
+ exit 0;
+ }
+ else {
+ &msg_handler(Type::Fatal, "======== *** Second Linking Process fail, please check link.log. ========", __FILE__, __LINE__);
+ }
+} else {
+ &msg_handler(Type::Fatal, "link fail, please check link.log.", __FILE__, __LINE__);
+}
+
+sub GetUROMInfo
+{
+ my ($nOrigin, $nLength) = (undef, undef);
+
+ open LDS, "< $LDS" or &msg_handler(Type::Fatal, "Fail to open $LDS.", __FILE__, __LINE__);
+ map { ($nOrigin, $nLength) = (hex($1), hex($2)) if(/^\s+UROM\s*:\s*ORIGIN\s*=\s*(\S+)\s*,\s*LENGTH\s*=\s*(\S+)\s*$/); } (<LDS>);
+ close LDS;
+ &msg_handler(Type::Fatal, "UROM can't be found in $LDS", __FILE__, __LINE__) unless(defined $nOrigin and defined $nLength);
+
+ return ($nOrigin, $nLength);
+}
+
+sub UpdateLDS
+{
+ my ($UROMLength, $RAMOrigin) = @_;
+ my ($Out, $bit) = (undef, 0);
+ open LDS, "< $LDS" or &msg_handler(Type::Fatal, "Fail to open $LDS.", __FILE__, __LINE__);
+ while(<LDS>) {
+ $bit ++ if(s/^\s+UROM\s*:\s*ORIGIN\s*=\s*0x00000000\s*,\s*LENGTH\s*=\s*\S+\s*$/ UROM : ORIGIN = 0x00000000, LENGTH = $UROMLength\n/ ||
+ s/^\s+RAM\s*:\s*ORIGIN\s*=\s*\S+\s*,\s*LENGTH\s*=\s*(\S+)\s*$/ RAM : ORIGIN = $RAMOrigin, LENGTH = $1\n/);
+ $Out .= $_;
+ }
+ &msg_handler(Type::Fatal, "UROM/RAM can't be found in $LDS.", __FILE__, __LINE__) if ($bit != 2);
+ close LDS;
+
+ open LDS, "> $LDS" or &msg_handler(Type::Fatal, "Fail to open $LDS.", __FILE__, __LINE__);
+ print LDS $Out;
+ close LDS;
+}
+
+sub Get_LastSection_Size
+{
+ my ($last_section_name) = @_;
+
+ my ($flag, $VMA, $size) = (0, 0, 0);
+ open MAP, "< $Mapfile" or &msg_handler(Type::Fatal, "Fail to open $Mapfile.", __FILE__, __LINE__);
+ foreach my $line (<MAP>) {
+ $flag = 1 if ($line =~ /^$last_section_name$/);
+ last if ($flag == 2);
+ next if ($flag != 1);
+ if ($flag == 1 and $line =~ /^\s+(0x\w+)\s+(0x\w+)/) {
+ ($VMA, $size) = (hex($1), hex($2));
+ $flag = 2;
+ }
+ }
+ &msg_handler(Type::Fatal, "Cannot find size of last ROM section($last_section_name) in $Mapfile.", __FILE__, __LINE__) if ($flag != 2);
+ close MAP;
+
+ return $size;
+}
+
+sub msg_handler
+{
+ my ($type, $msg, $file_name, $line_no) = (@_);
+ my $prompt_prefix;
+ if($type == Type::Log) {
+ print $msg . "\n";
+ }
+ elsif($type == Type::Warning) {
+ $prompt_prefix = ">> LINK Warning : ";
+ my $location = (defined $file_name) ? "[$file_name] " : "";
+ print $prompt_prefix . $location . $msg . "\n";
+ }
+ elsif($type == Type::Fatal) {
+ $prompt_prefix = ">> *** LINK Fatal : ";
+ my $location = "[at line $line_no] ";
+ die $prompt_prefix . $location . $msg . "\n";
+ }
+}
\ No newline at end of file