blob: e68fb159e6dba6a6ea0890889786ba3ec087669e [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) 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#* vivaHelper.pm
41#*
42#* Project:
43#* --------
44#* Maui_Software
45#*
46#* Description:
47#* ------------
48#* This file implemented the VIVA help library.
49#*
50#*
51#* Author:
52#* -------
53#* Ke-Ting Chen (mtk03141)
54#*
55#*****************************************************************************
56package vivaHelper;
57#****************************************************************************
58# Included Modules
59#****************************************************************************
60use strict;
61use warnings;
62BEGIN { push @INC, '.\\pcore\\tools\\' } # add additional library path
63use FileInfoParser;
64use sysGenUtility;
65use LISInfo;
66use objListHelper;
67
68#****************************************************************************
69# History
70#****************************************************************************
71my $VIVA_HELPER_VERNO = " v1.00";
72 # v1.00: Phase in VIVA
73
74#****************************************************************************
75# Constants
76#****************************************************************************
77use constant PROCESS_TYPE => 1;
78use constant CONFIG_TYPE => 2;
79
80my $vivaGFHHeaderSize = 56;
81my $vivaHeaderSize = 20;
82
83#****************************************************************************
84# Variables
85#****************************************************************************
86my $executionType;
87my %makefileOptions;
88my $chip;
89my $lisFilePath;
90
91#****************************************************************************
92# subroutine: Initialize
93# description: Initialize the module for further using.
94# input: Exeuction type, makefile path, LIS file
95# output: None
96# need init: N/A
97#****************************************************************************
98sub Initialize
99{
100 my $executionType = shift;
101 my $makefilePath = shift;
102 $lisFilePath = shift;
103
104 # Parse makefile
105 if (defined $makefilePath)
106 {
107 if (0 == &FileInfo::Parse_MAKEFILE($makefilePath, \%makefileOptions))
108 {
109 &ErrorHandler("Fail to parse makefile $makefilePath $!", __FILE__, __LINE__) ;
110 }
111
112 $chip = &GetMakefileOption("PLATFORM");
113 }
114
115 # Parse LIS file
116 if (defined $lisFilePath)
117 {
118 &LISInfo::ParseLIS($lisFilePath);
119 }
120}
121
122#****************************************************************************
123# subroutine: GetMakefileOption
124# description: Get the makefile feature option value.
125# input: Option name
126# output: Option value
127# need init: Yes
128#****************************************************************************
129sub GetMakefileOption
130{
131 my $option = shift;
132 return $makefileOptions{$option};
133}
134
135#****************************************************************************
136# subroutine: IsSV5
137# description: To see if current processing chip is SV5 support or not
138# input: None
139# output: 1: SV5; 0: otherwise
140# need init: Yes
141#****************************************************************************
142sub IsSV5
143{
144 return &sysUtil::is_sv5($chip);
145}
146
147#****************************************************************************
148# subroutine: GetVIVAHeaderSize
149# description: Get the size of VIVA header
150# input: None
151# output: The VIVA header size with GFH if existed
152# need init: Yes
153#****************************************************************************
154sub GetVIVAHeaderSize
155{
156 my $result = $vivaHeaderSize;
157 $result += $vivaGFHHeaderSize if (&IsSV5());
158 return $result;
159}
160
161#****************************************************************************
162# subroutine: GetVIVAHeaderSize_NI
163# description: Get the size of VIVA header
164# input: isSV5
165# output: The VIVA header size with GFH if existed
166# need init: No
167#****************************************************************************
168sub GetVIVAHeaderSize_NI
169{
170 my $isSV5 = shift;
171
172 my $result = $vivaHeaderSize;
173 $result += $vivaGFHHeaderSize if ($isSV5);
174 return $result;
175}
176
177#****************************************************************************
178# subroutine: IsVIEnabled
179# description: Check if any VI is enabled
180# input: None
181# output: 1: at least one VI is enabled; 0: otherwise
182# need init: Yes
183#****************************************************************************
184sub IsVIEnabled
185{
186 my $zImageOption = &GetMakefileOption("ZIMAGE_SUPPORT");
187 my $dcmcmpOption = &GetMakefileOption("DCM_COMPRESSION_SUPPORT");
188 my $aliceOption = &GetMakefileOption("ALICE_SUPPORT");
189
190 if (defined $zImageOption and $zImageOption eq "TRUE")
191 {
192 return 1;
193 }
194 elsif (defined $dcmcmpOption and $dcmcmpOption eq "TRUE")
195 {
196 return 1;
197 }
198 elsif (defined $aliceOption and $aliceOption eq "TRUE")
199 {
200 return 1;
201 }
202 else
203 {
204 return 0;
205 }
206}
207
208#****************************************************************************
209# subroutine: IsVIEnabled_NI
210# description: Check if any VI is enabled
211# input: Makefile path
212# output: 1: at least one VI is enabled; 0: otherwise
213# need init: No
214#****************************************************************************
215sub IsVIEnabled_NI
216{
217 my $makefilePath = shift;
218 my %options;
219 if (0 == &FileInfo::Parse_MAKEFILE($makefilePath, \%options))
220 {
221 &ErrorHandler("Fail to parse makefile $makefilePath $!", __FILE__, __LINE__) ;
222 }
223
224 my $zImageOption = $options{"ZIMAGE_SUPPORT"};
225 my $dcmcmpOption = $options{"DCM_COMPRESSION_SUPPORT"};
226 my $aliceOption = $options{"ALICE_SUPPORT"};
227
228 if (defined $zImageOption and $zImageOption eq "TRUE")
229 {
230 return 1;
231 }
232 elsif (defined $dcmcmpOption and $dcmcmpOption eq "TRUE")
233 {
234 return 1;
235 }
236 elsif (defined $aliceOption and $aliceOption eq "TRUE")
237 {
238 return 1;
239 }
240 else
241 {
242 return 0;
243 }
244}
245
246#****************************************************************************
247# subroutine: ReadGFHHeader
248# description: Read the GFH header.
249# input: Binary file handle reference, GFH header reference
250# output: GFH header. Note the the magic number is stripped
251# need init: No
252#****************************************************************************
253sub ReadGFHHeader
254{
255 # struct GFH_Header
256 # U32 m_magic_ver: 'M', 'M', 'M', version
257 # U16 m_size
258 # U16 m_type
259
260 my $input = shift;
261 my $headerRef = shift;
262 my $buffer;
263 my @result;
264
265 read $input, $buffer, 8;
266 @result = unpack("C[3]CSS", $buffer);
267
268 &ErrorHandler ("Error GFH header magic number!", __FILE__, __LINE__)
269 if (77 != $result[0] or 77 != $result[1] or 77 != $result[2]);
270
271 $headerRef->{"m_ver"} = $result[3];
272 $headerRef->{"m_size"} = $result[4];
273 $headerRef->{"m_type"} = $result[5];
274}
275
276#****************************************************************************
277# subroutine: ReadGFHFileInfo
278# description: Read the GFH file informatino.
279# input: Binary file handle reference, GFH file info reference
280# output: GFH file information
281# need init: No
282#****************************************************************************
283sub ReadGFHFileInfo
284{
285 # struct GFH_FILE_INFO_v1
286 # GFH_Header m_gfh_hdr;
287 # char m_identifier[12];
288 # U32 m_file_ver;
289 # U16 m_file_type;
290 # U8 m_flash_dev;
291 # U8 m_sig_type;
292 # U32 m_load_addr;
293 # U32 m_file_len;
294 # U32 m_max_size;
295 # U32 m_content_offset;
296 # U32 m_sig_len;
297 # U32 m_jump_offset;
298 # U32 m_attr;
299
300 my $input = shift;
301 my $fileInfoRef = shift;
302 my $buffer;
303 my @result;
304 my %header;
305
306 # Read GFH header
307 &ReadGFHHeader($input, \%header);
308 &ErrorHandler("Invalid GFH file info header!", __FILE__, __LINE__)
309 if (1 != $header{"m_ver"} or 56 != $header{"m_size"} or 0 != $header{"m_type"});
310
311 # Read file info
312 read $input, $buffer, 48; # The first 8 bytes were consumed by ReadGFHHeader
313 @result = unpack("Z[12]LSCCLLLLLLL", $buffer);
314
315 &ErrorHandler ("Error GFH header magic number!", __FILE__, __LINE__)
316 if ("FILE_INFO" ne $result[0]);
317
318 $fileInfoRef->{"m_gfh_hdr"} = \%header;
319 $fileInfoRef->{"m_identifier"} = $result[0];
320 $fileInfoRef->{"m_file_ver"} = $result[1];
321 $fileInfoRef->{"m_file_type"} = $result[2];
322 $fileInfoRef->{"m_flash_dev"} = $result[3];
323 $fileInfoRef->{"m_sig_type"} = $result[4];
324 $fileInfoRef->{"m_load_addr"} = $result[5];
325 $fileInfoRef->{"m_file_len"} = $result[6];
326 $fileInfoRef->{"m_max_size"} = $result[7];
327 $fileInfoRef->{"m_content_offset"} = $result[8];
328 $fileInfoRef->{"m_sig_len"} = $result[9];
329 $fileInfoRef->{"m_jump_offset"} = $result[10];
330 $fileInfoRef->{"m_attr"} = $result[11];
331}
332
333#****************************************************************************
334# subroutine: WriteGFHHeader
335# description: Write the GFH header.
336# input: Binary file handle reference, GFH header reference
337# output: None
338# need init: No
339#****************************************************************************
340sub WriteGFHHeader
341{
342 # struct GFH_Header
343 # U32 m_magic_ver: 'M', 'M', 'M', version
344 # U16 m_size
345 # U16 m_type
346
347 my $output = shift;
348 my $headerRef = shift;
349 my $buffer;
350 my @result;
351
352 $result[0] = 77;
353 $result[1] = 77;
354 $result[2] = 77;
355 $result[3] = $headerRef->{"m_ver"};
356 $result[4] = $headerRef->{"m_size"};
357 $result[5] = $headerRef->{"m_type"};
358
359 $buffer = pack("C[3]CSS", @result);
360
361 print $output $buffer;
362}
363
364#****************************************************************************
365# subroutine: WriteGFHFileInfo
366# description: Write the GFH file informatino.
367# input: Binary file handle reference, GFH file info reference
368# output: None
369# need init: No
370#****************************************************************************
371sub WriteGFHFileInfo
372{
373 # struct GFH_FILE_INFO_v1
374 # GFH_Header m_gfh_hdr;
375 # char m_identifier[12];
376 # U32 m_file_ver;
377 # U16 m_file_type;
378 # U8 m_flash_dev;
379 # U8 m_sig_type;
380 # U32 m_load_addr;
381 # U32 m_file_len;
382 # U32 m_max_size;
383 # U32 m_content_offset;
384 # U32 m_sig_len;
385 # U32 m_jump_offset;
386 # U32 m_attr;
387
388 my $output = shift;
389 my $fileInfoRef = shift;
390 my $buffer;
391 my @result;
392
393 # Write GFH header
394 &WriteGFHHeader($output, $fileInfoRef->{"m_gfh_hdr"});
395
396 # Write file info
397 $result[0] = $fileInfoRef->{"m_identifier"};
398 $result[1] = $fileInfoRef->{"m_file_ver"};
399 $result[2] = $fileInfoRef->{"m_file_type"};
400 $result[3] = $fileInfoRef->{"m_flash_dev"};
401 $result[4] = $fileInfoRef->{"m_sig_type"};
402 $result[5] = $fileInfoRef->{"m_load_addr"};
403 $result[6] = $fileInfoRef->{"m_file_len"};
404 $result[7] = $fileInfoRef->{"m_max_size"};
405 $result[8] = $fileInfoRef->{"m_content_offset"};
406 $result[9] = $fileInfoRef->{"m_sig_len"};
407 $result[10] = $fileInfoRef->{"m_jump_offset"};
408 $result[11] = $fileInfoRef->{"m_attr"};
409 $result[12] = 4095;
410
411 $buffer = pack("Z[12]LSCCLLLLLLL", @result);
412 print $output $buffer;
413}
414
415#****************************************************************************
416# subroutine: UpdateGFHFileInfo
417# description: Update the GFH file info in the binary.
418# input: Binary path, hash ref includes the new values
419# output: None
420# need init: No
421#****************************************************************************
422sub UpdateGFHFileInfo
423{
424 my $binary = shift;
425 my $diffInfoRef = shift;
426 my %fileInfo;
427
428 # Read the original GFH file info
429 open my $inout, "+<$binary" or &ErrorHandler("Cannot open binary $binary: $!", __FILE__, __LINE__);
430 binmode $inout;
431 &ReadGFHFileInfo($inout, \%fileInfo);
432
433 # Update the entry
434 while (my ($key, $value) = each (%$diffInfoRef))
435 {
436 &ErrorHandler("Unrecognizable GFH file info entry $key!", __FILE__, __LINE__)
437 unless exists $fileInfo{$key};
438
439 $fileInfo{$key} = $value;
440 }
441
442 # Write to modified GFH file info
443 seek $inout, 0, 0;
444 &WriteGFHFileInfo($inout, \%fileInfo);
445
446 close $inout;
447}
448
449#****************************************************************************
450# subroutine: ReadVIVAInfo
451# description: Read the VIVA information from the binary.
452# input: Binary name, VIVA info reference
453# output: VIVA info
454# need init: Yes
455#****************************************************************************
456sub ReadVIVAInfo
457{
458 my $input = shift;
459 my $infoRef = shift;
460
461 &ReadVIVAInfo_NI($input, $infoRef, &IsSV5());
462}
463
464#****************************************************************************
465# subroutine: ReadVIVAInfo_NI
466# description: Read the VIVA information from the binary.
467# input: Binary name, VIVA info reference
468# output: VIVA info
469# need init: No
470#****************************************************************************
471sub ReadVIVAInfo_NI
472{
473 # struct VIVA_HEADER
474 # U32 viva_base
475 # U32 zimage_base
476 # U32 boot_zimage_base
477 # U32 dcmcmp_base
478 # U32 alice_base
479
480 my $input = shift;
481 my $infoRef = shift;
482 my $isSV5 = shift;
483
484 my $buffer;
485 my @result;
486
487 if ($isSV5)
488 {
489 # Read and save the GFH for further use
490 my %GFHFileInfo;
491 &ReadGFHFileInfo($input, \%GFHFileInfo);
492 $infoRef->{"GFH_FILE_INFO"} = \%GFHFileInfo;
493 }
494
495 # Read the VIVA info
496 read $input, $buffer, 32;
497 @result = unpack("LLLLL", $buffer);
498
499 $infoRef->{"viva_base"} = $result[0];
500 $infoRef->{"zimage_base"} = $result[1];
501 $infoRef->{"boot_zimage_base"} = $result[2];
502 $infoRef->{"dcmcmp_base"} = $result[3];
503 $infoRef->{"alice_base"} = $result[4];
504}
505
506#****************************************************************************
507# subroutine: ReadVIVAInfoFromBinary_NI
508# description: Read the VIVA information from the binary.
509# input: Binary name, VIVA info reference
510# output: VIVA info
511# need init: No
512#****************************************************************************
513sub ReadVIVAInfoFromBinary_NI
514{
515 my $binary = shift;
516 my $infoRef = shift;
517 my $isSV5 = shift;
518
519 open my $input, "<$binary" or
520 &ErrorHandler("Cannot open binary $binary: $!", __FILE__, __LINE__);
521 binmode $input;
522
523 ReadVIVAInfo_NI($input, $infoRef, $isSV5);
524
525 close $input;
526}
527
528#****************************************************************************
529# subroutine: WriteVIVAInfo
530# description: Write the VIVA information to the binary.
531# input: Binary name, VIVA info reference
532# output: None
533# need init: Yes
534#****************************************************************************
535sub WriteVIVAInfo
536{
537 # struct VIVA_HEADER
538 # U32 viva_base
539 # U32 zimage_base
540 # U32 boot_zimage_base
541 # U32 dcmcmp_base
542 # U32 alice_base
543
544 my $output = shift;
545 my $infoRef = shift;
546
547 my $buffer;
548 my @result;
549
550 if (&IsSV5())
551 {
552 &WriteGFHFileInfo($output, $infoRef->{"GFH_FILE_INFO"});
553 }
554
555 # Write the VIVA info
556 $result[0] = $infoRef->{"viva_base"};
557 $result[1] = $infoRef->{"zimage_base"};
558 $result[2] = $infoRef->{"boot_zimage_base"};
559 $result[3] = $infoRef->{"dcmcmp_base"};
560 $result[4] = $infoRef->{"alice_base"};
561
562 $buffer = pack("LLLLL", @result);
563 print $output $buffer;
564}
565
566#****************************************************************************
567# subroutine: SplitBinaryBySize
568# description: Split the binary to several part by the input size.
569# input: Binary path, size array ref, filename array ref
570# output: The result binary number
571# need init: No
572#****************************************************************************
573sub SplitBinaryBySize
574{
575 my $binary = shift;
576 my $sizeArrayRef = shift;
577 my $filenameArrayRef = shift;
578 my $buffer;
579 my $readCount;
580 my $imageCount = 0;
581
582 #&ErrorHandler("The size number is different to filename number!", __FILE__, __LINE__)
583 # if (scalar(@$sizeArrayRef) != scalar(@$filenameArrayRef));
584
585 open my $input, "<$binary" or &ErrorHandler("Cannot open binary $binary: $!", __FILE__, __LINE__);
586 binmode $input;
587
588 for (my $i = 0; $i < scalar(@$sizeArrayRef); ++$i)
589 {
590 if (not defined $filenameArrayRef->[$i] or $filenameArrayRef->[$i] eq "")
591 {
592 &ErrorHandler("Invalid filename while split file!", __FILE__, __LINE__)
593 }
594
595 open my $output, ">$filenameArrayRef->[$i]"
596 or &ErrorHandler("Cannot open binary $filenameArrayRef->[$i]: $!", __FILE__, __LINE__);
597 binmode $output;
598
599 $readCount = read $input, $buffer, $sizeArrayRef->[$i];
600 print $output $buffer;
601
602 close $output;
603
604 ++$imageCount;
605 last if $readCount < $sizeArrayRef->[$i];
606 }
607
608 close $input;
609
610 return $imageCount;
611}
612
613#****************************************************************************
614# subroutine: SplitBinaryByGFH
615# description: Split the binary to three part: GFH, body, signature according
616# to the information in GFH.
617# input: Binary path, GFH filename, body filename, signature filename
618# output: The result binary number
619# need init: No
620#****************************************************************************
621sub SplitBinaryByGFH
622{
623 my $binary = shift;
624 my @filenameArray = (shift, shift, shift);
625 #my $GFHFilename = shift;
626 #my $bodyFilename = shift;
627 #my $signatureFilename = shift;
628 my @sizeArray;
629 my %fileInfo;
630 my $binarySize = -s $binary;
631
632 open my $input, "<$binary" or &ErrorHandler("Cannot open binary $binary: $!", __FILE__, __LINE__);
633 binmode $input;
634
635 &ReadGFHFileInfo($input, \%fileInfo);
636 close $input;
637
638 @sizeArray = ($fileInfo{"m_content_offset"},
639 $binarySize - $fileInfo{"m_content_offset"} - $fileInfo{"m_sig_len"},
640 $fileInfo{"m_sig_len"});
641
642 return &SplitBinaryBySize($binary, \@sizeArray, \@filenameArray);
643}
644
645#****************************************************************************
646# subroutine: ConcatenateBinary
647# description: Concatenate binaries.
648# input: Destination file handle ref, source filename array ref
649# output: None
650# need init: No
651#****************************************************************************
652sub ConcatenateBinary
653{
654 my $output = shift;
655 my $sourceArrayRef = shift;
656 my $pool;
657 my $readSize;
658
659 foreach my $source (@$sourceArrayRef)
660 {
661 open my $input, "<$source" or &ErrorHandler("Cannot open binary $source: $!", __FILE__, __LINE__);
662 binmode $input;
663
664 do
665 {
666 $readSize = read $input, $pool, 1048576;
667 print $output $pool;
668 } while ($readSize == 1048576);
669
670 close $input;
671 }
672}
673
674#****************************************************************************
675# subroutine: RoundUpToAlignment
676# description: Increase the input number to the required alignment.
677# input: Number, alignment
678# output: Aligned number
679# need init: No
680#****************************************************************************
681sub RoundUpToAlignment
682{
683 my $number = shift;
684 my $alignment = shift;
685
686 my $remainder = $number % $alignment;
687
688 if ($remainder)
689 {
690 return $number + $alignment - $remainder;
691 }
692 else
693 {
694 return $number;
695 }
696}
697
698#****************************************************************************
699# subroutine: RoundDownToAlignment
700# description: Decrease the input number to the required alignment.
701# input: Number, alignment
702# output: Aligned number
703# need init: No
704#****************************************************************************
705sub RoundDownToAlignment
706{
707 my $number = shift;
708 my $alignment = shift;
709
710 my $remainder = $number % $alignment;
711
712 if ($remainder)
713 {
714 return $number - $remainder;
715 }
716 else
717 {
718 return $number;
719 }
720}
721
722#****************************************************************************
723# subroutine: PaddingBinaryToAlignment
724# description: Add padding after a binary to target alignment requirement.
725# input: Binary path, alignment
726# output: Byte added
727# need init: No
728#****************************************************************************
729sub PaddingBinaryToAlignment
730{
731 my $binary = shift;
732 my $alignment = shift;
733 my $binarySize = -s $binary;
734
735 open my $output, ">>$binary" or &ErrorHandler("Cannot open binary $binary: $!", __FILE__, __LINE__);
736 binmode $output;
737
738 my $alignedSize = RoundUpToAlignment($binarySize, $alignment);
739 my $writeCount = $alignedSize - $binarySize;
740
741 my $buffer = pack("C[$writeCount]", 0);
742 print $output $buffer;
743
744 close $output;
745
746 return $writeCount;
747}
748
749#****************************************************************************
750# subroutine: GetLISLoadRegionInfo
751# description: Get the LIS load region information
752# input: Load region name, info hash ref
753# output: Info hash
754# need init: Yes
755#****************************************************************************
756sub GetLISLoadRegionInfo
757{
758 my $regionName = shift;
759 my $infoRef = shift;
760 my @result = &LISInfo::GetLoadRegionInfo($regionName, 0);
761
762 $infoRef->{"base_address"} = $result[0];
763 $infoRef->{"actual_size"} = $result[1];
764 $infoRef->{"max_size"} = $result[2];
765 $infoRef->{"attribute"} = $result[3];
766}
767
768#****************************************************************************
769# subroutine: GetLISExecutionRegionInfo
770# description: Get the LIS execution region information
771# input: Execution region name, info hash ref
772# output: Info hash
773# need init: Yes
774#****************************************************************************
775sub GetLISExecutionRegionInfo
776{
777 my $regionName = shift;
778 my $infoRef = shift;
779 my @result = &LISInfo::GetExeRegionInfo($regionName, 0);
780
781 $infoRef->{"base_address"} = $result[0];
782 $infoRef->{"actual_size"} = $result[1];
783 $infoRef->{"max_size"} = $result[2];
784 $infoRef->{"attribute"} = $result[3];
785}
786
787#****************************************************************************
788# subroutine: GetLISExecutionRegionObjectInfo
789# description: Get the LIS execution region object list with size
790# input: Execution region name, list array ref
791# output: Padding size in the region, list array
792# need init: Yes
793#****************************************************************************
794sub GetLISExecutionRegionObjectList
795{
796 my $regionName = shift;
797 my $listRef = shift;
798 my $attribute = shift;
799 my $category = shift;
800 my $result = &LISInfo::GetObjTotalSizesByExeRegion($regionName);
801 my %resultHash;
802
803 my @infoList;
804
805 my $totalSize = 0;
806
807 #foreach my $key (keys %$result)
808 #{
809 # if ($key =~ /(.+)::(.*)/)
810 # {
811 # if (exists $resultHash{$1})
812 # {
813 # $resultHash{$1} += $result->{$key};
814 # }
815 # else
816 # {
817 # $resultHash{$1} = $result->{$key};
818 # }
819 # $totalSize += $result->{$key};
820 # }
821 #}
822
823 foreach my $key (keys %$result)
824 {
825 if ($key =~ /(.+)::(.*)/)
826 {
827 push @infoList, {"name" => $1, "library" => $2, "size" => $result->{$key}};
828 }
829 }
830
831 &objListHelper::InputObjectListFromLISInfo(\@infoList, $listRef, $attribute, $category);
832
833 if (exists $result->{"PAD"})
834 {
835 return $result->{"PAD"};
836 }
837 else
838 {
839 return 0;
840 }
841}
842
843#****************************************************************************
844# subroutine: GetLISTotalSize
845# description: Get the total size information in LIS
846# input: Info hash ref
847# output: Info hash
848# need init: Yes
849#****************************************************************************
850sub GetLISTotalSize
851{
852 my $infoRef = shift;
853
854 $infoRef->{"RO"} = &LISInfo::GetTotalROSize(0);
855 $infoRef->{"RW"} = &LISInfo::GetTotalRWZISize(0);
856 $infoRef->{"ROM"} = &LISInfo::GetTotalROMSize(0);
857}
858
859#****************************************************************************
860# subroutine: GetScatterReservedSize
861# description: Get the estimated total ROM size with provided VIVA size
862# input: VIVA size
863# output: Estimated total size
864# need init: Yes
865#****************************************************************************
866sub GetScatterReservedSize
867{
868 my $fsBase = shift;
869 return &LISInfo::GetScatterReservedSize(\%makefileOptions, $fsBase);
870}
871
872#****************************************************************************
873# subroutine: InputObjectListFromFile
874# description: Get a new object list from the specified file.
875# input: Input filename, object list ref
876# output: Object list
877# need init: No
878#****************************************************************************
879sub InputObjectListFromFile
880{
881 my $filename = shift;
882 my $objectListRef = shift;
883
884 &objListHelper::InputObjectListFromObjListFile($filename, $objectListRef);
885}
886
887#****************************************************************************
888# subroutine: OutputObjectListToFile
889# description: Put the object list to the specified file.
890# input: Output filename, object list ref
891# output: Output to file
892# need init: No
893#****************************************************************************
894sub OutputObjectListToFile
895{
896 my $filename = shift;
897 my $objectListRef = shift;
898
899 &objListHelper::OutputObjectListToObjListFile($filename, $objectListRef, " ");
900}
901
902#****************************************************************************
903# subroutine: CompareObjectList
904# description: Compare two object list.
905# input: First object list, second object list
906# output: 0 for equal; 1 for larger; -1 for smaller
907# need init: No
908#****************************************************************************
909sub CompareObjectList
910{
911 my $firstList = shift;
912 my $secondList = shift;
913
914 return &objListHelper::CompareObjectList($firstList, $secondList);
915}
916
917#****************************************************************************
918# subroutine: SortObjectListByCategory
919# description: Sort the object list by the category.
920# input: Object list ref.
921# output: Sorted object list
922# need init: No
923#****************************************************************************
924sub SortObjectList
925{
926 my $listRef = shift;
927 &objListHelper::SortObjectListByCategory($listRef);
928}
929
930#****************************************************************************
931# subroutine: SplitObjectListBySize
932# description: Split the object list into two part with specified size.
933# input: Source list ref, target size,
934# split list ref with target size, another split list ref
935# output: The split lists
936# need init: No
937#****************************************************************************
938sub SplitObjectListBySize
939{
940 my $sourceListRef = shift;
941 my $targetSize = shift;
942 my $firstListRef = shift;
943 my $secondListRef = shift;
944
945 my @sortedSourceList = sort {$b->{"size"} <=> $a->{"size"}} @$sourceListRef;
946 my $remainingSize = $targetSize;
947
948 foreach my $object (@sortedSourceList)
949 {
950 if ($remainingSize >= $object->{"size"})
951 {
952 $remainingSize -= $object->{"size"};
953 push @$firstListRef, $object;
954 }
955 else
956 {
957 push @$secondListRef, $object;
958 }
959 }
960
961 return ($targetSize - $remainingSize);
962}
963
964#****************************************************************************
965# subroutine: SplitObjectListByName
966# description: Split the object list by a name list
967# input: Source list ref, name list,
968# split list ref with target names, another split list ref
969# output: The list with size
970# need init: No
971#****************************************************************************
972sub SplitObjectListByName
973{
974 my $sourceListRef = shift;
975 my $targetNameList = shift;
976 my $firstListRef = shift;
977 my $secondListRef = shift;
978
979 my %nameHash = map { $_ => 1 } @$targetNameList;
980
981 foreach my $object (@$sourceListRef)
982 {
983 if (exists $nameHash{$object->{"name"}})
984 {
985 push @$firstListRef, $object;
986 }
987 else
988 {
989 push @$secondListRef, $object;
990 }
991 }
992}
993
994#****************************************************************************
995# subroutine: ChangeObjectListAttributeListByObjectList
996# description: Chagne the attribute list of each object in the list by
997# the specified object list.
998# input: Target object ref, source object ref
999# output: Target object ref
1000# need init: No
1001#****************************************************************************
1002sub ChangeObjectListAttributeListByObjectList
1003{
1004 my $targetObjectListRef = shift;
1005 my $sourceObjectListRef = shift;
1006
1007 &objListHelper::ChangeObjectListAttributeListByObjectList($targetObjectListRef, $sourceObjectListRef);
1008}
1009
1010#****************************************************************************
1011# subroutine: DecToHex
1012# description: Transform decimal number to hex.
1013# input: Decimal number
1014# output: Hex number in 0xXXXXXXXX format
1015# need init: No
1016#****************************************************************************
1017sub DecToHex
1018{
1019 return sprintf("0x%08X", $_[0]);
1020}
1021
1022#****************************************************************************
1023# subroutine: ErrorHandler
1024# description: Handle the post process error and output the error message.
1025# Note calling this function will lead program terminated.
1026# input: Message, source filename, line number
1027# output: None
1028# need init: Yes/No
1029#****************************************************************************
1030sub ErrorHandler
1031{
1032 my ($message, $file, $line) = @_;
1033
1034 my $errorMessage = "VIVA ERROR: $message at $file line $line\n";
1035 print $errorMessage;
1036
1037 if (defined $executionType and $executionType eq CONFIG_TYPE)
1038 {
1039 die $errorMessage;
1040 }
1041 else
1042 {
1043 exit 1;
1044 }
1045}
1046
10471;