blob: 985b44e52db2abd1121353474b4fc1d4e5009759 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001#!/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) 2013
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#* prepend_gfh.pl
41#*
42#* Project:
43#* --------
44#* MOLY
45#*
46#* Description:
47#* ------------
48#* Add GFH header for the binary without GFH
49#*
50#* Author:
51#* -------
52#* Chin-Chieh Hung (mtk03404)
53#*
54#****************************************************************************
55use strict;
56
57
58#****************************************************************************
59# Included Modules
60#****************************************************************************
61BEGIN { push @INC, "pcore/" , './LTE_CDP_FMC/Tools/' } # add additional library path
62use File::Basename;
63use File::Copy;
64#use CommonUtility;
65#use tools::pack_dep_gen;
66#PrintDependModule();
67
68#****************************************************************************
69# Constants
70#****************************************************************************
71my $PREPEND_GFH_VERNO = "m0.05";
72# v0.05 by Yu-Hung Huang, add DSP platform id support in m_platform_id instead of hard code to "MT6290"
73# v0.04 by Yu-Hung Huang, support don't care flash in m_flash_dev with value FLASH_DEV_NONE (0x00)
74# v0.03 by Peiwen Qing, add DSP build time support in m_build_time
75# v0.02 by Peiwen Qing, add DSP version support in m_project_id
76# v0.01 by mtk03404 Chin-Chieh Hung, initial version
77
78#Usage: prepend_gfh.pl SRC_BINFILE_PATH(filename) DST_BINFILE_PATH(filename) file_info.conf
79
80#****************************************************************************
81# Global Variables
82#****************************************************************************
83my @GFH_Buffer;
84my $gfh_fileinfo_type = 1;
85my %GFH_FILE_TYPE;
86my %GFH_FLASH_DEV;
87my %GFH_SIG_TYPE;
88
89#****************************************************************************
90# GFH FileInfo Related Enum Definition
91#****************************************************************************
92$GFH_FILE_TYPE{ "LTE_DSP_ROM" } = chr(0x09).chr(0x01); #Big Endian
93
94$GFH_FLASH_DEV{ "FLASH_DEV_NONE" } = chr(0x00);
95$GFH_FLASH_DEV{ "F_NOR" } = chr(0x01);
96$GFH_FLASH_DEV{ "F_NAND_SEQUENTIAL" } = chr(0x02);
97$GFH_FLASH_DEV{ "F_NAND_TTBL" } = chr(0x03);
98$GFH_FLASH_DEV{ "F_NAND_FDM50" } = chr(0x04);
99$GFH_FLASH_DEV{ "F_EMMC_BOOT_REGION" } = chr(0x05);
100$GFH_FLASH_DEV{ "F_EMMC_DATA_REGION" } = chr(0x06);
101$GFH_FLASH_DEV{ "F_SF" } = chr(0x07);
102$GFH_FLASH_DEV{ "F_XBOOT" } = chr(0x08);
103$GFH_FLASH_DEV{ "FLASH_DEV_END" } = chr(0xFF);
104
105$GFH_SIG_TYPE{ "SIG_NONE" } = chr(0x00);
106$GFH_SIG_TYPE{ "SIG_PHASH" } = chr(0x01);
107$GFH_SIG_TYPE{ "SIG_SINGLE" } = chr(0x02);
108$GFH_SIG_TYPE{ "SIG_SINGLE_AND_PHASE" } = chr(0x03);
109$GFH_SIG_TYPE{ "SIG_MULTI" } = chr(0x04);
110$GFH_SIG_TYPE{ "SIG_TYPE_NUM" } = chr(0x05);
111$GFH_SIG_TYPE{ "SIG_TYPE_END" } = chr(0xFF);
112
113#****************************************************************************
114# Input Parameters
115#****************************************************************************
116my ($src_bin_file) = $ARGV[0];
117my ($dst_bin_file) = $ARGV[1];
118my ($file_info_cfg) = $ARGV[2];
119
120#****************************************************************************
121# Parameter Check
122#****************************************************************************
123die "source binary file $src_bin_file doesn't exist" if not -e $src_bin_file;
124die "config file $file_info_cfg doesn't exist" if not -e $file_info_cfg;
125
126
127#****************************************************************************
128# Functions
129#****************************************************************************
130if (&IsGFH($src_bin_file))
131{
132 print "The $dst_bin_file has the GFH header, does not prepend the GFH header for $dst_bin_file";
133 exit 0;
134}
135else
136{
137 my $b;
138 my $sum;
139 my $src_bin_file_size;
140 open (SRC_FILE_HANDLE, "<$src_bin_file") or &error_handler("$src_bin_file: open file error!");
141 binmode(SRC_FILE_HANDLE);
142 while (read(SRC_FILE_HANDLE, $b, 1))
143 {
144 $sum .= $b;
145 }
146 close SRC_FILE_HANDLE;
147
148 open (FILE_HANDLE, ">$dst_bin_file") or &error_handler("$dst_bin_file: open file error!");
149 $src_bin_file_size = (-s $src_bin_file) + 0x38 + 0xE0;
150 &GFH_FileInfo_Gen($file_info_cfg, $src_bin_file_size);
151 &GFH_DSPInfo_Gen($file_info_cfg, 0x38);
152 binmode(FILE_HANDLE);
153 print FILE_HANDLE @GFH_Buffer;
154 print FILE_HANDLE $sum;
155 close FILE_HANDLE;
156
157#copy($src_bin_file, $dst_bin_file) or die "$!";
158}
159
160# GFH_FILE_INFO_v1
161# [ 3: 0] GFH_Header.m_magic_ver
162# [ 5: 4] GFH_Header.m_size, = size of GFH_FILE_INFO_v1 structure
163# [ 7: 6] GFH_Header.m_type, = GFH_FILE_INFO_v1
164# [ 19: 8] identifier, = GFH_FILE_INFO_ID = "FILE_INFO"
165# [ 23: 20] m_file_ver
166# [ 25: 24] m_file_type, = PRI_ROM, DSP_ROM, ...
167# [ : 26] m_flash_dev
168# [ : 27] m_sig_type
169# [ 31: 28] m_load_addr
170# [ 35: 32] m_file_len
171# [ 39: 36] m_max_size
172# [ 43: 40] m_content_offset
173# [ 47: 44] m_sig_len
174# [ 51: 48] m_jump_offset
175# [ 55: 52] m_attr
176sub GFH_FileInfo_Gen
177{
178 my ($config_file, $input_file_len) = @_;
179 my ($nIndex, $data) = (0, undef);
180 my ($CONFIG_FILE_VER, $CONFIG_FILE_TYPE, $FLASH_DEV, $MAX_SIZE) = &GetFileInfoConfig($config_file);
181
182#GFH_Header.m_magic_ver
183 $GFH_Buffer[$nIndex++] = 'MMM'; #'M'
184 $GFH_Buffer[$nIndex++] = chr(0x01);
185
186#GFH_Header.m_size
187 $GFH_Buffer[$nIndex++] = chr(0x38);
188 $GFH_Buffer[$nIndex++] = chr(0x00);
189
190#GFH_Header.m_type
191 $GFH_Buffer[$nIndex++] = chr(0x00);
192 $GFH_Buffer[$nIndex++] = chr(0x00);
193
194#identifier
195 $GFH_Buffer[$nIndex++] = 'FILE_INFO';
196 $GFH_Buffer[$nIndex++] = chr(0x00);
197 $GFH_Buffer[$nIndex++] = chr(0x00);
198 $GFH_Buffer[$nIndex++] = chr(0x00);
199
200#m_file_ver
201 $GFH_Buffer[$nIndex++] = $CONFIG_FILE_VER;
202
203#m_file_type
204 $GFH_Buffer[$nIndex++] = $GFH_FILE_TYPE{ $CONFIG_FILE_TYPE };
205
206#m_flash_dev
207 if($FLASH_DEV =~ /_NAND_FLASH_BOOTING_/)
208 {
209 $GFH_Buffer[$nIndex++] = $GFH_FLASH_DEV{ "F_NAND_FDM50" };
210 }
211 elsif($FLASH_DEV =~ /__EMMC_BOOTING__/)
212 {
213 $GFH_Buffer[$nIndex++] = $GFH_FLASH_DEV{ "F_EMMC_DATA_REGION" };
214 }
215 elsif($FLASH_DEV =~ /__X_BOOTING__/)
216 {
217 $GFH_Buffer[$nIndex++] = $GFH_FLASH_DEV{ "F_XBOOT" };
218 }
219 elsif($FLASH_DEV =~ /__SERIAL_FLASH_EN__/)
220 {
221 $GFH_Buffer[$nIndex++] = $GFH_FLASH_DEV{ "F_SF" };
222 }
223 elsif($FLASH_DEV =~ /__DONT_CARE_FLASH__/)
224 {
225 $GFH_Buffer[$nIndex++] = $GFH_FLASH_DEV{ "FLASH_DEV_NONE" };
226 }
227 else
228 {
229 $GFH_Buffer[$nIndex++] = $GFH_FLASH_DEV{ "F_NOR" };
230 }
231
232#m_sig_type
233 $GFH_Buffer[$nIndex++] = $GFH_SIG_TYPE{ "SIG_NONE" };
234
235#m_load_addr
236 $GFH_Buffer[$nIndex++] = chr(0x00);
237 $GFH_Buffer[$nIndex++] = chr(0x00);
238 $GFH_Buffer[$nIndex++] = chr(0x00);
239 $GFH_Buffer[$nIndex++] = chr(0x00);
240
241#m_file_len
242 $GFH_Buffer[$nIndex++] = &Dec2ASCIIString($input_file_len);
243
244#m_max_size
245 $GFH_Buffer[$nIndex++] = &Dec2ASCIIString($MAX_SIZE);
246
247#m_content_offset
248 $GFH_Buffer[$nIndex++] = chr(0x18);
249 $GFH_Buffer[$nIndex++] = chr(0x01);
250 $GFH_Buffer[$nIndex++] = chr(0x00);
251 $GFH_Buffer[$nIndex++] = chr(0x00);
252
253#m_sig_len
254 $GFH_Buffer[$nIndex++] = chr(0x00);
255 $GFH_Buffer[$nIndex++] = chr(0x00);
256 $GFH_Buffer[$nIndex++] = chr(0x00);
257 $GFH_Buffer[$nIndex++] = chr(0x00);
258
259#m_jump_offset
260 $GFH_Buffer[$nIndex++] = chr(0x00);
261 $GFH_Buffer[$nIndex++] = chr(0x00);
262 $GFH_Buffer[$nIndex++] = chr(0x00);
263 $GFH_Buffer[$nIndex++] = chr(0x00);
264
265#m_attr, no XIP in MT6290, default value is 0
266 $GFH_Buffer[$nIndex++] = chr(0x00);
267 $GFH_Buffer[$nIndex++] = chr(0x00);
268 $GFH_Buffer[$nIndex++] = chr(0x00);
269 $GFH_Buffer[$nIndex++] = chr(0x00);
270
271 print pack("i*", @GFH_Buffer);
272}
273
274# GFH_DSP_INFO_v1
275# [ 3: 0] GFH_Header.m_magic_ver
276# [ 5: 4] GFH_Header.m_size = size of GFH_FILE_INFO_v1 structure
277# [ 7: 6] GFH_Header.m_type = GFH_FILE_INFO_v1
278# [ 11: 8] m_product_ver = 0x1 // 0x0: invalid, 0x1: debug version (DSP image not encrypted), 0x2: release version
279# [ 15: 12] m_image_type // 0x0: invalid, 0x1: normal image, 0x2: RFC flavor image
280# [ 31: 16] m_platform_id[16] // ex: "MT6290_S00", "MT6290_S01", "MT6595_S00"
281# [ 95: 32] m_project_id[64] // ex: "DSPMOLY.W13.21.LTE.p6"
282# [159: 96] m_build_time // ex: "24\10\2013 17:50:29"
283# [223: 160] reserved
284sub GFH_DSPInfo_Gen
285{
286 my ($config_file, $nIndex) = @_;
287 my ($PLATFORM_ID, $VERSION, $BUILD_TIME) = &GetDSPInfoConfig($config_file);
288 my ($counter);
289
290#GFH_Header.m_magic_ver
291 $GFH_Buffer[$nIndex++] = 'MMM'; #'M'
292 $GFH_Buffer[$nIndex++] = chr(0x01);
293
294#GFH_Header.m_size
295 $GFH_Buffer[$nIndex++] = chr(0xE0);
296 $GFH_Buffer[$nIndex++] = chr(0x00);
297
298#GFH_Header.m_type
299 $GFH_Buffer[$nIndex++] = chr(0x04);
300 $GFH_Buffer[$nIndex++] = chr(0x01);
301
302#m_product_ver
303 $GFH_Buffer[$nIndex++] = chr(0x01);
304 $GFH_Buffer[$nIndex++] = chr(0x00);
305 $GFH_Buffer[$nIndex++] = chr(0x00);
306 $GFH_Buffer[$nIndex++] = chr(0x00);
307
308#m_image_type
309 $GFH_Buffer[$nIndex++] = chr(0x00); #why not 1??
310 $GFH_Buffer[$nIndex++] = chr(0x00);
311 $GFH_Buffer[$nIndex++] = chr(0x00);
312 $GFH_Buffer[$nIndex++] = chr(0x00);
313
314#m_platform_id
315 if (length($PLATFORM_ID) > 16)
316 {
317 print "The platform ID strings exceed the max string size 16!";
318 exit 0;
319 }
320 $GFH_Buffer[$nIndex++] = $PLATFORM_ID;
321 for ($counter = length($PLATFORM_ID) + 1; $counter <= 16; $counter++)
322 {
323 $GFH_Buffer[$nIndex++] = chr(0x00);
324 }
325
326#m_project_id
327 if (length($VERSION) > 64)
328 {
329 print "The project ID strings exceed the max string size 64!";
330 exit 0;
331 }
332 $GFH_Buffer[$nIndex++] = $VERSION;
333 for ($counter = length($VERSION) + 1; $counter <= 64; $counter++)
334 {
335 $GFH_Buffer[$nIndex++] = chr(0x00);
336 }
337
338#m_build_time
339 if (length($BUILD_TIME) > 64)
340 {
341 print "The build time strings exceed the max string size 64!";
342 exit 0;
343 }
344 $GFH_Buffer[$nIndex++] = $BUILD_TIME;
345 for ($counter = length($BUILD_TIME) + 1; $counter <= 64; $counter++)
346 {
347 $GFH_Buffer[$nIndex++] = chr(0x00);
348 }
349
350#reserved
351 for (0..63)
352 {
353 $GFH_Buffer[$nIndex++] = chr(0x00);
354 }
355
356 print pack("i*", @GFH_Buffer);
357}
358
359#****************************************************************************
360# subroutine: Get file config
361# input: config file
362# output: File Info config setting
363#****************************************************************************
364sub GetFileInfoConfig
365{
366 my $fileContent = &GetFileContent(@_);
367 my $parse_file_ver;
368 my $parse_file_ver_str;
369 my $parse_file_type;
370 my $parse_flash_dev;
371 my $parse_max_size;
372
373 $fileContent =~ s/(.*)#(.*)/$1/g;
374
375 $fileContent =~ /FILE_VER:[ \f\t]*(\w*)[ \f\t]*/;
376 $parse_file_ver = hex($1);
377 $parse_file_ver_str = &Dec2ASCIIString($parse_file_ver);
378
379 $fileContent =~ /FILE_TYPE:[ \f\t]*(\w*)[ \f\t]*/;
380 $parse_file_type = $1;
381
382 $fileContent =~ /FLASH_DEV:[ \f\t]*(\w*)[ \f\t]*/;
383 $parse_flash_dev = $1;
384
385 $fileContent =~ /MAX_SIZE:[ \f\t]*(\w*)[ \f\t]*/;
386 $parse_max_size = hex($1);
387
388 return ($parse_file_ver_str, $parse_file_type, $parse_flash_dev, $parse_max_size);
389}
390
391#****************************************************************************
392# subroutine: Get dsp config
393# input: config file
394# output: DSP Info config setting
395#****************************************************************************
396sub GetDSPInfoConfig
397{
398 my $fileContent = &GetFileContent(@_);
399 my $platform_id;
400 my $parse_version;
401 my $build_time;
402
403 $fileContent =~ s/(.*)#(.*)/$1/g;
404
405 $fileContent =~ /PLATFORM_ID:[ \f\t]*(.*)[ \f\t]*/;
406 $platform_id = $1;
407
408 $fileContent =~ /VERSION:[ \f\t]*(.*)[ \f\t]*/;
409 $parse_version = $1;
410
411 $fileContent =~ /BUILD_TIME:[ \f\t]*(.*)[ \f\t]*/;
412 $build_time = $1;
413
414 return ($platform_id, $parse_version, $build_time);
415}
416
417#****************************************************************************
418# subroutine: GetFileContent
419# input: strFilePath
420# output: strFileContent after chomp
421#****************************************************************************
422sub GetFileContent
423{
424 my ($strFilePath) = @_;
425 my $content;
426 open FILE, "<$strFilePath" or &error_handler("$strFilePath: open file error!", __FILE__, __LINE__, 'CommonUtil::GetFileContent');
427 {
428 local $/;
429 $content = <FILE>;
430 }
431 close FILE;
432 chomp($content);
433 return $content;
434}
435
436#****************************************************************************
437# subroutine: Dec2HexASCII, without "0x" for prefix, big endian
438# input: Integer value
439# output: Hex ASCII without "0x"
440#****************************************************************************
441sub Dec2ASCIIString
442{
443 my ($dec) = @_;
444 my $str = "";
445 if ($dec > 0x00FF0000)
446 {
447 $str .= chr(($dec >> 0) & 0xFF);
448 $str .= chr(($dec >> 8) & 0xFF);
449 $str .= chr(($dec >> 16) & 0xFF);
450 $str .= chr(($dec >> 24) & 0xFF);
451 }
452 elsif($dec > 0x0000FF00)
453 {
454 $str .= chr($dec & 0xFF);
455 $str .= chr(($dec >> 8) & 0xFF);
456 $str .= chr(($dec >> 16) & 0xFF);
457 $str .= chr(0x00);
458 }
459 elsif($dec > 0x000000FF)
460 {
461 $str .= chr($dec & 0xFF);
462 $str .= chr(($dec >> 8) & 0xFF);
463 $str .= chr(0x00);
464 $str .= chr(0x00);
465 }
466 else
467 {
468 $str .= chr($dec & 0xFF);
469 $str .= chr(0x00);
470 $str .= chr(0x00);
471 $str .= chr(0x00);
472 }
473
474}
475
476#****************************************************************************
477# subroutine: Check GFH Header, (0-2: 4D 4D 4D, 8-16: FILE_INFO)
478# input: File Name
479# output: True/False
480#****************************************************************************
481sub IsGFH
482{
483 my ($strFilePath) = @_;
484 my $bIsGFH = 0;
485
486 if (-e $strFilePath)
487 {
488# Get 17bytes (0-2: 4D 4D 4D, 8-16: FILE_INFO
489 open (FILE_HANDLE, "<$strFilePath") or &error_handler("$strFilePath: open file error!");
490#binmode(FILE_HANDLE);
491 my ($nIndex, $data) = (0, undef);
492 my @Buffer;
493 while (read(FILE_HANDLE, $data, 1))
494 {
495 $Buffer[$nIndex++] = $data;
496 last if ($nIndex > 16);
497 }
498 close FILE_HANDLE;
499 my ($strFILE_INFO, $nMatchMMM) = (undef, 0);
500 for (0..2)
501 {
502 $nMatchMMM++ if (ord($Buffer[$_]) == 0x4D);
503 }
504 for (8..16)
505 {
506 $strFILE_INFO .= $Buffer[$_];
507 }
508 $bIsGFH =1 if($nMatchMMM == 3 and $strFILE_INFO eq "FILE_INFO");
509 }
510
511 return $bIsGFH;
512}
513
514#****************************************************************************
515# subroutine: error_handler
516# input: $error_msg: error message
517# $file: filename
518# $line_no: line number
519#****************************************************************************
520sub error_handler
521{
522 my ($error_msg) = @_;
523 my ($pack_name, $file, $line_no) = caller;
524 my $final_error_msg = "PREPEND_GFH ERROR: $error_msg at $file line $line_no\n";
525 die $final_error_msg;
526}