yu.dong | c33b307 | 2024-08-21 23:14:49 -0700 | [diff] [blame^] | 1 | #!/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) 2005 |
| 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 | #* |
| 38 | #* Filename: |
| 39 | #* --------- |
| 40 | #* link.pl |
| 41 | #* |
| 42 | #* Project: |
| 43 | #* -------- |
| 44 | #* |
| 45 | #* |
| 46 | #* Description: |
| 47 | #* ------------ |
| 48 | #* 1. This script will read link error and decide to enter two-phase linking |
| 49 | #* 2. If need, it will adjust ROM LENGTH. |
| 50 | #* |
| 51 | #* |
| 52 | #* Author: |
| 53 | #* ------- |
| 54 | #* Frank Hu |
| 55 | #* |
| 56 | #*============================================================================ |
| 57 | #* HISTORY |
| 58 | #* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| 59 | #*------------------------------------------------------------------------------ |
| 60 | #* |
| 61 | #*------------------------------------------------------------------------------ |
| 62 | #* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| 63 | #*============================================================================ |
| 64 | #**************************************************************************** |
| 65 | |
| 66 | use strict; |
| 67 | BEGIN { push @INC , './tools/', './tools/MemoryUtility/' } # add additional library path |
| 68 | use LinkerOutputParser; |
| 69 | use POSIX qw(floor ceil); |
| 70 | use FileInfoParser; |
| 71 | |
| 72 | package Type; |
| 73 | use constant Log => 0; |
| 74 | use constant Warning => 1; |
| 75 | use constant Fatal => 2; |
| 76 | |
| 77 | my ($LD, $LDS, $LinkLog, $LibTemp, $Makefile, $Mapfile) = @ARGV; |
| 78 | |
| 79 | die "$LD does not exist!\n" unless(-e $LD); |
| 80 | |
| 81 | system("$LD \@$LibTemp > $LinkLog 2>&1"); |
| 82 | exit 0 if($? == 0); |
| 83 | |
| 84 | &msg_handler(Type::Warning, "First link failed and check if it is UROM overflow.", __FILE__, __LINE__); |
| 85 | my %makefile_option; |
| 86 | &msg_handler(Type::Fatal, "Fail to open $LinkLog.", __FILE__, __LINE__) if(1 != &FileInfo::Parse_MAKEFILE($Makefile, \%makefile_option)); |
| 87 | |
| 88 | my ($bUROMOverflow, $ExceedSize, $address, $new_UROM_size) = (0, undef); |
| 89 | if (FileInfo::is("COMPILER_ISA", "NANOMIPS")) { |
| 90 | open LINK, "< $LinkLog" or &msg_handler(Type::Fatal, "Fail to open $LinkLog.", __FILE__, __LINE__); |
| 91 | my $last_ROM_section; |
| 92 | if (FileInfo::is("AMMS_DRDI_SUPPORT", "TRUE")) { |
| 93 | $last_ROM_section = "CACHED_EXTSRAM_MCURO_HWRW_DRDI_NR_63"; |
| 94 | } else { |
| 95 | $last_ROM_section = "ROM_SIGNATURE_SECTION"; |
| 96 | } |
| 97 | map { ($address, $bUROMOverflow) = ($1, 1) if(/^$LD: error: address (0x\w+) of section $last_ROM_section is not within region UROM/); } (<LINK>); |
| 98 | close LINK; |
| 99 | |
| 100 | $new_UROM_size = hex($address) + Get_LastSection_Size($last_ROM_section); |
| 101 | |
| 102 | } elsif (FileInfo::is("COMPILER_ISA", "MIPS16") or FileInfo::is("COMPILER_ISA", "MIPS32")) { |
| 103 | open LINK, "< $LinkLog" or &msg_handler(Type::Fatal, "Fail to open $LinkLog.", __FILE__, __LINE__); |
| 104 | map { ($ExceedSize, $bUROMOverflow) = ($1, 1) if(/^$LD: region `UROM' overflowed by (\d+) bytes/); } (<LINK>); |
| 105 | close LINK; |
| 106 | |
| 107 | } else { |
| 108 | &msg_handler(Type::Fatal, "Mismatch COMPILER_ISA, please check in project makefile.", __FILE__, __LINE__); |
| 109 | } |
| 110 | |
| 111 | if($bUROMOverflow == 1) { |
| 112 | &msg_handler(Type::Warning, "UROM overflow, Second-Link will be executed next.", __FILE__, __LINE__); |
| 113 | |
| 114 | my $nUROMAdjustedLength; |
| 115 | my ($nUROMOrigin, $nUROMLength) = &GetUROMInfo(); |
| 116 | if (FileInfo::is("COMPILER_ISA", "NANOMIPS")) { |
| 117 | $nUROMAdjustedLength = POSIX::ceil(($new_UROM_size) / (1024 * 1024)) * 1024 * 1024 ; |
| 118 | } elsif (FileInfo::is("COMPILER_ISA", "MIPS16") or FileInfo::is("COMPILER_ISA", "MIPS32")) { |
| 119 | $nUROMAdjustedLength = POSIX::ceil(($nUROMLength + $ExceedSize) / (1024 * 1024)) * 1024 * 1024 ; |
| 120 | } else { |
| 121 | &msg_handler(Type::Fatal, "Mismatch COMPILER_ISA, please check in project makefile.", __FILE__, __LINE__); |
| 122 | } |
| 123 | my $nUROMAdjustedStrLength = sprintf("0x%08x", $nUROMAdjustedLength); |
| 124 | my $RAM_AdjustedOrigin = POSIX::ceil(($nUROMOrigin + $nUROMAdjustedLength) / (1024 * 1024)) * 1024 * 1024; |
| 125 | my $RAM_AdjustedStrOrigin = sprintf("0x%08x", $RAM_AdjustedOrigin); |
| 126 | |
| 127 | &UpdateLDS($nUROMAdjustedStrLength, $RAM_AdjustedStrOrigin); |
| 128 | |
| 129 | my $Log = "\n"; |
| 130 | $Log .= sprintf "|----------------Memory Space Adjustment-------------|\n"; |
| 131 | $Log .= sprintf "+----------------------+--------------+--------------+\n"; |
| 132 | $Log .= sprintf "+----------------------+--------------+--------------+\n"; |
| 133 | $Log .= sprintf "+ Memory Space + Old Setting + New Setting +\n"; |
| 134 | $Log .= sprintf "+----------------------+--------------+--------------+\n"; |
| 135 | |
| 136 | $Log .= (sprintf "| %20s | 0x%.8x | 0x%.8x |\n", "UROM/ROM (LENGTH)", $nUROMLength, $nUROMAdjustedLength); |
| 137 | $Log .= (sprintf "| %20s | 0x%.8x | 0x%.8x |\n", "RAM (ORIGIN)", $nUROMLength, $RAM_AdjustedOrigin); |
| 138 | $Log .= sprintf "+----------------------+--------------+--------------+\n"; |
| 139 | |
| 140 | &msg_handler(Type::Log, $Log, __FILE__, __LINE__); |
| 141 | |
| 142 | #start the second link. |
| 143 | &msg_handler(Type::Warning, "======== Second Linking Process Start ========", __FILE__, __LINE__); |
| 144 | |
| 145 | system("$LD \@$LibTemp > $LinkLog 2>&1"); |
| 146 | if($? == 0) { |
| 147 | &msg_handler(Type::Warning, "======== Second Linking Process End ========", __FILE__, __LINE__); |
| 148 | exit 0; |
| 149 | } |
| 150 | else { |
| 151 | &msg_handler(Type::Fatal, "======== *** Second Linking Process fail, please check link.log. ========", __FILE__, __LINE__); |
| 152 | } |
| 153 | } else { |
| 154 | &msg_handler(Type::Fatal, "link fail, please check link.log.", __FILE__, __LINE__); |
| 155 | } |
| 156 | |
| 157 | sub GetUROMInfo |
| 158 | { |
| 159 | my ($nOrigin, $nLength) = (undef, undef); |
| 160 | |
| 161 | open LDS, "< $LDS" or &msg_handler(Type::Fatal, "Fail to open $LDS.", __FILE__, __LINE__); |
| 162 | map { ($nOrigin, $nLength) = (hex($1), hex($2)) if(/^\s+UROM\s*:\s*ORIGIN\s*=\s*(\S+)\s*,\s*LENGTH\s*=\s*(\S+)\s*$/); } (<LDS>); |
| 163 | close LDS; |
| 164 | &msg_handler(Type::Fatal, "UROM can't be found in $LDS", __FILE__, __LINE__) unless(defined $nOrigin and defined $nLength); |
| 165 | |
| 166 | return ($nOrigin, $nLength); |
| 167 | } |
| 168 | |
| 169 | sub UpdateLDS |
| 170 | { |
| 171 | my ($UROMLength, $RAMOrigin) = @_; |
| 172 | my ($Out, $bit) = (undef, 0); |
| 173 | open LDS, "< $LDS" or &msg_handler(Type::Fatal, "Fail to open $LDS.", __FILE__, __LINE__); |
| 174 | while(<LDS>) { |
| 175 | $bit ++ if(s/^\s+UROM\s*:\s*ORIGIN\s*=\s*0x00000000\s*,\s*LENGTH\s*=\s*\S+\s*$/ UROM : ORIGIN = 0x00000000, LENGTH = $UROMLength\n/ || |
| 176 | s/^\s+RAM\s*:\s*ORIGIN\s*=\s*\S+\s*,\s*LENGTH\s*=\s*(\S+)\s*$/ RAM : ORIGIN = $RAMOrigin, LENGTH = $1\n/); |
| 177 | $Out .= $_; |
| 178 | } |
| 179 | &msg_handler(Type::Fatal, "UROM/RAM can't be found in $LDS.", __FILE__, __LINE__) if ($bit != 2); |
| 180 | close LDS; |
| 181 | |
| 182 | open LDS, "> $LDS" or &msg_handler(Type::Fatal, "Fail to open $LDS.", __FILE__, __LINE__); |
| 183 | print LDS $Out; |
| 184 | close LDS; |
| 185 | } |
| 186 | |
| 187 | sub Get_LastSection_Size |
| 188 | { |
| 189 | my ($last_section_name) = @_; |
| 190 | |
| 191 | my ($flag, $VMA, $size) = (0, 0, 0); |
| 192 | open MAP, "< $Mapfile" or &msg_handler(Type::Fatal, "Fail to open $Mapfile.", __FILE__, __LINE__); |
| 193 | foreach my $line (<MAP>) { |
| 194 | $flag = 1 if ($line =~ /^$last_section_name$/); |
| 195 | last if ($flag == 2); |
| 196 | next if ($flag != 1); |
| 197 | if ($flag == 1 and $line =~ /^\s+(0x\w+)\s+(0x\w+)/) { |
| 198 | ($VMA, $size) = (hex($1), hex($2)); |
| 199 | $flag = 2; |
| 200 | } |
| 201 | } |
| 202 | &msg_handler(Type::Fatal, "Cannot find size of last ROM section($last_section_name) in $Mapfile.", __FILE__, __LINE__) if ($flag != 2); |
| 203 | close MAP; |
| 204 | |
| 205 | return $size; |
| 206 | } |
| 207 | |
| 208 | sub msg_handler |
| 209 | { |
| 210 | my ($type, $msg, $file_name, $line_no) = (@_); |
| 211 | my $prompt_prefix; |
| 212 | if($type == Type::Log) { |
| 213 | print $msg . "\n"; |
| 214 | } |
| 215 | elsif($type == Type::Warning) { |
| 216 | $prompt_prefix = ">> LINK Warning : "; |
| 217 | my $location = (defined $file_name) ? "[$file_name] " : ""; |
| 218 | print $prompt_prefix . $location . $msg . "\n"; |
| 219 | } |
| 220 | elsif($type == Type::Fatal) { |
| 221 | $prompt_prefix = ">> *** LINK Fatal : "; |
| 222 | my $location = "[at line $line_no] "; |
| 223 | die $prompt_prefix . $location . $msg . "\n"; |
| 224 | } |
| 225 | } |