rjw | 6c1fd8f | 2022-11-30 14:33:01 +0800 | [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) 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 | #* initLogParser.pl |
| 40 | #* |
| 41 | #* Project: |
| 42 | #* -------- |
| 43 | #* |
| 44 | #* |
| 45 | #* Description: |
| 46 | #* ------------ |
| 47 | #* This script parses raw data of the boot-up log |
| 48 | #* |
| 49 | #* Author: |
| 50 | #* ------- |
| 51 | #* Dot Li (mtk02439) |
| 52 | #* |
| 53 | #*============================================================================ |
| 54 | #* HISTORY |
| 55 | #* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| 56 | #*------------------------------------------------------------------------------ |
| 57 | #* $Revision$ |
| 58 | #* $Modtime$ |
| 59 | #* $Log$ |
| 60 | #* |
| 61 | #* 04 17 2013 dot.li |
| 62 | #* [MOLY00019590] [SystemService][Init] Smartphone modem boot-up trace phase 2 |
| 63 | #* . |
| 64 | #* |
| 65 | #* 03 12 2013 dot.li |
| 66 | #* [MOLY00011540] [SystemService][Init] Smartphone modem boot-up trace |
| 67 | #* . |
| 68 | #* |
| 69 | #*------------------------------------------------------------------------------ |
| 70 | #* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| 71 | #*============================================================================ |
| 72 | #****************************************************************************/ |
| 73 | |
| 74 | BEGIN { push @INC, "pcore/" , '..' } # add additional library path |
| 75 | |
| 76 | #**************************************************************************** |
| 77 | # Input arguments |
| 78 | #**************************************************************************** |
| 79 | my $LOG_STAGE = $ARGV[0]; |
| 80 | |
| 81 | my $DebugPrint = 1; # 1 for debug; 0 for non-debug |
| 82 | |
| 83 | #**************************************************************************** |
| 84 | # >>> Handle boot-up stage |
| 85 | #**************************************************************************** |
| 86 | #**************************************************************************** |
| 87 | # 1 >>> Abort at stage 1 |
| 88 | #**************************************************************************** |
| 89 | if ($LOG_STAGE eq "HS1") { |
| 90 | print "MD init stage 1\n"; |
| 91 | |
| 92 | #**************************************************************************** |
| 93 | # 1-1 >>> Parsing stage 1 label |
| 94 | #**************************************************************************** |
| 95 | my $stage1_label_file = "../../../pcore/driver/sys_drv/init/inc/bootarm.h"; |
| 96 | |
| 97 | &error_handler("$stage1_label_file: NOT exist!", __FILE__, __LINE__) if (!-e $stage1_label_file); |
| 98 | open (FILE_HANDLE, "<$stage1_label_file") or &error_handler("$stage1_label_file: file error!", __FILE__, __LINE__); |
| 99 | |
| 100 | my ($line, $add_label, @boot_stage_label, @boot_stage_code, $i); |
| 101 | |
| 102 | $add_label = 0; # not start enum |
| 103 | $i = 0; |
| 104 | |
| 105 | # parsing enum info |
| 106 | while ($line = <FILE_HANDLE>) { |
| 107 | if ($line =~ m/#define LABEL/) { |
| 108 | $boot_stage_label[$i] = $1 if ($line =~ m/(LABEL_(\w|\d)+)/ ); |
| 109 | $boot_stage_code[$i] = $1 if ($line =~ m/((0x|0X)[0-9A-Fa-f]+)/ ); |
| 110 | $i++; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | #**************************************************************************** |
| 115 | # 1-2 >>> Matching and output result |
| 116 | #**************************************************************************** |
| 117 | |
| 118 | print "Magic:"; |
| 119 | $hex=$ARGV[1]; |
| 120 | while($hex =~ /(.{2})/sg) { |
| 121 | print chr(hex($1)); |
| 122 | } |
| 123 | print " (0x$ARGV[1])\n"; |
| 124 | |
| 125 | if ($ARGV[1] =~ /30305f49/) { |
| 126 | $matching = 0; |
| 127 | |
| 128 | for($i = 0; $i < $#boot_stage_label; $i++) { |
| 129 | if(hex($boot_stage_code[$i]) == hex($ARGV[2])) { |
| 130 | print "last label record: $boot_stage_label[$i]\n"; |
| 131 | $matching = 1; |
| 132 | last; |
| 133 | } |
| 134 | } |
| 135 | print "No matching stage found!!\n" if ($matching == 0); |
| 136 | } |
| 137 | } # boot stage HS1 |
| 138 | #**************************************************************************** |
| 139 | # 2 >>> Abort at stage 2 |
| 140 | # input format: ./initLogParser.pl HS2 [project flavor] [log file] |
| 141 | #**************************************************************************** |
| 142 | if ($LOG_STAGE eq "HS2") { |
| 143 | |
| 144 | #**************************************************************************** |
| 145 | # 2-0 >>> Parse CPU speed |
| 146 | #**************************************************************************** |
| 147 | |
| 148 | use FileInfoParser; |
| 149 | my %MAKEFILE_OPTIONS; |
| 150 | my $themf = "../../make/" . $ARGV[1]; |
| 151 | if(1!=&FileInfo::Parse_MAKEFILE($themf, \%MAKEFILE_OPTIONS)) |
| 152 | { |
| 153 | &sysUtil::sysgen_die("[1.1]Parse MakeFile failed"); |
| 154 | } |
| 155 | |
| 156 | my $CPU_MHZ = $MAKEFILE_OPTIONS{'MCU_CLOCK'}; |
| 157 | |
| 158 | $CPU_MHZ =~ s/\D//g; |
| 159 | |
| 160 | my $LOG_FILE = $ARGV[2]; |
| 161 | |
| 162 | # to align error message file name format |
| 163 | $LOG_FILE =~ s/^.\\|^\\//; |
| 164 | |
| 165 | #**************************************************************************** |
| 166 | # 2-1 >>> Print out input parameters for checking |
| 167 | #**************************************************************************** |
| 168 | if ($DebugPrint == 1) { |
| 169 | print "LOG_STAGE: $LOG_STAGE\n"; |
| 170 | print "LOG_FILE: $LOG_FILE\n"; |
| 171 | print "\n"; |
| 172 | } |
| 173 | |
| 174 | my (@boot_log_raw, $boot_log, $start_idx, $i); |
| 175 | |
| 176 | #**************************************************************************** |
| 177 | # 2-2 >>> Read In Exception Log |
| 178 | #**************************************************************************** |
| 179 | print "Starting stage1... (Read in boot-up log)\n" if($DebugPrint == 1); |
| 180 | |
| 181 | &error_handler("$LOG_FILE: NOT exist!", __FILE__, __LINE__) if (!-e $LOG_FILE); |
| 182 | open (FILE_HANDLE, "<$LOG_FILE") or &error_handler("$LOG_FILE: file error!", __FILE__, __LINE__); |
| 183 | #binmode FILE_HANDLE; |
| 184 | |
| 185 | # parsing log file |
| 186 | use constant TASK_MAGIC => 0x4B534154; |
| 187 | |
| 188 | my ($line, @data32); |
| 189 | |
| 190 | $i = 0; |
| 191 | while ($line = <FILE_HANDLE>) { |
| 192 | if ($line =~ /(\w+) (\w+) (\w+) (\w+)/) { |
| 193 | $data32[0] = $1; |
| 194 | $data32[1] = $2; |
| 195 | $data32[2] = $3; |
| 196 | $data32[3] = $4; |
| 197 | foreach $_ (@data32) { |
| 198 | $boot_log_raw[$i++] = hex($_); |
| 199 | } |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | close (FILE_HANDLE); |
| 204 | |
| 205 | #**************************************************************************** |
| 206 | # 2-3 >>> Parse Header for log address |
| 207 | #**************************************************************************** |
| 208 | print "Starting stage2... (Parse header for log address)\n" if($DebugPrint == 1); |
| 209 | |
| 210 | $start_idx = $boot_log_raw[0]/16; |
| 211 | #print "$boot_log_raw[0] , $start_idx\n"; |
| 212 | |
| 213 | #**************************************************************************** |
| 214 | # 2-4 >>> Parse Boot-Up Log |
| 215 | #**************************************************************************** |
| 216 | print "Starting stage3... (Parse boot-up log)\n" if($DebugPrint == 1); |
| 217 | |
| 218 | $boot_log .= "CPU Speed = ".$CPU_MHZ." MHz\n"; |
| 219 | |
| 220 | print "MD init stage 2\n"; |
| 221 | my @boot_stage = &hs2_label_parse(); |
| 222 | |
| 223 | $boot_log .= sprintf("%4s%10s (%10s)\t\tLog\n","Idx","msec","CPU cycle"); |
| 224 | |
| 225 | my ($parse_task, $log_size, $ts_msec, $temp_str); |
| 226 | $i = $start_idx; |
| 227 | while($i < @boot_log_raw) { |
| 228 | if($boot_log_raw[$i] != 0) { |
| 229 | if($boot_log_raw[$i] == TASK_MAGIC) { |
| 230 | $parse_task = $boot_log_raw[$i+1]; |
| 231 | } else { |
| 232 | $log_size++; |
| 233 | $ts_msec = sprintf("%.2f", $boot_log_raw[$i+1] / $CPU_MHZ / 1000); # milli-second |
| 234 | if ($parse_task == 1) { |
| 235 | $boot_log .= sprintf("[%2d]%10.2f ms (%10d)\t\t[Task] Start of task index $boot_log_raw[$i] init \n", $log_size, $ts_msec, $boot_log_raw[$i+1]); |
| 236 | } else { |
| 237 | $boot_log .= sprintf("[%2d]%10.2f ms (%10d)\t\Start of $boot_stage[$boot_log_raw[$i]]\n", $log_size, $ts_msec, $boot_log_raw[$i+1]); |
| 238 | } |
| 239 | } |
| 240 | } |
| 241 | $i += 2; |
| 242 | } |
| 243 | |
| 244 | # print to console |
| 245 | print $boot_log; |
| 246 | print "Number of log = $log_size\n" if($DebugPrint == 1); |
| 247 | |
| 248 | #**************************************************************************** |
| 249 | # 2-5 >>> Output to a TXT |
| 250 | #**************************************************************************** |
| 251 | print "Output to $LOG_FILE.txt\n"; |
| 252 | open (FILE_HANDLE, ">$LOG_FILE.txt") or &error_handler("$LOG_FILE: file error!", __FILE__, __LINE__); |
| 253 | print FILE_HANDLE $boot_log; |
| 254 | close (FILE_HANDLE); |
| 255 | |
| 256 | } # boot stage HS2 |
| 257 | |
| 258 | #**************************************************************************** |
| 259 | # oo >>> Finished |
| 260 | #**************************************************************************** |
| 261 | exit 0; |
| 262 | |
| 263 | |
| 264 | #**************************************************************************** |
| 265 | # subroutine: error_handler |
| 266 | # input: $error_msg: error message |
| 267 | # $file: filename |
| 268 | # $line_no: line number |
| 269 | #**************************************************************************** |
| 270 | sub error_handler |
| 271 | { |
| 272 | my ($error_msg, $file, $line_no) = @_; |
| 273 | |
| 274 | my $final_error_msg = "BOOT LOG PARSER ERROR: $error_msg at $file line $line_no\n"; |
| 275 | die $final_error_msg; |
| 276 | } |
| 277 | |
| 278 | |
| 279 | #**************************************************************************** |
| 280 | # subroutine: hs2_label_parse |
| 281 | #**************************************************************************** |
| 282 | sub hs2_label_parse |
| 283 | { |
| 284 | my $stage2_label_file = "../../../pcore/driver/sys_drv/init/inc/init_trc_id.h"; |
| 285 | |
| 286 | &error_handler("$stage2_label_file: NOT exist!", __FILE__, __LINE__) if (!-e $stage2_label_file); |
| 287 | open (FILE_HANDLE, "<$stage2_label_file") or &error_handler("$stage2_label_file: file error!", __FILE__, __LINE__); |
| 288 | |
| 289 | my ($line, $add_label, @label_arr, $i); |
| 290 | |
| 291 | $add_label = 0; # not start enum |
| 292 | $i = 0; |
| 293 | |
| 294 | # parsing enum info |
| 295 | while ($line = <FILE_HANDLE>) { |
| 296 | if ($line =~ m/typedef enum {/) { |
| 297 | $add_label = 1; |
| 298 | } |
| 299 | |
| 300 | if ($line =~ m/} BOOT;/) { |
| 301 | $add_label = 2; |
| 302 | } |
| 303 | |
| 304 | if($add_label == 1) { |
| 305 | if ($line =~ m/(BOOT_(\w|\d)+)/) { |
| 306 | $label_arr[$i++]=$1; |
| 307 | } |
| 308 | } |
| 309 | } |
| 310 | |
| 311 | |
| 312 | return @label_arr; |
| 313 | } |