summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rwxr-xr-xsrc/tools/debug/simics/makefile53
-rwxr-xr-xsrc/tools/debug/simics/sbe_standalone.simics2
-rwxr-xr-xsrc/tools/debug/simics/sbe_startup.simics14
-rwxr-xr-xsrc/tools/debug/simics/simics-debug-framework.py88
-rwxr-xr-xsrc/tools/hooks/addCopyright1167
-rwxr-xr-xsrc/tools/hooks/gerrit-hostname78
-rwxr-xr-xsrc/tools/hooks/post-commit32
-rwxr-xr-xsrc/tools/hooks/pre-commit38
-rwxr-xr-xsrc/tools/hooks/pre-commit-actions48
-rwxr-xr-xsrc/tools/hooks/pre-commit-prologs46
-rwxr-xr-xsrc/tools/hooks/setupgithooks.sh63
-rwxr-xr-xsrc/tools/hooks/verify-commit358
-rw-r--r--src/tools/image/Makefile86
-rw-r--r--src/tools/image/sbe_default_tool.c310
-rw-r--r--src/tools/ppetracepp/Makefile37
-rw-r--r--src/tools/ppetracepp/cmvc/makefile28
-rwxr-xr-xsrc/tools/ppetracepp/jhash.h166
-rwxr-xr-xsrc/tools/ppetracepp/ppe2fsp.c532
-rw-r--r--src/tools/ppetracepp/ppe2fsp.h33
-rw-r--r--src/tools/ppetracepp/ppe2fsp_cmd.c138
-rwxr-xr-xsrc/tools/ppetracepp/ppetracepp.C949
-rwxr-xr-xsrc/tools/ppetracepp/trac_interface.h369
-rwxr-xr-xsrc/tools/ppetracepp/tracehash.pl896
-rwxr-xr-xsrc/tools/scripts/parseErrorInfo.pl1663
-rwxr-xr-xsrc/tools/scripts/ppeCreateAttrGetSetMacros.pl571
-rwxr-xr-xsrc/tools/scripts/ppeCreateIfAttrService.pl240
-rw-r--r--src/tools/scripts/ppeParseAttrGetSetMacros.pl286
-rwxr-xr-xsrc/tools/scripts/ppeParseAttributeInfo.pl746
-rwxr-xr-xsrc/tools/scripts/ppeParseProcSbeFixed.pl318
-rwxr-xr-xsrc/tools/scripts/ppeSetFixed.pl259
-rw-r--r--src/tools/scripts/src/fapi2PlatAttributeService.H1416
31 files changed, 11030 insertions, 0 deletions
diff --git a/src/tools/debug/simics/makefile b/src/tools/debug/simics/makefile
new file mode 100755
index 00000000..473c0088
--- /dev/null
+++ b/src/tools/debug/simics/makefile
@@ -0,0 +1,53 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/debug/simics/makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+#
+# FSP Destination: obj/ppc/sbei/sbfw/simics/makefile
+#
+# NOTE: Do NOT modify this file in CMVC directly! It comes from the SBE
+# repository and will be overwritten.
+
+.include <${RULES_MK}>
+
+OTHERS = copy_scripts
+
+SBE_SIMICS_PATH = ${MAKETOP}simu/scripts/sbfw/
+
+SBE_SRC_PATHS = ${.PATH:M*src*sbei*sbfw*simics*} ${.PATH:M*obj*sbei*sbfw*simics*}
+SBE_SRC_DIRS = ${SBE_SRC_PATHS:XD}
+SBE_SRC_FILES = ${:!${SBE_SRC_DIRS:@path@ls ${path};@}!}
+
+SBE_SCRIPTS_TO_COPY = ${SBE_SRC_FILES:Nmakefile}
+SBE_SCRIPTS_PATHS = ${SBE_SCRIPTS_TO_COPY:p}
+
+SBE_COPY_COMMAND = \
+ ${SBE_SCRIPTS_PATHS:@file@cp -r ${file} ${SBE_SIMICS_PATH}; @}
+SBE_REMOVE_COMMAND = \
+ ${SBE_SCRIPTS_TO_COPY:@file@rm -rf ${SBE_SIMICS_PATH}${file}; @}
+
+copy_scripts:
+ mkdir -p ${SBE_SIMICS_PATH}
+ ${SBE_COPY_COMMAND}
+
+clobber_copy_scripts:
+ ${SBE_REMOVE_COMMAND}
diff --git a/src/tools/debug/simics/sbe_standalone.simics b/src/tools/debug/simics/sbe_standalone.simics
new file mode 100755
index 00000000..8fd3bdb0
--- /dev/null
+++ b/src/tools/debug/simics/sbe_standalone.simics
@@ -0,0 +1,2 @@
+echo "SBE standalone Tools"
+
diff --git a/src/tools/debug/simics/sbe_startup.simics b/src/tools/debug/simics/sbe_startup.simics
new file mode 100755
index 00000000..5d466a20
--- /dev/null
+++ b/src/tools/debug/simics/sbe_startup.simics
@@ -0,0 +1,14 @@
+echo "Attempting to register SBE Tools"
+
+# Load SBE debug tools.
+try {
+ $sbe_startup_path = (lookup-file sbfw/simics-debug-framework.py);
+ $sbe_script_location = (python "''.join(map('/'.__add__,\""+$sbe_startup_path+"\"[1:].split('/')[0:-1]))")
+ python "os.environ['SBE_TOOLS_PATH'] = \""+$sbe_script_location+"\""
+ echo $sbe_script_location;
+ run-python-file (lookup-file sbfw/simics-debug-framework.py)
+ # Set mailbox scratch registers so that the SBE starts in plck mode
+ # p9Proc0.proc_chip.invoke parallel_store SCOM 0x5003F "20000000_00000000" 64
+ # p9Proc0.proc_chip.invoke parallel_store SCOM 0x5003A "00000000_00000000" 64
+} except { echo "ERROR: Failed to load SBE debug tools." }
+
diff --git a/src/tools/debug/simics/simics-debug-framework.py b/src/tools/debug/simics/simics-debug-framework.py
new file mode 100755
index 00000000..87d3656b
--- /dev/null
+++ b/src/tools/debug/simics/simics-debug-framework.py
@@ -0,0 +1,88 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/debug/simics/simics-debug-framework.py $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+import os
+import os.path
+import subprocess
+import re
+import random
+import sys
+import imp
+testIstepAuto = imp.load_source("testIstepAuto", os.environ['SBE_TOOLS_PATH'] + "/testIstepAuto.py")
+err = False
+
+syms = {};
+
+def check_sbe_tools_path ():
+ global SBE_TOOLS_PATH
+ SBE_TOOLS_PATH = os.environ['SBE_TOOLS_PATH'];
+
+def register_sbe_debug_framework_tools():
+ check_sbe_tools_path ()
+ fillSymTable()
+ # Create command hook.
+ new_command("sbe-istep",testIstepAuto.sbe_istep_func,
+ args = [arg(int_t, "major"), arg(int_t, "minor")],
+ alias = "istep",
+ type = ["sbe-commands"],
+ short = "Runs the debug framework for istep ",
+ doc = "")
+ new_command("sbe-trace", collectTrace,
+ args = [arg(int_t, "procNr")],
+ alias = "strace",
+ type = ["sbe-commands"],
+ short = "Runs the debug framework for trace ",
+ doc = "")
+ print "SBE Debug Framework: Registered tool:", "sbe-istep"
+ print "SBE Debug Framework: Registered tool:", "sbe-trace"
+
+
+def fillSymTable():
+# symFile = os.environ['SBE_IMG_OUT_LOC'] + "/sbe.syms"
+ symFile = SBE_TOOLS_PATH + "/sbe.syms"
+# symFile = os.environ['sb'] + "/../obj/ppc/sbei/sbfw/simics/sbe.syms"
+ f = open( symFile, 'r')
+ for line in f:
+ words = line.split()
+ if( len( words ) == 4 ):
+ syms[words[3]] = [words[0], words[1]]
+
+def collectTrace ( procNr ):
+ fileName = "sbe_" + `procNr` + "_tracMERG"
+ cmd1 = "pipe \"p9Proc" + `procNr` + ".sbe.mibo_space.x 0x" + syms['g_pk_trace_buf'][0] + " 0x2028\" \"sed 's/^p:0x........ //g' | sed 's/ ................$//g' | sed 's/ //g' | xxd -r -p> ppetrace.bin\""
+ cmd2 = "shell \"" + SBE_TOOLS_PATH + "/ppe2fsp ppetrace.bin sbetrace.bin \""
+ cmd3 = "shell \"" + SBE_TOOLS_PATH + "/fsp-trace -s " + SBE_TOOLS_PATH + "/sbeStringFile sbetrace.bin >" + fileName + "\""
+ cmd4 = "shell \"" + "cat " + fileName + "\""
+
+ ( rc, out ) = quiet_run_command( cmd1, output_modes.regular )
+ if ( rc ):
+ print "simics ERROR running %s: %d "%( cmd1, rc )
+
+ SIM_run_alone( run_command, cmd2 )
+ SIM_run_alone( run_command, cmd3 )
+ SIM_run_alone( run_command, cmd4 )
+
+
+# Run the registration automatically whenever this script is loaded.
+register_sbe_debug_framework_tools()
+
diff --git a/src/tools/hooks/addCopyright b/src/tools/hooks/addCopyright
new file mode 100755
index 00000000..13867e7e
--- /dev/null
+++ b/src/tools/hooks/addCopyright
@@ -0,0 +1,1167 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: sbe/tools/hooks/addCopyright.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+# [+] 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
+#################################### ABOUT ####################################
+# Forked from: #
+# Author: Mark Jerde (mjerde@us.ibm.com) #
+# Date: Fri Mar 19 17:40:32 2010 UTC #
+# #
+# addCopyright will automatically insert appropriate copyright statements #
+# in source files following the IBM copyright guidelines (and templates) #
+# referenced below : #
+# FSP ClearCase Architecture #
+# Version 1.9 #
+# 10/12/2010 #
+# Editor: Alan Hlava #
+# #
+# Section 3.14.1 of the above doc has templates for different files #
+# #
+# NOTE: FSP uses the phrase "OCO Source materials" in their copyright #
+# block, which is classified as 'p1' . We will use the same #
+# classification here. #
+# NOTE: to list all files in src EXCEPT the build dir, run: #
+# make clean # remove autogenerated files #
+# find src -path 'src/build' -prune -o ! -type d -print | tr '\n' ' ' #
+# #
+# addCopyright does not support piping, but you can send these #
+# to a file, add "addCopyright update" to the beginning of the line, #
+# and run the file to update all #
+###############################################################################
+
+use strict;
+use warnings;
+use POSIX;
+use Getopt::Long;
+use File::Basename;
+use lib dirname (__FILE__);
+use Cwd;
+
+#------------------------------------------------------------------------------
+# Project-specific settings.
+#------------------------------------------------------------------------------
+my $ReleaseYear = `date +%Y`;
+chomp( $ReleaseYear );
+$ReleaseYear = $ENV{'DATE_OVERRIDE'} if defined $ENV{'DATE_OVERRIDE'};
+
+my $copyrightSymbol = "";
+# my $copyrightSymbol = "(C)"; # Uncomment if unable to use  character.
+
+# set by environment variable in project env.bash
+my $projectName = $ENV{'PROJECT_NAME'};
+my $copyrightPrefix = "Contributors Listed Below - ";
+my $copyrightStr = $copyrightPrefix."COPYRIGHT";
+my $projectRoot = $ENV{'SBEROOT'};
+# Relative path of import tree from project root
+my $importPrefix = $ENV{'IMPORT_REL_PATH'}."/";
+
+## note that these use single ticks so that the escape chars are NOT evaluated yet.
+my $OLD_DELIMITER_END = 'IBM_PROLOG_END';
+my $DELIMITER_END = 'IBM_PROLOG_END_TAG';
+my $DELIMITER_BEGIN = 'IBM_PROLOG_BEGIN_TAG';
+
+my $SOURCE_BEGIN_TAG = "\$Source:";
+my $SOURCE_END_TAG = "\$";
+
+# Desired License, set by environment variable in project env.bash
+my $LicenseFile = $ENV{'LICENSE'};
+use constant LICENSE_PROLOG => "LICENSE_PROLOG";
+
+#------------------------------------------------------------------------------
+# Contributer info
+#------------------------------------------------------------------------------
+
+# Constants for company's copyright
+# When adding a new company add constant here and to %fileContributorsCompany
+use constant IBM => 'International Business Machines Corp.';
+use constant GOOGLE => 'Google Inc.';
+
+# Create mapping for git contrubitors to companies
+my %fileContributorsCompany = (
+ "ibm.com" => IBM,
+ "ozlabs.org" => IBM,
+ "google.com" => GOOGLE,
+ "Google Shared Technology" => GOOGLE,
+);
+
+#------------------------------------------------------------------------------
+# Constants
+#------------------------------------------------------------------------------
+use constant RC_INVALID_PARAMETERS => 1;
+use constant RC_NO_COPYRIGHT_BLOCK => 2;
+use constant RC_BAD_CONTRIBUTORS_BLOCK => 3;
+use constant RC_INVALID_FILETYPE => 4;
+use constant RC_DIFFERS_FROM_LICENSE_PROLOG => 5;
+use constant RC_NO_LICENSE_PROLOG_FILE => 6;
+
+#------------------------------------------------------------------------------
+# Global Vars
+#------------------------------------------------------------------------------
+my $opt_help = 0;
+my $opt_debug = 0;
+my $operation = "";
+my $opt_logfile = "";
+
+my $DelimiterBegin = "";
+my $CopyrightBlock = "";
+my $DelimiterEnd = "";
+my $CopyRightString = "";
+my $copyright_check = 0;
+
+my $TempFile = "";
+my @Files = ();
+
+my $rc = 0;
+
+# NOTE: $OLD_DELIMITER_END is a subset of $DELIMITER_END so must match
+# $DELIMITER_END first in order to return the entire string.
+my $g_end_del_re = "($DELIMITER_END|$OLD_DELIMITER_END)";
+my $g_prolog_re = "($DELIMITER_BEGIN)((.|\n)+?)$g_end_del_re";
+
+#######################################################################
+# Main
+#######################################################################
+if (scalar(@ARGV) < 2)
+{
+ ## needs at least one filename and an operation as a parameter
+ usage();
+}
+
+
+my @SaveArgV = @ARGV;
+#------------------------------------------------------------------------------
+# Parse optional input arguments
+#------------------------------------------------------------------------------
+GetOptions( "help|?" => \$opt_help,
+ "validate" => sub { $operation="validate"; },
+ "update" => sub { $operation="update"; },
+ "copyright-check" => \$copyright_check,
+ "log-failed-files=s" => \$opt_logfile,
+ "debug" => \$opt_debug,
+ );
+
+## scan through remaining args and store all files in @Files
+## check for old-type parms, just in case
+foreach ( @ARGV )
+{
+ ## print $_;
+ if ( m/^debug$/ ) { $opt_debug = 1; next; }
+ if ( m/^update$/ ) { $operation = $_; next; }
+ if ( m/^validate$/ ) { $operation = $_; next; }
+
+ push @Files, $_ ;
+}
+
+
+if ( $opt_debug )
+{
+ print STDERR __LINE__, " : ---- DEBUG -----\n";
+ print STDERR "help = $opt_help\n";
+ print STDERR "debug = $opt_debug\n";
+ print STDERR "operation = $operation\n";
+ print STDERR "log-failed-files = $opt_logfile\n";
+
+ ## dump files specified
+ print STDERR "Files:\n";
+ print STDERR join( ' ', @Files ), "\n";
+
+ print STDERR "ReleaseYear = $ReleaseYear\n";
+
+ print "\n";
+}
+
+if ( $operation eq "" )
+{
+ print STDOUT "No operation specified\n";
+ usage();
+ exit RC_INVALID_PARAMETERS;
+}
+
+if ( ( $opt_logfile ne "" )
+ ## && ( $operation eq "validate" )
+ )
+{
+ my $logdate = `date +%Y-%m-%d:%H%M`;
+ chomp $logdate;
+ open( LOGFH, "> $opt_logfile" ) or die "ERROR $?: Failed to open $opt_logfile: $!";
+ print LOGFH "## logfile generated $logdate from command line:\n";
+ print LOGFH $0, " ", join( ' ', @SaveArgV );
+ print LOGFH "\nFAILING files:\n";
+}
+
+########################################################################
+## MAIN
+########################################################################
+# Loop through all files and process.
+foreach ( @Files )
+{
+
+ ## clear global vars
+ $DelimiterBegin = "";
+ $CopyrightBlock = "";
+ $DelimiterEnd = "";
+ $CopyRightString = "";
+ $rc = 0;
+
+
+ ## get filetype
+ my $filetype = filetype($_);
+ print STDOUT "File $_: Type $filetype\n";
+
+ ## set Temporary file name.
+ $TempFile = "$_.gitCPYWRT";
+ if ( $opt_debug ) { print STDERR __LINE__, ": Temporary file name = $TempFile\n"; }
+
+ ##
+ ## Special case is this file, just return 0 and add copyright manually.
+ ##
+ if ( m/addCopyright/ )
+ {
+ print STDOUT "---------------------------------------------------------\n";
+ print STDOUT "Skipping special case file: $_\n";
+ print STDOUT " Please add the copyright prolog manually.\n";
+ print STDOUT "---------------------------------------------------------\n";
+ next;
+ }
+
+ ##
+ ## Gerrit submissions can include deleted files, just warn and continue
+ if ( ! -e $_ )
+ {
+ print STDOUT "---------------------------------------------------------\n";
+ print STDOUT "Skipping deleted file: $_\n";
+ print STDOUT "---------------------------------------------------------\n";
+ next;
+ }
+
+ ##
+ ## Unknown files are valid, but should generate a warning.
+ if ("Unknown" eq $filetype)
+ {
+ print STDOUT "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
+ print STDOUT "WARNING:: File $_ :Unknown Filetype: $filetype\n";
+ print STDOUT " Skipping this file and continuing.\n";
+ print STDOUT " Please add the copyright prolog manually.\n";
+ print STDOUT "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
+
+ next;
+ }
+
+ ##
+ ## text files are valid, but should generate a warning.
+ if (("txt" eq $filetype) || "Initfile" eq $filetype)
+ {
+ print STDOUT "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
+ print STDOUT "WARNING:: File $_ : Filetype: $filetype\n";
+ print STDOUT " Skipping this file and continuing.\n";
+ print STDOUT " If needed, Please add the copyright \n";
+ print STDOUT " prolog manually.\n";
+ print STDOUT "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
+
+ next;
+ }
+
+ ##
+ ## Check if any parent directory below $projectRoot has a LICENSE_PROLOG file
+ ## Backtrack from the directory where the file lives and find the first
+ ## custom LICENSE_PROLOG file.
+ my $path = cwd."/".$_;
+ do
+ {
+ # Remove everything after last slash
+ $path =~ s|/[^/]*$||;
+ # Check if path has LICENSE_PROLOG file
+ my $custom_license_file = $path."/".LICENSE_PROLOG;
+ if (-e $custom_license_file)
+ {
+ # Set LicenseFile to closest custom LICENSE_PROLOG to file.
+ $LicenseFile = $custom_license_file;
+ # Exit loop, 'last' breaks out of both loops.
+ $path = $projectRoot;
+ }
+ } while ($path ne $projectRoot);
+
+ $CopyrightBlock = extractCopyrightBlock( $_ );
+
+ ##
+ ## validate the file.
+ ## if $logfile exists, print failing filename to $logfile and
+ ## keep going.
+ ## Otherwise, exit with $rc
+ ##
+ if ( $operation =~ m/validate/i )
+ {
+ $rc = validate( $_ );
+ if ( $rc )
+ {
+ print STDOUT "$_ FAILED copyright validation: $rc \n";
+ if ( $opt_logfile ne "" )
+ {
+ print LOGFH "$_ # FAILED $rc \n";
+ }
+ else
+ {
+ exit $rc;
+ }
+ }
+
+ ## continue to next file
+ next;
+ } ## endif validate
+
+ ##
+ ## update
+ ##
+ if ($operation =~ m/update/i)
+ {
+ $rc = update( $_, $filetype );
+ if ( $rc )
+ {
+ print STDOUT "$_ FAILED copyright update: $rc \n";
+ exit $rc;
+ }
+
+ ## continue to next file
+ next;
+ } ## endif update
+
+} # end foreach
+
+if ( $opt_logfile ne "" )
+{
+ close( LOGFH );
+}
+
+#########################################################################
+## Subroutines
+#########################################################################
+
+#######################################
+## usage: print usage and quit
+#######################################
+sub usage
+{
+ print STDOUT "Usage: addCopyright { update | validate } \n";
+ print STDOUT " [ --log-failed-files ]\n";
+ print STDOUT " [ --debug ] \n";
+ print STDOUT " file1 file2 ...\n";
+
+}
+
+#######################################
+## validate the file
+## param[in] $filename to validate
+## returns 0 success, nonzero failure
+## See constants above for values of failure
+#######################################
+sub validate
+{
+ my ( $filename ) = @_;
+ my $rc = 0;
+
+ if ( $CopyrightBlock eq "" )
+ {
+ print STDOUT "WARNING: No copyright block.\n";
+ return RC_NO_COPYRIGHT_BLOCK;
+ }
+
+ $rc = checkCopyrightBlock( $CopyrightBlock, $filename);
+
+ # good file
+ return $rc;
+}
+
+##
+## @sub update the copyright block.
+##
+## @param[in] filename
+## @param[in] filetype
+##
+## @return success or failure (currently only return success)
+##
+sub update
+{
+ my ( $filename, $filetype ) = @_;
+ my $olddelimiter = 0;
+ my $localrc = 0;
+ $localrc = validate( $filename );
+
+ if ( $localrc != 0 )
+ {
+ print STDOUT "Copyright Block check returned $localrc , fixing...\n";
+
+ if ( $localrc != RC_NO_COPYRIGHT_BLOCK )
+ {
+ if ( $opt_debug) { print STDERR __LINE__, ": remove old copyright block...\n"; }
+ removeCopyrightBlock( $filename, $filetype );
+ }
+
+ if ($opt_debug) { print STDERR __LINE__, ": Add empty copyright block...\n"; }
+ addEmptyCopyrightBlock( $filename, $filetype, $localrc );
+
+ if ( $opt_debug ) { print STDERR __LINE__, ": fill in new copyright block...\n"; }
+ fillinEmptyCopyrightBlock( $filename, $filetype);
+ }
+
+ ## return OK by default.
+ return 0;
+}
+
+
+#####################################
+## Analyze file and return a text string of the file type
+#####################################
+sub filetype
+{
+ my $filename = shift;
+ my $fileinfo = `file $filename | sed 's/^.*: //'`;
+ chomp $fileinfo;
+
+ # Sorted by anticipated frequency of occurrence.
+ if ( $filename =~ m/\.xml$/i )
+ # Added XML file to the top of the list because some comments in
+ # an XML file cause older versions of 'file' to incorrectly return
+ # "ASCII C++ program text" even though the file is obviously XML.
+ # Specifically we are seeing "<!-- // ..." cause this trouble.
+ {
+ return "xml"
+ }
+ if ( $filename =~ m/\.txt$/i )
+ {
+ return "txt"
+ }
+ if ( $filename =~ m/\.initfile$/i )
+ {
+ return "Initfile"
+ }
+ if ( ( $filename =~ m/\.[cht]$/i )
+ ||( $filename =~ m/\.[cht]\+\+$/i )
+ ||( $filename =~ m/\.[cht]pp$/i )
+ ||( $filename =~ m/\.inl$/ ) # inline C functions
+ ||( $filename =~ m/\.y$/ ) # yacc
+ ||( $filename =~ m/\.lex$/ ) # flex
+ ||( $fileinfo =~ m/c program text/i )
+ ||( $fileinfo =~ m/c\+\+ program text/i )
+ ||( $fileinfo =~ m/c source/i )
+ ||( $fileinfo =~ m/c\+\+ source/i )
+ )
+ {
+ return "C";
+ }
+ if ( ( $filename =~ m/\.pl$/ )
+ ||( $filename =~ m/\.perl$/ )
+ ||( $filename =~ m/\.pm$/ )
+ ||( $fileinfo =~ m/perl.*script.*text executable/i) )
+ {
+ return "Perl";
+ }
+ if ($filename =~ m/\.s$/i)
+ {
+ return "Assembly";
+ }
+ if (($filename =~ m/Makefile$/i) or
+ ($filename =~ m/\.mk$/i))
+ {
+ return "Makefile";
+ }
+ if ( $filename =~ m/\.am$/i )
+ {
+ return "Automake";
+ }
+ if ( ($filename =~ m/configure\.ac$/i)
+ ||($filename =~ m/Makefile\.in$/i) )
+ {
+ return "Autoconf";
+ }
+ if ( ( $filename =~ m/\.[kc]{0,1}sh$/i )
+ ||( $filename =~ m/\.bash$/i )
+ ||( $fileinfo =~ m/shell script/i )
+ ||( $fileinfo =~ m/^a \/bin\/[af]sh( -x|) *script text( executable|)$/ )
+ ||( $fileinfo eq "Bourne shell script text")
+ ||( $fileinfo eq "Bourne shell script text executable")
+ ||( $fileinfo eq "Bourne-Again shell script text")
+ ||( $fileinfo eq "Bourne-Again shell script text executable") )
+ {
+ return "Shellscript";
+ }
+ if ( $filename =~ m/\.py$/ )
+ {
+ return "Python";
+ }
+ if ( $filename =~ m/\.tcl$/ )
+ {
+ return "Tcl";
+ }
+ if ( $filename =~ m/\.x$/ )
+ {
+ return "RPC";
+ }
+ if ( ($filename =~ m/^commitinfo$/)
+ ||($filename =~ m/^checkoutlist$/)
+ ||($filename =~ m/^loginfo$/) )
+ {
+ return "CVS";
+ }
+ if ( $filename =~ m/\.emx$/ )
+ {
+ # Used by Rational Software Architect. modelling file.
+ return "EmxFile";
+ }
+ if ( $filename =~ m/\.mof$/ )
+ {
+ return "MofFile";
+ }
+ if ( $filename =~ m/\.ld$/ )
+ {
+ return "LinkerScript";
+ }
+ if ( $filename =~ m/\.rule$/i )
+ {
+ return "PrdRuleFile"
+ }
+ if ( ( $filename =~ m/\.emx$/i )
+ ||( $filename =~ m/\.odt$/i )
+ ||( $filename =~ m/\.gitignore$/i )
+ ||( $filename =~ m/\.conf$/i )
+ ||( $filename =~ m/\.lidhdr$/i )
+ ||( $filename =~ m/\.vpdinfo$/i )
+ ||( $filename =~ m/\.pdf$/i )
+
+ )
+ {
+ # Known, but we can't deal with it so call it unknown.
+ return "Unknown";
+ }
+ if ( -f $filename )
+ {
+ my $type = `grep "\\\$Filetype:.*\\\$" $filename`;
+ if ( $type =~ m/\$Filetype:([^\$]*)\$/ )
+ {
+ $type = $1;
+ }
+ $type =~ s/^\s*//;
+ $type =~ s/\s*$//;
+ my %knownTypes = qw/Assembly Assembly Automake Automake Autoconf Autoconf C C CVS CVS EmxFile EmxFile LinkerScript LinkerScript Makefile Makefile MofFile MofFile Perl Perl PrdRuleFile PrdRuleFile Python Python RPC RPC Shellscript Shellscript Tcl Tcl/;
+ return $type if defined($knownTypes{$type});
+ }
+ { # Other random files containing non-printable characters.
+ my $file = `cat $filename`;
+ if ( $file =~ m/([^\x20-\x7E\s])/ )
+ {
+ return "Unknown";
+ }
+ }
+ return "Unknown";
+}
+
+########################################################################
+## extractCopyrightBlock
+##
+## param[in] $infile - filename
+##
+## param[out] returns block or ""
+########################################################################
+sub extractCopyrightBlock
+{
+ my ( $infile ) = shift;
+
+ # Extract the prolog
+ my $prolog = `sed -n \"/$DELIMITER_BEGIN/,/$DELIMITER_END/p\" $infile`;
+ # Critical to remove newline for validate step
+ chomp($prolog);
+
+ ## As long as we're here extract the copyright string within the block
+ ## and save it to a global var
+ $CopyRightString = $1 if ( $prolog =~ /(^.*$copyrightStr.*$)/m );
+
+ return $prolog;
+}
+
+
+#######################################
+## Check Copyright Block
+##
+## @param[in] - Copyright block
+## @parma[in] - filename
+##
+## @return 0 if success, nonzero otherwise
+#######################################
+use File::Temp;
+sub checkCopyrightBlock
+{
+ my ( $block, $filename ) = @_;
+
+ ## Check if custom LICENSE_PROLOG
+ if ($LicenseFile ne "")
+ {
+ ## Get desired license
+ my $license_prolog = genCopyrightBlock($filename, filetype($filename));
+
+ if ($block ne $license_prolog)
+ {
+ # Print strings to files to use unix diff, do not need to add the
+ # File::Diff module this way.
+ my ($blockHndl, $blockFile) = File::Temp::tempfile();
+ my ($licenseHndl, $licenseFile)= File::Temp::tempfile();
+ print $blockHndl $block;
+ print $licenseHndl $license_prolog;
+ close($blockHndl);
+ close($licenseHndl);
+
+ print STDOUT "\nERROR> Prolog not correct for $filename.\n";
+ print STDOUT "To fix run: git show --pretty=\"format:\" --name-only | xargs addCopyright update\n";
+ print STDOUT "\nDiff:\n";
+ print STDOUT `diff $blockFile $licenseFile`;
+ my $relLicensePath = $LicenseFile;
+ $relLicensePath =~ s/$projectRoot//;
+ print STDOUT "\nWARNING: Copyright block does not match LICENSE_PROLOG file found at $relLicensePath\n";
+ system("rm -f $blockFile $licenseFile");
+ return RC_DIFFERS_FROM_LICENSE_PROLOG;
+ }
+ }
+ else
+ {
+ print STDOUT "WARNING: Missing LICNESE_PROLOG file in directory structure\n";
+ return RC_NO_LICENSE_PROLOG_FILE;
+ }
+
+ return 0;
+}
+
+sub createYearString
+{
+ my ( $filename ) = @_;
+ my $yearstr = "";
+ my @years = ();
+
+ ## Analyse the CopyRightString for begin and end years - this is for old
+ ## files that are checked in from FSP. In this case the earliest
+ ## year will be before it was checked into git . We have to construct
+ ## a yearstring based on the earliest year.
+ if ( $CopyRightString =~ m/$copyrightStr/ )
+ {
+ @years = ( $CopyRightString =~ /([0-9]{4})/g );
+ }
+ push @years, $ReleaseYear; # Add the current year.
+
+ ##
+ ## Make a call to git to find the earliest commit date of the file
+ ## new files will not have a log, so the "git log" call above will
+ # return nothing.
+ ## Push any year we find onto the @years array
+ my $cmd = "git log -- $filename | grep Date: | tail -n 1";
+ ## print "run $cmd\n";
+ my @logstrings = split( " ", `$cmd` );
+ if ( $? ) { die "ERROR $? : Could not run $cmd $!\n"; }
+
+ if ( scalar(@logstrings) >= 5 )
+ {
+ push @years, $logstrings[5] ;
+ }
+
+ ## sort and remove duplicates by loading it into a hash
+ my %temphash;
+ @temphash{@years} = ();
+ my @outyears = sort keys %temphash;
+
+ if ( $opt_debug )
+ { print STDERR __LINE__, ": years: ", join( ',', @outyears ), "\n"; }
+
+ ## lowest year, which may be the only one.
+ $yearstr = $outyears[0] ;
+
+ ## if there is more than one index then also output the highest one.
+ if ( $#outyears > 0 )
+ {
+ # A '-' is preferred but CMVC uses ',' so using ','.
+ $yearstr .= ",$outyears[$#outyears]";
+ }
+
+
+ return $yearstr;
+}
+
+###################################
+## Helper function for removeCopyrightBlock()
+###################################
+sub removeProlog
+{
+ my ( $data, $begin_re, $end_re ) = @_;
+
+ $data =~ s/(\n?)(.*?$begin_re.*$g_prolog_re(.|\n)*?$end_re.*?\n)/$1/;
+
+ return $data;
+}
+
+###################################
+## remove old Copyright Block in preparation for making a new one.
+## makes up a debug file named "<filename>.remove"
+###################################
+sub removeCopyrightBlock
+{
+ my ( $filename, $filetype ) = @_ ;
+ my $data = "" ;
+
+ ## Modify file in place with temp file Perl Cookbook 7.8
+ my $savedbgfile = "$filename.remove";
+ system( "cp -p $filename $TempFile" ); ## preserve file permissions
+ open( INPUT, "< $filename" ) or die " $? can't open $filename: $!" ;
+ read( INPUT, $data, -s INPUT ) or die "ERROR $? : reading $filename: $!";
+ close( INPUT ) or die " $? can't close $filename: $!" ;
+
+ open( OUTPUT, "> $TempFile" ) or die " $? can't open $TempFile: $!" ;
+ select( OUTPUT ); ## new default filehandle for print
+
+ ## preprocess to get rid of OLD_DELIMITER_END
+ $data =~ s/$OLD_DELIMITER_END(\s+?)/$DELIMITER_END$1/;
+
+ if ( "C" eq $filetype )
+ {
+ ## pre-process this for /* */ comments
+ $data = removeProlog( $data, '\/\*', '\*\/' );
+
+ ## Now apply filter for // comments
+ $data = removeProlog( $data, '\/\/', '' );
+ }
+ elsif ( ("RPC" eq $filetype) or
+ ("LinkerScript" eq $filetype)
+ )
+ {
+ $data = removeProlog( $data, '\/\*', '\*\/' );
+ }
+ elsif ( $filetype eq "xml" )
+ {
+ $data = removeProlog( $data, '<!--', '-->' );
+ }
+ elsif ( "Assembly" eq $filetype )
+ {
+ $data = removeProlog( $data, '\#', '' );
+ }
+ elsif ( ("Autoconf" eq $filetype) or
+ ("Automake" eq $filetype) or
+ ("CVS" eq $filetype) or
+ ("Makefile" eq $filetype) or
+ ("Perl" eq $filetype) or
+ ("PrdRuleFile" eq $filetype) or
+ ("Python" eq $filetype) or
+ ("Shellscript" eq $filetype) or
+ ("Tcl" eq $filetype)
+ )
+ {
+ # Don't wipe the the '#!' line at the top.
+ $data = removeProlog( $data, '\#', '' );
+ }
+ else
+ {
+ print STDOUT "ERROR: Don't know how to remove old block from $filetype file.\n";
+ close OUTPUT;
+ return RC_INVALID_FILETYPE;
+ }
+
+ print OUTPUT $data;
+
+ ## finish up the files
+ close( OUTPUT ) or die " $? can't close $TempFile: $!" ;
+ rename( $filename, "$savedbgfile" ) or die " $? can't rename $filename: $!" ;
+ rename( $TempFile, $filename ) or die " $? can't rename $TempFile: $!" ;
+ if ( !$opt_debug )
+ {
+ ## leave the files around for debug
+ unlink( $savedbgfile ) or die " $? can't delete $savedbgfile: $!";
+
+ }
+}
+
+###################################
+## Add an empty copyright block to the file, for example (C/C++ files):
+##
+## // IBM_PROLOG_BEGIN_TAG IBM_PROLOG_END_TAG
+##
+## - The block will be filled-in in the next step.
+##
+## @param[in] - filename to modify
+## @param[in] - filetype
+## @param[in] - returncode from validate
+##
+## @return none
+##
+## - Makes up a debug file called "<filename>.empty"
+##################################
+sub addEmptyCopyrightBlock
+{
+ my ( $filename, $filetype, $validaterc ) = @_;
+ my $line;
+
+ ## Modify file in place with temp file Perl Cookbook 7.8
+ my $savedbgfile = "$filename.empty";
+ system( "cp -p $filename $TempFile" ) ; ## preserve permissions
+ open( INPUT, "< $filename" ) or die " $? can't open $filename: $!" ;
+ open( OUTPUT, "> $TempFile" ) or die " $? can't open $TempFile: $!" ;
+ select( OUTPUT ); ## new default filehandle for print
+
+ if (("Autoconf" eq $filetype) or
+ ("Automake" eq $filetype) or
+ ("CVS" eq $filetype) or
+ ("Perl" eq $filetype) or
+ ("Python" eq $filetype) or
+ ("Shellscript" eq $filetype) or
+ ("Tcl" eq $filetype))
+ {
+ ## All files with a "shebang" at the beginning
+ $line = <INPUT>;
+ # Keep the '#!' line at the top.
+ ## The following says : if the first line is a "shebang" line
+ ## (e.g. "#!/usr/bin/perl"), then print it _before_ the copyright
+ ## block, otherwise (the unless line), print it _after_ the copyright
+ ## block.
+ if ($line =~ m/^#!/)
+ {
+ print OUTPUT $line;
+ }
+ print OUTPUT "$DELIMITER_BEGIN $DELIMITER_END\n";
+ unless ($line =~ m/^#!/)
+ {
+ print OUTPUT $line;
+ }
+ }
+ else
+ {
+ print OUTPUT "$DELIMITER_BEGIN $DELIMITER_END\n";
+ }
+
+ # Copy rest of file
+ while (defined($line = <INPUT>))
+ {
+ print OUTPUT $line;
+ }
+
+ ## finish up the files
+ close( INPUT ) or die " $? can't close $filename: $!" ;
+ close( OUTPUT ) or die " $? can't close $TempFile: $!" ;
+ rename( $filename, "$savedbgfile" ) or die " $? can't rename $filename: $!" ;
+ rename( $TempFile, $filename ) or die " $? can't rename $TempFile: $!" ;
+ if ( !$opt_debug )
+ {
+ ## leave the files around for debug
+ unlink( $savedbgfile ) or die " $? can't delete $savedbgfile: $!";
+ }
+}
+
+############################################
+## Helper functions for fillinEmptyCopyrightBlock()
+############################################
+sub addPrologComments
+{
+ my ( $data, $begin, $end ) = @_;
+
+ my @lines = split( /\n/, $data );
+
+ $data = '';
+ for my $line ( @lines )
+ {
+ # If there is an block comment end tag, fill the end of the line with
+ # spaces.
+ if ( $end )
+ {
+ my $max_line_len = 70;
+ my $len = length($line);
+ if ( $len < $max_line_len )
+ {
+ my $fill = ' ' x ($max_line_len - $len);
+ $line .= $fill;
+ }
+ }
+
+ # NOTE: CMVC prologs with inline comments will have a single trailing
+ # space at the end of the line. This is undesirable for most
+ # developers so it will not be added.
+ if ( $line =~ m/$DELIMITER_BEGIN/)
+ {
+ $line = "$line $end" if ( $end );
+ $line = "$begin $line\n";
+ }
+ elsif ( $line =~ m/$DELIMITER_END/ )
+ {
+ $line = "$line $end" if ( $end );
+ $line = "$begin $line";
+ }
+ else
+ {
+ if ( not $end and not $line )
+ {
+ # Compensate for blank lines with no end delimeter.
+ $line = "$begin\n";
+ }
+ else
+ {
+ $line = "$begin $line";
+ $line = "$line $end" if ( $end );
+ $line = "$line\n";
+ }
+ }
+
+ $data .= $line;
+ }
+
+ return $data;
+}
+
+############################################
+## Generates final copyright block
+##
+## @parma[in] filename
+##
+## @return final copyright block string
+############################################
+sub genCopyrightBlock
+{
+ my ($filename, $filetype) = @_;
+
+ my $copyrightYear = createYearString( $filename );
+
+ # Get copyright contributors based on hash so no duplicates
+ my %fileContributors = getFileContributors( $filename );
+ my $copyright_Contributors = "";
+
+ foreach my $key (sort keys %fileContributors)
+ {
+ $copyright_Contributors .= "[+] ".$key."\n";
+ }
+
+ ## Get desired license
+ my $LicenseContent = "";
+ open(LICENSE, "< $LicenseFile") or die " $? can't open $LicenseFile: $!" ;
+ while (my $line = <LICENSE>)
+ {
+ my $evalLine = eval "qq($line)";
+ $LicenseContent .= $evalLine;
+ }
+ close(LICENSE);
+
+ ## define the final copyright block template here.
+ my $IBMCopyrightBlock = <<EOF;
+$DELIMITER_BEGIN
+$LicenseContent
+$DELIMITER_END
+EOF
+
+ if ("Assembly" eq $filetype)
+ {
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '#', '');
+ }
+ elsif ( ("Makefile" eq $filetype) or
+ ("PrdRuleFile" eq $filetype) )
+ {
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '#', '');
+ }
+ elsif (("Autoconf" eq $filetype) or
+ ("Automake" eq $filetype) or
+ ("CVS" eq $filetype) or
+ ("Perl" eq $filetype) or
+ ("Python" eq $filetype) or
+ ("Shellscript" eq $filetype) or
+ ("Tcl" eq $filetype))
+ {
+ ## all files with a "shebang"
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '#', '');
+ }
+ elsif ( "C" eq $filetype )
+ {
+ ## lex files are classified as C, but do not recognize '//' comments
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '/*', '*/');
+ }
+ elsif ( ("RPC" eq $filetype) or
+ ("LinkerScript" eq $filetype)
+ )
+ {
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '/*', '*/');
+ }
+ elsif ("EmxFile" eq $filetype)
+ {
+ # Not yet formatted correctly for EmxFile needs, but should coexist.
+ $IBMCopyrightBlock = "$DELIMITER_BEGIN IBM Confidential OCO Source Materials (C) Copyright IBM Corp. $copyrightYear The source code for this program is not published or otherwise divested of its trade secrets, irrespective of what has been deposited with the U.S. Copyright Office. $DELIMITER_END";
+ }
+ elsif ("MofFile" eq $filetype)
+ {
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '//', '');
+ }
+ elsif ( "xml" eq $filetype)
+ {
+ $IBMCopyrightBlock = addPrologComments($IBMCopyrightBlock, '<!--', '-->');
+ }
+ else
+ {
+ print STDOUT "ERROR: Can\'t handle filetype: $filetype\n";
+ return RC_INVALID_FILETYPE;
+ }
+
+ return $IBMCopyrightBlock;
+}
+
+############################################
+## fill in the empty copyright block
+## Copyright guidelines from:
+## FSP ClearCase Architecture
+## Version 1.9
+## 10/12/2010
+## Editor: Alan Hlava
+##
+## Section 3.14.1 has templates for different files
+##
+############################################
+sub fillinEmptyCopyrightBlock
+{
+ my ( $filename, $filetype ) = @_;
+
+ my $copyrightYear = createYearString( $filename );
+
+ ## define the final copyright block template here.
+ my $IBMCopyrightBlock = genCopyrightBlock($filename,$filetype);
+
+ ## Modify file in place with temp file Perl Cookbook 7.8
+ my $savedbgfile = "$filename.fillin";
+ system( "cp -p $filename $TempFile" ); ## preserve file permissions
+ open( INPUT, "< $filename" ) or die " $? can't open $filename: $!" ;
+ my $newline;
+ my $lines = "";
+ while ( defined($newline = <INPUT>) ) { $lines .= $newline; }
+
+ # Replace existing block with the current content.
+ $lines =~ s/$DELIMITER_BEGIN[^\$]*$DELIMITER_END/$IBMCopyrightBlock/s;
+
+ open( OUTPUT, "> $TempFile" ) or die " $? can't open $TempFile: $!" ;
+ select( OUTPUT ); ## new default filehandle for print
+ print OUTPUT $lines;
+
+ ## finish up the files
+ close( INPUT ) or die " $? can't close $filename: $!" ;
+ close( OUTPUT ) or die " $? can't close $TempFile: $!" ;
+ rename( $filename, "$savedbgfile" ) or die " $? can't rename $filename: $!" ;
+ rename( $TempFile, $filename ) or die " $? can't rename $TempFile: $!" ;
+ if ( !$opt_debug )
+ {
+ ## leave the files around for debug
+ unlink( $savedbgfile ) or die " $? can't delete $savedbgfile: $!";
+ }
+}
+
+#######################################
+## Gets file contirbutors based on git log of a file
+##
+## @parma[in] filename
+##
+## @return hash of contributors (key,value) => (name/company, 1)
+#######################################
+sub getFileContributors
+{
+ my ( $filename ) = @_;
+ # Create a "set like" hash for file contributors to handle duplicates
+ # so key is the only important information
+ my %fileContributors = ();
+
+ # Check file for company Origin
+ my $gitDomain = `git log --follow --find-copies-harder -C85% -M85% -- $filename | grep Origin: | sort | uniq`;
+ my @gitDomain = split('\n', $gitDomain);
+ foreach my $origin (@gitDomain)
+ {
+ chomp($origin);
+ # Remove all characters through word "Origin:"
+ $origin =~ s/[^:]*\://;
+ # Remove white space after colon
+ $origin =~ s/^\s+//;
+ if (exists($fileContributorsCompany{$origin}))
+ {
+ # Add company info for copyright contribution
+ $fileContributors{$fileContributorsCompany{$origin}} = 1;
+ }
+ }
+
+ # Check file for all contributors
+ my $gitAuthors = `git log --follow --find-copies-harder -C85% -M85% --pretty="%aN <%aE>" -- $filename | sort | uniq`;
+ my @gitAuthors = split('\n', $gitAuthors);
+
+ # Get commit's author
+ # # If running copyright_check run 'git log' as a commit is not taking place
+ # # Else we currently have no way of getting the current author. Because
+ # # this is a pre-commit hook, the commit staged to be committed does not
+ # # show up in 'git log' until commit has completed. We cannot look up
+ # # current user's info because the user pushing the commit may not be
+ # # the author.
+
+ if($copyright_check)
+ {
+ my $curAuthorEmail = `git log -n1 --pretty=format:"%aN <%aE>"`;
+ chomp($curAuthorEmail);
+ push(@gitAuthors, $curAuthorEmail);
+ }
+ # Internal mirror, add IBM as contributor
+ elsif (defined $ENV{'MIRROR'})
+ {
+ push(@gitAuthors, "\@ibm.com>");
+ }
+
+ foreach my $contributor (@gitAuthors)
+ {
+ my $companyExists = 0;
+ chomp($contributor);
+ # Grab company domain out of contributor's email
+ my $domain = substr ($contributor, index($contributor, '@') + 1, -1);
+
+ # Due to multiple prefixes for IBM like us, in, linux, etc will try
+ # removing characters up to each period (.) until correct domain
+ # address found
+ my @domainSections = split(/\./,$domain);
+ for (my $i = 0; $i < @domainSections; $i++)
+ {
+ if (exists($fileContributorsCompany{$domain}))
+ {
+ $companyExists = 1;
+ last;
+ }
+ # Remove all characters upto & including the first period (.) seen
+ $domain =~ s/[^.]*\.//;
+ }
+
+ #Check if contributor's company exists
+ if ($companyExists)
+ {
+ # Add company info for copyright contribution
+ $fileContributors{$fileContributorsCompany{$domain}} = 1;
+ }
+ else
+ {
+ my $name = substr ($contributor, 0, index($contributor, '<') -1);
+ if($name)
+ {
+ # Add individual info for copyright contribution
+ $fileContributors{$name} = 1;
+ }
+ else
+ {
+ die("Cannot find name of contributor in git commit");
+ }
+ }
+ }
+ return %fileContributors;
+}
diff --git a/src/tools/hooks/gerrit-hostname b/src/tools/hooks/gerrit-hostname
new file mode 100755
index 00000000..58c68d63
--- /dev/null
+++ b/src/tools/hooks/gerrit-hostname
@@ -0,0 +1,78 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/gerrit-hostname $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+## Usage
+# It is imperative that there are no prints other than the die command or
+# "export GERRIT_SRV=$host" as this script is evaluated by env.bash and not
+# called directly
+
+use strict;
+
+my $homeDir = $ENV{'HOME'};
+my $sshConfigFile = $homeDir."/.ssh/config";
+# If the server changes location these will change
+my $gerritHostname = "ralgit01.raleigh.ibm.com";
+my $gerritPort = "29418";
+
+open(CONFIG, "< $sshConfigFile") or die " $? can't open $sshConfigFile: $!" ;
+
+my $host = "";
+my $hostname = "";
+my $port = "";
+while (my $line = <CONFIG>)
+{
+ # Whitespace after each constant is important
+ if ($line =~ m/^Host [^\s]/)
+ {
+ ($host) = $line =~ m/^Host (.*?)\s/
+ }
+ elsif ($line =~ m/Hostname [^\s]/)
+ {
+ ($hostname) = $line =~ m/^*Hostname (.*)/;
+ }
+ elsif ($line =~ m/Port [^\s]/)
+ {
+ ($port) = $line =~ m/^*Port (.*)/;
+ }
+
+ # Check if we found the gerrit host name
+ if ($host ne "" &&
+ $hostname eq $gerritHostname &&
+ $port eq $gerritPort)
+ {
+ last;
+ }
+}
+close(CONFIG);
+
+if ($host eq "")
+{
+ die "Error> Could not find gerrit host in $sshConfigFile";
+}
+else
+{
+ # Set gerrit server env variable by returning command to env.bash
+ print "export GERRIT_SRV=$host\n";
+}
diff --git a/src/tools/hooks/post-commit b/src/tools/hooks/post-commit
new file mode 100755
index 00000000..21751582
--- /dev/null
+++ b/src/tools/hooks/post-commit
@@ -0,0 +1,32 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/post-commit $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+# NOTE: pre-commit hook and its associated helper functions are all
+# maintained same as that of Hoostboot except for minor changes to
+# suit the PPE environment.
+
+if [ -z $MIRROR ]; then
+ $TOOLSDIR/verify-commit
+fi
diff --git a/src/tools/hooks/pre-commit b/src/tools/hooks/pre-commit
new file mode 100755
index 00000000..9e05432f
--- /dev/null
+++ b/src/tools/hooks/pre-commit
@@ -0,0 +1,38 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/pre-commit $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+# NOTE: pre-commit hook and its associated helper functions are all
+# maintained same as that of Hoostboot except for minor changes to
+# suit the PPE environment.
+
+if [ -f $TOOLSDIR/pre-commit-actions ]; then
+ $TOOLSDIR/pre-commit-actions
+# Legacy support for older releases
+elif [ -f $TOOLSDIR/pre-commit-prologs ]; then
+ $TOOLSDIR/pre-commit-prologs
+else
+ echo "Missing pre-commit files"
+ exit -1
+fi
diff --git a/src/tools/hooks/pre-commit-actions b/src/tools/hooks/pre-commit-actions
new file mode 100755
index 00000000..821e78de
--- /dev/null
+++ b/src/tools/hooks/pre-commit-actions
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/pre-commit-actions $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+# This hook is used to add or update copyright prolog statements and run
+# the code beautifier astyle.
+
+my $copyrightScript = "addCopyright";
+
+## Make up a list of all staged files ( --cached --name-only )
+## Filter for only Added or Modified ( --diff-filter=AM )
+chomp( my @fileList = `git diff --cached --name-only --diff-filter=AM` );
+
+
+if ( @fileList )
+{
+ print "run $copyrightScript update ...\n";
+ print " $_\n" foreach @fileList;
+ print "\n";
+
+ system "$ENV{'TOOLSDIR'}/$copyrightScript update @fileList";
+ die("$?") if ($? != 0);
+
+ system "git add @fileList";
+ exit 1 if ($? != 0);
+}
+
+exit 0;
diff --git a/src/tools/hooks/pre-commit-prologs b/src/tools/hooks/pre-commit-prologs
new file mode 100755
index 00000000..eb53e316
--- /dev/null
+++ b/src/tools/hooks/pre-commit-prologs
@@ -0,0 +1,46 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/pre-commit-prologs $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+# This hook is used to add or update copyright prolog statements
+
+my $script = "addCopyright";
+
+## Make up a list of all staged files ( --cached --name-only )
+## Filter for only Added or Modified ( --diff-filter=AM )
+chomp( my @fileList = `git diff --cached --name-only --diff-filter=AM` );
+
+if ( @fileList )
+{
+ print "run $script update ...\n";
+ print " $_\n" foreach @fileList;
+ print "\n";
+
+ system "$ENV{'TOOLS_DIR'}/$script update @fileList";
+ die("$?") if ($? != 0);
+
+ system "git add @fileList";
+ exit 1 if ($? != 0);
+}
+
+exit 0;
diff --git a/src/tools/hooks/setupgithooks.sh b/src/tools/hooks/setupgithooks.sh
new file mode 100755
index 00000000..ae38b253
--- /dev/null
+++ b/src/tools/hooks/setupgithooks.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/setupgithooks.sh $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+
+# Each developer runs this from the git_repo base dir, where it will copy the
+# needed scripts into .git/hooks/ directory and make them executable.
+
+if [ -d $HOOKSDIR ]
+then
+
+ # Get hooks from Gerrit, if needed.
+ if [ ! -f $HOOKSDIR/commit-msg ]
+ then
+ echo "Copying Gerrit hooks..."
+ scp -p -q $GERRIT_SRV:hooks/commit-msg $HOOKSDIR
+ fi
+
+ # Copy custom pre/post commit hooks from tools directory.
+ if [ -f "$TOOLSDIR/pre-commit" -a \
+ -f "$TOOLSDIR/post-commit" ]
+ then
+ echo "Copying pre/post commit hooks..."
+
+ cp $TOOLSDIR/pre-commit $HOOKSDIR/
+ cp $TOOLSDIR/pre-commit $HOOKSDIR/pre-applypatch
+ cp $TOOLSDIR/post-commit $HOOKSDIR/
+
+ chmod u+x $HOOKSDIR/pre-commit
+ chmod u+x $HOOKSDIR/pre-applypatch
+ chmod u+x $HOOKSDIR/post-commit
+
+ else
+ echo "Cannot find or access pre or post commit scripts"
+ exit 1
+ fi
+
+else
+ echo "Cannot find or access .git/hooks directory"
+ exit 1
+fi
+
+exit 0
diff --git a/src/tools/hooks/verify-commit b/src/tools/hooks/verify-commit
new file mode 100755
index 00000000..68beebf5
--- /dev/null
+++ b/src/tools/hooks/verify-commit
@@ -0,0 +1,358 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/hooks/verify-commit $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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;
+
+my $issueFound = 0;
+my $errorFound = 0;
+
+my $projectName = $ENV{'PROJECT_NAME'};
+# Relative path of import tree from project root
+my $importPrefix = $ENV{'IMPORT_REL_PATH'}."/";
+
+verifyPatchSet(); # Verify the patch contents.
+verifyCommitMsg(); # Verify the commit message.
+
+# Finish out the divider.
+if ($issueFound)
+{
+ print "------------------------------------------------------------\n";
+}
+
+# Return a bad RC if we found an error. Let warnings pass.
+exit ($errorFound ? -1 : 0);
+
+
+########################### Subroutines ################################
+
+# @sub verifyPatchSet
+#
+# Extract the contents (lines changed) from the patch set and verify.
+#
+sub verifyPatchSet
+{
+ # git-diff options:
+ # * Diff against the previous commit (HEAD~1)
+ # * Filter only added and modified files (AM).
+ # * Show only the lines changed, with no context (U0).
+ # Grep only the lines marked with "+" (instead of "-") to find just the
+ # actions done by this patchset and not the content removed.
+ open PATCH_CONTENTS, "git diff HEAD~1 --diff-filter=AM -U0 | ".
+ "grep -e \"^+\" -e \"^@@.*+[0-9]\\+\" |";
+
+ my %fileContents = ();
+
+ my $lastFile = "";
+ my $fileLines = ();
+ my $lineCount = 0;
+ while (my $line = <PATCH_CONTENTS>)
+ {
+ chomp $line;
+
+ # Line starting with "+++ b/path/to/file" indicate a new file.
+ if ($line =~ m/^\+\+\+ b\/(.*)/)
+ {
+ # Save previous file into the map.
+ if ($lastFile ne "")
+ {
+ $fileContents{$lastFile} = $fileLines;
+ $fileLines = ();
+ $lineCount = 0;
+ }
+ $lastFile = $1;
+ }
+ # Lines starting with "@@" indicates a seek in the file, so update
+ # line numbers.
+ elsif ($line =~ m/^@@.*\+([0-9]+)/)
+ {
+ $lineCount = $1 - 1;
+ }
+ else
+ {
+ $line =~ s/^\+//; # filter off the leading + symbol.
+ $lineCount++;
+ push @{$fileLines}, [$line, $lineCount];
+ }
+ }
+ if ($lastFile ne "") # Save last file into the map.
+ {
+ $fileContents{$lastFile} = $fileLines;
+ $fileLines = ();
+ }
+
+ # Verify each line of each file.
+ foreach my $file (sort keys %fileContents)
+ {
+ foreach my $line (@{$fileContents{$file}})
+ {
+ verifyFileLine($file, @{$line}[0], @{$line}[1]);
+ }
+ }
+}
+
+# @sub verifyFileLine
+#
+# Checks a particular line of the file for the following issues:
+# * Warning: Lines longer than 80 characters, except in trace statement.
+# * Warning: Trailing whitespace.
+# * Warning: Tab characters outside of makefiles.
+# * Warning: TODO or FIXME type tag without a corresponding RTC number.
+# * Warning: NOMERGE tag found.
+#
+sub verifyFileLine
+{
+ my ($file,$line,$count) = @_;
+
+ # Check if file was mirrored
+ my $mirror = 0;
+ if ($file =~ m/^$importPrefix/)
+ {
+ $mirror = 1;
+ }
+
+ # Check line length.
+ if (length($line) > 80)
+ {
+ # Allow trace statements to slide.
+ if (($line =~ m/TRAC[DSFU]/) ||
+ ($line =~m/TS_FAIL/) ||
+ ($line =~m/printk/) ||
+ ($line =~m/displayf/) ||
+ ($line =~ m/FAPI_(INF|IMP|ERR|DBG|SCAN)/))
+ {
+ }
+ else
+ {
+ warning($file,$line,$count,
+ (sprintf "Length is more than 80 characters (%d).",
+ length($line))
+ );
+ }
+ }
+
+ # Check trailing whitespace.
+ if ($line =~ m/\s$/)
+ {
+ warning($file,$line,$count,
+ "Trailing whitespace found.");
+ }
+
+ # Check tabs.
+ if ($line =~ m/\t/)
+ {
+ # Makefiles are ok (require tabs).
+ if (not (($file =~ m/makefile/) || ($file =~ m/\.mk/)))
+ {
+ warning($file,$line,$count,
+ "Tab character found.");
+ }
+ }
+
+ # Check "TODO" or "FIXME" type comments.
+ if (($line =~ m/TODO/i) || ($line =~ m/FIXME/i))
+ {
+ if ( (not ($line =~ m/RTC[\s:]\s*[0-9]+/)) &&
+ (not ($line =~ m/CQ[\s:]\s*[A-Z][A-Z][0-9]+/)))
+ {
+ warning($file,$line,$count,
+ "TODO/FIXME tag without corresponding RTC or CQ number.");
+ }
+ }
+
+ # Check "NOMERGE" type comment.
+ if ($line =~ m/NOMERGE/i)
+ {
+ warning($file,$line,$count,
+ "NOMERGE tag found.");
+ }
+
+ # Check for "Confidential", unless it's a mirrored commit
+ if ($line =~ m/Confidential/i && $projectName =~ m/HostBoot/i && !$mirror)
+ {
+ unless (($file =~ m/verify-commit/) ||
+ ($file =~ m/addCopyright/))
+ {
+ error($file,$line,$count,
+ "File contains 'Confidential'.");
+ }
+ }
+}
+
+# @sub verifyCommitMsg
+#
+# Looks at the commit message to verify the following items:
+# * Topic is exactly 1 line long.
+# * Lines are less than 80 characters.
+# * No trailing whitespace.
+# * Tags, such as 'RTC:', are only found in the footer.
+# * Untagged lines are not found in the footer.
+# * RTC tag is formatted correctly.
+# * Warning for lacking RTC tag.
+#
+sub verifyCommitMsg
+{
+ open COMMIT_CONTENTS, "git log -n1 --pretty=format:%B |";
+ my $lineCount = 0;
+ my $rtcTag = "";
+ my $cqTag = "";
+ my $taggedLine = "";
+ my $untaggedLine = "";
+
+ while (my $line = <COMMIT_CONTENTS>)
+ {
+ $lineCount++;
+ chomp $line;
+
+ # Check line length over 80 characters.
+ if (length($line) > 80)
+ {
+ error("Commit Message",$line,$lineCount,
+ (sprintf "Length is more than 80 characters (%d).",
+ length($line))
+ );
+ }
+
+ # Check trailing whitespace.
+ if ($line =~ m/[^\s]+\s$/)
+ {
+ error("Commit Message",$line,$lineCount,
+ "Trailing whitespace found.");
+ }
+
+ # Blank line indicates a new "section".
+ if ($line =~ m/^$/)
+ {
+ # Check for tags outside of the footer.
+ # (new section implies previous section was not a footer)
+ if ("" ne $taggedLine)
+ {
+ error("Commit Message",$taggedLine,$lineCount,
+ "Tagged line found outside commit-msg footer.");
+ }
+
+ $rtcTag = "";
+ $cqTag = "";
+ $untaggedLine = "";
+ $taggedLine = "";
+ }
+ else
+ {
+ # Check for multi-line topic.
+ if ($lineCount == 2)
+ {
+ error("Commit Message",$line,$lineCount,
+ "Topic must be only one line long.");
+ }
+ }
+
+ # Verify format of RTC message.
+ if ($line =~ m/^\s*RTC:\s*[0-9]+(.*)/)
+ {
+ if ("" ne $rtcTag)
+ {
+ error("Commit Message",$line,$lineCount,
+ "Duplicate RTC tag found.");
+ }
+
+ $rtcTag = $line;
+ if ("" ne $1)
+ {
+ error("Commit Message",$line,$lineCount,
+ (sprintf "RTC tag format incorrect (%s).", $1));
+ }
+ }
+
+ if ($line =~ m/^\s*CQ:\s*[A-Z][A-Z][0-9]+(.*)/)
+ {
+ if ("" ne $cqTag)
+ {
+ error("Commit Message",$line,$lineCount,
+ "Duplicate CQ tag found.");
+ }
+
+ $cqTag = $line;
+ if ("" ne $1)
+ {
+ error("Commit Message",$line,$lineCount,
+ (sprintf "CQ tag format incorrect (%s).", $1));
+ }
+ }
+
+ # Identify if this is a tagged line or a non-tagged line and store
+ # away.
+ if ($line =~ m/^\s*[A-Za-z0-9\-_]+:[^:]/)
+ {
+ # We allow lines that look like tags in the topic like...
+ # "FOO: Adding support for BAR."
+ if ($lineCount > 1)
+ {
+ $taggedLine = $line;
+ }
+ }
+ else
+ {
+ $untaggedLine = $line;
+ }
+ }
+
+ # Warn for missing RTC tag.
+ if (("" eq $rtcTag) && ("" eq $cqTag))
+ {
+ warning("Commit Message","<end-of-file>",$lineCount,
+ "Neither RTC nor CQ tag found.");
+ }
+
+ # Error for a mix of tag / untagged in the last section (ie. untagged
+ # lines in the footer).
+ if (("" ne $untaggedLine) && ("" ne $taggedLine))
+ {
+ error("Commit Message",$untaggedLine,$lineCount,
+ "Untagged line found in footer.");
+ }
+}
+
+sub warning
+{
+ my ($file, $line, $count, $statement) = @_;
+ print "------------------------------------------------------------\n";
+ print "WARNING: $statement\n";
+ print " $file:$count\n";
+ print " $line\n";
+
+ $issueFound = 1;
+}
+
+sub error
+{
+ my ($file, $line, $count, $statement) = @_;
+ print "------------------------------------------------------------\n";
+ print "ERROR: $statement\n";
+ print " $file:$count\n";
+ print " $line\n";
+
+ $issueFound = 1;
+ $errorFound = 1;
+}
+
diff --git a/src/tools/image/Makefile b/src/tools/image/Makefile
new file mode 100644
index 00000000..fab89e66
--- /dev/null
+++ b/src/tools/image/Makefile
@@ -0,0 +1,86 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/image/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+############################################################################
+
+# Makefile for image tools
+# works on X86 Linux hosts.
+
+# Make targets:
+
+# all : utilities
+#
+# utilities : Build utility programs and procedures
+#
+# clean : Removes generated files
+#
+
+############################################################################
+include img_defs.mk
+
+# Under Linux the scheme is to use a common compiler to create procedures.
+# However, the common compiler can be VERY slow, so if the system compiler is
+# also 4.1.2 we're using that one instead. Also, the Linux FAPI libraries we
+# link with are 32-bit only so we need to force 32-bit mode.
+
+ifeq ($(wildcard /etc/ldap.conf), )
+ GSACELL = ausgsa
+else
+ GSACELL = $(shell cat /etc/ldap.conf | grep "host " | \
+ cut -d" " -f2 | cut -d. -f1)
+endif
+
+GCC-RELEASE = 4.8.2
+GCC-VERSION = $(shell gcc -v 2>&1 | grep "$(GCC-RELEASE)")
+
+ifeq ($(GCC-VERSION),)
+$(error wrong compiler version. Use $(GCC-RELEASE) compiler. Try: "scl enable devtoolset-2 bash")
+else
+CXX = g++
+endif
+
+UTILITIES-SOURCES = sbe_default_tool.c
+UTILITIES = sbe_default_tool
+
+# Utility targets
+UTILITIES-OBJc = $(patsubst %.c,$(BASE_OBJDIR)/%.o,$(UTILITIES-SOURCES))
+UTILITIES-OBJECTS += $(patsubst %.C,$(BASE_OBJDIR)/%.o,$(UTILITIES-OBJc))
+UTILITIES-DEPENDENCIES = $(patsubst %.o,%.d,$(UTILITIES-OBJECTS))
+UTILITIES-EXECUTABLES = $(patsubst %,$(BASE_OBJDIR)/%,$(UTILITIES))
+
+.PHONY : all utilities clean
+
+all: utilities
+
+utilities: $(UTILITIES-EXECUTABLES)
+
+CXXFLAGS+=-DFAPI2_NO_FFDC
+
+$(BASE_OBJDIR)/%.o: %.c
+ $(CXX) -std=c++11 $(INCLUDES) $(CXXFLAGS) -c -o $@ $<
+
+$(BASE_OBJDIR)/sbe_default_tool: $(P9_XIP_BINDIR)/p9_xip_image.o $(BASE_OBJDIR)/sbe_default_tool.o
+ $(CXX) $(CXXFLAGS) ${INCLUDES} -o $@ $^
+
+clean:
+ rm -f $(BASE_OBJDIR)/sbe_default_tool*
diff --git a/src/tools/image/sbe_default_tool.c b/src/tools/image/sbe_default_tool.c
new file mode 100644
index 00000000..ae2bbf53
--- /dev/null
+++ b/src/tools/image/sbe_default_tool.c
@@ -0,0 +1,310 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/image/sbe_default_tool.c $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 */
+/// \file sbe_default_tool.c
+/// \brief P9-XIP image setter tool for attributes in fixed section
+///
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <endian.h>
+
+
+#define __PPE__
+#include "fapi2.H"
+#include "proc_sbe_fixed.H"
+#include "p9_xip_image.h"
+
+const char* g_usage =
+"Usage: sbe_default_tool <image> <attribute> <value> <target type> <index>\n"
+"The 'image' is the binary image with fixed section.\n"
+"\n"
+"The 'attribute' is the attribute to be set.\n"
+"\n"
+"The 'value' is the value of the attribute to be set.\n"
+"\n"
+"The 'target type' is the type of the target. The following targets are defined:\n"
+"TARGET_TYPE_SYSTEM: system target\n"
+"TARGET_TYPE_PROC_CHIP: chip target\n"
+"TARGET_TYPE_PERV: pervasive target\n"
+"TARGET_TYPE_CORE: core target\n"
+"TARGET_TYPE_EQ: eq target\n"
+"TARGET_TYPE_EX: ex target\n"
+"\n"
+"The 'index' is the index of the value. Checking is performed.\n"
+"example:\n"
+"./sbe_default_tool ./sbe_main.bin ATTR_PLL_RING 0x33CAFE34 TARGET_TYPE_PERV 0\n"
+"./sbe_default_tool ./sbe_main.bin ATTR_SCRATCH_UINT8_1 12 TARGET_TYPE_PROC_CHIP 0\n"
+ ;
+
+
+void assertTarget(const char* str, unsigned int index)
+{
+
+ if(strcmp(str, "TARGET_TYPE_SYSTEM") == 0 || (strcmp(str, "TARGET_TYPE_PROC_CHIP") == 0)) {
+ if (index > 0) {
+ fprintf(stderr, "sbe_default_tool: index (%d) is larger than 0\n", index);
+ exit(1);
+ }
+ } else if(strcmp(str, "TARGET_TYPE_EX") == 0) {
+ if (index > EX_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index (%d) is larger than EX_TARGET_COUNT (%d)\n",
+ index, EX_TARGET_COUNT);
+ exit(1);
+ }
+ } else if(strcmp(str, "TARGET_TYPE_EQ") == 0) {
+ if (index > EQ_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index (%d) is larger than EQ_TARGET_COUNT (%d)\n",
+ index, EQ_TARGET_COUNT);
+ exit(1);
+ }
+ } else if(strcmp(str, "TARGET_TYPE_CORE") == 0) {
+ if (index > CORE_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index (%d) is larger than CORE_TARGET_COUNT (%d)\n",
+ index, CORE_TARGET_COUNT);
+ exit(1);
+ }
+ } else if(strcmp(str, "TARGET_TYPE_PERV") == 0) {
+ if (index > PERV_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: index (%d) is larger than PERV_TARGET_COUNT (%d)\n",
+ index, PERV_TARGET_COUNT);
+ exit(1);
+ }
+ } else {
+ if (index >= PERV_TARGET_COUNT) {
+ fprintf(stderr, "sbe_default_tool: target not supported:");
+ fprintf(stderr, " %s\n", str);
+ exit(1);
+ }
+ }
+ return;
+}
+
+void setAttribute(void* image, const char* attribute, unsigned int index, uint64_t val) {
+
+
+ P9XipItem item;
+ void *thePointer;
+ int rc;
+
+ rc = p9_xip_find(image, attribute, &item);
+ if (rc) {
+ fprintf(stderr, "sbe_default_tool: attribute not existing:");
+ fprintf(stderr, " %s", attribute);
+ exit(1);
+ }
+
+ // debug purpose
+ //printf("offset in string section: 0x%x \n", be32toh(item.iv_toc->iv_id));
+ //printf("address: 0x%x index: %2d 0x%x\n", item.iv_address, index, index);
+
+ p9_xip_image2host(image, item.iv_address, &thePointer);
+
+ // debug purpose
+ //printf("pointer1: 0x%x val: 0x%llx \n", thePointer, val);
+
+ if(item.iv_toc->iv_type == P9_XIP_UINT8) {
+
+ *((uint8_t*)thePointer + index) = (uint8_t)val;
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT8) {
+
+ *((int8_t*)thePointer + index) = (int8_t)val;
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT16) {
+
+ *((uint16_t*)thePointer + index) = htobe16((uint16_t)val);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT16) {
+
+ *((int16_t*)thePointer + index) = htobe16((int16_t)val);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT32) {
+
+ *((uint32_t*)thePointer + index) = htobe32((uint32_t)val);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT32) {
+
+ *((int32_t*)thePointer + index) = htobe32((int32_t)val);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT64) {
+
+ *((uint64_t*)thePointer + index) = htobe64((uint64_t)val);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT64) {
+
+ *((int64_t*)thePointer + index) = htobe64((int64_t)val);
+
+ } else {
+ fprintf(stderr, "sbe_default_tool: type not available");
+ exit(1);
+ }
+
+
+
+
+ P9_XIP_SECTION_NAMES(section_name);
+ P9_XIP_TYPE_STRINGS(type_name);
+
+ // debug purpose
+ //printf("pointer2: 0x%x \n", thePointer + index);
+ //printf("elements: %d \n", item.iv_elements);
+ //printf("section id: %s \n", section_name[item.iv_toc->iv_section]);
+ //printf("location in section: 0x%x \n", be32toh(item.iv_toc->iv_data));
+ //printf("type name: %s \n", type_name[item.iv_toc->iv_type]);
+
+ return;
+}
+
+
+uint64_t getAttribute(void* image, const char* attribute, unsigned int index) {
+
+ uint64_t val = 0;
+
+ P9XipItem item;
+ void *thePointer;
+ int rc;
+
+ rc = p9_xip_find(image, attribute, &item);
+ if (rc) {
+ fprintf(stderr, "sbe_default_tool: attribute not existing:");
+ fprintf(stderr, " %s", attribute);
+ exit(1);
+ }
+
+ p9_xip_image2host(image, item.iv_address, &thePointer);
+
+ if(item.iv_toc->iv_type == P9_XIP_UINT8) {
+
+ val = *((uint8_t*)thePointer + index);
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT8) {
+
+ val = *((int8_t*)thePointer + index);
+ val &= 0xFF;
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT16) {
+
+ val = htobe16(*((uint16_t*)thePointer + index));
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT16) {
+
+ val = htobe16(*((int16_t*)thePointer + index));
+ val &= 0xFFFF;
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT32) {
+
+ val = htobe32(*((uint32_t*)thePointer + (index)));
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT32) {
+
+ val = htobe32(*((int32_t*)thePointer + index));
+ val &= 0xFFFFFFFF;
+
+ } else if(item.iv_toc->iv_type == P9_XIP_UINT64) {
+
+ val = htobe64(*((uint64_t*)thePointer + index));
+
+ } else if(item.iv_toc->iv_type == P9_XIP_INT64) {
+
+ val = htobe64(*((int64_t*)thePointer + index));
+
+ } else {
+ fprintf(stderr, "sbe_default_tool: type not available");
+ exit(1);
+ }
+
+
+
+ return val;
+}
+
+int main(int argc, const char** argv)
+{
+
+ int fileFd, rc;
+ void* image;
+ struct stat buf;
+
+ if(argc != 6) {
+ fprintf(stderr, "sbe_default_tool: argument missing\n");
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+
+ printf("sbe_default_tool %s %s %s %s %s\n", argv[1], argv[2], argv[3], argv[4], argv[5]);
+
+ fileFd = open(argv[1], O_RDWR);
+ if (fileFd < 0) {
+ fprintf(stderr, "sbe_default_tool: open() of the file to be appended failed");
+ exit(1);
+ }
+
+ rc = fstat(fileFd, &buf);
+ if (rc) {
+ fprintf(stderr, "sbe_default_tool: fstat() of the file to be appended failed");
+ exit(1);
+ }
+
+ image = mmap(0, buf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fileFd, 0);
+ if (image == MAP_FAILED) {
+ fprintf(stderr, "sbe_default_tool: mmap() of the file to be appended failed");
+ exit(1);
+ }
+
+
+ uint64_t val=strtoull(argv[3], 0, 0);
+
+ unsigned int index = strtoul(argv[5], 0, 10);
+
+ assertTarget(argv[4], index);
+
+ setAttribute(image, argv[2], index, val);
+
+ uint64_t check = getAttribute(image, argv[2], index);
+
+ if((check & val) != check) {
+
+ fprintf(stderr, "sbe_default_tool: set and get values not equal -> ");
+ fprintf(stderr, "%lx != %lx\n", check, val);
+ exit(1);
+
+ }
+
+ rc = close(fileFd);
+ if (rc) {
+ fprintf(stderr, "sbe_default_tool: close() of modified image failed");
+ exit(1);
+ }
+
+
+ return 0;
+}
diff --git a/src/tools/ppetracepp/Makefile b/src/tools/ppetracepp/Makefile
new file mode 100644
index 00000000..eec6da6a
--- /dev/null
+++ b/src/tools/ppetracepp/Makefile
@@ -0,0 +1,37 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/ppetracepp/Makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+include img_defs.mk
+
+all: ppetracepp ppe2fsp
+
+ppetracepp: ppetracepp.C
+ g++ -m32 -O3 -w -g -I./ ppetracepp.C -o $(PPETRACEPP_BIN_DIR)/ppetracepp
+# g++ -O3 -w -x c++ -fPIC -g -I./ ppetracepp.C -o ppetracepp
+
+ppe2fsp: ppe2fsp.c ppe2fsp_cmd.c
+ gcc -m32 -w -g -I./ -I$(PK_SRCDIR)/trace ppe2fsp.c ppe2fsp_cmd.c -o $(PPETRACEPP_BIN_DIR)/ppe2fsp
+
+clean:
+ rm $(PPETRACEPP_BIN_DIR)/ppetracepp $(PPETRACEPP_BIN_DIR)/ppe2fsp
+
diff --git a/src/tools/ppetracepp/cmvc/makefile b/src/tools/ppetracepp/cmvc/makefile
new file mode 100644
index 00000000..cf2ad437
--- /dev/null
+++ b/src/tools/ppetracepp/cmvc/makefile
@@ -0,0 +1,28 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/ppetracepp/cmvc/makefile $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+PROGRAMS += ppe2fsp
+ppe2fsp_OFILES = ppe2fsp.o ppe2fsp_cmd.o
+
+.include <${RULES_MK}>
+
diff --git a/src/tools/ppetracepp/jhash.h b/src/tools/ppetracepp/jhash.h
new file mode 100755
index 00000000..0dcc3bf3
--- /dev/null
+++ b/src/tools/ppetracepp/jhash.h
@@ -0,0 +1,166 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/jhash.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+#ifndef _LINUX_JHASH_H
+#define _LINUX_JHASH_H
+
+/* jhash.h: Jenkins hash support.
+ *
+ * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
+ *
+ * http://burtleburtle.net/bob/hash/
+ *
+ * These are the credits from Bob's sources:
+ *
+ * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
+ * hash(), hash2(), hash3, and mix() are externally useful functions.
+ * Routines to test the hash are included if SELF_TEST is defined.
+ * You can use this free for any purpose. It has no warranty.
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ *
+ * I've modified Bob's hash to be useful in the Linux kernel, and
+ * any bugs present are surely my fault. -DaveM
+ */
+
+/* NOTE: Arguments are modified. */
+#define __jhash_mix(a, b, c) \
+{ \
+ a -= b; a -= c; a ^= (c>>13); \
+ b -= c; b -= a; b ^= (a<<8); \
+ c -= a; c -= b; c ^= (b>>13); \
+ a -= b; a -= c; a ^= (c>>12); \
+ b -= c; b -= a; b ^= (a<<16); \
+ c -= a; c -= b; c ^= (b>>5); \
+ a -= b; a -= c; a ^= (c>>3); \
+ b -= c; b -= a; b ^= (a<<10); \
+ c -= a; c -= b; c ^= (b>>15); \
+}
+
+/* The golden ration: an arbitrary value */
+#define JHASH_GOLDEN_RATIO 0x9e3779b9
+
+/* The most generic version, hashes an arbitrary sequence
+ * of bytes. No alignment or length assumptions are made about
+ * the input key.
+ */
+static inline u32 jhash(const void *key, u32 length, u32 initval)
+{
+ u32 a, b, c, len;
+ const u8 *k = (const u8*)key;
+
+ len = length;
+ a = b = JHASH_GOLDEN_RATIO;
+ c = initval;
+
+ while (len >= 12) {
+ a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24));
+ b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24));
+ c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24));
+
+ __jhash_mix(a,b,c);
+
+ k += 12;
+ len -= 12;
+ }
+
+ c += length;
+ switch (len) {
+ case 11: c += ((u32)k[10]<<24);
+ case 10: c += ((u32)k[9]<<16);
+ case 9 : c += ((u32)k[8]<<8);
+ case 8 : b += ((u32)k[7]<<24);
+ case 7 : b += ((u32)k[6]<<16);
+ case 6 : b += ((u32)k[5]<<8);
+ case 5 : b += k[4];
+ case 4 : a += ((u32)k[3]<<24);
+ case 3 : a += ((u32)k[2]<<16);
+ case 2 : a += ((u32)k[1]<<8);
+ case 1 : a += k[0];
+ };
+
+ __jhash_mix(a,b,c);
+
+ return c;
+}
+
+/* A special optimized version that handles 1 or more of u32s.
+ * The length parameter here is the number of u32s in the key.
+ */
+static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
+{
+ u32 a, b, c, len;
+
+ a = b = JHASH_GOLDEN_RATIO;
+ c = initval;
+ len = length;
+
+ while (len >= 3) {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ __jhash_mix(a, b, c);
+ k += 3; len -= 3;
+ }
+
+ c += length * 4;
+
+ switch (len) {
+ case 2 : b += k[1];
+ case 1 : a += k[0];
+ };
+
+ __jhash_mix(a,b,c);
+
+ return c;
+}
+
+
+/* A special ultra-optimized versions that knows they are hashing exactly
+ * 3, 2 or 1 word(s).
+ *
+ * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
+ * done at the end is not done here.
+ */
+static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
+{
+ a += JHASH_GOLDEN_RATIO;
+ b += JHASH_GOLDEN_RATIO;
+ c += initval;
+
+ __jhash_mix(a, b, c);
+
+ return c;
+}
+
+static inline u32 jhash_2words(u32 a, u32 b, u32 initval)
+{
+ return jhash_3words(a, b, 0, initval);
+}
+
+static inline u32 jhash_1word(u32 a, u32 initval)
+{
+ return jhash_3words(a, 0, 0, initval);
+}
+
+#endif /* _LINUX_JHASH_H */
diff --git a/src/tools/ppetracepp/ppe2fsp.c b/src/tools/ppetracepp/ppe2fsp.c
new file mode 100755
index 00000000..d681b147
--- /dev/null
+++ b/src/tools/ppetracepp/ppe2fsp.c
@@ -0,0 +1,532 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/ppe2fsp.c $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 */
+#include "pk_trace.h"
+#include "ppe2fsp.h"
+#include "trac_interface.h"
+#include <arpa/inet.h>
+#include <string.h>
+#include <stdint.h>
+
+#define TRACE_BUF_VERSION 0x01 /*!< Trace buffer version */
+#define TRACE_FIELDTRACE 0x4654 /*!< Field Trace - "FT" */
+#define TRACE_FIELDBIN 0x4644 /*!< Binary Field Trace - "FD" */
+
+#define TRAC_TIME_REAL 0 // upper 32 = seconds, lower 32 = nanoseconds
+#define TRAC_TIME_50MHZ 1
+#define TRAC_TIME_200MHZ 2
+#define TRAC_TIME_167MHZ 3 // 166666667Hz
+
+typedef struct
+{
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+ union
+ {
+ uint8_t data[PK_TRACE_MAX_BINARY + 1]; //add 1 byte for padding
+ uint32_t parms[PK_TRACE_MAX_PARMS];
+ };
+ uint32_t size;
+}largest_fsp_entry_t;
+
+typedef struct
+{
+ union
+ {
+ uint8_t binary_data[PK_TRACE_MAX_BINARY + 1];
+ struct
+ {
+ uint8_t rsvd[(PK_TRACE_MAX_BINARY + 1) - (PK_TRACE_MAX_PARMS * sizeof(uint32_t))];
+ uint32_t parms[PK_TRACE_MAX_PARMS];
+ };
+ };
+ PkTraceEntryFooter footer;
+}LargestPpeEntry;
+
+//convert a ppe timestamp to an fsp trace timestamp
+uint64_t ppe2fsp_time(uint64_t ppe_time, uint32_t hz)
+{
+ uint32_t seconds;
+ uint32_t remainder;
+ uint32_t nseconds;
+
+ //convert from ppe ticks to seconds and nanoseconds
+ seconds = ppe_time / hz;
+ remainder = ppe_time - (((uint64_t)seconds) * hz);
+ nseconds = (((uint64_t)remainder) * 1000000000) / hz;
+ return (((uint64_t)seconds) << 32) | nseconds;
+}
+
+//Writes an fsp trace entry to the fsp trace buffer
+void fsp_put_entry(trace_buf_head_t* tb, largest_fsp_entry_t* fte, size_t entry_size, uint32_t bytes_left)
+{
+ char* buffer = ((char*)tb) + sizeof(trace_buf_head_t);
+ char* tb_start;
+ char* fte_start;
+ uint32_t copy_bytes;
+
+ if(entry_size <= bytes_left)
+ {
+ tb_start = buffer + bytes_left - entry_size;
+ fte_start = (char*)fte;
+ copy_bytes = entry_size;
+ }
+ else
+ {
+ tb_start = buffer;
+ fte_start = ((char*)fte) + (entry_size - bytes_left);
+ copy_bytes = bytes_left;
+ }
+
+ memcpy(tb_start, fte_start, copy_bytes);
+}
+
+
+//convert a ppe trace entry to an fsp trace entry
+size_t pte2fte(PkTraceBuffer* ptb,
+ LargestPpeEntry* pte,
+ size_t pte_size,
+ largest_fsp_entry_t* fte,
+ uint64_t ppe_time64)
+{
+ size_t entry_size;
+ PkTraceGeneric* pte_footer = &pte->footer.generic;
+ uint32_t format;
+ uint32_t hash32;
+ uint32_t hash32_partial;
+ uint32_t* parm_start;
+ uint32_t parm_bytes;
+ uint64_t fsp_time64;
+
+ //convert the ppe trace time to an fsp trace time
+ fsp_time64 = ppe2fsp_time(ppe_time64, ntohl(ptb->hz));
+
+ //fill in the 64 bit timestamp
+ fte->stamp.tbh = htonl((uint32_t)(fsp_time64 >> 32));
+ fte->stamp.tbl = htonl((uint32_t)(fsp_time64 & 0x00000000ffffffffull));
+
+ //use the ppe instance id as the thread id.
+ fte->stamp.tid = htonl((uint32_t)ntohs(ptb->instance_id));
+
+ //merge the hash prefix and the string_id fields together for a 32 bit hash value
+ hash32 = ((uint32_t)ntohs(ptb->hash_prefix)) << 16;
+ hash32 |= pte_footer->string_id;
+ fte->head.hash = htonl(hash32);
+
+ //generate the 32bit hash value for a partial trace entry in case it's needed
+ hash32_partial = ((uint32_t)ntohs(ptb->hash_prefix)) << 16;
+ hash32_partial |= ntohs(ptb->partial_trace_hash);
+
+ //set the line number to 1
+ fte->head.line = htonl(1);
+
+ //determine the FSP trace format
+ format = PK_GET_TRACE_FORMAT(pte_footer->time_format.word32);
+ if(format == PK_TRACE_FORMAT_BINARY)
+ {
+ fte->head.tag = htons(TRACE_FIELDBIN);
+ }
+ else
+ {
+ fte->head.tag = htons(TRACE_FIELDTRACE);
+ }
+
+ parm_start = (uint32_t*)(((char*)pte) + (sizeof(LargestPpeEntry) - pte_size));
+
+ //fill in the parameters/binary data and size at the end
+ switch(format)
+ {
+
+ case PK_TRACE_FORMAT_TINY:
+ //one or 0 parameters
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ sizeof(uint32_t);
+ fte->parms[0] = htonl((uint32_t)(pte_footer->parm16));
+ fte->head.length = htons(sizeof(uint32_t));
+ parm_bytes = 0;
+ break;
+
+ case PK_TRACE_FORMAT_BIG:
+ //1 - 4 parameters
+ //
+ //If the trace entry data is incomplete (not all parm data
+ //had been written at the time the trace was captured) then
+ //we will write a trace to the fsp buffer that says
+ //"PARTIAL TRACE ENTRY. HASH_ID = %d"
+ if(pte_footer->complete)
+ {
+ parm_bytes = pte_footer->bytes_or_parms_count * sizeof(uint32_t);
+ fte->head.length = htons(parm_bytes + sizeof(uint32_t));
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ parm_bytes + sizeof(uint32_t);
+ }
+ else
+ {
+ parm_bytes = 0;
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ sizeof(uint32_t);
+ fte->parms[0] = fte->head.hash; //already corrected for endianess
+ fte->head.hash = htonl(hash32_partial);
+ fte->head.length = htons(sizeof(uint32_t));
+ }
+ break;
+
+ case PK_TRACE_FORMAT_BINARY:
+ //If the trace entry data is incomplete (not all parm data
+ //had been written at the time the trace was captured) then
+ //we will write a trace to the fsp buffer that says
+ //"PARTIAL TRACE ENTRY. HASH_ID = %d"
+ if(pte_footer->complete)
+ {
+ parm_bytes = pte_footer->bytes_or_parms_count;
+ fte->head.length = htons((uint16_t)parm_bytes);
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ parm_bytes;
+
+ //pad to 4 byte boundary
+ entry_size = (entry_size + 3) & ~3;
+ }
+ else
+ {
+ parm_bytes = 0;
+ entry_size = sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ sizeof(uint32_t);
+ fte->parms[0] = fte->head.hash;
+ fte->head.hash = htonl(hash32_partial);
+ fte->head.length = htons(sizeof(uint32_t));
+ fte->head.tag = htons(TRACE_FIELDTRACE);
+ }
+ break;
+
+
+ default:
+ entry_size = 0;
+ parm_bytes = 0;
+ break;
+ }
+
+ //copy parameter bytes to the fsp entry if necessary
+ if(parm_bytes)
+ {
+ memcpy(fte->data, parm_start, parm_bytes);
+ }
+
+ //add the entry size to the end
+ if(entry_size)
+ {
+ uint32_t new_entry_size = entry_size + sizeof(uint32_t);
+ *((uint32_t*)(((char*)fte) + entry_size)) = htonl(new_entry_size);
+ entry_size = new_entry_size;
+ }
+
+ return entry_size;
+}
+
+//retrieve a ppe trace entry from a ppe trace buffer
+size_t ppe_get_entry(PkTraceBuffer* tb, uint32_t offset, LargestPpeEntry* pte)
+{
+ uint32_t mask = ntohs(tb->size) - 1;
+ PkTraceEntryFooter* footer;
+ size_t entry_size;
+ size_t parm_size;
+ char* dest = (char*)pte;
+ uint32_t format;
+ uint32_t start_index;
+ uint32_t bytes_left;
+ uint32_t bytes_to_copy;
+
+ //Find the footer in the circular buffer
+ footer = (PkTraceEntryFooter*)(&tb->cb[(offset - sizeof(PkTraceEntryFooter)) & mask]);
+
+ //always correct endianess for the time and string id words
+ pte->footer.generic.time_format.word32 = ntohl(footer->generic.time_format.word32);
+ pte->footer.generic.string_id = ntohs(footer->generic.string_id);
+
+ //only need to byte swap the parm16 value if this is a tiny format
+ pte->footer.generic.parm16 = footer->generic.parm16;
+
+ //use footer data to determine the length of the binary data or parameters
+ format = PK_GET_TRACE_FORMAT(pte->footer.generic.time_format.word32);
+ switch(format)
+ {
+ case PK_TRACE_FORMAT_TINY:
+ pte->footer.generic.parm16 = ntohs(pte->footer.generic.parm16);
+ parm_size = 0;
+ entry_size = sizeof(PkTraceEntryFooter);
+ break;
+
+ case PK_TRACE_FORMAT_BIG:
+ parm_size = pte->footer.generic.bytes_or_parms_count * sizeof(uint32_t);
+ entry_size = sizeof(PkTraceEntryFooter);
+ break;
+
+ case PK_TRACE_FORMAT_BINARY:
+ parm_size = pte->footer.generic.bytes_or_parms_count;
+ entry_size = sizeof(PkTraceEntryFooter);
+ break;
+
+ default:
+ entry_size = 0;
+ parm_size = 0;
+ break;
+ }
+
+ //pad to 8 byte boundary
+ parm_size = (parm_size + 7) & ~0x00000007ul;
+
+ //add the parameter size to the total entry size
+ entry_size += parm_size;
+
+ //copy the entry from the circular buffer to pte
+ start_index = (offset - entry_size) & mask;
+ bytes_left = ntohs(tb->size) - start_index;
+
+ //only copy up to the end of the circular buffer
+ if(parm_size < bytes_left)
+ {
+ bytes_to_copy = parm_size;
+ }
+ else
+ {
+ bytes_to_copy = bytes_left;
+ }
+
+ dest += sizeof(LargestPpeEntry) - entry_size;
+ memcpy(dest, &tb->cb[start_index], bytes_to_copy);
+
+ //now copy the rest of the data starting from the beginning of the
+ //circular buffer.
+ if(bytes_to_copy < parm_size)
+ {
+ memcpy(dest + bytes_to_copy, tb->cb, parm_size - bytes_to_copy);
+ }
+
+ //return the size of the entry
+ return entry_size;
+}
+
+//convert a ppe trace buffer to an fsp trace buffer
+int ppe2fsp(void* in, size_t in_size, void* out, size_t* io_size)
+{
+ PkTraceBuffer* ptb = (PkTraceBuffer*)in;
+ trace_buf_head_t* ftb = (trace_buf_head_t*)out;
+ uint32_t ppe_bytes_left;
+ uint32_t fsp_bytes_left;
+ int rc = 0;
+ uint32_t ptb_offset;
+ uint64_t ppe_time64;
+ uint32_t fte_size, pte_size;
+ uint32_t fsp_te_count = 0;
+ uint32_t time_diff32, prev_time32, new_time32;
+ PkTraceGeneric* pte_footer;
+ largest_fsp_entry_t fte;
+ LargestPpeEntry pte;
+ uint64_t time_adj64;
+
+ do
+ {
+ if(!ptb || !ftb || !io_size)
+ {
+ rc = P2F_NULL_POINTER;
+ break;
+ }
+
+ if(ntohs(ptb->version) != PK_TRACE_VERSION)
+ {
+ rc = P2F_INVALID_VERSION;
+ break;
+ }
+
+ //check that the input buffer is large enough to have a ppe trace buffer
+ if(in_size < (((uintptr_t)(&ptb->cb[0])) - (uintptr_t)(ptb)))
+ {
+ rc = P2F_INPUT_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ //initialize some locals
+ fsp_bytes_left = *io_size - sizeof(trace_buf_head_t);
+ ppe_bytes_left = ntohs(ptb->size);
+ ptb_offset = ntohl(ptb->state.offset);
+ if(htonl(1) == 1)
+ {
+ time_adj64 = ptb->time_adj64;
+ }
+ else
+ {
+ time_adj64 = ntohl((uint32_t)(ptb->time_adj64 >> 32));
+ time_adj64 |= ((uint64_t)(ntohl((uint32_t)(ptb->time_adj64 & 0x00000000ffffffff)))) << 32;
+ }
+
+ //make sure the ppe buffer size is a power of two
+ if((ppe_bytes_left - 1) & ppe_bytes_left)
+ {
+ //size is not a power of two
+ rc = P2F_INVALID_INPUT_SIZE;
+ break;
+ }
+
+ //The ppe bytes field should always be a multiple of 8
+ if(ptb_offset & 0x7)
+ {
+ rc = P2F_INVALID_PPE_OFFSET;
+ break;
+ }
+
+ //make sure there is enough room for the fsp header
+ if(*io_size < sizeof(trace_buf_head_t))
+ {
+ rc = P2F_OUTPUT_BUFFER_TOO_SMALL;
+ break;
+ }
+
+
+ //initialize the fsp header
+ ftb->ver = TRACE_BUF_VERSION;
+ ftb->hdr_len = sizeof(trace_buf_head_t);
+ ftb->time_flg = TRAC_TIME_REAL;
+ ftb->endian_flg = 'B'; //big endian
+ memcpy(ftb->comp, ptb->image_str, sizeof(ftb->comp));
+ ftb->times_wrap = htonl(1);
+ ftb->size = htonl(sizeof(trace_buf_head_t) + sizeof(uint32_t));
+ ftb->next_free = htonl(sizeof(trace_buf_head_t));
+ ftb->extracted = htonl(0);
+ ftb->te_count = htonl(0);
+
+ //find the latest timestamp so that we can work back from there
+ ppe_time64 = ((uint64_t)(ntohl(ptb->state.tbu32) & 0xefffffff)) << 32;
+ pte_size = ppe_get_entry(ptb, ptb_offset, &pte);
+ prev_time32 = PK_GET_TRACE_TIME(pte.footer.generic.time_format.word32);
+ ppe_time64 |= prev_time32;
+
+ //process all of the input bytes one trace entry at a time
+ //from newest to oldest (backwards) until we run out of input bytes or
+ //we run out of output space.
+ while(1)
+ {
+ //check if we have enough data for a ppe footer
+ if(ppe_bytes_left < sizeof(PkTraceEntryFooter))
+ {
+ break;
+ }
+
+ //get the next ppe entry
+ pte_size = ppe_get_entry(ptb, ptb_offset, &pte);
+
+ //Stop if there are no more entries to retrieve from the ppe trace buffer
+ if(!pte_size)
+ {
+ break;
+ }
+ pte_footer = &pte.footer.generic;
+
+ //mark the entry as incomplete if we didn't have enough data
+ //for the entire entry
+ if(pte_size > ppe_bytes_left)
+ {
+ pte_footer->complete = 0;
+ ppe_bytes_left = 0;
+ }
+ else
+ {
+ ppe_bytes_left -= pte_size;
+ ptb_offset -= pte_size;
+ }
+
+ //Calculate the 64 bit timestamp for this entry....
+ //On PPE, getting the timestamp is not done atomically with writing
+ //the entry to the buffer. This means that an entry with an older
+ //timestamp could possibly be added to the buffer after an entry
+ //with a newer timestamp. Detect this condition by checking if the
+ //time difference is bigger than the max difference. The max
+ //difference is enforced by the PPE having a trace added on a
+ //shorter time boundary (using a timer).
+ new_time32 = PK_GET_TRACE_TIME(pte_footer->time_format.word32);
+ time_diff32 = prev_time32 - new_time32;
+
+ if(time_diff32 > ntohl(ptb->max_time_change))
+ {
+ time_diff32 = new_time32 - prev_time32;
+ ppe_time64 += time_diff32;
+ }
+ else
+ {
+ ppe_time64 -= time_diff32;
+ }
+
+ //save off the lower 32bit timestamp for the next iteration
+ prev_time32 = new_time32;
+
+ //convert the ppe trace entry to an fsp trace entry
+ fte_size = pte2fte(ptb, &pte, pte_size, &fte, ppe_time64 + time_adj64);
+
+ //fit as much of the entry into the fsp trace buffer as possible
+ fsp_put_entry(ftb, &fte, fte_size, fsp_bytes_left);
+
+ //update the fsp trace entry count
+ fsp_te_count++;
+
+ //stop if there is no more room left in the fsp trace buffer
+ if(fte_size >= fsp_bytes_left)
+ {
+ fsp_bytes_left = 0;
+ ftb->times_wrap = htonl(1);
+ break;
+ }
+ else
+ {
+ fsp_bytes_left -= fte_size;
+ }
+ }//while(1)
+
+
+ //shift the trace data up if there is space to do so
+ if(fsp_bytes_left)
+ {
+ char* dest = ((char*)ftb) + sizeof(trace_buf_head_t);
+ char* src = dest + fsp_bytes_left;
+ size_t data_size = *io_size - sizeof(trace_buf_head_t) - fsp_bytes_left;
+ memmove(dest, src, data_size);
+ }
+
+ //update the fsp header to reflect the true size and entry count
+ ftb->te_count = htonl(fsp_te_count);
+
+ //inform the caller of how many bytes were actually used
+ *io_size -= fsp_bytes_left;
+
+ //shrink the size field to what we actually ended up using
+ ftb->size = htonl(*io_size);
+
+ }while(0);
+
+ return rc;
+}
+
+
+
diff --git a/src/tools/ppetracepp/ppe2fsp.h b/src/tools/ppetracepp/ppe2fsp.h
new file mode 100644
index 00000000..2abb146c
--- /dev/null
+++ b/src/tools/ppetracepp/ppe2fsp.h
@@ -0,0 +1,33 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/ppe2fsp.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 */
+#include <stdio.h>
+
+#define P2F_NULL_POINTER 1
+#define P2F_INVALID_INPUT_SIZE 2
+#define P2F_INVALID_PPE_OFFSET 3
+#define P2F_OUTPUT_BUFFER_TOO_SMALL 4
+#define P2F_INPUT_BUFFER_TOO_SMALL 5
+#define P2F_INVALID_VERSION 6
+
+int ppe2fsp(void* in, size_t in_size, void* out, size_t* io_size);
diff --git a/src/tools/ppetracepp/ppe2fsp_cmd.c b/src/tools/ppetracepp/ppe2fsp_cmd.c
new file mode 100644
index 00000000..c36d735c
--- /dev/null
+++ b/src/tools/ppetracepp/ppe2fsp_cmd.c
@@ -0,0 +1,138 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/ppe2fsp_cmd.c $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+#include <stdio.h>
+#include "ppe2fsp.h"
+#include "pk_trace.h"
+
+#define MAX_INPUT_SIZE 0x2040 //8k
+#define MAX_OUTPUT_SIZE (4 * MAX_INPUT_SIZE)
+
+char* inbuf[MAX_INPUT_SIZE];
+char* outbuf[MAX_OUTPUT_SIZE];
+;
+int main(int argc, char** argv)
+{
+ FILE* in;
+ FILE* out;
+ size_t input_size;
+ size_t output_size;
+ size_t bytes_written;
+ int rc = -1;
+
+ do
+ {
+ if(argc > 3)
+ {
+ fprintf(stderr, "Usage: %s [input file] [output file]\n", argv[0]);
+ }
+
+ if(argc < 3)
+ {
+ out = stdout;
+ }
+ else
+ {
+ //open the output file for writing
+ out = fopen(argv[2], "w");
+ if(!out)
+ {
+ perror("failed to open file for writing");
+ break;
+ }
+ }
+
+ if(argc < 2)
+ {
+ in = stdin;
+ }
+ else
+ {
+ //open the input file for reading
+ in = fopen(argv[1], "r");
+ if(!in)
+ {
+ perror("failed to open file for reading");
+ break;
+ }
+ }
+
+ //read the input stream until we reach EOF or the max size
+ input_size = fread(inbuf, 1, MAX_INPUT_SIZE, in);
+ if(!feof(in))
+ {
+ if(ferror(in))
+ {
+ perror("failed to read input file");
+ break;
+ }
+ else
+ {
+ fprintf(stderr, "Input stream exceeds max size of %d bytes. Exiting.\n", MAX_INPUT_SIZE);
+ break;
+ }
+ }
+
+ output_size = MAX_OUTPUT_SIZE;
+
+ //Actual size of output buffer will be set upon successful completion
+ rc = ppe2fsp(inbuf, input_size, outbuf, &output_size);
+ if(rc)
+ {
+ fprintf(stderr, "Failed converting ppe trace to fsp trace. rc = %d\n", rc);
+ if(rc == P2F_INVALID_VERSION)
+ {
+ fprintf(stderr, "PPE trace buffer must be version %d.\n", PK_TRACE_VERSION);
+ }
+ break;
+ }
+
+ rc = -1;
+ //operation was successful. Write out the fsp trace data
+ bytes_written = fwrite(outbuf, 1, output_size, out);
+ if(bytes_written != output_size)
+ {
+ if(ferror(out))
+ {
+ perror("Failed to write output stream");
+ break;
+ }
+ fprintf(stderr, "Failure: Only able to write %d of %d bytes to output stream\n", bytes_written, output_size);
+ break;
+ }
+
+ fclose(in);
+ fclose(out);
+ fclose(stderr);
+
+ rc = 0;
+ }while(0);
+
+ return rc;
+}
+
+
+
+
+
+
diff --git a/src/tools/ppetracepp/ppetracepp.C b/src/tools/ppetracepp/ppetracepp.C
new file mode 100755
index 00000000..2829e4dd
--- /dev/null
+++ b/src/tools/ppetracepp/ppetracepp.C
@@ -0,0 +1,949 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/ppetracepp.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 */
+
+/*
+# *** ppetracepp - a fsp/common Linux trace pre processor
+# this one replaces the trace strings by the corresponding hash value
+# (i.e. the complete call to trace_ppe_hash is replaced)
+
+# *** Usage
+#
+# prepend compiler call with the call of this pre processor, i.e if you have
+# $(CC) $(CFLAGS) -o $@ $<
+# in your Makefile change it to this:
+# ppetracepp $(CC) $(CFLAGS) -o $@ $<
+# ppetracepp will use "$(CC) -E" to call the C pre processor "cpp".
+# you can set a env var "REALCPP" to the name of a program to select
+# a different programm as cpp
+#
+# ppetracepp creates a file "$target.ppe.hash" with the trace strings and the hash values.
+#
+# to enable debug mode set envvar PPETRACEPPDEBUG to 1 or give '-d' as first arg
+
+# *** Change History
+#
+# 2003-02-26 RBa created from scratch
+# 2003-02-28 RBa add C++ support (C++ interface uses own type for the hash)
+# 2003-05-28 RBa if cc should link instead of compile just call compiler
+# 2003-07-11 AGe Change search alg. slightly and put just format back
+# 2003-07-25 RBa just call gcc if called to link instead to compile
+# eat argument for option -x
+# 2003-11-26 RBa fix c/c++ algo: compile as c++ if realcc=*g++
+# 2004-02-02 RBa remove explicit test whether source file is readable
+# it is obsolete and might lead to an error if afs is used
+# 2004-02-13 RBa add support for dependency generation (-MD/-MG, -MF)
+# don't prepend './' to object filename
+# 2006-04-19 RBa rewrite trace_ppe_write_all support, handle C and C++ the same
+# 2006-05-24 RBa fix handling of missing -o ; add TRAC_PPVER for macro/API version
+# 2006-09-15 RBa add handling of \" in trace format strings ; reduce non-error output
+# put object file in current dir if no -o given
+# 2007-03-22 RBa handle more gcc options (-i) ; protect " in call to shell
+# store output of cpp as "unmodified" output for debug
+# only write string/hash file if strings found
+# 2012-09-24 hlava Rewritten as C program for better build performance (was perl)
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <string>
+#include <time.h>
+#include <fcntl.h>
+#include <map>
+#include <vector>
+#include <unistd.h>
+#include <sys/types.h>
+typedef u_int32_t u32 ;
+typedef u_int8_t u8 ;
+#include <jhash.h>
+
+using namespace std;
+
+static string version = "2.0";
+static string macro_version = "1";
+
+static bool debug = false;
+#define dprintf(format, ...) if (debug) { printf(format, ##__VA_ARGS__); fflush(stdout); }
+static map<string,string> hashtab;
+static string hashtype;
+static string hashtype_suffix;
+
+static string tmp;
+static string cmd;
+static FILE* CPP = NULL; // pipe from preprocessor
+static FILE* CC = NULL; // pipe to compiler
+static FILE* DEBUG = NULL;
+static FILE* DEBUGIN = NULL;
+
+//*****************************************************************************
+// replace_substr
+//*****************************************************************************
+void replace_substr(std::string& str, const std::string& oldStr, const std::string& newStr)
+{
+ size_t pos = 0;
+ while((pos = str.find(oldStr, pos)) != std::string::npos)
+ {
+ str.replace(pos, oldStr.length(), newStr);
+ pos += newStr.length();
+ }
+
+}
+
+//*****************************************************************************
+// fileparse
+//*****************************************************************************
+void fileparse(const string& in_str, string& name, string& dir, string& suff)
+{
+ string str(in_str);
+ size_t pos;
+ name = "";
+ dir = "";
+ suff = "";
+ pos = str.find_last_of('.');
+ if (pos != string::npos)
+ {
+ suff = str.substr(pos);
+ str = str.substr(0, pos);
+ }
+ pos = str.find_last_of('/');
+ if (pos != string::npos)
+ {
+ name = str.substr(pos+1);
+ str = str.substr(0, pos+1);
+ }
+ dir = str;
+}
+
+static const size_t TRACE_PPE_HASH_LEN = 13;
+//*****************************************************************************
+// chop_up_line
+//*****************************************************************************
+bool chop_up_line(string& in_line, string& prefix, string& strings, string& salt, string& suffix)
+{
+ // First see if this line matches the pattern we're looking for
+ // Since this will return false 95%+ of the time this function it called, we do it
+ // before doing any other init for performance reasons.
+ size_t pos = in_line.find("trace_ppe_hash");
+ if (pos == string::npos) { return(false); }
+
+ // trace_ppe_hash ( "..." ".." "..." , 2 )
+ // regex: PREFIX 'trace_ppe_hash' space '(' space STRINGS space ',' space NUMBER space ')' SUFFIX
+ // STRINGS: '"' .* '"' space? +
+
+ // Original perl magic incantation:
+ // while($line =~ m/^(.*?)trace_ppe_hash\s*\(\s*((".*?(?<!\\)"\s*)+),\s*(-?\d+)\s*\)(.*)$/) {
+ // ($prefix, $strings, $salt, $suffix) = ($1, $2, $4, $5);
+ //
+ // Decrypting the magic pattern matching...
+ // (.*?) => $1 = everything up to the word "trace_ppe_hash"
+ // trace_ppe_hash = delimiter
+ // \s*\(\s* = delimiter = <0-n whitespace chars>, left paren, <0-n whitespace chars>
+ // ((".*?(?<!\\)"\s*)+) => $2 = double-quote, some chars up to last closing double-quote ($3 used for nested regex)
+ // ,\s* = delimiter = comma followed by some whitespace
+ // (-?\d+)\s*\)(.*) => $4 and $5
+ // $/) = end of the line input string
+ string line(in_line);
+ prefix = "";
+ strings = "";
+ salt = "";
+ suffix = "";
+ size_t pos1;
+ size_t pos2;
+ size_t pos3;
+
+ pos1 = pos + 14; // pos1 = after "trace_ppe_hash"
+ pos2 = line.find("(", pos1);
+ if (pos2 == string::npos) { return(false); }
+ ++pos2;
+ pos3 = line.find("\"", pos2);
+ if (pos3 == string::npos) { return(false); }
+ dprintf("--------\nchop_up_line: Passed basic checks. line= %s\n", line.c_str());
+ dprintf("pos1=%d, pos2=%d, pos3=%d\n", pos1, pos2, pos3);
+ if ((pos1 != (pos2-1)) && (line.find_first_not_of(" \t", pos1, (pos2-pos1)+1) != string::npos)) { return(false); } //non-whitespace?
+ if ((pos2 != pos3) && (line.find_first_not_of(" \t", pos2, (pos3-pos2)) != string::npos)) { return(false); } //non-whitespace?
+
+ // Get the prefix data
+ dprintf(">chop_up_line(\"%s\",...)\n", line.c_str());
+ prefix = line.substr(0, pos);
+ line = line.substr(pos + TRACE_PPE_HASH_LEN);
+ dprintf(" prefix=\"%s\"\n", prefix.c_str());
+
+ // Get the strings and join/fix them: Store all strings between paired double-quotes up to the
+ // first comma not inside a string
+ pos = line.find_first_of('(');
+ if (pos == string::npos) { return(false); }
+ line = line.substr(pos + 1);
+ strings = "";
+ while(!line.empty())
+ {
+ pos = line.find_first_of(',');
+ pos1 = line.find_first_of('"');
+ if ((pos1 == string::npos) || ((pos != string::npos) && (pos < pos1))) { break; } // found comma before next quote
+ pos2 = line.find_first_of('"', (pos1+1));
+ if (pos2 == string::npos) { return(false); } // unbalanced quotes!
+ while(line[pos2-1] == '\\') // skip escaped quotes in the string (they're not the ending quote)
+ {
+ pos2 = line.find_first_of('"', (pos2+1));
+ if (pos2 == string::npos) { return(false); } // unbalanced quotes!
+ }
+ if (!strings.empty()) { strings += " "; }
+ strings += line.substr(pos1, (pos2-pos1)+1);
+ line = line.substr(pos2+1);
+ }
+ replace_substr(strings, "\" \"", "");
+ replace_substr(strings, "\\\"", "ESCAPEDQUOTE");
+ replace_substr(strings, "\"", "");
+ replace_substr(strings, "ESCAPEDQUOTE", "\"");
+ // Remove trailing whitespace ah20130717
+ pos = strings.find_last_not_of(" \t\n");
+ if ((pos != string::npos) && (pos < (strings.length()-1)))
+ {
+ strings = strings.substr(0, pos+1);
+ }
+
+ dprintf(" strings>%s<\n", strings.c_str());
+
+ // Get the salt
+ pos = line.find(",");
+ if (pos != string::npos) { line = line.substr(pos+1); }
+ pos = line.find_first_of(')');
+ if (pos == string::npos) { return(false); }
+ salt = line.substr(0, pos);
+ line = line.substr(pos+1);
+ //dprintf(" salt=\"%s\"\n", salt.c_str());
+ pos = salt.find_first_not_of(" \t\n");
+ if (pos == string::npos) { return(false); }
+ salt = salt.substr(pos);
+ pos = salt.find_last_not_of(" \t\n");
+ if (pos == string::npos) { return(false); }
+ salt = salt.substr(0, pos+1);
+ dprintf(" salt=\"%s\"\n", salt.c_str());
+
+ // Get the suffix (i.e. the rest)
+ suffix = line;
+ if (suffix[suffix.length()-1] == '\n') { suffix = suffix.substr(0, suffix.length()-1); }
+ dprintf(" suffix=\"%s\"\n<chop_up_line() returning true\n", suffix.c_str());
+
+ return(true);
+}
+
+//*****************************************************************************
+// get_format_string
+//*****************************************************************************
+int get_format_string(const string& in_str, string& format)
+{
+ int format_salt = 0;
+ size_t pos;
+ size_t pos_end;
+ string str(in_str);
+ // (@format_param) = ($strings =~ /(%[#0\- +'I]*\d*(?:\.\d*)?[hlLqjzt]*[diouxXeEfFgGaAcsCSpn])/g);
+ // $format = join(',', @format_param);
+ // Decrypting the regular expression magic...
+ // (%[#0\- +'I]*\d*(?:\.\d*)?[hlLqjzt]*[diouxXeEfFgGaAcsCSpn])
+
+ format = "";
+ while(!str.empty())
+ {
+ pos = str.find("%");
+ if (pos == string::npos) { break; }
+ if (pos == (str.length()-1)) { break; } // last char in string? just skip it
+ if (str[pos+1] == '%') // double percent sign? just skip first one
+ {
+ str = str.substr(pos+1);
+ continue;
+ }
+ pos_end = str.find_first_of("cdieEfgGosuxXpn", pos); // find formatting specifier
+ if (pos_end == string::npos)
+ {
+ fprintf(stderr, "ERROR: ppetracepp could not parse trace formatting string \"%s\" in \"%s\"\n", str.c_str(), in_str.c_str());
+ break;
+ }
+
+ if (!format.empty())
+ format += ",";
+ format += str.substr(pos, (pos_end-pos)+1);
+ ++format_salt;
+
+ str = str.substr(pos_end+1);
+ }
+ // Correct for escaped percent signs
+ string temp_str(in_str);
+ while((pos = temp_str.find("%%")) != string::npos)
+ {
+ if (pos < (temp_str.length()-2)) // Not the last thing in the string?
+ {
+ dprintf(" decrementing salt value %d\n", format_salt);
+ --format_salt;
+ temp_str = temp_str.substr(pos+2);
+ }
+ else
+ {
+ temp_str = "";
+ }
+ }
+
+ return(format_salt);
+}
+
+#define BUF_SIZE 40
+//*****************************************************************************
+// get_hash
+//*****************************************************************************
+void get_hash(const string& i_str, const unsigned int salt_num, string& hash32, string& hash16)
+{
+ string str(i_str);
+ unsigned int hash_num = 0;
+ char buf[BUF_SIZE];
+
+ hash16 = "";
+ hash32 = "";
+ dprintf(">get_hash(\"%s\",%d)\n", str.c_str(), salt_num);
+
+ // Call jhash function to get the hash value
+ hash_num = jhash((void*)str.c_str(), str.length(), salt_num);
+ dprintf("jhash() returned: %u\n", hash_num);
+ sprintf(buf, "%u", hash_num & 0x0000ffff);
+ hash16 = buf;
+ sprintf(buf, "%u", ((salt_num << 16) | (hash_num & 0x0000ffff)));
+ hash32 = buf;
+
+ // validate the hash value
+ size_t pos = hash32.find_first_not_of("0123456789");
+ if (pos != string::npos)
+ {
+ fprintf(stderr, "trexhash error: %s\n", hash32.c_str());
+ fprintf(stderr, "for call <<%s>>\n", cmd.c_str());
+ exit(1);
+ }
+
+//removing this since it doesn't seem to have any affect on the output
+#if 0
+ // If hash is empty, use the sum of the ord values in the original string
+ if ((hash == "")||(hash == "0"))
+ {
+ unsigned int len = str.length();
+ unsigned int hash_num = 0;
+ //unsigned char conv_buf[2] = { '\0', '\0' };
+ u_int8_t conv_num;
+ for (unsigned int i=0; i < len; ++i)
+ {
+ //conv_buf[0] = str[i];
+ conv_num = (u_int8_t)str[i];
+ hash_num += (unsigned int)conv_num;
+ }
+ }
+#endif
+
+ dprintf("<get_hash(\"%s\",%d) returned hash: %s\n", str.c_str(), salt_num, hash32.c_str());
+}
+
+//*****************************************************************************
+// parse_line
+//*****************************************************************************
+void parse_line(map<string,string>& rhash, string& line, string& out_line)
+{
+ // NOTE: "line" arg may get modified by this function! Caller must not assume it's unchanged.
+ string format;
+ string prefix;
+ string strings;
+ string tmp;
+ string salt;
+ string hash16;
+ string hash32;
+ int salt_num;
+ int format_salt;
+ string suffix;
+ string write_all_suffix;
+ size_t pos;
+
+ out_line = "";
+ // trace_ppe_hash ( "..." ".." "..." , 2 )
+ // regex: PREFIX 'trace_ppe_hash' space '(' space STRINGS space ',' space NUMBER space ')' SUFFIX
+ // STRINGS: '"' .* '"' space? +
+ //while($line =~ m/^(.*?)trace_ppe_hash\s*\(\s*((".*?(?<!\\)"\s*)+),\s*(-?\d+)\s*\)(.*)$/) {
+ // Attempt to approximate the above amazing perl regex...
+ while( chop_up_line(line, prefix, strings, salt, suffix) )
+ {
+ //dprintf("\n\nprefix = %s\nstrings = %s\nsalt = %s\nsuffix = %s\n",
+ // prefix.c_str(), strings.c_str(), salt.c_str(), suffix.c_str());
+ // is this a trace_ppe_write_all call?
+ pos = prefix.find("trace_ppe_write_all");
+ if (pos != string::npos)
+ {
+ // yes. replace trace_ppe_hash with hash value and reduced format string
+ format_salt = get_format_string(strings, format);
+ // reduced format string will be added after hash value
+ write_all_suffix = ",\" ";
+ write_all_suffix += format;
+ write_all_suffix += "\"";
+
+ if (!salt.empty())
+ {
+ salt_num = atoi(salt.c_str());
+ }
+ else
+ {
+ salt_num = -1;
+ }
+
+ if (salt_num == -1)
+ {
+ salt_num = format_salt;
+ }
+ else if (salt_num != format_salt)
+ {
+ fprintf(stderr, "ERROR: printf mismatch in '%s': TRACE says %d, format says %d args\n",
+ line.c_str(), salt_num, format_salt);
+ }
+ }
+ else
+ {
+ write_all_suffix = "";
+ salt_num = atoi(salt.c_str());
+ }
+
+ // get the trex hash value for the strings
+ get_hash(strings, salt_num, hash32, hash16);
+
+ // check for duplicate and store the mapping
+ if ((rhash.find(hash32) != rhash.end()) && (rhash[hash32] != strings))
+ {
+ fprintf(stderr, "hash collision: two different strings give the same hash value '%s'\n", hash32.c_str());
+ fprintf(stderr, "%s\n%s\n", strings.c_str(), rhash[hash32].c_str());
+ // Not breaking the compilation here. This is same as if we get hash
+ // collision across files. As in SBE we are using mirroring, these
+ // hash collisions will take some time to resolve. Till that time,
+ // let us allow compilation of procedures.
+ //return;
+ }
+ rhash[hash32] = strings;
+
+ // add the modified line to the output
+ tmp = prefix;
+ tmp += "(";
+ tmp += hashtype;
+ tmp += " ";
+ tmp += hash16;
+ tmp += hashtype_suffix;
+ tmp += ")";
+ tmp += write_all_suffix;
+ out_line += tmp;
+ dprintf("changed call: %s...\n", tmp.c_str());
+ line = suffix;
+ }
+ out_line += line;
+ if (out_line[out_line.length()-1] != '\n')
+ out_line += "\n";
+}
+
+//*****************************************************************************
+// main
+//*****************************************************************************
+int main(int argc, char** argv)
+{
+ char* p_env = getenv("PPETRACEPPDEBUG");
+ if (p_env)
+ debug = true;
+
+
+ int argi = 1;
+ string arg;
+ string optarg;
+ if (argc > 1) arg = argv[1];
+ if ((argc < 2) || (arg == "-h"))
+ {
+ fprintf(stderr, "usage: %s realcompiler compileroptions -o target source\n", argv[0]);
+ exit(9);
+ }
+ string realcc(argv[argi++]);
+ string cctype("c++");
+ bool optx_found = false;
+
+ if (realcc == "-d")
+ {
+ debug = true;
+ realcc = argv[argi++];
+ }
+
+ // wait until -d options is handled before checking $debug
+ dprintf("ppetracepp version %s - API/macro version %s\n", version.c_str(), macro_version.c_str());
+
+ p_env = getenv("REALCPP");
+ string realcpp;
+ if (p_env)
+ realcpp = p_env;
+ if (realcpp.empty())
+ {
+ dprintf("cannot find cpp, using <realcompiler> -E\n");
+ realcpp = realcc;
+ realcpp += " -E";
+ }
+ dprintf("realcpp is %s\n", realcpp.c_str());
+
+//------------------------------------------------------------------------------
+// parse all the arguments
+//------------------------------------------------------------------------------
+string source;
+string object;
+vector<string> ccopts;
+vector<string> cppopts;
+bool dodeps = false;
+string depfile;
+string pfx;
+string sfx;
+int origargi = argi;
+for( ; argi < argc; ++argi)
+{
+ arg = argv[argi];
+ dprintf("Processing argv[%d]: \"%s\"\n", argi, arg.c_str());
+ if (arg.length() > 2)
+ {
+ pfx = arg.substr(0,2);
+ sfx = arg.substr(arg.length()-2);
+ }
+ else
+ {
+ pfx = arg;
+ sfx = arg;
+ }
+ dprintf(" pfx: \"%s\" sfx: \"%s\"\n", pfx.c_str(), sfx.c_str());
+
+ if (pfx == "-o")
+ {
+ if (! object.empty())
+ {
+ fprintf(stderr, "two -o options, aborting\n");
+ exit(1);
+ }
+ if (arg.length() > 2)
+ {
+ object = sfx;
+ }
+ else
+ {
+ object = argv[++argi];
+ }
+ dprintf("object is now %s\n", object.c_str());
+ }
+ else if (arg == "-c")
+ {
+ // don't call cpp with -c, this is for the compiler
+ ccopts.push_back(arg);
+ dprintf("found -c option\n");
+ }
+ else if (pfx == "-l")
+ {
+ // cpp doesn't need library arguments
+ cppopts.push_back(arg);
+ }
+ else if (pfx == "-i")
+ {
+ // option takes an argument, handle it too
+ optarg = argv[argi++];
+ ccopts.push_back(arg);
+ ccopts.push_back(optarg);
+ cppopts.push_back(arg);
+ cppopts.push_back(optarg);
+ dprintf("found option '%s %s'\n", arg.c_str(), optarg.c_str());
+ }
+ else if ((arg == "-L") ||
+ (arg == "-I") ||
+ (arg == "-x") ||
+ (arg == "-b") ||
+ (arg == "-B") ||
+ (arg == "-V") ||
+ (arg == "-D") ||
+ (arg == "--param") ||
+ (arg == "-MQ") ||
+ (arg == "-MT"))
+ {
+ // option takes an argument, handle it too
+ optarg = argv[argi++];
+ ccopts.push_back(arg);
+ ccopts.push_back(optarg);
+ cppopts.push_back(arg);
+ cppopts.push_back(optarg);
+ dprintf("found option '%s %s'\n", arg.c_str(), optarg.c_str());
+ if (arg == "-x")
+ {
+ // option x sets the language - c or c++
+ if ((optarg != "c") && (optarg != "c++") && (optarg != "assembler-with-cpp"))
+ {
+ fprintf(stderr, "cannot process language '%s', aborting\n", optarg.c_str());
+ exit(1);
+ }
+ cctype = optarg;
+ optx_found = true;
+ }
+ }
+ else if ((arg == "-MD")||(arg == "-MG"))
+ {
+ // gen deps
+ dodeps = true;
+ dprintf("found %s, creating dependencies\n", arg.c_str());
+ }
+ else if (arg == "-MF")
+ {
+ // set dependencies file
+ depfile = argv[argi++];
+ dprintf("set dependencies file to '%s'\n", depfile.c_str());
+ }
+ else if (arg[0] == '-')
+ {
+ // arg starts with - so it's an option
+ ccopts.push_back(arg);
+ cppopts.push_back(arg);
+ dprintf("found option '%s'\n", arg.c_str());
+ }
+ else if ((sfx == ".a") ||
+ (sfx == ".o"))
+ {
+ // an object or archive, ignore this but give it to cc
+ ccopts.push_back(arg);
+ dprintf("found object/archive '%s'\n", arg.c_str());
+ }
+ else if ((sfx == ".c") ||
+ (sfx == ".C") ||
+ (sfx == ".S") ||
+ (arg.substr(arg.length()-4) == ".cpp") ||
+ (arg.substr(arg.length()-4) == ".cxx"))
+ {
+ // the source file(s). we should only get one
+ if (!source.empty())
+ {
+ fprintf(stderr, "don't know to handle two source files, aborting\n");
+ exit(1);
+ }
+ source = arg;
+ // put the - (for read-from-stdin) where the source file was
+ // (order is important!)
+ ccopts.push_back("-");
+ dprintf("found source file %s\n", source.c_str());
+ }
+ else if (access(arg.c_str(), F_OK))
+ {
+ // option but not a file, an unknown option?
+ ccopts.push_back(arg);
+ cppopts.push_back(arg);
+ dprintf("found unknown option '%s'\n", arg.c_str());
+ }
+}
+
+//------------------------------------------------------------------------------
+// set other parameters based on arguments specified
+//------------------------------------------------------------------------------
+if (source.empty())
+{
+ // this might be a call to link a program instead of compile a source (or asm source)
+ dprintf("NOTME: starting as cc '%s ...'\n", realcc.c_str());
+ execvp(realcc.c_str(), &(argv[origargi]));
+ fprintf(stderr, "ERROR: returned from execvp() call to run %s\n", realcc.c_str());
+}
+if (object.empty())
+{
+ dprintf("no object file given, default to source name\n");
+ // gcc builds object name from source name if no -o given, replacing
+ // suffix with .o. The file is placed in the current directory,
+ // not in the source directory!
+ string n;
+ string d;
+ string s;
+ fileparse(source, n, d, s);
+ if (!n.empty() && !s.empty())
+ {
+ object = n + ".o";
+ dprintf("tracpp: guessing object name %s\n", object.c_str());
+ dprintf(" from source name %s\n", source.c_str());
+ }
+ else
+ {
+ fprintf(stderr, "Unable to determine Source File Name\n");
+ exit(1);;
+ }
+}
+
+// set value of trace hash according to language
+// check source file extension if no explicit -x option given
+if (!optx_found)
+{
+ if (realcc.find("g++") != string::npos)
+ {
+ dprintf("compiler language: C++ (from compiler name)\n");
+ cctype = "c++";
+ }
+ else
+ {
+ if (source.substr(source.length()-2) == ".c")
+ {
+ dprintf("compiler language: C (from source file extension)\n");
+ cctype = "c";
+ }
+ else if (source.substr(source.length()-2) == ".S")
+ {
+ dprintf("compiler language: assembly (from source file extension)\n");
+ cctype = "assembler-with-cpp";
+ }
+ else
+ {
+ dprintf("compiler language: C++ (default)\n");
+ cctype = "c++";
+ }
+ }
+}
+else
+{
+ dprintf("compiler language: %s (from option '-x')\n", cctype.c_str());
+}
+
+if (cctype == "c")
+{
+ hashtype = "(unsigned short)";
+ hashtype_suffix = "U";
+}
+else if (cctype == "assembler-with-cpp")
+{
+ hashtype = "";
+ hashtype_suffix = "";
+}
+else
+{
+ hashtype = "(trace_hash_val)";
+ hashtype_suffix = "U";
+}
+// define TRAC_PPETRACEPP for macros
+tmp = "-DTRAC_PPETRACEPP -DTRAC_PPVER=";
+tmp += macro_version;
+cppopts.push_back(tmp);
+if (dodeps)
+{
+ if (depfile.empty())
+ {
+ if ((p_env = getenv("DEPENDENCIES_OUTPUT")) != NULL)
+ {
+ depfile = p_env;
+ }
+ else if ((p_env = getenv("SUNPRO_DEPENDENCIES")) != NULL)
+ {
+ depfile = p_env;
+ }
+ else
+ {
+ depfile = object;
+ if (depfile.substr(depfile.length()-2) == ".o")
+ {
+ depfile = depfile.substr(0, depfile.length()-2);
+ depfile += ".d";
+ }
+ }
+ }
+ tmp = "-MD -MF ";
+ tmp += depfile;
+ cppopts.push_back(tmp);
+}
+
+//------------------------------------------------------------------------------
+// start cpp
+//------------------------------------------------------------------------------
+cmd = realcpp;
+for(vector<string>::iterator p = cppopts.begin(); p != cppopts.end(); ++p)
+{
+ cmd += " ";
+ cmd += *p;
+}
+cmd += " ";
+cmd += source;
+cmd += " -o-";
+dprintf("starting as cpp '%s'\n", cmd.c_str());
+CPP = popen(cmd.c_str(), "r");
+if (CPP == NULL)
+{
+ fprintf(stderr, "cannot start cpp '%s'\n", realcpp.c_str());
+ perror("");
+ exit(1);
+}
+
+//------------------------------------------------------------------------------
+// start cc. manually set language as source file extension not available to cc
+//------------------------------------------------------------------------------
+string type_str = "";
+if (!optx_found)
+{
+ // no option -x given by caller, set manually
+ type_str = "-x ";
+ type_str += cctype;
+}
+cmd = realcc;
+cmd += " ";
+cmd += type_str;
+for(vector<string>::iterator p = ccopts.begin(); p != ccopts.end(); ++p)
+{
+ cmd += " ";
+ cmd += *p;
+}
+cmd += " -o ";
+cmd += object;
+dprintf("starting as cc '%s'\n", cmd.c_str());
+CC = popen(cmd.c_str(), "w");
+if (CC == NULL)
+{
+ fprintf(stderr, "cannot start cc '%s'\n", realcc.c_str());
+ perror("");
+ exit(1);
+}
+
+string modifiedfile;
+string unmodifiedfile;
+if (debug)
+{
+ modifiedfile = object + ".debug";
+ DEBUG = fopen(modifiedfile.c_str(), "w");
+ if (DEBUG == NULL)
+ {
+ string msg = "cannot open file ";
+ msg += modifiedfile;
+ perror(msg.c_str());
+ modifiedfile = "";
+ }
+ else
+ {
+ fprintf(stderr, "writing preprocessed source to %s\n", modifiedfile.c_str());
+ }
+ unmodifiedfile = object + ".debug_in";
+ DEBUGIN = fopen(unmodifiedfile.c_str(), "w");
+ if (DEBUGIN == NULL)
+ {
+ string msg = "cannot open file ";
+ msg += unmodifiedfile;
+ perror(msg.c_str());
+ unmodifiedfile = "";
+ }
+ else
+ {
+ fprintf(stderr, "writing unprocessed source to %s\n", unmodifiedfile.c_str());
+ }
+}
+
+string oldline;
+string newline;
+static const int MAX_BUFFER = 51200;
+char buf[MAX_BUFFER];
+while (!feof(CPP))
+{
+ if (fgets(buf, MAX_BUFFER, CPP) != NULL)
+ {
+ oldline = buf;
+ if (DEBUGIN) { fprintf(DEBUGIN, "%s", oldline.c_str()); }
+ parse_line(hashtab, oldline, newline);
+ //#print "oldline = $oldline";
+ //#print "newline = $newline";
+ if (newline.empty())
+ {
+ fprintf(stderr, "hash error in/with file %s\n", source.c_str());
+ exit(1);
+ }
+ //#print "newline = $newline\n";
+ fprintf(CC, "%s", newline.c_str());
+ if (DEBUG) { fprintf(DEBUG, "%s", newline.c_str()); }
+ }
+}
+if (DEBUG) { fclose(DEBUG); }
+if (DEBUGIN) { fclose(DEBUGIN); }
+int cmd_rc = pclose(CPP);
+if (cmd_rc)
+{
+ fprintf(stderr, "error from cpp\n");
+ if (cmd_rc & 127)
+ {
+ fprintf(stderr, "cpp got signal %d\n", (cmd_rc & 127));
+ exit(1);
+ }
+ else if (cmd_rc >> 8)
+ {
+ fprintf(stderr, "cpp returned %d\n", (cmd_rc >> 8));
+ exit(cmd_rc >> 8);
+ }
+}
+cmd_rc = pclose(CC);
+if (cmd_rc)
+{
+ fprintf(stderr, "error from cc\n");
+ if (cmd_rc & 127)
+ {
+ fprintf(stderr, "cc got signal %d\n", (cmd_rc & 127));
+ exit(1);
+ }
+ else if (cmd_rc >> 8)
+ {
+ fprintf(stderr, "cc returned %d\n", (cmd_rc >> 8));
+ exit(cmd_rc >> 8);
+ }
+}
+
+if (!hashtab.empty())
+{
+ string stringfile = object;
+ stringfile += ".ppe.hash";
+ // open trace string file
+ FILE* TRC = fopen(stringfile.c_str(), "w");
+ if (TRC == NULL)
+ {
+ fprintf(stderr, "cannot write trace string file '%s'\n", stringfile.c_str());
+ exit(1);
+ }
+ dprintf("Writing to file %s\n", stringfile.c_str());
+
+ string pwd;
+ FILE* PWD = popen("pwd", "r");
+ fgets(buf, MAX_BUFFER, PWD);
+ pwd = buf;
+ pclose(PWD);
+ time_t tt = time(NULL);
+ sprintf(buf, "%s", asctime(localtime(&tt)));
+ buf[strlen(buf)-1] = '\0'; // chop off extra newline
+ fprintf(TRC, "#FSP_TRACE_v2|||%s|||BUILD:%s", buf, pwd.c_str());
+
+ string srch_str = "||";
+ srch_str += source;
+ int srch_str_len = srch_str.length();
+ size_t pos;
+ for(map<string,string>::iterator p = hashtab.begin(); p != hashtab.end(); ++p)
+ {
+ pos = (p->second).find(srch_str);
+ if ((pos != string::npos) && ((pos + srch_str_len) == (p->second).length()))
+ {
+ // source file name is already part of the string
+ fprintf(TRC, "%s||%s\n", (p->first).c_str(), (p->second).c_str());
+ }
+ else
+ {
+ fprintf(TRC, "%s||%s||%s\n", (p->first).c_str(), (p->second).c_str(), source.c_str());
+ }
+ //#print TRC "$key||$source||$hashtab{$key}\n";
+ }
+ fclose(TRC);
+}
+else
+{
+ dprintf("No trace calls/strings found, not writing hash file\n");
+}
+} // end main
diff --git a/src/tools/ppetracepp/trac_interface.h b/src/tools/ppetracepp/trac_interface.h
new file mode 100755
index 00000000..2ff9dff0
--- /dev/null
+++ b/src/tools/ppetracepp/trac_interface.h
@@ -0,0 +1,369 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/ppetracepp/trac_interface.h $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* */
+/* */
+/* 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 */
+/******************************************************************************
+// @file trac_interface.h
+// @brief Interface codes for TRAC component.
+*/
+/******************************************************************************
+ *
+ * @page ChangeLogs Change Logs
+ * @section _trac_interface_h trac_interface.h
+ * @verbatim
+ *
+ * Flag Def/Fea Userid Date Description
+ * ------- ---------- -------- ---------- ----------------------------------
+ * TEAM 06/16/2010 Port
+ * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments
+ * @pb00E pbavari 03/11/2012 Added correct include file
+ * @at009 859308 alvinwan 10/15/2012 Added tracepp support
+ * @ai005 860268 ailutsar 11/20/2012 Create trace test applet
+ * @rc005 864101 rickylie 12/12/2012 add small circ buffer to handle ISR semaphore conflict
+ *
+ * @endverbatim
+ *
+ *///*************************************************************************/
+
+#ifndef _TRAC_INTERFACE_H
+#define _TRAC_INTERFACE_H
+
+/** \defgroup Trace Trace Component
+ * Port of the trace code used in the fsp and tpmd.
+ */
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+/**
+ * \defgroup TracMacros Trace Component Macro Interfaces
+ * \ingroup Trace
+ * Used to trace 0 - 5 arguments or a binary buffer when using a hash value.
+ */
+/*@{*/
+
+
+// @at009c - start
+#define TRACE(i_td,i_string,args...) \
+ trace_adal_write_all(i_td,trace_adal_hash(i_string,-1),__LINE__,0,##args)
+
+#define TRACEBIN(i_td,i_string,i_ptr,i_size) \
+ trac_write_bin(i_td,trace_adal_hash(i_string,0),__LINE__,i_ptr,i_size)
+
+#ifndef NO_TRAC_STRINGS
+
+#define FIELD(a) \
+ printf("%s",a)
+
+#define FIELD1(a,b) \
+ printf("%s%lx",a,(unsigned long)b)
+
+#else // NO_TRAC_STRINGS
+
+#define FIELD(a)
+
+#define FIELD1(a,b)
+
+#endif // NO_TRAC_STRINGS
+
+#define SUCCESS 0
+// @at009c - end
+
+
+
+/*@}*/
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+#define TRACE_MAX_ARGS 5 /*!< Maximum number of args to trace */
+
+typedef uint32_t trace_hash_val;
+
+// NOTE! Increment this when new components are added!
+#define TRAC_NUM_TRACE_COMPONENTS 1
+
+
+#define TRACE_BUFFER_SIZE 8192 // @ai005a
+
+#define CIRCULAR_BUFFER_SIZE 4 // @rc005a
+
+typedef uint32_t UINT32;
+typedef int32_t INT32;
+typedef uint8_t UCHAR;
+typedef uint8_t UINT8;
+typedef int8_t INT8;
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef char CHAR;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+typedef int INT;
+typedef void VOID;
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+/*
+ * @brief Structure is put at beginning of all trace buffers
+ */
+typedef struct trace_buf_head {
+ UCHAR ver; /*!< version of this struct (1) */
+ UCHAR hdr_len; /*!< size of this struct in bytes */
+ UCHAR time_flg; /*!< meaning of timestamp entry field */
+ UCHAR endian_flg; /*!< flag for big ('B') or little ('L') endian */
+ CHAR comp[16]; /*!< the buffer name as specified in init call */
+ UINT32 size; /*!< size of buffer, including this struct */
+ UINT32 times_wrap; /*!< how often the buffer wrapped */
+ UINT32 next_free; /*!< offset of the byte behind the latest entry */
+ UINT32 te_count; /*!< Updated each time a trace is done */
+ UINT32 extracted; /*!< Not currently used */
+}trace_buf_head_t;
+
+/*!
+ * @brief Timestamp and thread id for each trace entry.
+ */
+typedef struct trace_entry_stamp {
+ UINT32 tbh; /*!< timestamp upper part */
+ UINT32 tbl; /*!< timestamp lower part */
+ UINT32 tid; /*!< process/thread id */
+}trace_entry_stamp_t;
+
+/*
+ * @brief Structure is used by adal app. layer to fill in trace info.
+ */
+typedef struct trace_entry_head {
+ UINT16 length; /*!< size of trace entry */
+ UINT16 tag; /*!< type of entry: xTRACE xDUMP, (un)packed */
+ UINT32 hash; /*!< a value for the (format) string */
+ UINT32 line; /*!< source file line number of trace call */
+}trace_entry_head_t;
+
+/*
+ * @brief Parameter traces can be all contained in one write.
+ */
+typedef struct trace_entire_entry {
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+ UINT32 args[TRACE_MAX_ARGS + 1];
+} trace_entire_entry_t;
+
+
+/*
+ * @brief Binary first writes header and time stamp.
+ */
+typedef struct trace_bin_entry {
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+} trace_bin_entry_t;
+
+/**
+ * @brief Used as input to traces to get to correct buffer.
+ */
+typedef trace_buf_head_t * tracDesc_t;
+
+/*
+ * @brief Structure is used to hold array of all trace descriptors
+ */
+typedef struct trace_descriptor_array
+{
+ tracDesc_t *entry; /*!< Pointer to trace descriptor */
+ CHAR *comp; /*!< Pointer to component name */
+}trace_descriptor_array_t;
+
+// @rc005a - start
+typedef struct circular_buf_head
+{
+ UINT32 head; // pointer to head
+ UINT32 tail; // pointer to tail
+ UINT32 entryCount; // nums of entry
+} circular_buf_header_t;
+
+
+typedef struct circular_entire_data {
+ UINT32 len;
+ CHAR comp[4];
+ trace_entire_entry_t entry;
+} circular_entire_data_t;
+
+// @rc005a - end
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+// All TPMF component trace descriptors.
+extern tracDesc_t g_trac_inf; // @at009a
+extern tracDesc_t g_trac_err; // @at009a
+extern tracDesc_t g_trac_imp; // @at009a
+
+extern const trace_descriptor_array_t g_des_array[];
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+
+/**
+ * \defgroup TracIntefaces Trace Component Interfaces for External Use
+ * \ingroup Trace
+ */
+/*@{*/
+
+
+/**
+ * @brief Allocate and initialize all trace buffers in memory.
+ *
+ * This function will allocate memory for each of the pre-defined trace
+ * buffers, initilize the buffers with starting data, and setup the
+ * trace descriptors which each component will use to trace.
+ *
+ * This function must be called first before any components try to trace!
+ *
+ * @return Non-zero return code on error.
+ */
+UINT TRAC_init_buffers(void);
+
+/**
+ * @brief Retrieve full trace buffer for component i_comp
+ *
+ * This function assumes memory has already been allocated for
+ * the full trace buffer in o_data.
+ *
+ * @param i_td_ptr Trace descriptor of buffer to retrieve.
+ * @param o_data Pre-allocated pointer to where data will be stored.
+ *
+ * @return Non-zero return code on error
+ */
+UINT TRAC_get_buffer(const tracDesc_t i_td_ptr,
+ void *o_data);
+
+/**
+ * @brief Retrieve partial trace buffer for component i_comp
+ *
+ * This function assumes memory has already been allocated for
+ * the trace buffer (size io_size). This function will copy
+ * in up to io_size in bytes to the buffer and set io_size
+ * to the exact size that is copied in.
+ *
+ * @param i_td_ptr Trace descriptor of buffer to retrieve.
+ * @param o_data Pre-allocated pointer to where data will be stored.
+ * @param io_size Size of trace data to retrieve (input)
+ * Actual size of trace data stored (output)
+ *
+ * @return Non-zero return code on error
+ */
+UINT TRAC_get_buffer_partial(const tracDesc_t i_td_ptr,
+ void *o_data,
+ UINT *io_size);
+
+/**
+ * @brief Retrieve trace descriptor for input component name
+ *
+ * @param i_comp Component name to retrieve trace descriptor for.
+ *
+ * @return Valid trace descriptor on success, NULL on failure.
+ */
+tracDesc_t TRAC_get_td(const char *i_comp);
+
+/**
+ * @brief Reset all trace buffers
+ *
+ * @return Non-zero return code on error
+ */
+UINT TRAC_reset_buf(void);
+
+/*@}*/ // Ending tag for external interface module in doxygen
+
+
+/**
+ * @brief Trace input integers to trace buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * @param io_td Intialized trace descriptor point to buffer to trace to.
+ * @param i_hash Hash value to be recorded for this trace.
+ * @param i_fmt Output format
+ * @param i_line Line number trace is occurring on.
+ * @param i_type trace type. filed or debug.
+ * @param ... parames that are limited to a size of 4 bytes, i.e. int, uint32_t, nnn*
+ *
+ * @return Non-zero return code on error.
+ */
+UINT trace_adal_write_all(tracDesc_t io_td,const trace_hash_val i_hash,
+ const char *i_fmt,const ULONG i_line, const ULONG i_type,...);
+
+
+/**
+ * @brief Trace input integers to trace buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * @param io_td Intialized trace descriptor point to buffer to trace to.
+ * @param i_hash Hash value to be recorded for this trace.
+ * @param i_line Line number trace is occurring on.
+ * @param i_num_args Number of arguments to trace.
+ * @param i_1 Input Parameter 1
+ * @param i_2 Input Parameter 2
+ * @param i_3 Input Parameter 3
+ * @param i_4 Input Parameter 4
+ * @param i_5 Input Parameter 5
+ *
+ * @return Non-zero return code on error.
+ */
+UINT trac_write_int(tracDesc_t io_td,const trace_hash_val i_hash,
+ const ULONG i_line,
+ const UINT i_num_args,
+ const ULONG i_1,const ULONG i_2,const ULONG i_3,
+ const ULONG i_4,const ULONG i_5
+ );
+
+
+ /**
+ * @brief Trace binary data to buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * @param io_td Intialized trace descriptor point to buffer to trace to.
+ * @param i_hash Hash value to be recorded for this trace.
+ * @param i_line Line number trace is occurring on.
+ * @param i_ptr Pointer to binary data to trace.
+ * @param i_size Size of data to copy from i_ptr.
+ *
+ * @return Non-zero return code on error.
+ */
+UINT trac_write_bin(tracDesc_t io_td,const trace_hash_val i_hash,
+ const ULONG i_line,
+ const void *i_ptr,
+ const ULONG i_size);
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+#endif //_TRAC_INTERFACE_H
diff --git a/src/tools/ppetracepp/tracehash.pl b/src/tools/ppetracepp/tracehash.pl
new file mode 100755
index 00000000..8855adee
--- /dev/null
+++ b/src/tools/ppetracepp/tracehash.pl
@@ -0,0 +1,896 @@
+#!/usr/bin/perl -w
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/ppetracepp/tracehash.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+# File tracehash.pl created by B J Zander.
+
+use strict;
+
+sub determine_args();
+sub launch_cpp_and_parse($$);
+sub cpp_dir($);
+sub read_string_file();
+sub collect_files($);
+sub assimilate_file($);
+sub hash_strings();
+sub write_string_file();
+sub help();
+
+select (STDERR);
+$| = 1; # Make all prints to STDERR flush the buffer immediately
+select (STDOUT);
+$| = 1; # Make all prints to STDOUT flush the buffer immediately
+
+# Constants
+my $HEAD_SEP = "|||";
+my $HEAD_EYE_CATCHER = "#FSP_TRACE_v";
+my $HEAD_BUILD_FLAG = "BUILD:";
+my $HEAD_VER_FLAG = 2;
+my $BB_STRING_FILE = "/opt/fsp/etc/BB_StringFile";
+
+# Global Variables
+my $debug = 0;
+my $seperator = "&&&&";
+my $file_name = "sbeStringFile";
+my $in_sand;
+my ($backing) = $ENV{'bb'};
+my $hash_prog = "trexhash"; #default to in path
+my $build = "";
+my ($sandbox) = $ENV{'SANDBOX'} || "";
+my ($context) = $ENV{'CONTEXT'} || "";
+my ($sandboxbase) = $ENV{'SANDBOXBASE'} || "";
+my ($bb);
+my ($sourcebase) = "$sandboxbase/src";
+my ($version) = $HEAD_VER_FLAG; # default to oldest version
+my ($collect) = 0;
+my ($INCLUDE, $Arg, $file, $dir, $string_file);
+my $args = "";
+
+my $fail_on_collision = 0; # 1 = exit with error if hash collision occurs
+my $hash_filename_too = 0; # 1 = hash is calculated over format string + filename
+
+print "sourcebase = $sourcebase\n" if $debug;
+print "sandbox = $sandbox\n" if $debug;
+print "backing = $backing\n" if $debug;
+print "context = $context\n" if $debug;
+
+if ($context =~ /x86/)
+{
+ $bb = "i586-pc-linux-gnu";
+}
+else
+{
+ $bb = "powerpc-linux";
+}
+
+if(($sourcebase =~ /\w+/) && ($sandbox =~ /\w+/))
+{
+ $INCLUDE = "-I $sandboxbase/export/$context/fips/include -I $backing/export/$context/fips/include -I /opt/fsp/$bb/include/fsp -I/opt/fsp/$bb/include/ -include /opt/fsp/$bb/include/fsp/tracinterface.H";
+}
+else
+{
+ print "Not in Sandbox so guessing Include Paths...\n" if $debug;
+ $INCLUDE = "-I/opt/fsp/i586-pc-linux-gnu/include/fsp -I/opt/fsp/i586-pc-linux-gnu/include/ -include /opt/fsp/i586-pc-linux-gnu/include/fsp/tracinterface.H";
+}
+
+# I/P Series work in ODE sandbox env.
+if ($sandboxbase =~ /\w+/)
+{
+ $in_sand = 1;
+ print "backing = $backing\n" if $debug;
+}
+else
+{
+ $in_sand = 0;
+}
+
+
+
+# Parse the input parameters.
+
+while (@ARGV) {
+ $Arg = shift;
+
+ if ($Arg eq "-h" || $Arg eq "-H") {
+ help();
+ exit(127);
+ }
+ if ($Arg eq "-f") {
+ $file = shift;
+ next;
+ }
+ if ($Arg eq "-d") {
+ $dir = shift;
+ next;
+ }
+ if ($Arg eq "-s") {
+ $string_file = shift;
+ next;
+ }
+ if ($Arg eq "-c") {
+ $collect = 1;
+ next;
+ }
+ if ($Arg eq "-v") {
+ $debug = 1;
+ print "debug on\n" if $debug;
+ next;
+ }
+ if ($Arg eq "-C") { # fail if a hash collision is detected
+ $fail_on_collision = 1;
+ next;
+ }
+ if ($Arg eq "-F") { # hash is calculated over format string + file name
+ $hash_filename_too = 1;
+ next;
+ }
+ if ($Arg eq "-S") {
+ $BB_STRING_FILE = "";
+ next;
+ }
+
+ #just pass it onto compiler
+ $args = $args . " " . $Arg;
+}
+
+print "args = $args\n" if $debug;
+
+if (!$file && !$dir && !$in_sand) {
+ help();
+ exit(127);
+}
+
+#################################
+# M A I N #
+#################################
+
+my $clock = `date`;
+
+$build = $HEAD_EYE_CATCHER . "$HEAD_VER_FLAG" . $HEAD_SEP . $clock . $HEAD_SEP . $HEAD_BUILD_FLAG;
+
+$build =~ s/\n//g;
+
+# Global array to hold the parsed TRAC macro calls.
+my @strings = ();
+
+# Assoc. arrays to hold hash|string values.
+my %string_file_array = ();
+my %hash_strings_array = ();
+
+# Check all provided arguments and look for defaults if not provided by user
+determine_args();
+
+# Scan the appropriate files or directories for TRAC macro calls.
+
+if (defined $dir)
+{
+
+ $build = $build . $dir; # default to put at top of string file
+ if($collect)
+ {
+ collect_files($dir);
+ }
+ else
+ {
+ cpp_dir($dir);
+ # Hash the string that have been scanned.
+ %hash_strings_array = hash_strings();
+ }
+}
+else
+{
+ $build = $build . $file; # default to put at top of string file
+
+ if($collect)
+ {
+ assimilate_file($file);
+ }
+ else
+ {
+ # make sure include path includes directory that file is in
+ if($file =~ /^(.+)\/[^\/]+\.C$/)
+ {
+
+ launch_cpp_and_parse($file,$1);
+ }
+ else
+ {
+ # No path in front of file so it has to be local dir
+ launch_cpp_and_parse($file,"./");
+ }
+ # Hash the string that have been scanned.
+ %hash_strings_array = hash_strings();
+ }
+}
+
+# Read the existing string file into memory.
+%string_file_array = read_string_file();
+
+# Write out the new string file. check for collisions of new/old string here
+write_string_file();
+
+print "Hashing Started at $clock\n";
+$clock = `date`;
+print "Hashing Finished at $clock\n";
+
+exit 0;
+
+
+#################################
+# S U B R O U T I N E S #
+#################################
+
+#=============================================================================
+# Enhance usability by figuring out which build env. we are in
+#=============================================================================
+sub determine_args() {
+
+
+ # Find trexhash program
+ # but only if needed (i.e. not in collect mode)
+ if (!$collect) {
+ my $tmp = `which $hash_prog`;
+ chomp $tmp;
+
+ if ($tmp eq '') {
+ print STDOUT "\nWarning: Program trexhash does not exist in path.\n" if $debug;
+ $hash_prog = "./trexhash";
+
+ $tmp = `which $hash_prog`;
+ chomp $tmp;
+ if ($tmp eq '') {
+ print STDOUT "\nError: Unable to find trexhash \n";
+ exit(127);
+ }
+ }
+ }
+
+ # Verify input values.
+ if ((!defined $file) && (!defined $dir)) {
+ if(!($in_sand))
+ {
+ print STDOUT "\nError: No input directory or file provided as input to scan\n";
+ exit(127);
+ }
+
+ # Assume they want sandbox scanned
+ if($collect)
+ {
+ # collect all string files generated by tracepp and merge
+ $dir = "$sandboxbase/obj/";
+ }
+ else
+ {
+ # generate our own string file by pre-compiling all source code
+ $dir = "$sandboxbase/src/";
+ }
+ print STDOUT "\n-f <file> or -d <dir> not found...scanning $dir by default\n\n";
+ }
+
+ if (!defined $string_file)
+ {
+ if ($in_sand)
+ {
+
+ # Copy the current string file from backing build into our sandbox
+ system ("cp $backing/obj/$file_name $sandboxbase/obj/$file_name")
+ if !(-e "$sandboxbase/obj/$file_name");
+
+ $string_file = "$sandboxbase/obj/$file_name";
+ }
+ else
+ {
+ $string_file = "./$file_name";
+ }
+ print STDOUT "-sf <string_file> not specified, using $string_file instead...\n\n" if $debug;
+
+ }
+
+ # Try Creating the string file
+ `touch $string_file`;
+
+ if (! -f $string_file) {
+ print STDOUT "\nError: File $string_file does not exist. Current directory may not be writable.\n\n";
+ help();
+ exit(127);
+ }
+
+ # Make sure sbeStringFile is readable/writeable
+ system("chmod ugo+rw $string_file");
+
+}
+
+#=============================================================================
+# Launch cpp script and grab input from it looking for trace calls.
+#=============================================================================
+sub launch_cpp_and_parse($$) {
+
+ my ($l_loc, $l_dir) = @_;
+
+ print "Processing file $l_loc\n" if $debug;
+ my $cmd = "/usr/bin/cpp $INCLUDE -I $l_dir $args $l_loc|";
+ print "$cmd\n" if $debug;
+ open(FH,"$cmd")
+ or die ("Cannot open $_:$!,stopped");
+
+ # Read through all lines in the file..
+ my $line = <FH>;
+ while (defined $line)
+ {
+ chop $line; # remove EOL
+ $line =~ s/^\s*//; # remove unneccesary beginning white space.
+ $line =~ s/\s*$//; # remove unneccesary ending white space.
+ # Look for lines that are trace macro calls.
+ #if (/(trace_adal_hash)(\()( *)(".+")(,)(\d)/)
+ #if ($line =~ /(.*?)(trace_adal_hash)(\()( *)(".+")(,)(\d)\)+(.*\d.*)/)
+ while($line =~ m/^(.*?)trace_adal_hash\s*\(\s*(("[^"]*"\s*)+),\s*(\d+)\s*\)(.*)$/)
+ {
+ my ($prefix, $strings, $salt, $suffix) = ($1, $2, $4, $5);
+ print STDOUT "$strings $salt\n" if $debug;
+ $strings =~ s/"\s*$//; # remove trailing " and space
+ $strings =~ s/^"//; # remove leading "
+ $strings =~ s/"\s*"//g;
+ # Check to see if it's contained on a single line, or if we
+ # have to combine lines to get a complete trace call.
+
+ # Save the macro call so it can be hashed later..
+ push (@strings, [$l_loc, $strings, $salt]);
+ $line = $suffix; # check rest of line for a second trace call
+ }
+ my $nextline = <FH>;
+ last if !defined $nextline;
+ # if a trace call is spread over multiple lines we have to add the next
+ # line from the source. the only problem is the definition/declaration
+ # of trace_adal_hash: we have to ignore that. we catch that by requiring
+ # a " after the function name. hopefully nobody writes a comment with
+ # a " after the function declaration ...
+ if ($line =~ /trace_adal_hash.*"/) {
+ $line .= $nextline;
+ } else {
+ $line = $nextline;
+ }
+ }
+ close(FH);
+}
+
+#=============================================================================
+# run cpp on all files in this directory and return the output
+#=============================================================================
+sub cpp_dir($) {
+
+ my ($l_dir) = @_;
+ my @dir_entry;
+ my $l_entry;
+
+ # Open the directory and read all entry names.
+ opendir ( DH , "$l_dir")
+ or die ("Cannot open $l_dir: $!, stopped");
+
+ print STDOUT "Processing directory $l_dir\n" if $debug;
+ @dir_entry = readdir(DH);
+ closedir(DH);
+
+ while (@dir_entry) {
+ $l_entry = shift(@dir_entry);
+
+ if ($l_dir =~ m"/$") {
+ $l_entry = "$l_dir$l_entry";
+ }
+ else {
+ $l_entry = "$l_dir/$l_entry";
+ }
+
+ # Is the entry a directory?
+ if (-d $l_entry) {
+
+ if($l_entry =~ m"/?([^/]+)$")
+ {
+ # check dir we are going into
+ print "dir = $1\n" if $debug;
+ # should we recurse into this directory.
+ if ($1 =~ m/^(\.\.?|sim[ou]|bldv)$/)
+ {
+ next; # skip '.', '..' and some fips dirs
+ }
+ cpp_dir($l_entry);
+ }
+ else
+ {
+ # unable to determine name of dir (no / in filename)
+ # should we recurse into this directory.
+ if ($l_entry =~ m/^(\.\.?|sim[ou]|bldv)$/)
+ {
+ next; # skip '.', '..' and some fips dirs
+ }
+ cpp_dir($l_entry);
+ }
+ }
+ # Is the entry a file?
+ elsif ((-f $l_entry) && ($l_entry =~ m/\.C$/)) {
+ # it's a file so
+ launch_cpp_and_parse($l_entry,$l_dir);
+ }
+ else {
+ # Not a file or directory so ignore it...
+ }
+ }
+}
+
+#=============================================================================
+# Read in strings from the existing trace string file....
+#=============================================================================
+sub read_string_file() {
+
+ my %o_strings;
+ my ($line) = "";
+ my ($l_hash) = "";
+ my ($l_str) = "";
+ my ($cur_build) = "";
+ my ($l_file) = "";
+
+
+ # Make sure we can open each file.
+ open ( FH , "<$string_file")
+ or die ("Cannot open $_: $!, stopped");
+
+ $line = <FH>;
+
+ print "first line in sbeStringFile= $line\n" if $debug;
+
+ if((defined $line) && ($line =~ /^$HEAD_EYE_CATCHER(\d)/))
+ {
+ $version = $1;
+
+ print "version = $version\n" if $debug;
+
+ #Always put latest version in file
+ $line =~ s/^$HEAD_EYE_CATCHER\d/${HEAD_EYE_CATCHER}${HEAD_VER_FLAG}/;
+
+ # Take previous version in file and use it.
+ $build = $line;
+ chomp($build);
+ $line = <FH>;
+
+ while (defined $line) {
+ chomp $line; # remove EOL
+ if($version eq "1")
+ {
+ ($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ }
+ elsif($version eq "2")
+ {
+ ($l_hash, $l_str ,$l_file) = split(/\|\|/, $line);
+ }
+ else
+ {
+ print "Unknown version of stringfile $version\n";
+ exit(127);
+ }
+ $o_strings{$l_hash} = $l_str . "||" . $l_file;
+ $line = <FH>;
+ }
+
+ }
+ else
+ { # If there is a file then we are dealing with the first
+ # version of sbeStringFile so don't look for file name.
+ if ($debug) {
+ print "version 0 stringfile detected: $string_file\n";
+ }
+
+ # there is a file and it doesn't have a header
+ $version = 0;
+
+ while (defined $line) {
+ chomp $line; # remove EOL
+ ($l_hash,$l_str) = split(/\|\|/, $line);
+ $o_strings{$l_hash} =$l_str . "||" . "NO FILE";
+ $line = <FH>;
+ }
+ }
+
+ close(FH);
+
+ #Time to look for a building block string file
+ if($BB_STRING_FILE ne "" and $string_file ne $BB_STRING_FILE and -f $BB_STRING_FILE)
+ {
+
+ # Make sure we can open the file.
+ open ( FH , "<$BB_STRING_FILE")
+ or die ("Cannot open $_: $!, stopped");
+
+ $line = <FH>;
+
+ print "first line in BB_StringFile = $line\n" if $debug;
+ if((defined $line) && ($line =~ /^$HEAD_EYE_CATCHER(\d)/))
+ {
+ $version = $1;
+
+ $line = <FH>;
+ while (defined $line)
+ {
+ chop $line; # remove EOL
+ if($version eq "1")
+ {
+ ($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ }
+ elsif($version eq "2")
+ {
+ ($l_hash, $l_str ,$l_file) = split(/\|\|/, $line);
+ }
+ #($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ $o_strings{$l_hash} = $l_str . "||" . $l_file ;
+ $line = <FH>;
+ }
+ }
+ else
+ {
+ print "*** ERROR: BB_StringFile '$BB_STRING_FILE' should always have version!!!\n"
+ }
+
+ }
+ else
+ {
+ print "$BB_STRING_FILE is not available\n" if $debug;
+ }
+ #All files are latest version now.
+ $version = $HEAD_VER_FLAG;
+ return %o_strings;
+}
+
+#=============================================================================
+# Read in strings from the existing trace string file....
+#=============================================================================
+sub collect_files($) {
+
+ my ($l_dir) = @_;
+ my (@dir_entry);
+ my ($l_entry) = "";
+
+ # Open the directory and read all entry names.
+ opendir ( DH , "$l_dir")
+ or die ("Cannot open $l_dir: $!, stopped");
+
+ print STDOUT "Processing directory $l_dir\n" if $debug;
+ @dir_entry = readdir(DH);
+ closedir(DH);
+
+ while (@dir_entry) {
+ $l_entry = shift(@dir_entry);
+
+ if ($l_dir =~ m"/$") {
+ $l_entry = "$l_dir$l_entry";
+ }
+ else {
+ $l_entry = "$l_dir/$l_entry";
+ }
+
+ # Is the entry a directory?
+ if (-d $l_entry) {
+
+ # should we recurse into this directory.
+ if ($l_entry =~ m/\/(\.\.?|sim[ou]|bldv)$/)
+ {
+ next; # skip '.', '..' and some fips dirs
+ }
+ collect_files($l_entry);
+ }
+ # Is the entry a file?
+ elsif ((-f $l_entry) && ($l_entry =~ m"\.hash$")) {
+ # it's a file so
+ assimilate_file($l_entry);
+ }
+ else {
+ # Not a file or directory so ignore it...
+ }
+ }
+
+}
+
+#=============================================================================
+# Read in data from file and add to master one
+#=============================================================================
+sub assimilate_file($) {
+
+ my ($l_loc) = @_;
+
+ my (%o_strings);
+ my ($line) = "";
+ my ($l_hash) = "";
+ my ($l_str) = "";
+ my ($l_file) = "";
+
+ # Make sure we can open each file.
+ open ( FH , "<$l_loc")
+ or die ("Cannot open $_: $!, stopped");
+
+ $line = <FH>;
+
+ print "Assimilate: first line in $l_loc = $line" if $debug;
+
+ if((defined $line) && ($line =~ /^$HEAD_EYE_CATCHER(\d)/))
+ {
+ $version = $1;
+ if ($version eq "1") {
+ if ($hash_filename_too) {
+ print "*** ERROR: hash_filename_too (-F) isn't possible with trace version 1\n";
+ print " please rebuild all .hash files and global sbeStringFile\n";
+ print " version 1 file is '$l_loc'\n";
+ exit(127);
+ }
+ } elsif ($version ne "2") {
+ print "Unknown version of stringfile $version\n";
+ exit(127);
+ }
+
+ $line = <FH>;
+
+
+ while (defined $line) {
+ chop $line; # remove EOL
+ if($version eq "1")
+ {
+ ($l_hash, $l_file ,$l_str) = split(/\|\|/, $line);
+ }
+ elsif($version eq "2")
+ {
+ ($l_hash, $l_str ,$l_file) = split(/\|\|/, $line);
+ }
+ my $newstring = $l_str . "||" . $l_file;
+ if (exists $hash_strings_array{$l_hash}) {
+ my $hashstr1 = $hash_strings_array{$l_hash};
+ my $hashstr2 = $newstring;
+ if (!$hash_filename_too) {
+ # hash was made over format string only, remove file name
+ $hashstr1 =~ s/\|\|.*$//;
+ $hashstr2 = $l_str;
+ }
+ if ($debug) {
+ print "a_f: compare $hashstr1\n",
+ " vs. $hashstr2\n";
+ }
+ if ($hashstr1 ne $hashstr2)
+ {
+ print "*** ERROR: HASH Collision! (a_f)\n",
+ " Two different strings have the same hash value ($l_hash)\n",
+ " String 1: $hash_strings_array{$l_hash}\n",
+ " String 2: $newstring\n";
+ if ($fail_on_collision) {
+ exit(1);
+ }
+ }
+ }
+ $hash_strings_array{$l_hash} = $newstring;
+ $line = <FH>;
+ }
+
+ }
+ else
+ { # If there is a file then we are dealing with the first
+ # version of sbeStringFile so don't look for file name.
+ # these files shouldn't be there anymore. we don't check for collisions here
+ if ($debug) {
+ print "version 0 stringfile detected: $string_file\n";
+ }
+
+ if(defined $line)
+ {
+ # there is a file and it doesn't have a header
+ $version = 0;
+ }
+
+ while (defined $line) {
+ chop $line; # remove EOL
+ ($l_hash,$l_str) = split(/\|\|/, $line);
+ $hash_strings_array{$l_hash} = $l_str . "||" . "NO FILE";
+ $line = <FH>;
+ }
+ }
+ $version = $HEAD_VER_FLAG;
+ close(FH);
+}
+
+#=============================================================================
+
+#=============================================================================
+sub hash_strings() {
+
+ my ($hash_val, $l_key, $l_hash, %l_hash_strings);
+ my ($line_feed) = chr(10);
+ my ($l_file_name) = "NO FILENAME";
+ print "\nHashing printf strings.\n\n";
+
+ foreach my $str (@strings) {
+ my $printf_string;
+ $l_file_name = $str->[0];
+ $printf_string = $str->[1];
+ $l_key = $str->[2];
+ print "printf_string = $printf_string\n" if $debug;
+ $printf_string =~ s/"\s?"//g; #multi line traces will have extra " in them
+ $printf_string =~ s/`/\\`/g; # excape '
+ $printf_string =~ s/\\n/$line_feed/g; # escape \n
+ if ($hash_filename_too) {
+ $printf_string .= "||" . $l_file_name;
+ }
+
+ # call the hasher.
+ print "$hash_prog \"$printf_string\" $l_key\n" if $debug;
+ $hash_val = `$hash_prog \"$printf_string\" $l_key`;
+ if ($?) {
+ my ($hp_ret, $hp_sig) = ($? >> 8, $? & 127);
+ if ($hp_sig) {
+ print "*** ERROR: $hash_prog died with signal $hp_sig\n";
+ } elsif ($hp_ret) {
+ print "*** ERROR: $hash_prog returned the error $hp_ret\n";
+ if ($hash_val) {
+ print " error from $hash_prog:\n$hash_val";
+ }
+ }
+ exit(1);
+ }
+ print "printf_string = $printf_string l_key = $l_key hash val = $hash_val\n" if $debug;
+
+ # undo escaping
+ $printf_string =~ s/$line_feed/\\n/g;
+ $printf_string =~ s/\\`/`/g;
+
+ if (exists $l_hash_strings{$hash_val})
+ {
+ # hash val was found before. check if it's the same string
+ # else we have a hash collision
+ my $l_tmp = $l_hash_strings{$hash_val};
+ if (!$hash_filename_too) {
+ $l_tmp =~ s/\|\|.*$//;
+ }
+ if ($l_tmp ne $printf_string)
+ {
+ print "*** ERROR: HASH Collision! (h_s)\n",
+ " Two different strings have the same hash value ($hash_val)\n",
+ " String 1: $l_hash_strings{$hash_val}\n",
+ " String 2: $printf_string (file $l_file_name)\n";
+ if ($fail_on_collision) {
+ exit(1);
+ }
+ }
+ }
+ # this will overwrite an old string with a new one if a collision occurred
+ # but we might want to bail out in this case anyway
+ $printf_string = $printf_string . "||" . $l_file_name;
+ $l_hash_strings{$hash_val} = $printf_string;
+ }
+ return %l_hash_strings;
+}
+#=============================================================================
+
+#=============================================================================
+sub write_string_file() {
+
+ my (@keys) = ();
+ my ($l_key) = "";
+
+ # Combine the contents of the existing string file with the trace calls
+ # that we have just hashed.
+ print STDOUT "\nCombining Hash strings...\n\n";
+
+ @keys = keys(%hash_strings_array);
+
+ foreach $l_key (@keys) {
+ my $l_tmp = $hash_strings_array{$l_key}; # freshly collected strings
+ if (exists $string_file_array{$l_key})
+ { # hash exists in list from sbeStringFile
+ my $l_tmp2 = $string_file_array{$l_key};
+ if (!$hash_filename_too) {
+ $l_tmp =~ s/\|\|.*$//;
+ $l_tmp2 =~ s/\|\|.*$//;
+ }
+
+ # Check for hash collisions.
+ if ($l_tmp ne $l_tmp2)
+ {
+ print "*** ERROR: HASH Collision! (w_s_f)\n",
+ " Two different strings have the same hash value ($l_key)\n",
+ " String 1: $hash_strings_array{$l_key}\n",
+ " String 2: $string_file_array{$l_key}\n";
+ if ($fail_on_collision) {
+ exit(1);
+ }
+ # don't fail, write new one
+ }
+ }
+ if($version > 0)
+ {
+ # add/replace the new string to the string_file_array.
+ $string_file_array{$l_key} = $hash_strings_array{$l_key}
+ }
+ else
+ {
+ # old version so only write out format string (not file name to)
+ $string_file_array{$l_key} = $l_tmp;
+ }
+ }
+
+ # Write out the updated string file.
+ print STDOUT "\nWriting updated hash||string file...\n\n";
+
+ @keys = sort(keys(%string_file_array));
+
+ open ( FH , ">$string_file")
+ or die ("Cannot open $_: $!, stopped");
+
+ if($version > 0)
+ {
+ print FH "$build\n"; # only print version if newer then version 0
+ }
+ foreach $l_key (@keys) {
+ print FH "$l_key||$string_file_array{$l_key}\n";
+ }
+ close FH;
+}
+#=============================================================================
+
+#=============================================================================
+# Display command invokation help for this program...
+#=============================================================================
+sub help() {
+ print << "EOF";
+tracehash.pl - create a trace string file from sources or collect tracepp files
+Usage: tracehash.pl [options]
+ General options:
+ -h - Print this help text.
+ -v - Be verbose, tell what's going on (debug output)
+ Operation modes
+ -c - Collect StringFiles created by tracepp and merge.
+ default - Scan source files for trace calls.
+
+Collect mode: tracehash.pl -c [-vFCS] [-d <dir>] [-s <string_file>]
+ tracehash.pl -c [-vFCS] [-f <file>] [-s <string_file>]
+ Collect string files created by tracepp (.hash) from directory tree at
+ <dir> or read them from string file <file> and write to file
+ <string_file>, adding entries already in this file.
+ -f - String file to read and write/add to <string_file>.
+ -d - Start of directory tree to scan for .hash files. Default = .
+ -s - File with trace strings (and hashes) to read from and write to
+ default = ./sbeStringFile
+ -F - hash is calculated over trace string and source file name,
+ otherwise without source file name
+ -C - report an error if a hash collisions occurs
+ -S - don't read global FLD-2.2 string file ($BB_STRING_FILE)
+ If tracehash.pl is called in a FipS build sandbox without -d and -f
+ defaults for the sandbox will be used.
+
+Scan mode: tracehash.pl [-vFCS] [-d <dir>] [-s <string_file>] [ccpopts]
+ tracehash.pl [-vFCS] [-f <file>] [-s <string_file>] [cppopts]
+ Scan all files in directory tree <dir> or scan file <file> and write
+ strings to file <string_file>. Strings already in this file will be merged.
+ -f - Source file to scan for trace entries.
+ -d - Source directory to scan for trace entries.
+ -s - File with trace strings (and hashes) to read from and write to.
+ default = ./sbeStringFile
+ -F - hash for string was build from format string + source file name
+ -C - report an error if hash collisions occur
+ -S - don't read global FLD-2.2 string file ($BB_STRING_FILE)
+ All other arguments will be passed verbatim to cpp
+EOF
+}
+#=============================================================================
+
diff --git a/src/tools/scripts/parseErrorInfo.pl b/src/tools/scripts/parseErrorInfo.pl
new file mode 100755
index 00000000..839a836c
--- /dev/null
+++ b/src/tools/scripts/parseErrorInfo.pl
@@ -0,0 +1,1663 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/parseErrorInfo.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+#
+# @file parseErrorInfo.pl
+# @brief This perl script will parse HWP Error XML files and generate required
+# FAPI code to create and error log and add FFDC to the error.
+#
+# *HWP HWP Owner: N/A
+# *HWP FW Owner: Thi Tran <thi@us.ibm.com>
+# *HWP Team: N/A
+# *HWP Level: 1
+# *HWP Consumed by: HB
+#
+# Usage:
+# parseErrorInfo.pl <output dir> <filename1> <filename2> ...
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Set PREFERRED_PARSER to XML::Parser. Otherwise it uses XML::SAX which contains
+# bugs that result in XML parse errors that can be fixed by adjusting white-
+# space (i.e. parse errors that do not make sense).
+#------------------------------------------------------------------------------
+$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use Digest::MD5 qw(md5_hex);
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+use Data::Dumper;
+use Getopt::Long;
+
+my $target_ffdc_type = "fapi2::Target<T>";
+my $buffer_ffdc_type = "fapi2::buffer";
+my $variable_buffer_ffdc_type = "fapi2::variable_buffer";
+my $ffdc_type = "fapi2::ffdc_t";
+my $mcast_type = "fapi2::mcast_t";
+
+# We want to keep the signatures for the ffdc gathering hwp so that
+# we can create members of the proper types for the ffdc classes.
+my %signatures = ("proc_extract_pore_halt_ffdc" => ["por_base_state",
+ "por_halt_type_t",
+ "por_ffdc_offset_t"],
+ "hwpTestFfdc1" => [$target_ffdc_type],
+ "proc_extract_pore_base_ffdc" => ["por_base_state", "por_sbe_base_state"],
+ "proc_tp_collect_dbg_data" => [$target_ffdc_type],
+ );
+
+# There are some names used in the XML files which exist in either
+# c++ keywords (case, for example) or macros (DOMAIN). The one's which
+# cause problems and need to be changed are here.
+#
+# DOMAIN is defined to 1 in math.h
+my %mangle_names = ("DOMAIN" => "FAPI2_DOMAIN");
+
+# A list of deprecated elements. These will report messages to the
+# user, and not define anything. They have not been found to be used,
+# but that doesn't mean they're not ...
+my %deprecated = ("RC_PROCPM_PMCINIT_TIMEOUT" => "CHIP_IN_ERROR is defined as a callout procedure");
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $arg_empty_ffdc = undef;
+my $arg_local_ffdc = undef;
+my $arg_output_dir = undef;
+my $arg_use_variable_buffers = undef;
+
+# Get the options from the command line - the rest of @ARGV will
+# be filenames
+GetOptions("empty-ffdc-classes" => \$arg_empty_ffdc,
+ "local-ffdc" => \$arg_local_ffdc,
+ "output-dir=s" => \$arg_output_dir,
+ "use-variable-buffers" => \$arg_use_variable_buffers);
+
+my $numArgs = $#ARGV + 1;
+if (($numArgs < 1) || ($arg_output_dir eq undef))
+{
+ print ("Usage: parseErrorInfo.pl [--empty-ffdc-classes] [--use-variable-buffers] --output-dir=<output dir> <filename1> <filename2> ...\n");
+ print (" This perl script will parse HWP Error XML files and creates\n");
+ print (" the following files:\n");
+ print (" - hwp_return_codes.H. HwpReturnCode enumeration (HWP generated errors)\n");
+ print (" - hwp_error_info.H. Error information (used by FAPI_SET_HWP_ERROR\n");
+ print (" when a HWP generates an error)\n");
+ print (" - collect_reg_ffdc.H. Function to collect register FFDC\n");
+ print (" - set_sbe_error.H. Macro to create an SBE error\n");
+ print (" The --empty-ffdc-classes option is for platforms which don't collect ffdc.\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Hashes containing error names/enum-values
+#------------------------------------------------------------------------------
+my %errNameToValueHash;
+my %errValuePresentHash;
+
+#------------------------------------------------------------------------------
+# Hashes containing ffdc names/enum-values
+#------------------------------------------------------------------------------
+my %ffdcNameToValueHash;
+my %ffdcValuePresentHash;
+
+#------------------------------------------------------------------------------
+# Subroutine that checks if an entry exists in an array. If it doesn't exist
+# then it is added. The index of the entry within the array is returned
+#------------------------------------------------------------------------------
+sub addEntryToArray
+{
+ my ($arrayref, $entry ) = @_;
+
+ my $match = 0;
+ my $index = 0;
+
+ foreach my $element (@$arrayref)
+ {
+ if ($element eq $entry)
+ {
+ $match = 1;
+ last;
+ }
+ else
+ {
+ $index++;
+ }
+ }
+
+ if (!($match))
+ {
+ push(@$arrayref, $entry);
+ }
+
+ return $index;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine that figures out an error enum value from an error name and stores
+# it in global hashes
+#------------------------------------------------------------------------------
+sub setErrorEnumValue
+{
+ my $name = $_[0];
+
+ #--------------------------------------------------------------------------
+ # Check that the error name is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($errNameToValueHash{$name}))
+ {
+ # Two different errors with the same name!
+ print ("fapiParseErrorInfo.pl ERROR. Duplicate error name ", $name, "\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Figure out the error enum-value. This is a hash value generated from
+ # the error name. A hash is used for Cronus so that if a HWP is not
+ # recompiled against a new eCMD/Cronus version where the errors have
+ # changed then there will not be a mismatch in error values.
+ # This is a 24bit hash value because FAPI has a requirement that the
+ # top byte of the 32 bit error value be zero to store flags indicating
+ # the creator of the error
+ #--------------------------------------------------------------------------
+ my $errHash128Bit = md5_hex($name);
+ my $errHash24Bit = substr($errHash128Bit, 0, 6);
+
+ #--------------------------------------------------------------------------
+ # Check that the error enum-value is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($errValuePresentHash{$errHash24Bit}))
+ {
+ # Two different errors generate the same hash-value!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate error hash value\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Update the hashes with the error name and ID
+ #--------------------------------------------------------------------------
+ $errValuePresentHash{$errHash24Bit} = 1;
+ $errNameToValueHash{$name} = $errHash24Bit;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine that figures out an FFDC ID value from an FFDC name and stores it
+# in global hashes for use when creating the enumeration of FFDC IDs
+#------------------------------------------------------------------------------
+sub setFfdcIdValue
+{
+ my $name = $_[0];
+
+ #--------------------------------------------------------------------------
+ # Check that the FFDC name is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($ffdcNameToValueHash{$name}))
+ {
+ # Two different FFDCs with the same name!
+ print ("fapiParseErrorInfo.pl ERROR. Duplicate FFDC name ", $name, "\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Figure out the FFDC enum-value. This is a hash value generated from
+ # the FFDC name.
+ #--------------------------------------------------------------------------
+ my $ffdcHash128Bit = md5_hex($name);
+ my $ffdcHash32Bit = substr($ffdcHash128Bit, 0, 8);
+
+ #--------------------------------------------------------------------------
+ # Check that the error enum-value is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($ffdcValuePresentHash{$ffdcHash32Bit}))
+ {
+ # Two different FFDCs generate the same hash-value!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate FFDC hash value\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Update the hashes with the error name and ID
+ #--------------------------------------------------------------------------
+ $ffdcValuePresentHash{$ffdcHash32Bit} = 1;
+ $ffdcNameToValueHash{$name} = $ffdcHash32Bit;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine to create ffdc methods
+#------------------------------------------------------------------------------
+sub addFfdcMethod
+{
+ my $methods = shift;
+ my $ffdc_uc = shift;
+ my $class_name = shift;
+ my $type = shift;
+ my $objectNumber = shift;
+
+ # Remove the leading *_
+ $class_name = (split (/_/, $class_name, 2))[1];
+
+ # If we didn't get a type passed in, this element will get an ffdc_t pair.
+ $type = $ffdc_type if ($type eq undef);
+
+ # Mangle the uppercase name if needed
+ $ffdc_uc = $mangle_names{$ffdc_uc} if ($mangle_names{$ffdc_uc} ne undef);
+
+ my $key = $ffdc_uc.$type;
+ my $key_target = $ffdc_uc.$target_ffdc_type;
+ my $key_ffdc = $ffdc_uc.$ffdc_type;
+
+ # Check to see if this element already has been recorded with this
+ # type or a target type. Note the effect we're shooting for here is
+ # to define the member if it's not been defined before *or* it's
+ # changing from an ffdc_t to a target due to other information in the xml
+ return if ($methods->{$key}{type} eq $type);
+ return if ($methods->{$key_target}{type} eq $target_ffdc_type);
+
+ # Just leave if this is a variable_buffer ans we're not supporting that.
+ return if (($type eq $variable_buffer_ffdc_type) && ($arg_use_variable_buffers eq undef));
+
+ # Set the proper type, and clear out any previous members/methods if
+ # we're going from an ffdc_t to a target.
+ $methods->{$key}{type} = $type;
+ delete $methods->{$key_ffdc} if ($type eq $target_ffdc_type);
+
+ my $method = "";
+ my $method_body = "";
+
+ # If we're generating empty classes, not using an argument name will avoid the unused parameter warnings
+ my $param = ($arg_empty_ffdc eq undef) ? "i_value" : "";
+
+ if ($type eq $ffdc_type)
+ {
+ $method = "\ttemplate< typename T >\n";
+ $method .= "\tinline $class_name& set_$ffdc_uc(const T& $param)\n";
+
+ if(!$arg_local_ffdc)
+ {
+ $method_body = " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() =";
+ $method_body .= " fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n";
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+ else
+ {
+ # need to use the objectNumber here so when we decode the info at the hwsv/hb side we have a reference, they will
+ # be copied into/out of the sbe buffer in the correct order
+ $method_body .= "\t{\n\t\tfapi2::g_FfdcData.ffdcData[$objectNumber].data= convertType(i_value);\n";
+ $method_body .= "\t\tfapi2::g_FfdcData.ffdcData[$objectNumber].size =";
+ $method_body .=" fapi2::getErrorInfoFfdcSize(i_value);\n";
+ $method_body .= "\t\tfapi2::g_FfdcData.ffdcLength += sizeof(sbeFfdc_t);\n";
+ $method_body .= "\t\treturn *this;\n\t};\n\n";
+ }
+
+ }
+ elsif ($type eq $mcast_type )
+ {
+# uncomment once multicast is understood more
+# $method = "\n\t\ttemplate< typename T >\n";
+# $method .= "\t\tinline $class_name& set_$ffdc_uc(const T& $param)\n";
+#
+# if(!$arg_local_ffdc)
+# {
+# $method_body = " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() = fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n";
+# $methods->{$key}{member} = "$mcast_type $ffdc_uc;\n ";
+# }
+# else
+# {
+# $method_body .= "\t\t{\n\t\t\tfapi2::g_ErrorInfoFfdc[$objectNumber].iv_ffdcId = fapi2::EI_TYPE_FFDC;\n";
+# $method_body .= "\t\t\tfapi2::g_ErrorInfoFfdc[$objectNumber].iv_ffdc.ptr() = &i_value;\n";
+# $method_body .= "\t\t\tfapi2::g_ErrorInfoFfdc[$objectNumber].iv_ffdc.size() = fapi2::getErrorInfoFfdcSize(i_value);";
+# $method_body .= "\n\t\t\treturn *this;\n\t\t};\n\n";
+# }
+#
+ }
+ elsif ($type eq $buffer_ffdc_type)
+ {
+ # Two methods - one for integral buffers and one for variable_buffers
+ $method = "\n template< typename T >\n";
+ $method .= " inline $class_name& set_$ffdc_uc(const fapi2::buffer<T>& $param)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value(); $ffdc_uc.size() = i_value.template getLength<uint8_t>(); return *this;}\n\n";
+
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+
+ elsif ($type eq $variable_buffer_ffdc_type)
+ {
+ $method = "\n inline $class_name& set_$ffdc_uc(const fapi2::variable_buffer& $param)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value(); $ffdc_uc.size() = i_value.template getLength<uint8_t>(); return *this;}\n\n";
+
+ # No need to add the member here, it was added with fapi2::buffer. And we can't have variable
+ # buffer support with out integral buffer support (can we?)
+ }
+
+ elsif ($type eq $target_ffdc_type)
+ {
+ $method = "\n template< TargetType T >\n";
+ $method .= " inline $class_name& set_$ffdc_uc(const $type& $param)\n";
+ $method_body .= " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() = fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n";
+
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+
+ else
+ {
+ print ("ffdc type $type is unknown\n");
+ exit(1);
+ }
+
+ $method .= ($arg_empty_ffdc eq undef) ? $method_body : " {return *this;}\n\n";
+ $methods->{$key}{method} = $method;
+}
+
+#------------------------------------------------------------------------------
+# Open output files for writing
+#------------------------------------------------------------------------------
+my $rcFile = $arg_output_dir;
+$rcFile .= "/";
+$rcFile .= "hwp_return_codes.H";
+open(RCFILE, ">", $rcFile);
+
+my $eiFile = $arg_output_dir;
+$eiFile .= "/";
+$eiFile .= "hwp_error_info.H";
+open(EIFILE, ">", $eiFile);
+
+my $ecFile = $arg_output_dir;
+$ecFile .= "/";
+$ecFile .= "hwp_ffdc_classes.H";
+open(ECFILE, ">", $ecFile);
+
+my $crFile = $arg_output_dir;
+$crFile .= "/";
+$crFile .= "collect_reg_ffdc.H";
+open(CRFILE, ">", $crFile);
+
+my $sbFile = $arg_output_dir;
+$sbFile .= "/";
+$sbFile .= "set_sbe_error.H";
+open(SBFILE, ">", $sbFile);
+
+#------------------------------------------------------------------------------
+# Print start of file information to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "// hwp_error_info.H\n";
+print EIFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print EIFILE "#ifndef FAPI2_HWPERRORINFO_H_\n";
+print EIFILE "#define FAPI2_HWPERRORINFO_H_\n\n";
+print EIFILE "#include <target.H>\n";
+print EIFILE "#include <plat_trace.H>\n";
+print EIFILE "#include <hwp_return_codes.H>\n";
+print EIFILE "#include <set_sbe_error.H>\n";
+print EIFILE "/**\n";
+print EIFILE " * \@brief Error Information macros and HwpFfdcId enumeration\n";
+print EIFILE " *\/\n";
+#------------------------------------------------------------------------------
+# Print start of file information to hwp_ffdc_classes.H
+#------------------------------------------------------------------------------
+print ECFILE "// hwp_ffdc_classes.H\n";
+print ECFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print ECFILE "#ifndef FAPI2_HWP_FFDC_CLASSES_H_\n";
+print ECFILE "#define FAPI2_HWP_FFDC_CLASSES_H_\n\n";
+print ECFILE "#include <ffdc.H>\n";
+print ECFILE "#include <buffer.H>\n";
+print ECFILE "#include <variable_buffer.H>\n" if ($arg_use_variable_buffers ne undef);
+print ECFILE "#include <error_info.H>\n";
+print ECFILE "#include <utils.H>\n";
+print ECFILE "#include <hwp_error_info.H>\n";
+print ECFILE "#if !defined(FAPI2_NO_FFDC) && !defined(MINIMUM_FFDC)\n";
+#print ECFILE "#include <collect_reg_ffdc.H>\n";
+print ECFILE "#endif\n";
+#print ECFILE "#include <proc_extract_sbe_rc.H>\n\n";
+print ECFILE "/**\n";
+print ECFILE " * \@brief FFDC gathering classes\n";
+print ECFILE " *\/\n";
+print ECFILE "namespace fapi2\n{\n";
+if($arg_local_ffdc)
+{
+ print ECFILE "extern SbeFfdcData_t g_FfdcData; \n";
+}
+#------------------------------------------------------------------------------
+# Print start of file information to collectRegFfdc.H
+#------------------------------------------------------------------------------
+print CRFILE "// collect_reg_ffdc.H\n";
+print CRFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print CRFILE "#ifndef FAPI2_COLLECT_REG_FFDC_H_\n";
+print CRFILE "#define FAPI2_COLLECT_REG_FFDC_H_\n";
+print CRFILE "#include <stdint.h>\n";
+print CRFILE "#include <vector>\n";
+print CRFILE "#include <ffdc.H>\n";
+print CRFILE "#include <hwp_error_info.H>\n";
+print CRFILE "#include <error_info_defs.H>\n";
+print CRFILE "#include <buffer.H>\n";
+print CRFILE "#include <target.H>\n";
+print CRFILE "#include <return_code.H>\n";
+print CRFILE "#include <hw_access.H>\n";
+print CRFILE "#include <plat_trace.H>\n";
+print CRFILE "namespace fapi2\n";
+print CRFILE "{\n";
+print CRFILE "template< TargetType C, TargetType P >\n";
+print CRFILE "void collectRegFfdc(const fapi2::ffdc_t& i_target,\n";
+print CRFILE " const fapi2::HwpFfdcId i_ffdcId,\n";
+print CRFILE " fapi2::ReturnCode & o_rc,\n";
+print CRFILE " uint32_t i_childOffsetMult = 0)\n";
+print CRFILE "{\n";
+print CRFILE " FAPI_INF(\"collectRegFfdc. FFDC ID: 0x%x\", i_ffdcId);\n";
+print CRFILE " fapi2::ReturnCode l_rc;\n";
+print CRFILE " fapi2::buffer<uint64_t> l_buf;\n";
+print CRFILE " uint32_t l_cfamData = 0;\n";
+print CRFILE " uint64_t l_scomData = 0;\n";
+print CRFILE " std::vector<uint32_t> l_cfamAddresses;\n";
+print CRFILE " std::vector<uint64_t> l_scomAddresses;\n";
+print CRFILE " uint32_t l_ffdcSize = 0;\n\n";
+print CRFILE " switch (i_ffdcId)\n";
+print CRFILE " {\n";
+print CRFILE " // void statments for the unused variables\n";
+print CRFILE " static_cast<void>(l_cfamData);\n";
+print CRFILE " static_cast<void>(l_scomData);\n";
+print CRFILE " static_cast<void>(l_ffdcSize);\n";
+print CRFILE " static_cast<const void>(i_target);\n";
+print CRFILE " static_cast<void>(o_rc);\n";
+print CRFILE " static_cast<void>(i_childOffsetMult);\n";
+#------------------------------------------------------------------------------
+# Print start of file information to setSbeError.H
+#------------------------------------------------------------------------------
+print SBFILE "// setSbeError.H\n";
+print SBFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print SBFILE "// When SBE code creates an error, it produces an error value\n";
+print SBFILE "// that matches a value in the HwpReturnCode enum in\n";
+print SBFILE "// fapiHwpReturnCodes.H. The SBE uses the __ASSEMBLER__\n";
+print SBFILE "// primitives in hwpReturnCodes.H to do this. The function\n";
+print SBFILE "// that extracts the error value from the SBE needs to call\n";
+print SBFILE "// FAPI_SET_HWP_ERROR to create the error and get all the\n";
+print SBFILE "// actions in the error XML file performed, but that macro can\n";
+print SBFILE "// only be called with the enumerator, not the value. This\n";
+print SBFILE "// FAPI_SET_SBE_ERROR macro can be called instead, it calls\n";
+print SBFILE "// FAPI_SET_HWP_ERROR with the correct error enumerator.\n";
+print SBFILE "// Errors containing <sbeError/> in their XML are supported\n";
+print SBFILE "// in this macro.\n\n";
+print SBFILE "// Note that it is expected that this macro will be called\n";
+print SBFILE "// in one place (the function that extracts the error from\n";
+print SBFILE "// the SBE), if this changes and it is called in multiple\n";
+print SBFILE "// places then the macro could be turned into a function to\n";
+print SBFILE "// avoid the code size increase of expanding the macro in\n";
+print SBFILE "// multiple places. The function approach is slightly more\n";
+print SBFILE "// complicated, there is an extra C file and the function\n";
+print SBFILE "// must take a parameter for the generic chip ID in the error\n";
+print SBFILE "// XML.\n\n";
+print SBFILE "#ifndef FAPI2_SETSBEERROR_H_\n";
+print SBFILE "#define FAPI2_SETSBEERROR_H_\n\n";
+print SBFILE "#define FAPI_SET_SBE_ERROR(RC, ERRVAL, FFDC_BUFFER)\\\n";
+print SBFILE "{\\\n";
+print SBFILE "switch (ERRVAL)\\\n";
+print SBFILE "{\\\n";
+
+#------------------------------------------------------------------------------
+# For each XML file
+#------------------------------------------------------------------------------
+foreach my $argnum (0 .. $#ARGV)
+{
+ my $infile = $ARGV[$argnum];
+ my $count = 0;
+
+ #--------------------------------------------------------------------------
+ # Read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one element
+ #--------------------------------------------------------------------------
+ my $errors = $xml->XMLin($infile, ForceArray =>
+ ['hwpError', 'collectFfdc', 'ffdc','mcastId', 'callout', 'deconfigure', 'gard',
+ 'registerFfdc', 'collectRegisterFfdc', 'cfamRegister', 'scomRegister',
+ 'id','collectTrace', 'buffer']);
+
+ # Uncomment to get debug output of all errors
+ #print "\nFile: ", $infile, "\n", Dumper($errors), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Error
+ #--------------------------------------------------------------------------
+ foreach my $err (@{$errors->{hwpError}})
+ {
+ my $objectStr = "";
+ # Hash of methods for the ffdc-gathering class
+ my %methods;
+
+ #----------------------------------------------------------------------
+ # Check that expected fields are present
+ #----------------------------------------------------------------------
+ if (! exists $err->{rc})
+ {
+ print ("parseErrorInfo.pl ERROR. rc missing\n");
+ exit(1);
+ }
+
+ if (! exists $err->{description})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. description missing\n");
+ exit(1);
+ }
+
+ #----------------------------------------------------------------------
+ # Check that this rc hasn't been deprecated
+ #----------------------------------------------------------------------
+ if ($deprecated{$err->{rc}} ne undef)
+ {
+ print "WARNING: $err->{rc} has been deprecated because $deprecated{$err->{rc}}\n";
+ next;
+ }
+
+ #----------------------------------------------------------------------
+ # Set the error enum value in a global hash
+ #---------------------------------------------------------------------
+ setErrorEnumValue($err->{rc});
+
+
+ #----------------------------------------------------------------------
+ # Print the CALL_FUNCS_TO_COLLECT_FFDC macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_FFDC(RC) ";
+
+ # For now, this code is removed. It appears to work just fine but
+ # will require more of the fapi2 infrastructure to be in place.
+ # Because the ffdc collection classes create members with real types,
+ # the declarations of the types need to be visible - and they're not
+ # right now. When we get further along, we can enable this code.
+ $count = 0;
+ foreach my $collectFfdc (@{$err->{collectFfdc}})
+ {
+ if ($count == 0)
+ {
+ print EIFILE "{ fapi2::ReturnCode l_tempRc; ";
+ }
+ $count++;
+
+ print EIFILE "FAPI_EXEC_HWP(l_tempRc, $collectFfdc, RC); ";
+
+ # collectFfdc is a string we're going to stuff into FAPI_EXEC_HWP
+ # but we need to create the arguments in the ffdc class. The first
+ # element inthe collectFfdc string is the function to call.
+ my @elements = split /,/, $collectFfdc;
+# my @signature = @{$signatures{@elements[0]}};
+#
+# $TODO for SBE errors we need to get the parameters from the FFDC_BUFFER passed
+ for (my $i = 1; $i <= $#elements; $i++)
+ {
+ @elements[$i] =~ s/^\s+|\s+$//g;
+ addFfdcMethod(\%methods, @elements[$i], $err->{rc});
+ }
+ }
+
+ if ($count > 0)
+ {
+ print EIFILE "}";
+ }
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the CALL_FUNCS_TO_COLLECT_REG_FFDC macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC) ";
+
+ if(!$arg_local_ffdc)
+ {
+ foreach my $collectRegisterFfdc (@{$err->{collectRegisterFfdc}})
+ {
+ #------------------------------------------------------------------
+ # Check that expected fields are present
+ #------------------------------------------------------------------
+ if (! exists $collectRegisterFfdc->{id}[0])
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. id(s) missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+=begin
+ foreach my $id (@{$collectRegisterFfdc->{id}})
+ {
+ #---------------------------------------------------------------------------------
+ # Check FFDC register collection type: target, child, or based on present children
+ #---------------------------------------------------------------------------------
+ if (exists $collectRegisterFfdc->{target})
+ {
+ print EIFILE "fapi2::collectRegFfdc<fapi2::TARGET_TYPE_NONE, fapi2::TARGET_TYPE_NONE>($collectRegisterFfdc->{target}, ";
+ print EIFILE "fapi2::$id, RC); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{target},
+ $err->{rc}, $target_ffdc_type);
+ }
+ elsif (exists $collectRegisterFfdc->{childTargets})
+ {
+ if (! exists $collectRegisterFfdc->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR: parent missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR: childType missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ print EIFILE "fapi2::collectRegFfdc<fapi2::$collectRegisterFfdc->{childTargets}->{childType}, fapi2::TARGET_TYPE_NONE>";
+ print EIFILE "($collectRegisterFfdc->{childTargets}->{parent}, fapi2::$id, RC); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{childTargets}->{parent},
+ $err->{rc}, $target_ffdc_type);
+ }
+ elsif (exists $collectRegisterFfdc->{basedOnPresentChildren})
+ {
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{target})
+ {
+ print ("parseErrorInfo.pl ERROR: target missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR: childType missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{childPosOffsetMultiplier})
+ {
+ print ("parseErrorInfo.pl ERROR: childPosOffsetMultiplier missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ print EIFILE "fapi2::collectRegFfdc<fapi2::$collectRegisterFfdc->{basedOnPresentChildren}->{childType}, fapi2::TARGET_TYPE_NONE>";
+ print EIFILE "($collectRegisterFfdc->{basedOnPresentChildren}->{target}, fapi2::$id, RC, ";
+ print EIFILE "$collectRegisterFfdc->{basedOnPresentChildren}->{childPosOffsetMultiplier}); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{basedOnPresentChildren}->{target},
+ $err->{rc}, $target_ffdc_type);
+ }
+ else
+ {
+ print ("parseErrorInfo.pl ERROR: Invalid collectRegisterFfdc configuration\n");
+ exit(1);
+ }
+ }
+=cut
+ }
+
+ }
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the ADD_ERROR_INFO macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_ADD_ERROR_INFO(RC) ";
+
+ # Array of EI Objects
+ my @eiObjects;
+
+ my $eiEntryStr = "";
+ my $eiObjectMap = ""; #object names to buffer address mapping
+ my $eiObjectStr = "const void * l_objects[] = {";
+ my $executeStr = "";
+ my $eiEntryCount = 0;
+ my %cdgTargetHash; # Records the callout/deconfigure/gards for Targets
+ my %cdgChildHash; # Records the callout/deconfigure/gards for Children
+
+ # collect firmware trace
+ foreach my $collectTrace (@{$err->{collectTrace}})
+ {
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_COLLECT_TRACE; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].collect_trace.iv_eieTraceId = fapi2::CollectTraces::$collectTrace; \\\n";
+ $eiEntryCount++;
+ }
+ # Local FFDC
+ foreach my $ffdc (@{$err->{ffdc}})
+ {
+
+ # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc>
+ my $ffdcName = $err->{rc} . "_";
+ $ffdcName = $ffdcName . $ffdc;
+ setFfdcIdValue($ffdcName);
+
+ # Add the FFDC data to the EI Object array if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $ffdc);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $ffdc, $err->{rc},$ffdc_type,$objNum);
+
+ $ffdc = $mangle_names{$ffdc} if ($mangle_names{$ffdc} ne undef);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$ffdcName; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = $ffdc.size(); \\\n";
+ $eiEntryCount++;
+ }
+
+ # Multicast ID
+ foreach my $mcast (@{$err->{mcastId}})
+ {
+ # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc>
+ my $ffdcName = $err->{rc} . "_";
+ $ffdcName = $ffdcName . $mcast;
+ setFfdcIdValue($ffdcName);
+
+ # Add the FFDC data to the EI Object array if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $mcast);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $mcast, $err->{rc},$mcast_type,$objNum);
+
+ $mcast = $mangle_names{$mcast} if ($mangle_names{$mcast} ne undef);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$ffdcName; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = 4; \\\n";
+ $eiEntryCount++;
+ }
+
+ if(!$arg_local_ffdc)
+ {
+ # Buffers, looks a lot like local ffdc
+ foreach my $buffer (@{$err->{buffer}})
+ {
+ # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc>
+ my $bufferName = $err->{rc} . "_";
+ $bufferName = $bufferName . $buffer;
+ setFfdcIdValue($bufferName);
+
+ # Add the FFDC data to the EI Object array if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $buffer);
+
+ # Add a method to the ffdc-gathering class - one for each buffer type
+ addFfdcMethod(\%methods, $buffer, $err->{rc}, $buffer_ffdc_type);
+ addFfdcMethod(\%methods, $buffer, $err->{rc}, $variable_buffer_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$bufferName; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = fapi2::getErrorInfoFfdcSize($buffer); \\\n";
+ $eiEntryCount++;
+ }
+
+ # Procedure/Target/Bus/Child callouts
+ foreach my $callout (@{$err->{callout}})
+ {
+ if (! exists $callout->{priority})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout priority missing\n");
+ exit(1);
+ }
+
+ my $elementsFound = 0;
+ if (exists $callout->{hw})
+ {
+ # HW Callout
+ if (! exists $callout->{hw}->{hwid})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. HW Callout hwid missing\n");
+ exit(1);
+ }
+
+ # Check that those HW callouts that need reference targets have them
+ if (($callout->{hw}->{hwid} eq "TOD_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "MEM_REF_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "PROC_REF_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "PCI_REF_CLOCK"))
+ {
+ if (! exists $callout->{hw}->{refTarget})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout missing refTarget\n");
+ exit(1);
+ }
+ }
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_HW_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_hw = fapi2::HwCallouts::$callout->{hw}->{hwid}; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ if (exists $callout->{hw}->{refTarget})
+ {
+ # Add the Targets to the objectlist if they don't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $callout->{hw}->{refTarget});
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_refObjIndex = $objNum; \\\n";
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $callout->{hw}->{refTarget}, $err->{rc});
+ }
+ else
+ {
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_refObjIndex = 0xff; \\\n";
+ }
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{procedure})
+ {
+ # Procedure Callout
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_PROCEDURE_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].proc_callout.iv_procedure = fapi2::ProcedureCallouts::$callout->{procedure}; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].proc_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{bus})
+ {
+ # A Bus Callout consists of two targets separated by
+ # commas/spaces
+ my @targets = split(/\s*,\s*|\s+/, $callout->{bus});
+
+ if (scalar @targets != 2)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. did not find two targets in bus callout\n");
+ exit(1);
+ }
+
+ # Add the Targets to the objectlist if they don't already exist
+ my $objNum1 = addEntryToArray(\@eiObjects, $targets[0]);
+
+ my $objNum2 = addEntryToArray(\@eiObjects, $targets[1]);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $targets[0], $err->{rc}, $target_ffdc_type);
+ addFfdcMethod(\%methods, $targets[1], $err->{rc}, $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_BUS_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_endpoint1ObjIndex = $objNum1; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_endpoint2ObjIndex = $objNum2; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # deconfigure and GARD requests
+ $cdgTargetHash{$callout->{target}}{callout} = 1;
+ $cdgTargetHash{$callout->{target}}{priority} =
+ $callout->{priority};
+
+ $elementsFound++;
+ }
+ if (exists $callout->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $callout->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Callout parent missing\n");
+ exit(1);
+ }
+
+ if (! exists $callout->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Callout childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any deconfigure and GARD requests
+ my $parent = $callout->{childTargets}->{parent};
+ my $childType = $callout->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{callout} = 1;
+ $cdgChildHash{$parent}{$childType}{priority} =
+ $callout->{priority};
+
+ $elementsFound++;
+
+ if (exists $callout->{childTargets}->{childPort})
+ {
+ my $childPort = $callout->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+ }
+
+ if (exists $callout->{childTargets}->{childNumber})
+ {
+ my $childNum = $callout->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+ }
+
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout has multiple elements\n");
+ exit(1);
+ }
+ } # callout
+
+ # Target/Child deconfigures
+ foreach my $deconfigure (@{$err->{deconfigure}})
+ {
+ my $elementsFound = 0;
+ if (exists $deconfigure->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # callout and GARD requests
+ $cdgTargetHash{$deconfigure->{target}}{deconf} = 1;
+ $elementsFound++;
+ }
+ if (exists $deconfigure->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $deconfigure->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Deconfigure parent missing\n");
+ exit(1);
+ }
+ if (! exists $deconfigure->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Deconfigure childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any callout and GARD requests
+ my $parent = $deconfigure->{childTargets}->{parent};
+ my $childType = $deconfigure->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{deconf} = 1;
+
+ $elementsFound++;
+
+ if ( exists $deconfigure->{childTargets}->{childPort})
+ {
+ my $childPort = $deconfigure->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+ }
+
+ if ( exists $deconfigure->{childTargets}->{childNumber})
+ {
+ my $childNum = $deconfigure->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+
+ }
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Deconfigure incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Deconfigure has multiple elements\n");
+ exit(1);
+ }
+ } # deconfigure
+
+ # Target/Child Gards
+ foreach my $gard (@{$err->{gard}})
+ {
+ my $elementsFound = 0;
+ if (exists $gard->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # callout and deconfigure requests
+ $cdgTargetHash{$gard->{target}}{gard} = 1;
+ $elementsFound++;
+ }
+ if (exists $gard->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $gard->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child GARD parent missing\n");
+ exit(1);
+ }
+ if (! exists $gard->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child GARD childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any callout and deconfigure requests
+ my $parent = $gard->{childTargets}->{parent};
+ my $childType = $gard->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{gard} = 1;
+
+ $elementsFound++;
+
+ if ( exists $gard->{childTargets}->{childPort})
+ {
+ my $childPort = $gard->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+
+ }
+
+ if ( exists $gard->{childTargets}->{childNumber})
+ {
+ my $childNum = $gard->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+ }
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. GARD incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. GARD has multiple elements\n");
+ exit(1);
+ }
+ } # gard
+
+ # Process the callout, deconfigures and GARDs for each Target
+ foreach my $cdg (keys %cdgTargetHash)
+ {
+ my $callout = 0;
+ my $priority = 'LOW';
+ my $deconf = 0;
+ my $gard = 0;
+
+ if (exists $cdgTargetHash{$cdg}->{callout})
+ {
+ $callout = 1;
+ }
+ if (exists $cdgTargetHash{$cdg}->{priority})
+ {
+ $priority = $cdgTargetHash{$cdg}->{priority};
+ }
+ if (exists $cdgTargetHash{$cdg}->{deconf})
+ {
+ $deconf = 1;
+ }
+ if (exists $cdgTargetHash{$cdg}->{gard})
+ {
+ $gard = 1;
+ }
+
+ # Add the Target to the objectlist if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $cdg);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $cdg, $err->{rc}, $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_CDG; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_targetObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_callout = $callout; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_deconfigure = $deconf; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_gard = $gard; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n";
+ $eiEntryCount++;
+ }
+
+ # Process the callout, deconfigures and GARDs for Child Targets
+ foreach my $parent (keys %cdgChildHash)
+ {
+ foreach my $childType (keys %{$cdgChildHash{$parent}})
+ {
+ my $callout = 0;
+ my $priority = 'LOW';
+ my $deconf = 0;
+ my $gard = 0;
+ my $childPort = 0xFF;
+ my $childNumber = 0xFF;
+
+ if (exists $cdgChildHash{$parent}{$childType}->{callout})
+ {
+ $callout = 1;
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{priority})
+ {
+ $priority =
+ $cdgChildHash{$parent}->{$childType}->{priority};
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{deconf})
+ {
+ $deconf = 1;
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{childPort})
+ {
+ $childPort =
+ $cdgChildHash{$parent}->{$childType}->{childPort} ;
+ addFfdcMethod(\%methods, $childPort, $err->{rc});
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{childNumber})
+ {
+ $childNumber =
+ $cdgChildHash{$parent}->{$childType}->{childNumber} ;
+ addFfdcMethod(\%methods, $childNumber, $err->{rc});
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{gard})
+ {
+ $gard = 1;
+ }
+
+
+ # Add the Target to the objectlist if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $parent);
+ addFfdcMethod(\%methods, $parent, $err->{rc}, $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_CHILDREN_CDG; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_parentObjIndex = $objNum; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_callout = $callout; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_deconfigure = $deconf; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childType = fapi2::$childType; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childPort = $childPort; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childNumber = $childNumber; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_gard = $gard; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n";
+ $eiEntryCount++;
+ }
+ }
+ }
+ # Add all objects to $eiObjectStr
+ my $objCount = 0;
+
+ foreach my $eiObject (@eiObjects)
+ {
+ if ($objCount > 0)
+ {
+ $eiObjectStr .= ", ";
+ }
+
+ if ($mangle_names{$eiObject} eq undef)
+ {
+ $eiObjectStr .= "$eiObject";
+
+ if ((exists $err->{sbeError}) )
+ {
+ $objectStr .= "\t\tfapi2::ffdc_t $eiObject = getFfdcData(FFDC_BUFFER[$objCount]); \\\n";
+ }
+ }
+ else
+ {
+ $eiObjectStr .= $mangle_names{$eiObject};
+ }
+
+ $objCount++;
+ }
+ $eiObjectStr .= "};";
+
+
+ # Print info to file
+ if ($eiEntryCount > 0)
+ {
+ print EIFILE "\\\n{ \\\n $eiObjectStr \\\n";
+ print EIFILE " fapi2::ErrorInfoEntry l_entries[$eiEntryCount]; \\\n";
+ print EIFILE "$eiEntryStr";
+ print EIFILE " RC.addErrorInfo(l_objects, l_entries, $eiEntryCount); \\\n}";
+ }
+
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the return code class to hwp_error_info.H
+ #----------------------------------------------------------------------
+ # Remove the repeated whitespace and newlines other characters from the description
+ $err->{description} =~ s/^\s+|\s+$|"//g;
+ $err->{description} =~ tr{\n}{ };
+ $err->{description} =~ s/\h+/ /g;
+
+ #----------------------------------------------------------------------
+ # Print the return code class to hwp_error_info.H
+ #----------------------------------------------------------------------
+ my $class_name = $err->{rc};
+ # Remove everything upto and including the first _. This makes the ffdc class
+ # names different from the error code value enum names.
+ $class_name = (split (/_/, $class_name, 2))[1];
+
+ # Class declaration
+ print ECFILE "\nclass $class_name\n{\n public:\n";
+
+ # Constructor. This traces the description. If this is too much, we can
+ # remove it.
+ if ($arg_empty_ffdc eq undef)
+ {
+ if(!$arg_local_ffdc)
+ {
+ print ECFILE " $class_name(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, fapi2::ReturnCode& i_rc = fapi2::current_err):\n";
+ print ECFILE " iv_rc(i_rc),\n";
+ print ECFILE " iv_sev(i_sev)\n";
+ print ECFILE " { FAPI_ERR(\"$err->{description}\"); }\n";
+ }
+ else
+ {
+ print ECFILE " $class_name()\n";
+ print ECFILE " {\n\t\tfapi2::current_err = RC_$class_name;\n\t\tFAPI_ERR(\"$err->{description}\");\n";
+ print ECFILE " \tfapi2::g_FfdcData.fapiRc = RC_$class_name;\n\t}\n\n";
+ }
+ }
+ else
+ {
+ # Void expression keeps the compiler from complaining about the unused arguments.
+ # We want to set the i_rc to the RC if we're empty. This otherwise gets done in _setHwpError()
+ print ECFILE " $class_name(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, fapi2::ReturnCode& i_rc = fapi2::current_err)\n";
+ print ECFILE " {\n";
+ print ECFILE " static_cast<void>(i_sev);\n";
+ print ECFILE " i_rc = $err->{rc};\n";
+ print ECFILE " }\n\n";
+ }
+
+ my $method_count = 0;
+ # Methods
+ foreach my $key (keys %methods)
+ {
+ print ECFILE $methods{$key}{method};
+ $method_count++;
+ }
+ if(!$arg_local_ffdc)
+ {
+ # add a method to adjust the severity if desired
+ print ECFILE " inline void setSev(const fapi2::errlSeverity_t i_sev)\n";
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " { iv_sev = i_sev; };\n\n";
+ }
+ else
+ {
+ print ECFILE " { static_cast<void>(i_sev); };\n\n";
+ }
+
+ # add a method to read the severity if desired
+ print ECFILE " inline fapi2::errlSeverity_t getSev() const\n";
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " { return iv_sev; };\n\n";
+ }
+ else
+ {
+ print ECFILE " { return fapi2::FAPI2_ERRL_SEV_UNDEFINED; };\n\n";
+ }
+
+ }
+
+ if( $arg_local_ffdc eq undef )
+ {
+ # Stick the execute method at the end of the other methods. We allow
+ # passing in of the severity so that macros which call execute() can over-ride
+ # the default severity.
+ print ECFILE " void execute(fapi2::errlSeverity_t" .
+ " i_sev = fapi2::FAPI2_ERRL_SEV_UNDEFINED," .
+ "bool commit = false )\n";
+ if ($arg_empty_ffdc eq undef )
+ {
+ print ECFILE " {\n";
+ print ECFILE " FAPI_SET_HWP_ERROR(iv_rc, $err->{rc});\n";
+ print ECFILE " if( commit )\n";
+ print ECFILE " {\n";
+ print ECFILE " fapi2::logError(iv_rc, " .
+ "(i_sev == fapi2::FAPI2_ERRL_SEV_UNDEFINED)" .
+ " ? iv_sev : i_sev);\n";
+ print ECFILE " }\n";
+ print ECFILE " }\n";
+
+ }
+ else
+ {
+ print ECFILE " {\n";
+ print ECFILE " static_cast<void>(i_sev);\n";
+ print ECFILE " static_cast<void>(commit);\n";
+ print ECFILE " }\n\n";
+ }
+
+ # Instance variables
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " public:\n ";
+ foreach my $key (keys %methods)
+ {
+ print ECFILE $methods{$key}{member};
+ }
+
+ print ECFILE "fapi2::ReturnCode& iv_rc;\n";
+ print ECFILE " fapi2::errlSeverity_t iv_sev;\n";
+ }
+
+ }
+ else
+ {
+ print ECFILE " void execute()\n";
+ print ECFILE " {\n";
+ print ECFILE "$executeStr\n";
+ print ECFILE " }\n";
+ }
+
+ print ECFILE "};\n\n";
+
+ #----------------------------------------------------------------------
+ # If this is an SBE error, add it to set_sbe_error.H
+ #----------------------------------------------------------------------
+ if (exists $err->{sbeError})
+ {
+ print SBFILE "\tcase fapi2::$err->{rc}: \\\n";
+ print SBFILE "\t{ \\\n$objectStr";
+ print SBFILE "\t\tFAPI_SET_HWP_ERROR(RC, $err->{rc});\\\n";
+ print SBFILE " break; \\\n\t} \\\n";
+ }
+
+ }
+
+=pos
+ #
+ #--------------------------------------------------------------------------
+ # For each registerFfdc.
+ #--------------------------------------------------------------------------
+ foreach my $registerFfdc (@{$errors->{registerFfdc}})
+ {
+ #----------------------------------------------------------------------
+ # Check that expected fields are present
+ #----------------------------------------------------------------------
+ if (! exists $registerFfdc->{id}[0])
+ {
+ print ("parseErrorInfo.pl ERROR. id missing from registerFfdc\n");
+ exit(1);
+ }
+
+ if (scalar @{$registerFfdc->{id}} > 1)
+ {
+ print ("parseErrorInfo.pl ERROR. multiple ids in registerFfdc\n");
+ exit(1);
+ }
+
+ #----------------------------------------------------------------------
+ # Set the FFDC ID value in a global hash
+ #----------------------------------------------------------------------
+ setFfdcIdValue($registerFfdc->{id}[0]);
+
+ #----------------------------------------------------------------------
+ # Generate code to capture the registers in collect_reg_ffdc.C
+ #----------------------------------------------------------------------
+ print CRFILE " case $registerFfdc->{id}[0]:\n";
+
+# TODO: RTC 132226
+=begin NEED_P9_REGISTERS
+ # Look for CFAM Register addresses
+ foreach my $cfamRegister (@{$registerFfdc->{cfamRegister}})
+ {
+ print CRFILE " l_cfamAddresses.push_back($cfamRegister);\n";
+ print CRFILE " l_ffdcSize += sizeof(l_cfamData);\n";
+ }
+
+ # Look for SCOM Register addresses
+ foreach my $scomRegister (@{$registerFfdc->{scomRegister}})
+ {
+ print CRFILE " l_scomAddresses.push_back($scomRegister);\n";
+ print CRFILE " l_ffdcSize += sizeof(l_scomData);\n";
+ }
+=cut NEED_P9_REGISTERS
+
+print CRFILE " break;\n";
+ }
+=cut
+}
+
+#------------------------------------------------------------------------------
+# Print end of file information to collect_reg_ffdc.C
+#------------------------------------------------------------------------------
+print CRFILE " default:\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Invalid FFDC ID 0x%x\", ";
+print CRFILE "i_ffdcId);\n";
+print CRFILE " return;\n";
+print CRFILE " }\n\n";
+
+# TODO: RTC 132226
+=begin NEED_P9_REGISTERS
+print CRFILE " uint8_t * l_pBuf = NULL;\n";
+print CRFILE " uint8_t * l_pData = NULL;\n";
+print CRFILE " std::vector<fapi::Target> l_targets;\n";
+print CRFILE " uint32_t l_chipletPos32 = 0;\n";
+
+#---------------------------------------------------------------------------------------------------------
+# Populate chiplet vectors (if required by register collection method) and adjust buffer sizes accordingly
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " if (C != TARGET_TYPE_NONE)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetChildChiplets(i_target, i_child, l_targets, TARGET_STATE_FUNCTIONAL);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error: fapiGetChildChiplets: failed to get chiplets.\");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " if (l_targets.empty())\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_INF(\"collect_reg_ffdc.C: Error: No functional chiplets found. \");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_ffdcSize *= l_targets.size();\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " }\n";
+print CRFILE " else if (P != TARGET_TYPE_NONE)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetChildChiplets(i_target, i_presChild, l_targets, TARGET_STATE_PRESENT);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error: fapiGetChildChiplets: failed to get chiplets.\");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " if (l_targets.empty())\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_INF(\"collect_reg_ffdc.C: Error: No functional chiplets found. \");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_ffdcSize *= l_targets.size();\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " l_targets.push_back(i_target);\n";
+print CRFILE " }\n\n";
+
+#---------------------------------------------------------------------------------------------------------
+# Obtain target position and insert as the first word in the buffer
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " bool l_targIsChiplet = i_target.isChiplet();\n\n";
+print CRFILE " for (std::vector<fapi::Target>::const_iterator targetIter = l_targets.begin();\n";
+print CRFILE " targetIter != l_targets.end(); ++targetIter)\n";
+print CRFILE " {\n";
+print CRFILE " if ((fapi2::TARGET_TYPE_NONE != i_child) ||\n";
+print CRFILE " (fapi2::TARGET_TYPE_NONE != i_presChild) ||\n";
+print CRFILE " (true == l_targIsChiplet))\n";
+print CRFILE " {\n";
+print CRFILE " uint8_t l_chipletPos = 0;\n";
+print CRFILE " l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &(*targetIter), l_chipletPos);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error getting chiplet position\");\n";
+print CRFILE " l_chipletPos = 0xFF;\n";
+print CRFILE " }\n";
+ #-------------------------------------------------------------------------
+ # We print the target's position in the error log whether the target is a
+ # chip or chiplet, so we need to store the chiplet position in a uint32_t
+ # to have consitency in the buffer as ATTR_POS below returns a uint32_t
+ #-------------------------------------------------------------------------
+print CRFILE " l_chipletPos32 = l_chipletPos;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = FAPI_ATTR_GET(ATTR_POS, &(*targetIter), l_chipletPos32);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error getting chip position\");\n";
+print CRFILE " l_chipletPos32 = 0xFFFFFFFF;\n";
+print CRFILE " }\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint32_t *>(l_pData)) = l_chipletPos32;\n";
+print CRFILE " l_pData += sizeof(l_chipletPos32);\n";
+#---------------------------------------------------------------------------------------------------------
+# Instert cfam data (if any) related to this chip / chiplet into the buffer
+# If collecting FFDC based on present children, adjust the register address by the appropriate offset
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " for (std::vector<uint32_t>::const_iterator cfamIter = l_cfamAddresses.begin();\n";
+print CRFILE " cfamIter != l_cfamAddresses.end(); ++cfamIter)\n";
+print CRFILE " {\n";
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetCfamRegister(i_target, (*cfamIter + (l_chipletPos32 * i_childOffsetMult)), l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetCfamRegister(*targetIter, *cfamIter, l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: CFAM error for 0x%x\",";
+print CRFILE "*cfamIter);\n";
+print CRFILE " l_cfamData = 0xbaddbadd;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_cfamData = l_buf.getWord(0);\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint32_t *>(l_pData)) = l_cfamData;\n";
+print CRFILE " l_pData += sizeof(l_cfamData);\n";
+print CRFILE " }\n\n";
+#---------------------------------------------------------------------------------------------------------
+# Instert any scom data (if any) related to this chip / chiplet into the buffer
+# If collecting FFDC based on present children, adjust the register address by the appropriate offset
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " for (std::vector<uint64_t>::const_iterator scomIter = l_scomAddresses.begin();\n";
+print CRFILE " scomIter != l_scomAddresses.end(); ++scomIter)\n";
+print CRFILE " {\n";
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetScom(i_target, (*scomIter + (l_chipletPos32 * i_childOffsetMult)), l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetScom(*targetIter, *scomIter, l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: SCOM error for 0x%llx\",";
+print CRFILE "*scomIter);\n";
+print CRFILE " l_scomData = 0xbaddbaddbaddbaddULL;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_scomData = l_buf.getDoubleWord(0);\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint64_t *>(l_pData)) = l_scomData;\n";
+print CRFILE " l_pData += sizeof(l_scomData);\n";
+print CRFILE " }\n";
+print CRFILE " }\n\n";
+print CRFILE " o_rc.addEIFfdc(i_ffdcId, l_pBuf, l_ffdcSize);\n";
+print CRFILE " delete [] l_pBuf;\n";
+
+=cut NEED_P9_REGISTERS
+
+print CRFILE "}\n";
+print CRFILE "}\n";
+print CRFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Print the fapiHwpReturnCodes.H file
+#------------------------------------------------------------------------------
+print RCFILE "// fapiHwpReturnCodes.H\n";
+print RCFILE "// This file is generated by perl script parseErrorInfo.pl\n\n";
+print RCFILE "#ifndef FAPI2_HWPRETURNCODES_H_\n";
+print RCFILE "#define FAPI2_HWPRETURNCODES_H_\n\n";
+print RCFILE "#ifndef __ASSEMBLER__\n";
+print RCFILE "namespace fapi2\n";
+print RCFILE "{\n\n";
+print RCFILE "/**\n";
+print RCFILE " * \@brief Enumeration of HWP return codes\n";
+print RCFILE " *\/\n";
+print RCFILE "enum HwpReturnCode\n";
+print RCFILE "{\n";
+foreach my $key (keys %errNameToValueHash)
+{
+ print RCFILE " $key = 0x$errNameToValueHash{$key},\n";
+}
+print RCFILE "};\n\n";
+print RCFILE "}\n\n";
+print RCFILE "#else\n";
+foreach my $key (keys %errNameToValueHash)
+{
+ print RCFILE " .set $key, 0x$errNameToValueHash{$key}\n";
+}
+print RCFILE "#endif\n";
+print RCFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Print the HwpFfdcId enumeration to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "namespace fapi2\n";
+print EIFILE "{\n\n";
+if($arg_local_ffdc)
+{
+ print EIFILE " extern SbeFfdcData_t g_FfdcData;\n";
+}
+print EIFILE "/**\n";
+print EIFILE " * \@brief Enumeration of FFDC identifiers\n";
+print EIFILE " *\/\n";
+print EIFILE "enum HwpFfdcId\n";
+print EIFILE "{\n";
+foreach my $key (keys %ffdcNameToValueHash)
+{
+ print EIFILE " $key = 0x$ffdcNameToValueHash{$key},\n";
+}
+print EIFILE "};\n\n";
+print EIFILE "}\n\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "\n\n#endif\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to hwp_ffdc_classes.H
+#------------------------------------------------------------------------------
+print ECFILE "\n};\n"; # close the namespace
+print ECFILE "\n\n#endif\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to set_sbe_error.H
+#------------------------------------------------------------------------------
+print SBFILE " default:\\\n";
+#print SBFILE " FAPI_SET_HWP_ERROR(RC, RC_SBE_UNKNOWN_ERROR,0);\\\n";
+print SBFILE " break;\\\n";
+print SBFILE "}\\\n";
+print SBFILE "}\n\n";
+print SBFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Close output files
+#------------------------------------------------------------------------------
+close(RCFILE);
+close(EIFILE);
+close(ECFILE);
+close(CRFILE);
+close(SBFILE);
diff --git a/src/tools/scripts/ppeCreateAttrGetSetMacros.pl b/src/tools/scripts/ppeCreateAttrGetSetMacros.pl
new file mode 100755
index 00000000..72ae2aa8
--- /dev/null
+++ b/src/tools/scripts/ppeCreateAttrGetSetMacros.pl
@@ -0,0 +1,571 @@
+#!/usr/bin/perl -w
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeCreateAttrGetSetMacros.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+#find enums in AttributeId
+#for each enum check for ${enum}_Type
+#check for type and array values
+#Check Plat file for ${enum}_GETMACRO and ${enum}_SETMACRO
+#If they do not exist add apporpriate _SETMACRO and _GETMACRO to Plat file
+
+use strict;
+use File::Copy;
+use Getopt::Long;
+
+sub enumParser ($);
+sub help;
+
+my $DEBUG = 0;
+my $VERBOSE = 0;
+
+my $state = 0;
+my $last_value = -1;
+my $current_entry;
+my $current_enum_name;
+
+my %enums;
+
+my %attributeTypes;
+my %attributeArrayTypes;
+
+my %getMacros;
+my %setMacros;
+my %targetMacros;
+
+
+
+my $fapiAttributeIdsFile = "fapi2AttributeIds.H";
+my $fapiPlatAttributeServiceFile= "fapi2PlatAttributeService.H";
+
+
+my $includePath = "./";
+my $srcPath = "./";
+
+my @newAttributeDefines;
+my @newTargetDefines;
+my @newTargetImplementations;
+
+
+my $servicePath;
+my $help;
+
+GetOptions ("verbose" => \$VERBOSE,
+ "help" => \$help,
+ "debug" => \$DEBUG,
+ "path=s" => \$servicePath,
+ "inc=s" => \$includePath,
+ "src=s" => \$srcPath,
+);
+
+help() if $help;
+
+open (FILE, $includePath . "/" . $fapiAttributeIdsFile) or die "ERROR:: could not open $fapiAttributeIdsFile\n";
+
+while (<FILE>) {
+ # attempt to parse attributes from current line in file
+ enumParser($_);
+
+ # see if the line describes an attribute
+ if (m/\s*typedef\s+(\w+)\s+(\w+)_Type(\S*)\s*;/) {
+ my $type = $1;
+ my $attribute = $2;
+ my $arrayType = $3;
+
+ if ($DEBUG) { print "DEBUG:: type = $type : attribute = $attribute : arrayType = $arrayType\n"; }
+
+ # save attribute type and if it is an array and its size
+ $attributeTypes{$attribute} = $type;
+ if ($arrayType) {
+ $attributeArrayTypes{$attribute} = $arrayType;
+ } else {
+ $attributeArrayTypes{$attribute} = "none";
+ }
+ }
+
+ # look for MACROs
+ # look for: #define ATTR_CHIP_HAS_SBE_GETMACRO ATTRIBUTE_NOT_WRITABLE
+ if (m/\s*#define\s+(\w+)_GETMACRO\s+(\S+)\s*/) {
+ $getMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : GETMACRO = $2\n"; }
+ # look for: #define ATTR_CHIP_EC_FEATURE_TEST1_GETMACRO(ID, PTARGET, VAL) fapi::fapiQueryChipEcFeature(ID, PTARGET, VAL)
+ } elsif (m/\s*#define\s+(\w+)_GETMACRO\(ID\,\sPTARGET\,\sVAL\)\s(.+)/) {
+ $getMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : GETMACRO = $2\n"; }
+ # look for: #define ATTR_CHIP_HAS_SBE_SETMACRO ATTRIBUTE_NOT_WRITABLE
+ } elsif (m/\s*#define\s+(\w+)_SETMACRO\s+(\S+)\s*/) {
+ $setMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : SETMACRO = $2\n"; }
+ # look for: #define ATTR_CHIP_EC_FEATURE_TEST2_SETMACRO(ID, PTARGET, VAL) CHIP_EC_FEATURE_ATTRIBUTE_NOT_WRITABLE
+ } elsif (m/\s*#define\s+(\w+)_SETMACRO\(ID\,\sPTARGET\,\sVAL\)\s(.+)/) {
+ $setMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : SETMACRO = $2\n"; }
+ } elsif (m/\s*const\s*TargetType\s+(\w+)_TargetTypes\s*=\s*(\S+)\s*;\s*/) {
+ $targetMacros{$1} = $2;
+# print "DEBUG:: attribute = $1 : TARGET = $2\n";
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : TARGET = $2\n"; }
+ }
+}
+
+close (FILE);
+
+#find copy of fapiPlatAttributeService.H
+if (!$servicePath) {
+ #$CTEPATH/tools/ecmd/$ECMD_RELEASE/ext/fapi/capi
+ my $ctepath = $ENV{CTEPATH};
+ my $ecmd_release = $ENV{ECMD_RELEASE};
+ if ($DEBUG) { print "DEBUG:: ctepath = $ctepath\n"; }
+ if ($DEBUG) { print "DEBUG:: ecmd_release = $ecmd_release\n"; }
+ if (!$ctepath) {
+ print "ERROR:: environment variable CTEPATH not defined!\n";
+ exit 1;
+ }
+ if (!$ecmd_release) {
+ print "ERROR:: environment variable ECMD_RELEASE not defined!\n";
+ exit 1;
+ }
+ $servicePath = "$ctepath/tools/ecmd/$ecmd_release/ext/fapi/capi";
+}
+
+if ($DEBUG) { print "DEBUG:: servicePath = $servicePath\n"; }
+
+# test that servicePath exists
+if (!-d $servicePath) {
+ print "ERROR:: path $servicePath does not exist!\n";
+ exit 1;
+}
+
+# test that fapiPlatAttributeService.H is in that directory
+if (!-f "$servicePath/$fapiPlatAttributeServiceFile") {
+ print "ERROR:: $fapiPlatAttributeServiceFile does not exist in $servicePath\n";
+ exit 1;
+}
+
+# copy fapiPlatAttributeService.H to local dir
+#my $systemRc = system("cp $servicePath/$fapiPlatAttributeServiceFile $includePath");
+copy("$servicePath/$fapiPlatAttributeServiceFile","$includePath") or die "Copy failed: $!";
+
+#if ($systemRc) {
+# print "ERROR:: error copying $fapiPlatAttributeServiceFile from $servicePath\n";
+# exit 1;
+#}
+
+
+
+# look in fapiPlatAttributeService.H for MACROs
+open (FILE, $includePath . "/". $fapiPlatAttributeServiceFile) or die "ERROR:: could not open $fapiPlatAttributeServiceFile\n";
+while (<FILE>) {
+ if (m/\s*#define\s+(\w+)_GETMACRO\s+(\S+)\s*/) {
+ $getMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : GETMACRO = $2\n"; }
+ } elsif (m/\s*#define\s+(\w+)_SETMACRO\s+(\S+)\s*/) {
+ $setMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : SETMACRO = $2\n"; }
+ } elsif (m/\s*const\s*TargetType\s+(\w+)_TargetTypes\s*=\s*(\S+)\s*;\s*/) {
+ $targetMacros{$1} = $2;
+ if ($DEBUG) { print "DEBUG:: attribute = $1 : TARGET = $2\n"; }
+ }
+}
+close (FILE);
+
+# go through attributes found in file
+for my $attribute (sort keys %{$enums{AttributeId}}) {
+ if ($DEBUG) { print "DEBUG:: attribute = $attribute\n"; }
+ my $type;
+ my $arrayType;
+ my $dimension = 0;
+
+ # check that each attribute has attributeType
+ if ($attributeTypes{$attribute}) {
+ if ($attributeArrayTypes{$attribute}) {
+ $type = $attributeTypes{$attribute};
+ $arrayType = $attributeArrayTypes{$attribute};
+ } else {
+ print "ERROR:: arrayType not found for $attribute\n";
+ next;
+ }
+ } else {
+ print "ERROR:: type not found for $attribute\n";
+ next;
+ }
+
+ # determine if attribute is an array
+ if ($arrayType =~ m/none/) {
+ if ($DEBUG) { print "DEBUG:: $attribute = $type\n"; }
+ } else {
+ # find dimension for array
+ my $tempArrayType = $arrayType;
+ while ($tempArrayType =~ m/\[\d*\].*/) {
+ $dimension++;
+ $tempArrayType =~ s/\[\d*\]//;
+ }
+ if ($DEBUG) { print "DEBUG:: $attribute = $type$arrayType dimension = $dimension\n"; }
+ }
+
+ my $setMacro = $setMacros{$attribute};
+ my $getMacro = $getMacros{$attribute};
+ my $targetMacro = $targetMacros{$attribute};
+
+# print "$attribute $setMacro $getMacro $targetMacro \n";
+
+ # if an attribute is missing the SET or GET MACRO add to list in insert into file later
+ if (!($getMacro && $setMacro)) {
+ my $macroPrefix = "PLAT_ATTR_";
+ my $macroPostfix = "";
+
+ if ($dimension == 0) {
+ $macroPostfix = "_GLOBAL_INT";
+ } else {
+ if ($type =~ m/uint8_t/) {
+ $macroPostfix = "_UINT8_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/uint16_t/) {
+ $macroPostfix = "_UINT16_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/uint32_t/) {
+ $macroPostfix = "_UINT32_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/uint64_t/) {
+ $macroPostfix = "_UINT64_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/int8_t/) {
+ $macroPostfix = "_INT8_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/int16_t/) {
+ $macroPostfix = "_INT16_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/int32_t/) {
+ $macroPostfix = "_INT32_" . $dimension . "D_ARRAY";
+ } elsif ($type =~ m/int64_t/) {
+ $macroPostfix = "_INT64_" . $dimension . "D_ARRAY";
+ } else {
+ print "ERROR:: unknown type $type for attribute $attribute\n";
+ next;
+ }
+ }
+
+ my $macroTarget = "";
+ if(defined $targetMacro) {
+ if($targetMacro eq "TARGET_TYPE_SYSTEM") {
+ $macroTarget = "SystemAttributes_t";
+ } elsif ($targetMacro eq "TARGET_TYPE_PROC_CHIP") {
+ $macroTarget = "ProcChipAttributes_t";
+ } elsif ($targetMacro eq "TARGET_TYPE_CORE") {
+ $macroTarget = "CoreAttributes_t";
+ } elsif ($targetMacro eq "TARGET_TYPE_EX") {
+ $macroTarget = "EXAttributes_t";
+ } elsif ($targetMacro eq "TARGET_TYPE_EQ") {
+ $macroTarget = "EQAttributes_t";
+ } elsif ($targetMacro eq "TARGET_TYPE_PERV") {
+ $macroTarget = "PervAttributes_t";
+ } else {
+ print "ERROR:: unknown type $targetMacro for attribute $attribute\n";
+ next;
+ }
+ }
+
+ if (!$getMacro) {
+ if ($VERBOSE) { print "INFO:: did not find ${attribute}_GETMACRO\n"; }
+ my $attributeDefine = "#define ${attribute}_GETMACRO ${macroPrefix}GET${macroPostfix}";
+ push(@newAttributeDefines, $attributeDefine);
+
+ if(defined $targetMacro) {
+
+
+ my $targetFunction = "template<> inline void __get<fapi2::$targetMacro, fapi2attr::$macroTarget, $type, fapi2::${attribute}> ( const fapi2::Target<fapi2::$targetMacro>& i_ptarget, const fapi2attr::$macroTarget* object, const fapi2::AttributeId attrid, $type* o_pvalue )";
+ push(@newTargetDefines, $targetFunction . ";");
+
+ my $targetImplementation = "";
+ if($targetMacro eq "TARGET_TYPE_PROC_CHIP" | $targetMacro eq "TARGET_TYPE_SYSTEM") {
+
+ $targetImplementation .= "\n" . $targetFunction . "\n{\n *o_pvalue = object->fapi2attr::${macroTarget}::${attribute};\n}\n";
+
+ } elsif($targetMacro eq "TARGET_TYPE_PERV") {
+
+ $targetImplementation .= "\n" . $targetFunction .
+"\n{
+ *o_pvalue = object->fapi2attr::${macroTarget}::${attribute}[getPervAttrIndex(i_ptarget)];
+}\n";
+
+ } else {
+$targetImplementation .= "\n" . $targetFunction . "\n{\n uint32_t index = i_ptarget.getTargetNumber();\n *o_pvalue = object->fapi2attr::${macroTarget}::${attribute}[index];\n}\n"
+ }
+ push(@newTargetImplementations, $targetImplementation);
+ }
+ }
+ if (!$setMacro) {
+ if ($VERBOSE) { print "INFO:: did not find ${attribute}_SETMACRO\n"; }
+ my $attributeDefine = "#define ${attribute}_SETMACRO ${macroPrefix}SET${macroPostfix}";
+ push(@newAttributeDefines, $attributeDefine);
+
+ if(defined $targetMacro) {
+
+ my $targetFunction = "template<> inline void __set<fapi2::$targetMacro, fapi2attr::$macroTarget, $type, fapi2::${attribute}> ( const fapi2::Target<fapi2::$targetMacro>& i_ptarget, fapi2attr::$macroTarget* object, const fapi2::AttributeId attrid, const $type& i_pvalue )";
+ push(@newTargetDefines, $targetFunction . ";");
+
+ my $targetImplementation = "";
+
+ if($targetMacro eq "TARGET_TYPE_PROC_CHIP" | $targetMacro eq "TARGET_TYPE_SYSTEM") {
+
+ $targetImplementation = "\n" . $targetFunction . "\n{\n object->fapi2attr::${macroTarget}::${attribute} = i_pvalue;\n}\n";
+ } else {
+ $targetImplementation = "\n" . $targetFunction . "\n{\n uint32_t index = i_ptarget.getTargetNumber();\n object->fapi2attr::${macroTarget}::${attribute}[index] = i_pvalue;\n}\n";
+ }
+
+ push(@newTargetImplementations, $targetImplementation);
+ }
+ }
+ }
+}
+
+# if file is missing any GET or SET MACROs
+if (@newAttributeDefines != 0) {
+
+ my $updatedFapiPlatAttributeServiceFile = "$fapiPlatAttributeServiceFile.temp";
+ open (OUTFILE, ">$updatedFapiPlatAttributeServiceFile") or die "ERROR:: could not open $updatedFapiPlatAttributeServiceFile\n";
+ open (FILE, $includePath . "/" . $fapiPlatAttributeServiceFile) or die "ERROR:: could not open $fapiPlatAttributeServiceFile\n";
+
+ my $insertTagFound = 0;
+
+ while (<FILE>) {
+ print OUTFILE $_;
+ # search for tag to insert after
+ if (m/\/\*.*INSERT NEW ATTRIBUTES HERE.*\*\//) {
+ $insertTagFound = 1;
+ # insert missing GET or SET MACROs
+ print OUTFILE "\n";
+ foreach my $attributeDefine (@newAttributeDefines) {
+ print OUTFILE "$attributeDefine\n";
+ if ($VERBOSE) { print "INFO:: adding $attributeDefine\n"; }
+ }
+ }
+
+ if (m/\/\*.*INSERT NEW GETTER AND SETTER FUNCTIONS HERE.*\*\//) {
+
+ $insertTagFound = 1;
+ # insert missing GET or SET MACROs
+ print OUTFILE "\n";
+ foreach my $targetDefine (@newTargetDefines) {
+ print OUTFILE "$targetDefine\n";
+ if ($VERBOSE) { print "INFO:: adding getter setter method\n"; }
+ }
+ print OUTFILE "
+ __attribute__((always_inline)) inline uint32_t getPervAttrIndex(const fapi2::Target<TARGET_TYPE_PERV> &i_target)
+ {
+ uint32_t l_index = i_target.getTargetNumber();
+ if(PPE_TARGET_TYPE_EQ & i_target.getTargetType())
+ {
+ l_index += (EQ_TARGET_OFFSET);
+ }
+ else if(PPE_TARGET_TYPE_CORE & i_target.getTargetType())
+ {
+ l_index += (CORE_TARGET_OFFSET);
+ }
+ else if(PPE_TARGET_TYPE_MCBIST & i_target.getTargetType())
+ {
+ l_index += (MCBIST_TARGET_OFFSET);
+ }
+ else
+ {
+ l_index += (NEST_GROUP1_TARGET_OFFSET);
+ }
+ return (l_index - NEST_GROUP1_TARGET_OFFSET);
+ }
+ ";
+
+
+ foreach my $impl (@newTargetImplementations) {
+
+ print OUTFILE $impl;
+
+ }
+ }
+
+
+ }
+ close (FILE);
+ close (OUTFILE);
+
+ if ($insertTagFound == 0) {
+ # remove file that we did not update
+ system("rm $updatedFapiPlatAttributeServiceFile");
+ print ("WARNING:: did not find tag \"INSERT NEW ATTRIBUTES HERE\" in $fapiPlatAttributeServiceFile. no updates performed.\n");
+ } else {
+ # copy new file over the old one
+ system("mv $updatedFapiPlatAttributeServiceFile $includePath/$fapiPlatAttributeServiceFile");
+ }
+}
+
+
+
+
+exit;
+
+# enumParser state machine
+# "enum" "enum_name" "{" "entry" "}"
+# [0] ------> [1] -------------> [2] ---> [3] -----------> [4] -------------------------------------> [7]
+# "," "=" "value" "}"
+# [3] <----------- [4] ----> [5] --------> [6] -------------> [7]
+# "}" ";"
+# [3] -----------------------------------------------------> [7] ---> [0]
+# ","
+#
+# [3] <----------------------------------- [6]
+#
+
+sub enumParser ($){
+ my $line = $_[0];
+ chomp($line);
+
+ if ($DEBUG) { print "DEBUG:: state = $state : line = \"$line\"\n"; }
+
+ if ($state == 0) {
+ # find enum as first word
+ if ($line =~ m/\s*enum\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found enum in $line\n"; }
+ $state = 1;
+ # reset last_value
+ $last_value = -1;
+ # reset current_entry
+ $current_entry = "";
+ # reset current_enum_name;
+ $current_enum_name = "";
+ # remove enum from line recheck
+ $line =~ s/\s*enum\s*//;
+ enumParser($line);
+ }
+ } elsif ($state == 1) {
+ # find ENUM_NAME as first word
+ if ($line =~ m/\s*(\w+)\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found ENUM_NAME $1 in $line\n"; }
+ $state = 2;
+ my $enum_name = $1;
+ $current_enum_name = $enum_name;
+ # remove ENUM_NAME from line
+ $line =~ s/\s*$enum_name\s*//;
+ #recheck
+ enumParser($line);
+ }
+ } elsif ($state == 2) {
+ # find { as first word
+ if ($line =~ m/\s*{\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found { in $line\n"; }
+ $state = 3;
+ # remove { from line recheck
+ $line =~ s/\s*{\s*//;
+ enumParser($line);
+ }
+ } elsif ($state == 3) {
+ # find ENTRY as first word
+ if ($line =~ m/\s*(\w+)\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found ENTRY $1 in $line\n"; }
+ my $entry = $1;
+ $current_entry = $entry;
+ # remove ENTRY from line
+ $line =~ s/\s*$entry\s*//;
+ $state = 4;
+ #recheck
+ enumParser($line);
+ }
+ # find } as first word
+ elsif ($line =~ m/\s*}\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found } in $line\n"; }
+ $state = 7;
+ # remove } from line recheck
+ $line =~ s/\s*}\s*//;
+ enumParser($line);
+ }
+ } elsif ($state == 4) {
+ # find = as first word
+ if ($line =~ m/\s*=\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found = in $line\n"; }
+ $state = 5;
+ # remove = from line recheck
+ $line =~ s/\s*=\s*//;
+ enumParser($line);
+ }
+ # find , as first word
+ elsif ($line =~ m/\s*,\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found , in $line\n"; }
+ $state = 3;
+ # assign next last_value to entry
+ $last_value++;
+ my $value = $last_value;
+ if ($DEBUG) { print "DEBUG:: default VALUE $value assigned to $current_entry\n"; }
+ $enums{$current_enum_name}{$current_entry} = $value;
+ # remove , from line recheck
+ $line =~ s/\s*,\s*//;
+ enumParser($line);
+ }
+ # find } as first word
+ elsif ($line =~ m/\s*}\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found } in $line\n"; }
+ $state = 7;
+ # remove } from line recheck
+ $line =~ s/\s*}\s*//;
+ enumParser($line);
+ }
+ } elsif ($state == 5) {
+ # find VALUE as first word
+ if ($line =~ m/\s*(\w+)\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found VALUE $1 in $line\n"; }
+ my $value = $1;
+ $last_value = $value;
+ # assign value to entry
+ if ($DEBUG) { print "DEBUG:: VALUE $value assigned to $current_entry\n"; }
+ $enums{$current_enum_name}{$current_entry} = $value;
+ # remove VALUE from line
+ $line =~ s/\s*$value\s*//;
+ $state = 6;
+ #recheck
+ enumParser($line);
+ }
+ } elsif ($state == 6) {
+ # find , as first word
+ if ($line =~ m/\s*,\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found , in $line\n"; }
+ $state = 3;
+ # remove , from line recheck
+ $line =~ s/\s*,\s*//;
+ enumParser($line);
+ }
+ # find } as first word
+ elsif ($line =~ m/\s*}\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found } in $line\n"; }
+ $state = 7;
+ # remove } from line recheck
+ $line =~ s/\s*}\s*//;
+ enumParser($line);
+ }
+ } elsif ($state == 7) {
+ # find ; as first word
+ if ($line =~ m/\s*;\s*.*/) {
+ if ($DEBUG) { print "DEBUG:: found ; in $line\n"; }
+ $state = 0;
+ # remove ; from line recheck
+ $line =~ s/\s*;\s*//;
+ enumParser($line);
+ }
+ }
+}
+
+sub help {
+ printf("Usage: ppeCreateAttrGetSetMacros.pl [--path <pathToFapiHeaders>] [--verbose] [--help] [--src <pathToFapiTemplate>] [--inc <pathToFapiOutput]\n");
+ printf("-path <pathToFapiHeaders> Option to enable specifying alternate path to fapi headers\n");
+ printf("-v | -verbose Inform user of findings and changes\n");
+ printf("-h | -help print this message\n");
+ exit(0);
+}
diff --git a/src/tools/scripts/ppeCreateIfAttrService.pl b/src/tools/scripts/ppeCreateIfAttrService.pl
new file mode 100755
index 00000000..1202505a
--- /dev/null
+++ b/src/tools/scripts/ppeCreateIfAttrService.pl
@@ -0,0 +1,240 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeCreateIfAttrService.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+# Purpose: This perl script will parse HWP Attribute XML files and
+# initfile attr files and create the fapiGetInitFileAttr() function
+# in a file called fapi2AttributeService.C
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 3)
+{
+ print ("Usage: fapi2CreateIfAttrService.pl <output dir>\n");
+ print (" [<if-attr-file1> <if-attr-file2> ...]\n");
+ print (" -a <attr-xml-file1> [<attr-xml-file2> ...]\n");
+ print (" This perl script will parse if-attr files (containing the\n");
+ print (" attributes used by the initfile) and attribute XML files\n");
+ print (" (containing all HWPF attributes) and create the\n");
+ print (" fapiGetInitFileAttr() function in a file called\n");
+ print (" fapiAttributeService.C. Only the attributes specified in\n");
+ print (" the if-attr files are supported. If no if-attr files are\n");
+ print (" specified then all attributes are supported\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+#use Data::Dumper;
+
+#------------------------------------------------------------------------------
+# Open output file for writing
+#------------------------------------------------------------------------------
+my $asFile = $ARGV[0];
+$asFile .= "/";
+$asFile .= "fapi2AttributeService.C";
+open(ASFILE, ">", $asFile);
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttributeService.C
+#------------------------------------------------------------------------------
+print ASFILE "// fapi2AttributeService.C\n";
+print ASFILE "// This file is generated by perl script fapi2CreateIfAttrService.pl\n\n";
+print ASFILE "#include <fapi2AttributeService.H>\n";
+print ASFILE "//#include <fapi2ChipEcFeature.H>\n";
+print ASFILE "//#include <fapi2PlatTrace.H>\n\n";
+print ASFILE "namespace fapi2\n";
+print ASFILE "{\n\n";
+print ASFILE "ReturnCode fapiGetInitFileAttr(const AttributeId i_id,\n";
+print ASFILE " const Target * i_pTarget,\n";
+print ASFILE " uint64_t & o_val,\n";
+print ASFILE " const uint32_t i_arrayIndex1,\n";
+print ASFILE " const uint32_t i_arrayIndex2,\n";
+print ASFILE " const uint32_t i_arrayIndex3,\n";
+print ASFILE " const uint32_t i_arrayIndex4)\n";
+print ASFILE "{\n";
+print ASFILE " ReturnCode l_rc;\n\n";
+
+my $xmlFiles = 0;
+my $attCount = 0;
+my $numIfAttrFiles = 0;
+my @attrIds;
+
+#------------------------------------------------------------------------------
+# Element names
+#------------------------------------------------------------------------------
+my $attribute = 'attribute';
+
+#------------------------------------------------------------------------------
+# For each argument
+#------------------------------------------------------------------------------
+my $argfile = $ARGV[1];
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+foreach my $entr (@{$entries->{entry}}) {
+
+ my $inname = $entr->{name};
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+
+ foreach my $argnum (2 .. $#ARGV)
+ {
+ my $infile = $ARGV[$argnum];
+
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute']);
+
+ # Uncomment to get debug output of all attributes
+ #print "\nFile: ", $infile, "\n", Dumper($attributes), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+
+
+ if($attr->{id} eq $inname) {
+
+ #------------------------------------------------------------------
+ # Check that the AttributeId exists
+ #------------------------------------------------------------------
+ if (! exists $attr->{id})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'id' missing\n");
+ exit(1);
+ }
+
+
+ #------------------------------------------------------------------
+ # Figure out the number of attribute array dimensions
+ #------------------------------------------------------------------
+ my $numArrayDimensions = 0;
+ if ($attr->{array})
+ {
+ # Remove leading whitespace
+ my $dimText = $attr->{array};
+ $dimText =~ s/^\s+//;
+
+ # Split on commas or whitespace
+ my @vals = split(/\s*,\s*|\s+/, $dimText);
+
+ $numArrayDimensions=@vals;
+ }
+
+ #------------------------------------------------------------------
+ # Print the attribute get code to fapiAttributeService.C
+ #------------------------------------------------------------------
+ if ($attCount > 0)
+ {
+ print ASFILE " else ";
+ }
+ else
+ {
+ print ASFILE " ";
+ }
+ $attCount++;
+
+ print ASFILE "if (i_id == $attr->{id})\n";
+ print ASFILE " {\n";
+ print ASFILE " $attr->{id}_Type l_attr;\n";
+
+ if (exists $attr->{privileged})
+ {
+ print ASFILE " l_rc = FAPI_ATTR_GET_PRIVILEGED($attr->{id}, i_pTarget, l_attr);\n";
+ }
+ else
+ {
+ print ASFILE " l_rc = FAPI_ATTR_GET($attr->{id}, i_pTarget, l_attr);\n";
+ }
+ print ASFILE " o_val = l_attr";
+
+ if ($numArrayDimensions >= 5)
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. More than 4 array dimensions!!\n");
+ exit(1);
+ }
+ else
+ {
+ for (my $i = 0; $i < $numArrayDimensions; $i++)
+ {
+ print ASFILE "[i_arrayIndex";
+ print ASFILE $i+1;
+ print ASFILE "]";
+ }
+ }
+
+ print ASFILE ";\n";
+ print ASFILE " }\n";
+
+
+
+ }
+ }
+ }
+
+}
+
+#------------------------------------------------------------------------------
+# Print End of file information to fapiAttributeService.C
+#--------------------------------------------------------------------------
+if ($attCount > 0)
+{
+ print ASFILE " else\n";
+}
+print ASFILE " {\n";
+print ASFILE " FAPI_ERR(\"fapiGetInitFileAttr: Unrecognized attr ID: 0x%x\", i_id);\n";
+print ASFILE " l_rc.setFapiError(FAPI_RC_INVALID_ATTR_GET);\n";
+print ASFILE " l_rc.addEIFfdc(0, &i_id, sizeof(i_id));\n";
+print ASFILE " }\n\n";
+print ASFILE " if (l_rc)\n";
+print ASFILE " {\n";
+print ASFILE " if (i_pTarget)\n";
+print ASFILE " {\n";
+print ASFILE " FAPI_ERR(\"fapiGetInitFileAttr: Error getting attr ID 0x%x from targType 0x%x\",\n";
+print ASFILE " i_id, i_pTarget->getType());\n";
+print ASFILE " }\n";
+print ASFILE " else\n";
+print ASFILE " {\n";
+print ASFILE " FAPI_ERR(\"fapiGetInitFileAttr: Error getting attr ID 0x%x from system target\",\n";
+print ASFILE " i_id);\n";
+print ASFILE " }\n";
+print ASFILE " }\n\n";
+print ASFILE " return l_rc;\n";
+print ASFILE "}\n\n";
+print ASFILE "}\n";
+
+
+#------------------------------------------------------------------------------
+# Close output file
+#------------------------------------------------------------------------------
+close(ASFILE);
diff --git a/src/tools/scripts/ppeParseAttrGetSetMacros.pl b/src/tools/scripts/ppeParseAttrGetSetMacros.pl
new file mode 100644
index 00000000..013cad96
--- /dev/null
+++ b/src/tools/scripts/ppeParseAttrGetSetMacros.pl
@@ -0,0 +1,286 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeParseAttrGetSetMacros.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2016
+#
+#
+# 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
+# Purpose: This perl script will parse HWP Attribute XML files and
+# initfile attr files and create the fapiGetInitFileAttr() function
+# in a file called fapiAttributeService.C
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 3)
+{
+ print ("Usage: ppeParseAttrGetSetMacros.pl <output dir>\n");
+ print (" [<if-attr-file1> <if-attr-file2> ...]\n");
+ print (" -a <attr-xml-file1> [<attr-xml-file2> ...]\n");
+ print (" This perl script will parse if-attr files (containing the\n");
+ print (" attributes used by the initfile) and attribute XML files\n");
+ print (" (containing all HWPF attributes) and create the\n");
+ print (" fapiGetInitFileAttr() function in a file called\n");
+ print (" fapiAttributeService.C. Only the attributes specified in\n");
+ print (" the if-attr files are supported. If no if-attr files are\n");
+ print (" specified then all attributes are supported\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+#use Data::Dumper;
+
+#------------------------------------------------------------------------------
+# Open output file for writing
+#------------------------------------------------------------------------------
+my $chipFile = $ARGV[0];
+$chipFile .= "/";
+$chipFile .= "proc_sbe_fixed_proc_chip.H";
+open(CHFILE, ">", $chipFile);
+
+my $exFile = $ARGV[0];
+$exFile .= "/";
+$exFile .= "proc_sbe_fixed_ex.H";
+open(EXFILE, ">", $exFile);
+
+my $coreFile = $ARGV[0];
+$coreFile .= "/";
+$coreFile .= "proc_sbe_fixed_core.H";
+open(COFILE, ">", $coreFile);
+
+my $eqFile = $ARGV[0];
+$eqFile .= "/";
+$eqFile .= "proc_sbe_fixed_eq.H";
+open(EQFILE, ">", $eqFile);
+
+my $pervFile = $ARGV[0];
+$pervFile .= "/";
+$pervFile .= "proc_sbe_fixed_perv.H";
+open(PEFILE, ">", $pervFile);
+
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttributeService.C
+#------------------------------------------------------------------------------
+#print ASFILE "// proc_sbe_func.H\n";
+#print ASFILE "// This file is generated by perl script fapi2ParseProcSbeFixed.pl\n\n";
+#print ASFILE "#ifndef __PROC_SBE_FIXED_H__\n";
+#print ASFILE "#define __PROC_SBE_FIXED_H__\n";
+#print ASFILE "#include \"p9_sbe.H\"\n";
+#print ASFILE "#include \"plat_target_parms.H\"\n";
+#print ASFILE "#include \"fapi2AttributeIds.H\"\n\n";
+
+
+my $xmlFiles = 0;
+my $attCount = 0;
+my $numIfAttrFiles = 0;
+my @attrSystemIds;
+my @attrChipIds;
+my @attrExIds;
+my @attrCoreIds;
+my @attrEqIds;
+my @attrPervIds;
+
+
+
+#------------------------------------------------------------------------------
+# Element names
+#------------------------------------------------------------------------------
+my $attribute = 'attribute';
+
+#------------------------------------------------------------------------------
+# For each argument
+#------------------------------------------------------------------------------
+my $argfile = $ARGV[1];
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+foreach my $entr (@{$entries->{entry}}) {
+
+ my $inname = $entr->{name};
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+
+ foreach my $argnum (2 .. $#ARGV)
+ {
+ my $infile = $ARGV[$argnum];
+
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute']);
+
+ # Uncomment to get debug output of all attributes
+ #print "\nFile: ", $infile, "\n", Dumper($attributes), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+ if($attr->{id} eq $inname) {
+
+ #------------------------------------------------------------------
+ # Check that the AttributeId exists
+ #------------------------------------------------------------------
+ if (! exists $attr->{id})
+ {
+ print ("ppeParseGetSetMacros.pl ERROR. Att 'id' missing\n");
+ exit(1);
+ }
+
+ if($attr->{targetType} eq "TARGET_TYPE_SYSTEM") {
+
+ push(@attrSystemIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_PROC_CHIP") {
+
+ push(@attrChipIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_CORE") {
+
+ push(@attrCoreIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_EQ") {
+
+ push(@attrEqIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_EX") {
+
+ push(@attrExIds, $attr);
+
+ } elsif($attr->{targetType} eq "TARGET_TYPE_PERV") {
+
+# push(@attrPervIds, $attr->{id});
+ push(@attrPervIds, $attr);
+
+ } else {
+
+ print ("ppeParseAttrGetSetMacros.pl ERROR. Wrong attribute type: $attr->{targetType}\n");
+ exit(1);
+
+ }
+
+ }
+ }
+ }
+}
+
+print SYFILE "// proc_sbe_fixed_system.H\n";
+print SYFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print SYFILE "#ifndef __PROC_SBE_FIXED_SYSTEM_H__\n";
+print SYFILE "#define __PROC_SBE_FIXED_SYSTEM_H__\n\n";
+foreach my $attr (@attrSystemIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print SYFILE "PROC_SBE_FIXED_$value($attr->{id});\n"
+
+
+}
+print SYFILE "\n#endif // __PROC_SBE_FIXED_SYSTEM_H__";
+
+print CHFILE "// proc_sbe_fixed_proc_chip.H\n";
+print CHFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print CHFILE "#ifndef __PROC_SBE_FIXED_PROC_CHIP_H__\n";
+print CHFILE "#define __PROC_SBE_FIXED_PROC_CHIP_H__\n\n";
+foreach my $attr (@attrChipIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print CHFILE "PROC_SBE_FIXED_$value($attr->{id});\n"
+
+
+}
+print CHFILE "\n#endif // __PROC_SBE_FIXED_PROC_CHIP_H__";
+
+print EXFILE "// proc_sbe_fixed_ex.H\n";
+print EXFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print EXFILE "#ifndef __PROC_SBE_FIXED_EX_H__\n";
+print EXFILE "#define __PROC_SBE_FIXED_EX_H__\n";
+foreach my $attr (@attrExIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print EXFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, EX_TARGET_COUNT);\n"
+
+
+}
+print EXFILE "\n#endif // __PROC_SBE_FIXED_EX_H__";
+
+print COFILE "// proc_sbe_fixed_co.H\n";
+print COFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print COFILE "#ifndef __PROC_SBE_FIXED_CO_H__\n";
+print COFILE "#define __PROC_SBE_FIXED_CO_H__\n";
+foreach my $attr (@attrCoreIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print COFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, CORE_TARGET_COUNT);\n"
+
+
+}
+print COFILE "\n#endif // __PROC_SBE_FIXED_CO_H__";
+
+print EQFILE "// proc_sbe_fixed_eq.H\n";
+print EQFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print EQFILE "#ifndef __PROC_SBE_FIXED_EQ_H__\n";
+print EQFILE "#define __PROC_SBE_FIXED_EQ_H__\n";
+foreach my $attr (@attrEqIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print EQFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, EQ_TARGET_COUNT);\n"
+
+
+}
+print EQFILE "\n#endif // __PROC_SBE_FIXED_EQ_H__";
+
+print PEFILE "// proc_sbe_fixed_perv.H\n";
+print PEFILE "// This file is generated by perl script ppeParseAttrGetSetMacros.pl\n\n";
+print PEFILE "#ifndef __PROC_SBE_FIXED_PERV_H__\n";
+print PEFILE "#define __PROC_SBE_FIXED_PERV_H__\n";
+foreach my $attr (@attrPervIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print PEFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, PERV_TARGET_COUNT);\n"
+
+
+}
+print PEFILE "\n#endif // __PROC_SBE_FIXED_PERV_H__";
+
+#print ASFILE "#endif // __PROC_SBE_FIXED_H__";
+
+#------------------------------------------------------------------------------
+# Close output file
+#------------------------------------------------------------------------------
+close(CHFILE);
+close(COFILE);
+close(EXFILE);
+close(PEFILE);
+close(EQFILE);
+
diff --git a/src/tools/scripts/ppeParseAttributeInfo.pl b/src/tools/scripts/ppeParseAttributeInfo.pl
new file mode 100755
index 00000000..1b881a4d
--- /dev/null
+++ b/src/tools/scripts/ppeParseAttributeInfo.pl
@@ -0,0 +1,746 @@
+#!/usr/bin/perl -w
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeParseAttributeInfo.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+# Purpose: This perl script will parse HWP Attribute XML files
+# and add attribute information to a file called fapi2AttributeIds.H
+
+use strict;
+
+sub help {
+ print ("Usage: ppeParseAttributeInfo.pl <output dir> <attr-xml-file1> [<attr-xml-file2> ...]\n");
+ print (" This perl script will parse attribute XML files and create the following files:\n");
+ print (" - fapi2AttributeIds.H. Contains IDs, type, value enums and other information\n");
+ print (" - fapi2ChipEcFeature.C. Contains a function to query chip EC features\n");
+ print (" - fapi2AttributePlatCheck.H. Contains compile time checks that all attributes are\n");
+ print (" handled by the platform\n");
+ print (" - fapi2AttributesSupported.html Contains the HWPF attributes supported\n");
+ print (" - fapi2AttrInfo.csv Used to process Attribute Override Text files\n");
+ print (" - fapi2AttrEnumInfo.csv Used to process Attribute Override Text files\n");
+}
+
+my $DEBUG = 0;
+my $VERBOSE = 0;
+my $help = 0;
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 2)
+{
+ print ("Invalid number of arguments\n\n");
+ help();
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use Getopt::Long;
+use Digest::MD5 qw(md5_hex);
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+GetOptions ("verbose" => \$VERBOSE,
+ "help" => \$help,
+ "debug" => \$DEBUG,
+ );
+
+if ($help)
+{
+ help();
+ exit(0);
+}
+
+if ($DEBUG)
+{
+ print "DEBUG enabled!!!!\n";
+}
+
+# Uncomment to enable debug output
+# use Data::Dumper;
+
+#------------------------------------------------------------------------------
+# Set PREFERRED_PARSER to XML::Parser. Otherwise it uses XML::SAX which contains
+# bugs that result in XML parse errors that can be fixed by adjusting white-
+# space (i.e. parse errors that do not make sense).
+#------------------------------------------------------------------------------
+$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
+
+#------------------------------------------------------------------------------
+# Open output files for writing
+#------------------------------------------------------------------------------
+my $aiFile = $ARGV[0];
+$aiFile .= "/";
+$aiFile .= "fapi2AttributeIds.H";
+open(AIFILE, ">", $aiFile);
+
+my $echFile = $ARGV[0];
+$echFile .= "/";
+$echFile .= "fapi2ChipEcFeature.H";
+open(ECHFILE, ">", $echFile);
+
+my $acFile = $ARGV[0];
+$acFile .= "/";
+$acFile .= "fapi2AttributePlatCheck.H";
+open(ACFILE, ">", $acFile);
+
+my $asFile = $ARGV[0];
+$asFile .= "/";
+$asFile .= "fapi2AttributesSupported.html";
+open(ASFILE, ">", $asFile);
+
+my $itFile = $ARGV[0];
+$itFile .= "/";
+$itFile .= "fapi2AttrInfo.csv";
+open(ITFILE, ">", $itFile);
+
+my $etFile = $ARGV[0];
+$etFile .= "/";
+$etFile .= "fapi2AttrEnumInfo.csv";
+open(ETFILE, ">", $etFile);
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttributeIds.H
+#------------------------------------------------------------------------------
+print AIFILE "// fapi2AttributeIds.H\n";
+print AIFILE "// This file is generated by perl script fapiParseAttributeInfo.pl\n\n";
+print AIFILE "#ifndef FAPI2ATTRIBUTEIDS_H_\n";
+print AIFILE "#define FAPI2ATTRIBUTEIDS_H_\n\n";
+print AIFILE "#ifndef __ASSEMBLER__\n\n";
+print AIFILE "#include <target.H>\n";
+print AIFILE "#include <target_types.H>\n\n";
+print AIFILE "namespace fapi2\n";
+print AIFILE "{\n\n";
+print AIFILE "\/**\n";
+print AIFILE " * \@brief Enumeration of attribute IDs\n";
+print AIFILE " *\/\n";
+print AIFILE "enum AttributeId\n{\n";
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapi2_chip_ec_feature.H
+#------------------------------------------------------------------------------
+print ECHFILE "// This file is generated by perl script parseAttributeInfo.pl\n";
+print ECHFILE "// It implements the fapi2_chip_ec_feature function\n\n";
+print ECHFILE "#ifndef __FAPI2_CHIP_EC_FEATURE_H_\n";
+print ECHFILE "#define __FAPI2_CHIP_EC_FEATURE_H_\n";
+print ECHFILE "#include <fapi2AttributeService.H>\n";
+print ECHFILE "#include <fapi2AttributeIds.H>\n";
+print ECHFILE "namespace fapi2\n";
+print ECHFILE "{\n\n";
+print ECHFILE "// create a unique type from an int ( or attribute id) \n";
+print ECHFILE "template<int I>\n";
+print ECHFILE "struct int2Type {\n";
+print ECHFILE "enum { value = I };\n";
+print ECHFILE "};\n";
+print ECHFILE "ReturnCode queryChipEcAndName(\n";
+print ECHFILE " const Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,\n";
+print ECHFILE " fapi2::ATTR_NAME_Type& , fapi2::ATTR_EC_Type & );\n\n";
+print ECHFILE "template<int T>\n";
+print ECHFILE "ReturnCode queryChipEcFeature(int2Type<T> id,\n";
+print ECHFILE " const Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,\n";
+print ECHFILE " uint8_t & o_hasFeature)\n";
+print ECHFILE "{\n";
+print ECHFILE " fapi2::ATTR_NAME_Type l_chipName;\n";
+print ECHFILE " fapi2::ATTR_EC_Type l_chipEc;\n\n";
+print ECHFILE " o_hasFeature = 0;\n\n";
+print ECHFILE " ReturnCode l_rc = queryChipEcAndName(i_target, l_chipName, l_chipEc);\n";
+print ECHFILE " if (l_rc)\n";
+print ECHFILE " {\n";
+print ECHFILE " FAPI_ERR(\"queryChipEcFeature: error getting chip name\");\n";
+print ECHFILE " }\n";
+print ECHFILE " else\n";
+print ECHFILE " {\n";
+print ECHFILE " o_hasFeature = hasFeature(int2Type<T>(), l_chipName, l_chipEc);\n";
+print ECHFILE " }\n";
+print ECHFILE " return l_rc;\n";
+print ECHFILE "}\n\n";
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttributePlatCheck.H
+#------------------------------------------------------------------------------
+print ACFILE "// fapiAttributePlatCheck.H\n";
+print ACFILE "// This file is generated by perl script fapiParseAttributeInfo.pl\n";
+print ACFILE "// A platform can include it to ensure that it handles all HWPF\n";
+print ACFILE "// attributes\n\n";
+print ACFILE "#ifndef FAPIATTRIBUTEPLATCHECK_H_\n";
+print ACFILE "#define FAPIATTRIBUTEPLATCHECK_H_\n\n";
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttributesSupported.html
+#------------------------------------------------------------------------------
+print ASFILE "<html>\n";
+print ASFILE "<body>\n\n";
+print ASFILE "<!-- fapiAttributesSupported.html -->\n";
+print ASFILE "<!-- This file is generated by perl script fapiParseAttributeInfo.pl -->\n";
+print ASFILE "<!-- It lists all HWPF attributes supported -->\n\n";
+print ASFILE "<h4>HWPF Attributes supported by this build.</h4>\n";
+print ASFILE "<table border=\"4\">\n";
+print ASFILE "<tr><th>Attribute ID</th><th>Attribute Description</th></tr>";
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttrInfo.csv
+#------------------------------------------------------------------------------
+print ITFILE "# fapiAttrInfo.csv\n";
+print ITFILE "# This file is generated by perl script fapiParseAttributeInfo.pl\n";
+print ITFILE "# It lists information about FAPI attributes and is used to\n";
+print ITFILE "# process FAPI Attribute text files (overrides/syncs)\n";
+print ITFILE "# Format:\n";
+print ITFILE "# <FAPI-ATTR-ID-STR>,<LAYER-ATTR-ID-STR>,<ATTR-ID-VAL>,<ATTR-TYPE>\n";
+print ITFILE "# Note that for the AttributeTanks at the FAPI layer, the\n";
+print ITFILE "# FAPI-ATTR-ID-STR and LAYER-ATTR-ID-STR will be identical\n";
+
+#------------------------------------------------------------------------------
+# Print Start of file information to fapiAttrEnumInfo.csv
+#------------------------------------------------------------------------------
+print ETFILE "# fapiAttrEnumInfo.csv\n";
+print ETFILE "# This file is generated by perl script fapiParseAttributeInfo.pl\n";
+print ETFILE "# It lists information about FAPI attribute enumeratorss and is\n";
+print ETFILE "# used to process FAPI Attribute text files (overrides/syncs)\n";
+print ETFILE "# Format:\n";
+print ETFILE "# <ENUM-STR>,<ENUM-VAL>\n";
+
+my %attrIdHash; # Records which Attribute IDs have been used
+my %attrValHash; # Records which Attribute values have been used
+
+#------------------------------------------------------------------------------
+# For each XML file
+#------------------------------------------------------------------------------
+#my $argfile = "p9_ppe_attributes.xml";
+my $argfile = $ARGV[1];
+if ($DEBUG) { print "DEBUG:: XML filter file - $argfile\n" }
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+foreach my $entr (@{$entries->{entry}}) {
+
+ my $inname = $entr->{name};
+ if ($DEBUG) { print "DEBUG:: entr->file = $entr->{file}; \n" }
+
+ foreach my $argnum (2 .. $#ARGV)
+ {
+ my $infile = $ARGV[$argnum];
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute', 'chip']);
+
+ if ($DEBUG) { print "DEBUG:: File: ", $infile, "\n", Dumper($attributes), "\n"; }
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+ #print "? $attr->{id}, $inname\n";
+
+ if($attr->{id} eq $inname) {
+
+ #print "yes $attr->{id}, $inname\n";
+
+ #----------------------------------------------------------------------
+ # Print the Attribute ID and calculated value to fapiAttributeIds.H and
+ # fapiAttributeIds.txt. The value for an attribute is a hash value
+ # generated from the attribute name, this ties a specific value to a
+ # specific attribute name. This is done for Cronus so that if a HWP is
+ # not recompiled against a new eCMD/Cronus version where the attributes
+ # have changed then there will not be a mismatch in enumerator values.
+ # This is a 28bit hash value because the Initfile compiler has a
+ # requirement that the top nibble of the 32 bit attribute ID be zero to
+ # store flags
+ #----------------------------------------------------------------------
+ if (! exists $attr->{id})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Attribute 'id' missing in $infile\n");
+ exit(1);
+ }
+
+ if (exists($attrIdHash{$attr->{id}}))
+ {
+ # Two different attributes with the same id!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate Attribute id $attr->{id} in $infile\\n");
+ exit(1);
+ }
+
+ # Calculate a 28 bit hash value.
+ my $attrHash128Bit = md5_hex($attr->{id});
+ my $attrHash28Bit = substr($attrHash128Bit, 0, 7);
+
+ # Print the attribute ID/value to fapiAttributeIds.H
+ print AIFILE " $attr->{id} = 0x$attrHash28Bit,\n";
+
+ if (exists($attrValHash{$attrHash28Bit}))
+ {
+ # Two different attributes generate the same hash-value!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate attr id hash value for $attr->{id} in $infile\ \n");
+ exit(1);
+ }
+
+ $attrIdHash{$attr->{id}} = $attrHash28Bit;
+ $attrValHash{$attrHash28Bit} = 1;
+ }
+ };
+ }
+}
+
+#------------------------------------------------------------------------------
+# Print AttributeId enumeration end to fapiAttributeIds.H
+#------------------------------------------------------------------------------
+print AIFILE "};\n\n";
+
+#------------------------------------------------------------------------------
+# Print Attribute Information comment to fapiAttributeIds.H
+#------------------------------------------------------------------------------
+print AIFILE "\/**\n";
+print AIFILE " * \@brief Attribute Information\n";
+print AIFILE " *\/\n";
+
+
+foreach my $entr (@{$entries->{entry}}) {
+
+# print " $entr->{file}, $entr->{name}\n";
+
+# my $infile = $entr->{file};
+ my $inname = $entr->{name};
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+
+ foreach my $argnum (2 .. $#ARGV)
+ {
+ my $infile = $ARGV[$argnum];
+
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute', 'chip']);
+
+ # Uncomment to get debug output of all attributes
+ if ($DEBUG) { print "DEBUG:: File: ", $infile, "\n", Dumper($attributes), "\n"; }
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+ if($attr->{id} eq $inname) {
+
+ #----------------------------------------------------------------------
+ # Print a comment with the attribute ID fapiAttributeIds.H
+ #----------------------------------------------------------------------
+ print AIFILE "/* $attr->{id} */\n";
+
+ #----------------------------------------------------------------------
+ # Print the AttributeId and description to fapiAttributesSupported.html
+ #----------------------------------------------------------------------
+ if (! exists $attr->{description})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Attribute 'description' missing for $attr->{id} in $infile\n");
+ exit(1);
+ }
+
+
+ #----------------------------------------------------------------------
+ # Figure out the attribute array dimensions (if array)
+ #----------------------------------------------------------------------
+ my $arrayDimensions = "";
+ my $numArrayDimensions = 0;
+ if ($attr->{array})
+ {
+ # Remove leading whitespace
+ my $dimText = $attr->{array};
+ $dimText =~ s/^\s+//;
+
+ # Split on commas or whitespace
+ my @vals = split(/\s*,\s*|\s+/, $dimText);
+
+ foreach my $val (@vals)
+ {
+ $arrayDimensions .= "[${val}]";
+ $numArrayDimensions++;
+ }
+ }
+
+ #----------------------------------------------------------------------
+ # Print the typedef for each attribute's val type to fapiAttributeIds.H
+ # Print the attribute information to fapiAttrInfo.csv
+ #----------------------------------------------------------------------
+ if (exists $attr->{chipEcFeature})
+ {
+ # The value type of chip EC feature attributes is uint8_t
+ print AIFILE "typedef uint8_t $attr->{id}_Type;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u8\n"
+ }
+ else
+ {
+ if (! exists $attr->{valueType})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'valueType' missing for $attr->{id} in $infile\n");
+ exit(1);
+ }
+
+ if ($attr->{valueType} eq 'uint8')
+ {
+ print AIFILE "typedef uint8_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u8" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'uint16')
+ {
+ print AIFILE "typedef uint16_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u8" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'uint32')
+ {
+ print AIFILE "typedef uint32_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u32" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'uint64')
+ {
+ print AIFILE "typedef uint64_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},u64" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'int8')
+ {
+ print AIFILE "typedef int8_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},8" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'int16')
+ {
+ print AIFILE "typedef int16_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},32" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'int32')
+ {
+ print AIFILE "typedef int32_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},32" .
+ "$arrayDimensions\n";
+ }
+ elsif ($attr->{valueType} eq 'int64')
+ {
+ print AIFILE "typedef int64_t $attr->{id}_Type$arrayDimensions;\n";
+ print ITFILE "$attr->{id},$attr->{id},0x$attrIdHash{$attr->{id}},64" .
+ "$arrayDimensions\n";
+ }
+ else
+ {
+ print ("fapi2ParseAttributeInfo.pl ERROR. valueType not recognized: ");
+ print $attr->{valueType}, " for $attr->{id} in $infile\n";
+ exit(1);
+ }
+ }
+
+ #----------------------------------------------------------------------
+ # Print if the attribute is privileged
+ #----------------------------------------------------------------------
+ if (exists $attr->{privileged})
+ {
+ print AIFILE "const bool $attr->{id}_Privileged = true;\n";
+ }
+ else
+ {
+ print AIFILE "const bool $attr->{id}_Privileged = false;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the target type(s) that the attribute is associated with
+ #----------------------------------------------------------------------
+ if (! exists $attr->{targetType})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'targetType' missing for $attr->{id} in $infile\n");
+ exit(1);
+ }
+
+ print AIFILE "const TargetType $attr->{id}_TargetTypes = ";
+
+ # Split on commas
+ my @targTypes = split(',', $attr->{targetType});
+ my $targType = $targTypes[0];
+
+ foreach my $targType (@targTypes)
+ {
+ # Remove newlines and leading/trailing whitespace
+ $targType =~ s/\n//;
+ $targType =~ s/^\s+//;
+ $targType =~ s/\s+$//;
+
+ # Consider only supported target types. The rest are ignored
+ if($targType ~~ ["TARGET_TYPE_PROC_CHIP", "TARGET_TYPE_SYSTEM",
+ "TARGET_TYPE_CORE", "TARGET_TYPE_MCS", "TARGET_TYPE_PERV",
+ "TARGET_TYPE_EQ", "TARGET_TYPE_EX"])
+ {
+ print AIFILE "$targType";
+ last;
+ }
+ else
+ {
+ next;
+ }
+ }
+ print AIFILE ";\n";
+
+ #----------------------------------------------------------------------
+ # Print if the attribute is a platInit attribute
+ #----------------------------------------------------------------------
+ if (exists $attr->{platInit})
+ {
+ print AIFILE "const bool $attr->{id}_PlatInit = true;\n";
+ }
+ else
+ {
+ print AIFILE "const bool $attr->{id}_PlatInit = false;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print if the attribute is a initToZero attribute
+ #----------------------------------------------------------------------
+ if (exists $attr->{initToZero})
+ {
+ print AIFILE "const bool $attr->{id}_InitToZero = true;\n";
+ }
+ else
+ {
+ print AIFILE "const bool $attr->{id}_InitToZero = false;\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the value enumeration (if specified) to fapiAttributeIds.H and
+ # fapiAttributeEnums.txt
+ #----------------------------------------------------------------------
+ if (exists $attr->{enum})
+ {
+ print AIFILE "enum $attr->{id}_Enum\n{\n";
+
+ # Values must be separated by commas to allow for values to be
+ # specified: <enum>VAL_A = 3, VAL_B = 5, VAL_C = 0x23</enum>
+ my @vals = split(',', $attr->{enum});
+
+ foreach my $val (@vals)
+ {
+ # Remove newlines and leading/trailing whitespace
+ $val =~ s/\n//;
+ $val =~ s/^\s+//;
+ $val =~ s/\s+$//;
+
+ # Print the attribute enum to fapiAttributeIds.H
+ print AIFILE " ENUM_$attr->{id}_${val}";
+
+ # Print the attribute enum to fapiAttrEnumInfo.csv
+ my $attrEnumTxt = "$attr->{id}_${val}\n";
+ $attrEnumTxt =~ s/ = /,/;
+ print ETFILE $attrEnumTxt;
+
+ if ($attr->{valueType} eq 'uint64')
+ {
+ print AIFILE "ULL";
+ }
+
+ print AIFILE ",\n";
+ }
+
+ print AIFILE "};\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print _GETMACRO and _SETMACRO where appropriate to fapiAttributeIds.H
+ #----------------------------------------------------------------------
+ if (exists $attr->{chipEcFeature})
+ {
+ #------------------------------------------------------------------
+ # The attribute is a Chip EC Feature, define _GETMACRO to call a
+ # fapi function and define _SETMACRO to something that will cause a
+ # compile failure if a set is attempted
+ #------------------------------------------------------------------
+ print AIFILE "#define $attr->{id}_GETMACRO(ID, PTARGET, VAL) \\\n";
+ print AIFILE " PLAT_GET_CHIP_EC_FEATURE_OVERRIDE(ID, PTARGET, VAL) ? fapi2::FAPI2_RC_SUCCESS : \\\n";
+ print AIFILE " fapi2::queryChipEcFeature(fapi2::int2Type<ID>(), PTARGET, VAL)\n";
+ print AIFILE "#define $attr->{id}_SETMACRO(ID, PTARGET, VAL) ";
+ print AIFILE "CHIP_EC_FEATURE_ATTRIBUTE_NOT_WRITABLE\n";
+ }
+ elsif (! exists $attr->{writeable})
+ {
+ #------------------------------------------------------------------
+ # The attribute is read-only, define the _SETMACRO to something
+ # that will cause a compile failure if a set is attempted
+ #------------------------------------------------------------------
+ if (! exists $attr->{writeable})
+ {
+ print AIFILE "#define $attr->{id}_SETMACRO ATTRIBUTE_NOT_WRITABLE\n";
+ }
+ }
+
+ #----------------------------------------------------------------------
+ # If the attribute is a Chip EC Feature, print the chip EC feature
+ # query to fapi2_chip_ec_feature.H
+ #----------------------------------------------------------------------
+ # Each EC attribute will generate a new inline overloaded version of
+ # hasFeature with the attribute specific logic
+ if (exists $attr->{chipEcFeature})
+ {
+ my $chipCount = 0;
+ print ECHFILE " inline uint8_t hasFeature(int2Type<$attr->{id}>,\n";
+ print ECHFILE " fapi2::ATTR_NAME_Type i_name,\n";
+ print ECHFILE " fapi2::ATTR_EC_Type i_ec)\n";
+ print ECHFILE " {\n";
+ print ECHFILE " uint8_t hasFeature = 0;\n\n";
+ print ECHFILE " if(";
+
+ foreach my $chip (@{$attr->{chipEcFeature}->{chip}})
+ {
+ if (! exists $chip->{name})
+ {
+ print ("parseAttributeInfo.pl ERROR. Att 'name' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec})
+ {
+ print ("parseAttributeInfo.pl ERROR. Att 'ec' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec}->{value})
+ {
+ print ("parseAttributeInfo.pl ERROR. Att 'value' missing\n");
+ exit(1);
+ }
+
+ if (! exists $chip->{ec}->{test})
+ {
+ print ("parseAttributeInfo.pl ERROR. Att 'test' missing\n");
+ exit(1);
+ }
+
+ if($chip->{name} eq 'ENUM_ATTR_NAME_CENTAUR')
+ {
+ # Skip Centaur chip
+ next;
+ }
+
+ $chipCount++;
+ my $test;
+ if ($chip->{ec}->{test} eq 'EQUAL')
+ {
+ $test = '==';
+ }
+ elsif ($chip->{ec}->{test} eq 'GREATER_THAN')
+ {
+ $test = '>';
+ }
+ elsif ($chip->{ec}->{test} eq 'GREATER_THAN_OR_EQUAL')
+ {
+ $test = '>=';
+ }
+ elsif ($chip->{ec}->{test} eq 'LESS_THAN')
+ {
+ $test = '<';
+ }
+ elsif ($chip->{ec}->{test} eq 'LESS_THAN_OR_EQUAL')
+ {
+ $test = '<=';
+ }
+ else
+ {
+ print ("parseAttributeInfo.pl ERROR. test '$chip->{ec}->{test}' unrecognized\n");
+ exit(1);
+ }
+
+ if ($chipCount > 1)
+ {
+ print ECHFILE " ||\n\t";
+ }
+ print ECHFILE "((i_name == $chip->{name}) && ";
+ print ECHFILE " (i_ec $test $chip->{ec}->{value}))";
+ }
+ print ECHFILE ")\n";
+ print ECHFILE " {\n";
+ print ECHFILE " hasFeature = 1;\n";
+ print ECHFILE " }\n";
+ print ECHFILE " return hasFeature;\n";
+ print ECHFILE " };\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the platform attribute checks to fapiAttributePlatCheck.H
+ #----------------------------------------------------------------------
+ if (exists $attr->{writeable})
+ {
+ print ACFILE "#ifndef $attr->{id}_SETMACRO\n";
+ print ACFILE "#error Platform does not support set of HWPF attr $attr->{id}\n";
+ print ACFILE "#endif\n";
+ }
+
+ print ACFILE "#ifndef $attr->{id}_GETMACRO\n";
+ print ACFILE "#error Platform does not support get of HWPF attr $attr->{id}\n";
+ print ACFILE "#endif\n\n";
+
+ #----------------------------------------------------------------------
+ # Print newline between each attribute's info to fapiAttributeIds.H
+ #----------------------------------------------------------------------
+ print AIFILE "\n";
+
+
+
+
+
+ }
+ };
+ }
+}
+
+#------------------------------------------------------------------------------
+# Print End of file information to fapiAttributeIds.H
+#------------------------------------------------------------------------------
+print AIFILE "} //fapi2 \n\n";
+print AIFILE "#endif // __ASSEMBLER__\n\n";
+print AIFILE "#endif\n";
+
+print ECHFILE "}\n";
+print ECHFILE "#endif\n";
+
+
+#------------------------------------------------------------------------------
+# Print End of file information to fapiAttributePlatCheck.H
+#------------------------------------------------------------------------------
+print ACFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Print End of file information to fapiAttributesSupported.html
+#------------------------------------------------------------------------------
+print ASFILE "</table>\n\n";
+print ASFILE "</body>\n";
+print ASFILE "</html>\n";
+
+
+#------------------------------------------------------------------------------
+# Close output files
+#------------------------------------------------------------------------------
+close(AIFILE);
+close(ECHFILE);
+close(ACFILE);
+close(ASFILE);
+close(ITFILE);
+close(ETFILE);
diff --git a/src/tools/scripts/ppeParseProcSbeFixed.pl b/src/tools/scripts/ppeParseProcSbeFixed.pl
new file mode 100755
index 00000000..4279ca3b
--- /dev/null
+++ b/src/tools/scripts/ppeParseProcSbeFixed.pl
@@ -0,0 +1,318 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeParseProcSbeFixed.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+# Purpose: This perl script will parse HWP Attribute XML files and
+# initfile attr files and create the fapiGetInitFileAttr() function
+# in a file called fapiAttributeService.C
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 3)
+{
+ print ("Usage: ppeParseProcSbeFixed.pl <output dir>\n");
+ print (" [<if-attr-file1> <if-attr-file2> ...]\n");
+ print (" -a <attr-xml-file1> [<attr-xml-file2> ...]\n");
+ print (" This perl script will parse if-attr files (containing the\n");
+ print (" attributes used by the initfile) and attribute XML files\n");
+ print (" (containing all HWPF attributes) and create the\n");
+ print (" fapiGetInitFileAttr() function in a file called\n");
+ print (" fapiAttributeService.C. Only the attributes specified in\n");
+ print (" the if-attr files are supported. If no if-attr files are\n");
+ print (" specified then all attributes are supported\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+#use Data::Dumper;
+
+#------------------------------------------------------------------------------
+# Open output file for writing
+#------------------------------------------------------------------------------
+my $sysFile = $ARGV[0];
+$sysFile .= "/";
+$sysFile .= "proc_sbe_fixed_system.H";
+open(SYFILE, ">", $sysFile);
+
+my $chipFile = $ARGV[0];
+$chipFile .= "/";
+$chipFile .= "proc_sbe_fixed_proc_chip.H";
+open(CHFILE, ">", $chipFile);
+
+my $exFile = $ARGV[0];
+$exFile .= "/";
+$exFile .= "proc_sbe_fixed_ex.H";
+open(EXFILE, ">", $exFile);
+
+my $coreFile = $ARGV[0];
+$coreFile .= "/";
+$coreFile .= "proc_sbe_fixed_core.H";
+open(COFILE, ">", $coreFile);
+
+my $eqFile = $ARGV[0];
+$eqFile .= "/";
+$eqFile .= "proc_sbe_fixed_eq.H";
+open(EQFILE, ">", $eqFile);
+
+my $pervFile = $ARGV[0];
+$pervFile .= "/";
+$pervFile .= "proc_sbe_fixed_perv.H";
+open(PEFILE, ">", $pervFile);
+
+
+
+my $xmlFiles = 0;
+my $attCount = 0;
+my $numIfAttrFiles = 0;
+my @attrSystemIds;
+my @attrChipIds;
+my @attrExIds;
+my @attrCoreIds;
+my @attrEqIds;
+my @attrPervIds;
+
+
+
+#------------------------------------------------------------------------------
+# Element names
+#------------------------------------------------------------------------------
+my $attribute = 'attribute';
+
+#------------------------------------------------------------------------------
+# For each argument
+#------------------------------------------------------------------------------
+my $argfile = $ARGV[1];
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+foreach my $entr (@{$entries->{entry}}) {
+
+ my $inname = $entr->{name};
+
+ # Skip virtual attributes
+ if(exists $entr->{virtual})
+ {
+ next;
+ }
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+
+ foreach my $argnum (2 .. $#ARGV)
+ {
+ my $infile = $ARGV[$argnum];
+
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute']);
+
+ # Uncomment to get debug output of all attributes
+ #print "\nFile: ", $infile, "\n", Dumper($attributes), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+
+ if($attr->{id} eq $inname) {
+
+ #------------------------------------------------------------------
+ # Check that the AttributeId exists
+ #------------------------------------------------------------------
+ if (! exists $attr->{id})
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Att 'id' missing\n");
+ exit(1);
+ }
+
+ my @targets = split(",", $attr->{targetType});
+ my $targetTypeMatched = 0;
+
+ foreach my $target (@targets)
+ {
+
+ if ($target eq "TARGET_TYPE_SYSTEM") {
+
+ push(@attrSystemIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif ($target eq "TARGET_TYPE_PROC_CHIP") {
+
+ push(@attrChipIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif ($target eq "TARGET_TYPE_CORE") {
+
+ push(@attrCoreIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif ($target eq "TARGET_TYPE_EQ") {
+
+ push(@attrEqIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif ($target eq "TARGET_TYPE_EX") {
+
+ push(@attrExIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif ($target eq "TARGET_TYPE_PERV") {
+
+ push(@attrPervIds, $attr);
+ $targetTypeMatched = 1;
+ last;
+
+ } else {
+
+ print ("ppeParseProcSbeFixed.pl WARNING. Unsupported ".
+ "target type: $target for attribute $inname in $infile\n");
+ next;
+
+ }
+ }
+ if($targetTypeMatched eq 0)
+ {
+ print ("ppeParseProcSbeFixed.pl ERROR. Unsupported ".
+ "target type: $attr->{targetType} for attribute $inname in $infile\n");
+ exit(1);
+ }
+ }
+ }
+ }
+}
+
+
+print SYFILE "// proc_sbe_fixed_system.H\n";
+print SYFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print SYFILE "#ifndef __PROC_SBE_FIXED_SYSTEM_H__\n";
+print SYFILE "#define __PROC_SBE_FIXED_SYSTEM_H__\n\n";
+foreach my $attr (@attrSystemIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print SYFILE "PROC_SBE_FIXED_$value($attr->{id});\n"
+
+
+}
+print SYFILE "\n#endif // __PROC_SBE_FIXED_SYSTEM_H__";
+
+print CHFILE "// proc_sbe_fixed_proc_chip.H\n";
+print CHFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print CHFILE "#ifndef __PROC_SBE_FIXED_PROC_CHIP_H__\n";
+print CHFILE "#define __PROC_SBE_FIXED_PROC_CHIP_H__\n\n";
+foreach my $attr (@attrChipIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print CHFILE "PROC_SBE_FIXED_$value($attr->{id});\n"
+
+
+}
+print CHFILE "\n#endif // __PROC_SBE_FIXED_PROC_CHIP_H__";
+
+print EXFILE "// proc_sbe_fixed_ex.H\n";
+print EXFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print EXFILE "#ifndef __PROC_SBE_FIXED_EX_H__\n";
+print EXFILE "#define __PROC_SBE_FIXED_EX_H__\n";
+foreach my $attr (@attrExIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print EXFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, EX_TARGET_COUNT);\n"
+
+
+}
+print EXFILE "\n#endif // __PROC_SBE_FIXED_EX_H__";
+
+
+print COFILE "// proc_sbe_fixed_co.H\n";
+print COFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print COFILE "#ifndef __PROC_SBE_FIXED_CO_H__\n";
+print COFILE "#define __PROC_SBE_FIXED_CO_H__\n";
+foreach my $attr (@attrCoreIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print COFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, CORE_TARGET_COUNT);\n"
+
+
+}
+print COFILE "\n#endif // __PROC_SBE_FIXED_CO_H__";
+
+
+
+print EQFILE "// proc_sbe_fixed_eq.H\n";
+print EQFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print EQFILE "#ifndef __PROC_SBE_FIXED_EQ_H__\n";
+print EQFILE "#define __PROC_SBE_FIXED_EQ_H__\n";
+foreach my $attr (@attrEqIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print EQFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, EQ_TARGET_COUNT);\n"
+
+
+}
+print EQFILE "\n#endif // __PROC_SBE_FIXED_EQ_H__";
+
+
+
+print PEFILE "// proc_sbe_fixed_perv.H\n";
+print PEFILE "// This file is generated by perl script ppeParseProcSbeFixed.pl\n\n";
+print PEFILE "#ifndef __PROC_SBE_FIXED_PERV_H__\n";
+print PEFILE "#define __PROC_SBE_FIXED_PERV_H__\n";
+foreach my $attr (@attrPervIds)
+{
+
+ my $value = uc $attr->{valueType};
+ print PEFILE "PROC_SBE_FIXED_TARGET_$value($attr->{id}, PERV_TARGET_COUNT);\n"
+
+
+}
+print PEFILE "\n#endif // __PROC_SBE_FIXED_PERV_H__";
+
+
+#print ASFILE "#endif // __PROC_SBE_FIXED_H__";
+
+
+#------------------------------------------------------------------------------
+# Close output file
+#------------------------------------------------------------------------------
+close(CHFILE);
+close(COFILE);
+close(EXFILE);
+close(PEFILE);
+close(EQFILE);
+
diff --git a/src/tools/scripts/ppeSetFixed.pl b/src/tools/scripts/ppeSetFixed.pl
new file mode 100755
index 00000000..ab92ec42
--- /dev/null
+++ b/src/tools/scripts/ppeSetFixed.pl
@@ -0,0 +1,259 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/tools/scripts/ppeSetFixed.pl $
+#
+# OpenPOWER sbe Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2016
+#
+#
+# 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
+# Purpose: This perl script will parse the attribute and default list and
+# and set the default values into the image.
+
+use strict;
+
+my $attrpath = "../../importtemp/xml";
+my $sbedefaultpath = "../../script/image";
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $numArgs = $#ARGV + 1;
+if ($numArgs < 3)
+{
+ print ("Usage: ppeSetFixed.pl <image> <attributes and default list> <attribute file> ...\n");
+ print (" This perl script will the attributes and default list to lookup the defaults\n");
+ print (" and parse the attribute file to lookup the types.\n");
+ print (" The default values will be set in the image.\n");
+ print ("example:\n");
+ print ("./ppeSetFixed.pl \\\n" );
+ print (". \\\n" );
+ print (" ../../obj/seeprom_main.bin \\\n" );
+ print ("$attrpath/p9_ppe_attributes.xml \\\n" );
+ print ("$attrpath/attribute_info/perv_attributes.xml \\\n" );
+ print ("$attrpath/attribute_info/proc_attributes.xml \\\n" );
+ print ("$attrpath/attribute_info/ex_attributes.xml \\\n" );
+ print ("$attrpath/attribute_info/eq_attributes.xml \\\n" );
+ print ("$attrpath/attribute_info/core_attributes.xml \\ \n");
+ print ("$attrpath/attribute_info/nest_attributes.xml \n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+
+my $xmlFiles = 0;
+my $attCount = 0;
+my $numIfAttrFiles = 0;
+my @attrSystemIds;
+my @attrChipIds;
+my @attrExIds;
+my @attrCoreIds;
+my @attrEqIds;
+my @attrPervIds;
+
+
+
+#------------------------------------------------------------------------------
+# Element names
+#------------------------------------------------------------------------------
+my $attribute = 'attribute';
+
+#------------------------------------------------------------------------------
+# For each argument
+#------------------------------------------------------------------------------
+my $sbedefaultpath = $ARGV[0];
+my $image = $ARGV[1];
+my $argfile = $ARGV[2];
+my $entries = $xml->XMLin($argfile, ForceArray => ['entry']);
+
+if ( ! -e $image) {die "ppeSetFixed.pl: $image $!"};
+
+foreach my $entr (@{$entries->{entry}}) {
+
+ # Skip virtual attributes
+ if(exists $entr->{virtual})
+ {
+ next;
+ }
+
+ my $inname = $entr->{name};
+
+ # read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one such element in the file
+
+ foreach my $argnum (3 .. $#ARGV)
+ {
+ my $infile = $ARGV[$argnum];
+
+ if ( ! -e $infile) {die "ppeSetFixed.pl: $infile $!"};
+
+ my $attributes = $xml->XMLin($infile, ForceArray => ['attribute']);
+
+ #--------------------------------------------------------------------------
+ # For each Attribute
+ #--------------------------------------------------------------------------
+ foreach my $attr (@{$attributes->{attribute}})
+ {
+ if($attr->{id} eq $inname) {
+
+ #------------------------------------------------------------------
+ # Check that the AttributeId exists
+ #------------------------------------------------------------------
+ if (! exists $attr->{id})
+ {
+ print ("ppeSbeFixed.pl ERROR. Att 'id' missing\n");
+ exit(1);
+ }
+
+ my @targets = split(",", $attr->{targetType});
+
+ my $targetTypeMatched = 0;
+
+ foreach my $target (@targets)
+ {
+ if($target eq "TARGET_TYPE_SYSTEM") {
+
+ push(@attrSystemIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif($target eq "TARGET_TYPE_PROC_CHIP") {
+
+ push(@attrChipIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif($target eq "TARGET_TYPE_CORE") {
+
+ push(@attrCoreIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif($target eq "TARGET_TYPE_EQ") {
+
+ push(@attrEqIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif($target eq "TARGET_TYPE_EX") {
+
+ push(@attrExIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } elsif($target eq "TARGET_TYPE_PERV") {
+
+ push(@attrPervIds, $entr);
+ $targetTypeMatched = 1;
+ last;
+
+ } else {
+
+ print ("ppeSetFixed.pl WARNING. Ignoring unsupported".
+ " target type: $target for attribute: $inname\n");
+ next;
+
+ }
+ }
+ if($targetTypeMatched eq 0)
+ {
+ print ("ppeSetFixed.pl ERROR. No matching target type ".
+ "found for attribute: $inname\n");
+ exit(1);
+ }
+
+ }
+ }
+ }
+}
+
+
+setFixed("TARGET_TYPE_SYSTEM", @attrSystemIds);
+setFixed("TARGET_TYPE_PROC_CHIP", @attrChipIds);
+setFixed("TARGET_TYPE_CORE", @attrCoreIds);
+setFixed("TARGET_TYPE_EQ", @attrEqIds);
+setFixed("TARGET_TYPE_EX", @attrExIds);
+setFixed("TARGET_TYPE_PERV", @attrPervIds);
+
+
+
+sub setFixed {
+
+ my ($string, @entries) = @_;
+
+ foreach my $attr (@entries)
+ {
+
+ my $inname = $attr->{name};
+
+ my @values = $attr->{value};
+
+
+ if(scalar @values > 0) {
+ foreach my $val (@values)
+ {
+
+ if(defined $val && ref($val) eq "") {
+
+ if ($val =~ /(0x)?[0-9a-fA-F]+/) {
+
+ my $systemRc = system("$sbedefaultpath/sbe_default_tool $image $inname $val $string 0");
+
+ if ($systemRc) {
+ print "sbe_default_tool: error in execution\n";
+ exit 1;
+ }
+
+ } else {
+ print ("ppeSetFixed.pl ERROR. not hex\n");
+ exit(1);
+ }
+
+ } elsif(defined $val && ref($val) eq "ARRAY") {
+
+ my $index = 0;
+
+ foreach my $arr (@{$val}) {
+
+ if(defined $arr && ref($arr) eq "") {
+ if ($arr =~ /(0x)?[0-9a-fA-F]+/) {
+
+ my $systemRc = system("$sbedefaultpath/sbe_default_tool $image $inname $arr $string $index");
+
+ if ($systemRc) {
+ print "sbe_default_tool: error in execution\n";
+ exit 1;
+ }
+
+
+ }
+ }
+ $index++;
+ }
+ }
+ }
+ }
+ }
+}
+
+
diff --git a/src/tools/scripts/src/fapi2PlatAttributeService.H b/src/tools/scripts/src/fapi2PlatAttributeService.H
new file mode 100644
index 00000000..7c992d65
--- /dev/null
+++ b/src/tools/scripts/src/fapi2PlatAttributeService.H
@@ -0,0 +1,1416 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/tools/scripts/src/fapi2PlatAttributeService.H $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 */
+/**
+ * @file fapiPlatAttributeService.H
+ *
+ * @brief Defines the PLAT attribute access macros and defines which macro
+ * handles each attribute.
+ *
+ */
+
+
+#ifndef FAPI2PLATATTRIBUTESERVICE_H_
+#define FAPI2PLATATTRIBUTESERVICE_H_
+
+#include <stdint.h>
+#include <stddef.h>
+#include <type_traits>
+#include <fapi2AttributeIds.H>
+#include <fapi2ChipEcFeature.H>
+#include <plat_includes.H>
+#include "proc_sbe_fixed.H"
+#include "plat_target_parms.H"
+
+#define PLAT_GET_CHIP_EC_FEATURE_OVERRIDE(ID, PTARGET, VAL) \
+ _getEcFeatureOverride<ID##_Type>(ID, PTARGET, VAL)
+
+/* INSERT NEW ATTRIBUTES HERE */
+
+
+/******************************************************************************/
+/* * Global macros * */
+/* These macros are called by the macros above to invoke the appropriate API. */
+/* These macros do not need to change when a new attribute is introduced. */
+/******************************************************************************/
+
+/* global get uint8_t 1D array macro */
+#define PLAT_ATTR_GET_UINT8_1D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayShort<ID##_Type, static_cast<fapi2::TargetType>(ID##_TargetTypes), ID> \
+ (ID, PTARGET, VAL)
+
+/* global set uint8_t 1D array macro */
+#define PLAT_ATTR_SET_UINT8_1D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayShort<ID##_Type, static_cast<fapi2::TargetType>(ID##_TargetTypes), ID> \
+ (ID, PTARGET, VAL)
+
+/* global get uint8_t 2D array macro */
+#define PLAT_ATTR_GET_UINT8_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayShort(ID, PTARGET, VAL[0])
+/* global set uint8_t 2D array macro */
+#define PLAT_ATTR_SET_UINT8_2D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayShort(ID, PTARGET, VAL[0])
+
+/* global get uint8_t 3D array macro */
+#define PLAT_ATTR_GET_UINT8_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayShort(ID, PTARGET, VAL[0][0])
+/* global set uint8_t 3D array macro */
+#define PLAT_ATTR_SET_UINT8_3D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayShort(ID, PTARGET, VAL[0][0])
+
+/* global get uint8_t 4D array macro */
+#define PLAT_ATTR_GET_UINT8_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayShort(ID, PTARGET, VAL[0][0][0])
+/* global set uint8_t 4D array macro */
+#define PLAT_ATTR_SET_UINT8_4D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayShort(ID, PTARGET, VAL[0][0][0])
+
+/* global get uint32_t 1D array macro */
+#define PLAT_ATTR_GET_UINT32_1D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayWord(ID, PTARGET, VAL)
+/* global set uint32_t 1D array macro */
+#define PLAT_ATTR_SET_UINT32_1D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayWord(ID, PTARGET, VAL)
+
+/* global get uint32_t 2D array macro */
+#define PLAT_ATTR_GET_UINT32_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayWord(ID, PTARGET, VAL[0])
+/* global set uint32_t 2D array macro */
+#define PLAT_ATTR_SET_UINT32_2D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayWord(ID, PTARGET, VAL[0])
+
+/* global get uint32_t 3D array macro */
+#define PLAT_ATTR_GET_UINT32_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayWord(ID, PTARGET, VAL[0][0])
+/* global set uint32_t 3D array macro */
+#define PLAT_ATTR_SET_UINT32_3D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayWord(ID, PTARGET, VAL[0][0])
+
+/* global get uint32_t 4D array macro */
+#define PLAT_ATTR_GET_UINT32_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayWord(ID, PTARGET, VAL[0][0][0])
+/* global set uint32_t 4D array macro */
+#define PLAT_ATTR_SET_UINT32_4D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayWord(ID, PTARGET, VAL[0][0][0])
+
+
+/* global get uint64_t 1D array macro */
+#define PLAT_ATTR_GET_UINT64_1D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayDoubleWord(ID, PTARGET, VAL)
+/* global set uint64_t 1D array macro */
+#define PLAT_ATTR_SET_UINT64_1D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayDoubleWord(ID, PTARGET, VAL)
+
+/* global get uint64_t 2D array macro */
+#define PLAT_ATTR_GET_UINT64_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayDoubleWord(ID, PTARGET, VAL[0])
+/* global set uint64_t 2D array macro */
+#define PLAT_ATTR_SET_UINT64_2D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayDoubleWord(ID, PTARGET, VAL[0])
+
+/* global get uint64_t 3D array macro */
+#define PLAT_ATTR_GET_UINT64_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayDoubleWord(ID, PTARGET, VAL[0][0])
+/* global set uint64_t 3D array macro */
+#define PLAT_ATTR_SET_UINT64_3D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayDoubleWord(ID, PTARGET, VAL[0][0])
+
+/* global get uint64_t 4D array macro */
+#define PLAT_ATTR_GET_UINT64_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeArrayDoubleWord(ID, PTARGET, VAL[0][0][0])
+/* global set uint64_t 4D array macro */
+#define PLAT_ATTR_SET_UINT64_4D_ARRAY(ID, PTARGET, VAL) \
+ _setAttributeArrayDoubleWord(ID, PTARGET, VAL[0][0][0])
+
+/* global get int macro (uint8_t, 16, 32 and 64) */
+#define PLAT_ATTR_GET_GLOBAL_INT(ID, PTARGET, VAL) \
+ _get<ID##_Type, static_cast<fapi2::TargetType>(ID##_TargetTypes), ID> \
+ (ID, PTARGET, VAL)
+
+/* global set int macro (uint8_t, 16, 32 and 64) */
+#define PLAT_ATTR_SET_GLOBAL_INT(ID, PTARGET, VAL) \
+ _set<ID##_Type, static_cast<fapi2::TargetType>(ID##_TargetTypes), ID> \
+ (ID, PTARGET, VAL)
+
+
+//here
+
+/******************************************************************************/
+// Get Override Macros
+/******************************************************************************/
+/* global get override uint8_t 1D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_1D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayShort(ID, PTARGET, VAL)
+/* global get override uint8_t 2D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayShort(ID, PTARGET, VAL[0])
+/* global get override uint8_t 3D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayShort(ID, PTARGET, VAL[0][0])
+/* global get override uint8_t 4D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT8_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayShort(ID, PTARGET, VAL[0][0][0])
+
+
+/* global get override uint32_t 1D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_1D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayWord(ID, PTARGET, VAL)
+/* global get override uint32_t 2D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayWord(ID, PTARGET, VAL[0])
+/* global get override uint32_t 3D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayWord(ID, PTARGET, VAL[0][0])
+/* global get override uint32_t 4D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT32_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayWord(ID, PTARGET, VAL[0][0][0])
+
+
+/* global get override uint64_t 1D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_1D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayDoubleWord(ID, PTARGET, VAL)
+/* global get override uint64_t 2D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_2D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayDoubleWord(ID, PTARGET, VAL[0])
+/* global get override uint64_t 3D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_3D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayDoubleWord(ID, PTARGET, VAL[0][0])
+/* global get override uint64_t 4D array macro */
+#define PLAT_ATTR_GET_OVERRIDE_UINT64_4D_ARRAY(ID, PTARGET, VAL) \
+ _getAttributeOverrideArrayDoubleWord(ID, PTARGET, VAL[0][0][0])
+
+/* global get override int macro (uint8_t, 32 and 64) */
+#define PLAT_ATTR_GET_OVERRIDE_GLOBAL_INT(ID, PTARGET, VAL) \
+ _getOverride<ID##_Type>(ID, PTARGET, VAL)
+
+/******************************************************************************/
+// Get string
+/******************************************************************************/
+
+extern "C"
+{
+ extern fapi2attr::SystemAttributes_t G_system_attributes asm("G_system_attributes") __attribute__ ((section (".fixed")));
+ extern fapi2attr::ProcChipAttributes_t G_proc_chip_attributes asm("G_proc_chip_attributes") __attribute__ ((section (".fixed")));
+ extern fapi2attr::PervAttributes_t G_perv_attributes asm("G_perv_attributes") __attribute__ ((section (".fixed")));
+ extern fapi2attr::CoreAttributes_t G_core_attributes asm("G_core_attributes") __attribute__ ((section (".fixed")));
+ extern fapi2attr::EQAttributes_t G_eq_attributes asm("G_eq_attributes") __attribute__ ((section (".fixed")));
+ extern fapi2attr::EXAttributes_t G_ex_attributes asm("G_ex_attributes") __attribute__ ((section (".fixed")));
+
+ extern fapi2attr::SystemAttributes_t* G_system_attributes_ptr;
+ extern fapi2attr::ProcChipAttributes_t* G_proc_chip_attributes_ptr;
+ extern fapi2attr::PervAttributes_t* G_perv_attributes_ptr;
+ extern fapi2attr::CoreAttributes_t* G_core_attributes_ptr;
+ extern fapi2attr::EQAttributes_t* G_eq_attributes_ptr;
+ extern fapi2attr::EXAttributes_t* G_ex_attributes_ptr;
+
+}
+
+namespace fapi2
+{
+
+
+// Parameters are done as pointers (vs references) to allow the attribute
+// storage to be relocated
+template<TargetType K, typename TAttrStruct, typename TValue, AttributeId AId>
+void __set( const Target<K>& i_ptarget, TAttrStruct* object, const AttributeId attrid, const TValue& value );
+
+template<TargetType K, typename TAttrStruct, typename TValue, AttributeId AId>
+void __get( const Target<K>& i_ptarget, const TAttrStruct* object, const AttributeId attrid, TValue* value );
+
+
+/* INSERT NEW GETTER AND SETTER FUNCTIONS HERE */
+
+
+
+//******************************************************************************
+// Get base template
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ T& o_value)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get uint8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint8_t& o_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get uint16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint16_t& o_value)
+{
+ static_assert(std::is_same<T, uint16_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get uint32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint32_t& o_value)
+{
+ static_assert(std::is_same<T, uint32_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get uint64_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint64_t& o_value)
+{
+ static_assert(std::is_same<T, uint64_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override uint8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint8_t& o_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override uint16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint16_t& o_value)
+{
+ static_assert(std::is_same<T, uint16_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override uint32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint32_t& o_value)
+{
+ static_assert(std::is_same<T, uint32_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override uint64_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint64_t& o_value)
+{
+ static_assert(std::is_same<T, uint64_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get override EC Feature (uint8_t)
+//******************************************************************************
+template<typename T, TargetType K>
+ReturnCode _getEcFeatureOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint8_t& o_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch");
+
+ // The way this is implemented, we want to return a non-zero return code if we found an override.
+ // Return 0 if there was an error.
+ // This is how it's implemented:
+ // PLAT_GET_CHIP_EC_FEATURE_OVERRIDE(ID, PTARGET, VAL) ? fapi::FAPI_RC_SUCCESS : fapi::fapiQueryChipEcFeature(fapi::ID, PTARGET, VAL)
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get uint8_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeArrayShort(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint8_t * o_pValues)
+{
+// fapi2::Attributeta o_data;
+// fapi2::ReturnCode l_fapi_rc(FAPI2_RC_SUCCESS);
+// uint32_t l_ecmd_rc = ECMD_SUCCESS;
+//
+// ecmdChipTarget l_ecmd_target;
+// fapiTargetPointerToEcmdTarget(i_pTarget, l_ecmd_target);
+//
+// o_data.faValidMask = FAPI_ATTRIBUTE_TYPE_UINT8ARY;
+// o_data.faUint8ary = o_pValues;
+//
+// l_ecmd_rc = fapi2GetAttribute(l_ecmd_target, i_id, o_data);
+// if (l_ecmd_rc)
+// {
+// l_fapi_rc = (ReturnCodes) l_ecmd_rc;
+// }
+// return l_fapi_rc;
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set uint8_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _setAttributeArrayShort(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint8_t * i_pValues)
+{
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, *i_pValues );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, *i_pValues );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get uint16_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeArrayWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint16_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set uint16_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _setAttributeArrayWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint16_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get uint32_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeArrayWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint32_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set uint32_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _setAttributeArrayWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint32_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get uint64_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeArrayDoubleWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint64_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set uint64_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _setAttributeArrayDoubleWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint64_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override uint8_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeOverrideArrayShort(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint8_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override uint16_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeOverrideArrayWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint16_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override uint32_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeOverrideArrayWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint32_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override uint64_t array
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getAttributeOverrideArrayDoubleWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ uint64_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set base template
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const T& i_value)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+
+//******************************************************************************
+// Set uint8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const uint8_t& i_value)
+{
+ static_assert(std::is_same<T, uint8_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set uint16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const uint16_t& i_value)
+{
+ static_assert(std::is_same<T, uint16_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set uint32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const uint32_t& i_value)
+{
+ static_assert(std::is_same<T, uint32_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id,i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set uint64_t
+//******************************************************************************
+
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const uint64_t & i_value)
+{
+ static_assert(std::is_same<T, uint64_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int8_t& o_value)
+{
+ static_assert(std::is_same<T, int8_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get int16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int16_t& o_value)
+{
+ static_assert(std::is_same<T, int16_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int32_t& o_value)
+{
+ static_assert(std::is_same<T, int32_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __get<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int64_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _get(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int64_t& o_value)
+{
+ static_assert(std::is_same<T, int64_t>::value, "Attribute type mismatch");
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __get<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __get<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __get<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __get<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, &o_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __get<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, &o_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override int8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int8_t& o_value)
+{
+ static_assert(std::is_same<T, int8_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override int16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int16_t& o_value)
+{
+ static_assert(std::is_same<T, int16_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override int32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int32_t& o_value)
+{
+ static_assert(std::is_same<T, int32_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override int64_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _getOverride(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int64_t& o_value)
+{
+ static_assert(std::is_same<T, int64_t>::value, "Attribute type mismatch");
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int8_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeArraySignedShort(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int8_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int8_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _setAttributeArraySignedShort(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int8_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get int16_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeArraySignedWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int16_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int16_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _setAttributeArraySignedWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int16_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get int32_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeArraySignedWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int32_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int32_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _setAttributeArraySignedWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int32_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get int64_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeArraySignedDoubleWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int64_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set int64_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _setAttributeArraySignedDoubleWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int64_t * i_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override int8_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeOverrideArraySignedShort(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int8_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override int16_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeOverrideArraySignedWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int16_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Get Override int32_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeOverrideArraySignedWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int32_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Get Override int64_t array
+//******************************************************************************
+template<TargetType K>
+ReturnCode _getAttributeOverrideArraySignedDoubleWord(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ int64_t * o_pValues)
+{
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int8_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const int8_t& i_value)
+{
+ static_assert(std::is_same<T, int8_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set int16_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const int16_t& i_value)
+{
+ static_assert(std::is_same<T, int16_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+//******************************************************************************
+// Set int32_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const int32_t& i_value)
+{
+ static_assert(std::is_same<T, int32_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+//******************************************************************************
+// Set int64_t
+//******************************************************************************
+template<typename T, TargetType K, AttributeId A>
+ReturnCode _set(const AttributeId i_id,
+ const Target<K> & i_pTarget,
+ const int64_t & i_value)
+{
+ static_assert(std::is_same<T, int64_t>::value, "Attribute type mismatch"); // May need to remove
+
+ if(K & TARGET_TYPE_SYSTEM)
+ {
+ __set<K, fapi2attr::SystemAttributes_t, T, A>( i_pTarget, G_system_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PROC_CHIP)
+ {
+ __set<K, fapi2attr::ProcChipAttributes_t, T, A>( i_pTarget, G_proc_chip_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_PERV)
+ {
+ __set<K, fapi2attr::PervAttributes_t, T, A>( i_pTarget, G_perv_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_CORE)
+ {
+ __set<K, fapi2attr::CoreAttributes_t, T, A>( i_pTarget, G_core_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EQ)
+ {
+ __set<K, fapi2attr::EQAttributes_t, T, A>( i_pTarget, G_eq_attributes_ptr, i_id, i_value );
+ }
+
+ if(K & TARGET_TYPE_EX)
+ {
+ __set<K, fapi2attr::EXAttributes_t, T, A>( i_pTarget, G_ex_attributes_ptr, i_id, i_value );
+ }
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+} // namespace fapi2
+#endif // FAPIPLATATTRIBUTESERVICE_H_
OpenPOWER on IntegriCloud