diff options
Diffstat (limited to 'src/build/tools')
-rwxr-xr-x | src/build/tools/addCopyright | 6 | ||||
-rwxr-xr-x | src/build/tools/build-cppcheck | 95 | ||||
-rwxr-xr-x | src/build/tools/cflags.sh | 68 | ||||
-rwxr-xr-x | src/build/tools/eecache_editor.pl | 802 | ||||
-rwxr-xr-x | src/build/tools/hb | 22 | ||||
-rwxr-xr-x | src/build/tools/listdeps.pl | 1 | ||||
-rwxr-xr-x | src/build/tools/pre-commit | 49 |
7 files changed, 1037 insertions, 6 deletions
diff --git a/src/build/tools/addCopyright b/src/build/tools/addCopyright index 81e871010..1a172a49b 100755 --- a/src/build/tools/addCopyright +++ b/src/build/tools/addCopyright @@ -96,6 +96,9 @@ use constant LICENSE_PROLOG => "LICENSE_PROLOG"; # When adding a new company add constant here and to %fileContributorsCompany use constant IBM => 'International Business Machines Corp.'; use constant GOOGLE => 'Google Inc.'; +use constant INSPUR => 'Inspur Power Systems Corp.'; +use constant SUPERMICRO => 'Super Micro Computer, Inc.'; +use constant YADRO => 'YADRO'; # Create mapping for git contrubitors to companies my %fileContributorsCompany = ( @@ -103,6 +106,9 @@ my %fileContributorsCompany = ( "ozlabs.org" => IBM, "google.com" => GOOGLE, "Google Shared Technology" => GOOGLE, + "inspur.com" => INSPUR, + "supermicro.com" => SUPERMICRO, + "yadro.com" => YADRO, ); #------------------------------------------------------------------------------ diff --git a/src/build/tools/build-cppcheck b/src/build/tools/build-cppcheck new file mode 100755 index 000000000..8e19ed429 --- /dev/null +++ b/src/build/tools/build-cppcheck @@ -0,0 +1,95 @@ +#!/bin/bash -e +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/build/tools/build-cppcheck $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2019 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG + +source $PROJECT_ROOT/src/build/citest/etc/cppcheck + +update_toolconfig(){ + echo "commit: $CPPCHECK_COMMIT" + echo "gcc version: $(gcc -dumpversion)" + echo "S: $(uname -o)" + echo "arch: $(uname -m)" + echo "$(lsb_release -i)" + echo "$(lsb_release -r)" +} + +if [ -n "${OPENPOWER_BUILD}" ]; then + exit +fi + +cd $PROJECT_ROOT/src/build/tools + +if [[ ! -d "cpptools" ]]; then + mkdir cpptools +fi + +cd cpptools +if [[ ! -d "cppcheck" ]]; then + # cppcheck folder does not exist, clone repo for the first time + git clone git@github.com:danmar/cppcheck.git + cd cppcheck + git reset --hard $CPPCHECK_COMMIT #update to cppcheck commit + update_toolconfig >.cpp_toollevel + SHOULDMAKE=1 +else + cd cppcheck + if ! cmp -s .cpp_toollevel <(update_toolconfig) ; then + # cppcheck repo is not at the + # level set in $PROJECT_ROOT/src/build/citest/etc/cppcheck + if ! git fetch origin; then + cd $PROJECT_ROOT/src/build/tools/cpptools + rm -rf cppcheck + git clone git@github.com:danmar/cppcheck.git + cd cppcheck + fi + git reset --hard $CPPCHECK_COMMIT + update_toolconfig >.cpp_toollevel + + SHOULDMAKE=1 + fi + if [[ ! -f "cppcheck" ]]; then + SHOULDMAKE=1 + fi +fi + +if [ "${SHOULDMAKE}" ]; then + + # Check if CXX is set, if it is not then try to find it with CXXPATH + # if CXXPATH does not exist, default to host's g++ + if [ -z "$CXX" ]; then + if [ -z "${CXXPATH}" ]; then + export CXX=g++ + else + export CXX=${CXXPATH}/g++ + fi + fi + + make + +fi + +cd $PROJECT_ROOT + + diff --git a/src/build/tools/cflags.sh b/src/build/tools/cflags.sh new file mode 100755 index 000000000..0ca39f374 --- /dev/null +++ b/src/build/tools/cflags.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/build/tools/cflags.sh $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2019 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG + +# The purpose of this script is to convert a series of GCC compiler +# flags into an equivalent series of flags, but which use absolute +# paths for include directories (i.e. the "-I" flag) instead of +# relative paths. We have to do this when GCOV is in use, because it +# stupidly puts data files in one path but stores paths inside the +# data files that are relative to some other path. When GCOV then +# tries to read the source files via these relative paths, it can't +# find the files. We correct this by converting all paths to source +# and header files to absolute paths. + +if [ ! "$HOSTBOOT_PROFILE" ] ; then + echo "$@" + exit +fi + +make_path_abs () { + local ABSPATH + ABSPATH=$(readlink -f "$1") + + if [ $? -ne 0 ] ; then + ABSPATH="$1" + fi + + echo -n "$ABSPATH" +} + +while [ "$#" -gt 0 ] ; do + FLAG="$1" + + if [ "$FLAG" = "-I" ] ; then + shift + echo -n "-I $(make_path_abs "$1") " + elif [ "${FLAG:0:2}" = "-I" ] ; then + echo -n "-I $(make_path_abs "${FLAG:2}") " + else + echo -n "$FLAG " + fi + + shift +done + +echo diff --git a/src/build/tools/eecache_editor.pl b/src/build/tools/eecache_editor.pl new file mode 100755 index 000000000..262f56376 --- /dev/null +++ b/src/build/tools/eecache_editor.pl @@ -0,0 +1,802 @@ +#!/usr/local/bin/perl +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/build/tools/eecache_editor.pl $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2019 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG + +use strict; +use Getopt::Long; +use File::Copy; + + +binmode STDOUT, ':bytes'; + +my $pnorBinaryPath = ""; +my $eecacheBinaryPath = ""; +my $newImagePath = ""; +my $outFilePath = "./eecache_editor_output.dat"; +my $masterHuid = 0; +my $port = 0; +my $engine = 0; +my $devAddr = 0; +my $muxHuid = 0; +my $muxSelect = 0xFF; +my $eepromSize = 0; +my $usage = 0; +my $uniqueId = ""; +my $verbose = 0; +my $onlyValid = 0; +my $clearEepromData = 0; +my $overwrite = 0; +my $summary = 0; +my $devOffset = 0xFFFF; # initialized to invalid offset + +# Goals of this tool: +# +# ** Handle both entire PNOR image as well as single EECACHE section as input ** +# +# 1) Given masterHuid, port, engine, devAddr, muxSelect lookup cached EEPROM value and replace +# it with a given binary file. (File size must be <= allocated space) +# +# 2) Given a binary pnor/eecache. Print summary of cached eeproms +# +# 3) Zero out a given cached eeprom +# +# 4) Extract the contents for a given masterHuid, port, engine, devAddr, muxSelect + +use constant VERSION_1_TOC_ENTRY_SIZE_BYTES => 17; +use constant VERSION_1_TOC_ENTRY_SIZE_BITS => (VERSION_1_TOC_ENTRY_SIZE_BYTES * 8) ; +use constant VERSION_1_NUM_ENTRIES => 50; +use constant VERSION_1_TOC_SIZE => (VERSION_1_TOC_ENTRY_SIZE_BYTES * VERSION_1_NUM_ENTRIES) + 5; + +use constant VERSION_2_TOC_ENTRY_SIZE_BYTES => 18; +use constant VERSION_2_TOC_ENTRY_SIZE_BITS => (VERSION_2_TOC_ENTRY_SIZE_BYTES * 8) ; +use constant VERSION_2_NUM_ENTRIES => 50; +use constant VERSION_2_TOC_SIZE => (VERSION_2_TOC_ENTRY_SIZE_BYTES * VERSION_2_NUM_ENTRIES) + 5; + +use constant VERSION_LATEST => 2; + +use constant EEPROM_ACCESS_I2C => 1; +use constant EEPROM_ACCESS_SPI => 2; + + + +my $eecacheVersion = VERSION_LATEST; + +GetOptions("pnor:s" => \$pnorBinaryPath, + "eecache:s" => \$eecacheBinaryPath, + "newImage:s" => \$newImagePath, + "newFile:s" => \$newImagePath, + "out:s" => \$outFilePath, + "of:s" => \$outFilePath, + "masterHuid:o" => \$masterHuid, + "port:o" => \$port, + "engine:o" => \$engine, + "devAddr:o" => \$devAddr, + "muxSelect:o" => \$muxSelect, + "eepromSize:o" => \$eepromSize, + "uniqueId:s" => \$uniqueId, + "devOffset:o" => \$devOffset, + "version:o" => \$eecacheVersion, + "onlyValid" => \$onlyValid, + "overwrite" => \$overwrite, + "clear" => \$clearEepromData, + "verbose" => \$verbose, + "usage" => \$usage, + "help" => \$usage, + "h" => \$usage); + +sub print_help() +{ + print "--------- EECACHE Editor Tool V 2.0 ---------\n"; + print "\n"; + print "Mandatory:\n\n"; + + print " --eecache Path to ECC-less eeprom cache section of PNOR (IE : EECACHE.bin )\n\n"; + + print "Optional:\n\n"; + + print " --clear If a matching eeprom is found, clear out its contents\n"; + print " --devAddr Device address of desired EEPROM\n"; + print " --devOffset Offset (KB) of where record begins in eeprom for SPI access\n"; + print " --engine Engine of I2C/SPI Master desired EEPROM exists on\n"; + print " --masterHuid HUID of the I2C/SPI Master Target\n"; + print " --muxSelect Mux Select (if needed) defaults to 0xFF \n"; + print " --onlyValid If printing summary, only print valid eeprom caches\n"; + print " --out Full path to desired out file, if not provided defaults to ./eecache_editor_output.dat\n"; + print " --port Port of I2C Master desired EEPROM exists on\n"; + print " --uniqueId Combination of unique I2C Slave information, alternative to passing\n"; + print " information in 1 thing at a time\n"; + print " --version Version of eecache (default to latest if this isn't provided)\n"; + print " --verbose Print extra information \n"; + print " --help Print this information \n"; + print "\n "; + print "Examples: \n\n"; + print " # prints out info about all eeproms in EECACHE.bin\n"; + print " eecache_editor.pl --eecache EECACHE.bin\n"; + print "\n"; + print " # (I2C) lookup eeprom matching input params and write contents of that EEPROM's cached data to outfile \n"; + print " eecache_editor.pl --eecache EECACHE.bin --version 1 --port 0 --engine 3 --muxSelect 8 --devAddr 0xa0 --masterHuid 0x50000\n"; + print "\n"; + print " # (I2C) lookup eeprom matching input params and clear the contents ( manipulate input binary )\n"; + print " eecache_editor.pl --eecache EECACHE.bin --port 0 --engine 3 --muxSelect 8 --devAddr 0xa0 --masterHuid 0x50000 --clear\n"; + print "\n"; + print " # (I2C) lookup eeprom matching input params and write new image's contents to offset in EECACHE where matching eeprom data exists ( manipulate input binary )\n"; + print " eecache_editor.pl --eecache EECACHE.bin --port 0 --engine 3 --muxSelect 8 --devAddr 0xa0 --masterHuid 0x50000 --newImage newSPD.dat\n"; + print "\n"; + print " # (SPI) lookup eeprom matching input params and write contents of that EEPROM's cached data to outfile \n"; + print " eecache_editor.pl --eecache EECACHE.bin --engine 3 --devOffset 0xc0 --masterHuid 0x50000\n"; + print "\n"; + print " # (SPI) lookup eeprom matching input params and clear the contents ( manipulate input binary )\n"; + print " eecache_editor.pl --eecache EECACHE.bin --engine 3 --devOffset 0xc0 --masterHuid 0x50000 --clear\n"; + print "\n"; + print " # (SPI) lookup eeprom matching input params and write new image's contents to offset in EECACHE where matching eeprom data exists ( manipulate input binary )\n"; + print " eecache_editor.pl --eecache EECACHE.bin --engine 3 --devOffset 0xc0 --masterHuid 0x50000 --newImage newSPD.dat\n"; + print "---------------------------------------------\n"; +} + +if( $usage ) +{ + print_help(); + exit 0; +} + +if( ($pnorBinaryPath eq "") && + ($eecacheBinaryPath eq "")) +{ + # Print error saying we need one of these filled in + print "ERROR Neither PNOR binary nor EECACHE section binary passed in. Cannot continue.\n\n"; + print_help(); + exit 0; +} + +# if PNOR is not empty, ignore eecacheBinary , we will +# output a full updated pnor since we were provided a pnor. +# but if no pnor is provided , we will just return and EECACHE sections +my $inputIsEntirePnor = 0; +if( $pnorBinaryPath ne "") +{ + $inputIsEntirePnor = 1; +} + +if($newImagePath ne "") +{ + $overwrite = 1; +} + +if ($eecacheVersion > VERSION_LATEST) +{ + print "ERROR: --version $eecacheVersion is greater than max ".VERSION_LATEST."\n\n"; + print_help(); + exit 0; +} + +if ($uniqueId eq "") +{ + if ($eecacheVersion == VERSION_LATEST) + { + # devOffset is specific to SPI access so check to see if it is valid + if ($devOffset != 0xFFFF) + { + $uniqueId = sprintf ("%.02X", EEPROM_ACCESS_SPI); + $uniqueId .= sprintf ("%.08X", $masterHuid); + $uniqueId .= sprintf ("%.02X", $engine); + $uniqueId .= sprintf ("%.04X", $devOffset); + $uniqueId .= "00"; # blank byte + } + else + { + $uniqueId = sprintf ("%.02X", EEPROM_ACCESS_I2C); + $uniqueId .= sprintf ("%.08X", $masterHuid); + $uniqueId .= sprintf ("%.02X", $port); + $uniqueId .= sprintf ("%.02X", $engine); + $uniqueId .= sprintf ("%.02X", $devAddr); + $uniqueId .= sprintf ("%.02X", $muxSelect); + } + } + elsif ($eecacheVersion == 1) + { + $uniqueId .= sprintf ("%.08X", $masterHuid); + $uniqueId .= sprintf ("%.02X", $port); + $uniqueId .= sprintf ("%.02X", $engine); + $uniqueId .= sprintf ("%.02X", $devAddr); + $uniqueId .= sprintf ("%.02X", $muxSelect); + } +} + +my $displayOnly = 0; + +unless (isUniqueIdValid($uniqueId)) +{ + if( $clearEepromData ) + { + print_help(); + print "\n ERROR: Detecting that user is trying to --clear data without providing what info on what eeprom to clear. Exiting. \n\n"; + exit 0; + } + $displayOnly = 1; + $verbose = 1; +} +else +{ + print "\nUnique ID we are looking up: 0x$uniqueId \n\n" ; +} + +# setup input and output files +my $input_fh; +my $output_fh; + +my $new_fh; + +if($inputIsEntirePnor) +{ + open $input_fh, '<', $pnorBinaryPath or die "failed to open $pnorBinaryPath: $!\n"; + if($overwrite) + { + open $output_fh, '>', $pnorBinaryPath or die "failed to open $pnorBinaryPath: $!\n"; + } + else + { + open $output_fh, '>', $outFilePath or die "failed to open $outFilePath: $!\n"; + } +} +else +{ + open $input_fh, '+<:raw', $eecacheBinaryPath or die "failed to open $eecacheBinaryPath: $!\n"; + if($overwrite) + { + $output_fh = $input_fh; + } + else + { + open $output_fh, '+>:raw', $outFilePath or die "failed to open $outFilePath: $!\n"; + copy($eecacheBinaryPath, $outFilePath) ; + } +} + +if($newImagePath ne "") +{ + open $new_fh, '<', $newImagePath or die "failed to open $newImagePath: $!\n"; +} + + + +# at this point we should know what we are trying to accomplish : +# +# IF ($displayOnly != 0) THEN we will only print a summary +# +# ELSE IF ($newImagePath != "") THEN we will write new contents if matching section found +# +# ELSE IF ($clear != 0) THEN clear the contents if matching section found +# +# ELSE if matching section found, then write contents to outfile + + + +# TODO handle entire PNOR +if($inputIsEntirePnor) +{ + #find EECACHE offset , seek to there +} +else +{ + # Parse the larger binary blob to get just the Table of Contents + my $eecacheTOC = readEecacheToc($input_fh); + + # The hashRef you key back has members: offset and size + # This represents offset and size of eeprom data in given + # binary. + my $hashRef = parseEecacheToc($eecacheTOC, $uniqueId); + + # if we are doing displayOnly then we are done, we can skip the following logic + if(!$displayOnly) + { + # If the offset is 0, then no match was found + if($hashRef->{'entry_offset'} != 0) + { + if($newImagePath ne "") # if a new image is available try to load it in + { + my $new_file_size = -s $newImagePath ; + my $new_file_data; + read($new_fh, $new_file_data, $new_file_size ); + + # Verify the new image is the correct size + if( $new_file_size != $hashRef->{'entry_size'}) + { + print "ERROR incorrect size, EECACHE is reporting size to be".$hashRef->{'entry_size'}."bytes but file proved is only".$new_file_size." bytes\n"; + exit 0; + } + + # seek to the offset inside EEACHE where this eeprom's cache lives + # and write the new file contents + seek($output_fh, $hashRef->{'entry_offset'} , 0); + print $output_fh $new_file_data; + } + elsif($clearEepromData) # if we are told to clear the data do that + { + print "Attempting Clearing starting at $hashRef->{'entry_offset'} $hashRef->{'header_offset'}!!!!!!!!\n"; + my $byteOfOnes = pack("H2", "FF") ; + my $byteOfZeroes = pack("H2", "00") ; + seek($output_fh, $hashRef->{'entry_offset'} , 0); + for(my $i = 0; $i < $hashRef->{'entry_size'}; $i++) + { + print $output_fh $byteOfOnes; + } + + # seek($output_fh, $hashRef->{'header_offset'} + 16, 0); + # print $output_fh $byteOfZeroes; + } + else + { + seek($input_fh, $hashRef->{'entry_offset'} , 0); + my $cur_pos = tell $input_fh; + print "reading $hashRef->{'entry_size'} from $cur_pos\n "; + my $cachedData; + read($input_fh, $cachedData, $hashRef->{'entry_size'}); + print $output_fh $cachedData; + } + } + } +} + +close $input_fh; +close $output_fh; + +# End of Main +exit 0; + + +# Start Subroutines + +sub readEecacheToc { + my $eecache_fh = shift; + + my $start_location = tell $eecache_fh; + + my $eecache_toc_version = 0; + + read($eecache_fh, $eecache_toc_version, 1) == 1 or die "failed to read single byte from eecache file handle"; + $eecache_toc_version = unpack 'C', $eecache_toc_version; + + my $eecache_toc; + + if( $eecache_toc_version == 1 ) + { + seek($eecache_fh, $start_location, 0); + read($eecache_fh, $eecache_toc, VERSION_1_TOC_SIZE) or die "failed to read ".VERSION_1_TOC_SIZE." bytes from eecache file handle"; ; + } + elsif ( $eecache_toc_version == 2) + { + seek($eecache_fh, $start_location, 0); + read($eecache_fh, $eecache_toc, VERSION_2_TOC_SIZE) or die "failed to read ".VERSION_2_TOC_SIZE." bytes from eecache file handle"; ; + } + else + { + die "Failed to find valid TOC, version found = $eecache_toc_version. Latest version this tool supports is ".VERSION_LATEST; + } + + return $eecache_toc; +} + +# Brief : Takes in binary blob representing EECACHE table of contents, as well as +# a uniqueID to match against, returns hash that contains size and offset of +# cached eeprom data inside EEACHE section +# +# If verbose is set, + +sub parseEecacheToc { + my $eecacheTOC = shift; + my $idToMatch = shift; + + # figure out what version of EECACHE header exists + my $headerVersion = 0; + my $tocEntrySizeBytes = 0; + my $tocEntries = 0; + + my ($version) = unpack('H2', "$eecacheTOC"); + if ($version == 0x01) + { + $headerVersion = 1; + $tocEntrySizeBytes = VERSION_1_TOC_ENTRY_SIZE_BYTES; + $tocEntries = VERSION_1_NUM_ENTRIES; + } + elsif ($version == 0x02) + { + $headerVersion = 2; + $tocEntrySizeBytes = VERSION_2_TOC_ENTRY_SIZE_BYTES; + $tocEntries = VERSION_2_NUM_ENTRIES; + } + else + { + die "Unsupported PNOR EECACHE level $version"; + } + + # verify uniqueId was built against same version as PNOR's EECACHE + if (isUniqueIdValid($uniqueId)) + { + unless (($headerVersion == $eecacheVersion)) + { + die "PNOR EECACHE version $headerVersion is not same as expected EECACHE version $eecacheVersion!" . + "Maybe changed expected with --version option"; + } + } + + # header entries start after on 6th byte + my $headerEntryOffset = 5; + + # this will end up being the return value + my %entryInfo; + $entryInfo{entry_offset} = 0; + $entryInfo{entry_size} = 0; + $entryInfo{header_offset} = 0; + + my $totalEntryCount = 0; + my $validEntryCount = 0; + + my $matchSummaryString = ""; + + # Some common variables between header versions + my $internal_offset = 0xFFFF; + my $cached_copy_valid = 0; + my $cached_copy_size = 0; + my $entry_size = 0; + my $entry_offset = 0; + my $bitFieldByte = 0; # last byte of header + my $entryUniqueID = "FFFFFFFFFFFFFFFF"; + + use Class::Struct; + + struct I2C_Entry_t => { + i2c_master_huid => '$', + port => '$', + engine => '$', + devAddr => '$', + mux_select => '$', + }; + + struct SPI_Entry_t => { + spi_master_huid => '$', + engine => '$', + offset_KB => '$', + }; + + for(my $i = 0; $i < $tocEntries; $i++) + { + my $eepromAccess = EEPROM_ACCESS_I2C; + my $master_eeprom = 0xFF; # default to invalid master eeprom + + my $entry = substr $eecacheTOC, $headerEntryOffset, $tocEntrySizeBytes; + + # update offset right away so we dont forget + $headerEntryOffset += $tocEntrySizeBytes; + my $entry_data; + + if ($headerVersion == 1) + { + ###### VERSION 1 ######## + # struct completeRecord + # { + # uint32_t i2c_master_huid; // HUID of i2c Master + # uint8_t port; // I2C Port + # uint8_t engine; // I2C Engine + # uint8_t devAddr; // I2C Device Address + # uint8_t mux_select; // Some I2C devices are behind a mux, this says + # // what setting on the mux is required + # uint32_t cache_copy_size; // Size of data saved in cache (in KB) + # uint32_t internal_offset; // offset from start of EECACHE section where cached + # // data exists + # uint8_t cached_copy_valid : 1, // This bit is set when we think the contents of the + # // cache is valid. + # unused : 7; + # + # } PACKED completeRecord; + # + # struct uniqueRecord + # { + # uint8_t uniqueID [NUM_BYTE_UNIQUE_ID]; + # uint8_t metaData [sizeof(completeRecord) - NUM_BYTE_UNIQUE_ID]; + # } PACKED uniqueRecord; + + # unpack according to src/include/usr/i2c/eeprom_const.H ( pasted above) + my @entryFields = unpack('H8 H2 H2 H2 H2 H8 H8 H2', "$entry"); + + $entryUniqueID = "@entryFields[0]@entryFields[1]@entryFields[2]@entryFields[3]@entryFields[4]"; + $eepromAccess = EEPROM_ACCESS_I2C; + $entry_data = I2C_Entry_t->new(); + $entry_data->i2c_master_huid( @entryFields[0] ); + $entry_data->port ( @entryFields[1] ); + $entry_data->engine ( @entryFields[2] ); + $entry_data->devAddr ( @entryFields[3] ); + $entry_data->mux_select ( @entryFields[4] ); + $bitFieldByte = @entryFields[7]; + $cached_copy_valid = (hex( "0x".@entryFields[7]) & 0x80) >> 7; + + + # if the entry ID is FFFFFFFFFFFFFFFF this indicates + # that the entry is not filled out + if($entryUniqueID == "FFFFFFFFFFFFFFFF") + { + next; + } + $cached_copy_size = @entryFields[5]; + $internal_offset = @entryFields[6]; + } + elsif ($headerVersion == 2) + { + ###### VERSION 2 ######## + # struct completeRecord + # { + # EepromAccessMethodType accessType; // how to access record + # union eepromAccess_t + # { + # struct i2cAccess_t + # { + # uint32_t i2c_master_huid; // HUID of i2c Master + # uint8_t port; // I2C Port + # uint8_t engine; // I2C Engine + # uint8_t devAddr; // I2C Device Address + # uint8_t mux_select; // Some I2C devices are behind a mux, this says + # // what setting on the mux is required + # } PACKED i2cAccess; + # struct spiAccess_t + # { + # uint32_t spi_master_huid; // HUID of SPI master + # uint8_t engine; // engine specific to eeprom + # uint16_t offset_KB; // offset in KB of where record begins in eeprom + # } PACKED spiAccess; + # } PACKED eepromAccess; + # uint32_t cache_copy_size; // Size of data saved in cache (in KB) + # uint32_t internal_offset; // offset from start of EECACHE section where cached + # // data exists + # uint8_t cached_copy_valid : 1, // This bit is set when we think the contents of the + # // cache is valid. + # master_eeprom : 1, // This bit marks this record as the master one (i.e. look at this one for change) + # unused : 6; + # + # } PACKED completeRecord; + # + # struct uniqueRecord + # { + # uint8_t uniqueID [NUM_BYTE_UNIQUE_ID]; + # uint8_t metaData [sizeof(completeRecord) - NUM_BYTE_UNIQUE_ID]; + # } PACKED uniqueRecord; + + ($eepromAccess) = unpack('H2', "$entry"); + if ($eepromAccess == EEPROM_ACCESS_I2C) + { + # unpack according to src/include/usr/i2c/eeprom_const.H ( pasted above) + my @entryFields = unpack('H2 H8 H2 H2 H2 H2 H8 H8 H2', "$entry"); + + $entryUniqueID = "@entryFields[0]@entryFields[1]@entryFields[2]@entryFields[3]@entryFields[4]@entryFields[5]"; + + $entry_data = I2C_Entry_t->new(); + $entry_data->i2c_master_huid( @entryFields[1] ); + $entry_data->port( @entryFields[2] ); + $entry_data->engine( @entryFields[3] ); + $entry_data->devAddr( @entryFields[4] ); + $entry_data->mux_select( @entryFields[5] ); + + $cached_copy_size = @entryFields[6]; + $internal_offset = @entryFields[7]; + + $bitFieldByte = @entryFields[8]; + $cached_copy_valid = (hex("0x".@entryFields[8]) & 0x80) >> 7; + $master_eeprom = (hex("0x".@entryFields[8]) & 0x40) >> 6; + } + elsif ($eepromAccess == EEPROM_ACCESS_SPI) + { + # unpack according to src/include/usr/i2c/eeprom_const.H ( pasted above) + my @entryFields = unpack('H2 H8 H2 H4 H2 H8 H8 H2', "$entry"); + + $entryUniqueID = "@entryFields[0]@entryFields[1]@entryFields[2]@entryFields[3]00"; + + $entry_data = SPI_Entry_t->new(); + $entry_data->spi_master_huid( @entryFields[1] ); + $entry_data->engine( @entryFields[2] ); + $entry_data->offset_KB( @entryFields[3] ); + + # @entryField[4] is just filler + + $cached_copy_size = @entryFields[5]; + $internal_offset = @entryFields[6]; + + $bitFieldByte = @entryFields[7]; + $cached_copy_valid = (hex("0x".@entryFields[7]) & 0x80) >> 7; + $master_eeprom = (hex("0x".@entryFields[7]) & 0x40) >> 6; + } + else + { + # entry is not filled out if eepromAccess is not I2C or SPI + next; + } + } + + $totalEntryCount++; + + if(uc $entryUniqueID eq uc $idToMatch) + { + $entryInfo{entry_offset} = $internal_offset; + $entryInfo{entry_size} = $cached_copy_size * 1024; # KB to Bytes + $entryInfo{header_offset} = $headerEntryOffset - $tocEntrySizeBytes; + + $matchSummaryString = "ENTRY FOUND ...\n"; + if ($eepromAccess == EEPROM_ACCESS_I2C) + { + if ($headerVersion >= 2) + { + $matchSummaryString .= + "accessType = 0x".$eepromAccess." I2C ACCESS\n"; + } + $matchSummaryString .= + "Master I2C Huid = 0x". $entry_data->i2c_master_huid ."\n". + "Port = 0x". $entry_data->port ."\n". + "Engine = 0x". $entry_data->engine ."\n". + "Device Address = 0x". $entry_data->devAddr ."\n". + "Mux Select = 0x". $entry_data->mux_select ."\n". + "Size of Cached Copy (KB) = 0x$cached_copy_size\n". + "Offset within EECACHE = 0x$internal_offset\n". + "Cached copy valid ? = 0x$cached_copy_valid (1st bit of 0x$bitFieldByte)\n"; + } + else # EEPROM_ACCESS_SPI + { + if ($headerVersion >= 2) + { + $matchSummaryString .= + "accessType = 0x".$eepromAccess." SPI ACCESS\n"; + } + $matchSummaryString .= + "Master SPI Huid = 0x". $entry_data->spi_master_huid ."\n". + "Engine = 0x". $entry_data->engine ."\n". + "Offset in EEPROM = 0x". $entry_data->offset_KB ."\n". + "Size of Cached Copy (KB) = 0x$cached_copy_size\n". + "Offset within EECACHE = 0x$internal_offset\n". + "Cached copy valid ? = $cached_copy_valid (1st bit of 0x$bitFieldByte)\n"; + } + if ($master_eeprom != 0xFF) + { + $matchSummaryString .= + "EEPROM master ? = $master_eeprom (2nd bit of 0x$bitFieldByte)\n"; + } + $matchSummaryString .= + "unique ID = 0x$entryUniqueID \n\n"; + + if(!$verbose) + { + last; + } + } + + if( !$cached_copy_valid ) + { + # skip if this entry is not valid and told to just + # print valid only entries + if($onlyValid) + { + next; + } + } + else + { + $validEntryCount++; + } + + my $entryString = ""; + if ($eepromAccess == EEPROM_ACCESS_I2C) + { + if ($headerVersion >= 2) + { + $entryString .= + "accessType = 0x".$eepromAccess." I2C ACCESS\n"; + } + $entryString .= + "Master I2C Huid = 0x". $entry_data->i2c_master_huid ."\n". + "Port = 0x". $entry_data->port ."\n". + "Engine = 0x". $entry_data->engine ."\n". + "Device Address = 0x". $entry_data->devAddr ."\n". + "Mux Select = 0x". $entry_data->mux_select ."\n". + "Size of Cached Copy (KB) = 0x$cached_copy_size\n". + "Offset within EECACHE = 0x$internal_offset\n". + "Cached copy valid ? = $cached_copy_valid (1st bit of 0x$bitFieldByte)\n"; + } + else + { + if ($headerVersion >= 2) + { + $entryString .= + "accessType = 0x".$eepromAccess." SPI ACCESS\n"; + } + $entryString .= + "Master SPI Huid = 0x". $entry_data->spi_master_huid ."\n". + "Engine = 0x". $entry_data->engine ."\n". + "Offset in EEPROM = 0x". $entry_data->offset_KB ."\n". + "Size of Cached Copy (KB) = 0x$cached_copy_size\n". + "Offset within EECACHE = 0x$internal_offset\n". + "Cached copy valid ? = $cached_copy_valid (1st bit of 0x$bitFieldByte)\n"; + } + + if ($master_eeprom != 0xFF) + { + $entryString .= + "EEPROM master ? = $master_eeprom (2nd bit of 0x$bitFieldByte)\n"; + } + $entryString .= + "unique ID = 0x$entryUniqueID \n\n"; + + printVerbose($entryString); + } + + printVerbose( + "Summary :\n". + " Total Entry Count : $totalEntryCount \n". + " Valid Entry Count : $validEntryCount \n". + " Max Possible Entries : $tocEntries\n\n"); + + if($matchSummaryString ne "") + { + print $matchSummaryString; + } + else + { + # Skip failure message if not looking for a unique id match + if (isUniqueIdValid($uniqueId)) + { + print "No Match Found! \n\n"; + } + } + + return \%entryInfo; +} + + +sub findEepromRecordOffset { + + + +} + +sub printVerbose { + + my $string = shift; + + if($verbose) + { + print $string; + } +} + +sub isUniqueIdValid +{ + my ($uniqueId) = @_; + + if( (($eecacheVersion == 1) && ($uniqueId == "00000000000000FF")) || + (($eecacheVersion == 2) && ($uniqueId == "0100000000000000FF")) || + (($eecacheVersion == 2) && ($uniqueId == "020000000000000000")) ) + { + return 0; + } + else + { + return 1; + } +} + diff --git a/src/build/tools/hb b/src/build/tools/hb index 9576adb0f..9e7e38a48 100755 --- a/src/build/tools/hb +++ b/src/build/tools/hb @@ -39,6 +39,7 @@ execute_in_sandbox() echo $1 > ${SANDBOXBASE}/src/sandbox_execute_cmd chmod 700 ${SANDBOXBASE}/src/sandbox_execute_cmd + echo "Sandbox :: $1" ${WORKON_CMD} -c ./sandbox_execute_cmd @@ -356,14 +357,16 @@ hb_simsetup() DRIVER=`cat ${PROJECT_ROOT}/src/build/citest/etc/bbuild` SIMICS_LEVEL=`cat ${PROJECT_ROOT}/src/build/citest/etc/simbuild` + EECACHE_PREBUILT=`cat ${PROJECT_ROOT}/src/build/citest/etc/eecache_prebuilt` needs_machine_variable if [ "${MACHINE}" == "AXONE" ]; then - echo "mkdir -p ${SANDBOXBASE}/simics" execute_in_sandbox "mkdir -p ${SANDBOXBASE}/simics" "ppc" - echo "tar ${SIMICS_LEVEL} -C ${SANDBOXBASE}/simics/" execute_in_sandbox "tar -xf ${SIMICS_LEVEL} -C ${SANDBOXBASE}/simics/" "ppc" + echo "cd ${SANDBOXBASE}/simics/ && ./INSTALL.sh" execute_in_sandbox "cd ${SANDBOXBASE}/simics/ && ./INSTALL.sh" "ppc" + echo "cp ${EECACHE_PREBUILT} ${SANDBOXBASE}/simics/eecache_prebuilt.bin.ecc" + execute_in_sandbox "cp ${EECACHE_PREBUILT} ${SANDBOXBASE}/simics/eecache_prebuilt.bin.ecc" "ppc" else execute_in_sandbox "start_simics -no_start -machine ${MACHINE}" "ppc" fi @@ -424,8 +427,19 @@ hb_startsimics() #export MYDIR=$bb/obj/ppc/hbfw/simics/startup.simics #then /runsim -m axone -o hb_script_to_run=$MYDIR export MY_DIR="${SANDBOXBASE}/obj/ppc/simu/scripts/hbfw" - echo "cd ${SANDBOXBASE}/simics/ && ./runsim -m ${MACHINE} hb_script_to_run=${MY_DIR}/startup.simics pnor_img=${MY_DIR}/../../../hbfw/img/axone.pnor sbe_seeprom_img=${SANDBOXBASE}/images/ppc/lab/flash/sbe_seeprom_p9a_10.bin.ecc num_procs=1 vpd_proc=vpd/images/99a8c3fe4e5c74798f5bd4212f3d9a2a" - execute_in_sandbox "cd ${SANDBOXBASE}/simics/ && ./runsim -m ${MACHINE} hb_script_to_run=${MY_DIR}/startup.simics pnor_img=${MY_DIR}/../../../hbfw/img/axone.pnor sbe_seeprom_img=${SANDBOXBASE}/images/ppc/lab/flash/sbe_seeprom_p9a_10.bin.ecc num_procs=1 vpd_proc=vpd/images/99a8c3fe4e5c74798f5bd4212f3d9a2a" "ppc" + # If '-nre' was passed in as a flag, then do not vexec + # also, if $POOL is defined, this indicates are already in + # a vexec shell so do not vexec + if [ "$*" = "-nre" ] || [ ! -z ${POOL} ]; then + VEXEC_STR=" vexec" + else + VEXEC_STR="" + fi + export RUNSIMCMD="cd ${SANDBOXBASE}/simics/ &&${VEXEC_STR} ./runsim -m ${MACHINE} hb_script_to_run=${MY_DIR}/startup.simics pnor_img=${MY_DIR}/../../../hbfw/img/axone.pnor sbe_seeprom_img=${SANDBOXBASE}/images/ppc/lab/flash/sbe_seeprom_p9a_10.bin.ecc num_procs=2 enable_lpc_console=TRUE hb_pnor_dir=${MY_DIR}/../../../hbfw/img/" + echo "**********" + echo $RUNSIMCMD + echo "**********" + execute_in_sandbox "${RUNSIMCMD} ${SIMICSOPTIONS}" "ppc" else execute_in_sandbox \ "start_simics -machine ${MACHINE} ${SIMICSOPTIONS} $*" "ppc" diff --git a/src/build/tools/listdeps.pl b/src/build/tools/listdeps.pl index 9bad71ef9..2eaf7a6ad 100755 --- a/src/build/tools/listdeps.pl +++ b/src/build/tools/listdeps.pl @@ -229,6 +229,7 @@ my $resident_modules = { "libexpaccess.so" => '1', "libnvdimm.so" => '1', "libmmio.so" => '1', + "libsmf.so" => '1', }; # A list of the dependent libraries in each istep. diff --git a/src/build/tools/pre-commit b/src/build/tools/pre-commit index 3dc621bb3..ccf02b80a 100755 --- a/src/build/tools/pre-commit +++ b/src/build/tools/pre-commit @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # @@ -6,7 +6,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2011,2017 +# Contributors Listed Below - COPYRIGHT 2011,2019 # [+] International Business Machines Corp. # # @@ -35,3 +35,48 @@ else echo "For more info run './hb --help'" exit -1 fi + +# Run cppcheck if variable is set, if not exit here +if [[ $DOCPPCHECK -ne 1 ]]; then + exit 0 +fi + +echo "Running CPPCHECK" + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # This is the hash of the default empty tree in Git. + # If for some reason HEAD is not set, then diff'ing against this is like + # diff'ing against the very first commit. + against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 +fi + +${TOOLSDIR}/build-cppcheck +CPPCHECKTOOL=${TOOLSDIR}/cpptools/cppcheck/cppcheck +CPPCHECKFLAGS="--inline-suppr --error-exitcode=1" +CPPCHECK=" ${CPPCHECKTOOL} ${CPPCHECKFLAGS}" + +for file in $(git diff-index --cached $against | \ + grep -E '[MA].*\.(C|c|cpp|cc|cxx)$' | cut -f 2) +do + + dir="$(dirname $file)" + filename="$(basename $file)" + + # TODO RTC 215692 + # The following command checks for cppcheck errors. All cppcheck errors are + # printed to the terminal and stored to a file .${filename}.cppcheck. + set -o pipefail && cd ${dir} && timeout 2m ${CPPCHECK} $filename 2>&1 | tee .${filename}.cppcheck; exit_code=$?; \ + if [ "$exit_code" -ne 1 ]; then \ + # If exit code does not equal 1 (which is the error code when a cppcheck + # error is found) delete the created .cppcheck file. + # Note that time-out fails with error code 127. + rm -f .${filename}.cppcheck; \ + fi + cd $PROJECT_ROOT + +done + +exit 0 |