| #!/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) 2005 | |
| # | |
| # 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: | |
| #* --------- | |
| #* vivaHelper.pm | |
| #* | |
| #* Project: | |
| #* -------- | |
| #* Maui_Software | |
| #* | |
| #* Description: | |
| #* ------------ | |
| #* This file implemented the VIVA help library. | |
| #* | |
| #* | |
| #* Author: | |
| #* ------- | |
| #* Ke-Ting Chen (mtk03141) | |
| #* | |
| #***************************************************************************** | |
| package vivaHelper; | |
| #**************************************************************************** | |
| # Included Modules | |
| #**************************************************************************** | |
| use strict; | |
| use warnings; | |
| BEGIN { push @INC, '.\\pcore\\tools\\' } # add additional library path | |
| use FileInfoParser; | |
| use sysGenUtility; | |
| use LISInfo; | |
| use objListHelper; | |
| #**************************************************************************** | |
| # History | |
| #**************************************************************************** | |
| my $VIVA_HELPER_VERNO = " v1.00"; | |
| # v1.00: Phase in VIVA | |
| #**************************************************************************** | |
| # Constants | |
| #**************************************************************************** | |
| use constant PROCESS_TYPE => 1; | |
| use constant CONFIG_TYPE => 2; | |
| my $vivaGFHHeaderSize = 56; | |
| my $vivaHeaderSize = 20; | |
| #**************************************************************************** | |
| # Variables | |
| #**************************************************************************** | |
| my $executionType; | |
| my %makefileOptions; | |
| my $chip; | |
| my $lisFilePath; | |
| #**************************************************************************** | |
| # subroutine: Initialize | |
| # description: Initialize the module for further using. | |
| # input: Exeuction type, makefile path, LIS file | |
| # output: None | |
| # need init: N/A | |
| #**************************************************************************** | |
| sub Initialize | |
| { | |
| my $executionType = shift; | |
| my $makefilePath = shift; | |
| $lisFilePath = shift; | |
| # Parse makefile | |
| if (defined $makefilePath) | |
| { | |
| if (0 == &FileInfo::Parse_MAKEFILE($makefilePath, \%makefileOptions)) | |
| { | |
| &ErrorHandler("Fail to parse makefile $makefilePath $!", __FILE__, __LINE__) ; | |
| } | |
| $chip = &GetMakefileOption("PLATFORM"); | |
| } | |
| # Parse LIS file | |
| if (defined $lisFilePath) | |
| { | |
| &LISInfo::ParseLIS($lisFilePath); | |
| } | |
| } | |
| #**************************************************************************** | |
| # subroutine: GetMakefileOption | |
| # description: Get the makefile feature option value. | |
| # input: Option name | |
| # output: Option value | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub GetMakefileOption | |
| { | |
| my $option = shift; | |
| return $makefileOptions{$option}; | |
| } | |
| #**************************************************************************** | |
| # subroutine: IsSV5 | |
| # description: To see if current processing chip is SV5 support or not | |
| # input: None | |
| # output: 1: SV5; 0: otherwise | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub IsSV5 | |
| { | |
| return &sysUtil::is_sv5($chip); | |
| } | |
| #**************************************************************************** | |
| # subroutine: GetVIVAHeaderSize | |
| # description: Get the size of VIVA header | |
| # input: None | |
| # output: The VIVA header size with GFH if existed | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub GetVIVAHeaderSize | |
| { | |
| my $result = $vivaHeaderSize; | |
| $result += $vivaGFHHeaderSize if (&IsSV5()); | |
| return $result; | |
| } | |
| #**************************************************************************** | |
| # subroutine: GetVIVAHeaderSize_NI | |
| # description: Get the size of VIVA header | |
| # input: isSV5 | |
| # output: The VIVA header size with GFH if existed | |
| # need init: No | |
| #**************************************************************************** | |
| sub GetVIVAHeaderSize_NI | |
| { | |
| my $isSV5 = shift; | |
| my $result = $vivaHeaderSize; | |
| $result += $vivaGFHHeaderSize if ($isSV5); | |
| return $result; | |
| } | |
| #**************************************************************************** | |
| # subroutine: IsVIEnabled | |
| # description: Check if any VI is enabled | |
| # input: None | |
| # output: 1: at least one VI is enabled; 0: otherwise | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub IsVIEnabled | |
| { | |
| my $zImageOption = &GetMakefileOption("ZIMAGE_SUPPORT"); | |
| my $dcmcmpOption = &GetMakefileOption("DCM_COMPRESSION_SUPPORT"); | |
| my $aliceOption = &GetMakefileOption("ALICE_SUPPORT"); | |
| if (defined $zImageOption and $zImageOption eq "TRUE") | |
| { | |
| return 1; | |
| } | |
| elsif (defined $dcmcmpOption and $dcmcmpOption eq "TRUE") | |
| { | |
| return 1; | |
| } | |
| elsif (defined $aliceOption and $aliceOption eq "TRUE") | |
| { | |
| return 1; | |
| } | |
| else | |
| { | |
| return 0; | |
| } | |
| } | |
| #**************************************************************************** | |
| # subroutine: IsVIEnabled_NI | |
| # description: Check if any VI is enabled | |
| # input: Makefile path | |
| # output: 1: at least one VI is enabled; 0: otherwise | |
| # need init: No | |
| #**************************************************************************** | |
| sub IsVIEnabled_NI | |
| { | |
| my $makefilePath = shift; | |
| my %options; | |
| if (0 == &FileInfo::Parse_MAKEFILE($makefilePath, \%options)) | |
| { | |
| &ErrorHandler("Fail to parse makefile $makefilePath $!", __FILE__, __LINE__) ; | |
| } | |
| my $zImageOption = $options{"ZIMAGE_SUPPORT"}; | |
| my $dcmcmpOption = $options{"DCM_COMPRESSION_SUPPORT"}; | |
| my $aliceOption = $options{"ALICE_SUPPORT"}; | |
| if (defined $zImageOption and $zImageOption eq "TRUE") | |
| { | |
| return 1; | |
| } | |
| elsif (defined $dcmcmpOption and $dcmcmpOption eq "TRUE") | |
| { | |
| return 1; | |
| } | |
| elsif (defined $aliceOption and $aliceOption eq "TRUE") | |
| { | |
| return 1; | |
| } | |
| else | |
| { | |
| return 0; | |
| } | |
| } | |
| #**************************************************************************** | |
| # subroutine: ReadGFHHeader | |
| # description: Read the GFH header. | |
| # input: Binary file handle reference, GFH header reference | |
| # output: GFH header. Note the the magic number is stripped | |
| # need init: No | |
| #**************************************************************************** | |
| sub ReadGFHHeader | |
| { | |
| # struct GFH_Header | |
| # U32 m_magic_ver: 'M', 'M', 'M', version | |
| # U16 m_size | |
| # U16 m_type | |
| my $input = shift; | |
| my $headerRef = shift; | |
| my $buffer; | |
| my @result; | |
| read $input, $buffer, 8; | |
| @result = unpack("C[3]CSS", $buffer); | |
| &ErrorHandler ("Error GFH header magic number!", __FILE__, __LINE__) | |
| if (77 != $result[0] or 77 != $result[1] or 77 != $result[2]); | |
| $headerRef->{"m_ver"} = $result[3]; | |
| $headerRef->{"m_size"} = $result[4]; | |
| $headerRef->{"m_type"} = $result[5]; | |
| } | |
| #**************************************************************************** | |
| # subroutine: ReadGFHFileInfo | |
| # description: Read the GFH file informatino. | |
| # input: Binary file handle reference, GFH file info reference | |
| # output: GFH file information | |
| # need init: No | |
| #**************************************************************************** | |
| sub ReadGFHFileInfo | |
| { | |
| # struct GFH_FILE_INFO_v1 | |
| # GFH_Header m_gfh_hdr; | |
| # char m_identifier[12]; | |
| # U32 m_file_ver; | |
| # U16 m_file_type; | |
| # U8 m_flash_dev; | |
| # U8 m_sig_type; | |
| # U32 m_load_addr; | |
| # U32 m_file_len; | |
| # U32 m_max_size; | |
| # U32 m_content_offset; | |
| # U32 m_sig_len; | |
| # U32 m_jump_offset; | |
| # U32 m_attr; | |
| my $input = shift; | |
| my $fileInfoRef = shift; | |
| my $buffer; | |
| my @result; | |
| my %header; | |
| # Read GFH header | |
| &ReadGFHHeader($input, \%header); | |
| &ErrorHandler("Invalid GFH file info header!", __FILE__, __LINE__) | |
| if (1 != $header{"m_ver"} or 56 != $header{"m_size"} or 0 != $header{"m_type"}); | |
| # Read file info | |
| read $input, $buffer, 48; # The first 8 bytes were consumed by ReadGFHHeader | |
| @result = unpack("Z[12]LSCCLLLLLLL", $buffer); | |
| &ErrorHandler ("Error GFH header magic number!", __FILE__, __LINE__) | |
| if ("FILE_INFO" ne $result[0]); | |
| $fileInfoRef->{"m_gfh_hdr"} = \%header; | |
| $fileInfoRef->{"m_identifier"} = $result[0]; | |
| $fileInfoRef->{"m_file_ver"} = $result[1]; | |
| $fileInfoRef->{"m_file_type"} = $result[2]; | |
| $fileInfoRef->{"m_flash_dev"} = $result[3]; | |
| $fileInfoRef->{"m_sig_type"} = $result[4]; | |
| $fileInfoRef->{"m_load_addr"} = $result[5]; | |
| $fileInfoRef->{"m_file_len"} = $result[6]; | |
| $fileInfoRef->{"m_max_size"} = $result[7]; | |
| $fileInfoRef->{"m_content_offset"} = $result[8]; | |
| $fileInfoRef->{"m_sig_len"} = $result[9]; | |
| $fileInfoRef->{"m_jump_offset"} = $result[10]; | |
| $fileInfoRef->{"m_attr"} = $result[11]; | |
| } | |
| #**************************************************************************** | |
| # subroutine: WriteGFHHeader | |
| # description: Write the GFH header. | |
| # input: Binary file handle reference, GFH header reference | |
| # output: None | |
| # need init: No | |
| #**************************************************************************** | |
| sub WriteGFHHeader | |
| { | |
| # struct GFH_Header | |
| # U32 m_magic_ver: 'M', 'M', 'M', version | |
| # U16 m_size | |
| # U16 m_type | |
| my $output = shift; | |
| my $headerRef = shift; | |
| my $buffer; | |
| my @result; | |
| $result[0] = 77; | |
| $result[1] = 77; | |
| $result[2] = 77; | |
| $result[3] = $headerRef->{"m_ver"}; | |
| $result[4] = $headerRef->{"m_size"}; | |
| $result[5] = $headerRef->{"m_type"}; | |
| $buffer = pack("C[3]CSS", @result); | |
| print $output $buffer; | |
| } | |
| #**************************************************************************** | |
| # subroutine: WriteGFHFileInfo | |
| # description: Write the GFH file informatino. | |
| # input: Binary file handle reference, GFH file info reference | |
| # output: None | |
| # need init: No | |
| #**************************************************************************** | |
| sub WriteGFHFileInfo | |
| { | |
| # struct GFH_FILE_INFO_v1 | |
| # GFH_Header m_gfh_hdr; | |
| # char m_identifier[12]; | |
| # U32 m_file_ver; | |
| # U16 m_file_type; | |
| # U8 m_flash_dev; | |
| # U8 m_sig_type; | |
| # U32 m_load_addr; | |
| # U32 m_file_len; | |
| # U32 m_max_size; | |
| # U32 m_content_offset; | |
| # U32 m_sig_len; | |
| # U32 m_jump_offset; | |
| # U32 m_attr; | |
| my $output = shift; | |
| my $fileInfoRef = shift; | |
| my $buffer; | |
| my @result; | |
| # Write GFH header | |
| &WriteGFHHeader($output, $fileInfoRef->{"m_gfh_hdr"}); | |
| # Write file info | |
| $result[0] = $fileInfoRef->{"m_identifier"}; | |
| $result[1] = $fileInfoRef->{"m_file_ver"}; | |
| $result[2] = $fileInfoRef->{"m_file_type"}; | |
| $result[3] = $fileInfoRef->{"m_flash_dev"}; | |
| $result[4] = $fileInfoRef->{"m_sig_type"}; | |
| $result[5] = $fileInfoRef->{"m_load_addr"}; | |
| $result[6] = $fileInfoRef->{"m_file_len"}; | |
| $result[7] = $fileInfoRef->{"m_max_size"}; | |
| $result[8] = $fileInfoRef->{"m_content_offset"}; | |
| $result[9] = $fileInfoRef->{"m_sig_len"}; | |
| $result[10] = $fileInfoRef->{"m_jump_offset"}; | |
| $result[11] = $fileInfoRef->{"m_attr"}; | |
| $result[12] = 4095; | |
| $buffer = pack("Z[12]LSCCLLLLLLL", @result); | |
| print $output $buffer; | |
| } | |
| #**************************************************************************** | |
| # subroutine: UpdateGFHFileInfo | |
| # description: Update the GFH file info in the binary. | |
| # input: Binary path, hash ref includes the new values | |
| # output: None | |
| # need init: No | |
| #**************************************************************************** | |
| sub UpdateGFHFileInfo | |
| { | |
| my $binary = shift; | |
| my $diffInfoRef = shift; | |
| my %fileInfo; | |
| # Read the original GFH file info | |
| open my $inout, "+<$binary" or &ErrorHandler("Cannot open binary $binary: $!", __FILE__, __LINE__); | |
| binmode $inout; | |
| &ReadGFHFileInfo($inout, \%fileInfo); | |
| # Update the entry | |
| while (my ($key, $value) = each (%$diffInfoRef)) | |
| { | |
| &ErrorHandler("Unrecognizable GFH file info entry $key!", __FILE__, __LINE__) | |
| unless exists $fileInfo{$key}; | |
| $fileInfo{$key} = $value; | |
| } | |
| # Write to modified GFH file info | |
| seek $inout, 0, 0; | |
| &WriteGFHFileInfo($inout, \%fileInfo); | |
| close $inout; | |
| } | |
| #**************************************************************************** | |
| # subroutine: ReadVIVAInfo | |
| # description: Read the VIVA information from the binary. | |
| # input: Binary name, VIVA info reference | |
| # output: VIVA info | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub ReadVIVAInfo | |
| { | |
| my $input = shift; | |
| my $infoRef = shift; | |
| &ReadVIVAInfo_NI($input, $infoRef, &IsSV5()); | |
| } | |
| #**************************************************************************** | |
| # subroutine: ReadVIVAInfo_NI | |
| # description: Read the VIVA information from the binary. | |
| # input: Binary name, VIVA info reference | |
| # output: VIVA info | |
| # need init: No | |
| #**************************************************************************** | |
| sub ReadVIVAInfo_NI | |
| { | |
| # struct VIVA_HEADER | |
| # U32 viva_base | |
| # U32 zimage_base | |
| # U32 boot_zimage_base | |
| # U32 dcmcmp_base | |
| # U32 alice_base | |
| my $input = shift; | |
| my $infoRef = shift; | |
| my $isSV5 = shift; | |
| my $buffer; | |
| my @result; | |
| if ($isSV5) | |
| { | |
| # Read and save the GFH for further use | |
| my %GFHFileInfo; | |
| &ReadGFHFileInfo($input, \%GFHFileInfo); | |
| $infoRef->{"GFH_FILE_INFO"} = \%GFHFileInfo; | |
| } | |
| # Read the VIVA info | |
| read $input, $buffer, 32; | |
| @result = unpack("LLLLL", $buffer); | |
| $infoRef->{"viva_base"} = $result[0]; | |
| $infoRef->{"zimage_base"} = $result[1]; | |
| $infoRef->{"boot_zimage_base"} = $result[2]; | |
| $infoRef->{"dcmcmp_base"} = $result[3]; | |
| $infoRef->{"alice_base"} = $result[4]; | |
| } | |
| #**************************************************************************** | |
| # subroutine: ReadVIVAInfoFromBinary_NI | |
| # description: Read the VIVA information from the binary. | |
| # input: Binary name, VIVA info reference | |
| # output: VIVA info | |
| # need init: No | |
| #**************************************************************************** | |
| sub ReadVIVAInfoFromBinary_NI | |
| { | |
| my $binary = shift; | |
| my $infoRef = shift; | |
| my $isSV5 = shift; | |
| open my $input, "<$binary" or | |
| &ErrorHandler("Cannot open binary $binary: $!", __FILE__, __LINE__); | |
| binmode $input; | |
| ReadVIVAInfo_NI($input, $infoRef, $isSV5); | |
| close $input; | |
| } | |
| #**************************************************************************** | |
| # subroutine: WriteVIVAInfo | |
| # description: Write the VIVA information to the binary. | |
| # input: Binary name, VIVA info reference | |
| # output: None | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub WriteVIVAInfo | |
| { | |
| # struct VIVA_HEADER | |
| # U32 viva_base | |
| # U32 zimage_base | |
| # U32 boot_zimage_base | |
| # U32 dcmcmp_base | |
| # U32 alice_base | |
| my $output = shift; | |
| my $infoRef = shift; | |
| my $buffer; | |
| my @result; | |
| if (&IsSV5()) | |
| { | |
| &WriteGFHFileInfo($output, $infoRef->{"GFH_FILE_INFO"}); | |
| } | |
| # Write the VIVA info | |
| $result[0] = $infoRef->{"viva_base"}; | |
| $result[1] = $infoRef->{"zimage_base"}; | |
| $result[2] = $infoRef->{"boot_zimage_base"}; | |
| $result[3] = $infoRef->{"dcmcmp_base"}; | |
| $result[4] = $infoRef->{"alice_base"}; | |
| $buffer = pack("LLLLL", @result); | |
| print $output $buffer; | |
| } | |
| #**************************************************************************** | |
| # subroutine: SplitBinaryBySize | |
| # description: Split the binary to several part by the input size. | |
| # input: Binary path, size array ref, filename array ref | |
| # output: The result binary number | |
| # need init: No | |
| #**************************************************************************** | |
| sub SplitBinaryBySize | |
| { | |
| my $binary = shift; | |
| my $sizeArrayRef = shift; | |
| my $filenameArrayRef = shift; | |
| my $buffer; | |
| my $readCount; | |
| my $imageCount = 0; | |
| #&ErrorHandler("The size number is different to filename number!", __FILE__, __LINE__) | |
| # if (scalar(@$sizeArrayRef) != scalar(@$filenameArrayRef)); | |
| open my $input, "<$binary" or &ErrorHandler("Cannot open binary $binary: $!", __FILE__, __LINE__); | |
| binmode $input; | |
| for (my $i = 0; $i < scalar(@$sizeArrayRef); ++$i) | |
| { | |
| if (not defined $filenameArrayRef->[$i] or $filenameArrayRef->[$i] eq "") | |
| { | |
| &ErrorHandler("Invalid filename while split file!", __FILE__, __LINE__) | |
| } | |
| open my $output, ">$filenameArrayRef->[$i]" | |
| or &ErrorHandler("Cannot open binary $filenameArrayRef->[$i]: $!", __FILE__, __LINE__); | |
| binmode $output; | |
| $readCount = read $input, $buffer, $sizeArrayRef->[$i]; | |
| print $output $buffer; | |
| close $output; | |
| ++$imageCount; | |
| last if $readCount < $sizeArrayRef->[$i]; | |
| } | |
| close $input; | |
| return $imageCount; | |
| } | |
| #**************************************************************************** | |
| # subroutine: SplitBinaryByGFH | |
| # description: Split the binary to three part: GFH, body, signature according | |
| # to the information in GFH. | |
| # input: Binary path, GFH filename, body filename, signature filename | |
| # output: The result binary number | |
| # need init: No | |
| #**************************************************************************** | |
| sub SplitBinaryByGFH | |
| { | |
| my $binary = shift; | |
| my @filenameArray = (shift, shift, shift); | |
| #my $GFHFilename = shift; | |
| #my $bodyFilename = shift; | |
| #my $signatureFilename = shift; | |
| my @sizeArray; | |
| my %fileInfo; | |
| my $binarySize = -s $binary; | |
| open my $input, "<$binary" or &ErrorHandler("Cannot open binary $binary: $!", __FILE__, __LINE__); | |
| binmode $input; | |
| &ReadGFHFileInfo($input, \%fileInfo); | |
| close $input; | |
| @sizeArray = ($fileInfo{"m_content_offset"}, | |
| $binarySize - $fileInfo{"m_content_offset"} - $fileInfo{"m_sig_len"}, | |
| $fileInfo{"m_sig_len"}); | |
| return &SplitBinaryBySize($binary, \@sizeArray, \@filenameArray); | |
| } | |
| #**************************************************************************** | |
| # subroutine: ConcatenateBinary | |
| # description: Concatenate binaries. | |
| # input: Destination file handle ref, source filename array ref | |
| # output: None | |
| # need init: No | |
| #**************************************************************************** | |
| sub ConcatenateBinary | |
| { | |
| my $output = shift; | |
| my $sourceArrayRef = shift; | |
| my $pool; | |
| my $readSize; | |
| foreach my $source (@$sourceArrayRef) | |
| { | |
| open my $input, "<$source" or &ErrorHandler("Cannot open binary $source: $!", __FILE__, __LINE__); | |
| binmode $input; | |
| do | |
| { | |
| $readSize = read $input, $pool, 1048576; | |
| print $output $pool; | |
| } while ($readSize == 1048576); | |
| close $input; | |
| } | |
| } | |
| #**************************************************************************** | |
| # subroutine: RoundUpToAlignment | |
| # description: Increase the input number to the required alignment. | |
| # input: Number, alignment | |
| # output: Aligned number | |
| # need init: No | |
| #**************************************************************************** | |
| sub RoundUpToAlignment | |
| { | |
| my $number = shift; | |
| my $alignment = shift; | |
| my $remainder = $number % $alignment; | |
| if ($remainder) | |
| { | |
| return $number + $alignment - $remainder; | |
| } | |
| else | |
| { | |
| return $number; | |
| } | |
| } | |
| #**************************************************************************** | |
| # subroutine: RoundDownToAlignment | |
| # description: Decrease the input number to the required alignment. | |
| # input: Number, alignment | |
| # output: Aligned number | |
| # need init: No | |
| #**************************************************************************** | |
| sub RoundDownToAlignment | |
| { | |
| my $number = shift; | |
| my $alignment = shift; | |
| my $remainder = $number % $alignment; | |
| if ($remainder) | |
| { | |
| return $number - $remainder; | |
| } | |
| else | |
| { | |
| return $number; | |
| } | |
| } | |
| #**************************************************************************** | |
| # subroutine: PaddingBinaryToAlignment | |
| # description: Add padding after a binary to target alignment requirement. | |
| # input: Binary path, alignment | |
| # output: Byte added | |
| # need init: No | |
| #**************************************************************************** | |
| sub PaddingBinaryToAlignment | |
| { | |
| my $binary = shift; | |
| my $alignment = shift; | |
| my $binarySize = -s $binary; | |
| open my $output, ">>$binary" or &ErrorHandler("Cannot open binary $binary: $!", __FILE__, __LINE__); | |
| binmode $output; | |
| my $alignedSize = RoundUpToAlignment($binarySize, $alignment); | |
| my $writeCount = $alignedSize - $binarySize; | |
| my $buffer = pack("C[$writeCount]", 0); | |
| print $output $buffer; | |
| close $output; | |
| return $writeCount; | |
| } | |
| #**************************************************************************** | |
| # subroutine: GetLISLoadRegionInfo | |
| # description: Get the LIS load region information | |
| # input: Load region name, info hash ref | |
| # output: Info hash | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub GetLISLoadRegionInfo | |
| { | |
| my $regionName = shift; | |
| my $infoRef = shift; | |
| my @result = &LISInfo::GetLoadRegionInfo($regionName, 0); | |
| $infoRef->{"base_address"} = $result[0]; | |
| $infoRef->{"actual_size"} = $result[1]; | |
| $infoRef->{"max_size"} = $result[2]; | |
| $infoRef->{"attribute"} = $result[3]; | |
| } | |
| #**************************************************************************** | |
| # subroutine: GetLISExecutionRegionInfo | |
| # description: Get the LIS execution region information | |
| # input: Execution region name, info hash ref | |
| # output: Info hash | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub GetLISExecutionRegionInfo | |
| { | |
| my $regionName = shift; | |
| my $infoRef = shift; | |
| my @result = &LISInfo::GetExeRegionInfo($regionName, 0); | |
| $infoRef->{"base_address"} = $result[0]; | |
| $infoRef->{"actual_size"} = $result[1]; | |
| $infoRef->{"max_size"} = $result[2]; | |
| $infoRef->{"attribute"} = $result[3]; | |
| } | |
| #**************************************************************************** | |
| # subroutine: GetLISExecutionRegionObjectInfo | |
| # description: Get the LIS execution region object list with size | |
| # input: Execution region name, list array ref | |
| # output: Padding size in the region, list array | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub GetLISExecutionRegionObjectList | |
| { | |
| my $regionName = shift; | |
| my $listRef = shift; | |
| my $attribute = shift; | |
| my $category = shift; | |
| my $result = &LISInfo::GetObjTotalSizesByExeRegion($regionName); | |
| my %resultHash; | |
| my @infoList; | |
| my $totalSize = 0; | |
| #foreach my $key (keys %$result) | |
| #{ | |
| # if ($key =~ /(.+)::(.*)/) | |
| # { | |
| # if (exists $resultHash{$1}) | |
| # { | |
| # $resultHash{$1} += $result->{$key}; | |
| # } | |
| # else | |
| # { | |
| # $resultHash{$1} = $result->{$key}; | |
| # } | |
| # $totalSize += $result->{$key}; | |
| # } | |
| #} | |
| foreach my $key (keys %$result) | |
| { | |
| if ($key =~ /(.+)::(.*)/) | |
| { | |
| push @infoList, {"name" => $1, "library" => $2, "size" => $result->{$key}}; | |
| } | |
| } | |
| &objListHelper::InputObjectListFromLISInfo(\@infoList, $listRef, $attribute, $category); | |
| if (exists $result->{"PAD"}) | |
| { | |
| return $result->{"PAD"}; | |
| } | |
| else | |
| { | |
| return 0; | |
| } | |
| } | |
| #**************************************************************************** | |
| # subroutine: GetLISTotalSize | |
| # description: Get the total size information in LIS | |
| # input: Info hash ref | |
| # output: Info hash | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub GetLISTotalSize | |
| { | |
| my $infoRef = shift; | |
| $infoRef->{"RO"} = &LISInfo::GetTotalROSize(0); | |
| $infoRef->{"RW"} = &LISInfo::GetTotalRWZISize(0); | |
| $infoRef->{"ROM"} = &LISInfo::GetTotalROMSize(0); | |
| } | |
| #**************************************************************************** | |
| # subroutine: GetScatterReservedSize | |
| # description: Get the estimated total ROM size with provided VIVA size | |
| # input: VIVA size | |
| # output: Estimated total size | |
| # need init: Yes | |
| #**************************************************************************** | |
| sub GetScatterReservedSize | |
| { | |
| my $fsBase = shift; | |
| return &LISInfo::GetScatterReservedSize(\%makefileOptions, $fsBase); | |
| } | |
| #**************************************************************************** | |
| # subroutine: InputObjectListFromFile | |
| # description: Get a new object list from the specified file. | |
| # input: Input filename, object list ref | |
| # output: Object list | |
| # need init: No | |
| #**************************************************************************** | |
| sub InputObjectListFromFile | |
| { | |
| my $filename = shift; | |
| my $objectListRef = shift; | |
| &objListHelper::InputObjectListFromObjListFile($filename, $objectListRef); | |
| } | |
| #**************************************************************************** | |
| # subroutine: OutputObjectListToFile | |
| # description: Put the object list to the specified file. | |
| # input: Output filename, object list ref | |
| # output: Output to file | |
| # need init: No | |
| #**************************************************************************** | |
| sub OutputObjectListToFile | |
| { | |
| my $filename = shift; | |
| my $objectListRef = shift; | |
| &objListHelper::OutputObjectListToObjListFile($filename, $objectListRef, " "); | |
| } | |
| #**************************************************************************** | |
| # subroutine: CompareObjectList | |
| # description: Compare two object list. | |
| # input: First object list, second object list | |
| # output: 0 for equal; 1 for larger; -1 for smaller | |
| # need init: No | |
| #**************************************************************************** | |
| sub CompareObjectList | |
| { | |
| my $firstList = shift; | |
| my $secondList = shift; | |
| return &objListHelper::CompareObjectList($firstList, $secondList); | |
| } | |
| #**************************************************************************** | |
| # subroutine: SortObjectListByCategory | |
| # description: Sort the object list by the category. | |
| # input: Object list ref. | |
| # output: Sorted object list | |
| # need init: No | |
| #**************************************************************************** | |
| sub SortObjectList | |
| { | |
| my $listRef = shift; | |
| &objListHelper::SortObjectListByCategory($listRef); | |
| } | |
| #**************************************************************************** | |
| # subroutine: SplitObjectListBySize | |
| # description: Split the object list into two part with specified size. | |
| # input: Source list ref, target size, | |
| # split list ref with target size, another split list ref | |
| # output: The split lists | |
| # need init: No | |
| #**************************************************************************** | |
| sub SplitObjectListBySize | |
| { | |
| my $sourceListRef = shift; | |
| my $targetSize = shift; | |
| my $firstListRef = shift; | |
| my $secondListRef = shift; | |
| my @sortedSourceList = sort {$b->{"size"} <=> $a->{"size"}} @$sourceListRef; | |
| my $remainingSize = $targetSize; | |
| foreach my $object (@sortedSourceList) | |
| { | |
| if ($remainingSize >= $object->{"size"}) | |
| { | |
| $remainingSize -= $object->{"size"}; | |
| push @$firstListRef, $object; | |
| } | |
| else | |
| { | |
| push @$secondListRef, $object; | |
| } | |
| } | |
| return ($targetSize - $remainingSize); | |
| } | |
| #**************************************************************************** | |
| # subroutine: SplitObjectListByName | |
| # description: Split the object list by a name list | |
| # input: Source list ref, name list, | |
| # split list ref with target names, another split list ref | |
| # output: The list with size | |
| # need init: No | |
| #**************************************************************************** | |
| sub SplitObjectListByName | |
| { | |
| my $sourceListRef = shift; | |
| my $targetNameList = shift; | |
| my $firstListRef = shift; | |
| my $secondListRef = shift; | |
| my %nameHash = map { $_ => 1 } @$targetNameList; | |
| foreach my $object (@$sourceListRef) | |
| { | |
| if (exists $nameHash{$object->{"name"}}) | |
| { | |
| push @$firstListRef, $object; | |
| } | |
| else | |
| { | |
| push @$secondListRef, $object; | |
| } | |
| } | |
| } | |
| #**************************************************************************** | |
| # subroutine: ChangeObjectListAttributeListByObjectList | |
| # description: Chagne the attribute list of each object in the list by | |
| # the specified object list. | |
| # input: Target object ref, source object ref | |
| # output: Target object ref | |
| # need init: No | |
| #**************************************************************************** | |
| sub ChangeObjectListAttributeListByObjectList | |
| { | |
| my $targetObjectListRef = shift; | |
| my $sourceObjectListRef = shift; | |
| &objListHelper::ChangeObjectListAttributeListByObjectList($targetObjectListRef, $sourceObjectListRef); | |
| } | |
| #**************************************************************************** | |
| # subroutine: DecToHex | |
| # description: Transform decimal number to hex. | |
| # input: Decimal number | |
| # output: Hex number in 0xXXXXXXXX format | |
| # need init: No | |
| #**************************************************************************** | |
| sub DecToHex | |
| { | |
| return sprintf("0x%08X", $_[0]); | |
| } | |
| #**************************************************************************** | |
| # subroutine: ErrorHandler | |
| # description: Handle the post process error and output the error message. | |
| # Note calling this function will lead program terminated. | |
| # input: Message, source filename, line number | |
| # output: None | |
| # need init: Yes/No | |
| #**************************************************************************** | |
| sub ErrorHandler | |
| { | |
| my ($message, $file, $line) = @_; | |
| my $errorMessage = "VIVA ERROR: $message at $file line $line\n"; | |
| print $errorMessage; | |
| if (defined $executionType and $executionType eq CONFIG_TYPE) | |
| { | |
| die $errorMessage; | |
| } | |
| else | |
| { | |
| exit 1; | |
| } | |
| } | |
| 1; |