[Feature]Upload Modem source code

Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/tools/AutoAdjustL2CacheLockSection.pl b/mcu/tools/AutoAdjustL2CacheLockSection.pl
new file mode 100644
index 0000000..5d81585
--- /dev/null
+++ b/mcu/tools/AutoAdjustL2CacheLockSection.pl
@@ -0,0 +1,396 @@
+#!/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) 2018
+#
+#  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:
+#* ---------
+#*   AutoAdjustInputSection.pl
+#*
+#* Project:
+#* --------
+#*
+#*
+#* Description:
+#* ------------
+#*   This scripts is used to parse the configuration of Auto-Placement symbols with order.
+#*
+#* Author:
+#* -------
+#*   Yao Liu (mtk15073)
+#*
+#****************************************************************************/
+
+use strict;
+use warnings;
+
+BEGIN { push @INC , './tools/' }  # add additional library path
+use FileInfoParser;
+use CommonUtility;
+use File::Basename;
+use File::Spec;
+use Data::Dumper;
+use constant {
+    LOG        => 0,
+    WARNING    => 1,
+    FATAL      => 2,
+};
+
+my ($ToolChainBase, $LDSFileName, $Tempdir) = (@ARGV);
+&msg_handler(LOG, "Input file: $ToolChainBase, $LDSFileName, $Tempdir\n");
+
+my ($Readelf, $AR);
+my ($Project, $Flavor);
+my ($LibPath1Prefix, $LibPath2Prefix);
+my $tempInputFolder;
+&GetEnvInfo();
+
+#record all the used lib and obj
+my %libObjHash;
+#extract the info of all symbols of a .obj
+my %SymLogInfoHash;
+#extract the info of all sections of a .obj
+my %SecLogInfoHash;
+#Enable/disable local test, 0: disable, 1: enable
+my $local_test = 0;
+#record all official config info
+my %Official_Config;
+#record all local config info
+my %Local_Config;
+#record all section ID
+my %SectionIDHash;
+#record the order of section ID
+my @SectionOrder;
+
+my $official_config = $Tempdir."~official_config.ldf";
+my $local_config = $Tempdir."~local_config.ldf";
+&msg_handler(FATAL, "official/local config file do not exist!\n") if(!-e $official_config && !-e $local_config);
+
+&ParseConfigFile($official_config);
+&ParseConfigFile($local_config) if($local_test);
+
+&ParseLibObj();
+
+&CheckUserConfiguration();
+
+&UpdateLDS($LDSFileName);
+
+&CleanTempFiles();
+
+
+exit 0;
+
+sub GetEnvInfo
+{
+    $AR      = $ToolChainBase."ar";
+    $Readelf = $ToolChainBase."readelf";
+
+    &msg_handler(FATAL, "GCC tool does not exist", __LINE__) unless(-e $Readelf and -e $AR);
+
+    my $RelPath = File::Basename::dirname($LDSFileName);
+    my $AbsPath = File::Spec->rel2abs($RelPath);
+
+    if($AbsPath =~ m|/mcu/build/(\w+)/(\w+)/|) {
+        ($Project, $Flavor) = ($1, $2);
+    }else {
+        &msg_handler(FATAL, "Fail to get project and flavor", __LINE__);
+    }
+
+    $LibPath1Prefix = "./mtk_rel/$Project/$Flavor/TARGET/lib/";
+    $LibPath2Prefix = "./build/$Project/$Flavor/bin/lib/";
+
+    $tempInputFolder = $Tempdir . "CustomInputSection";
+    system("rm -rf $tempInputFolder") if(-e $tempInputFolder);
+    system("mkdir -p $tempInputFolder");
+    $? == 0 or &msg_handler(FATAL, "Making $tempInputFolder failed $?", __LINE__);
+}
+
+sub ParseConfigFile
+{
+    my ($ConfigFile) = (@_);
+    my $FileName = $ConfigFile;
+
+    open CFG, "$ConfigFile" or &msg_handler(FATAL, "Can not open $ConfigFile!", __LINE__);
+    local $/ = undef;
+    my $tempOutput = <CFG>;
+    close CFG;
+
+    my ($SubSection, $bFlag, $sFlag) = (undef, 0, 0);
+    my @TotalSecArray;
+    my $BreakRegExp = "[\\*]{20}\\s[<]\\sGROUP\\s*CFG\\s[>]\\s[\\*]{20}";
+
+    #split entire config file into several configuration groups.
+    foreach my $line (split /\n/, $tempOutput) {
+        if($bFlag == 0) {
+            $bFlag = 1 if(($line =~ m/^\[Symbol\]\s+\[Obj\]\s+\[Lib\]$/));
+            next;
+        }
+        next if($line =~ m/^\s*$/);
+
+        if($line =~ m/^\s*$BreakRegExp\s*$/) {
+            $sFlag = 1;
+            if(defined $SubSection) {
+                push @TotalSecArray, $SubSection;
+                undef $SubSection;
+            }
+            next;
+        }
+        $SubSection .= $line."\n" if($sFlag == 1);
+    }
+    push @TotalSecArray, $SubSection if(defined $SubSection);
+
+    my %unique;
+    foreach my $content (@TotalSecArray) {
+        my @tempArray = split /\n/, $content;
+        my ($Section_ID, $name_flag, $size_flag);
+        foreach my $line (@tempArray) {
+            if($line =~ /^Section ID\s*:\s*(.*)$/) {
+                $Section_ID = $1;
+                if (! $Section_ID =~ /L2CACHE_LOCK_RO_SECTION_\w+/) {
+                    my $msg = "Illegal Line Format: $line";
+                    &msg_handler(FATAL, "Illegal Line Format: $line", __LINE__, $FileName);
+                    next;
+                }
+                &msg_handler(FATAL, "The section ID $Section_ID has been defined in config file!\n", __LINE__) if(exists $SectionIDHash{$Section_ID});
+                $SectionIDHash{$Section_ID} = 0;
+                $name_flag = 1;
+                next;
+            } elsif($line =~ /^Reserved size\s*:\s*(.*)$/ && $name_flag == 1) {
+                $Official_Config{$Section_ID}{"size"} = $1 if($ConfigFile eq $official_config);
+                $Local_Config{$Section_ID}{"size"} = $1 if($ConfigFile eq $local_config);
+                push @SectionOrder, $Section_ID;
+                $size_flag = 1;
+                next;
+            } elsif(!($name_flag == 1 && $size_flag == 1)) {
+                &msg_handler(FATAL, "Wrong config format in $Section_ID!", __LINE__, $FileName);
+            }
+      
+            if($line =~ m/^(\S+)\s+(\S+)\s+(\S+)\s*$/ && ($ConfigFile eq $official_config)) {
+                if(exists $unique{$1.":".$2.":".$3}) {
+                    &msg_handler(FATAL, "[Duplicated Lines]: $line", __LINE__, $FileName);
+                    next;
+                } else {
+                    $Official_Config{$Section_ID}{$1.":".$2.":".$3}{"symbol_name"} = $1;
+                    $Official_Config{$Section_ID}{$1.":".$2.":".$3}{"obj"} = $2;
+                    $Official_Config{$Section_ID}{$1.":".$2.":".$3}{"lib"} = $3;
+                    $unique{$1.":".$2.":".$3} = 0;
+                    $libObjHash{$3}{$2} = 0;
+                }
+            }
+        }
+    }
+}
+
+sub ParseLibObj
+{
+    foreach my $lib (keys %libObjHash) {
+        my $LibPath1 = $LibPath1Prefix . $lib;
+        my $LibPath2 = $LibPath2Prefix . $lib;
+        my $LibPath = (-e $LibPath1) ? $LibPath1 : $LibPath2;
+        if(!-e $LibPath) {
+            delete $libObjHash{$lib};
+            next;
+        }
+
+        my @ObjArray = keys %{$libObjHash{$lib}};
+        foreach my $obj (@ObjArray) {
+            my $ExtractObj = $Tempdir . "CustomInputSection/" . $lib . $obj;
+            my $SymLog = $ExtractObj . "." . "symbols.log";
+            my $SecLog = $ExtractObj . "." . "sections.log";
+
+            next if(-f $SymLog && -f $SecLog); #have been parsed before.
+
+            #extract the obj from lib
+            system("$AR -x $LibPath $obj 2> /dev/null");
+            unless(-f $obj) {
+                delete $libObjHash{$lib}{$obj};
+                next;
+            }
+
+            #move the obj to certain folder
+            system("mv $obj $ExtractObj");
+            $? == 0 or &msg_handler(FATAL, "$ExtractObj moving failed", __LINE__);
+
+            #generate SYM log
+            system("$Readelf --syms -W $ExtractObj > $SymLog");
+            $? == 0 or &msg_handler(FATAL, "Generating $SymLog failed", __LINE__);
+
+            #generate SECTION log
+            system("$Readelf -S -W $ExtractObj > $SecLog");
+            $? == 0 or &msg_handler(FATAL, "Generating $SecLog failed", __LINE__);
+
+            &ParseSymAndSecLog($SymLog, $SecLog, $lib, $obj);
+        }
+    }
+}
+
+sub ParseSymAndSecLog
+{
+    my ($tempSymLog, $tempSecLog, $tempLib, $tempObj) = (@_);
+    my $key = $tempLib . $tempObj;
+
+    open SYM_LOG, "< $tempSymLog" or &msg_handler(FATAL, "Fail to open $tempSymLog", __LINE__);
+    while(my $line = <SYM_LOG>) {
+        #    17: 00000024    40 FUNC    LOCAL  DEFAULT [MIPS16]     9 ev_cmp_f
+        if($line =~ m/^\s*\d+\s*:\s*\S+\s+(\d+).*\s+(\d+)\s+(\w+)$/) {
+            my ($Symbol, $index, $size) = ($3, $2, $1);
+            $SymLogInfoHash{$key}{$Symbol}{'index'} = $index;
+            $SymLogInfoHash{$key}{$Symbol}{'size'}  = $size;
+        }
+    }
+    close SYM_LOG;
+
+    open SEC_LOG, "< $tempSecLog" or &msg_handler(FATAL, "Fail to open $tempSecLog", __LINE__);
+    while(my $line = <SEC_LOG>) {
+        #  [22] .text.evshed_give PROGBITS        00000000 000bbc 00002c 00  AX  0   0  4
+        if($line =~ m/^\s*\[\s*(\d+)\s*\]\s+(\S+)\s+/) {
+            my ($index, $Section) = ($1, $2);
+            if($Section =~ m/^(\.?\w+)\.\w+$/) {
+                $SecLogInfoHash{$key}{$index}{'type'}  = $1;
+                $SecLogInfoHash{$key}{$index}{'valid'} = 'false';
+            }elsif($Section =~ m/^[^\.]*$/) {
+                $SecLogInfoHash{$key}{$index}{'type'}  = $Section;
+                $SecLogInfoHash{$key}{$index}{'valid'} = 'true';
+            }
+        }
+    }
+    close SEC_LOG;
+}
+
+sub CheckUserConfiguration
+{
+    foreach my $id (keys %Official_Config) {
+        foreach my $item (keys %{$Official_Config{$id}}) {
+            next if($item eq "size");
+            my $symbol_name = $Official_Config{$id}{$item}{"symbol_name"};
+            my $obj = $Official_Config{$id}{$item}{"obj"};
+            my $lib = $Official_Config{$id}{$item}{"lib"};
+            my $SymNameInObj;
+            
+            if(not exists $libObjHash{$lib}) { #lib does not exist
+                my $tips = "$lib does not exist.";
+                &msg_handler(FATAL, "$symbol_name not found in Group" . "[$id]" . ": $tips", __LINE__);
+                next;
+            }elsif(not exists $libObjHash{$lib}{$obj}) { #obj can't be found in lib
+                my $tips = "$symbol_name not exists in $obj.";
+                &msg_handler(FATAL, "$symbol_name not found in Group" . "[$id]" . ": $tips", __LINE__);
+                next;
+            }elsif(not exists $SymLogInfoHash{$lib.$obj}) { #the symbol not exists
+                my $tips = "If your symbol type is C++, please use the full name in MAP/SYM, such as [ipfcore_task_init] -> [_Z17ipfcore_task_initv]";
+                &msg_handler(FATAL, "$symbol_name can't be found in Group" . "[$id]" . ", $tips", __LINE__);
+                next;
+            }
+            my $index = $SymLogInfoHash{$lib.$obj}{$symbol_name}{"index"};
+            if(not exists $SecLogInfoHash{$lib.$obj}{$index}) {
+                &msg_handler(FATAL, "Can not find the input section of $symbol_name in [$id]!", __LINE__);
+                next;
+            }elsif(not $SecLogInfoHash{$lib.$obj}{$index}{'type'} eq $id) {
+                &msg_handler(FATAL, "$symbol_name is not used $id to define. Please check!", __LINE__);
+                next;
+            }
+        }
+    }
+}
+
+sub UpdateLDS
+{
+    my ($LDSFile) = (@_);
+    my ($output, $assert, $flag) = (undef, "", 0);
+    open LDS, "< $LDSFile" or &msg_handler(FATAL, "Fail to open $LDSFile", __LINE__);
+
+    while(my $line = <LDS>) {
+        if($line =~ /^(\s+)Image\$\$CACHED_EXTSRAM_L2CACHE_LOCK_RO\$\$Base = \. ;/) {
+            my $prefix = $1;
+            $output .= $line;
+            foreach my $section (@SectionOrder){
+                my $template = <<"__TEMPLATE";
+$prefix. = ALIGN(64);
+$prefix$section\$\$Base = .;
+$prefix* ($section)
+$prefix. = ALIGN(64);
+$prefix$section\$\$Limit = .;
+$prefix$section\$\$Length = ABSOLUTE($section\$\$Limit - $section\$\$Base);
+
+__TEMPLATE
+                $output .= $template;
+                my $setting_size;
+                if(exists $Official_Config{$section}){
+                    $setting_size = $Official_Config{$section}{"size"};
+                }elsif(exists $Local_Config{$section}){
+                    $setting_size = $Local_Config{$section}{"size"};
+                }else{
+                    &msg_handler(FATAL, "The section $section is not defined in config file!", __LINE__);
+                }
+                $assert .= "    ASSERT( $section\$\$Length <= $setting_size,\"$section exceeds the setting size!\")\n";
+            }
+        }elsif($line =~ /^(\s+)ASSERT\(/ && $flag == 0) {
+            $output .= $assert;
+            $output .= $line;
+            $flag = 1;
+        }else{
+            $output .= $line;
+        }
+    }
+    close LDS;
+
+    open LDS, "> $LDSFile" or &msg_handler(FATAL, "Fail to open $LDSFile", __LINE__);
+    print LDS $output;
+    close LDS;
+
+    &msg_handler(LOG, "\nLDS is updated successfully ^O^, please check $LDSFileName.", __LINE__);
+}
+
+sub CleanTempFiles
+{
+    system("rm -rf $tempInputFolder");
+    $? == 0 or &msg_handler(FATAL, "Deleting $tempInputFolder failed $?", __LINE__);
+}
+
+sub msg_handler
+{
+    my ($type, $msg, $line_no) = (@_);
+    my $prompt_prefix;
+    if($type == LOG) {
+        print $msg . "\n";
+    }
+    elsif($type == WARNING) {
+        $prompt_prefix = ">> AAIS Warning : ";
+        print $prompt_prefix . $msg . "\n";
+    }
+    elsif($type == FATAL) {
+        $prompt_prefix = ">> *** AAIS Fatal : ";
+        my $location = "[at line $line_no] ";
+        die $prompt_prefix . $location . $msg . "\n";
+    }
+}