summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Geissler <andrewg@us.ibm.com>2011-05-09 14:51:09 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-05-16 16:49:41 -0500
commit0ec3f482259bdcc1867fb884eb89a4c0c5fc026d (patch)
tree23ae2abc22750e836c0c7179958437837f4d8fef
parent038fb97fb799935574a62821fa3eab7ef8ccc14c (diff)
downloadtalos-hostboot-0ec3f482259bdcc1867fb884eb89a4c0c5fc026d.tar.gz
talos-hostboot-0ec3f482259bdcc1867fb884eb89a4c0c5fc026d.zip
Initial trace support for host boot
Change-Id: Ib2450ae3d32549673ca8e1c814a7a11b5f1a0c09 Reviewed-on: http://gfwr801.rchland.ibm.com:8080/gerrit/69 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--config.mk2
-rwxr-xr-xsrc/build/trace/tracehash_hb.pl881
-rw-r--r--src/include/trace_adal.h249
-rw-r--r--src/include/tracinterface.H315
-rw-r--r--src/include/usr/trace/interface.H350
-rw-r--r--src/usr/example/example.C36
-rw-r--r--src/usr/trace/trace.C697
-rw-r--r--src/usr/trace/trace.H132
-rw-r--r--src/usr/trace/tracebuffer.C2
9 files changed, 2061 insertions, 603 deletions
diff --git a/config.mk b/config.mk
index e24b30e3a..721dd71c6 100644
--- a/config.mk
+++ b/config.mk
@@ -98,7 +98,7 @@ ${OBJDIR}/%.dep : %.S
rm -f $@.$$$$
ifdef MODULE
-${IMGDIR}/%.so : ${OBJECTS} ${ROOTPATH}/src/module.ld ${MODULE_INIT} ${SUBDIRS}
+${IMGDIR}/%.so : ${OBJECTS} ${ROOTPATH}/src/module.ld ${MODULE_INIT}
${LD} -shared -z now ${LDFLAGS} \
$(filter-out ${ROOTPATH}/src/module.ld,$^) \
-T ${ROOTPATH}/src/module.ld -o $@
diff --git a/src/build/trace/tracehash_hb.pl b/src/build/trace/tracehash_hb.pl
new file mode 100755
index 000000000..7b5548463
--- /dev/null
+++ b/src/build/trace/tracehash_hb.pl
@@ -0,0 +1,881 @@
+#!/usr/bin/perl -w
+# File tracehash.pl created by B J Zander.
+# 05/08/2011 - Update by andrewg to work in host boot environment
+
+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 = "trexStringFile";
+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 trexStringFile 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 trexStringFile= $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 trexStringFile 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 trexStringFile\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
+
+ # 64 bit support
+ $line =~ s/\%d/\%lld/;
+ $line =~ s/\%u/\%llu/;
+ $line =~ s/\%x/\%llx/;
+ $line =~ s/\%X/\%llX/;
+ #print "line: $line\n";
+
+ 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 trexStringFile 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 trexStringFile
+ 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 = ./trexStringFile
+ -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 = ./trexStringFile
+ -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/include/trace_adal.h b/src/include/trace_adal.h
deleted file mode 100644
index fb8e1501e..000000000
--- a/src/include/trace_adal.h
+++ /dev/null
@@ -1,249 +0,0 @@
-/******************************************************************************
- * IBM Confidential
- *
- * Licensed Internal Code Source Materials
- *
- * IBM Flexible Support Processor Licensed Internal Code
- *
- * (c) Copyright IBM Corp. 2004, 2009
- *
- * The source code is 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.
- *****************************************************************************
- * \file trace_adal.h
- * \brief Contains header data for trace component..
- *
- * The trace component allows an application to trace its execution into
- * circular buffers (like a flight recorder) with low performance and
- * memory usage impact. This implementation focuses on the Linux operating
- * system running on embedded controllers.
- *
- * \note Please see the document trace_doc.lyx for full documentation on this
- * \note component.
- *****************************************************************************/
-
-
-#ifndef _TRACE_ADAL_H
-#define _TRACE_ADAL_H
-
-#include <stdint.h>
-
-/**
- * @brief Maximum size of component name
- * @note Make sure to also change in include/linux/trac.h -
- * TRACER_FSP_TRACE_NAME_SIZE
-*/
-#define TRACE_MAX_COMP_NAME_SIZE 16
-
-#define TRACE_DEBUG_ON 1 //Set to this when debug trace on
-#define TRACE_DEBUG_OFF 0 //Set to this when debug trace off
-#define TRACE_DEBUG 1 //Pass this when trace is debug
-#define TRACE_FIELD 0 //Pass this when trace is field
-
-#define TRACE_COMP_TRACE 0x434F //Identifies trace as a component trace (printf)
-#define TRACE_BINARY_TRACE 0x4249 //Identifies trace as a binary trace
-#define TRACE_INTERNAL_BLOCKED 0xFF42 //Identifies trace as an dd internal trace
-
-#define TRACE_BUFFER_VERSION 1 //Trace buffer version
-#define TRACE_BUFFER_BINARY_VERSION 2 //Trace buffer version when collected by fsp-trace from pipe
-
-#define TRACE_DEFAULT_TD 0 //Default trace descriptor
-
-
-/*
- * Parsing and output modifier flags
- */
-
-/* When multiple buffers are given the traces of all buffers are sorted by timestamp and printed as one list.
- * If this flag is not given the traces are printed separatly for each trace buffers (i.e. grouped by buffer).
- */
-#define TRACE_MIX_BUFFERS 1
-
-/* Show the name of a trace buffer for each trace. The buffer name will be inserted between timestamp and trace text.
- * Only one of TRACE_APPEND_BUFFERNAME and TRACE_PREPEND_BUFFERNAME can be given.
- */
-#define TRACE_PREPEND_BUFFERNAME 2
-
-/* Show the name of a trace buffer for each trace. The buffer name will be appended at the end of the line
- * (after trace text). Only one of TRACE_APPEND_BUFFERNAME and TRACE_PREPEND_BUFFERNAME can be given.
- */
-#define TRACE_APPEND_BUFFERNAME 4
-
-/* When set timestamps are translated to timeofday values (date/time). This needs "timeref" to be given.
- * If timeref is not given the timestamps are treated as if the PPC timebase counter was started at epoch time
- * (i.e. the printed timestamp will be the time since FSP boot time).
- */
-#define TRACE_TIMEOFDAY 8
-
-/* If a TIMEREF trace is found in a trace buffer and timeref is a valid
- * pointer the values from the TIMEREF trace are written to timeref. This flag is independent of TRACE_TIMEOFDAY.
- */
-#define TRACE_SET_TIMEOFDAY 16
-
-/* Show the name of the source file that contains the trace statement for each trace.
- * (at the end of the line, after buffer name if this is printed too).
- */
-#define TRACE_FILENAME 32
-#define TRACE_VERBOSE 64 //some messages are printed to STDERR.
-#define TRACE_IGNORE_VERSION 128
-#define TRACE_OVERWRITE 256
-#define TRACE_BINARY 512
-
-/* When this is set trace pipe isn't turned off after pipe read
- */
-#define TRACE_DONTSTOP 1024
-
-
-/* MSB of tid field is used as trace-in-irq flag
- */
-#define TRACE_TID_IRQ (1<<31)
-#define TRACE_TID_TID(tid) ((tid) & ~(TRACE_TID_IRQ))
-
-/*!
- * @brief Device driver fills in this structure for each trace entry.
- * It will put this data first in the trace buffer.
- */
-typedef struct trace_entry_stamp {
- uint32_t tbh; /*!< timestamp upper part */
- uint32_t tbl; /*!< timestamp lower part */
- uint32_t 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_t length; /*!< size of trace entry */
- uint16_t tag; /*!< type of entry: xTRACE xDUMP, (un)packed */
- uint32_t hash; /*!< a value for the (format) string */
- uint32_t line; /*!< source file line number of trace call */
- uint32_t args[0]; /*!< trace args or data of binary trace */
-} trace_entry_head_t;
-
-
-/*
- * @brief Structure is used to return current components tracing
- */
-typedef struct trace_buf_list {
- char name[TRACE_MAX_COMP_NAME_SIZE]; /*!< component name */
- size_t size; /*!< size of component trace buffer */
-} trace_buf_list_t;
-
-
-typedef uint64_t trace_desc_t; //Type definition for users trace descriptor data type
-typedef uint64_t tracDesc_t; //Type definition for older trace descriptor type
-typedef unsigned long trace_strings_t; /* type for trace strings */
-
-
-/*
- * @brief Will use this to hold hash value.
- *
- */
-enum trace_hash_val { trace_hash };
-
-/* struct for time */
-struct trace_tbtime {
- uint32_t high;
- uint32_t low;
-};
-
-
-/*----------------------------------------------------------------------------*/
-/* Constants */
-/*----------------------------------------------------------------------------*/
-/* only define if not defined by trace_dd.h (make different versions of
- * these files compatible). check only for one define instead of all */
-#ifndef TRACE_FIELDTRACE
-
-/* a component trace of type field (non-debug): x4654 = "FT" */
-#define TRACE_FIELDTRACE 0x4654
-/* a component trace of type debug: x4454 = "DT" */
-#define TRACE_DEBUGTRACE 0x4454
-/* a binary trace of type field (non-debug): x4644 = "FD" */
-#define TRACE_FIELDBIN 0x4644
-/* a binary trace of type debug: x4644 = "DD" */
-#define TRACE_DEBUGBIN 0x4444
-/* a string trace of type field (non-debug): x4653 = "FS" */
-#define TRACE_FIELDSTRING 0x4653
-/* a string trace of type debug: x4453 = "DS" */
-#define TRACE_DEBUGSTRING 0x4453
-
-#endif
-
-/*----------------------------------------------------------------------------*/
-/* Function Prototypes */
-/*----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- * @brief Initialize a trace buffer for a component.
- *
- * @param td Device driver will assign caller a trace descriptor.
- * @param comp Pointer to 16 character null terminated string.
- * @param size Requested buffer size.
- *
- * @return 0 for success, negative value for failure.
- * @retval #TRACE_INIT_BUFF_IOCTL_ERR device driver refused to create buffer
- * @retval #TRACE_INIT_BUFF_NAME_ERR buffer name was too long, a buffer with the
- name "BADN" was created instead
- * @retval #TRACE_INIT_FD_ERR cannot open trace device (module not loaded?), errno set
- */
-int32_t trace_adal_init_buffer(trace_desc_t *,const char *,const size_t);
-
-/*!
- * @brief Set trace debug level
- *
- * @param td Assigned trace descriptor.
- * @param level If 0 only field traces will be active. If > 0 debug traces
- * with level <= 'level' will be active.
- *
- * @return 0 for success, negative value for failure.
- * @retval #TRACE_SETDEBUG_IOCTL_ERR error from device driver, errno set
- * @retval #TRACE_SETDEBUG_INV_PARM_ERR second parm must be TRACE_DEBUG_ON or TRACE_DEBUG_OFF
- * @retval #TRACE_INIT_FD_ERR cannot open trace device (module not loaded?), errno set
- */
-int32_t trace_adal_setdebug(const trace_desc_t, const int32_t);
-
-/*!
- * @brief Write some data to trace buffer.
- *
- * @param td Assigned trace descriptor.
- * @param debug Is it a debug trace or field.
- * @param size Size of data.
- * @param data Data to write to buffer.
- * @param size2 Size of second data block.
- * @param data2 Second data block to write to buffer.
- *
- * @return 0 for success, negative value for failure.
- * @retval #TRACE_WRITE_IOCTL_ERR error from device driver, errno set
- * @retval #TRACE_INIT_FD_ERR cannot open trace device (module not loaded?), errno set
- */
-int32_t trace_adal_write2(const trace_desc_t, const int32_t,
- const size_t,const void *,const size_t,const void *);
-
-/*!
- * @brief Write trace data (can handle all data types)
- *
- * @return 0 for success, negative value for failure.
- * @retval #TRACE_WRITE_ALL_IOCTL_ERR error from device driver, errno set
- * @retval #TRACE_WRITE_NOT_INIT trying to trace without device driver
- * @retval #TRACE_THREAD_LOCK_FAIL error locking thread lock
- * @retval #TRACE_THREAD_UNLOCK_FAIL error unlocking thread lock
- * @retval #TRACE_INIT_FD_ERR cannot open trace device (module not loaded?), errno set
- * @retval #TRACE_WRITE_ALL_BAD_TD bad trace descriptor
- */
-int32_t trace_adal_write_all(const trace_desc_t i_td,const enum trace_hash_val i_hash,
- const char *i_fmt,
- const uint32_t i_line, const int32_t i_type,...)
- __attribute__ ((format (printf, 3, 6)));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/include/tracinterface.H b/src/include/tracinterface.H
deleted file mode 100644
index a6d885314..000000000
--- a/src/include/tracinterface.H
+++ /dev/null
@@ -1,315 +0,0 @@
-/******************************************************************************
- * IBM Confidential
- *
- * Licensed Internal Code Source Materials
- *
- * IBM Flexible Support Processor Licensed Internal Code
- *
- * (c) Copyright IBM Corp. 2004, 2010
- *
- * The source code is 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.
- *****************************************************************************/
-
-#ifndef TRACINTERFACE_H
-#define TRACINTERFACE_H
-
-/*!@file tracinterface.H
- * @brief Contains macros for trace interface
- *
- * This header file provides a common interface for the Trace
- * mechanism. Trace is a way for developers to debug their code. They
- * can use the trace Macro's to write to standar out, to wraparound files and
- * to a wraparound buffer which will be stored in shared memory.
- *
- * There are two types of trace, debug and field, that you can use when tracing.
- * Debug traces will be compiled out of the code when the system is released to the field.
- * Field traces will be remain in the code permenantly.
- *
- * TRACxSYSn calls will always go to syslog
- *
- * There are three different environments trace will operate in.
- *
- * Unit Test / Simulation: All component traces (debug and field) are sent to standard out by default.
- * The developer has the option to do define an evironmental variable:
- * 'export FIPS_TRACE_PATH="<path>"' where path is the location to write the files (ex. "./").
- *
- * Lab: All component traces will, by default, follow the same implementation as the
- * Unit Test / Simulation env. However, drivers flashed onto the system (built by the
- * build team) will use the memory wrapping implementation. Code built in a local
- * sandbox will continue to use the file wrapping implementation. This will give
- * the developer the speed of the memory wrapping trace (for code they don't really
- * care about) and ease of debug with the file wrapping code (for their own code).
- *
- * Field: Only component traces of type field will be sent to the shared memory wraparound
- * buffer. Debug traces will be compiled out of the code.
- *
- * In Unit Test / Simulation, The file will have the name "trac" + 'component name'.
- * For example the error logger component would be <path>/tracERRL
-*/
-/* Change Log *****************************************************************/
-/* */
-/* ch# Feat/def# Userid Date Description */
-/* --- ---------- -------- -------- ----------------------------------------*/
-/* 00 N/A andrewg 08/27/01 Created */
-/* 01 N/A andrewg 10/03/01 Removed duplicate copyright and other housekeeping */
-/* 02 N/A andrewg 10/17/01 Added deallocateBuffer flag to TRAC_FREE_BUFFER */
-/* 03 N/A andrewg 10/19/01 Added 'using namespace std;', vector.h -> vector */
-/* included iostream.h, printf bug. */
-/* 04 354052 andrewg 11/09/01 Took out file writing portion, only go to printf */
-/* ag05 354388 andrewg 11/14/01 Changed binary macro name and added typedef */
-/* ag06 354696 andrewg 11/19/01 Removed ag05 change flags, causing errors */
-/* n/a 355095 andrewg 11/28/01 Put common.h include first */
-/* ag07 354971 andrewg 11/28/01 Added file wrapping code */
-/* ag08 359225 andrewg 02/11/01 Added memory wrapping code, removed USE_PRINTF defined flag */
-/* ag09 360869 andrewg 03/04/02 Added persistant writing macro */
-/* ag10 361649 andrewg 03/08/02 Added the constants */
-/* n/a 363697 andrewg 03/28/02 Modified to use new file object */
-/* n/a 376324 andrewg 07/24/02 Fixed bad define of TRACDCOMP9 */
-/* ag11 382759 andrewg 09/09/02 Support compile flag to remove debug trace */
-/* n/a 385314 andrewg 09/27/02 Remove use of STL */
-/* n/a 388981 andrewg 11/12/02 Add new static variable constructor */
-/* n/a HBIBASE iawilllia 10/05/10 Removed a lot of stuff for HBI trace base. */
-/* End Change Log *************************************************************/
-
-//--------------------------------------------------------------------//
-// Constants //
-//--------------------------------------------------------------------//
-#define ENTER_MRK ">>" // -- ag10
-#define EXIT_MRK "<<" // -- ag10
-#define ERR_MRK "E>" // -- ag10
-#define INFO_MRK "I>" // -- ag10
-#define ARG_MRK "A>" // -- ag10
-
-#ifndef NFP_CLIENT // dc99
-#include <stdint.h>
-#include <trace_adal.h>
-#else
-typedef int tracDesc_t;
-typedef int trace_desc_t;
-#endif
-
-#if( defined(NFP_LIBRARY) || defined(NFP_CLIENT) ) // dc99
-
-#define TRACSCOMP(des,printf_string,args...) do {} while(0)
-#define TRACDCOMP(des,printf_string,args...) do {} while(0)
-#define TRACDBIN(des,descString,address,length) do {} while(0)
-
-#define TRACFCOMP(des,printf_string,args...) \
- printf(printf_string "\n", ##args)
-#define TRACFBIN(des,descString,address,length) \
- printf("%s pointer:%p size:%d\n",descString,address,length)
-
-#define TRAC_INIT_BUFFER(des,comp_name, bufferSize) \
- *(des) = 1
-
-#define TRAC_INIT(des,comp_name, bufferSize)
-
-#define TRAC_FREE_BUFFER(des,deallocateBuff) do {} while(0)
-
-#else
-
-// check compatibility of header file/macros and preprocessor tracepp
-// if tracepp was used
-#define TRAC_MACROVER 1
-#ifdef TRAC_TRACEPP
-#if !defined(TRAC_PPVER)
-#warning fsptrace preprocessor version unknown, might be incompatible with header file
-#elif TRAC_PPVER < TRAC_MACROVER
-#error fsptrace header file version and preprocessor version dont fit
-#endif
-#endif
-
-//------------------------------------------------------------------------------
-// INCLUDES
-//------------------------------------------------------------------------------
-
-#include <trace_adal.h>
-
-/* for any trace_adal_write_all call we need the printf_string in addition to
- * the hash value. if tracepp is used it will add a (shortened) printf string,
- * otherwise the macros has to add it
- */
-
-#ifdef TRAC_TRACEPP
-#define __ALL_HASH(printf_string,num) trace_adal_hash(printf_string,num)
-#else
-#define __ALL_HASH(printf_string,num) trace_adal_hash(printf_string,num),printf_string
-#endif
-
-#ifdef TRAC_DEBUG_OUT /* compile out everyones debug traces */
-
-#define TRACDCOMP(des,printf_string,args...) do {} while(0)
-#define TRACDBIN(des,descString,address,length) do {} while(0)
-
-#else /* direct them to real function calls */
-
-/**
- @fn void TRACDCOMP0(des, printf_string)
- @brief Defines all Debug Component Traces
-
- The user can pass 0 to 9 parameters to the macro. In the field environment,
- these trace calls will be compiled out of the code. Use these for early bringup
- needs. These trace calls are written to a memory buffer.
- @note If you are passing parameters then make sure 'printf_string' has the
- @note necessary parameter formatting i.e. 'p1' = "hello" make sure
- @note 'printf_string' has "%s" somewhere in it to corretcly format p1.
- @return void The user will not be impacted by the failure of this function
- @param des This is assigned by TRAC_INIT_BUFFER
- @param printf_string string describing the trace entry and providing the formatting flags for any parameters passed.
- @param p1,p2... Optional parameters
-*/
-
-/* a macro w/o the param number suffix. number is calculated from printf string */
-#define TRACDCOMP(des,printf_string,args...) \
- trace_adal_write_all((des),__ALL_HASH(printf_string,-1),__LINE__,TRACE_DEBUG, ##args)
-
-/**
- @fn void TRACDBIN(des,descString,address,length)
- @brief Defines debug binary trace
-
- The binary trace should be used to write out a section of memory. The debug
- binary trace will be compiled out in the field environment so only use for early
- bringup debug. When this is being written to a file, it will be displayed in
- hexidecimal.
- @return void The user will not be impacted by the failure of this function
- @param des This is assigned by TRAC_INIT_BUFFER
- @param descString A string that will be put in front of the binary dump, developer assigns anything they want.
- @param address Address of beginning of data to dump.
- @param length lenght of the binary data.
-*/
-#define TRACDBIN(des,descString,address,len) \
- do{ trace_entry_head_t __e; \
- __e.tag = TRACE_DEBUGBIN; \
- __e.line = __LINE__; \
- __e.length = (len); \
- __e.hash = trace_adal_hash(descString, 0); \
- trace_adal_write2((des), TRACE_DEBUG, sizeof(trace_entry_head_t), &__e, \
- (uint32_t) (__e.length), (uint32_t *) (address)); \
- } while(0)
-
-#endif /* TRAC_DEBUG_OUT */
-
-/**
- @fn void TRACFCOMP0(des, printf_string)
- @brief Defines all Field Component Traces
-
- The user can pass 0 to 9 parameters to the macro. These trace calls will
- always be written to the trace memory buffer.
- @note If you are passing parameters then make sure 'printf_string' has the
- @note necessary parameter formatting
- @note i.e. 'p1' = "hello" make sure 'printf_string' has "%s" somewhere in
- @note it to corretcly format p1.
- @return void The user will not be impacted by the failure of this function
- @param des This is assigned by TRAC_INIT_BUFFER
- @param printf_string string describing the trace entry and providing the formatting flags for any parameters passed.
- @param p1,p2... Optional parameters
-*/
-
-/* a macro w/o the param number suffix. number is calculated from printf string */
-#define TRACFCOMP(des,printf_string,args...) \
- trace_adal_write_all((des),__ALL_HASH(printf_string,-1),__LINE__,TRACE_FIELD, ##args)
-
-/**
- @fn void TRACSCOMP0(des, printf_string)
- @brief Defines all Strace Component Traces
-
- The user can pass 0 to 9 parameters to the macro. These traces will be treated
- as debug traces but will never be compiled out of the code so that they can always be
- dynamically turned on/off.
-
- @note If you are passing parameters then make sure 'printf_string' has the
- @note necessary parameter formatting i.e. 'p1' = "hello" make sure
- @note 'printf_string' has '%s' somewhere in it to corretcly format p1.
- @return void The user will not be impacted by the failure of this function
- @param des This is assigned by TRAC_INIT_BUFFER
- @param printf_string string describing the trace entry and providing the formatting flags for any parameters passed.
- @param p1,p2... Optional parameters
-
- tracepp replaces trace_adal_hash() with hash value and reduced format string
-*/
-
-/* a macro w/o the param number suffix. number is calculated from printf string */
-#define TRACSCOMP(des,printf_string,args...) \
- trace_adal_write_all((des),__ALL_HASH(printf_string,-1),__LINE__,TRACE_DEBUG, ##args)
-
-/**
- @fn void TRACFBIN(des,descString,address,length)
- @brief Defines field binary trace
-
- The binary trace should be used to write out a section of memory. The field
- binary trace will always be logged so use for important information.
- When this is being written to a file, it will be displayed in hexidecimal.
- @return void The user will not be impacted by the failure of this function
- @param des This is assigned by TRAC_INIT_BUFFER
- @param descString A string that will be put in front of the binary dump, developer assigns anything they want.
- @param address Address of beginning of data to dump.
- @param length lenght of the binary data.
-*/
-#define TRACFBIN(des,descString,address,len) \
- do{ trace_entry_head_t __e; \
- __e.tag = TRACE_FIELDBIN; \
- __e.line = __LINE__; \
- __e.length = (len); \
- __e.hash = trace_adal_hash(descString, 0); \
- trace_adal_write2((des), TRACE_FIELD, sizeof(trace_entry_head_t), &__e, \
- (uint32_t) (__e.length), (uint32_t *) (address)); \
- } while(0)
-
-
-/**
- @fn void TRAC_INIT_BUFFER(des,comp_name, bufferSize)
- @brief Initializes trace buffer for component
-
- This function must be called before any other trace calls. It
- initializes a file for the calling component and returns a trace
- descriptor which is used by the trace calls to find the correct file to write to.
- @return void The user will not be impacted by the failure of this function. If des is a positive value, success.
- @param des This is assigned by this function.
- @param comp_name This is the four character name of the component requesting the trace buffer.
- @param bufferSize Requested length of the buffer, if 0 is entered the user will get default buffer size.
-*/
-#define TRAC_INIT_BUFFER(des,comp_name, bufferSize) \
- trace_adal_init_buffer((des), (comp_name), (bufferSize))
-
-
-class TracInit
-{
- public:
-
- /*------------------------------------------------------------------------*/
- /* Constructor */
- /*------------------------------------------------------------------------*/
-
- TracInit(tracDesc_t *o_td, const char *i_comp,const size_t i_size)
- {
- // printf("TracInit constructor called for %s, size %u\n",i_comp,i_size);
- TRAC_INIT_BUFFER(o_td,i_comp,i_size);
- }
-
- ~TracInit()
- {
- // printf("in the TracInit destructor\n");
- }
-
-};
-
-/*******************************************************************************
- TRAC_INIT: Class for creating trace descriptor object.
-
- About the macros.
- TRAC_INIT -- Called by users, adds __LINE__ for uniqueness.
- TRAC_INIT_LINE -- Translates __LINE__ into the line number. Using
- macro expansion in this statement would result in
- tracInit static g_trac_"__LINE__"
- TRAC_INIT_UNIQ -- With line number translated, use the '##' operator to
- append number in variable name.
-*******************************************************************************/
-
-#define TRAC_INIT_UNIQ(des, name, sz, ln) TracInit static g_trac_##ln(des, name, sz)
-#define TRAC_INIT_LINE(des, name, sz, ln) TRAC_INIT_UNIQ(des, name, sz, ln)
-#define TRAC_INIT(des, name, sz) TRAC_INIT_LINE(des, name, sz, __LINE__)
-
-#endif //! -- NFP Library
-#endif //! -- !defined TRACINTERFACE_H
diff --git a/src/include/usr/trace/interface.H b/src/include/usr/trace/interface.H
new file mode 100644
index 000000000..6d62efca0
--- /dev/null
+++ b/src/include/usr/trace/interface.H
@@ -0,0 +1,350 @@
+/******************************************************************************
+ * IBM Confidential
+ *
+ * Licensed Internal Code Source Materials
+ *
+ * IBM Flexible Support Processor Licensed Internal Code
+ *
+ * (c) Copyright IBM Corp. 2004, 2010
+ *
+ * The source code is 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.
+ *****************************************************************************/
+
+#ifndef __TRACE_INTERFACE_H
+#define __TRACE_INTERFACE_H
+
+/*!@file interface.H
+ * @brief Contains macros for trace interface
+ *
+ * Note that this file was for the most parted ported in from the fsp-trace
+ * implementation.
+ *
+ * This header file provides a common interface for the Trace
+ * mechanism.
+ *
+ * There are two types of trace, debug and field, that you can use when tracing.
+ * Debug traces are not enabled by default, they must be enabled by the user.
+ * Field traces will always be enabled.
+*/
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+
+/******************************************************************************/
+// Globals/Constants
+/******************************************************************************/
+#define ENTER_MRK ">>"
+#define EXIT_MRK "<<"
+#define ERR_MRK "E>"
+#define INFO_MRK "I>"
+#define ARG_MRK "A>"
+
+#define TRAC_COMP_SIZE 16 // Max component name size
+#define TRAC_MAX_ARGS 9 // Max number of arguments in trace
+
+
+#define TRACE_DEBUG 1 //Indicates trace is debug
+#define TRACE_FIELD 0 //Indicates trace is field
+
+// check compatibility of header file/macros and preprocessor tracepp
+// if tracepp was used
+#define TRAC_MACROVER 1
+#ifdef TRAC_TRACEPP
+#if !defined(TRAC_PPVER)
+#warning fsptrace preprocessor version unknown, might be incompatible with header file
+#elif TRAC_PPVER < TRAC_MACROVER
+#error fsptrace header file version and preprocessor version dont fit
+#endif
+#endif
+
+
+/* for any trace_adal_write_all call we need the printf_string in addition to
+ * the hash value. if tracepp is used it will add a (shortened) printf string,
+ * otherwise the macros has to add it
+ */
+#ifdef TRAC_TRACEPP
+#define __ALL_HASH(printf_string,num) trace_adal_hash(printf_string,num)
+#else
+#define __ALL_HASH(printf_string,num) trace_adal_hash(printf_string,num),printf_string
+#endif
+
+/******************************************************************************/
+// Macros
+/******************************************************************************/
+
+#ifdef TRAC_DEBUG_OUT /* compile out everyones debug traces */
+
+#define TRACDCOMP(des,printf_string,args...) do {} while(0)
+#define TRACDBIN(des,descString,address,length) do {} while(0)
+
+#else /* direct them to real function calls */
+
+/**
+ * @fn void TRACDCOMP0(des, printf_string)
+ * @brief Defines all Debug Component Traces
+ *
+ * The user can pass 0 to 9 parameters to the macro. In the field environment,
+ * these trace calls will be compiled out of the code. Use these for early bringup
+ * needs. These trace calls are written to a memory buffer.
+ *
+ * @param des This is assigned by TRAC_INIT_BUFFER
+ * @param printf_string String describing the trace entry and providing the
+ * formatting flags for any parameters passed.
+ * @param p1,p2... Optional parameters
+ *
+ * @return void
+*/
+
+/* a macro w/o the param number suffix. number is calculated from printf string */
+#define TRACDCOMP(des,printf_string,args...) \
+ TRACE::trace_adal_write_all((des),__ALL_HASH(printf_string,-1),__LINE__,TRACE_DEBUG, ##args)
+
+/**
+ * @fn void TRACDBIN(des,descString,address,length)
+ * @brief Defines debug binary trace
+ *
+ * The binary trace should be used to write out a section of memory.
+ *
+ * @param des This is assigned by TRAC_INIT_BUFFER
+ * @param descString A string that will be put in front of the binary dump,
+ * developer assigns anything they want.
+ * @param address Address of beginning of data to dump.
+ * @param length length of the binary data.
+ *
+ * @return void
+
+*/
+#define TRACDBIN(des,printf_string,address,len) \
+ TRACE::trace_adal_write_bin(des,__ALL_HASH(printf_string,0), \
+ __LINE__, \
+ address, \
+ len, \
+ TRACE_DEBUG)
+#endif /* TRAC_DEBUG_OUT */
+
+/**
+ * @fn void TRACFCOMP0(des, printf_string)
+ * @brief Defines all Field Component Traces
+ *
+ * The user can pass 0 to 9 parameters to the macro. These trace calls will
+ * always be written to the trace memory buffer.
+ *
+ * @param des This is assigned by TRAC_INIT_BUFFER
+ * @param printf_string String describing the trace entry and providing the
+ * formatting flags for any parameters passed.
+ * @param p1,p2... Optional parameters
+ *
+ * @return void
+*/
+
+/* a macro w/o the param number suffix. number is calculated from printf string */
+#define TRACFCOMP(des,printf_string,args...) \
+ TRACE::trace_adal_write_all((des),__ALL_HASH(printf_string,-1),__LINE__,TRACE_FIELD, ##args)
+
+
+/**
+ * @fn void TRACFBIN(des,descString,address,len)
+ * @brief Defines field binary trace
+ *
+ * The binary trace should be used to write out a section of memory.
+ *
+ * @param des This is assigned by TRAC_INIT_BUFFER
+ * @param descString A string that will be put in front of the binary dump,
+ * developer assigns anything they want.
+ * @param address Address of beginning of data to dump.
+ * @param length lenght of the binary data.
+ *
+ * @return void
+*/
+#define TRACFBIN(des,printf_string,address,len) \
+ TRACE::trace_adal_write_bin(des,__ALL_HASH(printf_string,0), \
+ __LINE__, \
+ address, \
+ len, \
+ TRACE_FIELD)
+
+/**
+ * @fn void TRAC_INIT_BUFFER(des,comp_name, bufferSize)
+ * @brief Initializes trace buffer for component
+ *
+ * This function must be called before any other trace calls. It
+ * initializes a buffer for the calling component and returns a trace
+ * descriptor which is used by the trace calls to find the correct
+ * buffer to write to.
+ *
+ * @param des This is assigned by this function.
+ * @param comp_name This is the four character name of the component requesting
+ * the trace buffer.
+ * @param bufferSize Requested length of the buffer, if 0 is entered the user will
+ * get default buffer size.
+ * @return void
+*/
+#define TRAC_INIT_BUFFER(des,comp_name, bufferSize) \
+ TRACE::trace_adal_init_buffer((des), (comp_name), (bufferSize))
+
+/*******************************************************************************
+ TRAC_INIT: Class for creating trace descriptor object.
+
+ About the macros.
+ TRAC_INIT -- Called by users, adds __LINE__ for uniqueness.
+ TRAC_INIT_LINE -- Translates __LINE__ into the line number. Using
+ macro expansion in this statement would result in
+ tracInit static g_trac_"__LINE__"
+ TRAC_INIT_UNIQ -- With line number translated, use the '##' operator to
+ append number in variable name.
+*******************************************************************************/
+
+#define TRAC_INIT_UNIQ(des, name, sz, ln) TRACE::TracInit static g_trac_##ln(des, name, sz)
+#define TRAC_INIT_LINE(des, name, sz, ln) TRAC_INIT_UNIQ(des, name, sz, ln)
+#define TRAC_INIT(des, name, sz) TRAC_INIT_LINE(des, name, sz, __LINE__)
+
+
+/******************************************************************************/
+// Internals - Not to be called or used directly by host boot code
+/******************************************************************************/
+
+
+typedef uint32_t trace_hash_val; // Hash values are 32 bytes
+
+/*
+ * @brief Structure is put at beginning of all trace buffers
+ */
+typedef struct trace_buf_head {
+ unsigned char ver; /*!< version of this struct (1) */
+ unsigned char hdr_len; /*!< size of this struct in bytes */
+ unsigned char time_flg; /*!< meaning of timestamp entry field */
+ unsigned char endian_flg; /*!< flag for big ('B') or little ('L') endian*/
+ char comp[TRAC_COMP_SIZE]; /*!< the buffer name as specified in init call*/
+ uint32_t size; /*!< size of buffer, including this struct */
+ uint32_t times_wrap; /*!< how often the buffer wrapped */
+ uint32_t next_free; /*!< offset of the byte behind the latest entry*/
+ uint32_t te_count; /*!< Updated each time a trace is done */
+ uint32_t extracted; /*!< Not currently used */
+}trace_buf_head_t;
+
+/*!
+ * @brief Timestamp and thread id for each trace entry.
+ */
+typedef struct trace_entry_stamp {
+ //uint32_t tbh; /*!< timestamp upper part */
+ //uint32_t tbl; /*!< timestamp lower part */
+ uint32_t tb[2];
+ //uint64_t tb;
+ uint32_t 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_t length; /*!< size of trace entry */
+ uint16_t tag; /*!< type of entry: xTRACE xDUMP, (un)packed */
+ uint32_t hash; /*!< a value for the (format) string */
+ uint32_t 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;
+ uint64_t args[TRAC_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 New version name of this typedef
+ */
+typedef trace_buf_head_t trace_desc_t;
+
+namespace TRACE
+{
+
+/**
+ * @brief Initialize a trace buffer
+ *
+ * @param o_td[out] Trace descriptor to initialize
+ * @param i_comp[in] Component name for trace buffer
+ * @param i_size[in] Size to allocate for trace buffer
+ *
+ * @return void
+ */
+void trace_adal_init_buffer(trace_desc_t **o_td,
+ const char* i_comp,
+ const size_t i_size );
+
+/**
+ * @brief Write component trace out to input buffer
+ *
+ * @param io_td[inout] Trace descriptor of buffer to write to.
+ * @param i_hash[in] Descriptive string hash value
+ * @param i_fmt [in] Formatting string
+ * @param i_line[in] Line number trace was done at
+ * @param i_type[in] Type of trace (TRACE_DEBUG, TRACE_FIELD)
+ *
+ * @return void
+ */
+void trace_adal_write_all(trace_desc_t *io_td,
+ const trace_hash_val i_hash,
+ const char * i_fmt,
+ const uint32_t i_line,
+ const int32_t i_type, ...);
+
+/**
+ * @brief Write binary data out to trace buffer
+ *
+ * @param io_td[inout] Trace descriptor of buffer to write to.
+ * @param i_hash[in] Descriptive string hash value
+ * @param i_line[in] Line number trace was done at
+ * @param i_ptr[in] Pointer to binary data
+ * @param i_size[in] Size of binary data
+ * @param i_type[in] Type of trace (TRACE_DEBUG, TRACE_FIELD)
+ *
+ * @return void
+ */
+void trace_adal_write_bin(trace_desc_t * io_td,
+ const trace_hash_val i_hash,
+ const uint32_t i_line,
+ const void *i_ptr,
+ const uint32_t i_size,
+ const int32_t type);
+
+
+/******************************************************************************/
+// Allow users to init trace buffer outside of a function
+/******************************************************************************/
+class TracInit
+{
+ public:
+
+ /*------------------------------------------------------------------------*/
+ /* Constructor */
+ /*------------------------------------------------------------------------*/
+
+ TracInit(trace_desc_t **o_td, const char *i_comp,const size_t i_size)
+ {
+ TRAC_INIT_BUFFER(o_td,i_comp,i_size);
+ }
+
+ ~TracInit()
+ {
+ }
+
+};
+
+}; // Namespace
+
+#endif //! -- !defined __TRACE_INTERFACE_H
diff --git a/src/usr/example/example.C b/src/usr/example/example.C
index 6aa188f3c..193bbb9d3 100644
--- a/src/usr/example/example.C
+++ b/src/usr/example/example.C
@@ -1,18 +1,44 @@
+/*
+ * Change Log ******************************************************************
+ * Flag Defect/Feature User Date Description
+ * ------ -------------- ---------- ----------- ----------------------------
+ * $ag000 andrewg 04/01/2011 Updated
+ *
+*/
+
#include <kernel/console.H>
#include <sys/mutex.h>
#include <sys/vfs.h>
#include <sys/task.h>
-#include <tracinterface.H>
+#include <trace/interface.H>
//static mutex_t value = mutex_create();
-
-trace_desc_t g_exampleTrace;
-TRAC_INIT(&g_exampleTrace, "EXAMPLE", 4096);
+trace_desc_t *g_trac_test = NULL;
+TRAC_INIT(&g_trac_test, "EXAMPLE", 4096);
extern "C"
void _start(void*)
{
printk("Executing example module.\n");
- TRACFCOMP(g_exampleTrace, "Executing example module: %d", task_gettid());
+
+ // Component trace tests
+ //for(uint32_t i=0;i<100;i++)
+ //{
+ uint32_t i=0;
+ TRACFCOMP(g_trac_test, "Executing example module: %d", task_gettid());
+ TRACFCOMP(g_trac_test, "Test 2: %d %u %c", i,i+1,'a');
+ TRACFCOMP(g_trac_test, "Test 3: %d %u 0x%X", i+2,i+3,
+ 0x123456789ABCDEF0);
+ //}
+
+ // Pointer trace
+ //TRACFCOMP(g_trac_test, "Pointer Test: %llp",g_trac_test);
+
+ // Binary Trace
+ TRACFBIN(g_trac_test,"Binary dump of trace descriptor",
+ g_trac_test,sizeof(trace_desc_t));
+
+
+
task_end();
}
diff --git a/src/usr/trace/trace.C b/src/usr/trace/trace.C
index 38d9c5957..33a3de888 100644
--- a/src/usr/trace/trace.C
+++ b/src/usr/trace/trace.C
@@ -1,54 +1,685 @@
-#include <trace_adal.h>
-#include <util/singleton.H>
+/* TODO
+ * - Add support in for debug traces
+ * - Time support
+ * - FORMAT_PRINTF support
+ *
+ *
+ */
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <trace/interface.H>
#include <stdarg.h>
#include <arch/ppc.H>
+#include <kernel/console.H>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/task.h>
+#include <sys/mutex.h>
+
+#include "trace.H"
+
+/******************************************************************************/
+// Namespace
+/******************************************************************************/
+namespace TRACE
+{
+
+/******************************************************************************/
+// Globals/Constants
+/******************************************************************************/
+
+#define TRAC_TIME_REAL 0 // upper 32 = seconds, lower 32 = microseconds
+#define TRAC_TIME_50MHZ 1
+#define TRAC_TIME_200MHZ 2
+#define TRAC_TIME_167MHZ 3 // 166666667Hz
+#define COMP_NAME_SIZE 16
+
+// Global value used as a "timer" to provide tracing point32_t of reference
+uint32_t g_trac_time_high = 0;
+uint32_t g_trac_time_low = 0;
+
+// Global Mutex
+mutex_t g_trac_mutex;
+
+// Global buffer
+trace_desc_t *g_trac_global = NULL;
+
-#include "tracebuffer.H"
-int32_t trace_adal_init_buffer(trace_desc_t * td, const char* comp,
- const size_t size )
+/******************************************************************************/
+// trace_adal_init_buffer
+/******************************************************************************/
+void trace_adal_init_buffer(trace_desc_t **o_td, const char* i_comp,
+ const size_t i_size )
{
- // For now, just store the component name.
- *td = (trace_desc_t) comp;
- return 0;
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+ if(*o_td == NULL)
+ {
+ if(g_trac_global == NULL)
+ {
+ // TODO - How do I make this pre-emption/mutli-threading safe?
+ g_trac_mutex = mutex_create();
+
+ printk("Global trace buffer is NULL so create and init it!\n");
+
+ g_trac_global = (trace_desc_t *)(malloc(PAGE_SIZE));
+ char l_g_comp[TRAC_COMP_SIZE] = "GLOBAL";
+ trace_init_values_buffer(g_trac_global,
+ l_g_comp);
+
+ }
+
+ // Just assign it to the global buffer since we only have
+ // one buffer
+ *o_td = g_trac_global;
+ printk("Assigned input trace descriptor to global buffer\n");
+ }
+
+ printk("*td = %lu\n",(unsigned long int)*o_td);
+
+ return;
}
-int32_t trace_adal_write_all(const trace_desc_t td,
- const enum trace_hash_val hash,
- const char * fmt,
- const uint32_t line,
- const int32_t type, ...)
+/******************************************************************************/
+// trace_init_values_buffer
+/******************************************************************************/
+void trace_init_values_buffer(trace_desc_t *o_buf,const char *i_comp)
{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ // Initialize it to all 0's
+ memset(o_buf,0,(size_t)PAGE_SIZE);
+
+ (o_buf)->ver = TRACE_BUF_VERSION;
+ (o_buf)->hdr_len = sizeof(trace_buf_head_t);
+ (o_buf)->time_flg = TRAC_TIME_167MHZ;
+ (o_buf)->endian_flg = 'B'; // Big Endian
+ memcpy((o_buf)->comp,i_comp,(size_t)COMP_NAME_SIZE);
+ (o_buf)->size = PAGE_SIZE;
+ (o_buf)->times_wrap = 0;
+ (o_buf)->next_free = sizeof(trace_buf_head_t);
+
+ return;
+}
+
+/******************************************************************************/
+// trace_adal_write_all
+/******************************************************************************/
+void trace_adal_write_all(trace_desc_t *io_td,
+ const trace_hash_val i_hash,
+ const char * i_fmt,
+ const uint32_t i_line,
+ const int32_t i_type, ...)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ int64_t l_rc = 0;
+ uint32_t l_entry_size = 0;
+ trace_entire_entry_t l_entry;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
// This code is incorrect for determining formatting but will work for now.
- size_t size = 0;
- const char* _fmt = fmt;
+ uint32_t num_args = 0;
+ const char* _fmt = i_fmt;
while ('\0' != *_fmt)
{
if ('%' == *_fmt)
- size++;
+ num_args++;
_fmt++;
}
- traceEntry* entry =
- Singleton<TraceBuffer>::instance().claimEntry(sizeof(traceEntry) +
- sizeof(uint64_t) * size);
+ if(num_args > TRAC_MAX_ARGS)
+ {
+ printk ("Too many arguments: %u",num_args);
+ }
+ else if(io_td != NULL)
+ {
+
+ // Calculate total space needed
+ l_entry_size = sizeof(trace_entry_stamp_t);
+ l_entry_size += sizeof(trace_entry_head_t);
+
+ // We always add the size of the entry at the end of the trace entry
+ // so the parsing tool can easily walk the trace buffer stack so we
+ // need to add that on to total size
+ l_entry_size += sizeof(uint32_t);
+
+ // Now add on size for acutal number of arguments we're tracing
+ l_entry_size += (num_args * sizeof(uint64_t));
+
+ // Word align the entry
+ l_entry_size = (l_entry_size + 3) & ~3;
+
+ // Fill in the entry structure
+ l_entry.stamp.tid = (uint32_t)task_gettid(); // What is response to this in AME code?
+
+ // Length is equal to size of data
+ l_entry.head.length = (num_args * sizeof(uint64_t));
+ l_entry.head.tag = TRACE_FIELDTRACE;
+ l_entry.head.hash = i_hash;
+ l_entry.head.line = i_line;
- entry->component = (uint64_t) td;
- entry->tid = task_gettid();
- entry->length = sizeof(uint64_t) * size;
- entry->hash = hash;
- entry->timestamp = getTB();
- entry->line = line;
+ // Time stamp
+ *(l_entry.stamp.tb) = getTB();
- uint64_t* data = &entry->values[0];
+ uint64_t* data = &l_entry.args[0];
- va_list args;
- va_start(args, type);
- for (size_t i = 0; i < size; i++)
+ va_list args;
+ va_start(args, i_type);
+ for (size_t i = 0; i < num_args; i++)
+ {
+ *data = va_arg(args, uint64_t);
+ data++;
+ }
+ va_end(args);
+
+ // Now put total size at end of buffer
+ // Note that fsp-trace assumes this to be a 32 bit long word
+ uint32_t *l_size = (uint32_t *)&(l_entry.args[num_args]);
+ *l_size = l_entry_size;
+
+ printk("l_entry_size = %u ttid = %u\n",l_entry_size,l_entry.stamp.tid);
+
+ // We now have total size and need to reserve a part of the trace
+ // buffer for this
+
+ // CRITICAL REGION START
+ l_rc = mutex_lock(g_trac_mutex);
+ if(l_rc != 0)
+ {
+ printk("trace_adal_write_all: Failed to get mutex");
+ }
+ else
+ {
+ // Update the entry count
+ io_td->te_count++;
+
+ trace_write_data(io_td,
+ (void *)&l_entry,
+ l_entry_size);
+
+ l_rc = mutex_unlock(g_trac_mutex);
+ if(l_rc != 0)
+ {
+ // Badness
+ printk("trace_adal_write_all: Failed to release mutex");
+ }
+ }
+ // CRITICAL REGION END
+ }
+ else
{
- *data = va_arg(args, uint64_t);
- data++;
+ printk("trace_adal_write_all: User passed invalid parameter");
}
- va_end(args);
- return 0;
+
+ return;
}
+
+/******************************************************************************/
+// trace_adal_write_bin
+/******************************************************************************/
+void trace_adal_write_bin(trace_desc_t *io_td,const trace_hash_val i_hash,
+ const uint32_t i_line,
+ const void *i_ptr,
+ const uint32_t i_size,
+ const int32_t type)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ int64_t l_rc = 0;
+ uint32_t l_entry_size = 0;
+ trace_bin_entry_t l_entry;
+
+ /*---------------------------------------------------------------------- --*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+ do
+ {
+
+ if((io_td == NULL) || (i_ptr == NULL) || (i_size == 0))
+ {
+ break;
+ }
+
+ // Calculate total space needed
+ l_entry_size = sizeof(trace_entry_stamp_t);
+ l_entry_size += sizeof(trace_entry_head_t);
+
+ // We always add the size of the entry at the end of the trace entry
+ // so the parsing tool can easily walk the trace buffer stack so we
+ // need to add that on to total size
+ l_entry_size += sizeof(uint32_t);
+
+ // Now add on size for acutal size of the binary data
+ l_entry_size += i_size;
+
+ // Word align the entry
+ l_entry_size = (l_entry_size + 3) & ~3;
+
+ // Fill in the entry structure
+ l_entry.stamp.tid = (uint32_t)task_gettid(); // What is response to this in AME code?
+
+ // Length is equal to size of data
+ l_entry.head.length = i_size;
+ l_entry.head.tag = TRACE_FIELDBIN;
+ l_entry.head.hash = i_hash;
+ l_entry.head.line = i_line;
+
+ // We now have total size and need to reserve a part of the trace
+ // buffer for this
+
+ // Time stamp
+ *(l_entry.stamp.tb) = getTB();
+
+ // CRITICAL REGION START
+ l_rc = mutex_lock(g_trac_mutex);
+ if(l_rc != 0)
+ {
+ printk("trace_adal_write_bin: Failed to get mutex");
+ }
+ else
+ {
+
+ // Increment trace counter
+ io_td->te_count++;;
+
+ // First write the header
+ trace_write_data(io_td,
+ (void *)&l_entry,
+ sizeof(l_entry));
+
+ // Now write the actual binary data
+ trace_write_data(io_td,
+ i_ptr,
+ i_size);
+
+ // Now write the size at the end
+ trace_write_data(io_td,
+ (void *)&l_entry_size,
+ sizeof(l_entry_size));
+
+ // CRITICAL REGION END
+ l_rc = mutex_unlock(g_trac_mutex);
+ if(l_rc != 0)
+ {
+ // Badness
+ printk("trace_adal_write_bin: Failed to release mutex");
+ }
+ }
+
+ }while(0);
+
+ return;
+}
+
+/******************************************************************************/
+// trace_write_data
+/******************************************************************************/
+void trace_write_data(trace_desc_t *io_td,
+ const void *i_ptr,
+ const uint32_t i_size)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ uint32_t l_total_size = i_size;
+ void *l_buf_ptr = NULL;
+ uint32_t l_offset = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ do
+ {
+
+ if(i_size > PAGE_SIZE)
+ {
+ printk("trace_write_data: Input size to large!");
+ break;
+ }
+
+ if((io_td->next_free + l_total_size) > PAGE_SIZE)
+ {
+ // copy what we can to end
+ l_buf_ptr = (char *)io_td + io_td->next_free;
+ l_buf_ptr = (void *) ( ((uint64_t) l_buf_ptr + 3) & ~3);
+ l_offset = PAGE_SIZE-io_td->next_free;
+ memcpy(l_buf_ptr,i_ptr,(size_t)l_offset);
+
+ l_total_size -= l_offset;
+
+ // Now adjust the main header of buffer
+ io_td->times_wrap++;
+ io_td->next_free = io_td->hdr_len;
+ }
+
+ l_buf_ptr = (char *)io_td + io_td->next_free;
+
+ // Word align the write - total size includes this allignment
+ l_buf_ptr = (void *) ( ((uint64_t) l_buf_ptr + 3) & ~3);
+
+ memcpy(l_buf_ptr,(char *)i_ptr + l_offset,l_total_size);
+
+ // Make sure size is correct for word allignment
+ // Note that this works with binary trace because only the binary data
+ // has the potential to be un-word aligned. If two parts of the binary
+ // trace had this problem then this code would not work.
+ l_total_size = (l_total_size + 3) & ~3;
+ io_td->next_free += l_total_size;
+
+ }while(0);
+
+ return;
+
+}
+
+/******************************************************************************/
+// TRAC_get_td - TODO
+/******************************************************************************/
+trace_desc_t * trace_get_td(const char *i_comp)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ //uint32_t l_num_des = 0;
+ //uint32_t i=0;
+ //trace_desc_t * l_td = NULL;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+#if 0
+ l_num_des = sizeof(g_des_array) / sizeof(trace_descriptor_array_t);
+
+ for(i=0;i<l_num_des;i++)
+ {
+ if(memcmp(i_comp,(g_des_array[i].entry)->comp,(size_t)COMP_NAME_SIZE) == 0)
+ {
+ // Found the component
+ l_td = g_des_array[i].entry;
+ break;
+ }
+ }
+#endif
+ // Only one trace buffer currently
+ return(g_trac_global);
+}
+
+/******************************************************************************/
+// trace_get_buffer - TODO
+/******************************************************************************/
+int32_t trace_get_buffer(const trace_desc_t *i_td_ptr,
+ void *o_data)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ int64_t l_rc = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ if((i_td_ptr) && (o_data != NULL))
+ {
+ // Get the lock
+ // TODO Mutex
+#if 0
+ l_rc = UTIL_MUTEX_GET(&g_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT);
+ if(l_rc != 0)
+ {
+ // Badness
+ printk("TRAC_get_buffer: Failed to get mutex");
+ }
+ else
+ {
+ l_rc = SUCCESS;
+ }
+#endif
+ // Copy it's buffer into temp one
+ memcpy(o_data,i_td_ptr,(size_t)PAGE_SIZE);
+
+ // Always try to release even if error above
+ // TODO - mutex
+ //UTIL_MUTEX_PUT(&g_trac_mutex);
+ }
+ else
+ {
+ printk("TRAC_get_buffer: Invalid parameter passed by caller");
+ }
+
+ return(l_rc);
+}
+
+#if 0
+/******************************************************************************/
+// trace_get_buffer_partial - TODO
+/******************************************************************************/
+// TODO
+int32_t trace_get_buffer_partial(const trace_desc_t *i_td_ptr,
+ void *o_data,
+ uint32_t *io_size)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ int32_t l_rc = 0;
+ char *l_full_buf = NULL;
+ trace_desc_t *l_head = NULL;
+ uint32_t l_part_size = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ do
+ {
+
+ if((i_td_ptr == NULL) || (o_data == NULL) || (io_size == NULL))
+ {
+ printk("trace_get_buffer_partial: Invalid parameter passed by caller");
+ l_rc = TRAC_INVALID_PARM;
+ if(io_size != NULL)
+ {
+ *io_size = 0;
+ }
+ break;
+ }
+
+ if(*io_size < sizeof(trace_buf_head_t))
+ {
+ // Need to at least have enough space for the header
+ printk("trace_get_buffer_partial: *io_size to small");
+ l_rc = TRAC_MEM_BUFF_TO_SMALL;
+ *io_size = 0;
+ break;
+ }
+
+ // First get the full buffer
+ l_rc = tx_byte_allocate(&tpmd_trac_debug_byte_pool,
+ (void **)&l_full_buf,
+ TPMD_TRACE_BUFFER_SIZE,
+ TX_NO_WAIT);
+ if(l_rc != TX_SUCCESS)
+ {
+ printk("trace_get_buffer_partial: Failure allocating memory for temp buffer");
+ *io_size = 0;
+ l_rc = TRAC_MEM_ALLOC_FAIL;
+ break;
+ }
+
+ l_rc = trace_get_buffer(i_td_ptr,
+ l_full_buf);
+ if(l_rc != 0)
+ {
+ printk("trace_get_buffer_partial: Failure in call to TRAC_get_buffer()");
+ *io_size = 0;
+ break;
+ }
+
+ // Now that we have full buffer, adjust it to be requested size
+ memset(o_data,0,(size_t)*io_size);
+
+ if(*io_size > TPMD_TRACE_BUFFER_SIZE)
+ {
+ // It fits
+ *io_size = TPMD_TRACE_BUFFER_SIZE;
+ memcpy(o_data,l_full_buf,(size_t)*io_size);
+ break;
+ }
+
+ l_head = (trace_desc_t *)l_full_buf;
+ memcpy(o_data,l_full_buf,(size_t)(l_head->hdr_len));
+ l_head = (trace_desc_t *)o_data;
+ l_head->size = *io_size;
+
+ if((l_head->next_free == l_head->hdr_len) && (l_head->times_wrap == 0))
+ {
+ // No data in buffer so just return what we have
+ break;
+ }
+
+ if(l_head->next_free > *io_size)
+ {
+ // We can't even fit in first part of buffer
+ // Make sure data size is larger than header length
+ // Otherwise, we will be accessing beyond memory
+ if(*io_size < l_head->hdr_len)
+ {
+ l_rc = TRAC_DATA_SIZE_LESS_THAN_HEADER_SIZE;
+ break;
+ }
+ l_part_size = *io_size - l_head->hdr_len;
+
+ memcpy((UCHAR *)o_data+l_head->hdr_len,
+ l_full_buf+l_head->next_free-l_part_size,
+ (size_t)l_part_size);
+
+ // Set pointer at beginning because this will be a
+ // "just wrapped" buffer.
+ l_head->next_free = l_head->hdr_len;
+
+ // Buffer is now wrapped because we copied max data into it.
+ if(!l_head->times_wrap)
+ {
+ l_head->times_wrap = 1;
+ }
+ }
+ else
+ {
+ // First part of buffer fits fine
+ memcpy((UCHAR *)o_data+l_head->hdr_len,
+ l_full_buf+l_head->hdr_len,
+ (size_t)(l_head->next_free - l_head->hdr_len));
+
+
+ // If it's wrapped then pick up some more data
+ if(l_head->times_wrap)
+ {
+ // Figure out how much room we have left
+ l_part_size = *io_size - l_head->next_free;
+
+ memcpy((UCHAR *)o_data+l_head->next_free,
+ l_full_buf+TPMD_TRACE_BUFFER_SIZE-l_part_size,
+ (size_t)l_part_size);
+
+ }
+ else
+ {
+ // No more data to get, make buffer look as small
+ // as possible
+ // add '+4' to avoid the need to mark it as wrapped
+ // (if the last byte of the buffer is filled
+ // next_free has to pointer to the first byte)
+
+ l_head->size = l_head->next_free + 4;
+
+ }
+
+ }
+
+ *io_size = l_head->size;
+
+ }while(0);
+
+ if(l_full_buf != NULL)
+ {
+ tx_byte_release(l_full_buf);
+ }
+
+ return(l_rc);
+}
+#endif
+
+/******************************************************************************/
+// trace_reset_buf - TODO
+/******************************************************************************/
+int32_t trace_reset_buf()
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ int64_t l_rc = 0;
+ //uint32_t l_num_des = 0;
+ //uint32_t i=0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ // Get mutex so no one traces
+#if 0
+ // TODO
+ l_rc = UTIL_MUTEX_GET(&g_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT);
+ if(l_rc != TX_SUCCESS)
+ {
+ printk("trace_reset_buf: Failure trying to get mutex");
+ // Badness
+ }
+ else
+ {
+ l_num_des = sizeof(g_des_array) / sizeof(trace_descriptor_array_t);
+
+ for(i=0;i<l_num_des;i++)
+ {
+ // Initialize the buffer
+ l_rc = trace_init_values_buffer(g_des_array[i].entry,
+ g_des_array[i].comp);
+ if(l_rc)
+ {
+ printk("trace_reset_buf: Failure in call to trace_init_values_buffer()");
+ break;
+ }
+ }
+ }
+
+#endif
+ // Always try to release even if fail above
+ // TODO - mutex
+ //UTIL_MUTEX_PUT(&g_trac_mutex);
+
+ return(l_rc);
+}
+
+} // namespace
diff --git a/src/usr/trace/trace.H b/src/usr/trace/trace.H
new file mode 100644
index 000000000..8087e6c32
--- /dev/null
+++ b/src/usr/trace/trace.H
@@ -0,0 +1,132 @@
+/**
+ * @file trace.H
+ *
+ * @brief Internal trace definitions and functions
+*/
+
+#ifndef __TRACE_TRACE_H
+#define __TRACE_TRACE_H
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+#include <trace/interface.H>
+
+namespace TRACE
+{
+
+/******************************************************************************/
+// Globals/Constants
+/******************************************************************************/
+
+#define TRACE_BUF_VERSION 0x01; // Trace buffer version
+#define TRACE_FIELDTRACE 0x4654 // Field Trace - "FT"
+#define TRACE_FIELDBIN 0x4644 // Binary Field Trace - "FD"
+
+#define TRACE_DEBUG_ON 1 //Set to this when debug trace on
+#define TRACE_DEBUG_OFF 0 //Set to this when debug trace off
+
+
+/******************************************************************************/
+// Typedef/Enumerations
+/******************************************************************************/
+
+/******************************************************************************/
+// Function Prototypes
+/******************************************************************************/
+
+/**
+ * @brief Initialize a new trace buffer
+ *
+ * Internal function responsible setting up the defaults in a newly created
+ * trace buffer.
+ *
+ * @param[out] o_buf Trace descriptor of component buffer to initialize.
+ * @param[in] i_comp Component name
+ *
+ * @return void
+ *
+ */
+void trace_init_values_buffer(trace_desc_t *o_buf,
+ const char *i_comp);
+
+
+/**
+ * @brief Write the trace data into the buffer
+ *
+ * Internal function responsible for copying the trace data into the appropriate
+ * buffer.
+ *
+ * @param[inout] io_td Trace descriptor of component buffer to write to.
+ * @param[in] i_ptr Pointer to data to copy into the trace buffer.
+ * @param[in] i_size Size of the i_ptr data to copy into the buffer.
+ *
+ * @return void
+ *
+ */
+void trace_write_data(trace_desc_t * io_td,
+ const void *i_ptr,
+ const uint32_t i_size);
+
+
+/**
+ * @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.
+ *
+ * TODO - Not Supported Yet
+ *
+ * @return Non-zero return code on error
+ */
+int32_t trace_get_buffer(const trace_desc_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.
+ *
+ * TODO - Not Supported Yet
+ *
+ * @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
+ */
+int32_t trace_get_buffer_partial(const trace_desc_t * i_td_ptr,
+ void *o_data,
+ uint32_t *io_size);
+
+/**
+ * @brief Retrieve trace descriptor for input component name
+ *
+ * @param i_comp Component name to retrieve trace descriptor for.
+ *
+ * TODO - Not Supported Yet
+ *
+ * @return Valid trace descriptor on success, NULL on failure.
+ */
+trace_desc_t * trace_get_td(const char *i_comp);
+
+/**
+ * @brief Reset all trace buffers
+ *
+ * TODO - Not Supported Yet
+ *
+ * @return Non-zero return code on error
+ */
+int32_t trace_reset_buf(void);
+
+} // namespace TRACE
+
+#endif
diff --git a/src/usr/trace/tracebuffer.C b/src/usr/trace/tracebuffer.C
index 5e5b697a1..3a56fde7b 100644
--- a/src/usr/trace/tracebuffer.C
+++ b/src/usr/trace/tracebuffer.C
@@ -8,6 +8,8 @@ TracePage* TracePage::setNext(TracePage* new_next)
traceEntry* TracePage::claimEntry(size_t size)
{
+ // this->size will eventually wrap and it will suddenly look like there
+ // is free space?
size_t position = __sync_fetch_and_add(&this->size, size);
if (position > (PAGE_SIZE - sizeof(TracePage)))
{
OpenPOWER on IntegriCloud